From 6bcc3ff918fbd6bca2c91b7c3495ef68ed49fe8a Mon Sep 17 00:00:00 2001 From: morbalint Date: Mon, 20 May 2024 21:00:54 +0200 Subject: [PATCH] !!!add felszerelesek BREAKING API!!! --- .../second-edition/components/Felszereles.tsx | 447 ++++++++++++++---- .../src/second-edition/data/felszereles.json | 4 +- .../domain-models/allowed-fegyver.ts | 6 + .../domain-models/felszereles.ts | 25 +- .../second-edition/pdf/karakter_pdf_view.ts | 68 ++- 5 files changed, 428 insertions(+), 122 deletions(-) diff --git a/frontend/src/second-edition/components/Felszereles.tsx b/frontend/src/second-edition/components/Felszereles.tsx index af64418..f09d043 100644 --- a/frontend/src/second-edition/components/Felszereles.tsx +++ b/frontend/src/second-edition/components/Felszereles.tsx @@ -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 } +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) => { 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) => { 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 <>
Felszerelés
-
+
Harci felszerelés
@@ -179,7 +341,7 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change value={p.Id}>{`${p.Name} (+${p.VO} VO) - ${p.Price} at`})}
- {valasztottFegyverek.map(({idx, fegyver}) => ( + {valasztottFegyverek.map(({idx, fegyver, count, max}) => (
changeFegyver(idx, fegyverId)} dataTestId={`felszereles-fegyver-${idx}`} /> - + {(count > 1 || max > 1) && +
+
+
+ +
+ {' '}{count}{' db '} +
+ +
+
+
} + {max <= 1 &&
+ +
}
))} {viseltSize < 8 && ()} -
-
+
Viselt felszerelés
- {viseltFelszereles.map(({idx, targy}) => ( + {viseltFelszereles.map(({idx, targy, count, max}) => (
- + {(count > 1 || max > 1) && +
+
+
+ +
+ {' '}{count}{' db '} +
+ +
+
+
} + {max <= 1 &&
+ +
}
))} {viseltSize < 8 && ()} - {cipeltCapacity > 0 && <>
-
-
Cipelt felszerelés
-
- {cipeltFelszereles.map(({idx, targy}) => ( -
- x.size > 0)} - onChange={changeCipelt(idx)} - selectedId={targy!.id} - dataTestId={`felszereles-viselt-selector-${idx}`} - /> - + {cipeltCapacity > 0 && <> +
+
Cipelt felszerelés
+ {cipeltFelszereles.map(({idx, targy, count, max}) => ( +
+ + {(count > 1 || max > 1) && +
+
+
+ +
+ {' '}{count}{' db '} +
+ +
+
+
} + {max <= 1 &&
+ +
} +
))} - {felszereles.cipeltFelszerelesIDk.length < cipeltCapacity && ()}} -
-
+
Apróságok
- {aprosagFelszereles.map(({idx, targy}) => ( + {aprosagFelszereles.map(({idx, targy, count}) => (
x.size === 0)} @@ -266,15 +507,33 @@ export function FelszerelesView(props: {felszereles: KarakterFelszereles, change selectedId={targy!.id} dataTestId={`felszereles-viselt-selector-${idx}`} /> - +
+
+
+ +
+ {' '}{count}{' db '} +
+ +
+
+
))} - {felszereles.aprosagFelszerelesIDk.length < 8 && (