- scriptified Heretic's crossbow and gauntlets.

This commit is contained in:
Christoph Oelckers 2016-11-24 11:29:51 +01:00
parent 2ece9b6172
commit 677d7579d4
5 changed files with 420 additions and 446 deletions

View File

@ -18,7 +18,6 @@
static FRandom pr_boltspark ("BoltSpark");
static FRandom pr_macerespawn ("MaceRespawn");
static FRandom pr_maceatk ("FireMacePL1");
static FRandom pr_gatk ("GauntletAttack");
static FRandom pr_bfx1 ("BlasterFX1");
static FRandom pr_ripd ("RipperD");
static FRandom pr_fb1 ("FireBlasterPL1");
@ -46,172 +45,6 @@ void P_DSparilTeleport (AActor *actor);
extern bool P_AutoUseChaosDevice (player_t *player);
//----------------------------------------------------------------------------
//
// PROC A_FireCrossbowPL1
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1)
{
PARAM_ACTION_PROLOGUE(AActor);
player_t *player;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1"));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 4.5);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_FireCrossbowPL2
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
{
PARAM_ACTION_PROLOGUE(AActor);
player_t *player;
if (NULL == (player = self->player))
{
return 0;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw - 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw + 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 9.);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 9.);
return 0;
}
//---------------------------------------------------------------------------
//
// PROC A_GauntletAttack
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GauntletAttack)
{
PARAM_ACTION_PROLOGUE(AActor);
DAngle Angle;
int damage;
DAngle slope;
int randVal;
double dist;
player_t *player;
PClassActor *pufftype;
FTranslatedLineTarget t;
int actualdamage = 0;
if (nullptr == (player = self->player))
{
return 0;
}
PARAM_INT(power);
AWeapon *weapon = player->ReadyWeapon;
if (weapon != nullptr)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
player->GetPSprite(PSP_WEAPON)->x = ((pr_gatk() & 3) - 2);
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_gatk() & 3);
}
Angle = self->Angles.Yaw;
if (power)
{
damage = pr_gatk.HitDice (2);
dist = 4*MELEERANGE;
Angle += pr_gatk.Random2() * (2.8125 / 256);
pufftype = PClass::FindActor("GauntletPuff2");
}
else
{
damage = pr_gatk.HitDice (2);
dist = SAWRANGE;
Angle += pr_gatk.Random2() * (5.625 / 256);
pufftype = PClass::FindActor("GauntletPuff1");
}
slope = P_AimLineAttack (self, Angle, dist);
P_LineAttack (self, Angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage);
if (!t.linetarget)
{
if (pr_gatk() > 64)
{
player->extralight = !player->extralight;
}
S_Sound (self, CHAN_AUTO, "weapons/gauntletson", 1, ATTN_NORM);
return 0;
}
randVal = pr_gatk();
if (randVal < 64)
{
player->extralight = 0;
}
else if (randVal < 160)
{
player->extralight = 1;
}
else
{
player->extralight = 2;
}
if (power)
{
if (!(t.linetarget->flags5 & MF5_DONTDRAIN)) P_GiveBody (self, actualdamage>>1);
S_Sound (self, CHAN_AUTO, "weapons/gauntletspowhit", 1, ATTN_NORM);
}
else
{
S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM);
}
// turn to face target
DAngle ang = t.angleFromSource;
DAngle anglediff = deltaangle(self->Angles.Yaw, ang);
if (anglediff < 0.0)
{
if (anglediff < -4.5)
self->Angles.Yaw = ang + 90.0 / 21;
else
self->Angles.Yaw -= 4.5;
}
else
{
if (anglediff > 4.5)
self->Angles.Yaw = ang - 90.0 / 21;
else
self->Angles.Yaw += 4.5;
}
self->flags |= MF_JUSTATTACKED;
return 0;
}
// --- Mace -----------------------------------------------------------------
#define MAGIC_JUNK 1234

View File

@ -97,6 +97,8 @@ zscript/heretic/dsparil.txt
zscript/heretic/chicken.txt
zscript/heretic/weaponstaff.txt
zscript/heretic/weaponwand.txt
zscript/heretic/weaponcrossbow.txt
zscript/heretic/weapongauntlets.txt
zscript/hexen/baseweapons.txt
zscript/hexen/korax.txt

View File

@ -8,285 +8,6 @@ class HereticWeapon : Weapon
}
// Crossbow -----------------------------------------------------------------
class Crossbow : HereticWeapon
{
Default
{
Weapon.SelectionOrder 800;
Weapon.AmmoUse 1;
Weapon.AmmoGive 10;
Weapon.AmmoType "CrossbowAmmo";
Weapon.SisterWeapon "CrossbowPowered";
Weapon.YAdjust 15;
Inventory.PickupMessage "$TXT_WPNCROSSBOW";
Tag "$TAG_CROSSBOW";
}
action native void A_FireCrossbowPL1 ();
States
{
Spawn:
WBOW A -1;
Stop;
Ready:
CRBW AAAAAABBBBBBCCCCCC 1 A_WeaponReady;
Loop;
Deselect:
CRBW A 1 A_Lower;
Loop;
Select:
CRBW A 1 A_Raise;
Loop;
Fire:
CRBW D 6 A_FireCrossbowPL1;
CRBW EFGH 3;
CRBW AB 4;
CRBW C 5 A_ReFire;
Goto Ready;
}
}
class CrossbowPowered : Crossbow
{
Default
{
+WEAPON.POWERED_UP
Weapon.AmmoGive 0;
Weapon.SisterWeapon "Crossbow";
Tag "$TAG_CROSSBOWP";
}
action native void A_FireCrossbowPL2();
States
{
Fire:
CRBW D 5 A_FireCrossbowPL2;
CRBW E 3;
CRBW F 2;
CRBW G 3;
CRBW H 2;
CRBW A 3;
CRBW B 3;
CRBW C 4 A_ReFire;
Goto Ready;
}
}
// Crossbow FX1 -------------------------------------------------------------
class CrossbowFX1 : Actor
{
Default
{
Radius 11;
Height 8;
Speed 30;
Damage 10;
Projectile;
RenderStyle "Add";
SeeSound "weapons/bowshoot";
DeathSound "weapons/bowhit";
Obituary "$OB_MPCROSSBOW";
}
States
{
Spawn:
FX03 B 1 BRIGHT;
Loop;
Death:
FX03 HIJ 8 BRIGHT;
Stop;
}
}
// Crossbow FX2 -------------------------------------------------------------
class CrossbowFX2 : CrossbowFX1
{
Default
{
Speed 32;
Damage 6;
Obituary "$OB_MPPCROSSBOW";
}
States
{
Spawn:
FX03 B 1 BRIGHT A_SpawnItemEx("CrossbowFX4", random2[BoltSpark]()*0.015625, random2[BoltSpark]()*0.015625, 0, 0,0,0,0,SXF_ABSOLUTEPOSITION, 50);
Loop;
}
}
// Crossbow FX3 -------------------------------------------------------------
class CrossbowFX3 : CrossbowFX1
{
Default
{
Speed 20;
Damage 2;
SeeSound "";
-NOBLOCKMAP
+WINDTHRUST
+THRUGHOST
}
States
{
Spawn:
FX03 A 1 BRIGHT;
Loop;
Death:
FX03 CDE 8 BRIGHT;
Stop;
}
}
// Crossbow FX4 -------------------------------------------------------------
class CrossbowFX4 : Actor
{
Default
{
+NOBLOCKMAP
Gravity 0.125;
RenderStyle "Add";
}
States
{
Spawn:
FX03 FG 8 BRIGHT;
Stop;
}
}
// Gauntlets ----------------------------------------------------------------
class Gauntlets : Weapon
{
Default
{
+BLOODSPLATTER
Weapon.SelectionOrder 2300;
+WEAPON.WIMPY_WEAPON
+WEAPON.MELEEWEAPON
Weapon.Kickback 0;
Weapon.YAdjust 15;
Weapon.UpSound "weapons/gauntletsactivate";
Weapon.SisterWeapon "GauntletsPowered";
Inventory.PickupMessage "$TXT_WPNGAUNTLETS";
Tag "$TAG_GAUNTLETS";
Obituary "$OB_MPGAUNTLETS";
}
action native void A_GauntletAttack (int power);
States
{
Spawn:
WGNT A -1;
Stop;
Ready:
GAUN A 1 A_WeaponReady;
Loop;
Deselect:
GAUN A 1 A_Lower;
Loop;
Select:
GAUN A 1 A_Raise;
Loop;
Fire:
GAUN B 4 A_PlaySound("weapons/gauntletsuse", CHAN_WEAPON);
GAUN C 4;
Hold:
GAUN DEF 4 BRIGHT A_GauntletAttack(0);
GAUN C 4 A_ReFire;
GAUN B 4 A_Light0;
Goto Ready;
}
}
class GauntletsPowered : Gauntlets
{
Default
{
+WEAPON.POWERED_UP
Tag "$TAG_GAUNTLETSP";
Obituary "$OB_MPPGAUNTLETS";
Weapon.SisterWeapon "Gauntlets";
}
States
{
Ready:
GAUN GHI 4 A_WeaponReady;
Loop;
Deselect:
GAUN G 1 A_Lower;
Loop;
Select:
GAUN G 1 A_Raise;
Loop;
Fire:
GAUN J 4 A_PlaySound("weapons/gauntletsuse", CHAN_WEAPON);
GAUN K 4;
Hold:
GAUN LMN 4 BRIGHT A_GauntletAttack(1);
GAUN K 4 A_ReFire;
GAUN J 4 A_Light0;
Goto Ready;
}
}
// Gauntlet puff 1 ----------------------------------------------------------
class GauntletPuff1 : Actor
{
Default
{
+NOBLOCKMAP
+NOGRAVITY
+PUFFONACTORS
RenderStyle "Translucent";
Alpha 0.4;
VSpeed 0.8;
}
States
{
Spawn:
PUF1 ABCD 4 BRIGHT;
Stop;
}
}
// Gauntlet puff 2 ---------------------------------------------------------
class GauntletPuff2 : GauntletPuff1
{
States
{
Spawn:
PUF1 EFGH 4 BRIGHT;
Stop;
}
}
// The mace itself ----------------------------------------------------------

