mirror of
https://github.com/ZDoom/Raze.git
synced 2025-04-25 09:10:59 +00:00
- scriptified the melee attack.
This commit is contained in:
parent
1d887755a5
commit
0643ab22c0
14 changed files with 176 additions and 242 deletions
|
@ -986,6 +986,16 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, ChangeStat, ChangeActorStat)
|
||||||
return 0;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
switch (atwith)
|
||||||
{
|
{
|
||||||
case DTILE_KNEE:
|
|
||||||
shootknee(actor, p, spos, sang);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DTILE_SHOTSPARK1:
|
case DTILE_SHOTSPARK1:
|
||||||
case DTILE_SHOTGUN:
|
case DTILE_SHOTGUN:
|
||||||
case DTILE_CHAINGUN:
|
case DTILE_CHAINGUN:
|
||||||
|
|
|
@ -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)
|
static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith)
|
||||||
{
|
{
|
||||||
auto sectp = actor->sector();
|
auto sectp = actor->sector();
|
||||||
|
@ -772,14 +655,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
|
||||||
|
|
||||||
switch (atwith)
|
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_SHOTSPARK1:
|
||||||
case RTILE_SHOTGUN:
|
case RTILE_SHOTGUN:
|
||||||
case RTILE_CHAINGUN:
|
case RTILE_CHAINGUN:
|
||||||
|
|
|
@ -1103,6 +1103,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, StartBoat, OnBoat)
|
||||||
return 0;
|
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)
|
static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ spawnclasses
|
||||||
9 = DukeRespawnController, noskill
|
9 = DukeRespawnController, noskill
|
||||||
10 = DukeGPSpeed, noskill
|
10 = DukeGPSpeed, noskill
|
||||||
4890 = DukeNaturalLightning, noskill
|
4890 = DukeNaturalLightning, noskill
|
||||||
2521 = DukeKneeAttack, noskill
|
2521 = DukeMeleeAttack, noskill
|
||||||
2613 = DukeShotgunShot, noskill
|
2613 = DukeShotgunShot, noskill
|
||||||
2536 = DukeChaingunShot, noskill
|
2536 = DukeChaingunShot, noskill
|
||||||
1670 = DukeRadiusExplosion, noskill
|
1670 = DukeRadiusExplosion, noskill
|
||||||
|
|
|
@ -193,4 +193,5 @@ spawnclasses
|
||||||
78 = RedneckMotoAmmo, noskill
|
78 = RedneckMotoAmmo, noskill
|
||||||
8460 = RedneckBoatAmmo, noskill
|
8460 = RedneckBoatAmmo, noskill
|
||||||
7170 = RedneckMotoHit, noskill
|
7170 = RedneckMotoHit, noskill
|
||||||
|
3510 = RedneckSlingbladeAttack, noskill
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ spawnclasses
|
||||||
34 = RedneckKeyinfoSetter, noskill
|
34 = RedneckKeyinfoSetter, noskill
|
||||||
3380 = RedneckChaingunShot, noskill
|
3380 = RedneckChaingunShot, noskill
|
||||||
3350 = RedneckShotgunShot, noskill
|
3350 = RedneckShotgunShot, noskill
|
||||||
3340 = RedneckCrowbarAttack, noskill
|
3340 = DukeMeleeAttack, noskill
|
||||||
1426 = DukeRadiusExplosion, noskill
|
1426 = DukeRadiusExplosion, noskill
|
||||||
|
|
||||||
1298 = DukeCranePole, noskill
|
1298 = DukeCranePole, noskill
|
||||||
|
|
|
@ -158,6 +158,7 @@ version "4.10"
|
||||||
#include "zscript/games/duke/actors/rabbit.zs"
|
#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/shrinker.zs"
|
||||||
#include "zscript/games/duke/actors/dukeweapons/grower.zs"
|
#include "zscript/games/duke/actors/dukeweapons/grower.zs"
|
||||||
#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs"
|
#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs"
|
||||||
|
|
|
@ -69,6 +69,7 @@ class CoreActor native
|
||||||
native void setPosition(Vector3 pos);
|
native void setPosition(Vector3 pos);
|
||||||
native void setPositionZ(Vector3 pos);
|
native void setPositionZ(Vector3 pos);
|
||||||
native bool isAwayFromWall(double dist);
|
native bool isAwayFromWall(double dist);
|
||||||
|
native TextureID spritetexture();
|
||||||
|
|
||||||
native void ChangeSector(sectortype s, bool forcetail = false);
|
native void ChangeSector(sectortype s, bool forcetail = false);
|
||||||
native void ChangeStat(int s, bool forcetail = false);
|
native void ChangeStat(int s, bool forcetail = false);
|
||||||
|
|
|
@ -1,20 +1,3 @@
|
||||||
|
|
||||||
// dummy items representing certain weapons
|
|
||||||
|
|
||||||
class DukeKneeAttack : DukeActor
|
|
||||||
{
|
|
||||||
default
|
|
||||||
{
|
|
||||||
pic "KNEE";
|
|
||||||
+DIENOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RedneckCrowbarAttack : DukeKneeAttack
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class DukeRadiusExplosion : DukeActor
|
class DukeRadiusExplosion : DukeActor
|
||||||
{
|
{
|
||||||
default
|
default
|
||||||
|
|
145
wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs
Normal file
145
wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs
Normal 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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class RedneckPowderKeg : DukeItemBase
|
||||||
override void Tick()
|
override void Tick()
|
||||||
{
|
{
|
||||||
let sectp = self.sector;
|
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)
|
if (self.vel.X != 0)
|
||||||
{
|
{
|
||||||
movesprite((self.Angle.ToVector()* self.vel.X, self.vel.Z), CLIPMASK0);
|
movesprite((self.Angle.ToVector()* self.vel.X, self.vel.Z), CLIPMASK0);
|
||||||
|
|
|
@ -131,14 +131,6 @@ class RedneckTeslaBall : DukeItemBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RedneckBuzzSaw : DukeItemBase
|
|
||||||
{
|
|
||||||
default
|
|
||||||
{
|
|
||||||
pic "BUZSAW";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RedneckBustaWin5a : DukeItemBase
|
class RedneckBustaWin5a : DukeItemBase
|
||||||
{
|
{
|
||||||
default
|
default
|
||||||
|
|
|
@ -379,6 +379,7 @@ struct DukePlayer native
|
||||||
native void setbobpos();
|
native void setbobpos();
|
||||||
native void StartMotorcycle();
|
native void StartMotorcycle();
|
||||||
native void StartBoat();
|
native void StartBoat();
|
||||||
|
native void checkhitswitch(walltype wal, DukeActor act);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue