!!!add felszerelesek BREAKING API!!!

This commit is contained in:
2024-05-20 21:00:54 +02:00
parent 8135e3fd10
commit 6bcc3ff918
5 changed files with 428 additions and 122 deletions
@@ -9,7 +9,7 @@ import {
import {Osztaly2E} from '../domain-models/osztaly2E'
import {AllowedPajzsTypes, AllowedPancelTypes} from '../domain-models/allowed-pancel-types'
import {arraySetN} from "../../util";
import {AllowedFegyverek} from "../domain-models/allowed-fegyver";
import {AllowedFegyverek, HarcosFegyverforgatok} from "../domain-models/allowed-fegyver";
import FegyverSelector from "../display-components/FegyverSelector";
import {useDispatch, useSelector} from "react-redux";
import {AppDispatch, RootState} from "../../store";
@@ -25,6 +25,17 @@ export function Felszereles(){
return <FelszerelesView felszereles={felszereles} changeFelszereles={changeFelszereles} osztalyok={osztalyok} />
}
function ItemMaxCount(targy?: FelszerelesDto): number {
const targySize = targy?.size ?? 1
return (targySize < 1 && targySize > 0) ? Math.round(1/targy!.size) : 1;
}
// TODO: Make all items use the same `size`. Lowercase data fields!
function FegyverMaxCount(fegyver?: Fegyver): number {
const fegyverSize = fegyver?.Size ?? 1
return (fegyverSize < 1 && fegyverSize > 0) ? Math.round(1/fegyver!.Size) : 1;
}
export function FelszerelesView(props: {felszereles: KarakterFelszereles, changeFelszereles: (felszereles: KarakterFelszereles) => void, osztalyok: Osztaly2E[]}) {
const {felszereles, changeFelszereles, osztalyok} = props;
const viseltSize = ViseltSize(felszereles)
@@ -32,34 +43,36 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
.filter(x => felszereles.pancelID === x.Id || x.Size + viseltSize - (GetPancel(felszereles.pancelID)?.Size ?? 0) <= 8)
const allowedPajzs = AllowedPajzsTypes(osztalyok)
.filter(x => felszereles.pajzsID === x.Id || x.Size + viseltSize - (GetPajzs(felszereles.pajzsID)?.Size ?? 0) <= 8)
const valasztottFegyverek = felszereles.fegyverIDk
.map((id, idx) => ({
idx,
fegyver: GetFegyver(id),
})).filter((x) => x.fegyver != null).map(({idx, fegyver}) => ({idx, fegyver: fegyver as Fegyver}));
const valasztottFegyverek = felszereles.fegyverek
.map(({id, count}, idx) => {
const fegyver = GetFegyver(id)
const max = FegyverMaxCount(fegyver)
return {
idx,
fegyver: GetFegyver(id),
count,
max
};
}).filter((x) => x.fegyver != null).map(x => ({...x, fegyver: x.fegyver as Fegyver}));
const viseltFelszereles= felszereles.viselt.map(({id, count}, idx) => {
const targy = GetFelszereles(id)
const max = ItemMaxCount(targy)
return {
idx,
targy,
count,
max,
};
}).filter(x => x.targy != null);
const viseltFelszereles= felszereles.viseltFelszerelesIDk.map((id, idx) => ({
idx,
targy: GetFelszereles(id),
})).filter(x => x.targy != null);
const aprosagFelszereles= felszereles.aprosagFelszerelesIDk.map((id, idx) => ({
idx,
targy: GetFelszereles(id),
})).filter(x => x.targy != null);
const osztalyAllowedFegyverek = AllowedFegyverek(osztalyok)
const allowedFegyverek = (selected?: Fegyver) => ([
...osztalyAllowedFegyverek.filter(x => x.Size + viseltSize - (selected?.Size ?? 0) <= 8),
...osztalyAllowedFegyverek.filter(x => x.Size + viseltSize - (selected?.Size ?? 1 > 1 ? selected!.Size : 1) <= 8),
...valasztottFegyverek.filter(({idx,fegyver}) => !osztalyAllowedFegyverek.map(f => f.Id).includes(fegyver.Id))
.map(({fegyver}) => fegyver)])
const changeFegyver = (idx: number, newID: string) => {
const found = GetFegyver(newID)
if (!found) {
console.log('Nem létező fegyver ID: ', newID)
return
}
changeFelszereles({...felszereles, fegyverIDk: arraySetN(felszereles.fegyverIDk, idx, newID)})
}
const changePancel = (event: React.ChangeEvent<HTMLSelectElement>) => {
changeFelszereles({...felszereles, pancelID: event.target.value === 'nincs' ? undefined : event.target.value})
@@ -67,17 +80,58 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
const changePajzs = (event: React.ChangeEvent<HTMLSelectElement>) => {
changeFelszereles({...felszereles, pajzsID: event.target.value === 'nincs' ? undefined : event.target.value})
}
const addFegyver = () => {
const newFegyver = osztalyok.some(o => HarcosFegyverforgatok.has(o)) ? 'okol_harcos' : 'okol'
changeFelszereles({...felszereles, fegyverek: [...felszereles.fegyverek, {id: newFegyver, count: 1}]});
}
const changeFegyver = (idx: number, newID: string) => {
const found = GetFegyver(newID)
if (!found) {
console.log('Nem létező fegyver ID: ', newID)
return
}
changeFelszereles({...felszereles, fegyverek: arraySetN(felszereles.fegyverek, idx, {id: newID, count: 1})})
}
const increaseFegyverCount = (idx: number) => () => {
const old = felszereles.fegyverek[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.fegyverek)
return
}
if(old.count >= FegyverMaxCount(GetFegyver(old.id))){
console.error("Can't increase item count more than max!", old)
return;
}
changeFelszereles({...felszereles, fegyverek: arraySetN(felszereles.fegyverek, idx, {...old, count: old.count + 1})})
}
const decreaseFegyverCount = (idx: number) => () => {
const old = felszereles.fegyverek[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.fegyverek)
return
}
if(old.count === 1){
changeFelszereles({
...felszereles,
fegyverek: [...felszereles.fegyverek.slice(0, idx), ...felszereles.viselt.slice(idx + 1)]
})
}
else{
changeFelszereles({...felszereles, fegyverek: arraySetN(felszereles.fegyverek, idx, {...old, count: old.count - 1})})
}
}
const removeFegyver = (idx: number) => () => changeFelszereles({
...felszereles,
fegyverIDk: [...felszereles.fegyverIDk.slice(0, idx), ...felszereles.fegyverIDk.slice(idx + 1)]
fegyverek: [...felszereles.fegyverek.slice(0, idx), ...felszereles.fegyverek.slice(idx + 1)]
})
const addFegyver = () => changeFelszereles({...felszereles, fegyverIDk: [...felszereles.fegyverIDk, 'okol']})
const allowedViselt = (selected?: FelszerelesDto) => AllFelszereles.filter(x =>
(x.size > 0 && viseltSize + x.size - (selected?.size ?? 0) <= 8))
const addViseltFelszereles = () => changeFelszereles({
const allowedViselt = (selected?: FelszerelesDto) => AllFelszereles.filter(x => {
const selectedSize = (selected?.size ?? 1) > 1 ? selected!.size : 1
return (x.size > 0 && (viseltSize + x.size - selectedSize) <= 8);
})
const addViselt = () => changeFelszereles({
...felszereles,
viseltFelszerelesIDk: [...felszereles.viseltFelszerelesIDk, 'szog']
viselt: [...felszereles.viselt, {id: 'szog', count: 1}]
})
const changeViselt = (idx: number) => (newID: string) => {
const found = GetFelszereles(newID)
@@ -85,39 +139,113 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
console.log('Nem létező tárgy ID: ', newID)
return
}
changeFelszereles({...felszereles, viseltFelszerelesIDk: arraySetN(felszereles.viseltFelszerelesIDk, idx, newID)})
const old = felszereles.viselt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.viselt)
return
}
const item = {id: newID, count: 1}
changeFelszereles({...felszereles, viselt: arraySetN(felszereles.viselt, idx, item)})
}
const removeViseltFelszereles = (idx: number) => () => changeFelszereles({
const increaseViseltCount = (idx: number) => () => {
const old = felszereles.viselt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.viselt)
return
}
if(old.count >= ItemMaxCount(GetFelszereles(old.id))){
console.error("Can't increase item count more than max!", old)
return;
}
changeFelszereles({...felszereles, viselt: arraySetN(felszereles.viselt, idx, {...old, count: old.count + 1})})
}
const decreaseViseltCount = (idx: number) => () => {
const old = felszereles.viselt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.viselt)
return
}
if(old.count === 1){
changeFelszereles({
...felszereles,
viselt: [...felszereles.viselt.slice(0, idx), ...felszereles.viselt.slice(idx + 1)]
})
}
else{
changeFelszereles({...felszereles, viselt: arraySetN(felszereles.viselt, idx, {...old, count: old.count - 1})})
}
}
const removeViselt = (idx: number) => () => changeFelszereles({
...felszereles,
viseltFelszerelesIDk: [...felszereles.viseltFelszerelesIDk.slice(0, idx), ...felszereles.viseltFelszerelesIDk.slice(idx + 1)]
viselt: [...felszereles.viselt.slice(0, idx), ...felszereles.viselt.slice(idx + 1)]
})
const aprosagFelszereles= felszereles.aprosagok.map(({id, count}, idx) => ({
idx,
targy: GetFelszereles(id),
count,
})).filter(x => x.targy != null);
const addAprosag = () => changeFelszereles({
...felszereles,
aprosagFelszerelesIDk: [...felszereles.aprosagFelszerelesIDk, 'tarsoly']
aprosagok: [...felszereles.aprosagok, {id: 'tarsoly', count: 1}]
})
const changeAprosag = (idx: number) => (newID: string) => {
const found = GetFelszereles(newID)
if (!found) {
console.log('Nem létező tárgy ID: ', newID)
console.error('Nem létező tárgy ID: ', newID)
return
}
changeFelszereles({...felszereles, aprosagFelszerelesIDk: arraySetN(felszereles.aprosagFelszerelesIDk, idx, newID)})
const old = felszereles.aprosagok[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.aprosagok)
return
}
changeFelszereles({...felszereles, aprosagok: arraySetN(felszereles.aprosagok, idx, {...old, id: newID})})
}
const increaseAprosagCount = (idx: number) => () => {
const old = felszereles.aprosagok[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.aprosagok)
return
}
changeFelszereles({...felszereles, aprosagok: arraySetN(felszereles.aprosagok, idx, {...old, count: old.count + 1})})
}
const decreaseAprosagCount = (idx: number) => () => {
const old = felszereles.aprosagok[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.aprosagok)
return
}
if(old.count === 1){
changeFelszereles({
...felszereles,
aprosagok: [...felszereles.aprosagok.slice(0, idx), ...felszereles.aprosagok.slice(idx + 1)]
})
}
else{
changeFelszereles({...felszereles, aprosagok: arraySetN(felszereles.aprosagok, idx, {...old, count: old.count - 1})})
}
}
const removeAprosag = (idx: number) => () => changeFelszereles({
...felszereles,
aprosagFelszerelesIDk: [...felszereles.aprosagFelszerelesIDk.slice(0, idx), ...felszereles.aprosagFelszerelesIDk.slice(idx + 1)]
})
const cipeltCapacity = viseltFelszereles.reduce((acc, item) => acc + (item.targy?.type === 'container' ? item.targy.capacity : 0), 0)
const addCipelt = () => changeFelszereles({
...felszereles,
cipeltFelszerelesIDk: [...felszereles.cipeltFelszerelesIDk, 'szog']
cipelt: [...felszereles.cipelt, {id: 'szog', count: 1}]
})
const cipeltFelszereles= felszereles.cipeltFelszerelesIDk.map((id, idx) => ({
idx,
targy: GetFelszereles(id),
})).filter(x => x.targy != null);
const cipeltFelszereles= felszereles.cipelt.map(({id, count}, idx) => {
const targy = GetFelszereles(id)
const max = ItemMaxCount(targy)
return ({
idx,
targy,
count,
max
});
}).filter(x => x.targy != null);
const cipeltSize = cipeltFelszereles.reduce((acc, item) => acc + Math.ceil(item.targy?.size ?? 1), 0)
const allowedCipelt = (selected?: FelszerelesDto) => AllFelszereles.filter(x => x.size > 0
&& Math.ceil(x.size) + cipeltSize - Math.ceil(selected?.size ?? 0) <= cipeltCapacity)
const changeCipelt = (idx: number) => (newID: string) => {
const found = GetFelszereles(newID)
@@ -125,18 +253,52 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
console.log('Nem létező tárgy ID: ', newID)
return
}
changeFelszereles({...felszereles, cipeltFelszerelesIDk: arraySetN(felszereles.cipeltFelszerelesIDk, idx, newID)})
const old = felszereles.cipelt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.cipelt)
return
}
const newItem = {id: newID, count: 1}
changeFelszereles({...felszereles, cipelt: arraySetN(felszereles.cipelt, idx, newItem)})
}
const increaseCipeltCount = (idx: number) => () => {
const old = felszereles.cipelt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.cipelt)
return
}
if(old.count >= ItemMaxCount(GetFelszereles(old.id))){
console.error("Can't increase item count more than max!", old)
return;
}
changeFelszereles({...felszereles, cipelt: arraySetN(felszereles.cipelt, idx, {...old, count: old.count + 1})})
}
const decreaseCipeltCount = (idx: number) => () => {
const old = felszereles.cipelt[idx]
if (old == null) {
console.error('Index out of range! index: {0}, array: {1}', idx, felszereles.cipelt)
return
}
if(old.count === 1){
changeFelszereles({
...felszereles,
cipelt: [...felszereles.cipelt.slice(0, idx), ...felszereles.cipelt.slice(idx + 1)]
})
}
else{
changeFelszereles({...felszereles, cipelt: arraySetN(felszereles.cipelt, idx, {...old, count: old.count - 1})})
}
}
const removeCipelt = (idx: number) => () => changeFelszereles({
...felszereles,
cipeltFelszerelesIDk: [...felszereles.cipeltFelszerelesIDk.slice(0, idx), ...felszereles.cipeltFelszerelesIDk.slice(idx + 1)]
cipelt: [...felszereles.cipelt.slice(0, idx), ...felszereles.cipelt.slice(idx + 1)]
})
return <>
<div className='row'>
<h5 className='col align-self-center'>Felszerelés</h5>
</div>
<div className='row mt-2'>
<div className='row mt-4'>
<h6 className='col align-self-center'>Harci felszerelés</h6>
</div>
<div className='row m-2'>
@@ -179,7 +341,7 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
value={p.Id}>{`${p.Name} (+${p.VO} VO) - ${p.Price} at`}</option>)}
</select>
</div>
{valasztottFegyverek.map(({idx, fegyver}) => (
{valasztottFegyverek.map(({idx, fegyver, count, max}) => (
<div key={`fegyver-${idx}`} className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Fegyver</label>
<FegyverSelector
@@ -188,25 +350,51 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
onChange={(fegyverId) => changeFegyver(idx, fegyverId)}
dataTestId={`felszereles-fegyver-${idx}`}
/>
<button
className='col-md-2 col-sm-3 btn btn-outline-dark btn-lg ms-2'
type='button'
onClick={removeFegyver(idx)}>Elvesz
</button>
{(count > 1 || max > 1) &&
<div className="col-lg-2 col-md-3 col-sm-4">
<div className="row">
<div className="w-25 ps-2">
<button
className='btn btn-outline-dark'
type='button'
onClick={decreaseFegyverCount(idx)}
>
</button>
</div>
<span className="w-50 align-content-center text-center">{' '}{count}{' db '}</span>
<div className="w-25 ps-2 ">
<button
className='btn btn-outline-dark float-end'
type='button'
disabled={count >= max}
onClick={increaseFegyverCount(idx)}
>
+
</button>
</div>
</div>
</div>}
{max <= 1 && <div className="col-lg-2 col-md-3 col-sm-4">
<button
className='btn btn-outline-dark w-100'
type='button'
onClick={removeFegyver(idx)}>Elvesz
</button>
</div>}
</div>
))}
{viseltSize < 8 && (<button
className='btn btn-outline-dark btn btn-lg ms-2'
className='btn btn-outline-dark btn ms-2'
type='button'
onClick={addFegyver}
>
Fegyver hozzáadása
</button>)}
<hr/>
<div className='row mt-2'>
<div className='row mt-4'>
<h6 className='col align-self-center'>Viselt felszerelés</h6>
</div>
{viseltFelszereles.map(({idx, targy}) => (
{viseltFelszereles.map(({idx, targy, count, max}) => (
<div key={`felszereles-viselt-${idx}`} className='row m-2'>
<FelszerlesSelector
felszerelesek={allowedViselt(targy)}
@@ -214,51 +402,104 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
selectedId={targy!.id}
dataTestId={`felszereles-viselt-selector-${idx}`}
/>
<button
className='col-md-2 col-sm-3 btn btn-outline-dark btn-lg ms-2'
type='button'
onClick={removeViseltFelszereles(idx)}>Elvesz
</button>
{(count > 1 || max > 1) &&
<div className="col-lg-2 col-md-3 col-sm-4">
<div className="row">
<div className="w-25 ps-2">
<button
className='btn btn-outline-dark'
type='button'
onClick={decreaseViseltCount(idx)}
>
</button>
</div>
<span className="w-50 align-content-center text-center">{' '}{count}{' db '}</span>
<div className="w-25 ps-2 ">
<button
className='btn btn-outline-dark float-end'
type='button'
disabled={count >= max}
onClick={increaseViseltCount(idx)}
>
+
</button>
</div>
</div>
</div>}
{max <= 1 && <div className="col-lg-2 col-md-3 col-sm-4">
<button
className='btn btn-outline-dark w-100'
type='button'
onClick={removeViselt(idx)}>Elvesz
</button>
</div>}
</div>
))}
{viseltSize < 8 && (<button
className='btn btn-outline-dark btn btn-lg ms-2'
className='btn btn-outline-dark btn ms-2'
type='button'
onClick={addViseltFelszereles}
onClick={addViselt}
>
Felszerelés hozzáadása
Viselt felszerelés hozzáadása
</button>)}
{cipeltCapacity > 0 && <><hr/>
<div className='row mt-2'>
<h6 className='col align-self-center'>Cipelt felszerelés</h6>
</div>
{cipeltFelszereles.map(({idx, targy}) => (
<div key={`felszereles-viselt-${idx}`} className='row m-2'>
<FelszerlesSelector
felszerelesek={AllFelszereles.filter(x => x.size > 0)}
onChange={changeCipelt(idx)}
selectedId={targy!.id}
dataTestId={`felszereles-viselt-selector-${idx}`}
/>
<button
className='col-md-2 col-sm-3 btn btn-outline-dark btn-lg ms-2'
type='button'
onClick={removeCipelt(idx)}>Elvesz
</button>
{cipeltCapacity > 0 && <>
<div className='row mt-4'>
<h6 className='col align-self-center'>Cipelt felszerelés</h6>
</div>
{cipeltFelszereles.map(({idx, targy, count, max}) => (
<div key={`felszereles-viselt-${idx}`} className='row m-2'>
<FelszerlesSelector
felszerelesek={allowedCipelt(targy)}
onChange={changeCipelt(idx)}
selectedId={targy!.id}
dataTestId={`felszereles-viselt-selector-${idx}`}
/>
{(count > 1 || max > 1) &&
<div className="col-lg-2 col-md-3 col-sm-4">
<div className="row">
<div className="w-25 ps-2">
<button
className='btn btn-outline-dark'
type='button'
onClick={decreaseCipeltCount(idx)}
>
</button>
</div>
<span className="w-50 align-content-center text-center">{' '}{count}{' db '}</span>
<div className="w-25 ps-2 ">
<button
className='btn btn-outline-dark float-end'
type='button'
disabled={count >= max}
onClick={increaseCipeltCount(idx)}
>
+
</button>
</div>
</div>
</div>}
{max <= 1 && <div className="col-lg-2 col-md-3 col-sm-4">
<button
className='btn btn-outline-dark w-100'
type='button'
onClick={removeCipelt(idx)}>Elvesz
</button>
</div>}
</div>
))}
{felszereles.cipeltFelszerelesIDk.length < cipeltCapacity && (<button
className='btn btn-outline-dark btn btn-lg ms-2'
{cipeltSize < cipeltCapacity && (<button
className='btn btn-outline-dark btn ms-2'
type='button'
onClick={addCipelt}
>
Cipelt felszerelés hozzáadása
</button>)}</>}
<hr/>
<div className='row mt-2'>
<div className='row mt-4'>
<h6 className='col align-self-center'>Apróságok</h6>
</div>
{aprosagFelszereles.map(({idx, targy}) => (
{aprosagFelszereles.map(({idx, targy, count}) => (
<div key={`felszereles-viselt-${idx}`} className='row m-2'>
<FelszerlesSelector
felszerelesek={AllFelszereles.filter(x => x.size === 0)}
@@ -266,15 +507,33 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change
selectedId={targy!.id}
dataTestId={`felszereles-viselt-selector-${idx}`}
/>
<button
className='col-md-2 col-sm-3 btn btn-outline-dark btn-lg ms-2'
type='button'
onClick={removeAprosag(idx)}>Elvesz
</button>
<div className="col-lg-2 col-md-3 col-sm-4">
<div className="row">
<div className="w-25 ps-2">
<button
className='btn btn-outline-dark'
type='button'
onClick={decreaseAprosagCount(idx)}
>
</button>
</div>
<span className="w-50 align-content-center text-center">{' '}{count}{' db '}</span>
<div className="w-25 ps-2 ">
<button
className='btn btn-outline-dark float-end'
type='button'
onClick={increaseAprosagCount(idx)}
>
+
</button>
</div>
</div>
</div>
</div>
))}
{felszereles.aprosagFelszerelesIDk.length < 8 && (<button
className='btn btn-outline-dark btn btn-lg ms-2'
{felszereles.aprosagok.length < 8 && (<button
className='btn btn-outline-dark btn ms-2'
type='button'
onClick={addAprosag}
>