mirror of
https://github.com/yquake2/zaero.git
synced 2024-11-21 19:41:07 +00:00
Added support for ANIM_REVERSE
Allows to define animations that go in the opposite direction of the usual flow. Added a couple of animations from Q2 3.21 that use ANIM_REVERSE. Make the "laser trip bomb" to use Weapon_Generic instead of the "copy & paste" version it used. Modified the original Weapon_Generic function to get the proper ammo quantity the weapon uses; useful for IT_AMMO weapons.
This commit is contained in:
parent
50f18732f6
commit
e3743c5b2c
5 changed files with 104 additions and 123 deletions
|
@ -1009,4 +1009,3 @@ void fire_bfg (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, f
|
|||
|
||||
gi.linkentity (bfg);
|
||||
}
|
||||
|
||||
|
|
|
@ -850,6 +850,7 @@ void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer);
|
|||
// g_pweapon.c
|
||||
//
|
||||
void PlayerNoise(edict_t *who, vec3_t where, int type);
|
||||
int get_ammo_usage(gitem_t *weap);
|
||||
|
||||
//
|
||||
// m_move.c
|
||||
|
@ -905,7 +906,7 @@ void ai_schoolSideStepLeft (edict_t *self, float dist);
|
|||
#define ANIM_PAIN 3
|
||||
#define ANIM_ATTACK 4
|
||||
#define ANIM_DEATH 5
|
||||
|
||||
#define ANIM_REVERSE 6
|
||||
|
||||
// client data that stays across multiple level loads
|
||||
typedef struct
|
||||
|
|
|
@ -996,7 +996,15 @@ void G_SetClientFrame (edict_t *ent)
|
|||
if (!ent->groundentity && client->anim_priority <= ANIM_WAVE)
|
||||
goto newanim;
|
||||
|
||||
if (ent->s.frame < client->anim_end)
|
||||
if (client->anim_priority == ANIM_REVERSE)
|
||||
{
|
||||
if (ent->s.frame > client->anim_end)
|
||||
{
|
||||
ent->s.frame--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ent->s.frame < client->anim_end)
|
||||
{ // continue an animation
|
||||
ent->s.frame++;
|
||||
return;
|
||||
|
|
|
@ -244,6 +244,19 @@ void ChangeWeapon (edict_t *ent)
|
|||
ent->client->weaponstate = WEAPON_ACTIVATING;
|
||||
ent->client->ps.gunframe = 0;
|
||||
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
|
||||
|
||||
ent->client->anim_priority = ANIM_PAIN;
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain1;
|
||||
ent->client->anim_end = FRAME_crpain4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_pain301;
|
||||
ent->client->anim_end = FRAME_pain304;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -425,6 +438,52 @@ void Drop_Weapon (edict_t *ent, gitem_t *item)
|
|||
ent->client->pers.inventory[index]--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns ammo used on a single shot for the given weapon
|
||||
*/
|
||||
int
|
||||
get_ammo_usage(gitem_t *weap)
|
||||
{
|
||||
if (!weap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handles grenades and tesla which only use 1 ammo per shot */
|
||||
/* have to check this because they don't store their ammo usage in weap->quantity */
|
||||
if (weap->flags & IT_AMMO)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* weapons store their ammo usage in the quantity field */
|
||||
return weap->quantity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Client (player) animation for changing weapon
|
||||
*/
|
||||
static void
|
||||
Change_Weap_Animation(edict_t *ent)
|
||||
{
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4 + 1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_pain304 + 1;
|
||||
ent->client->anim_end = FRAME_pain301;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -453,6 +512,15 @@ void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
ChangeWeapon (ent);
|
||||
return;
|
||||
}
|
||||
else if ( (FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) >= 4 )
|
||||
{
|
||||
unsigned short int remainder = FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe;
|
||||
// "if (remainder == 4)" at change_speed == 1
|
||||
if (remainder == 4)
|
||||
{
|
||||
Change_Weap_Animation(ent);
|
||||
}
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
return;
|
||||
|
@ -475,6 +543,10 @@ void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
{
|
||||
ent->client->weaponstate = WEAPON_DROPPING;
|
||||
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
|
||||
if ( (FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4 )
|
||||
{
|
||||
Change_Weap_Animation(ent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -484,7 +556,7 @@ void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
{
|
||||
ent->client->latched_buttons &= ~BUTTON_ATTACK;
|
||||
if ((!ent->client->ammo_index) ||
|
||||
( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity))
|
||||
( ent->client->pers.inventory[ent->client->ammo_index] >= get_ammo_usage(ent->client->pers.weapon) ))
|
||||
{
|
||||
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
|
||||
ent->client->weaponstate = WEAPON_FIRING;
|
||||
|
@ -603,6 +675,24 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
|
|||
|
||||
// play quad damage sound
|
||||
playQuadSound(ent);
|
||||
|
||||
if (ent->deadflag || ent->health <= 0 || ent->s.modelindex != 255)
|
||||
{
|
||||
return; // VWep animations screw up corpses
|
||||
}
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->client->anim_priority = ANIM_ATTACK;
|
||||
ent->s.frame = FRAME_crattak1 - 1;
|
||||
ent->client->anim_end = FRAME_crattak3;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
ent->s.frame = FRAME_wave08;
|
||||
ent->client->anim_end = FRAME_wave01;
|
||||
}
|
||||
}
|
||||
|
||||
void Weapon_Grenade (edict_t *ent)
|
||||
|
|
|
@ -520,124 +520,8 @@ void Weapon_LaserTripBomb(edict_t *ent)
|
|||
static int pause_frames[] = {24, 33, 43, 0};
|
||||
static int fire_frames[] = {6, 10, 15, 0};
|
||||
|
||||
const int deactivateFirst = 44;
|
||||
const int deactivateLast = 48;
|
||||
const int idleFirst = 16;
|
||||
const int idleLast = 43;
|
||||
const int fireFirst = 7;
|
||||
const int activateLast = 6;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_DROPPING)
|
||||
{
|
||||
if (ent->client->ps.gunframe == deactivateLast)
|
||||
{
|
||||
ChangeWeapon (ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_ACTIVATING)
|
||||
{
|
||||
if (ent->client->ps.gunframe == activateLast)
|
||||
{
|
||||
ent->client->weaponstate = WEAPON_READY;
|
||||
ent->client->ps.gunframe = idleFirst;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ent->client->newweapon) && (ent->client->weaponstate != WEAPON_FIRING))
|
||||
{
|
||||
ent->client->weaponstate = WEAPON_DROPPING;
|
||||
ent->client->ps.gunframe = deactivateFirst;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_READY)
|
||||
{
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
|
||||
{
|
||||
ent->client->latched_buttons &= ~BUTTON_ATTACK;
|
||||
if(ent->client->pers.inventory[ent->client->ammo_index])
|
||||
{
|
||||
ent->client->ps.gunframe = fireFirst;
|
||||
ent->client->weaponstate = WEAPON_FIRING;
|
||||
|
||||
// start the animation
|
||||
ent->client->anim_priority = ANIM_ATTACK;
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crattak1-1;
|
||||
ent->client->anim_end = FRAME_crattak9;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->s.frame = FRAME_attack1-1;
|
||||
ent->client->anim_end = FRAME_attack8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (level.time >= ent->pain_debounce_time)
|
||||
{
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
|
||||
ent->pain_debounce_time = level.time + 1;
|
||||
}
|
||||
NoAmmoWeaponChange (ent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->client->ps.gunframe == idleLast)
|
||||
{
|
||||
ent->client->ps.gunframe = idleFirst;
|
||||
return;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (n = 0; pause_frames[n]; n++)
|
||||
{
|
||||
if (ent->client->ps.gunframe == pause_frames[n])
|
||||
{
|
||||
if (rand()&15)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ent->client->ps.gunframe++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_FIRING)
|
||||
{
|
||||
int n = 0;
|
||||
for (n = 0; fire_frames[n]; n++)
|
||||
{
|
||||
if (ent->client->ps.gunframe == fire_frames[n])
|
||||
{
|
||||
weapon_lasertripbomb_fire(ent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fire_frames[n])
|
||||
ent->client->ps.gunframe++;
|
||||
|
||||
if (ent->client->ps.gunframe == idleFirst+1)
|
||||
ent->client->weaponstate = WEAPON_READY;
|
||||
}
|
||||
Weapon_Generic(ent, 6, 15, 43, 48, pause_frames,
|
||||
fire_frames, weapon_lasertripbomb_fire);
|
||||
}
|
||||
|
||||
void SP_misc_lasertripbomb(edict_t *bomb)
|
||||
|
@ -1649,4 +1533,3 @@ void Action_Push (edict_t *ent)
|
|||
else
|
||||
ent->client->ps.gunframe++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue