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
202 changes: 108 additions & 94 deletions packages/client/src/components/ActionsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { useMovement } from '../contexts/MovementContext';
import { EncounterType } from '../utils/types';

export const ActionsPanel = (): JSX.Element => {
const { character, equippedWeapons } = useCharacter();
const { character, equippedSpells, equippedWeapons } = useCharacter();
const { isSpawned, monstersOnTile, position } = useMap();
const {
attackOutcomes,
Expand Down Expand Up @@ -149,105 +149,119 @@ export const ActionsPanel = (): JSX.Element => {
return false;
}, [currentBattle, userTurn, turnTimeLeft]);

const equippedSpellsAndWeapons = useMemo(
() => [...equippedSpells, ...equippedWeapons],
[equippedSpells, equippedWeapons],
);

return (
<Box maxH="100%" overflowY="auto" pb={4} ref={parentDivRef}>
{!battleOver && currentBattle && equippedWeapons && opponent && (
<VStack bgColor="white" position="sticky" spacing={0} top={0} w="100%">
{currentBattle.encounterType === EncounterType.PvE && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
<Text as="span" fontWeight="bold">
Choose your move!
{!battleOver &&
currentBattle &&
equippedSpellsAndWeapons.length !== 0 &&
opponent && (
<VStack
bgColor="white"
position="sticky"
spacing={0}
top={0}
w="100%"
>
{currentBattle.encounterType === EncounterType.PvE && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
<Text as="span" fontWeight="bold">
Choose your move!
</Text>
</Text>
</Text>
)}
)}

{currentBattle.encounterType === EncounterType.PvP && (
<>
{userTurn && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
<Text as="span" fontWeight="bold">
Choose your move!
</Text>{' '}
You have {turnTimeLeft} seconds before your opponent can
attack.
</Text>
)}
{!userTurn && !canAttack && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
It is your opponent&apos;s turn. But you can attack in{' '}
{turnTimeLeft} seconds.
</Text>
)}
{!userTurn && canAttack && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
Your opponent took too long to make a move.{' '}
<Text as="span" fontWeight={700}>
You can now attack!
</Text>
</Text>
)}
{equippedWeapons.length === 0 && (
<Text color="red" fontWeight={700} p={{ base: 2, lg: 4 }}>
You have no equipped items. In order to attack, you must go to
your{' '}
<Text
as={Link}
color="blue"
to={`/characters/${character?.id}`}
_hover={{ textDecoration: 'underline' }}
>
character page
</Text>{' '}
and equip at least 1 item.
</Text>
)}
</>
)}
<HStack position="relative" spacing={0} w="100%">
{currentBattle.encounterType === EncounterType.PvP && (
<Progress
position="absolute"
size="xs"
top={-1}
value={(turnTimeLeft / 32) * 100}
variant="timer"
w="100%"
/>
<>
{userTurn && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
<Text as="span" fontWeight="bold">
Choose your move!
</Text>{' '}
You have {turnTimeLeft} seconds before your opponent can
attack.
</Text>
)}
{!userTurn && !canAttack && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
It is your opponent&apos;s turn. But you can attack in{' '}
{turnTimeLeft} seconds.
</Text>
)}
{!userTurn && canAttack && (
<Text p={{ base: 2, lg: 4 }} size="xs" textAlign="center">
Your opponent took too long to make a move.{' '}
<Text as="span" fontWeight={700}>
You can now attack!
</Text>
</Text>
)}
{equippedSpellsAndWeapons.length === 0 && (
<Text color="red" fontWeight={700} p={{ base: 2, lg: 4 }}>
You have no equipped items. In order to attack, you must go
to your{' '}
<Text
as={Link}
color="blue"
to={`/characters/${character?.id}`}
_hover={{ textDecoration: 'underline' }}
>
character page
</Text>{' '}
and equip at least 1 item.
</Text>
)}
</>
)}
{equippedWeapons.map((item, index) => (
<Button
borderLeft={index === 0 ? 'none' : '2px'}
borderRadius={0}
borderRight={
index === 0 || index === equippedWeapons.length - 1
? 'none'
: '2px'
}
isDisabled={attackingItemId !== null || !canAttack}
isLoading={attackingItemId === item.tokenId}
key={`equipped-item-${index}`}
loadingText="Attacking..."
onClick={() =>
onAttack(
item.tokenId,
userTurn ||
currentBattle.encounterType === EncounterType.PvE
? currentBattle.currentTurn
: (
BigInt(currentBattle.currentTurn) + BigInt(1)
).toString(),
)
}
ref={index === 0 ? attackButton1Ref : attackButton2Ref}
variant="outline"
w="100%"
>
{item.name}
</Button>
))}
</HStack>
</VStack>
)}
<HStack position="relative" spacing={0} w="100%">
{currentBattle.encounterType === EncounterType.PvP && (
<Progress
position="absolute"
size="xs"
top={-1}
value={(turnTimeLeft / 32) * 100}
variant="timer"
w="100%"
/>
)}
{equippedSpellsAndWeapons.map((item, index) => (
<Button
borderLeft={index === 0 ? 'none' : '2px'}
borderRadius={0}
borderRight={
index === 0 || index === equippedSpellsAndWeapons.length - 1
? 'none'
: '2px'
}
isDisabled={attackingItemId !== null || !canAttack}
isLoading={attackingItemId === item.tokenId}
key={`equipped-item-${index}`}
loadingText="Attacking..."
onClick={() =>
onAttack(
item.tokenId,
userTurn ||
currentBattle.encounterType === EncounterType.PvE
? currentBattle.currentTurn
: (
BigInt(currentBattle.currentTurn) + BigInt(1)
).toString(),
)
}
ref={index === 0 ? attackButton1Ref : attackButton2Ref}
variant="outline"
w="100%"
>
{item.name}
</Button>
))}
</HStack>
</VStack>
)}
<Stack p={{ base: 2, lg: 4 }}>
{!currentBattle && !(isSpawned && position) && (
<Typist
Expand Down
26 changes: 16 additions & 10 deletions packages/client/src/components/AuctionRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ import { useNavigate } from 'react-router-dom';

import { ITEM_PATH } from '../Routes';
import { removeEmoji } from '../utils/helpers';
import { type ArmorTemplate, type WeaponTemplate } from '../utils/types';
import {
type ArmorTemplate,
ItemType,
type SpellTemplate,
type WeaponTemplate,
} from '../utils/types';

export const AuctionRow = ({
name,
agiModifier,
hpModifier,
intModifier,
minLevel,
strModifier,
emoji,
tokenId,
floor,
}: (ArmorTemplate | WeaponTemplate) & {
...item
}: (ArmorTemplate | SpellTemplate | WeaponTemplate) & {
emoji: string;
floor: string;
}): JSX.Element => {
Expand Down Expand Up @@ -63,10 +65,14 @@ export const AuctionRow = ({
<HStack w="100%">
<Text size={{ base: '2xs', lg: 'sm' }}>{removeEmoji(name)}</Text>
</HStack>
<Text size={{ base: '3xs', sm: '2xs', lg: 'sm' }}>
HP {hpModifier} • STR {strModifier} • AGI {agiModifier} • INT{' '}
{intModifier}
</Text>
{item.itemType !== ItemType.Spell && (
<Text size={{ base: '3xs', sm: '2xs', lg: 'sm' }}>
HP {(item as ArmorTemplate | WeaponTemplate).hpModifier} • STR{' '}
{(item as ArmorTemplate | WeaponTemplate).strModifier} • AGI{' '}
{(item as ArmorTemplate | WeaponTemplate).agiModifier} • INT{' '}
{(item as ArmorTemplate | WeaponTemplate).intModifier}
</Text>
)}
</VStack>
</Flex>
<HStack>
Expand Down
Loading