mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- scriptified A_CustomPunch
This commit is contained in:
parent
7bb3855439
commit
5c130737c4
6 changed files with 146 additions and 184 deletions
|
@ -1626,122 +1626,6 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_JumpIfNoAmmo)
|
|||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_CustomPunch
|
||||
//
|
||||
// Berserk is not handled here. That can be done with A_CheckIfInventory
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
CPF_USEAMMO = 1,
|
||||
CPF_DAGGER = 2,
|
||||
CPF_PULLIN = 4,
|
||||
CPF_NORANDOMPUFFZ = 8,
|
||||
CPF_NOTURN = 16,
|
||||
CPF_STEALARMOR = 32,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AStateProvider, A_CustomPunch)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AStateProvider);
|
||||
PARAM_INT (damage);
|
||||
PARAM_BOOL (norandom);
|
||||
PARAM_INT (flags);
|
||||
PARAM_CLASS (pufftype, AActor);
|
||||
PARAM_FLOAT (range);
|
||||
PARAM_FLOAT (lifesteal);
|
||||
PARAM_INT (lifestealmax);
|
||||
PARAM_CLASS (armorbonustype, AActor);
|
||||
PARAM_SOUND (MeleeSound);
|
||||
PARAM_SOUND (MissSound);
|
||||
|
||||
if (!self->player)
|
||||
return 0;
|
||||
|
||||
player_t *player = self->player;
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
|
||||
|
||||
DAngle angle;
|
||||
DAngle pitch;
|
||||
FTranslatedLineTarget t;
|
||||
int actualdamage;
|
||||
|
||||
if (!norandom)
|
||||
damage *= pr_cwpunch() % 8 + 1;
|
||||
|
||||
angle = self->Angles.Yaw + pr_cwpunch.Random2() * (5.625 / 256);
|
||||
if (range == 0) range = DEFMELEERANGE;
|
||||
pitch = P_AimLineAttack (self, angle, range, &t, 0., ALF_CHECK3D);
|
||||
|
||||
// only use ammo when actually hitting something!
|
||||
if ((flags & CPF_USEAMMO) && t.linetarget && weapon && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
||||
return 0; // out of ammo
|
||||
}
|
||||
|
||||
if (pufftype == NULL)
|
||||
pufftype = PClass::FindActor(NAME_BulletPuff);
|
||||
int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0);
|
||||
|
||||
P_LineAttack (self, angle, range, pitch, damage, NAME_Melee, pufftype, puffFlags, &t, &actualdamage);
|
||||
|
||||
if (!t.linetarget)
|
||||
{
|
||||
if (MissSound) S_Sound(self, CHAN_WEAPON, MissSound, 1, ATTN_NORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lifesteal > 0 && !(t.linetarget->flags5 & MF5_DONTDRAIN))
|
||||
{
|
||||
if (flags & CPF_STEALARMOR)
|
||||
{
|
||||
if (armorbonustype == NULL)
|
||||
{
|
||||
armorbonustype = PClass::FindActor("ArmorBonus");
|
||||
}
|
||||
if (armorbonustype != NULL)
|
||||
{
|
||||
auto armorbonus = Spawn(armorbonustype);
|
||||
armorbonus->IntVar(NAME_SaveAmount) *= int(actualdamage * lifesteal);
|
||||
if (lifestealmax > 0) armorbonus->IntVar("MaxSaveAmount") = lifestealmax;
|
||||
armorbonus->flags |= MF_DROPPED;
|
||||
armorbonus->ClearCounters();
|
||||
|
||||
if (!static_cast<AInventory*>(armorbonus)->CallTryPickup(self))
|
||||
{
|
||||
armorbonus->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax);
|
||||
}
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (MeleeSound) S_Sound(self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM);
|
||||
else S_Sound (self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
if (!(flags & CPF_NOTURN))
|
||||
{
|
||||
// turn to face target
|
||||
self->Angles.Yaw = t.angleFromSource;
|
||||
}
|
||||
|
||||
if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED;
|
||||
if (flags & CPF_DAGGER) P_DaggerAlert (self, t.linetarget);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// customizable railgun attack function
|
||||
|
|
|
@ -268,71 +268,6 @@ DEFINE_ACTION_FUNCTION(AActor, SoundAlert)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_DaggerAlert
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_DaggerAlert(AActor *target, AActor *emitter)
|
||||
{
|
||||
AActor *looker;
|
||||
sector_t *sec = emitter->Sector;
|
||||
|
||||
if (emitter->LastHeard != NULL)
|
||||
return;
|
||||
if (emitter->health <= 0)
|
||||
return;
|
||||
if (!(emitter->flags3 & MF3_ISMONSTER))
|
||||
return;
|
||||
if (emitter->flags4 & MF4_INCOMBAT)
|
||||
return;
|
||||
emitter->flags4 |= MF4_INCOMBAT;
|
||||
|
||||
emitter->target = target;
|
||||
FState *painstate = emitter->FindState(NAME_Pain, NAME_Dagger);
|
||||
if (painstate != NULL)
|
||||
{
|
||||
emitter->SetState(painstate);
|
||||
}
|
||||
|
||||
for (looker = sec->thinglist; looker != NULL; looker = looker->snext)
|
||||
{
|
||||
if (looker == emitter || looker == target)
|
||||
continue;
|
||||
|
||||
if (looker->health <= 0)
|
||||
continue;
|
||||
|
||||
if (!(looker->flags4 & MF4_SEESDAGGERS))
|
||||
continue;
|
||||
|
||||
if (!(looker->flags4 & MF4_INCOMBAT))
|
||||
{
|
||||
if (!P_CheckSight(looker, target) && !P_CheckSight(looker, emitter))
|
||||
continue;
|
||||
|
||||
looker->target = target;
|
||||
if (looker->SeeSound)
|
||||
{
|
||||
S_Sound(looker, CHAN_VOICE, looker->SeeSound, 1, ATTN_NORM);
|
||||
}
|
||||
looker->SetState(looker->SeeState);
|
||||
looker->flags4 |= MF4_INCOMBAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, DaggerAlert)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(target, AActor);
|
||||
// Note that the emitter is self, not the target of the alert! Target can be NULL.
|
||||
P_DaggerAlert(target, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// AActor :: CheckMeleeRange
|
||||
|
|
|
@ -46,7 +46,6 @@ struct FLookExParams
|
|||
FState *seestate;
|
||||
};
|
||||
|
||||
void P_DaggerAlert (AActor *target, AActor *emitter);
|
||||
bool P_HitFriend (AActor *self);
|
||||
void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash=false, double maxdist=0);
|
||||
|
||||
|
|
|
@ -584,7 +584,6 @@ class Actor : Thinker native
|
|||
native clearscope int PlayerNumber() const;
|
||||
native void SetFriendPlayer(PlayerInfo player);
|
||||
native void SoundAlert(Actor target, bool splash = false, double maxdist = 0);
|
||||
native void DaggerAlert(Actor target);
|
||||
native void ClearBounce();
|
||||
native TerrainDef GetFloorTerrain();
|
||||
native bool CheckLocalView(int consoleplayer);
|
||||
|
|
|
@ -116,5 +116,59 @@ extend class Actor
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_DaggerAlert
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DaggerAlert(Actor target)
|
||||
{
|
||||
Actor looker;
|
||||
|
||||
if (LastHeard != NULL)
|
||||
return;
|
||||
if (health <= 0)
|
||||
return;
|
||||
if (!bIsMonster)
|
||||
return;
|
||||
if (bInCombat)
|
||||
return;
|
||||
bInCombat = true;
|
||||
|
||||
self.target = target;
|
||||
let painstate = FindState('Pain', 'Dagger');
|
||||
if (painstate != NULL)
|
||||
{
|
||||
SetState(painstate);
|
||||
}
|
||||
|
||||
for (looker = cursector.thinglist; looker != NULL; looker = looker.snext)
|
||||
{
|
||||
if (looker == self || looker == target)
|
||||
continue;
|
||||
|
||||
if (looker.health <= 0)
|
||||
continue;
|
||||
|
||||
if (!looker.bSeesDaggers)
|
||||
continue;
|
||||
|
||||
if (!looker.bInCombat)
|
||||
{
|
||||
if (!looker.CheckSight(target) && !looker.CheckSight(self))
|
||||
continue;
|
||||
|
||||
looker.target = target;
|
||||
if (looker.SeeSound)
|
||||
{
|
||||
looker.A_PlaySound(looker.SeeSound, CHAN_VOICE);
|
||||
}
|
||||
looker.SetState(looker.SeeState);
|
||||
looker.bInCombat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
class StateProvider : Inventory native
|
||||
{
|
||||
action native state A_JumpIfNoAmmo(statelabel label);
|
||||
action native void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", double range = 0, double lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = 0, sound MissSound = "");
|
||||
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = 0, color color2 = 0, int flags = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = "none", double spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||
action native void A_WeaponReady(int flags = 0);
|
||||
|
||||
|
@ -175,6 +174,98 @@ class StateProvider : Inventory native
|
|||
return null;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_CustomPunch
|
||||
//
|
||||
// Berserk is not handled here. That can be done with A_CheckIfInventory
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
action void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", double range = 0, double lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = 0, sound MissSound = "")
|
||||
{
|
||||
let player = self.player;
|
||||
if (!player) return;
|
||||
|
||||
let weapon = player.ReadyWeapon;
|
||||
|
||||
double angle;
|
||||
double pitch;
|
||||
FTranslatedLineTarget t;
|
||||
int actualdamage;
|
||||
|
||||
if (!norandom)
|
||||
damage *= random[cwpunch](1, 8);
|
||||
|
||||
angle = self.Angle + random2[cwpunch]() * (5.625 / 256);
|
||||
if (range == 0) range = DEFMELEERANGE;
|
||||
pitch = AimLineAttack (angle, range, t, 0., ALF_CHECK3D);
|
||||
|
||||
// only use ammo when actually hitting something!
|
||||
if ((flags & CPF_USEAMMO) && t.linetarget && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
|
||||
{
|
||||
if (!weapon.DepleteAmmo(weapon.bAltFire, true))
|
||||
return; // out of ammo
|
||||
}
|
||||
|
||||
if (pufftype == NULL)
|
||||
pufftype = 'BulletPuff';
|
||||
int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0);
|
||||
|
||||
Actor puff;
|
||||
[puff, actualdamage] = LineAttack (angle, range, pitch, damage, 'Melee', pufftype, puffFlags, t);
|
||||
|
||||
if (!t.linetarget)
|
||||
{
|
||||
if (MissSound) A_PlaySound(MissSound, CHAN_WEAPON);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lifesteal > 0 && !(t.linetarget.bDontDrain))
|
||||
{
|
||||
if (flags & CPF_STEALARMOR)
|
||||
{
|
||||
if (armorbonustype == NULL)
|
||||
{
|
||||
armorbonustype = 'ArmorBonus';
|
||||
}
|
||||
if (armorbonustype != NULL)
|
||||
{
|
||||
let armorbonus = ArmorBonus(Spawn(armorbonustype));
|
||||
armorbonus.SaveAmount *= int(actualdamage * lifesteal);
|
||||
if (lifestealmax > 0) armorbonus.MaxSaveAmount = lifestealmax;
|
||||
armorbonus.bDropped = true;
|
||||
armorbonus.ClearCounters();
|
||||
|
||||
if (!armorbonus.CallTryPickup(self))
|
||||
{
|
||||
armorbonus.Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GiveBody (int(actualdamage * lifesteal), lifestealmax);
|
||||
}
|
||||
}
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (MeleeSound) A_PlaySound(MeleeSound, CHAN_WEAPON);
|
||||
else A_PlaySound(AttackSound, CHAN_WEAPON);
|
||||
}
|
||||
|
||||
if (!(flags & CPF_NOTURN))
|
||||
{
|
||||
// turn to face target
|
||||
self.Angle = t.angleFromSource;
|
||||
}
|
||||
|
||||
if (flags & CPF_PULLIN) self.bJustAttacked = true;
|
||||
if (flags & CPF_DAGGER) t.linetarget.DaggerAlert (self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue