Add support for weapon transcendence

This commit is contained in:
Justin Edmund 2024-01-13 11:22:34 -08:00
parent f52fec54b2
commit 0bc246641d
3 changed files with 141 additions and 6 deletions

View file

@ -17,6 +17,7 @@ interface Props {
removeWeapon: (id: string) => void removeWeapon: (id: string) => void
updateObject: (object: SearchableObject, position: number) => void updateObject: (object: SearchableObject, position: number) => void
updateUncap: (id: string, position: number, uncap: number) => void updateUncap: (id: string, position: number, uncap: number) => void
updateTranscendence: (id: string, position: number, stage: number) => void
} }
// Constants // Constants
@ -29,6 +30,7 @@ const ExtraWeaponsGrid = ({
removeWeapon, removeWeapon,
updateObject, updateObject,
updateUncap, updateUncap,
updateTranscendence,
}: Props) => { }: Props) => {
return ( return (
<ul className={styles.grid}> <ul className={styles.grid}>
@ -47,6 +49,7 @@ const ExtraWeaponsGrid = ({
removeWeapon={removeWeapon} removeWeapon={removeWeapon}
updateObject={updateObject} updateObject={updateObject}
updateUncap={updateUncap} updateUncap={updateUncap}
updateTranscendence={updateTranscendence}
/> />
</li> </li>
) )

View file

@ -65,6 +65,10 @@ const WeaponGrid = (props: Props) => {
const [previousUncapValues, setPreviousUncapValues] = useState<{ const [previousUncapValues, setPreviousUncapValues] = useState<{
[key: number]: number [key: number]: number
}>({}) }>({})
const [previousTranscendenceStages, setPreviousTranscendenceStages] =
useState<{
[key: number]: number
}>({})
// Initialize an array of current uncap values for each weapon // Initialize an array of current uncap values for each weapon
useEffect(() => { useEffect(() => {
@ -90,13 +94,16 @@ const WeaponGrid = (props: Props) => {
const payload: DetailsObject = { extra: party.extra } const payload: DetailsObject = { extra: party.extra }
props.createParty(payload).then((team) => { props.createParty(payload).then((team) => {
saveWeapon(team.id, weapon, position).then((response) => { saveWeapon(team.id, weapon, position).then((response) => {
if (response) storeGridWeapon(response.data.grid_weapon) if (response && response.data.grid_weapon) {
storeGridWeapon(response.data.grid_weapon)
}
}) })
}) })
} else { } else {
if (props.editable) if (props.editable)
saveWeapon(party.id, weapon, position) saveWeapon(party.id, weapon, position)
.then((response) => { .then((response) => {
console.log(response)
if (response) handleWeaponResponse(response.data) if (response) handleWeaponResponse(response.data)
}) })
.catch((error) => { .catch((error) => {
@ -135,7 +142,12 @@ const WeaponGrid = (props: Props) => {
if (data.position) setPosition(data.position) if (data.position) setPosition(data.position)
setModalOpen(true) setModalOpen(true)
} else { } else {
if (data.grid_weapon) {
storeGridWeapon(data.grid_weapon) storeGridWeapon(data.grid_weapon)
} else {
console.error('No grid weapon returned')
console.log(data)
}
// If we replaced an existing weapon, remove it from the grid // If we replaced an existing weapon, remove it from the grid
if (data.hasOwnProperty('meta') && data.meta['replaced'] !== undefined) { if (data.hasOwnProperty('meta') && data.meta['replaced'] !== undefined) {
@ -217,7 +229,12 @@ const WeaponGrid = (props: Props) => {
}) })
// Store new character in state // Store new character in state
if (response.data.grid_weapon)
storeGridWeapon(response.data.grid_weapon) storeGridWeapon(response.data.grid_weapon)
else {
console.error('No grid weapon returned')
console.log(response.data)
}
// Reset conflict // Reset conflict
resetConflict() resetConflict()
@ -335,6 +352,110 @@ const WeaponGrid = (props: Props) => {
setPreviousUncapValues(newPreviousValues) setPreviousUncapValues(newPreviousValues)
} }
// Methods: Updating transcendence stage
// Note: Saves, but debouncing is not working properly
async function saveTranscendence(
id: string,
position: number,
stage: number
) {
storePreviousUncapValue(position)
storePreviousTranscendenceStage(position)
const payload = {
weapon: {
uncap_level: stage > 0 ? 6 : 5,
transcendence_step: stage,
},
}
try {
if (stage != previousTranscendenceStages[position])
await api.updateTranscendence('weapon', id, stage).then((response) => {
storeGridWeapon(response.data.grid_weapon)
})
} catch (error) {
console.error(error)
// Revert optimistic UI
updateUncapLevel(position, previousUncapValues[position])
updateTranscendenceStage(position, previousTranscendenceStages[position])
// Remove optimistic key
let newPreviousTranscendenceStages = { ...previousTranscendenceStages }
let newPreviousUncapValues = { ...previousUncapValues }
delete newPreviousTranscendenceStages[position]
delete newPreviousUncapValues[position]
setPreviousTranscendenceStages(newPreviousTranscendenceStages)
setPreviousUncapValues(newPreviousUncapValues)
}
}
function initiateTranscendenceUpdate(
id: string,
position: number,
stage: number
) {
if (props.editable) {
memoizeTranscendenceAction(id, position, stage)
// Optimistically update UI
updateTranscendenceStage(position, stage)
if (stage > 0) {
updateUncapLevel(position, 6)
}
}
}
const memoizeTranscendenceAction = useCallback(
(id: string, position: number, stage: number) => {
debouncedTranscendenceAction(id, position, stage)
},
[props, previousTranscendenceStages]
)
const debouncedTranscendenceAction = useMemo(
() =>
debounce((id, position, number) => {
saveTranscendence(id, position, number)
}, 500),
[props, saveTranscendence]
)
const updateTranscendenceStage = (position: number, stage: number) => {
// console.log(`Updating uncap level at position ${position} to ${uncapLevel}`)
if (appState.grid.weapons.mainWeapon && position == -1)
appState.grid.weapons.mainWeapon.transcendence_step = stage
else {
const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) {
weapon.transcendence_step = stage
appState.grid.weapons.allWeapons[position] = weapon
}
}
}
function storePreviousTranscendenceStage(position: number) {
// Save the current value in case of an unexpected result
let newPreviousValues = { ...previousUncapValues }
if (appState.grid.weapons.mainWeapon && position == -1) {
newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncap_level
} else {
const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) {
newPreviousValues[position] = weapon.uncap_level
} else {
newPreviousValues[position] = 0
}
}
setPreviousUncapValues(newPreviousValues)
}
// Methods: Convenience // Methods: Convenience
const displayExtraContainer = const displayExtraContainer =
props.editable || props.editable ||
@ -352,6 +473,7 @@ const WeaponGrid = (props: Props) => {
removeWeapon={removeWeapon} removeWeapon={removeWeapon}
updateObject={receiveWeaponFromSearch} updateObject={receiveWeaponFromSearch}
updateUncap={initiateUncapUpdate} updateUncap={initiateUncapUpdate}
updateTranscendence={initiateTranscendenceUpdate}
/> />
) )
@ -370,6 +492,7 @@ const WeaponGrid = (props: Props) => {
removeWeapon={removeWeapon} removeWeapon={removeWeapon}
updateObject={receiveWeaponFromSearch} updateObject={receiveWeaponFromSearch}
updateUncap={initiateUncapUpdate} updateUncap={initiateUncapUpdate}
updateTranscendence={initiateTranscendenceUpdate}
/> />
</li> </li>
) )
@ -388,6 +511,7 @@ const WeaponGrid = (props: Props) => {
removeWeapon={removeWeapon} removeWeapon={removeWeapon}
updateObject={receiveWeaponFromSearch} updateObject={receiveWeaponFromSearch}
updateUncap={initiateUncapUpdate} updateUncap={initiateUncapUpdate}
updateTranscendence={initiateTranscendenceUpdate}
/> />
)} )}
</ExtraContainerItem> </ExtraContainerItem>

View file

@ -37,6 +37,7 @@ interface Props {
removeWeapon: (id: string) => void removeWeapon: (id: string) => void
updateObject: (object: SearchableObject, position: number) => void updateObject: (object: SearchableObject, position: number) => void
updateUncap: (id: string, position: number, uncap: number) => void updateUncap: (id: string, position: number, uncap: number) => void
updateTranscendence: (id: string, position: number, stage: number) => void
} }
const WeaponUnit = ({ const WeaponUnit = ({
@ -47,6 +48,7 @@ const WeaponUnit = ({
removeWeapon: sendWeaponToRemove, removeWeapon: sendWeaponToRemove,
updateObject, updateObject,
updateUncap, updateUncap,
updateTranscendence,
}: Props) => { }: Props) => {
// Translations and locale // Translations and locale
const { t } = useTranslation('common') const { t } = useTranslation('common')
@ -130,6 +132,10 @@ const WeaponUnit = ({
if (gridWeapon) updateUncap(gridWeapon.id, position, index) if (gridWeapon) updateUncap(gridWeapon.id, position, index)
} }
function passTranscendenceData(stage: number) {
if (gridWeapon) updateTranscendence(gridWeapon.id, position, stage)
}
function removeWeapon() { function removeWeapon() {
if (gridWeapon) sendWeaponToRemove(gridWeapon.id) if (gridWeapon) sendWeaponToRemove(gridWeapon.id)
setAlertOpen(false) setAlertOpen(false)
@ -559,18 +565,20 @@ const WeaponUnit = ({
<div className={classes}> <div className={classes}>
{contextMenu()} {contextMenu()}
{image()} {image()}
{gridWeapon && weapon ? ( {gridWeapon && (
<UncapIndicator <UncapIndicator
type="weapon" type="weapon"
ulb={gridWeapon.object.uncap.ulb || false} ulb={gridWeapon.object.uncap.ulb || false}
flb={gridWeapon.object.uncap.flb || false} flb={gridWeapon.object.uncap.flb || false}
transcendence={gridWeapon.object.uncap.transcendence || false}
editable={editable}
uncapLevel={gridWeapon.uncap_level} uncapLevel={gridWeapon.uncap_level}
transcendenceStage={gridWeapon.transcendence_step}
position={gridWeapon.position} position={gridWeapon.position}
updateUncap={passUncapData} updateUncap={passUncapData}
updateTranscendence={passTranscendenceData}
special={false} special={false}
/> />
) : (
''
)} )}
<h3 className={styles.name}>{weapon?.name[locale]}</h3> <h3 className={styles.name}>{weapon?.name[locale]}</h3>
</div> </div>