View File

@ -0,0 +1,208 @@
// Crossbow -----------------------------------------------------------------
class Crossbow : HereticWeapon
{
Default
{
Weapon.SelectionOrder 800;
Weapon.AmmoUse 1;
Weapon.AmmoGive 10;
Weapon.AmmoType "CrossbowAmmo";
Weapon.SisterWeapon "CrossbowPowered";
Weapon.YAdjust 15;
Inventory.PickupMessage "$TXT_WPNCROSSBOW";
Tag "$TAG_CROSSBOW";
}
States
{
Spawn:
WBOW A -1;
Stop;
Ready:
CRBW AAAAAABBBBBBCCCCCC 1 A_WeaponReady;
Loop;
Deselect:
CRBW A 1 A_Lower;
Loop;
Select:
CRBW A 1 A_Raise;
Loop;
Fire:
CRBW D 6 A_FireCrossbowPL1;
CRBW EFGH 3;
CRBW AB 4;
CRBW C 5 A_ReFire;
Goto Ready;
}
//----------------------------------------------------------------------------
//
// PROC A_FireCrossbowPL1
//
//----------------------------------------------------------------------------
action void A_FireCrossbowPL1 ()
{
if (player == null)
{
return;
}
Weapon weapon = player.ReadyWeapon;
if (weapon != null)
{
if (!weapon.DepleteAmmo (weapon.bAltFire))
return;
}
SpawnPlayerMissile ("CrossbowFX1");
SpawnPlayerMissile ("CrossbowFX3", angle - 4.5);
SpawnPlayerMissile ("CrossbowFX3", angle + 4.5);
}
}
class CrossbowPowered : Crossbow
{
Default
{
+WEAPON.POWERED_UP
Weapon.AmmoGive 0;
Weapon.SisterWeapon "Crossbow";
Tag "$TAG_CROSSBOWP";
}
States
{
Fire:
CRBW D 5 A_FireCrossbowPL2;
CRBW E 3;
CRBW F 2;
CRBW G 3;
CRBW H 2;
CRBW A 3;
CRBW B 3;
CRBW C 4 A_ReFire;
Goto Ready;
}
//----------------------------------------------------------------------------
//
// PROC A_FireCrossbowPL2
//
//----------------------------------------------------------------------------
action void A_FireCrossbowPL2()
{
if (player == null)
{
return;
}
Weapon weapon = player.ReadyWeapon;
if (weapon != null)
{
if (!weapon.DepleteAmmo (weapon.bAltFire))
return;
}
SpawnPlayerMissile ("CrossbowFX2");
SpawnPlayerMissile ("CrossbowFX2", angle - 4.5);
SpawnPlayerMissile ("CrossbowFX2", angle + 4.5);
SpawnPlayerMissile ("CrossbowFX3", angle - 9.);
SpawnPlayerMissile ("CrossbowFX3", angle + 9.);
}
}
// Crossbow FX1 -------------------------------------------------------------
class CrossbowFX1 : Actor
{
Default
{
Radius 11;
Height 8;
Speed 30;
Damage 10;
Projectile;
RenderStyle "Add";
SeeSound "weapons/bowshoot";
DeathSound "weapons/bowhit";
Obituary "$OB_MPCROSSBOW";
}
States
{
Spawn:
FX03 B 1 BRIGHT;
Loop;
Death:
FX03 HIJ 8 BRIGHT;
Stop;
}
}
// Crossbow FX2 -------------------------------------------------------------
class CrossbowFX2 : CrossbowFX1
{
Default
{
Speed 32;
Damage 6;
Obituary "$OB_MPPCROSSBOW";
}
States
{
Spawn:
FX03 B 1 BRIGHT A_SpawnItemEx("CrossbowFX4", random2[BoltSpark]()*0.015625, random2[BoltSpark]()*0.015625, 0, 0,0,0,0,SXF_ABSOLUTEPOSITION, 50);
Loop;
}
}
// Crossbow FX3 -------------------------------------------------------------
class CrossbowFX3 : CrossbowFX1
{
Default
{
Speed 20;
Damage 2;
SeeSound "";
-NOBLOCKMAP
+WINDTHRUST
+THRUGHOST
}
States
{
Spawn:
FX03 A 1 BRIGHT;
Loop;
Death:
FX03 CDE 8 BRIGHT;
Stop;
}
}
// Crossbow FX4 -------------------------------------------------------------
class CrossbowFX4 : Actor
{
Default
{
+NOBLOCKMAP
Gravity 0.125;
RenderStyle "Add";
}
States
{
Spawn:
FX03 FG 8 BRIGHT;
Stop;
}
}

