Handle player model weapon attachments & animation for all the weapons!

This commit is contained in:
Marco Cawthorne 2021-04-06 09:20:12 +02:00
parent 07090c5780
commit fe4bfc455f
20 changed files with 374 additions and 154 deletions

View File

@ -27,3 +27,10 @@ ClientGame_EntityUpdate(float id, float new)
return TRUE;
}
void
ClientGame_EntityRemove(void)
{
if (self.classname == "player")
Player_DestroyWeaponModel((base_player) self);
}

View File

@ -14,6 +14,147 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
string g_pbones[] =
{
"Bip01",
"Bip01 Footsteps",
"Bip01 Pelvis",
"Bip01 L Leg",
"Bip01 L Leg1",
"Bip01 L Foot",
"Bip01 L Toe0",
"Bip01 L Toe01",
"Bip01 L Toe02",
"Dummy16",
"Bip01 R Leg",
"Bip01 R Leg1",
"Bip01 R Foot",
"Bip01 R Toe0",
"Bip01 R Toe01",
"Bip01 R Toe02",
"Dummy11",
"Bip01 Spine",
"Bip01 Spine1",
"Bip01 Spine2",
"Bip01 Spine3",
"Bip01 Neck",
"Bip01 Head",
"Dummy21",
"Dummy08",
"Bone02",
"Bone03",
"Bone04",
"Dummy05",
"Bone09",
"Bone10",
"Dummy04",
"Bone05",
"Bone06",
"Dummy03",
"Bone07",
"Bone08",
"Dummy09",
"Bone11",
"Bone12",
"Dummy10",
"Bone13",
"Bone14",
"Bone15",
"Bip01 L Arm",
"Bip01 L Arm1",
"Bip01 L Arm2",
"Bip01 L Hand",
"Bip01 L Finger0",
"Bip01 L Finger01",
"Bip01 L Finger02",
"Dummy06",
"Bip01 L Finger1",
"Bip01 L Finger11",
"Bip01 L Finger12",
"Dummy07",
"Bip01 R Arm",
"Bip01 R Arm1",
"Bip01 R Arm2",
"Bip01 R Hand",
"Bip01 R Finger0",
"Bip01 R Finger01",
"Bip01 R Finger02",
"Dummy01",
"Bip01 R Finger1",
"Bip01 R Finger11",
"Bip01 R Finger12",
"Dummy02",
"Box02",
"Bone08",
"Bone15"
};
void
Player_HandleWeaponModel(base_player pp, float thirdperson)
{
player pl = (player)pp;
/* if we don't exist, create us */
if (!pl.p_model) {
pl.p_model = spawn();
}
/* only make it visible when it's a thirdperson drawcall */
pl.p_model.drawmask = (thirdperson) ? MASK_ENGINE:0;
/* let's not waste any time doing bone calculations then */
if (pl.p_model.drawmask == 0)
return;
/* what's the current weapon model supposed to be anyway? */
string wmodel = Weapons_GetPlayermodel(pl.activeweapon);
/* we changed weapons, update skeletonindex */
if (pl.p_model.model != wmodel) {
/* free memory */
if (pl.p_model.skeletonindex)
skel_delete(pl.p_model.skeletonindex);
/* set the new model and mark us updated */
setmodel(pl.p_model, wmodel);
pl.p_model.model = wmodel;
/* set the new skeletonindex */
pl.p_model.skeletonindex = skel_create(pl.p_model.modelindex);
}
/* follow player at all times */
setorigin(pl.p_model, pl.origin);
pl.p_model.angles = pl.angles;
skel_build(pl.p_model.skeletonindex, pl.p_model, pl.p_model.modelindex,0, 0, -1);
/* we have to loop through all valid bones of the weapon model and match them
* to the player one */
for (float i = 0; i < g_pbones.length; i++) {
vector bpos;
float pbone = gettagindex(pl, g_pbones[i]);
float wbone = gettagindex(pl.p_model, g_pbones[i]);
/* if the bone doesn't ignore in either skeletal mesh, ignore */
if (wbone <= 0 || pbone <= 0)
continue;
bpos = gettaginfo(pl, pbone);
/* the most expensive bit */
skel_set_bone_world(pl.p_model, wbone, bpos, v_forward, v_right, v_up);
}
}
/* we need to call this when a player entity gets removed */
void
Player_DestroyWeaponModel(entity pp)
{
player pl = (player)pp;
if (pl.p_model)
remove(pl.p_model);
}
void
Player_PreDraw(base_player pl, int thirdperson)
{
@ -41,4 +182,7 @@ Player_PreDraw(base_player pl, int thirdperson)
dynamiclight_set(p, LFIELD_FLAGS, 3);
}
}
Animation_PlayerUpdate(pl);
Player_HandleWeaponModel(pl, thirdperson);
}

View File

@ -19,7 +19,6 @@ void
Game_RunClientCommand(void)
{
Footsteps_Update();
Animation_PlayerUpdate();
PMove_Run();
}

View File

@ -91,5 +91,5 @@ enum
ANIM_CR_SHOOTBOW
};
void Animation_PlayerTop(float);
void Animation_PlayerTopTemp(float, float);
void Animation_PlayerTop(player, float, float);
void Animation_PlayerBottom(player, float, float);

View File

@ -14,22 +14,13 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.float baselerpfrac;
.float lerpfrac;
.float frame_time;
.float frame_old;
.float fWasCrouching;
.float frame2time;
.float frame2;
.float baseframe2time;
.float baseframe1time;
.float baseframe2;
// For lerping, sigh
.float frame_last;
.float baseframe_last;
.float subblendfrac;
.float subblend2frac;
.float subblendfrac;
.float baseframe1time;
.float bonecontrol1;
.float bonecontrol2;
.float bonecontrol3;
.float bonecontrol4;
void Animation_Print(string sWow) {
#ifdef CLIENT
@ -39,9 +30,23 @@ void Animation_Print(string sWow) {
#endif
}
var int autocvar_bone_spinebone = 0;
var int autocvar_bone_baseframe = 0;
var int autocvar_bone_frame = 0;
void
Animation_TimerUpdate(player pl)
{
makevectors([0, pl.angles[1], 0]);
/* top animation is always just being incremented */
pl.anim_top_time += input_timelength;
pl.anim_top_delay -= input_timelength;
/* we may be walking backwards, thus decrement bottom */
if (dotproduct(pl.velocity, v_forward) < 0) {
pl.anim_bottom_time -= input_timelength;
} else {
pl.anim_bottom_time += input_timelength;
}
}
/*
=================
Animation_PlayerUpdate
@ -51,128 +56,75 @@ depending on what the player is doing
=================
*/
void
Animation_PlayerUpdate(void)
Animation_PlayerUpdate(player pl)
{
self.basebone = gettagindex(self, "Bip01 Spine1");
pl.basebone = gettagindex(pl, "Bip01 Spine1");
// TODO: Make this faster
if (self.frame_time < time) {
player pl = (player)self;
self.frame = Weapons_GetAim(pl.activeweapon);
self.frame_old = self.frame;
if (pl.anim_top_delay <= 0.0f) {
pl.anim_top = Weapons_GetAim(pl.activeweapon);
}
/* in order to appear jumping, we want to not be on ground,
* but also make sure we're not just going down a ramp */
if (!(self.flags & FL_ONGROUND) && (self.velocity[2] > 0 || self.baseframe == ANIM_JUMP)) {
self.baseframe = ANIM_JUMP;
} else if (vlen(self.velocity) == 0) {
if (self.flags & FL_CROUCHING) {
self.baseframe = ANIM_CROUCHIDLE;
if (vlen(pl.velocity) == 0) {
if (pl.flags & FL_CROUCHING) {
pl.anim_bottom = ANIM_CROUCHIDLE;
} else {
self.baseframe = ANIM_IDLE;
pl.anim_bottom = ANIM_IDLE;
}
} else if (vlen(self.velocity) < 150) {
if (self.flags & FL_CROUCHING) {
self.baseframe = ANIM_CRAWL;
} else if (vlen(pl.velocity) < 150) {
if (pl.flags & FL_CROUCHING) {
pl.anim_bottom = ANIM_CRAWL;
} else {
self.baseframe = ANIM_WALK;
pl.anim_bottom = ANIM_WALK;
}
} else if (vlen(self.velocity) > 150) {
if (self.flags & FL_CROUCHING) {
self.baseframe = ANIM_CRAWL;
} else if (vlen(pl.velocity) > 150) {
if (pl.flags & FL_CROUCHING) {
pl.anim_bottom = ANIM_CRAWL;
} else {
self.baseframe = ANIM_RUN;
pl.anim_bottom = ANIM_RUN;
}
}
// Lerp it down!
if (self.lerpfrac > 0) {
self.lerpfrac -= frametime * 5;
if (self.lerpfrac < 0) {
self.lerpfrac = 0;
}
pl.frame = pl.anim_top;
pl.frame1time = pl.anim_top_time;
pl.baseframe = pl.anim_bottom;
pl.baseframe1time = pl.anim_bottom_time;
/* hack, we can't play the animations in reverse the normal way */
if (pl.frame1time < 0.0f) {
pl.frame1time = 10.0f;
}
if (self.baselerpfrac > 0) {
self.baselerpfrac -= frametime * 5;
if (self.baselerpfrac < 0) {
self.baselerpfrac = 0;
}
}
makevectors([0, pl.angles[1], 0]);
float fCorrect = dotproduct(pl.velocity, v_right) * 0.25f;
if (self.frame != self.frame_last) {
//Animation_Print(sprintf("New Frame: %d, Last Frame: %d\n", self.frame, self.frame_last));
// Move everything over to frame 2
self.frame2time = self.frame1time;
self.frame2 = self.frame_last;
// Set frame_last to avoid this being called again
self.frame_last = self.frame;
self.lerpfrac = 1.0f;
self.frame1time = 0.0f;
}
if (self.baseframe != self.baseframe_last) {
//Animation_Print(sprintf("New Baseframe: %d, Last Baseframe: %d\n", self.baseframe, self.baseframe_last));
// Move everything over to frame 2
self.baseframe2time = self.baseframe1time;
self.baseframe2 = self.baseframe_last;
// Set frame_last to avoid this being called again
self.baseframe_last = self.baseframe;
self.baselerpfrac = 1.0f;
self.baseframe1time = 0.0f;
}
self.subblend2frac = self.angles[0];
/* Turn torso */
pl.bonecontrol1 = fCorrect;
pl.bonecontrol2 = pl.bonecontrol1 * 0.5;
pl.bonecontrol3 = pl.bonecontrol2 * 0.5;
pl.bonecontrol4 = pl.bonecontrol3 * 0.5;
self.angles[0] = self.angles[2] = 0;
if (!(self.flags & FL_ONGROUND)) {
/*self.frame = ANIM_JUMP;*/
}
// Force the code above to update if we switched positions
if (self.fWasCrouching != (self.flags & FL_CROUCHING)) {
self.frame_old = 0;
self.frame_time = 0;
self.fWasCrouching = (self.flags & FL_CROUCHING);
}
/* Correct the legs */
pl.angles[1] -= fCorrect;
#ifndef CLIENT
// On the CSQC it's done in Player.c
self.subblendfrac =
self.subblend2frac = self.v_angle[0] / 90;
#endif
}
/*
=================
Animation_PlayerTop
Changes the animation sequence for the upper body part
=================
*/
void
Animation_PlayerTop(float fFrame)
{
#ifndef CLIENT
self.frame = fFrame;
self.frame_old = fFrame;
#ifdef SERVER
pl.subblendfrac =
pl.subblend2frac = pl.v_angle[0] / 90;
#else
pl.subblendfrac =
pl.subblend2frac = pl.pitch / 90;
#endif
}
void
Animation_PlayerTopTemp(float fFrame, float fTime)
Animation_PlayerTop(player pl, float topanim, float timer)
{
#ifndef CLIENT
self.frame = fFrame;
self.frame_time = time + fTime;
self.SendFlags |= PLAYER_FRAME;
#endif
pl.anim_top = topanim;
pl.anim_top_time = 0.0f;
pl.anim_top_delay = timer;
}
void
Animation_PlayerBottom(player pl, float botanim, float timer)
{
pl.anim_bottom = botanim;
}

View File

@ -68,6 +68,8 @@ FX_Blood(vector pos, vector color)
#ifdef GS_RENDERFX
eBlood.m_vecRenderColor = color;
eBlood.m_iRenderMode = RM_COLOR;
eBlood.m_flRenderAmt = 1.0f;
#else
eBlood.colormod = color;
#endif
@ -88,6 +90,8 @@ FX_Blood(vector pos, vector color)
#ifdef GS_RENDERFX
ePart.m_vecRenderColor = color;
ePart.m_iRenderMode = RM_COLOR;
ePart.m_flRenderAmt = 1.0f;
#else
ePart.colormod = color;
#endif

View File

@ -33,8 +33,8 @@ enumflags
PLAYER_ARMOR,
PLAYER_MOVETYPE,
PLAYER_VIEWOFS,
PLAYER_BASEFRAME,
PLAYER_FRAME,
PLAYER_TOPFRAME,
PLAYER_BOTTOMFRAME,
PLAYER_AMMO1,
PLAYER_AMMO2,
PLAYER_AMMO3,
@ -132,6 +132,12 @@ class player:base_player
int mode_tempstate;
int mode_tempstate_net;
float anim_top; float anim_top_net;
float anim_top_time; float anim_top_time_net;
float anim_top_delay; float anim_top_delay_net;
float anim_bottom; float anim_bottom_net;
float anim_bottom_time; float anim_bottom_time_net;
#ifdef CLIENT
/* External model */
entity p_model;
@ -139,7 +145,6 @@ class player:base_player
int p_model_bone;
float lastweapon;
virtual void(void) gun_offset;
virtual void(void) draw;
virtual float() predraw;
virtual void(void) postdraw;
@ -215,12 +220,16 @@ player::ReceiveEntity(float new)
movetype = readbyte();
if (fl & PLAYER_VIEWOFS)
view_ofs[2] = readfloat();
if (fl & PLAYER_BASEFRAME)
baseframe = readbyte();
if (fl & PLAYER_FRAME) {
frame = readbyte();
frame1time = 0.0f;
frame2time = 0.0f;
/* animation */
if (fl & PLAYER_TOPFRAME) {
anim_top = readbyte();
anim_top_time = readfloat();
anim_top_delay = readfloat();
}
if (fl & PLAYER_BOTTOMFRAME) {
anim_bottom = readbyte();
anim_bottom_time = readfloat();
}
if (fl & PLAYER_AMMO1) {
@ -294,6 +303,12 @@ player::PredictPreFrame(void)
ammo_gauss_volume_net = ammo_gauss_volume;
ammo_rpg_state_net = ammo_rpg_state;
mode_tempstate_net = mode_tempstate;
anim_top_net = anim_top;
anim_top_delay_net = anim_top_delay;
anim_top_time_net = anim_top_time;
anim_bottom_net = anim_bottom;
anim_bottom_time_net = anim_bottom_time;
}
/*
@ -330,6 +345,12 @@ player::PredictPostFrame(void)
ammo_gauss_volume = ammo_gauss_volume_net;
ammo_rpg_state = ammo_rpg_state_net;
mode_tempstate = mode_tempstate_net;
anim_top = anim_top_net;
anim_top_delay = anim_top_delay_net;
anim_top_time = anim_top_time_net;
anim_bottom = anim_bottom_net;
anim_bottom_time = anim_bottom_time_net;
}
#else
@ -392,11 +413,11 @@ player::EvaluateEntity(void)
if (old_viewofs != view_ofs[2])
SendFlags |= PLAYER_VIEWOFS;
if (old_baseframe != baseframe)
SendFlags |= PLAYER_BASEFRAME;
if (old_frame != frame)
SendFlags |= PLAYER_FRAME;
/* animation */
if (anim_bottom_net != anim_bottom || anim_bottom_time != anim_bottom_time_net)
SendFlags |= PLAYER_BOTTOMFRAME;
if (anim_top_net != anim_top || anim_top_time != anim_top_time_net || anim_top_delay != anim_top_delay_net)
SendFlags |= PLAYER_TOPFRAME;
/* ammo 1 type updates */
if (glock_mag != glock_mag_net) {
@ -510,6 +531,12 @@ player::EvaluateEntity(void)
ammo_gauss_volume_net = ammo_gauss_volume;
ammo_rpg_state_net = ammo_rpg_state;
mode_tempstate_net = mode_tempstate;
anim_top_net = anim_top;
anim_top_delay_net = anim_top_delay;
anim_top_time_net = anim_top_time;
anim_bottom_net = anim_bottom;
anim_bottom_time_net = anim_bottom_time;
}
/*
@ -578,10 +605,16 @@ player::SendEntity(entity ePEnt, float fChanged)
WriteByte(MSG_ENTITY, movetype);
if (fChanged & PLAYER_VIEWOFS)
WriteFloat(MSG_ENTITY, view_ofs[2]);
if (fChanged & PLAYER_BASEFRAME)
WriteByte(MSG_ENTITY, baseframe);
if (fChanged & PLAYER_FRAME)
WriteByte(MSG_ENTITY, frame);
if (fChanged & PLAYER_TOPFRAME) {
WriteByte(MSG_ENTITY, anim_top);
WriteFloat(MSG_ENTITY, anim_top_time);
WriteFloat(MSG_ENTITY, anim_top_delay);
}
if (fChanged & PLAYER_BOTTOMFRAME) {
WriteByte(MSG_ENTITY, anim_bottom);
WriteFloat(MSG_ENTITY, anim_bottom_time);
}
if (fChanged & PLAYER_AMMO1) {
WriteByte(MSG_ENTITY, glock_mag);

View File

@ -199,6 +199,11 @@ w_crossbow_primary(void)
Weapons_ViewAnimation(CROSSBOW_FIRE3);
}
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTBOW, 0.25f);
else
Animation_PlayerTop(pl, ANIM_SHOOTBOW, 0.25f);
Weapons_ViewPunchAngle([-2,0,0]);
pl.w_attack_next = 0.75f;
@ -266,13 +271,13 @@ w_crossbow_release(void)
int r = (float)input_sequence % 2;
if (r == 1) {
if (pl.ammo_bolt) {
if (pl.crossbow_mag) {
Weapons_ViewAnimation(CROSSBOW_IDLE1);
} else {
Weapons_ViewAnimation(CROSSBOW_IDLE2);
}
} else {
if (pl.ammo_bolt) {
if (pl.crossbow_mag) {
Weapons_ViewAnimation(CROSSBOW_FIDGET1);
} else {
Weapons_ViewAnimation(CROSSBOW_FIDGET2);

View File

@ -125,11 +125,10 @@ w_crowbar_primary(void)
Weapons_ViewAnimation(trace_fraction >= 1 ? CBAR_ATTACK3MISS:CBAR_ATTACK3HIT);
}
if (pl.flags & FL_CROUCHING) {
Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f);
} else {
Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f);
}
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTCROWBAR, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTCROWBAR, 0.5f);
#ifdef SERVER
Sound_Play(self, CHAN_WEAPON, "weapon_crowbar.miss");

View File

@ -282,6 +282,11 @@ void w_gauss_primary(void)
w_gauss_fire(1);
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTGAUSS, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTGAUSS, 0.43f);
pl.w_attack_next = 0.2f;
pl.w_idle_next = 2.5f;
}
@ -361,6 +366,12 @@ void w_gauss_release(void)
return;
} else if (pl.mode_tempstate == 2) {
Weapons_ViewAnimation(GAUSS_FIRE1);
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTGAUSS, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTGAUSS, 0.43f);
#ifdef CLIENT
FXGauss p = (FXGauss)pSeat->m_pWeaponFX;
p.m_iBeams = 1;

View File

@ -184,12 +184,12 @@ w_glock_primary(void)
#else
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, Skill_GetValue("plr_9mm_bullet", 8), [0.01,0.01], WEAPON_GLOCK);
Sound_Play(pl, CHAN_WEAPON, "weapon_glock.fire");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
Animation_PlayerTop(pl, ANIM_CR_SHOOT1HAND, 0.2f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
Animation_PlayerTop(pl, ANIM_SHOOT1HAND, 0.2f);
pl.w_attack_next = 0.3f;
pl.w_idle_next = 5.0f;
@ -225,12 +225,12 @@ w_glock_secondary(void)
#else
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, Skill_GetValue("plr_9mm_bullet", 8), [0.1,0.1], WEAPON_GLOCK);
Sound_Play(pl, CHAN_WEAPON, "weapon_glock.fire");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
Animation_PlayerTop(pl, ANIM_CR_SHOOT1HAND, 0.2f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
Animation_PlayerTop(pl, ANIM_SHOOT1HAND, 0.2f);
pl.w_attack_next = 0.2f;
pl.w_idle_next = 5.0f;

View File

@ -199,6 +199,11 @@ void w_handgrenade_release(void)
pl.mode_tempstate = 2;
pl.w_attack_next = 1.0f;
pl.w_idle_next = 0.5f;
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTCROWBAR, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTCROWBAR, 0.5f);
} else if (pl.mode_tempstate == 2) {
#ifdef CLIENT
Weapons_ViewAnimation(HANDGRENADE_DRAW);

View File

@ -185,6 +185,11 @@ w_hornetgun_primary(void)
pl.ammo_hornet--;
Weapons_ViewAnimation(HORNETGUN_SHOOT);
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTHIVE, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTHIVE, 0.43f);
pl.w_attack_next = 0.25;
pl.w_idle_next = 1.0f;
}
@ -211,6 +216,11 @@ w_hornetgun_secondary(void)
pl.ammo_hornet--;
Weapons_ViewAnimation(HORNETGUN_SHOOT);
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTHIVE, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTHIVE, 0.43f);
pl.w_attack_next = 0.1;
pl.w_idle_next = 1.0f;
}

View File

@ -162,6 +162,11 @@ w_mp5_primary(void)
Sound_Play(pl, CHAN_WEAPON, "weapon_mp5.shoot");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTMP5, 0.1f);
else
Animation_PlayerTop(pl, ANIM_SHOOTMP5, 0.1f);
pl.w_attack_next = 0.1f;
pl.w_idle_next = 10.0f;
}
@ -216,6 +221,11 @@ w_mp5_secondary(void)
Sound_Play(pl, CHAN_WEAPON, "weapon_mp5.gl");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTMP5, 0.45f);
else
Animation_PlayerTop(pl, ANIM_SHOOTMP5, 0.45f);
pl.w_attack_next = 1.0f;
pl.w_idle_next = 10.0f;
}

View File

@ -152,6 +152,11 @@ w_python_primary(void)
Sound_Play(pl, CHAN_WEAPON, "weapon_357.shoot");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTPYTHON, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTPYTHON, 0.43f);
pl.w_attack_next = 0.75f;
pl.w_idle_next = 10.0f;
}

View File

@ -162,6 +162,11 @@ void w_rpg_primary(void)
Sound_Play(pl, CHAN_WEAPON, "weapon_rpg.shoot");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTRPG, 0.43f);
else
Animation_PlayerTop(pl, ANIM_SHOOTRPG, 0.43f);
pl.w_attack_next =
pl.w_idle_next = 2.5f;
}

View File

@ -190,6 +190,11 @@ w_satchel_primary(void)
s_satchel_drop(self, pl.origin, throw);
pl.satchel_chg++;
pl.ammo_satchel--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTSQUEAK, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTSQUEAK, 0.5f);
} else {
/* detonate all we have */
s_satchel_detonate(pl);
@ -240,6 +245,11 @@ w_satchel_secondary(void)
Weapons_ViewAnimation(RADIO_DRAW);
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTSQUEAK, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTSQUEAK, 0.5f);
pl.satchel_chg++;
pl.ammo_satchel--;

View File

@ -190,6 +190,11 @@ w_shotgun_primary(void)
View_AddEvent(w_shotgun_ejectshell, 0.5f);
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTSHOTGUN, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTSHOTGUN, 0.5f);
pl.shotgun_mag--;
/* after 1/2 a second, play the cocksound and eject shell */
@ -231,6 +236,12 @@ w_shotgun_secondary(void)
Weapons_ViewPunchAngle([-10,0,0]);
View_AddEvent(w_shotgun_ejectshell, 1.0f);
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTSHOTGUN, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTSHOTGUN, 0.5f);
/* after 1 second, play the cocksound and eject shell */
pl.mode_tempstate = SHOTTY_COCKSOUND;
pl.w_idle_next = 1.0f;

View File

@ -193,6 +193,11 @@ void w_snark_primary(void)
}
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTSQUEAK, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTSQUEAK, 0.5f);
pl.w_idle_next = 1.0f;
pl.w_attack_next = 0.25f;

View File

@ -293,6 +293,11 @@ w_tripmine_primary(void)
Sound_Play(mine, CHAN_WEAPON, "weapon_tripmine.charge");
#endif
if (self.flags & FL_CROUCHING)
Animation_PlayerTop(pl, ANIM_CR_SHOOTTRIPMINE, 0.41f);
else
Animation_PlayerTop(pl, ANIM_SHOOTTRIPMINE, 0.5f);
pl.a_ammo3 = 1;
pl.w_attack_next =
pl.w_idle_next = 0.5f;