refactor: enhance action handling and introduce ActionResourceButton component
This commit is contained in:
parent
a85a80938b
commit
6e3b86df24
63
src/components/ActionResourceButton.tsx
Normal file
63
src/components/ActionResourceButton.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { LucideIcon } from 'lucide-react';
|
||||||
|
import { Pet, Resources } from '../types/Pet';
|
||||||
|
import { isActionActive, formatResourceName, getResourceFromAction } from '../utils/petUtils';
|
||||||
|
|
||||||
|
const colorClassMap = {
|
||||||
|
amber: 'bg-amber-900/30 hover:bg-amber-800/50 border-amber-500/50',
|
||||||
|
emerald: 'bg-emerald-900/30 hover:bg-emerald-800/50 border-emerald-500/50',
|
||||||
|
red: 'bg-red-900/30 hover:bg-red-800/50 border-red-500/50',
|
||||||
|
green: 'bg-green-900/30 hover:bg-green-800/50 border-green-500/50',
|
||||||
|
blue: 'bg-blue-900/30 hover:bg-blue-800/50 border-blue-500/50',
|
||||||
|
purple: 'bg-purple-900/30 hover:bg-purple-800/50 border-purple-500/50',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const getActionVerb = (actionType: 'gather' | 'explore' | 'battle'): string => {
|
||||||
|
const verbs = {
|
||||||
|
gather: 'Gathering',
|
||||||
|
explore: 'Exploring',
|
||||||
|
battle: 'Battling',
|
||||||
|
};
|
||||||
|
return verbs[actionType];
|
||||||
|
};
|
||||||
|
|
||||||
|
type ButtonColor = keyof typeof colorClassMap;
|
||||||
|
|
||||||
|
interface ActionResourceButtonProps {
|
||||||
|
pet: Pet;
|
||||||
|
icon: LucideIcon;
|
||||||
|
label: string;
|
||||||
|
actionType: 'gather' | 'explore' | 'battle';
|
||||||
|
color: ButtonColor;
|
||||||
|
onActionClick: () => void;
|
||||||
|
onActionComplete: (updatedPet: Pet) => void;
|
||||||
|
onResourcesUpdate: (resources: Resources) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ActionResourceButton({
|
||||||
|
pet,
|
||||||
|
icon: Icon,
|
||||||
|
label,
|
||||||
|
actionType,
|
||||||
|
color,
|
||||||
|
onActionClick
|
||||||
|
}: ActionResourceButtonProps) {
|
||||||
|
const isActive = isActionActive(pet.petGatherAction, actionType);
|
||||||
|
const currentResource = getResourceFromAction(pet.petGatherAction);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={onActionClick}
|
||||||
|
className={`flex items-center justify-center space-x-2
|
||||||
|
${colorClassMap[color]}
|
||||||
|
border-2 rounded-lg p-4
|
||||||
|
transition-all duration-300 transform hover:scale-105 w-full`}
|
||||||
|
>
|
||||||
|
<Icon className="w-6 h-6" />
|
||||||
|
<span>
|
||||||
|
{isActive && currentResource
|
||||||
|
? `${getActionVerb(actionType)} ${formatResourceName(currentResource)}`
|
||||||
|
: label}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
@ -1,117 +0,0 @@
|
|||||||
import { useState, useEffect } from 'react';
|
|
||||||
import { FeatherIcon as GatherIcon } from 'lucide-react';
|
|
||||||
import ResourceSelectionModal from './modal/ResourceSelectionModal';
|
|
||||||
import { Pet, Resources } from '../types/Pet';
|
|
||||||
import { updatePetAction, getPetGatheredResources } from '../services/api/api';
|
|
||||||
import { PetGatherAction } from '../types/PetUpdateActionRequest';
|
|
||||||
import { isGatheringAction, formatResourceName, getResourceFromAction } from '../utils/petUtils';
|
|
||||||
|
|
||||||
interface GatherResourcesButtonProps {
|
|
||||||
pet: Pet;
|
|
||||||
onGatherStart: () => void;
|
|
||||||
onGatherComplete: (updatedPet: Pet) => void;
|
|
||||||
onResourcesUpdate: (resources: Resources) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resourceToActionMap: Record<string, PetGatherAction> = {
|
|
||||||
wisdom: 'GATHERING_WISDOM',
|
|
||||||
gold: 'GATHERING_GOLD',
|
|
||||||
food: 'GATHERING_FOOD'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function GatherResourcesButton({ pet, onGatherStart, onGatherComplete, onResourcesUpdate }: GatherResourcesButtonProps) {
|
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
||||||
const [isGathering, setIsGathering] = useState(isGatheringAction(pet.petGatherAction));
|
|
||||||
|
|
||||||
// Initialize gathering check if pet is already gathering
|
|
||||||
useEffect(() => {
|
|
||||||
if (isGatheringAction(pet.petGatherAction)) {
|
|
||||||
setIsGathering(true);
|
|
||||||
getPetGatheredResources(pet.id).then(resources => {
|
|
||||||
onResourcesUpdate(resources);
|
|
||||||
});
|
|
||||||
onGatherStart();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let interval: number;
|
|
||||||
|
|
||||||
if (isGathering) {
|
|
||||||
interval = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
const resources = await getPetGatheredResources(pet.id);
|
|
||||||
onResourcesUpdate(resources);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to check gathered resources:', error);
|
|
||||||
}
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (interval) {
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [isGathering, pet.id]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsGathering(isGatheringAction(pet.petGatherAction));
|
|
||||||
}, [pet.petGatherAction]);
|
|
||||||
|
|
||||||
const handleGatherStart = async (resourceType: string) => {
|
|
||||||
if (resourceType === 'stop') {
|
|
||||||
try {
|
|
||||||
await updatePetAction(pet.id, { gatherAction: 'IDLE' });
|
|
||||||
setIsGathering(false);
|
|
||||||
onGatherComplete(pet);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to stop gathering:', error);
|
|
||||||
}
|
|
||||||
setIsModalOpen(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsGathering(true);
|
|
||||||
onGatherStart();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const petAction = resourceToActionMap[resourceType];
|
|
||||||
const updatedPet = await updatePetAction(pet.id, { gatherAction: petAction });
|
|
||||||
onGatherComplete(updatedPet);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to gather resources:', error);
|
|
||||||
} finally {
|
|
||||||
setIsModalOpen(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const currentResource = getResourceFromAction(pet.petGatherAction);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => setIsModalOpen(true)}
|
|
||||||
className={`flex items-center justify-center space-x-2
|
|
||||||
bg-amber-900/30 hover:bg-amber-800/50
|
|
||||||
border-2 border-amber-500/50 rounded-lg p-4
|
|
||||||
transition-all duration-300 transform hover:scale-105 w-full`}
|
|
||||||
>
|
|
||||||
<GatherIcon className="w-6 h-6" />
|
|
||||||
<span>
|
|
||||||
{isGathering && currentResource
|
|
||||||
? `Gathering ${formatResourceName(currentResource)}...`
|
|
||||||
: 'Gather Resources'}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ResourceSelectionModal
|
|
||||||
isOpen={isModalOpen}
|
|
||||||
onClose={() => setIsModalOpen(false)}
|
|
||||||
onGather={handleGatherStart}
|
|
||||||
pet={pet}
|
|
||||||
isGathering={isGathering}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,11 +1,13 @@
|
|||||||
import { Pizza, PlayCircle, Moon } from 'lucide-react';
|
import { Pizza, PlayCircle, Moon, Compass, Sword, FeatherIcon } from 'lucide-react';
|
||||||
import GatherResourcesButton from './GatherResourcesButton';
|
|
||||||
import CollectResourcesButton from './CollectResourcesButton';
|
import CollectResourcesButton from './CollectResourcesButton';
|
||||||
import { Pet, Resources } from '../types/Pet';
|
import { Pet, Resources } from '../types/Pet';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { updatePetAction } from '../services/api/api';
|
import { updatePetAction, getPetGatheredResources } from '../services/api/api';
|
||||||
import { PetBasicAction } from '../types/PetUpdateActionRequest';
|
import { PetBasicAction } from '../types/PetUpdateActionRequest';
|
||||||
import ActionButton from './button/ActionButton';
|
import ActionButton from './button/ActionButton';
|
||||||
|
import ActionResourceButton from './ActionResourceButton';
|
||||||
|
import ResourceSelectionModal from './modal/ResourceSelectionModal';
|
||||||
|
import { PetAction } from '../types/PetUpdateActionRequest';
|
||||||
|
|
||||||
interface InteractionMenuProps {
|
interface InteractionMenuProps {
|
||||||
pet: Pet;
|
pet: Pet;
|
||||||
@ -16,6 +18,8 @@ interface InteractionMenuProps {
|
|||||||
export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuProps) {
|
export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuProps) {
|
||||||
const [gatheredResources, setGatheredResources] = useState<Resources>({ wisdom: 0, gold: 0, food: 0, junk: 0 });
|
const [gatheredResources, setGatheredResources] = useState<Resources>({ wisdom: 0, gold: 0, food: 0, junk: 0 });
|
||||||
const [remainingCooldown, setRemainingCooldown] = useState<number | null>(null);
|
const [remainingCooldown, setRemainingCooldown] = useState<number | null>(null);
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [selectedActionType, setSelectedActionType] = useState<'gather' | 'explore' | 'battle' | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateCooldown = () => {
|
const updateCooldown = () => {
|
||||||
@ -40,6 +44,26 @@ export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuPro
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [pet.basicActionCooldown]);
|
}, [pet.basicActionCooldown]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchGatheredResources = async () => {
|
||||||
|
if (pet.petGatherAction === 'IDLE') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resources = await getPetGatheredResources(pet.id);
|
||||||
|
setGatheredResources(resources);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch gathered resources:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchGatheredResources();
|
||||||
|
const interval = setInterval(fetchGatheredResources, 10000); // Poll every 10 seconds
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [pet.id, pet.petGatherAction]);
|
||||||
|
|
||||||
const formatCooldownTime = (ms: number) => {
|
const formatCooldownTime = (ms: number) => {
|
||||||
const minutes = Math.floor(ms / 60000);
|
const minutes = Math.floor(ms / 60000);
|
||||||
const seconds = Math.floor((ms % 60000) / 1000);
|
const seconds = Math.floor((ms % 60000) / 1000);
|
||||||
@ -73,6 +97,45 @@ export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuPro
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleActionStart = async (actionType: 'gather' | 'explore' | 'battle') => {
|
||||||
|
if (actionType === 'gather') {
|
||||||
|
setSelectedActionType(actionType);
|
||||||
|
setIsModalOpen(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const action: PetAction = actionType === 'explore' ? 'EXPLORING' : 'BATTLE';
|
||||||
|
const updatedPet = await updatePetAction(pet.id, { gatherAction: action });
|
||||||
|
onPetUpdate(updatedPet);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to start action:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResourceSelect = async (resourceType: string) => {
|
||||||
|
if (resourceType === 'stop') {
|
||||||
|
try {
|
||||||
|
const updatedPet = await updatePetAction(pet.id, { gatherAction: 'IDLE' });
|
||||||
|
onPetUpdate(updatedPet);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to stop action:', error);
|
||||||
|
}
|
||||||
|
setIsModalOpen(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const action: PetAction = `GATHERING_${resourceType.toUpperCase()}` as PetAction;
|
||||||
|
const updatedPet = await updatePetAction(pet.id, { gatherAction: action });
|
||||||
|
onPetUpdate(updatedPet);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to start gathering:', error);
|
||||||
|
} finally {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
{remainingCooldown !== null && (
|
{remainingCooldown !== null && (
|
||||||
@ -103,19 +166,54 @@ export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuPro
|
|||||||
disabled={remainingCooldown !== null}
|
disabled={remainingCooldown !== null}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="col-span-2 md:col-span-3">
|
<div className="col-span-2 md:col-span-3 grid grid-cols-3 gap-4">
|
||||||
<GatherResourcesButton
|
<ActionResourceButton
|
||||||
pet={pet}
|
pet={pet}
|
||||||
onGatherStart={() => console.log('Gathering started')}
|
icon={FeatherIcon}
|
||||||
onGatherComplete={handleGatherComplete}
|
label="Gather"
|
||||||
|
actionType="gather"
|
||||||
|
color="amber"
|
||||||
|
onActionClick={() => handleActionStart('gather')}
|
||||||
|
onActionComplete={handleGatherComplete}
|
||||||
onResourcesUpdate={handleResourcesUpdate}
|
onResourcesUpdate={handleResourcesUpdate}
|
||||||
/>
|
/>
|
||||||
|
<ActionResourceButton
|
||||||
|
pet={pet}
|
||||||
|
icon={Compass}
|
||||||
|
label="Explore"
|
||||||
|
actionType="explore"
|
||||||
|
color="emerald"
|
||||||
|
onActionClick={() => handleActionStart('explore')}
|
||||||
|
onActionComplete={handleGatherComplete}
|
||||||
|
onResourcesUpdate={handleResourcesUpdate}
|
||||||
|
/>
|
||||||
|
<ActionResourceButton
|
||||||
|
pet={pet}
|
||||||
|
icon={Sword}
|
||||||
|
label="Battle"
|
||||||
|
actionType="battle"
|
||||||
|
color="red"
|
||||||
|
onActionClick={() => handleActionStart('battle')}
|
||||||
|
onActionComplete={handleGatherComplete}
|
||||||
|
onResourcesUpdate={handleResourcesUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-span-2 md:col-span-3">
|
||||||
<CollectResourcesButton
|
<CollectResourcesButton
|
||||||
petId={pet.id}
|
petId={pet.id}
|
||||||
resources={gatheredResources}
|
resources={gatheredResources}
|
||||||
onCollect={handleCollect}
|
onCollect={handleCollect}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ResourceSelectionModal
|
||||||
|
isOpen={isModalOpen}
|
||||||
|
onClose={() => setIsModalOpen(false)}
|
||||||
|
onGather={handleResourceSelect}
|
||||||
|
pet={pet}
|
||||||
|
isGathering={pet.petGatherAction !== 'IDLE'}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { Pet } from '../types/Pet';
|
import { Pet } from '../types/Pet';
|
||||||
import { Brain, Dumbbell, Heart, Sparkles, Coins, Pizza, Trash2 } from 'lucide-react';
|
import { Brain, Dumbbell, Heart, Sparkles, Coins, Pizza, Trash2, Trophy } from 'lucide-react';
|
||||||
import { PET_CLASSES } from '../data/petClasses';
|
import { PET_CLASSES } from '../data/petClasses';
|
||||||
|
|
||||||
interface PetDisplayProps {
|
interface PetDisplayProps {
|
||||||
@ -7,16 +7,16 @@ interface PetDisplayProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function PetDisplay({ pet }: PetDisplayProps) {
|
export default function PetDisplay({ pet }: PetDisplayProps) {
|
||||||
const StatBar = ({ value, label, icon: Icon }: { value: number; label: string; icon: any }) => (
|
const StatBar = ({ value, maxValue, label, icon: Icon }: { value: number; maxValue: number; label: string; icon: any }) => (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Icon className="w-5 h-5" />
|
<Icon className="w-5 h-5" />
|
||||||
<div className="flex-1 bg-gray-700 rounded-full h-4">
|
<div className="flex-1 bg-gray-700 rounded-full h-4">
|
||||||
<div
|
<div
|
||||||
className="bg-blue-500 rounded-full h-4"
|
className="bg-blue-500 rounded-full h-4"
|
||||||
style={{ width: `${value}%` }}
|
style={{ width: `${(value / maxValue) * 100}%` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm">{value}%</span>
|
<span className="text-sm font-medium">{value}/{maxValue}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -29,19 +29,42 @@ export default function PetDisplay({ pet }: PetDisplayProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 p-6 rounded-xl">
|
<div className="bg-gray-900 p-6 rounded-xl shadow-xl">
|
||||||
<div className="text-center mb-8">
|
<div className="text-center mb-8">
|
||||||
<div className="text-8xl mb-4">{PET_CLASSES[pet.class].emoji}</div>
|
<div className="text-8xl mb-4">{PET_CLASSES[pet.class].emoji}</div>
|
||||||
<h2 className="text-2xl font-bold">{pet.name}</h2>
|
<h2 className="text-2xl font-bold mb-2">
|
||||||
|
<span className="bg-gradient-to-r from-blue-500 to-purple-500 text-transparent bg-clip-text">
|
||||||
|
{pet.name}
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<div className="flex items-center justify-center gap-2 mb-2">
|
||||||
|
<Trophy className="w-5 h-5 text-yellow-500" />
|
||||||
|
<span className="text-lg font-semibold">Level {pet.level}</span>
|
||||||
|
</div>
|
||||||
<p className={`text-${PET_CLASSES[pet.class].color}-400`}>
|
<p className={`text-${PET_CLASSES[pet.class].color}-400`}>
|
||||||
{PET_CLASSES[pet.class].name}
|
{PET_CLASSES[pet.class].name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4 mb-6">
|
<div className="space-y-4 mb-6">
|
||||||
<StatBar value={pet.stats.intelligence} label="Intelligence" icon={Brain} />
|
<StatBar
|
||||||
<StatBar value={pet.stats.strength} label="Strength" icon={Dumbbell} />
|
value={pet.stats.intelligence}
|
||||||
<StatBar value={pet.stats.charisma} label="Charisma" icon={Heart} />
|
maxValue={pet.stats.maxIntelligence}
|
||||||
|
label="Intelligence"
|
||||||
|
icon={Brain}
|
||||||
|
/>
|
||||||
|
<StatBar
|
||||||
|
value={pet.stats.strength}
|
||||||
|
maxValue={pet.stats.maxStrength}
|
||||||
|
label="Strength"
|
||||||
|
icon={Dumbbell}
|
||||||
|
/>
|
||||||
|
<StatBar
|
||||||
|
value={pet.stats.charisma}
|
||||||
|
maxValue={pet.stats.maxCharisma}
|
||||||
|
label="Charisma"
|
||||||
|
icon={Heart}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
@ -4,11 +4,31 @@ export function isGatheringAction(action: PetGatherAction): boolean {
|
|||||||
return action.startsWith('GATHERING_');
|
return action.startsWith('GATHERING_');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getResourceFromAction(action: PetGatherAction): string | null {
|
export function getResourceFromAction(action: string): string | null {
|
||||||
if (!isGatheringAction(action)) return null;
|
if (!action) return null;
|
||||||
return action.replace('GATHERING_', '').toLowerCase();
|
|
||||||
|
const patterns = ['GATHERING_', 'EXPLORING_', 'BATTLE_'];
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (action.startsWith(pattern)) {
|
||||||
|
return action.replace(pattern, '').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatResourceName(resource: string): string {
|
export function formatResourceName(resource: string): string {
|
||||||
return resource.charAt(0).toUpperCase() + resource.slice(1);
|
return resource.charAt(0).toUpperCase() + resource.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isActionActive(action: string, actionType: string): boolean {
|
||||||
|
if (!action) return false;
|
||||||
|
|
||||||
|
const actionMap = {
|
||||||
|
'gather': 'GATHERING_',
|
||||||
|
'explore': 'EXPLORING_',
|
||||||
|
'battle': 'BATTLE_'
|
||||||
|
};
|
||||||
|
|
||||||
|
return action.startsWith(actionMap[actionType] || '');
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user