Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions packages/client/src/components/ActionsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ export const ActionsPanel = (): JSX.Element => {
} = useCharacter();
const {
actionOutcomes,
aliveMonsters,
currentBattle,
isAttacking,
isRefreshing: isRefreshingMap,
isSpawned,
monsterOponent,
monsters,
onAttack,
position,
} = useMapNavigation();
Expand Down Expand Up @@ -106,7 +106,7 @@ export const ActionsPanel = (): JSX.Element => {
);
}

if ((position.x !== 0 || position.y !== 0) && monsters.length === 0) {
if ((position.x !== 0 || position.y !== 0) && aliveMonsters.length === 0) {
return (
<Typist
avgTypingDelay={10}
Expand All @@ -124,7 +124,7 @@ export const ActionsPanel = (): JSX.Element => {
);
}

if ((position.x !== 0 || position.y !== 0) && monsters.length > 0) {
if ((position.x !== 0 || position.y !== 0) && aliveMonsters.length > 0) {
return (
<Typist
avgTypingDelay={10}
Expand All @@ -143,7 +143,13 @@ export const ActionsPanel = (): JSX.Element => {
}

return '';
}, [isRefreshingCharacter, isRefreshingMap, isSpawned, monsters, position]);
}, [
aliveMonsters,
isRefreshingCharacter,
isRefreshingMap,
isSpawned,
position,
]);

return (
<>
Expand Down
116 changes: 116 additions & 0 deletions packages/client/src/components/BattleOutcomeModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import {
Box,
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
VStack,
} from '@chakra-ui/react';
import { useCallback, useMemo } from 'react';

import { useCharacter } from '../contexts/CharacterContext';
import { useMapNavigation } from '../contexts/MapNavigationContext';
import { BATTLE_OUTCOME_SEEN_KEY } from '../utils/constants';
import { type CombatOutcomeType } from '../utils/types';

type BattleOutcomeModalProps = {
isOpen: boolean;
onClose: () => void;
battleOutcome: CombatOutcomeType;
};

export const BattleOutcomeModal: React.FC<BattleOutcomeModalProps> = ({
isOpen,
onClose,
battleOutcome,
}): JSX.Element => {
const { character } = useCharacter();
const { allMonsters, otherPlayers } = useMapNavigation();

const opponent = useMemo(() => {
if (!character) return null;
const opponent =
character.characterId === battleOutcome.defenders[0]
? battleOutcome.attackers[0]
: battleOutcome.defenders[0];

const monsterOpponent = allMonsters.find(
monster => monster.monsterId === opponent,
);
if (monsterOpponent) {
return monsterOpponent;
}

const characterOpponent = otherPlayers.find(
player => player.characterId === opponent,
);
if (characterOpponent) {
return characterOpponent;
}

return null;
}, [allMonsters, battleOutcome, character, otherPlayers]);

const onAcknowledge = useCallback(() => {
localStorage.setItem(BATTLE_OUTCOME_SEEN_KEY, battleOutcome.encounterId);
onClose();
}, [battleOutcome.encounterId, onClose]);

if (!character) {
return <Box />;
}

const { expDropped, goldDropped, itemsDropped, winner } = battleOutcome;

return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center">
{winner === character.characterId ? 'Victory!' : 'Defeat...'}
</ModalHeader>
<ModalCloseButton />
<ModalBody p={4}>
<VStack alignItems="center" pb={8} spacing={4}>
<Text>
{winner === character.characterId
? `You defeated ${opponent?.name}!`
: `You lost to ${opponent?.name}.`}
</Text>
{winner === character.characterId && (
<Text textAlign="center">
You earned{' '}
<Text as="span" color="green" fontWeight="bold">
{expDropped}
</Text>{' '}
experience and{' '}
<Text as="span" color="gold" fontWeight="bold">
{Number(goldDropped).toLocaleString()}
</Text>{' '}
$GOLD.
</Text>
)}
{itemsDropped.length > 0 && (
<Text>
You looted the following items:
<ul>
{itemsDropped.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</Text>
)}
</VStack>
</ModalBody>
<ModalFooter>
<Button onClick={onAcknowledge}>Continue</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};
2 changes: 1 addition & 1 deletion packages/client/src/components/ItemEquipModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export const ItemEquipModal: React.FC<ItemEquipModalProps> = ({
<ModalContent>
<ModalHeader>{isOwner ? 'Equip Item' : 'Make an offer'}</ModalHeader>
<ModalCloseButton />
<ModalBody padding={4}>
<ModalBody p={4}>
{isOwner ? (
<Text mb={6}>Do you want to equip this item?</Text>
) : (
Expand Down
8 changes: 4 additions & 4 deletions packages/client/src/components/TileDetailsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ export const TileDetailsPanel = (): JSX.Element => {
} = useMUD();
const { character } = useCharacter();
const {
aliveMonsters,
actionOutcomes,
currentBattle,
isRefreshing,
monsterOponent,
monsters,
otherPlayers,
} = useMapNavigation();

Expand Down Expand Up @@ -239,8 +239,8 @@ export const TileDetailsPanel = (): JSX.Element => {
</Grid>
<Grid gap={5} mt={1} templateColumns="repeat(4, 1fr)">
<GridItem colSpan={2}>
{monsters.length > 0 &&
monsters.map((monster, i) => (
{aliveMonsters.length > 0 &&
aliveMonsters.map((monster, i) => (
<MonsterRow
key={`tile-monster-${i}-${monster.name}`}
monster={monster}
Expand All @@ -249,7 +249,7 @@ export const TileDetailsPanel = (): JSX.Element => {
}}
/>
))}
{monsters.length === 0 && (
{aliveMonsters.length === 0 && (
<Text size={{ base: '2xs', lg: 'sm' }}>
No monsters in this area
</Text>
Expand Down
Loading