summaryrefslogtreecommitdiff
path: root/src/strife/p_pspr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/strife/p_pspr.c')
-rw-r--r--src/strife/p_pspr.c970
1 files changed, 970 insertions, 0 deletions
diff --git a/src/strife/p_pspr.c b/src/strife/p_pspr.c
new file mode 100644
index 00000000..6e2ccfad
--- /dev/null
+++ b/src/strife/p_pspr.c
@@ -0,0 +1,970 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION:
+// Weapon sprite animation, weapon objects.
+// Action functions for weapons.
+//
+//-----------------------------------------------------------------------------
+
+
+#include "doomdef.h"
+#include "d_event.h"
+
+#include "deh_misc.h"
+
+#include "m_random.h"
+#include "p_local.h"
+#include "s_sound.h"
+
+// State.
+#include "doomstat.h"
+
+// Data.
+#include "sounds.h"
+
+#include "p_pspr.h"
+
+#define LOWERSPEED FRACUNIT*6
+#define RAISESPEED FRACUNIT*6
+
+#define WEAPONBOTTOM 128*FRACUNIT
+#define WEAPONTOP 32*FRACUNIT
+
+
+
+//
+// P_SetPsprite
+//
+// [STRIFE]
+// villsa: Removed psprite sx, sy modification via misc1/2
+//
+void
+P_SetPsprite
+( player_t* player,
+ int position,
+ statenum_t stnum )
+{
+ pspdef_t* psp;
+ state_t* state;
+
+ psp = &player->psprites[position];
+
+ do
+ {
+ if (!stnum)
+ {
+ // object removed itself
+ psp->state = NULL;
+ break;
+ }
+
+ state = &states[stnum];
+ psp->state = state;
+ psp->tics = state->tics; // could be 0
+
+ // villsa [STRIFE] unused
+ /*if (state->misc1)
+ {
+ // coordinate set
+ psp->sx = state->misc1 << FRACBITS;
+ psp->sy = state->misc2 << FRACBITS;
+ }*/
+
+ // Call action routine.
+ // Modified handling.
+ if (state->action.acp2)
+ {
+ state->action.acp2(player, psp);
+ if (!psp->state)
+ break;
+ }
+
+ stnum = psp->state->nextstate;
+
+ } while (!psp->tics);
+ // an initial state of 0 could cycle through
+}
+
+// haleyjd 09/06/10: [STRIFE] Removed P_CalcSwing
+
+//
+// P_BringUpWeapon
+// Starts bringing the pending weapon up
+// from the bottom of the screen.
+// Uses player
+//
+// villsa [STRIFE] Modifications for Strife weapons
+//
+void P_BringUpWeapon (player_t* player)
+{
+ statenum_t newstate;
+
+ if (player->pendingweapon == wp_nochange)
+ player->pendingweapon = player->readyweapon;
+
+ if (player->pendingweapon == wp_flame)
+ S_StartSound (player->mo, sfx_flidl); // villsa [STRIFE] flame sounds
+
+ newstate = weaponinfo[player->pendingweapon].upstate;
+
+ player->psprites[ps_weapon].sy = WEAPONBOTTOM;
+ P_SetPsprite (player, ps_weapon, newstate);
+
+ // villsa [STRIFE] set various flash states
+ if(player->pendingweapon == wp_elecbow)
+ P_SetPsprite(player, ps_flash, S_XBOW_10); // 31
+ else if(player->pendingweapon == wp_sigil && player->sigiltype)
+ P_SetPsprite(player, ps_flash, S_SIGH_00 + player->sigiltype); // 117
+ else
+ P_SetPsprite(player, ps_flash, S_NULL);
+
+ player->pendingweapon = wp_nochange;
+}
+
+//
+// P_CheckAmmo
+// Returns true if there is enough ammo to shoot.
+// If not, selects the next weapon to use.
+//
+// villsa [STRIFE] Changes to handle Strife weapons
+//
+boolean P_CheckAmmo (player_t* player)
+{
+ ammotype_t ammo;
+ int count;
+
+ ammo = weaponinfo[player->readyweapon].ammo;
+
+ // Minimal amount for one shot varies.
+ if (player->readyweapon == wp_torpedo)
+ count = 30;
+ else if (player->readyweapon == wp_mauler)
+ count = 20;
+ else
+ count = 1; // Regular.
+
+ // Some do not need ammunition anyway.
+ // Return if current ammunition sufficient.
+ if (ammo == am_noammo || player->ammo[ammo] >= count)
+ return true;
+
+ // Out of ammo, pick a weapon to change to.
+ // Preferences are set here.
+
+ // villsa [STRIFE] new weapon preferences
+ if (player->weaponowned[wp_mauler] && player->ammo[am_cell] >= 20)
+ player->pendingweapon = wp_mauler;
+
+ else if(player->weaponowned[wp_rifle] && player->ammo[am_bullets])
+ player->pendingweapon = wp_rifle;
+
+ else if (player->weaponowned[wp_elecbow] && player->ammo[am_elecbolts])
+ player->pendingweapon = wp_elecbow;
+
+ else if (player->weaponowned[wp_missile] && player->ammo[am_missiles])
+ player->pendingweapon = wp_missile;
+
+ else if (player->weaponowned[wp_flame] && player->ammo[am_cell])
+ player->pendingweapon = wp_flame;
+
+ else if (player->weaponowned[wp_hegrenade] && player->ammo[am_hegrenades])
+ player->pendingweapon = wp_hegrenade;
+
+ else if (player->weaponowned[wp_poisonbow] && player->ammo[am_poisonbolts])
+ player->pendingweapon = wp_poisonbow;
+
+ else if (player->weaponowned[wp_wpgrenade] && player->ammo[am_wpgrenades])
+ player->pendingweapon = wp_wpgrenade;
+
+ // BUG: This will *never* be selected for an automatic switch because the
+ // normal Mauler is higher priority and uses less ammo.
+ else if (player->weaponowned[wp_torpedo] && player->ammo[am_cell] >= 30)
+ player->pendingweapon = wp_torpedo;
+
+ else
+ player->pendingweapon = wp_fist;
+
+
+ // Now set appropriate weapon overlay.
+ P_SetPsprite(player, ps_weapon, weaponinfo[player->readyweapon].downstate);
+
+ return false;
+}
+
+
+//
+// P_FireWeapon.
+//
+// villsa [STRIFE] Changes for player state and weapons
+//
+void P_FireWeapon (player_t* player)
+{
+ statenum_t newstate;
+
+ if (!P_CheckAmmo (player))
+ return;
+
+ P_SetMobjState (player->mo, S_PLAY_05); // 292
+ newstate = weaponinfo[player->readyweapon].atkstate;
+ P_SetPsprite (player, ps_weapon, newstate);
+
+ // villsa [STRIFE] exclude these weapons from causing noise
+ if(player->readyweapon > wp_elecbow && player->readyweapon != wp_poisonbow)
+ P_NoiseAlert (player->mo, player->mo);
+}
+
+
+
+//
+// P_DropWeapon
+// Player died, so put the weapon away.
+//
+void P_DropWeapon (player_t* player)
+{
+ P_SetPsprite (player,
+ ps_weapon,
+ weaponinfo[player->readyweapon].downstate);
+}
+
+
+
+//
+// A_WeaponReady
+// The player can fire the weapon
+// or change to another weapon at this time.
+// Follows after getting weapon up,
+// or after previous attack/fire sequence.
+//
+void A_WeaponReady( player_t* player, pspdef_t* psp)
+{
+ statenum_t newstate;
+ int angle;
+
+ // get out of attack state
+ if (player->mo->state == &states[S_PLAY_05] || // 292
+ player->mo->state == &states[S_PLAY_06]) // 293
+ {
+ P_SetMobjState (player->mo, S_PLAY_00); // 287
+ }
+
+ // villsa [STRIFE] check for wp_flame instead of chainsaw
+ // haleyjd 09/06/10: fixed state (00 rather than 01)
+ if (player->readyweapon == wp_flame
+ && psp->state == &states[S_FLMT_00]) // 62
+ {
+ S_StartSound (player->mo, sfx_flidl);
+ }
+
+ // check for change
+ // if player is dead, put the weapon away
+ if (player->pendingweapon != wp_nochange || !player->health)
+ {
+ // change weapon
+ // (pending weapon should allready be validated)
+ newstate = weaponinfo[player->readyweapon].downstate;
+ P_SetPsprite (player, ps_weapon, newstate);
+ return;
+ }
+
+ // check for fire
+ // the missile launcher and torpedo do not auto fire
+ if (player->cmd.buttons & BT_ATTACK)
+ {
+
+ if ( !player->attackdown
+ || (player->readyweapon != wp_missile
+ && player->readyweapon != wp_torpedo)) // villsa [STRIFE] replace bfg with torpedo
+ {
+ player->attackdown = true;
+ P_FireWeapon (player);
+ return;
+ }
+ }
+ else
+ player->attackdown = false;
+
+ // bob the weapon based on movement speed
+ angle = (128*leveltime)&FINEMASK;
+ psp->sx = FRACUNIT + FixedMul (player->bob, finecosine[angle]);
+ angle &= FINEANGLES/2-1;
+ psp->sy = WEAPONTOP + FixedMul (player->bob, finesine[angle]);
+}
+
+
+
+//
+// A_ReFire
+// The player can re-fire the weapon
+// without lowering it entirely.
+//
+void A_ReFire
+( player_t* player,
+ pspdef_t* psp )
+{
+
+ // check for fire
+ // (if a weaponchange is pending, let it go through instead)
+ if ( (player->cmd.buttons & BT_ATTACK)
+ && player->pendingweapon == wp_nochange
+ && player->health)
+ {
+ player->refire++;
+ P_FireWeapon (player);
+ }
+ else
+ {
+ player->refire = 0;
+ P_CheckAmmo (player);
+ }
+}
+
+//
+// A_CheckReload
+//
+void A_CheckReload(player_t* player, pspdef_t* psp)
+{
+ P_CheckAmmo(player);
+
+ // villsa [STRIFE] set animating sprite for crossbow
+ if(player->readyweapon == wp_elecbow)
+ P_SetPsprite(player, player->readyweapon, S_XBOW_10);
+}
+
+
+
+//
+// A_Lower
+// Lowers current weapon,
+// and changes weapon at bottom.
+//
+void
+A_Lower
+( player_t* player,
+ pspdef_t* psp )
+{
+ psp->sy += LOWERSPEED;
+
+ // Is already down.
+ if (psp->sy < WEAPONBOTTOM )
+ return;
+
+ // Player is dead.
+ if (player->playerstate == PST_DEAD)
+ {
+ psp->sy = WEAPONBOTTOM;
+
+ // don't bring weapon back up
+ return;
+ }
+
+ // The old weapon has been lowered off the screen,
+ // so change the weapon and start raising it
+ if (!player->health)
+ {
+ // Player is dead, so keep the weapon off screen.
+ P_SetPsprite (player, ps_weapon, S_NULL);
+ return;
+ }
+
+ player->readyweapon = player->pendingweapon;
+
+ P_BringUpWeapon (player);
+}
+
+
+//
+// A_Raise
+//
+void
+A_Raise
+( player_t* player,
+ pspdef_t* psp )
+{
+ statenum_t newstate;
+
+ psp->sy -= RAISESPEED;
+
+ if (psp->sy > WEAPONTOP )
+ return;
+
+ psp->sy = WEAPONTOP;
+
+ // The weapon has been raised all the way,
+ // so change to the ready state.
+ newstate = weaponinfo[player->readyweapon].readystate;
+
+ P_SetPsprite (player, ps_weapon, newstate);
+}
+
+
+
+//
+// A_GunFlash
+//
+void
+A_GunFlash
+( player_t* player,
+ pspdef_t* psp )
+{
+ P_SetMobjState (player->mo, S_PLAY_06);
+ P_SetPsprite (player,ps_flash,weaponinfo[player->readyweapon].flashstate);
+}
+
+
+
+//
+// WEAPON ATTACKS
+//
+
+
+//
+// A_Punch
+//
+
+void A_Punch(player_t* player, pspdef_t* psp)
+{
+ angle_t angle;
+ int damage;
+ int slope;
+ int sound;
+
+ // villsa [STRIFE] new damage formula
+ damage = ((player->stamina / 10) + 2) * (psp->tics + 3) & P_Random();
+
+ if(player->powers[pw_strength])
+ damage *= 10;
+
+ angle = player->mo->angle;
+ angle += (P_Random()-P_Random())<<18;
+ slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
+ P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);
+
+ // turn to face target
+ if(linetarget)
+ {
+ // villsa [STRIFE] check for non-flesh types
+ if(linetarget->flags & MF_NOBLOOD)
+ sound = sfx_mtalht;
+ else
+ sound = sfx_meatht;
+
+ S_StartSound (player->mo, sound);
+ player->mo->angle = R_PointToAngle2 (player->mo->x,
+ player->mo->y,
+ linetarget->x,
+ linetarget->y);
+
+ // villsa [STRIFE] apply flag
+ player->mo->flags |= MF_JUSTATTACKED;
+ // villsa [STRIFE] do punch alert routine
+ P_DoPunchAlert(player->mo, linetarget);
+ }
+ else
+ S_StartSound (player->mo, sfx_swish);
+}
+
+
+//
+// A_FireFlameThrower
+// villsa [STRIFE] new codepointer
+//
+
+void A_FireFlameThrower(player_t* player, pspdef_t* psp)
+{
+ mobj_t* mo;
+
+ P_SetMobjState(player->mo, S_PLAY_06);
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ player->mo->angle += (P_Random() - P_Random()) << 18;
+
+ mo = P_SpawnPlayerMissile(player->mo, MT_SFIREBALL);
+ mo->momz += (5*FRACUNIT);
+}
+
+//
+// A_FireMissile
+// villsa [STRIFE] completly new compared to the original
+//
+
+void A_FireMissile(player_t* player, pspdef_t* psp)
+{
+ angle_t an;
+ mobj_t* mo;
+
+ an = player->mo->angle;
+ player->mo->angle += (P_Random() - P_Random())<<(19 - (player->accuracy * 4 / 100));
+ P_SetMobjState(player->mo, S_PLAY_06);
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ P_SpawnPlayerMissile(player->mo, MT_MINIMISSLE);
+ player->mo->angle = an;
+}
+
+//
+// A_FireMauler2
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireMauler2(player_t* player, pspdef_t* pspr)
+{
+ P_SetMobjState(player->mo, S_PLAY_06);
+ P_DamageMobj(player->mo, player->mo, NULL, 20);
+ player->ammo[weaponinfo[player->readyweapon].ammo] -= 30;
+ P_SpawnPlayerMissile(player->mo, MT_TORPEDO);
+ P_Thrust(player, player->mo->angle + ANG180, 512000);
+}
+
+//
+// A_FireGrenade
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireGrenade(player_t* player, pspdef_t* pspr)
+{
+ mobjtype_t type;
+ mobj_t* mo;
+ state_t* st1;
+ state_t* st2;
+ angle_t an;
+ fixed_t radius;
+
+ // decide on what type of grenade to spawn
+ if(player->readyweapon == wp_hegrenade)
+ type = MT_HEGRENADE;
+ else
+ {
+ if(player->readyweapon == wp_wpgrenade)
+ type = MT_PGRENADE;
+ }
+
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+
+ // set flash frame
+ st1 = &states[(pspr->state - states) + weaponinfo[player->readyweapon].flashstate];
+ st2 = &states[weaponinfo[player->readyweapon].atkstate];
+ P_SetPsprite(player, ps_flash, st1 - st2);
+
+ player->mo->z += MAXRADIUS; // ugh
+ mo = P_SpawnMortar(player->mo, type);
+ player->mo->z -= MAXRADIUS; // ugh
+
+ // change momz based on player's pitch
+ mo->momz = FixedMul((player->pitch<<FRACBITS) / 160, mo->info->speed) + (8*FRACUNIT);
+ S_StartSound(mo, mo->info->seesound);
+
+ radius = mobjinfo[type].radius + player->mo->info->radius;
+ an = (player->mo->angle >> ANGLETOFINESHIFT);
+
+ mo->x += FixedMul(finecosine[an], radius + (4*FRACUNIT));
+ mo->y += FixedMul(finesine[an], radius + (4*FRACUNIT));
+
+ // shoot grenade from left or right side?
+ if(&states[weaponinfo[player->readyweapon].atkstate] == pspr->state)
+ an = (player->mo->angle - ANG90) >> ANGLETOFINESHIFT;
+ else
+ an = (player->mo->angle + ANG90) >> ANGLETOFINESHIFT;
+
+ mo->x += FixedMul((15*FRACUNIT), finecosine[an]);
+ mo->y += FixedMul((15*FRACUNIT), finesine[an]);
+
+ // set bounce flag
+ mo->flags |= MF_BOUNCE;
+}
+
+//
+// A_FireElectricBolt
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireElectricBolt(player_t* player, pspdef_t* pspr)
+{
+ angle_t an = player->mo->angle;
+
+ player->mo->angle += (P_Random() - P_Random()) << (18 - (player->accuracy * 4 / 100));
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ P_SpawnPlayerMissile(player->mo, MT_ELECARROW);
+ player->mo->angle = an;
+ S_StartSound(player->mo, sfx_xbow);
+}
+
+//
+// A_FirePoisonBolt
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FirePoisonBolt(player_t* player, pspdef_t* pspr)
+{
+ angle_t an = player->mo->angle;
+
+ player->mo->angle += (P_Random() - P_Random())<<(18 - (player->accuracy * 4 / 100));
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ P_SpawnPlayerMissile(player->mo, MT_POISARROW);
+ player->mo->angle = an;
+ S_StartSound(player->mo, sfx_xbow);
+}
+
+//
+// P_BulletSlope
+// Sets a slope so a near miss is at aproximately
+// the height of the intended target
+//
+// haleyjd 09/06/10 [STRIFE] Modified with a little target hack...
+//
+fixed_t bulletslope;
+
+
+void P_BulletSlope (mobj_t *mo)
+{
+ angle_t an;
+
+ // see which target is to be aimed at
+ an = mo->angle;
+ bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
+
+ if (!linetarget)
+ {
+ an += 1<<26;
+ bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
+ if (!linetarget)
+ {
+ an -= 2<<26;
+ bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
+ }
+ }
+
+ // haleyjd 09/06/10: [STRIFE] Somebody added this here, and without it, you
+ // will get spurious crashing in routines such as P_LookForPlayers!
+ if(linetarget)
+ mo->target = linetarget;
+}
+
+
+//
+// P_GunShot
+//
+// [STRIFE] Modifications to support accuracy.
+//
+void
+P_GunShot
+( mobj_t* mo,
+ boolean accurate )
+{
+ angle_t angle;
+ int damage;
+ int t;
+
+ damage = 4*(P_Random ()%3+4); // villsa [STRIFE] different damage formula
+ angle = mo->angle;
+
+ // villsa [STRIFE] apply player accuracy
+ if (!accurate)
+ {
+ t = P_Random();
+ angle += (t - P_Random())<<(20 - (mo->player->accuracy * 4 / 100));
+ }
+
+ P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);
+}
+
+//
+// A_FireRifle
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireRifle(player_t* player, pspdef_t* pspr)
+{
+ S_StartSound(player->mo, sfx_rifle);
+
+ if(player->ammo[weaponinfo[player->readyweapon].ammo])
+ {
+ P_SetMobjState(player->mo, S_PLAY_06);
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ P_BulletSlope(player->mo);
+ P_GunShot(player->mo, !player->refire);
+ }
+}
+
+//
+// A_FireMauler1
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireMauler1(player_t* player, pspdef_t* pspr)
+{
+ int i;
+ angle_t angle;
+ int damage;
+
+ if(player->ammo[weaponinfo[player->readyweapon].ammo] > 20)
+ {
+ player->ammo[weaponinfo[player->readyweapon].ammo] -= 20;
+ P_BulletSlope(player->mo);
+ S_StartSound(player->mo, sfx_pgrdat);
+
+ for(i = 0; i < 20; i++)
+ {
+ damage = 5*(P_Random ()%3+1);
+ angle = player->mo->angle;
+ angle += (P_Random()-P_Random())<<19;
+ P_LineAttack(player->mo, angle, MISSILERANGE,
+ bulletslope + ((P_Random()-P_Random())<<5), damage);
+ }
+ }
+}
+
+//
+// A_SigilSound
+// villsa [STRIFE] - new codepointer
+//
+
+void A_SigilSound(player_t* player, pspdef_t* pspr)
+{
+ S_StartSound(player->mo, sfx_siglup);
+ player->extralight = 2;
+
+}
+
+//
+// A_FireSigil
+// villsa [STRIFE] - new codepointer
+//
+
+void A_FireSigil(player_t* player, pspdef_t* pspr)
+{
+ mobj_t* mo;
+ angle_t an;
+ int i;
+
+ // keep info on armor because sigil does piercing damage
+ i = player->armortype;
+ player->armortype = 0;
+ P_DamageMobj(player->mo, player->mo, 0, 4 * player->sigiltype + 1);
+
+ // restore armor
+ player->armortype = i;
+
+ S_StartSound(player->mo, sfx_siglup);
+
+ switch(player->sigiltype)
+ {
+ // falling lightning bolts from the sky
+ case 0:
+ P_BulletSlope(player->mo);
+ if(linetarget)
+ {
+ mo = P_SpawnMobj(linetarget->x, linetarget->y, -ONFLOORZ, MT_SIGIL_A_GROUND);
+ mo->tracer = linetarget;
+ }
+ else
+ {
+ an = player->mo->angle>>ANGLETOFINESHIFT;
+ mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SIGIL_A_GROUND);
+ mo->momx += FixedMul((28*FRACUNIT), finecosine[an]);
+ mo->momy += FixedMul((28*FRACUNIT), finesine[an]);
+ }
+ mo->health = -1;
+ mo->target = player->mo;
+ break;
+
+ // simple projectile
+ case 1:
+ P_SpawnPlayerMissile(player->mo, MT_SIGIL_B_SHOT)->health = -1;
+ break;
+
+ // spread shot
+ case 2:
+ player->mo->angle -= ANG90;
+ for(i = 0; i < 20; i++)
+ {
+ player->mo->angle += (ANG90 / 10);
+ mo = P_SpawnMortar(player->mo, MT_SIGIL_C_SHOT);
+ mo->health = -1;
+ mo->z = player->mo->z + (32*FRACUNIT);
+ }
+ player->mo->angle -= ANG90;
+ break;
+
+ // tracer attack
+ case 3:
+ P_BulletSlope(player->mo);
+ if(linetarget)
+ {
+ mo = P_SpawnPlayerMissile(player->mo, MT_SIGIL_D_SHOT);
+ mo->tracer = linetarget;
+ }
+ else
+ {
+ an = player->mo->angle>>ANGLETOFINESHIFT;
+ mo = P_SpawnPlayerMissile(player->mo, MT_SIGIL_D_SHOT);
+ mo->momx += FixedMul(mo->info->speed, finecosine[an]);
+ mo->momy += FixedMul(mo->info->speed, finesine[an]);
+ }
+ mo->health = -1;
+ break;
+
+ // mega blast
+ case 4:
+ mo = P_SpawnPlayerMissile(player->mo, MT_SIGIL_E_SHOT);
+ mo->health = -1;
+ if(!linetarget)
+ {
+ an = player->pitch>>ANGLETOFINESHIFT;
+ mo->momz += FixedMul(finesine[an], mo->info->speed);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+//
+// A_GunFlashThinker
+// villsa [STRIFE] - new codepointer
+//
+
+void A_GunFlashThinker(player_t* player, pspdef_t* pspr)
+{
+ if(player->readyweapon == wp_sigil && player->sigiltype)
+ P_SetPsprite(player, ps_flash, S_SIGH_00 + player->sigiltype);
+ else
+ P_SetPsprite(player, ps_flash, S_NULL);
+
+}
+
+
+//
+// ?
+//
+void A_Light0 (player_t *player, pspdef_t *psp)
+{
+ player->extralight = 0;
+}
+
+void A_Light1 (player_t *player, pspdef_t *psp)
+{
+ player->extralight = 1;
+}
+
+void A_Light2 (player_t *player, pspdef_t *psp)
+{
+ player->extralight = 2;
+}
+
+//
+// A_SigilShock
+// villsa [STRIFE] - new codepointer
+//
+
+void A_SigilShock (player_t *player, pspdef_t *psp)
+{
+ player->extralight = -3;
+}
+
+//
+// A_TorpedoExplode
+// villsa [STRIFE] - new codepointer
+//
+
+void A_TorpedoExplode(mobj_t* actor)
+{
+ int i = 0;
+
+ actor->angle -= ANG180;
+
+ for(i = 0; i < 80; i++)
+ {
+ actor->angle += (ANG90 / 20);
+ P_SpawnMortar(actor, MT_TORPEDOSPREAD)->target = actor->target;
+ }
+}
+
+//
+// A_MaulerSound
+// villsa [STRIFE] - new codepointer
+//
+
+void A_MaulerSound(player_t *player, pspdef_t *psp)
+{
+ S_StartSound(player->mo, sfx_proton);
+ psp->sx += (P_Random() - P_Random()) << 10;
+ psp->sy += (P_Random() - P_Random()) << 10;
+
+}
+
+
+//
+// P_SetupPsprites
+// Called at start of level for each player.
+//
+void P_SetupPsprites(player_t* player)
+{
+ int i;
+
+ // remove all psprites
+ for(i = 0; i < NUMPSPRITES; i++)
+ player->psprites[i].state = NULL;
+
+ // spawn the gun
+ player->pendingweapon = player->readyweapon;
+ P_BringUpWeapon(player);
+}
+
+
+
+
+//
+// P_MovePsprites
+// Called every tic by player thinking routine.
+//
+void P_MovePsprites (player_t* player)
+{
+ int i;
+ pspdef_t* psp;
+ state_t* state;
+
+ psp = &player->psprites[0];
+ for(i = 0; i < NUMPSPRITES; i++, psp++)
+ {
+ // a null state means not active
+ if((state = psp->state))
+ {
+ // drop tic count and possibly change state
+
+ // a -1 tic count never changes
+ if(psp->tics != -1)
+ {
+ psp->tics--;
+ if(!psp->tics)
+ P_SetPsprite (player, i, psp->state->nextstate);
+ }
+ }
+ }
+
+ player->psprites[ps_flash].sx = player->psprites[ps_weapon].sx;
+ player->psprites[ps_flash].sy = player->psprites[ps_weapon].sy;
+
+ // villsa [STRIFE] extra stuff for targeter
+ player->psprites[ps_targleft].sx = (100 - player->accuracy) - (160*FRACUNIT);
+ player->psprites[ps_targright].sx = (100 - player->accuracy) + (160*FRACUNIT);
+}
+
+