Merge branch 'battle-tweaks-monday' into 'master'

Super Flicky intangibility, range check; Battle UFO tractor beam strength

Closes #873, #872, and #871

See merge request KartKrew/Kart!1799
This commit is contained in:
Oni 2024-01-09 00:43:50 +00:00
commit 1cf7115a97
2 changed files with 85 additions and 3 deletions

View file

@ -38,6 +38,7 @@
#define controller_mode(o) ((o)->movecount) #define controller_mode(o) ((o)->movecount)
#define controller_zofs(o) ((o)->sprzoff) #define controller_zofs(o) ((o)->sprzoff)
#define controller_expiry(o) ((o)->fuse) #define controller_expiry(o) ((o)->fuse)
#define controller_intangible(o) ((o)->threshold)
namespace namespace
{ {
@ -53,6 +54,7 @@ constexpr int kDescendHeight = 256;
constexpr int kDescendSmoothing = 16; constexpr int kDescendSmoothing = 16;
constexpr int kSearchRadius = 1920; constexpr int kSearchRadius = 1920;
constexpr int kScaredRadius = 2048;
constexpr int kFlightRadius = 1280; constexpr int kFlightRadius = 1280;
constexpr int kPeckingRadius = 256; constexpr int kPeckingRadius = 256;
@ -63,6 +65,7 @@ constexpr fixed_t kWeakSpeed = FRACUNIT/2;
constexpr fixed_t kRebound = 8*FRACUNIT/9; constexpr fixed_t kRebound = 8*FRACUNIT/9;
constexpr tic_t kDelay = 8; constexpr tic_t kDelay = 8;
constexpr tic_t kDamageCooldown = TICRATE;
constexpr tic_t kStunTime = 10*TICRATE; constexpr tic_t kStunTime = 10*TICRATE;
constexpr tic_t kBlockTime = 5*TICRATE; constexpr tic_t kBlockTime = 5*TICRATE;
@ -129,6 +132,9 @@ struct Controller : mobj_t
tic_t expiry() const { return controller_expiry(this); } tic_t expiry() const { return controller_expiry(this); }
void expiry(tic_t n) { controller_expiry(this) = n; } void expiry(tic_t n) { controller_expiry(this) = n; }
tic_t intangible() const { return controller_intangible(this); }
void intangible(tic_t n) { controller_intangible(this) = n; }
static Controller* spawn(player_t* player, tic_t time) static Controller* spawn(player_t* player, tic_t time)
{ {
Controller* x = static_cast<Controller*>(P_SpawnMobjFromMobjUnscaled( Controller* x = static_cast<Controller*>(P_SpawnMobjFromMobjUnscaled(
@ -194,6 +200,8 @@ struct Controller : mobj_t
} }
void search(); void search();
void range_check();
void collect();
}; };
struct Flicky : mobj_t struct Flicky : mobj_t
@ -412,19 +420,27 @@ struct Flicky : mobj_t
fly(Fly::kNormal); fly(Fly::kNormal);
} }
auto speed_lines = [&](angle_t dir)
{
if (dist > kPeckingRadius * mapobjectscale)
{
spawn_speed_lines(dir);
}
};
if (d > ANGLE_45 && dist > kFlightRadius * mapobjectscale) if (d > ANGLE_45 && dist > kFlightRadius * mapobjectscale)
{ {
// Cut momentum when too far outside of intended trajectory // Cut momentum when too far outside of intended trajectory
momx = FixedMul(momx, kRebound); momx = FixedMul(momx, kRebound);
momy = FixedMul(momy, kRebound); momy = FixedMul(momy, kRebound);
spawn_speed_lines(th); speed_lines(th);
fly(Fly::kSlow); fly(Fly::kSlow);
} }
else else
{ {
spawn_speed_lines(angle); speed_lines(angle);
} }
// Returning to owner // Returning to owner
@ -433,6 +449,7 @@ struct Flicky : mobj_t
if (AngleDelta(th, R_PointToAngle2(x + momx, y + momy, pos.x, pos.y)) > ANG1) if (AngleDelta(th, R_PointToAngle2(x + momx, y + momy, pos.x, pos.y)) > ANG1)
{ {
mode(Mode::kReserved); mode(Mode::kReserved);
controller()->collect();
} }
else else
{ {
@ -456,6 +473,8 @@ struct Flicky : mobj_t
break; break;
} }
} }
noclip(chasing() && dist > kFlightRadius * mapobjectscale);
} }
void rise() void rise()
@ -480,6 +499,11 @@ struct Flicky : mobj_t
return; return;
} }
if (leveltime < controller()->intangible())
{
return;
}
if (P_DamageMobj(mobj, this, source(), 1, DMG_NORMAL)) if (P_DamageMobj(mobj, this, source(), 1, DMG_NORMAL))
{ {
P_InstaThrust(mobj, K_MomentumAngleReal(this), FixedHypot(momx, momy)); P_InstaThrust(mobj, K_MomentumAngleReal(this), FixedHypot(momx, momy));
@ -490,6 +514,7 @@ struct Flicky : mobj_t
P_SetTarget(&mobj->player->flickyAttacker, this); P_SetTarget(&mobj->player->flickyAttacker, this);
controller()->mode(Controller::Mode::kAttached); controller()->mode(Controller::Mode::kAttached);
controller()->intangible(leveltime + mobj->hitlag + kDamageCooldown);
} }
S_StartSound(this, sfx_supflk); S_StartSound(this, sfx_supflk);
@ -502,6 +527,12 @@ struct Flicky : mobj_t
P_SetObjectMomZ(this, 8*FRACUNIT, false); P_SetObjectMomZ(this, 8*FRACUNIT, false);
} }
void noclip(bool n)
{
constexpr UINT32 kNoClipFlags = MF_NOCLIP | MF_NOCLIPHEIGHT;
flags = (flags & ~kNoClipFlags) | (kNoClipFlags * n);
}
void nerf() void nerf()
{ {
light_up(false); light_up(false);
@ -605,6 +636,8 @@ void Controller::search()
if (chasing() && flicky()) if (chasing() && flicky())
{ {
// Detach flicky from swarm. This one keeps its previous target. // Detach flicky from swarm. This one keeps its previous target.
// FIXME: when this one's target dies, it will
// become dormant and not return to controller.
flicky(flicky()->next()); flicky(flicky()->next());
} }
@ -620,6 +653,51 @@ void Controller::search()
} }
} }
void Controller::range_check()
{
if (!chasing())
{
return;
}
if (FixedHypot(source()->x - chasing()->x, source()->y - chasing()->y) < kScaredRadius * mapobjectscale)
{
return;
}
if (chasing()->player)
{
P_SetTarget(&chasing()->player->flickyAttacker, nullptr);
}
chasing(nullptr);
mode(Mode::kReturning);
for (Flicky* x = flicky(); x; x = x->next())
{
x->next_target(nullptr);
}
}
void Controller::collect()
{
if (mode() != Mode::kReturning)
{
return;
}
// Resume searching once all Flickys return
for (Flicky* x = flicky(); x; x = x->next())
{
if (x->mode() != Flicky::Mode::kReserved)
{
return;
}
}
mode(Mode::kOrbit);
}
}; // namespace }; // namespace
void Obj_SpawnSuperFlickySwarm(player_t* owner, tic_t time) void Obj_SpawnSuperFlickySwarm(player_t* owner, tic_t time)
@ -696,9 +774,11 @@ void Obj_SuperFlickyControllerThink(mobj_t* mobj)
break; break;
case Controller::Mode::kEnRoute: case Controller::Mode::kEnRoute:
x->range_check();
break; break;
case Controller::Mode::kAttached: case Controller::Mode::kAttached:
x->range_check();
x->search(); x->search();
break; break;

View file

@ -787,7 +787,9 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if (!tm.thing->player || !tm.thing->player->fastfall) if (!tm.thing->player || !tm.thing->player->fastfall)
{ {
P_SetObjectMomZ(tm.thing, FRACUNIT, true); fixed_t tractorHeight = 211*mapobjectscale;
fixed_t zRange = FixedDiv(thing->z - tm.thing->z, tractorHeight);
P_SetObjectMomZ(tm.thing, max(zRange, FRACUNIT/16), true);
} }
fixed_t friction = 33*FRACUNIT/35; fixed_t friction = 33*FRACUNIT/35;