diff --git a/src/g_weapon.c b/src/g_weapon.c index dbd9568..280a2e4 100644 --- a/src/g_weapon.c +++ b/src/g_weapon.c @@ -1009,4 +1009,3 @@ void fire_bfg (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, f gi.linkentity (bfg); } - diff --git a/src/header/local.h b/src/header/local.h index 9a09739..fbc6f77 100644 --- a/src/header/local.h +++ b/src/header/local.h @@ -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 diff --git a/src/player/view.c b/src/player/view.c index af68a1c..3b100d3 100644 --- a/src/player/view.c +++ b/src/player/view.c @@ -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; diff --git a/src/player/weapon.c b/src/player/weapon.c index aba22e6..4a00cb7 100644 --- a/src/player/weapon.c +++ b/src/player/weapon.c @@ -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) diff --git a/src/zaero/weapon.c b/src/zaero/weapon.c index 91a17c7..c8ac173 100644 --- a/src/zaero/weapon.c +++ b/src/zaero/weapon.c @@ -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++; } -