1
0
forked from mico/idle_moloch
idle_moloch/app/src/components/MarchingBand.tsx

116 lines
2.8 KiB
TypeScript

import { useCallback, useEffect, useMemo, useState } from 'react';
import styles from '../styles/Army.module.css';
interface MarchingGroupType {
id: number,
people: [number, number][]
removeGroup: (id: number) => void
}
const MarchingGroup = ({ people, id, removeGroup }: MarchingGroupType) => {
useEffect(() => {
const destroyTimeout = setTimeout(() => {
removeGroup(id)
}, 18000);
return () => clearTimeout(destroyTimeout)
}, [id, removeGroup])
const groupHtml = useMemo(() => {
return <div className={`${styles.marchingGroup}`}>
{people.map(([personStatus, role], index) => {
const cssRole = intToRole(role);
const cssStatus = intToStatus(personStatus);
return <div key={id + index} className={`${styles.person} ${cssRole} ${cssStatus}`} />
})}
</div >
}, [people, id])
return groupHtml
}
const MarchingBand = () => {
const [groups, setGroups] = useState<MarchingGroupType[]>([]);
const removeGroup = useCallback((id: number) => {
setGroups(p => p.filter(p => p.id !== id));
}, [setGroups])
const addGroup = useCallback(() => {
const nPeople = getRandomInt(2, 4);
const people: [number, number][] = []
for (let i = 0; i < nPeople; i++) {
people.push([getRandomInt(0, 3), getRandomInt(0, 14)])
}
setGroups(g => [...g, { id: Math.random(), people, removeGroup }]);
}, [removeGroup])
useEffect(() => {
const addingInterval = setInterval(() => {
addGroup()
}, 8000)
return () => clearInterval(addingInterval)
}, [addGroup])
return <div className={styles.marchingBand}>
{groups.map(({ id, people }) =>
<MarchingGroup
key={id}
id={id}
people={people}
removeGroup={removeGroup}
/>)}
</div>
}
const getRandomInt = (min: number, max: number) => Math.floor(Math.random() * (max + 1 - min) + min)
const intToRole = (val: number) => {
switch (val) {
case 0:
return styles.alchemist
case 1:
return styles.archer
case 2:
return styles.cleric
case 3:
return styles.druid
case 4:
return styles.dwarf
case 5:
return styles.monk
case 6:
return styles.necromancer
case 7:
return styles.paladin
case 8:
return styles.ranger
case 9:
return styles.rogue
case 10:
return styles.scribe
case 11:
return styles.warrior
case 12:
return styles.wizard
case 13:
return styles.healer
case 14:
return styles.hunter
default:
return styles.wizard
}
}
const intToStatus = (val: number) => {
switch (val) {
case 0:
return styles.moloch_denier;
case 1:
return styles.apprentice;
case 2:
return styles.anointed;
case 3:
return styles.champion;
default:
return styles.moloch_denier;
}
}
export default MarchingBand