View File

@ -0,0 +1,210 @@
// Gauntlets ----------------------------------------------------------------
class Gauntlets : Weapon
{
Default
{
+BLOODSPLATTER
Weapon.SelectionOrder 2300;
+WEAPON.WIMPY_WEAPON
+WEAPON.MELEEWEAPON
Weapon.Kickback 0;
Weapon.YAdjust 15;
Weapon.UpSound "weapons/gauntletsactivate";
Weapon.SisterWeapon "GauntletsPowered";
Inventory.PickupMessage "$TXT_WPNGAUNTLETS";
Tag "$TAG_GAUNTLETS";
Obituary "$OB_MPGAUNTLETS";
}
States
{
Spawn:
WGNT A -1;
Stop;
Ready:
GAUN A 1 A_WeaponReady;
Loop;
Deselect:
GAUN A 1 A_Lower;
Loop;
Select:
GAUN A 1 A_Raise;
Loop;
Fire:
GAUN B 4 A_PlaySound("weapons/gauntletsuse", CHAN_WEAPON);
GAUN C 4;
Hold:
GAUN DEF 4 BRIGHT A_GauntletAttack(0);
GAUN C 4 A_ReFire;
GAUN B 4 A_Light0;
Goto Ready;
}
//---------------------------------------------------------------------------
//
// PROC A_GauntletAttack
//
//---------------------------------------------------------------------------
action void A_GauntletAttack (int power)
{
int damage;
double dist;
Class<Actor> pufftype;
FTranslatedLineTarget t;
int actualdamage = 0;
Actor puff;
if (player == null)
{
return;
}
Weapon weapon = player.ReadyWeapon;
if (weapon != null)
{
if (!weapon.DepleteAmmo (weapon.bAltFire))
return;
player.GetPSprite(PSP_WEAPON).x = ((random[GauntletAtk]() & 3) - 2);
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + (random[GauntletAtk]() & 3);
}
double ang = angle;
if (power)
{
damage = random[GauntletAtk](1, 8) * 2;
dist = 4*MELEERANGE;
ang += random2[GauntletAtk]() * (2.8125 / 256);
pufftype = "GauntletPuff2";
}
else
{
damage = random[GauntletAtk](1, 8) * 2;
dist = SAWRANGE;
ang += random2[GauntletAtk]() * (5.625 / 256);
pufftype = "GauntletPuff1";
}
double slope = AimLineAttack (ang, dist);
[puff, actualdamage] = LineAttack (ang, dist, slope, damage, 'Melee', pufftype, false, t);
if (!t.linetarget)
{
if (random[GauntletAtk]() > 64)
{
player.extralight = !player.extralight;
}
A_PlaySound ("weapons/gauntletson", CHAN_AUTO);
return;
}
int randVal = random[GauntletAtk]();
if (randVal < 64)
{
player.extralight = 0;
}
else if (randVal < 160)
{
player.extralight = 1;
}
else
{
player.extralight = 2;
}
if (power)
{
if (!t.linetarget.bDontDrain) GiveBody (actualdamage >> 1);
A_PlaySound ("weapons/gauntletspowhit", CHAN_AUTO);
}
else
{
A_PlaySound ("weapons/gauntletshit", CHAN_AUTO);
}
// turn to face target
ang = t.angleFromSource;
double anglediff = deltaangle(angle, ang);
if (anglediff < 0.0)
{
if (anglediff < -4.5)
angle = ang + 90.0 / 21;
else
angle -= 4.5;
}
else
{
if (anglediff > 4.5)
angle = ang - 90.0 / 21;
else
angle += 4.5;
}
bJustAttacked = true;
}
}
class GauntletsPowered : Gauntlets
{
Default
{
+WEAPON.POWERED_UP
Tag "$TAG_GAUNTLETSP";
Obituary "$OB_MPPGAUNTLETS";
Weapon.SisterWeapon "Gauntlets";
}
States
{
Ready:
GAUN GHI 4 A_WeaponReady;
Loop;
Deselect:
GAUN G 1 A_Lower;
Loop;
Select:
GAUN G 1 A_Raise;
Loop;
Fire:
GAUN J 4 A_PlaySound("weapons/gauntletsuse", CHAN_WEAPON);
GAUN K 4;
Hold:
GAUN LMN 4 BRIGHT A_GauntletAttack(1);
GAUN K 4 A_ReFire;
GAUN J 4 A_Light0;
Goto Ready;
}
}
// Gauntlet puff 1 ----------------------------------------------------------
class GauntletPuff1 : Actor
{
Default
{
+NOBLOCKMAP
+NOGRAVITY
+PUFFONACTORS
RenderStyle "Translucent";
Alpha 0.4;
VSpeed 0.8;
}
States
{
Spawn:
PUF1 ABCD 4 BRIGHT;
Stop;
}
}
// Gauntlet puff 2 ---------------------------------------------------------
class GauntletPuff2 : GauntletPuff1
{
States
{
Spawn:
PUF1 EFGH 4 BRIGHT;
Stop;
}
}