- scriptified the melee attack.

This commit is contained in:
Christoph Oelckers 2022-12-22 21:42:43 +01:00
parent 1d887755a5
commit 0643ab22c0
14 changed files with 176 additions and 242 deletions

View file

@ -986,6 +986,16 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, ChangeStat, ChangeActorStat)
return 0;
}
static int CoreActor_spritetexture(DCoreActor* self)
{
return self->spr.spritetexture().GetIndex();
}
DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, spritetexture, CoreActor_spritetexture)
{
PARAM_SELF_PROLOGUE(DCoreActor);
ACTION_RETURN_INT(CoreActor_spritetexture(self));
}

View file

@ -81,91 +81,6 @@ void incur_damage_d(player_struct* p)
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void shootknee(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
{
auto sectp = actor->sector();
double vel = 1024., zvel;
HitInfo hit{};
if (p >= 0)
{
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 16.);
pos.Z += 6;
ang += DAngle1 * 2.64;
}
else
{
double x;
auto pactor = ps[findplayer(actor, &x)].GetActor();
zvel = ((pactor->spr.pos.Z - pos.Z) * 16) / (x + 1/16.);
ang = (pactor->spr.pos.XY() - pos.XY()).Angle();
}
hitscan(pos, sectp, DVector3(ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
if (hit.hitSector == nullptr) return;
if ((pos.XY() - hit.hitpos.XY()).Sum() < 64)
{
if (hit.hitWall || hit.actor())
{
auto knee = CreateActor(hit.hitSector, hit.hitpos, DTILE_KNEE, -15, DVector2(0, 0), ang, 2., 0., actor, 4);
if (knee)
{
knee->spr.extra += (krand() & 7);
if (p >= 0)
{
auto k = spawn(knee, PClass::FindActor(NAME_DukeSmallSmoke));
if (k) k->spr.pos.Z -= 8;
S_PlayActorSound(KICK_HIT, knee);
}
if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400)
knee->spr.extra += (gs.max_player_health >> 2);
}
if (hit.actor() && ! isaccessswitch(hit.actor()->spr.spritetexture()))
{
checkhitsprite(hit.actor(), knee);
if (p >= 0) checkhitswitch(p, nullptr, hit.actor());
}
else if (hit.hitWall)
{
if (hit.hitWall->cstat & CSTAT_WALL_BOTTOM_SWAP)
if (hit.hitWall->twoSided())
if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz)
hit.hitWall =hit.hitWall->nextWall();
if (!isaccessswitch(hit.hitWall->walltexture))
{
checkhitwall(knee, hit.hitWall, hit.hitpos);
if (p >= 0) checkhitswitch(p, hit.hitWall, nullptr);
}
}
}
else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1)
{
auto splash = spawn(ps[p].GetActor(), DTILE_WATERSPLASH2);
if (splash)
{
splash->spr.pos.XY() = hit.hitpos.XY();
splash->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw;
splash->vel.X = 2;
ssp(actor, CLIPMASK0);
splash->vel.X = 0;
}
}
}
}
//---------------------------------------------------------------------------
//
//
@ -702,10 +617,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls)
switch (atwith)
{
case DTILE_KNEE:
shootknee(actor, p, spos, sang);
break;
case DTILE_SHOTSPARK1:
case DTILE_SHOTGUN:
case DTILE_CHAINGUN:

View file

@ -83,123 +83,6 @@ void incur_damage_r(player_struct* p)
//
//---------------------------------------------------------------------------
static void shootmelee(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atwith)
{
auto sectp = actor->sector();
double vel = 1024., zvel;
HitInfo hit{};
if (p >= 0)
{
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 16.);
pos.Z += 6;
ang += DAngle1 * 2.64;
}
else
{
double x;
auto pactor = ps[findplayer(actor, &x)].GetActor();
zvel = ((pactor->spr.pos.Z - pos.Z) * 16) / (x + 1 / 16.);
ang = (pactor->spr.pos.XY() - pos.XY()).Angle();
}
hitscan(pos, sectp, DVector3(ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
if (isRRRA() && hit.hitSector != nullptr && ((hit.hitSector->lotag == ST_160_FLOOR_TELEPORT && zvel > 0) || (hit.hitSector->lotag == ST_161_CEILING_TELEPORT && zvel < 0))
&& hit.actor() == nullptr && hit.hitWall == nullptr)
{
DukeStatIterator its(STAT_EFFECTOR);
while (auto effector = its.Next())
{
if (effector->sector() == hit.hitSector && iseffector(effector) && effector->GetOwner()
&& effector->spr.lotag == SE_7_TELEPORT)
{
DVector3 npos;
npos.XY() = hit.hitpos.XY() + (effector->GetOwner()->spr.pos.XY() - effector->spr.pos.XY());
if (hit.hitSector->lotag == ST_161_CEILING_TELEPORT)
{
npos.Z = effector->GetOwner()->sector()->floorz;
}
else
{
npos.Z = effector->GetOwner()->sector()->ceilingz;
}
hitscan(npos, effector->GetOwner()->sector(), DVector3(ang.ToVector() * 1024, zvel * 0.25), hit, CLIPMASK1);
break;
}
}
}
if (hit.hitSector == nullptr) return;
if ((pos.XY() - hit.hitpos.XY()).Sum() < 64)
{
if (hit.hitWall != nullptr || hit.actor())
{
DDukeActor* wpn;
if (isRRRA() && atwith == RTILE_SLINGBLADE)
{
wpn = CreateActor(hit.hitSector, hit.hitpos, RTILE_SLINGBLADE, -15, DVector2(0, 0), ang, 32., 0., actor, 4);
if (!wpn) return;
wpn->spr.extra += 50;
}
else
{
wpn = CreateActor(hit.hitSector, hit.hitpos, RTILE_KNEE, -15, DVector2(0, 0), ang, 32., 0., actor, 4);
if (!wpn) return;
wpn->spr.extra += (krand() & 7);
}
if (p >= 0)
{
auto k = spawn(wpn, PClass::FindActor(NAME_DukeSmallSmoke));
if (k) k->spr.pos.Z -= 8;
if (atwith == RTILE_KNEE) S_PlayActorSound(KICK_HIT, wpn);
else if (isRRRA() && atwith == RTILE_SLINGBLADE) S_PlayActorSound(260, wpn);
}
if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400)
wpn->spr.extra += (gs.max_player_health >> 2);
if (hit.actor() && !isaccessswitch(hit.actor()->spr.spritetexture()))
{
checkhitsprite(hit.actor(), wpn);
if (p >= 0) checkhitswitch(p, nullptr, hit.actor());
}
else if (hit.hitWall)
{
if (hit.hitWall->cstat & CSTAT_WALL_BOTTOM_SWAP)
if (hit.hitWall->twoSided())
if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz)
hit.hitWall = hit.hitWall->nextWall();
if (!isaccessswitch(hit.hitWall->walltexture))
{
checkhitwall(wpn, hit.hitWall, hit.hitpos);
if (p >= 0) checkhitswitch(p, hit.hitWall, nullptr);
}
}
}
else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1)
{
auto splash = spawn(ps[p].GetActor(), RTILE_WATERSPLASH2);
if (splash)
{
splash->spr.pos.XY() = hit.hitpos.XY();
splash->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw;
splash->vel.X = 2;
ssp(actor, 0);
splash->vel.X = 0;
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith)
{
auto sectp = actor->sector();
@ -772,14 +655,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
switch (atwith)
{
case RTILE_SLINGBLADE:
if (!isRRRA()) break;
[[fallthrough]];
case RTILE_KNEE:
case RTILE_GROWSPARK:
shootmelee(actor, p, spos, sang, atwith);
return;
case RTILE_SHOTSPARK1:
case RTILE_SHOTGUN:
case RTILE_CHAINGUN:

View file

@ -1103,6 +1103,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, StartBoat, OnBoat)
return 0;
}
void pl_checkhitswitch(player_struct* p, walltype* wal, DDukeActor* act)
{
checkhitswitch(p->GetPlayerNum(), wal, act);
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, checkhitswitch, pl_checkhitswitch)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_POINTER(wal, walltype);
PARAM_POINTER(act, DDukeActor);
pl_checkhitswitch(self, wal, act);
return 0;
}
static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum)
{

View file

@ -11,7 +11,7 @@ spawnclasses
9 = DukeRespawnController, noskill
10 = DukeGPSpeed, noskill
4890 = DukeNaturalLightning, noskill
2521 = DukeKneeAttack, noskill
2521 = DukeMeleeAttack, noskill
2613 = DukeShotgunShot, noskill
2536 = DukeChaingunShot, noskill
1670 = DukeRadiusExplosion, noskill

View file

@ -193,4 +193,5 @@ spawnclasses
78 = RedneckMotoAmmo, noskill
8460 = RedneckBoatAmmo, noskill
7170 = RedneckMotoHit, noskill
3510 = RedneckSlingbladeAttack, noskill
}

View file

@ -35,7 +35,7 @@ spawnclasses
34 = RedneckKeyinfoSetter, noskill
3380 = RedneckChaingunShot, noskill
3350 = RedneckShotgunShot, noskill
3340 = RedneckCrowbarAttack, noskill
3340 = DukeMeleeAttack, noskill
1426 = DukeRadiusExplosion, noskill
1298 = DukeCranePole, noskill

View file

@ -158,6 +158,7 @@ version "4.10"
#include "zscript/games/duke/actors/rabbit.zs"
#include "zscript/games/duke/actors/dukeweapons/melee.zs"
#include "zscript/games/duke/actors/dukeweapons/shrinker.zs"
#include "zscript/games/duke/actors/dukeweapons/grower.zs"
#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs"

View file

@ -69,6 +69,7 @@ class CoreActor native
native void setPosition(Vector3 pos);
native void setPositionZ(Vector3 pos);
native bool isAwayFromWall(double dist);
native TextureID spritetexture();
native void ChangeSector(sectortype s, bool forcetail = false);
native void ChangeStat(int s, bool forcetail = false);

View file

@ -1,20 +1,3 @@
// dummy items representing certain weapons
class DukeKneeAttack : DukeActor
{
default
{
pic "KNEE";
+DIENOW;
}
}
class RedneckCrowbarAttack : DukeKneeAttack
{
}
class DukeRadiusExplosion : DukeActor
{
default

View file

@ -0,0 +1,145 @@
class DukeMeleeAttack : DukeActor
{
meta sound attacksound;
meta int extradamage;
property attacksound: attacksound;
property extradamage: extradamage;
default
{
pic "KNEE";
+DIENOW;
DukeMeleeAttack.extradamage 0;
DukeMeleeAttack.attacksound "KICK_HIT";
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
let sectp = actor.sector;
double vel = 1024., zvel;
HitInfo hit;
if (p)
{
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 16.);
pos.Z += 6;
ang += 2.64;
}
else
{
double x;
let pactor = self.findplayer().Actor;
zvel = ((pactor.pos.Z - pos.Z) * 16) / (x + 1 / 16.);
ang = (pactor.pos.XY - pos.XY).Angle();
}
Raze.hitscan(pos, sectp, (ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
if (Raze.isRRRA() && hit.hitSector != nullptr && ((hit.hitSector.lotag == ST_160_FLOOR_TELEPORT && zvel > 0) || (hit.hitSector.lotag == ST_161_CEILING_TELEPORT && zvel < 0))
&& hit.hitActor == nullptr && hit.hitWall == nullptr)
{
DukeStatIterator its;
for (let effector = its.First(STAT_EFFECTOR); effector; effector = its.Next())
{
if (effector.sector == hit.hitSector && effector.GetClassName() == 'DukeSectorEffector' && effector.ownerActor && effector.lotag == SE_7_TELEPORT)
{
let owner = effector.ownerActor;
Vector3 npos;
npos.XY = hit.hitpos.XY + (owner.pos.XY - effector.pos.XY);
if (hit.hitSector.lotag == ST_161_CEILING_TELEPORT)
{
npos.Z = owner.sector.floorz;
}
else
{
npos.Z = owner.sector.ceilingz;
}
Raze.hitscan(npos, owner.sector, (ang.ToVector() * 1024, zvel * 0.25), hit, CLIPMASK1);
break;
}
}
}
if (hit.hitSector == nullptr) return true;
if ((pos.XY - hit.hitpos.XY).Sum() < 64)
{
if (hit.hitWall != nullptr || hit.hitactor)
{
let wpn = dlevel.SpawnActor(hit.hitSector, hit.hitpos, GetClass(), -15, (0, 0), ang, 2., 0., actor, STAT_PROJECTILE);
if (!wpn) return true;
if (self.extradamage > 0)
{
wpn.extra += self.extradamage;
}
else
{
wpn.extra += random(0, 7);
}
if (p)
{
let k = wpn.spawn("DukeSmallSmoke");
if (k) k.pos.Z -= 8;
wpn.PlayActorSound(self.attacksound);
if (p.steroids_amount > 0 && p.steroids_amount < 400)
wpn.extra += (gs.max_player_health >> 2);
}
if (hit.hitActor && !Duke.isaccessswitch(hit.hitactor.spritetexture()))
{
let da = DukeActor(hit.hitActor);
da.OnHit(wpn);
if (p) p.checkhitswitch(nullptr, da);
}
else if (hit.hitWall)
{
if (hit.hitWall.cstat & CSTAT_WALL_BOTTOM_SWAP)
if (hit.hitWall.twoSided())
if (hit.hitpos.Z >= hit.hitWall.nextSectorp().floorz)
hit.hitWall = hit.hitWall.nextWallp();
if (!Duke.isaccessswitch(hit.hitWall.walltexture))
{
dlevel.checkhitwall(hit.hitWall, wpn, hit.hitpos);
if (p) p.checkhitswitch(hit.hitWall, nullptr);
}
}
}
else if (p && zvel > 0 && hit.hitSector.lotag == 1)
{
let splash = p.actor.spawn("DukeWaterSplash");
if (splash)
{
splash.pos.XY = hit.hitpos.XY;
splash.Angle = p.actor.Angle;
splash.vel.X = 2;
actor.DoMove(CLIPMASK0);
splash.vel.X = 0;
}
}
}
return true;
}
}
class RedneckBuzzSaw : DukeMeleeAttack
{
default
{
pic "BUZSAW";
}
}
class RedneckSlingbladeAttack : DukeMeleeAttack
{
default
{
pic "SLINGBLADE";
DukeMeleeAttack.extradamage 50; // extra attack power.
DukeMeleeAttack.attacksound "SLINGHIT";
}
}

View file

@ -14,7 +14,7 @@ class RedneckPowderKeg : DukeItemBase
override void Tick()
{
let sectp = self.sector;
if (sectp.lotag != ST_1_ABOVE_WATER && sectp.lotag != ST_160_FLOOR_TELEPORT)
if (sectp.lotag != ST_1_ABOVE_WATER && (!Raze.isRRRA() && sectp.lotag != ST_160_FLOOR_TELEPORT))
if (self.vel.X != 0)
{
movesprite((self.Angle.ToVector()* self.vel.X, self.vel.Z), CLIPMASK0);

View file

@ -131,14 +131,6 @@ class RedneckTeslaBall : DukeItemBase
}
}
class RedneckBuzzSaw : DukeItemBase
{
default
{
pic "BUZSAW";
}
}
class RedneckBustaWin5a : DukeItemBase
{
default

View file

@ -379,6 +379,7 @@ struct DukePlayer native
native void setbobpos();
native void StartMotorcycle();
native void StartBoat();
native void checkhitswitch(walltype wal, DukeActor act);
}