Training dummy leans with knockback, blast pushes, Vacuum suction and gusts
Hits tip it by their actual knockback (shared with fighters through knock_get), blasts push it, a Vacuum pulls it toward its wielder and an airblast shoves it away. Blocks stay still. Protocol 7.
This commit is contained in:
1 parent
b96defa1e6
commit
f4e7784f3c
4 files changed
+52
-13
No files matched your search
+37
-7
@@ -85,7 +85,10 @@ constexpr float WHIP_WOBBLES = 1;
|
||||
constexpr float WHIP_DAMPING = 0.02f;
|
||||
constexpr float WHIP_SAG = 0.6f;
|
||||
constexpr float WHIP_PULL = 220;
|
||||
constexpr float WOBBLE_IMPULSE = 0.15f;
|
||||
// How far a push tips a dummy: its sideways speed into lean speed for a sudden push (a hit or a blast), and its
|
||||
// sideways acceleration into lean acceleration for a steady one (a Vacuum's pull).
|
||||
constexpr float WOBBLE_PER_SPEED = 0.005f;
|
||||
constexpr float WOBBLE_PER_PULL = 0.05f;
|
||||
// Vacuum: how fast its pull speeds fighters and shots up toward it, how much of an airblast's knock is left at the edge
|
||||
// of its reach, and how much of it shoves shots.
|
||||
constexpr float VACUUM_PULL_RATE = 900;
|
||||
@@ -1607,6 +1610,14 @@ void Weapons::attack_hit(Sim& sim, Attack& attack, int target, Vec2 point)
|
||||
});
|
||||
}
|
||||
|
||||
// Tips a dummy the way a sudden push goes (a block, which never leans, ignores it), by its sideways part: a dummy
|
||||
// stands on its stand, so only its lean feels the push.
|
||||
static void dummy_push(Dummy& dummy, Vec2 push)
|
||||
{
|
||||
if (dummy.tile < 0)
|
||||
dummy.wobbleSpeed += push.x * WOBBLE_PER_SPEED;
|
||||
}
|
||||
|
||||
// Hurts a target with all the feedback: sparks, a number, shake that grows with the damage and a sound. The attacker
|
||||
// freezes in hitstop, its Boxing Glove adds to the knock, and its Embiggener to the damage.
|
||||
// Dummies flash and wobble, blocks crack and break, and fighters take the damage themselves. In a race, fighters only
|
||||
@@ -1627,7 +1638,7 @@ void Weapons::damage_deal(Sim& sim, Damage damage)
|
||||
{
|
||||
Dummy& dummy = sim.world.dummies[damage.target - MAX_FIGHTERS];
|
||||
dummy.flash = 1;
|
||||
dummy.wobbleSpeed += side * WOBBLE_IMPULSE * damage.amount;
|
||||
dummy_push(dummy, knock_get(damage, {box.x + box.w / 2, box.y + box.h / 2}));
|
||||
dummy.health -= damage.amount;
|
||||
if (dummy.tile >= 0 && dummy.health <= 0)
|
||||
sim.world.block_break(sim, dummy, damage.owner);
|
||||
@@ -2052,6 +2063,13 @@ void Weapons::blast_spawn(Sim& sim, Blast blast)
|
||||
vec2_normalize(distance > 0 ? away : Vec2{0, -1}) * KNOCKBACK_SPEED * (1 - distance / reach) * absorb;
|
||||
fighter.impulse_add(push);
|
||||
}
|
||||
for (Dummy& dummy : sim.world.dummies)
|
||||
{
|
||||
Vec2 away = Vec2{dummy.box.x + dummy.box.w / 2, dummy.box.y + dummy.box.h / 2} - blast.position;
|
||||
float distance = vec2_length(away);
|
||||
if (blast.isPushing && distance < reach)
|
||||
dummy_push(dummy, vec2_normalize(away) * KNOCKBACK_SPEED * (1 - distance / reach) * boxing);
|
||||
}
|
||||
|
||||
Attack attack = {
|
||||
.stats = {.damage = blast.damage, .range = blast.area},
|
||||
@@ -2283,6 +2301,15 @@ void Weapons::vacuum_move(Sim& sim, Attack& attack)
|
||||
float pull = std::min(room, VACUUM_PULL_RATE * boxing * TICK) * target.stat_get(STAT_KNOCKBACK_TAKEN);
|
||||
target.body.velocity = target.body.velocity + toward * pull;
|
||||
}
|
||||
for (int i = 0; i < (int)sim.world.dummies.size(); i++)
|
||||
{
|
||||
Dummy& dummy = sim.world.dummies[i];
|
||||
Vec2 center = {dummy.box.x + dummy.box.w / 2, dummy.box.y + dummy.box.h / 2};
|
||||
if (dummy.tile >= 0 || !is_target(sim, MAX_FIGHTERS + i, attack.owner) || !is_in_cone(attack, center))
|
||||
continue;
|
||||
Vec2 toward = vec2_normalize(attack.position - center);
|
||||
dummy.wobbleSpeed += toward.x * VACUUM_PULL_RATE * fighter.stat_get(STAT_KNOCKBACK) * WOBBLE_PER_PULL * TICK;
|
||||
}
|
||||
// Each interval (the hit cooldown counting it down), everyone in the cone can be nibbled again.
|
||||
float interval = fighter.level_get(attack.key).cooldown / fighter.stat_get(STAT_ATTACK_RATE);
|
||||
bool isPulse = attack.hitCooldown <= 0;
|
||||
@@ -2323,13 +2350,16 @@ void Weapons::gust_move(Sim& sim, Attack& attack)
|
||||
if (!is_target(sim, target, attack.owner) || !is_in_cone(attack, center))
|
||||
continue;
|
||||
attack_hit(sim, attack, target, center);
|
||||
if (target >= MAX_FIGHTERS)
|
||||
continue;
|
||||
// Boxing Glove adds to it as to any knock.
|
||||
Vec2 push = vec2_normalize(center - attack.position) * attack.stats.speed * cone_strength_get(attack, center) *
|
||||
sim.fighters[attack.owner].stat_get(STAT_KNOCKBACK);
|
||||
if (target >= MAX_FIGHTERS)
|
||||
{
|
||||
dummy_push(sim.world.dummies[target - MAX_FIGHTERS], push);
|
||||
continue;
|
||||
}
|
||||
Fighter& fighter = sim.fighters[target];
|
||||
float strength = attack.stats.speed * cone_strength_get(attack, center) *
|
||||
fighter.stat_get(STAT_KNOCKBACK_TAKEN) * sim.fighters[attack.owner].stat_get(STAT_KNOCKBACK);
|
||||
fighter.knock_take(vec2_normalize(center - attack.position) * strength, attack.owner);
|
||||
fighter.knock_take(push * fighter.stat_get(STAT_KNOCKBACK_TAKEN), attack.owner);
|
||||
}
|
||||
shots_drift(sim, attack, attack.stats.speed * GUST_SHOT_SHARE, 0, attack.isCopy ? 0 : GUST_RESTORE);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user