mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 08:30:49 +00:00
0770c0022c
Many uses of random() & value have been turned into random(0, value). This is not only more efficient, it also ensures better random distribution because the parameter-less variant only returns values between 0 and 255.
249 lines
5 KiB
Text
249 lines
5 KiB
Text
|
|
// The Cleric's Serpent Staff -----------------------------------------------
|
|
|
|
class CWeapStaff : ClericWeapon
|
|
{
|
|
Default
|
|
{
|
|
Weapon.SelectionOrder 1600;
|
|
Weapon.AmmoUse1 1;
|
|
Weapon.AmmoGive1 25;
|
|
Weapon.KickBack 150;
|
|
Weapon.YAdjust 10;
|
|
Weapon.AmmoType1 "Mana1";
|
|
Inventory.PickupMessage "$TXT_WEAPON_C2";
|
|
Obituary "$OB_MPCWEAPSTAFFM";
|
|
Tag "$TAG_CWEAPSTAFF";
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
WCSS A -1;
|
|
Stop;
|
|
Select:
|
|
CSSF C 1 A_Raise;
|
|
Loop;
|
|
Deselect:
|
|
CSSF B 3;
|
|
CSSF C 4;
|
|
CSSF C 1 A_Lower;
|
|
Wait;
|
|
Ready:
|
|
CSSF C 4;
|
|
CSSF B 3 A_CStaffInitBlink;
|
|
CSSF AAAAAAA 1 A_WeaponReady;
|
|
CSSF A 1 A_CStaffCheckBlink;
|
|
Goto Ready + 2;
|
|
Fire:
|
|
CSSF A 1 Offset (0, 45) A_CStaffCheck;
|
|
CSSF J 1 Offset (0, 50) A_CStaffAttack;
|
|
CSSF J 2 Offset (0, 50);
|
|
CSSF J 2 Offset (0, 45);
|
|
CSSF A 2 Offset (0, 40);
|
|
CSSF A 2 Offset (0, 36);
|
|
Goto Ready + 2;
|
|
Blink:
|
|
CSSF BBBCCCCCBBB 1 A_WeaponReady;
|
|
Goto Ready + 2;
|
|
Drain:
|
|
CSSF K 10 Offset (0, 36);
|
|
Goto Ready + 2;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_CStaffCheck
|
|
//
|
|
//============================================================================
|
|
|
|
action void A_CStaffCheck()
|
|
{
|
|
FTranslatedLineTarget t;
|
|
|
|
if (player == null)
|
|
{
|
|
return;
|
|
}
|
|
Weapon weapon = player.ReadyWeapon;
|
|
|
|
int damage = random[StaffCheck](20, 35);
|
|
int max = player.mo.GetMaxHealth();
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
for (int j = 1; j >= -1; j -= 2)
|
|
{
|
|
double ang = angle + j*i*(45. / 16);
|
|
double slope = AimLineAttack(ang, 1.5 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
|
|
if (t.linetarget)
|
|
{
|
|
LineAttack(ang, 1.5 * DEFMELEERANGE, slope, damage, 'Melee', "CStaffPuff", false, t);
|
|
if (t.linetarget != null)
|
|
{
|
|
angle = t.angleFromSource;
|
|
if (((t.linetarget.player && (!t.linetarget.IsTeammate(self) || level.teamdamage != 0)) || t.linetarget.bIsMonster)
|
|
&& (!t.linetarget.bDormant && !t.linetarget.bInvulnerable))
|
|
{
|
|
int newLife = player.health + (damage >> 3);
|
|
newLife = newLife > max ? max : newLife;
|
|
if (newLife > player.health)
|
|
{
|
|
health = player.health = newLife;
|
|
}
|
|
if (weapon != null)
|
|
{
|
|
State newstate = weapon.FindState("Drain");
|
|
if (newstate != null) player.SetPsprite(PSP_WEAPON, newstate);
|
|
}
|
|
}
|
|
if (weapon != null)
|
|
{
|
|
weapon.DepleteAmmo(weapon.bAltFire, false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_CStaffAttack
|
|
//
|
|
//============================================================================
|
|
|
|
action void A_CStaffAttack()
|
|
{
|
|
if (player == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Weapon weapon = player.ReadyWeapon;
|
|
if (weapon != null)
|
|
{
|
|
if (!weapon.DepleteAmmo (weapon.bAltFire))
|
|
return;
|
|
}
|
|
Actor mo = SpawnPlayerMissile ("CStaffMissile", angle - 3.0);
|
|
if (mo)
|
|
{
|
|
mo.WeaveIndexXY = 32;
|
|
}
|
|
mo = SpawnPlayerMissile ("CStaffMissile", angle + 3.0);
|
|
if (mo)
|
|
{
|
|
mo.WeaveIndexXY = 0;
|
|
}
|
|
A_PlaySound ("ClericCStaffFire", CHAN_WEAPON);
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_CStaffInitBlink
|
|
//
|
|
//============================================================================
|
|
|
|
action void A_CStaffInitBlink()
|
|
{
|
|
weaponspecial = (random[CStaffBlink]() >> 1) + 20;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_CStaffCheckBlink
|
|
//
|
|
//============================================================================
|
|
|
|
action void A_CStaffCheckBlink()
|
|
{
|
|
if (player && player.ReadyWeapon)
|
|
{
|
|
if (!--weaponspecial)
|
|
{
|
|
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.FindState ("Blink"));
|
|
weaponspecial = (random[CStaffBlink]() + 50) >> 2;
|
|
}
|
|
else
|
|
{
|
|
A_WeaponReady();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Serpent Staff Missile ----------------------------------------------------
|
|
|
|
class CStaffMissile : Actor
|
|
{
|
|
Default
|
|
{
|
|
Speed 22;
|
|
Radius 12;
|
|
Height 10;
|
|
Damage 5;
|
|
RenderStyle "Add";
|
|
Projectile;
|
|
DeathSound "ClericCStaffExplode";
|
|
Obituary "$OB_MPCWEAPSTAFFR";
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
CSSF DDEE 1 Bright A_CStaffMissileSlither;
|
|
Loop;
|
|
Death:
|
|
CSSF FG 4 Bright;
|
|
CSSF HI 3 Bright;
|
|
Stop;
|
|
}
|
|
|
|
override int DoSpecialDamage (Actor target, int damage, Name damagetype)
|
|
{
|
|
// Cleric Serpent Staff does poison damage
|
|
if (target.player)
|
|
{
|
|
target.player.PoisonPlayer (self, self.target, 20);
|
|
damage >>= 1;
|
|
}
|
|
return damage;
|
|
}
|
|
|
|
}
|
|
|
|
extend class Actor
|
|
{
|
|
|
|
//============================================================================
|
|
//
|
|
// A_CStaffMissileSlither
|
|
//
|
|
//============================================================================
|
|
|
|
void A_CStaffMissileSlither()
|
|
{
|
|
A_Weave(3, 0, 1., 0.);
|
|
}
|
|
|
|
}
|
|
|
|
// Serpent Staff Puff -------------------------------------------------------
|
|
|
|
class CStaffPuff : Actor
|
|
{
|
|
Default
|
|
{
|
|
+NOBLOCKMAP +NOGRAVITY
|
|
+PUFFONACTORS
|
|
RenderStyle "Translucent";
|
|
Alpha 0.6;
|
|
SeeSound "ClericCStaffHitThing";
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FHFX STUVW 4;
|
|
Stop;
|
|
}
|
|
}
|