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.c1009
1 files changed, 1009 insertions, 0 deletions
diff --git a/src/strife/p_pspr.c b/src/strife/p_pspr.c
new file mode 100644
index 00000000..42a6bd7b
--- /dev/null
+++ b/src/strife/p_pspr.c
@@ -0,0 +1,1009 @@
+// 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;
+ int stamina;
+ int t;
+
+ // villsa [STRIFE] new damage formula
+ // haleyjd 09/19/10: seriously corrected...
+ stamina = player->stamina;
+ damage = (P_Random() & ((stamina/10) + 7)) * ((stamina/10) + 2);
+
+ if(player->powers[pw_strength])
+ damage *= 10;
+
+ angle = player->mo->angle;
+ t = P_Random();
+ angle += (t - P_Random()) << 18;
+ slope = P_AimLineAttack (player->mo, angle, PLAYERMELEERANGE);
+ P_LineAttack (player->mo, angle, PLAYERMELEERANGE, 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;
+ int t;
+
+ P_SetMobjState(player->mo, S_PLAY_06);
+ player->ammo[weaponinfo[player->readyweapon].ammo]--;
+ t = P_Random();
+ player->mo->angle += (t - 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;
+ int t;
+
+ // haleyjd 09/19/10: I previously missed an add op that meant it should be
+ // accuracy * 5, not 4. Checks out with other sources.
+ an = player->mo->angle;
+ t = P_Random();
+ player->mo->angle += (t - P_Random()) << (19 - (player->accuracy * 5 / 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;
+ }
+ else
+ {
+ type = MT_HEGRENADE;
+ fprintf(stderr, "Warning: A_FireGrenade used on wrong weapon!\n");
+ }
+
+ 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 += 32*FRACUNIT; // ugh
+ mo = P_SpawnMortar(player->mo, type);
+ player->mo->z -= 32*FRACUNIT; // 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;
+ int t;
+
+ // haleyjd 09/19/10: Use 5 mul on accuracy here as well
+ t = P_Random();
+ player->mo->angle += (t - P_Random()) << (18 - (player->accuracy * 5 / 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;
+ int t;
+
+ // haleyjd 09/19/10: Use 5 mul on accuracy here as well
+ t = P_Random();
+ player->mo->angle += (t - P_Random()) << (18 - (player->accuracy * 5 / 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;
+
+ angle = mo->angle;
+
+ // villsa [STRIFE] apply player accuracy
+ // haleyjd 09/18/10: made some corrections: use 5x accuracy;
+ // eliminated order-of-evaluation dependency
+ if (!accurate)
+ {
+ int t = P_Random();
+ angle += (t - P_Random()) << (20 - ((mo->player->accuracy * 5) / 100));
+ }
+
+ // haleyjd 09/18/10 [STRIFE] corrected damage formula and moved down to
+ // preserve proper P_Random call order.
+ damage = 4 * (P_Random() % 3 + 1);
+
+ 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); // 293
+ 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;
+
+ // haleyjd 09/18/10: Corrected ammo check to use >=
+ 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++)
+ {
+ int t;
+ damage = 5*(P_Random ()%3+1);
+ angle = player->mo->angle;
+ t = P_Random();
+ angle += (t - P_Random()) << 19;
+ t = P_Random();
+ P_LineAttack(player->mo, angle, 2112*FRACUNIT,
+ bulletslope + ((t - 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)
+ {
+ // haleyjd 09/18/10: corrected z coordinate
+ 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; // starting at 270...
+ for(i = 0; i < 20; i++) // increment by 1/10 of 90, 20 times.
+ {
+ 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; // subtract off the extra 90
+ 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;
+
+ 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)
+{
+ int t;
+ S_StartSound(player->mo, sfx_proton);
+ t = P_Random();
+ psp->sx += (t - P_Random()) << 10;
+ t = P_Random();
+ psp->sy += (t - 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 =
+ (160*FRACUNIT) - ((100 - player->accuracy) << FRACBITS);
+
+ player->psprites[ps_targright].sx =
+ ((100 - player->accuracy) << FRACBITS) + (160*FRACUNIT);
+}
+
+