204 lines
5.4 KiB
TypeScript
204 lines
5.4 KiB
TypeScript
import {
|
|
EggbugEmotion,
|
|
EggbugImg,
|
|
HCenter,
|
|
Main,
|
|
render_and_copy,
|
|
} from "./common.tsx";
|
|
|
|
const Eggbug = ({ type = "smiling" }: { type?: EggbugEmotion }) => (
|
|
<HCenter>
|
|
<EggbugImg type={type} />
|
|
</HCenter>
|
|
);
|
|
|
|
function health_style(current: number, last: number, max: number) {
|
|
const inc_width = 100 / max;
|
|
const dhealth = last - current;
|
|
console.log(inc_width, dhealth);
|
|
|
|
return {
|
|
transform: `translateX(${-(inc_width * dhealth)}%)`,
|
|
width: `${last * inc_width}%`,
|
|
};
|
|
}
|
|
|
|
// could be generalized
|
|
// might be worthwhile later since <progress> is BAN
|
|
const Health = ({
|
|
current,
|
|
last,
|
|
max,
|
|
}: {
|
|
current: number;
|
|
last: number;
|
|
max: number;
|
|
}) => (
|
|
console.log({ current, last, max }),
|
|
(
|
|
<div class="health">
|
|
<div class="health-bar">
|
|
<div
|
|
class="health-full"
|
|
style={health_style(current, last, max)}
|
|
></div>
|
|
</div>
|
|
<HCenter /*class="health-numeric"*/>
|
|
<span class="health-current">
|
|
{Math.floor(current).toString()}
|
|
</span>
|
|
/<span class="health-max">{max.toString()}</span>
|
|
</HCenter>
|
|
</div>
|
|
)
|
|
);
|
|
// one-time animations of hit numbers of health flying off the screen
|
|
|
|
const BattleFrame = ({
|
|
health,
|
|
last_health,
|
|
max_health,
|
|
phase,
|
|
}: {
|
|
health: number;
|
|
last_health: number;
|
|
max_health: number;
|
|
phase: 1 | 2;
|
|
}) => (
|
|
<div class="battle-frame">
|
|
<Eggbug type={phase == 1 ? "smiling" : "revengeance"} />
|
|
<Health current={health} last={last_health} max={max_health} />
|
|
</div>
|
|
);
|
|
|
|
const Defeated = ({
|
|
last_health,
|
|
max_health,
|
|
phase,
|
|
}: {
|
|
last_health: number;
|
|
max_health: number;
|
|
phase: 1 | 2;
|
|
}) =>
|
|
phase == 1 ? (
|
|
<details class="defeated" style={{ backgroundColor: "#232233" }}>
|
|
<summary>
|
|
<Eggbug type="frowning" />
|
|
<Health current={0} last={0} max={max_health} />
|
|
eggbug is physically unharmed, emotionally destroyed <br />
|
|
... <br />
|
|
ok eggbug is fine now <br />
|
|
"re bug" to "killbug" <br />
|
|
submit runs to{" "}
|
|
<a href="https://cohost.org/rc/tagged/KILLing%20eggbug%20rapidly">
|
|
#KILLing eggbug rapidly
|
|
</a>{" "}
|
|
<br />
|
|
click again <br />
|
|
at you OWN PREIL!
|
|
</summary>
|
|
<Battle
|
|
max_health={100_000_000}
|
|
damage_multiplier={3_000_000}
|
|
damage_bonus={10_000}
|
|
phase={2}
|
|
/>
|
|
</details>
|
|
) : (
|
|
<div class="defeated" style={{ backgroundColor: "black" }}>
|
|
<Eggbug type="jpeg_annihilation" />
|
|
<br />
|
|
WHAT HAVE YOU DONE
|
|
</div>
|
|
);
|
|
|
|
const DamageNumber = ({
|
|
dmg,
|
|
max_dmg,
|
|
shl,
|
|
}: {
|
|
dmg: number;
|
|
max_dmg: number;
|
|
shl: number;
|
|
}) => (
|
|
<div
|
|
class="damage-number"
|
|
// changing this to use this much nicer styles thing helped me notice the bug awesome
|
|
// i still should really, really switch to react
|
|
// or preact!
|
|
// anything with *actual typing*
|
|
style={{
|
|
top: `${Math.floor(50 * Math.random())}%`,
|
|
left: `${Math.floor(50 * Math.random()) + 25 - shl}%`,
|
|
// tried some exponential stuff but it was too unwieldy
|
|
// i think this still accomplishes that punch
|
|
fontSize: `calc(${dmg / max_dmg} * 5rem + 0.5rem)`,
|
|
}}
|
|
>
|
|
<div class="sway">{Math.round(dmg).toString()}</div>
|
|
</div>
|
|
);
|
|
|
|
const Battle = ({
|
|
max_health = 100,
|
|
health = max_health,
|
|
last_health = health,
|
|
damage_multiplier = 10,
|
|
damage_bonus = 1,
|
|
phase = 1,
|
|
}: // ...rest
|
|
Partial<{
|
|
max_health: number;
|
|
health: number;
|
|
last_health: number;
|
|
damage_multiplier: number;
|
|
damage_bonus: number;
|
|
phase?: 1 | 2;
|
|
}>) =>
|
|
health > 0 ? (
|
|
<details class="battle" /*{...rest}*/>
|
|
<summary>
|
|
<BattleFrame
|
|
health={health}
|
|
last_health={last_health}
|
|
max_health={max_health}
|
|
phase={phase}
|
|
/>
|
|
{health < last_health && (
|
|
<DamageNumber
|
|
dmg={last_health - health}
|
|
max_dmg={damage_multiplier + damage_bonus}
|
|
// V sucks V
|
|
shl={phase == 1 ? 0 : 50}
|
|
/>
|
|
)}
|
|
</summary>
|
|
<Battle
|
|
health={
|
|
health - (damage_multiplier * Math.random() + damage_bonus)
|
|
}
|
|
last_health={health}
|
|
max_health={max_health}
|
|
damage_multiplier={damage_multiplier}
|
|
damage_bonus={damage_bonus}
|
|
phase={phase}
|
|
/>
|
|
</details>
|
|
) : (
|
|
<Defeated
|
|
last_health={last_health}
|
|
max_health={max_health}
|
|
phase={phase}
|
|
/>
|
|
);
|
|
|
|
// a timer would be flippin rad
|
|
// (it would look like an actual scrolling clock thingie)
|
|
// (because it would have to)
|
|
render_and_copy(
|
|
<Main>
|
|
<Battle max_health={10_000} damage_multiplier={300} damage_bonus={40} />
|
|
{/* <Timer /> */}
|
|
</Main>
|
|
);
|