CLIENT/SERVER: Rewrite CSQC View Model drawing, simplify protocol

This commit is contained in:
MotoLegacy 2024-01-12 14:40:38 -05:00
parent a41eeb23c6
commit da4bd373b0
17 changed files with 427 additions and 654 deletions

View file

@ -10,4 +10,5 @@
../source/client/hud.qc ../source/client/hud.qc
../source/client/chat.qc ../source/client/chat.qc
../source/client/user_input.qc ../source/client/user_input.qc
../source/client/view_model.qc
../source/client/main.qc ../source/client/main.qc

View file

@ -44,28 +44,14 @@ string loadscreen_mapname;
string loadscreen_maptitle; string loadscreen_maptitle;
string loadscreen_tip; string loadscreen_tip;
entity player;
entity vmodel;
entity v2model;
entity mzlflash;
entity dummy;
float weapon; float weapon;
float tracercounter; float tracercounter;
.float rate; .float rate;
.vector targetpos; .vector targetpos;
vector vmodel_targetpos; entity cl_viewent;
vector v2model_targetpos; entity cl_viewent2;
vector vmodel_currentpos;
vector v2model_currentpos;
vector vmodel_velocity;
vector v2model_velocity;
vector vmodel_avelocity;
vector v2model_avelocity;
vector vmodel_muzzleoffset;
vector v2model_muzzleoffset;
const float MENU_NONE = 0; const float MENU_NONE = 0;
const float MENU_MAIN = 1; const float MENU_MAIN = 1;

View file

@ -1706,7 +1706,7 @@ void(float width, float height) HUD_Draw =
HUD_Progressbar(width, height); HUD_Progressbar(width, height);
HUD_Powerups(); HUD_Powerups();
if (vmodel.model == GetWeaponModel(getstatf(STAT_ACTIVEWEAPON), FALSE) && vmodel.model != "") if (cl_viewent.modelindex != 0)
HUD_AmmoString(); HUD_AmmoString();
if (nameprint_time > time) if (nameprint_time > time)
@ -1719,7 +1719,7 @@ void(float width, float height) HUD_Draw =
{ {
HUD_Grenades(width, height); HUD_Grenades(width, height);
if (vmodel.model == GetWeaponModel(getstatf(STAT_ACTIVEWEAPON), FALSE) && vmodel.model != "") { if (cl_viewent.modelindex != 0) {
HUD_Ammo(width, height); HUD_Ammo(width, height);
HUD_Weaponstring(width, height); HUD_Weaponstring(width, height);
} }

View file

@ -85,7 +85,6 @@ noref void(float apiver, string enginename, float enginever) CSQC_Init =
} }
//print("CSQC Started\n"); //print("CSQC Started\n");
dummy = spawn();
if(serverkey("constate") == "disconnected") if(serverkey("constate") == "disconnected")
ToggleMenu(); ToggleMenu();
//bgpos = 0; //bgpos = 0;
@ -117,6 +116,7 @@ noref void(float apiver, string enginename, float enginever) CSQC_Init =
autocvar(nzp_particles, 1); autocvar(nzp_particles, 1);
autocvar(nzp_decals, 1); autocvar(nzp_decals, 1);
autocvar(vid_ultrawide_limiter, 0); autocvar(vid_ultrawide_limiter, 0);
autocvar(cl_bobside, 0.02);
// per-channel volume // per-channel volume
autocvar(snd_channel1volume, 1); autocvar(snd_channel1volume, 1);
@ -173,28 +173,6 @@ void() Init_Particles =
noref void() CSQC_WorldLoaded = noref void() CSQC_WorldLoaded =
{ {
//precache_model("models/weapons/mg/mzl.iqm");
//precache_model("models/blood.iqm");
if(!player)
player = findfloat(world, entnum, player_localnum);
if(!vmodel)
vmodel = spawn();
if(!v2model)
v2model = spawn();
if(!mzlflash)
mzlflash = spawn();
v2model.renderflags = vmodel.renderflags = RF_VIEWMODEL;
v2model.origin = vmodel.origin = '24 -12 -18';
v2model_targetpos = v2model_currentpos = v2model.origin = vmodel_targetpos = vmodel_currentpos = vmodel.origin;
v2model_velocity = vmodel_velocity = '0 0 0';
//v2model_muzzleoffset = vmodel_muzzleoffset = '48 -1 2';
setmodel(vmodel,"");
setmodel(v2model,"");
mzlflash.renderflags = vmodel.renderflags;
mzlflash.origin = vmodel.origin + vmodel_muzzleoffset;
Achievement_Init(); Achievement_Init();
Init_Particles(); Init_Particles();
nameprint_time = time + 12; nameprint_time = time + 12;
@ -213,252 +191,6 @@ float weapon_bob_factor_z_coef;
vector dampening_factor; vector dampening_factor;
float vaccel; float vaccel;
float vzaccel; float vzaccel;
void() Update_Vmodel =
{
local vector offset, adsoffset;
local vector dir;
local float ads;
if (cvar("r_drawviewmodel") == FALSE || hide_viewmodel == true) {
vmodel.origin = '-10000 -10000 -10000';
return;
}
//
// View Bobbing Factors.
//
// PAUSED, NO BOB
if (serverkey(SERVERKEY_PAUSESTATE) == "1") {
weapon_bob_factor = '0 0 0';
dampening_factor = weapon_bob_factor;
weapon_bob_factor_z_coef = 0;
}
// ADS
else if (getstatf(STAT_WEAPONZOOM) && getstatf(STAT_WEAPONZOOM) != 3) {
weapon_bob_factor = '0 0 0';
dampening_factor = weapon_bob_factor;
weapon_bob_factor_z_coef = 0;
}
// SPRINT
else if (getstatf(STAT_WEAPONZOOM) == 3) {
weapon_bob_factor_x = 2;
weapon_bob_factor_y = 8;
weapon_bob_factor_z = 12;
weapon_bob_factor_z_coef = 1;
dampening_factor_x = sin(cltime*weapon_bob_factor_x);
dampening_factor_y = 9*cos(cltime*weapon_bob_factor_y);
dampening_factor_z = 0.1*sin(cltime*weapon_bob_factor_z);
}
// WALK
else if (K_FORWARDDOWN || K_BACKDOWN || K_LEFTDOWN || K_RIGHTDOWN && !getstatf(STAT_WEAPONZOOM)) {
weapon_bob_factor_x = 8;
weapon_bob_factor_y = 8;
weapon_bob_factor_z = 13.4;
weapon_bob_factor_z_coef = 0.2;
dampening_factor_x = 0.2*sin(cltime*weapon_bob_factor_x);
dampening_factor_y = 0.2*cos(cltime*weapon_bob_factor_y);
dampening_factor_z = 0.2*sin(cltime*weapon_bob_factor_z);
}
// STILL
else if (!getstatf(STAT_WEAPONZOOM)) {
// HACK HACK
if (weapon_bob_factor_z == 12) {
weapon_bob_factor_x = 8;
weapon_bob_factor_y = 8;
weapon_bob_factor_z = 13.4;
weapon_bob_factor_z_coef = 0.2;
dampening_factor_x = 0.2*sin(cltime*weapon_bob_factor_x);
dampening_factor_y = 0.2*cos(cltime*weapon_bob_factor_y);
dampening_factor_z = 0.2*sin(cltime*weapon_bob_factor_z);
}
// Naievil -- stupid ass calcs...
// Basically we have a dampening factor per offset and we have to decrease it back down to zero
// Problem is that we may be going in postive OR negative direction?
// Better solution: use fabs() lol
if (dampening_factor_x > 0 && sin(time*weapon_bob_factor_x) > 0) {
if ((dampening_factor_x - 0.00000068* sin(time*weapon_bob_factor_x)) < 0)
dampening_factor_x -= (0.00000068 - dampening_factor_x*sin(time*weapon_bob_factor_x));
else
dampening_factor_x -= 0.00000068* sin(time*weapon_bob_factor_x);
} else if (dampening_factor_x < 0 && sin(time*weapon_bob_factor_x) < 0) {
if ((dampening_factor_x + 0.00000068* sin(time*weapon_bob_factor_x)) > 0)
dampening_factor_x += (0.00000068 - dampening_factor_x*sin(time*weapon_bob_factor_x));
else
dampening_factor_x += 0.00000068* sin(time*weapon_bob_factor_x);
} else {
weapon_bob_factor_x = 1.2;
}
if (weapon_bob_factor_x - 0.00000068 < 1.2)
weapon_bob_factor_x = 1.2;
else
weapon_bob_factor_x -= 0.00000068;
if (dampening_factor_y > 0 && cos(time*weapon_bob_factor_y) > 0) {
if ((dampening_factor_y - 0.00000065* cos(time*weapon_bob_factor_y)) < 0)
dampening_factor_y -= (0.00000065 - dampening_factor_y*cos(time*weapon_bob_factor_y));
else
dampening_factor_y -= 0.00000065* cos(time*weapon_bob_factor_y);
} else if (dampening_factor_y < 0 && cos(time*weapon_bob_factor_y) < 0) {
if ((dampening_factor_y + 0.00000065* cos(time*weapon_bob_factor_y)) > 0)
dampening_factor_y += (0.00000065 - dampening_factor_y*cos(time*weapon_bob_factor_y));
else
dampening_factor_y += 0.00000065* cos(time*weapon_bob_factor_y);
} else {
weapon_bob_factor_y = 1.5;
}
if (weapon_bob_factor_y - 0.00000065 < 1.5)
weapon_bob_factor_y = 1.5;
else
weapon_bob_factor_y -= 0.00000065;
if (dampening_factor_z > 0 && sin(time*weapon_bob_factor_z) > 0) {
if ((dampening_factor_z - 0.00000123* sin(time*weapon_bob_factor_z)) < 0)
dampening_factor_z -= (0.00000123 - dampening_factor_z*sin(time*weapon_bob_factor_z));
else
dampening_factor_z -= 0.00000123* sin(time*weapon_bob_factor_z);
} else if (dampening_factor_z <= 0 && sin(time*weapon_bob_factor_z) < 0) {
if ((dampening_factor_z + 0.00000123* sin(time*weapon_bob_factor_z)) > 0)
dampening_factor_z += (0.00000123 - dampening_factor_z*sin(time*weapon_bob_factor_z));
else
dampening_factor_z += 0.00000123* sin(time*weapon_bob_factor_z);
} else {
weapon_bob_factor_z = 1.1;
}
if (weapon_bob_factor_z - 0.00000123 < 1.1)
weapon_bob_factor_z = 1.1;
else
weapon_bob_factor_z -= 0.00000123;
if (weapon_bob_factor_z_coef <= 0.1)
weapon_bob_factor_z_coef = 0.1;
else
weapon_bob_factor_z_coef -= 0.0000001*sin(time*weapon_bob_factor_z);
}
offset_x = 0.2 * (sin(cltime * weapon_bob_factor_x) + dampening_factor_x);
offset_y = 0.2 * (cos(cltime * weapon_bob_factor_y) + dampening_factor_y);
offset_z = weapon_bob_factor_z_coef * (sin(weapon_bob_factor_z*cltime + 0.5) + dampening_factor_z);
vector tempv;
tempv_x = 0.2 * (sin(cltime * weapon_bob_factor_x));
tempv_y = 0.2 * (cos(cltime * weapon_bob_factor_y));
tempv_z = weapon_bob_factor_z_coef * (sin(weapon_bob_factor_z*cltime + 0.5));
dir = vmodel_targetpos - vmodel_currentpos;
if(vlen(dir) < (0.15 * 128 * frametime))
vmodel_currentpos = vmodel_targetpos;
else
vmodel_currentpos += (dir * 0.15 * 128) * frametime;
if(vlen(vmodel.angles) < (0.1 * 128 * frametime))
vmodel.angles = '0 0 0';
else
vmodel.angles += (-vmodel.angles * 0.2 * 128) * frametime;
vmodel_currentpos += (vmodel_velocity * 128) * frametime;
vmodel_velocity *= 1 - frametime * 30;
vmodel.angles += (vmodel_avelocity * 128) * frametime;
vmodel_avelocity *= 1 - frametime * 30;
adsoffset = GetWeaponADSPos(weapon);
ads = getstatf(STAT_WEAPONZOOM); //get the zoomtoggle value
if(ads == 1 || ads == 2 && serverkey(SERVERKEY_PAUSESTATE) == "0")
{
vmodel_currentpos += (adsoffset * 0.15 * 128) * frametime;
vmodel.origin = vmodel_currentpos + adsoffset;
}
else
{
switch(getstatf(STAT_PLAYERSTANCE)) {
case 2:
break;
case 1:
vmodel_currentpos = '0 0.6 -0.3';
break;
case 0:
vmodel_currentpos = '1.5 0.6 -0.3';
break;
default: break;
}
vmodel.origin = vmodel_currentpos + offset;
vmodel.origin_y += vaccel;
vmodel.origin_z += vzaccel;
if (in_menu != MENU_NONE)
return;
if (K_LEFTDOWN) {
vaccel -= 0.01;
if (vaccel < -0.8)
vaccel = -0.8;
} else if (K_RIGHTDOWN) {
vaccel += 0.01;
if (vaccel > 0.8)
vaccel = 0.8;
} else if (vaccel != 0) {
if (vaccel > 0)
vaccel -= 0.01;
else
vaccel += 0.01;
}
//black ops -0.01 till -0.6 (looks better)
if (K_BACKDOWN || K_FORWARDDOWN) {
if (ads == 3) {
vzaccel -= 0.1;
if (vzaccel < -1.2)
vzaccel = -1.2;
} else {
vzaccel -= 0.01;
if (vzaccel < -0.6)
vzaccel = -0.6;
}
} else if (vzaccel != 0) {
if (vzaccel > 0)
vzaccel -= 0.02;
else
vzaccel += 0.02;
}
}
if(weapon == 1)
{
if(mzlflash.scale < 1)
mzlflash.scale += (10 * random()) * frametime;
}
else if(weapon == 2)
{
if(mzlflash.scale < 1.5)
mzlflash.scale += (20 * random()) * frametime;
}
mzlflash.origin = vmodel.origin + vmodel_muzzleoffset;
mzlflash.alpha -= (0.15 * 100) * frametime;
if(mzlflash.alpha < 0.1)
mzlflash.alpha = 0.01;
}
float Player_PreDraw() = float Player_PreDraw() =
{ {
@ -804,6 +536,33 @@ noref void(float width, float height, float notmenu) CSQC_UpdateViewLoading =
#define SCALE_CONSTANT 8 #define SCALE_CONSTANT 8
//MOVEME
float(float a) angledelta =
{
a = anglemod(a);
if (a > 180)
a -= 360;
return a;
}
//MOVEME
float delta_pitch, delta_yaw;
vector sniper_sway;
// Sways the camera while scoped in.
void() Camera_SniperSway =
{
if (getstatf(STAT_WEAPONZOOM) != 2) {
sniper_sway = '0 0 0';
return;
}
delta_pitch = (cos(cltime/0.7) + cos(cltime) + sin(cltime/1.1)) * 0.5;
delta_yaw = (sin(cltime/0.4) + cos(cltime/0.56) + sin(cltime)) * 0.5;
sniper_sway[0] = angledelta(delta_pitch);
sniper_sway[1] = angledelta(delta_yaw);
};
// CALLED EVERY CLIENT RENDER FRAME // CALLED EVERY CLIENT RENDER FRAME
float pap_flash_alternate; float pap_flash_alternate;
noref void(float width, float height, float menushown) CSQC_UpdateView = noref void(float width, float height, float menushown) CSQC_UpdateView =
@ -859,123 +618,18 @@ noref void(float width, float height, float menushown) CSQC_UpdateView =
setproperty(VF_ORIGIN, playerOrigin + [ 0, 0, getstatf(STAT_VIEWHEIGHT)]); setproperty(VF_ORIGIN, playerOrigin + [ 0, 0, getstatf(STAT_VIEWHEIGHT)]);
//setproperty(VF_ANGLES, view_angles); //setproperty(VF_ANGLES, view_angles);
//do viewmodel manipulation, purely cosmetic stuff // Draw the client's viewmodels.
if(vmodel) ViewModel_Draw();
{
Update_Vmodel();
local vector vorg;
local vector vang;
vorg = getviewprop(VF_ORIGIN);
vang = getviewprop(VF_ANGLES);
//vmodel.origin += vorg;
//vmodel.angles += vang;
addentity(vmodel);
addentity(v2model);
//vmodel.origin -= vorg;
//vmodel.angles -= vang;
//addentity(vmodel);
float weaponframe, weapon2frame;
weaponframe = getstatf(STAT_WEAPONFRAME);
float duration = getstatf(STAT_WEAPONDURATION);
if (!duration) {
duration = 0.1;
}
if (curweaponframe != weaponframe) {
interpolating = TRUE;
vmodel.lerpfrac = 0;
oldweaponframe = curweaponframe;
curweaponframe = weaponframe;
}
if (interpolating == TRUE) {
vmodel.lerpfrac += frametime * (1/duration);
if (vmodel.lerpfrac >= 1.0) {
oldweaponframe = curweaponframe;
vmodel.lerpfrac = 0;
interpolating = FALSE;
}
}
vmodel.frame = oldweaponframe;
vmodel.frame2 = curweaponframe;
if (IsDualWeapon(getstatf(STAT_ACTIVEWEAPON))) {
float duration2 = getstatf(STAT_WEAPON2DURATION);
if (!duration2) {
duration2 = 0.1;
}
weapon2frame = getstatf(STAT_WEAPON2FRAME);
if (curweapon2frame != weapon2frame) {
interpolating2 = TRUE;
v2model.lerpfrac = 0;
oldweapon2frame = curweapon2frame;
curweapon2frame = weapon2frame;
}
if (interpolating2 == TRUE) {
v2model.lerpfrac += frametime * (1/duration2);
if (v2model.lerpfrac >= 1.0) {
oldweapon2frame = curweapon2frame;
v2model.lerpfrac = 0;
interpolating2 = FALSE;
}
}
v2model.frame = oldweapon2frame;
v2model.frame2 = curweapon2frame;
} else {
//v2model.frame = getstatf(STAT_WEAPON2FRAME);
v2model.lerpfrac = vmodel.lerpfrac;
v2model.frame = oldweaponframe;
v2model.frame2 = curweaponframe;
}
v2model.angles = vmodel.angles;
v2model.origin = vmodel.origin;
if(mzlflash.alpha > 0.09)
{
makevectors(view_angles);
local vector offset = vmodel.origin + vmodel_muzzleoffset;
local vector muzzlepos;
muzzlepos = getviewprop(VF_ORIGIN);
muzzlepos += v_forward * offset_x;
muzzlepos -= v_right * offset_y;
muzzlepos += v_up * (offset_z + 6);
if (cvar("r_drawviewmodel")) {
if (IsPapWeapon(getstatf(STAT_ACTIVEWEAPON))) {
if (pap_flash_alternate)
dynamiclight_add(muzzlepos, 128 * mzlflash.alpha, '0.7 0 0' * mzlflash.alpha);
else
dynamiclight_add(muzzlepos, 128 * mzlflash.alpha, '0 0 0.7' * mzlflash.alpha);
pap_flash_alternate = !pap_flash_alternate;
}
else
dynamiclight_add(muzzlepos, 128 * mzlflash.alpha, '1.2 0.7 0.2' * mzlflash.alpha);
addentity(mzlflash);
}
}
}
//deltalisten makes engine call the "add_outline" func for each entity with the set model every frame
/*deltalisten("models/mg_ammo.iqm", add_outline, 0);
deltalisten("models/weapons/mg/mg.iqm", add_outline, 0);
deltalisten("models/weapons/pistol/pistol.iqm", add_outline, 0);*/
//deltalisten("models/humanoid_simplerig.iqm", add_outline, 0);
DropRecoilKick(); DropRecoilKick();
Camera_SniperSway();
camang[0] += gun_kick[0]; camang[0] += gun_kick[0];
camang[1] += gun_kick[1]; camang[1] += gun_kick[1];
camang[2] += gun_kick[2]; camang[2] += gun_kick[2];
camang[0] += sniper_sway[0];
camang[1] += sniper_sway[1];
camang[2] += sniper_sway[2];
setviewprop(VF_ANGLES, camang); setviewprop(VF_ANGLES, camang);
@ -1216,6 +870,7 @@ noref float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent
noref void() CSQC_Input_Frame = noref void() CSQC_Input_Frame =
{ {
input_angles += gun_kick; input_angles += gun_kick;
input_angles += sniper_sway;
} }
#define DEG2RAD(x) (x * M_PI / 180.f) #define DEG2RAD(x) (x * M_PI / 180.f)
@ -1239,46 +894,49 @@ noref void() CSQC_Parse_Event =
traceent = readentitynum(); traceent = readentitynum();
if(entnum == player_localentnum) // Muzzleflash Logic
if (entnum == player_localentnum && getstatf(STAT_WEAPONZOOM) != 2)
{ {
// originally was view_angles, but thats only what is reported // originally was view_angles, but thats only what is reported
// to the server, weapon kick is NOT reported, so offset continued // to the server, weapon kick is NOT reported, so offset continued
// to grow. // to grow.
getinputstate(servercommandframe); getinputstate(servercommandframe);
makevectors(input_angles); makevectors(input_angles);
local vector offset = vmodel.origin + vmodel_muzzleoffset;
local vector muzzlepos, muzzle_offset;
muzzlepos = getviewprop(VF_ORIGIN);
muzzle_offset = GetWeaponFlash_Offset(getstatf(STAT_ACTIVEWEAPON))/1000; vector muzzleflash_offset;
vector muzzleflash_position = getviewprop(VF_ORIGIN);
// Firing from the left? Use the other position instead // If firing the left side of a dual-wield weapon, use the left side muzzleflash offset.
if (side == 0 && IsDualWeapon(getstatf(STAT_ACTIVEWEAPON))) if (side == 0 && IsDualWeapon(getstatf(STAT_ACTIVEWEAPON)))
muzzle_offset = WepDef_GetLeftFlashOffset(getstatf(STAT_ACTIVEWEAPON))/1000; muzzleflash_offset = WepDef_GetLeftFlashOffset(getstatf(STAT_ACTIVEWEAPON))/1000;
// Otherwise, use the standard offset.
else
muzzleflash_offset = GetWeaponFlash_Offset(getstatf(STAT_ACTIVEWEAPON))/1000;
// ADS offset // Move to match ADS position if Zoomed in.
if(getstatf(STAT_WEAPONZOOM) == 1) { if(getstatf(STAT_WEAPONZOOM) == 1) {
muzzle_offset += GetWeaponADSOfs_PSP(weapon)/1000; muzzleflash_offset += GetWeaponADSOfs_PSP(getstatf(STAT_ACTIVEWEAPON))/1000;
} }
muzzlepos += v_forward * muzzle_offset_z; muzzleflash_position += v_forward * muzzleflash_offset_z;
muzzlepos += v_right * muzzle_offset_x; muzzleflash_position += v_right * muzzleflash_offset_x;
muzzlepos += v_up * muzzle_offset_y; muzzleflash_position += v_up * muzzleflash_offset_y;
mzlflash.alpha = 1;
// Scale the muzzleflash to meet viewmodel FOV
// FTE doesnt support vector scaling :(
// float afov = cvar("fov");
// float vfov = cvar("r_viewmodel_default_fov");
// float ascale = 1.0 / tan(DEG2RAD(afov/2.0)) * vfov / 90.0;
// mzlflash.scale = ascale;
if (cvar("nzp_particles") && cvar("r_drawviewmodel")) { if (cvar("nzp_particles") && cvar("r_drawviewmodel")) {
float index = rint(random() * 2); float index = rint(random() * 2);
if (IsPapWeapon(getstatf(STAT_ACTIVEWEAPON))) // Display Muzzleflash Particle and Dynamic Light
pointparticles(particleeffectnum(strcat("muzzle.muzzle_pap_part", ftos(index))), muzzlepos, norm*24, 1); if (IsPapWeapon(getstatf(STAT_ACTIVEWEAPON))) {
pointparticles(particleeffectnum(strcat("muzzle.muzzle_pap_part", ftos(index))), muzzleflash_position, norm*24, 1);
// Pack-A-Punched Weapons can display either a Blue or Red light
if (random() > 0.5)
dynamiclight_add(muzzleflash_position, 256, '0.7 0 0');
else else
pointparticles(particleeffectnum(strcat("muzzle.muzzle_part", ftos(index))), muzzlepos, norm*24, 1); dynamiclight_add(muzzleflash_position, 256, '0 0 0.7');
} else {
pointparticles(particleeffectnum(strcat("muzzle.muzzle_part", ftos(index))), muzzleflash_position, norm*24, 1);
dynamiclight_add(muzzleflash_position, 256, '1.2 0.7 0.2');
}
} }
} }
@ -1350,39 +1008,6 @@ noref void() CSQC_Parse_Event =
string message = readstring(); string message = readstring();
Chat_Register(sender, player_id, message); Chat_Register(sender, player_id, message);
break; break;
case EVENT_WEAPONCHANGE:
local float to;
to = readbyte();
setmodel(vmodel,GetWeaponModel(to, FALSE));
if (to == W_KAR_SCOPE && vmodel.model == "models/weapons/kar/v_kar.mdl") {
setmodel(v2model,"models/weapons/kar/v_karscope.mdl");
} else {
setmodel(v2model,"");
}
v2model.origin = vmodel.origin = '0 0 0';
v2model.angles = vmodel.angles = '-60 0 0';
v2model_currentpos = vmodel_currentpos = vmodel.origin + '0 0 -24';
v2model_targetpos = vmodel_targetpos = vmodel.origin;
v2model_muzzleoffset = vmodel_muzzleoffset = '12 0 1';
weapon = to;
HUD_Change_time = time + 6;
break;
case EVENT_UPDATEVMODEL:
local string new;
local float skin2;
new = readstring();
setmodel(vmodel,new);
vmodel.skin = readbyte();
break;
case EVENT_UPDATEV2MODEL:
local string new2;
new2 = readstring();
setmodel(v2model,new2);
v2model.skin = readbyte();
break;
case EVENT_USEPRINT: case EVENT_USEPRINT:
useprint_type = readbyte(); useprint_type = readbyte();
useprint_cost = readshort(); useprint_cost = readshort();

303
source/client/view_model.qc Normal file
View file

@ -0,0 +1,303 @@
/*
client/view_model.qc
View Model Drawing and Manipulation.
Copyright (C) 2021-2024 NZ:P Team
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
vector current_viewmodel_ads_position;
vector viewmodel_slack_distance;
vector last_viewangles;
#define VIEWMODEL_ADS_TIME_FACTOR (16 * frametime) // We want this to be server dependent.
#define VIEWMODEL_ANGLE_SLACK_FACTOR (3)
//MOVEME
float(float a, float b, float mix) lerp =
{
if (mix <= 0) return a;
if (mix >= 1) return b;
return (b * mix + a * ( 1 - mix ) );
};
//MOVEME
float(float value, float minValue, float maxValue) clamp = {
if (value < minValue) return minValue;
else if (value > maxValue) return maxValue;
return value;
};
//MOVEME
float(float source, float target, float smoothing, float dt) damp =
{
return lerp(source, target, 1 - pow(smoothing, dt));
};
//
// ViewModel_CalcBob()
// Blubs' refactored V_CalcBob reimplemented in CSQC.
// Edited to also add idle bobbing if low speed.
//
float(float speed, float which) ViewModel_CalcBob =
{
float sprint = 1;
float client_zoom = getstatf(STAT_WEAPONZOOM);
float cl_bobup_value = cvar("cl_bobup");
float cl_bobside_value = cvar("cl_bobside");
// Bob idle-y, instead of presenting as if in-motion.
if (speed < 0.1) {
// If we're zoomed in, we only want idle bobbing to be very subtle..
if (client_zoom == 1)
speed = 0.05;
else
speed = 0.25;
if (which == 0)
return cl_bobup_value * 10 * speed * (sprint * sprint) * sin(cltime * 3.25 * sprint);
else
return cl_bobside_value * 50 * speed * (sprint * sprint * sprint) * sin((cltime * sprint) - (M_PI * 0.25));
}
// Normal walk/sprint bob.
else {
if (client_zoom == 3)
sprint = 1.8;
if (which == 0)
return cl_bobup_value * 36 * speed * (sprint * sprint) * sin(cltime * 12.5 * sprint);
else
return cl_bobside_value * 36 * speed * (sprint * sprint * sprint) * sin((cltime * 6.25 * sprint) - (M_PI * 0.25));
}
};
//
// ViewModel_CalcViewAngleDifference()
// Returns the difference in client viewangles between this frame
// and last.
//
vector() ViewModel_CalcViewAngleDifference =
{
if (last_viewangles == '0 0 0')
last_viewangles = getviewprop(VF_ANGLES);
vector cl_viewangles = getviewprop(VF_ANGLES);
vector difference = last_viewangles - cl_viewangles;
last_viewangles = cl_viewangles;
// Invert the X (up/down) axis, so that viewmodel
// accels downward when camera moves up, and vice versa.
difference[0] = -difference[0];
return difference;
};
//
// ViewModel_CalcSlack()
// Calculates "slack" -- how far behind the viewents
// should fall behind the camera. Appended to viewent's angles.
//
vector() ViewModel_CalcSlack =
{
// Calculate the target slack distance based on the view angle difference
vector target_slack_distance = ViewModel_CalcViewAngleDifference();
target_slack_distance[0] *= VIEWMODEL_ANGLE_SLACK_FACTOR;
target_slack_distance[1] *= VIEWMODEL_ANGLE_SLACK_FACTOR;
target_slack_distance[2] *= VIEWMODEL_ANGLE_SLACK_FACTOR;
for(float i = 0; i < 2; i++) {
// Apply smoothing to the viewmodel_slack_distance
viewmodel_slack_distance[i] = damp(viewmodel_slack_distance[i], target_slack_distance[i], 0.1, clframetime * 4);
// Clamp the values to a maximum threshold
// Sorta nasty hack.. or something.. if the client is under 60FPS clamp at a lower value
if (clframetime > 0.016)
viewmodel_slack_distance[i] = clamp(viewmodel_slack_distance[i], -0.2, 0.2);
else
viewmodel_slack_distance[i] = clamp(viewmodel_slack_distance[i], -0.5, 0.5);
}
return viewmodel_slack_distance;
};
//
// ViewModel_Animate(viewent)
// Interpolation and animation for specified view entity.
//
void(entity viewent) ViewModel_Animate =
{
float new_frame, new_model, anim_duration = 0;
if (viewent == cl_viewent) {
new_frame = getstatf(STAT_WEAPONFRAME);
new_model = getstatf(STAT_WEAPONMODELI);
anim_duration = getstatf(STAT_WEAPONDURATION);
} else { // Assumes cl_viewent2
new_model = getstatf(STAT_WEAPON2MODELI);
anim_duration = getstatf(STAT_WEAPON2DURATION);
// If our current weapon is not dual-wielded, we want weapon2frame
// to always match standard weapon frames.
if (!IsDualWeapon(getstatf(STAT_ACTIVEWEAPON)))
new_frame = getstatf(STAT_WEAPONFRAME);
else
new_frame = getstatf(STAT_WEAPON2FRAME);
}
if (!anim_duration) anim_duration = 0.1; // Default to 10fps.
// Server requested a model change
if (new_model != viewent.modelindex) {
viewent.modelindex = new_model;
// Don't lerp new models. Fixes perceieved stutter.
viewent.frame = new_frame;
// If we switched to a different weapon model,
// make sure to update the HUD.
if (getmodelindex(GetWeaponModel(getstatf(STAT_ACTIVEWEAPON), false)) == viewent.modelindex)
HUD_Change_time = time + 6;
// Update the skin.
viewent.skin = getstatf(STAT_WEAPONSKIN);
}
// Server requested a frame change
if (new_frame != viewent.frame) {
viewent.frame2 = viewent.frame;
viewent.frame2time = viewent.frame1time;
viewent.frame = new_frame;
viewent.frame1time = 0;
viewent.lerpfrac = 1;
}
else {
viewent.frame = new_frame;
}
viewent.lerpfrac -= frametime * (1/anim_duration);
viewent.frame1time += frametime;
};
//
// ViewModel_MotionBob(viewent)
// Bobs the specified view entity with ViewModel_CalcBob.
//
void(entity viewent) ViewModel_MotionBob =
{
// If the server is paused, early-out..
if (serverkey(SERVERKEY_PAUSESTATE) == "1")
return;
float client_speed;
// Calculate a rough estimate of the client's speed
client_speed = (0.2 + sqrt((playerVelocity[0] * playerVelocity[0]) + (playerVelocity[1] * playerVelocity[1])))/280;
// Run the bob calculation
float bob, bobside;
bob = ViewModel_CalcBob(client_speed, 0);
bobside = ViewModel_CalcBob(client_speed, 1);
// Set as start of view entity's origin offset.
viewent.origin[2] = bob*0.5;
viewent.origin[1] = bobside * 0.4;
};
//
// ViewModel_GetADSPosition()
// Returns a vector representing current offset
// progress on Aiming Down the Sight.
//
vector() ViewModel_GetADSPosition =
{
vector ads_offset = '0 0 0';
float client_zoom = getstatf(STAT_WEAPONZOOM);
if (client_zoom == 1 || client_zoom == 2) {
// These are ordered differently in QuakeC because ??
// right, up, forward
vector temp_adsofs = GetWeaponADSOfs_PSP(getstatf(STAT_ACTIVEWEAPON));
// Translate to proper order, and re-gain precision.
ads_offset[0] = temp_adsofs[2]/1000;
ads_offset[1] = -temp_adsofs[0]/1000; // Y needs to be negative here -- matches Blender output, discrepancy from glQuake.
ads_offset[2] = temp_adsofs[1]/1000;
}
// Interpolate values in/out of ADS over time.
current_viewmodel_ads_position[0] += (ads_offset[0] - current_viewmodel_ads_position[0]) * VIEWMODEL_ADS_TIME_FACTOR;
current_viewmodel_ads_position[1] += (ads_offset[1] - current_viewmodel_ads_position[1]) * VIEWMODEL_ADS_TIME_FACTOR;
current_viewmodel_ads_position[2] += (ads_offset[2] - current_viewmodel_ads_position[2]) * VIEWMODEL_ADS_TIME_FACTOR;
// Limit the vector to avoid bouncing back and forth on low framerates.
if (client_zoom == 1 || client_zoom == 2) {
if (current_viewmodel_ads_position[0] > ads_offset[0]) current_viewmodel_ads_position[0] = ads_offset[0];
if (current_viewmodel_ads_position[1] > ads_offset[1]) current_viewmodel_ads_position[1] = ads_offset[1];
if (current_viewmodel_ads_position[2] > ads_offset[2]) current_viewmodel_ads_position[2] = ads_offset[2];
} else {
if (current_viewmodel_ads_position[0] < 0) current_viewmodel_ads_position[0] = 0;
if (current_viewmodel_ads_position[1] < 0) current_viewmodel_ads_position[1] = 0;
if (current_viewmodel_ads_position[2] < 0) current_viewmodel_ads_position[2] = 0;
}
// Return progress on Zoom position.
return current_viewmodel_ads_position;
};
//
// ViewModel_Draw()
// Performs drawing routine for cl_viewent and cl_viewent2
//
void() ViewModel_Draw =
{
// Spawn the model entities if they do not already exist..
if (!cl_viewent) {
cl_viewent = spawn();
cl_viewent2 = spawn();
cl_viewent.renderflags = cl_viewent2.renderflags = RF_VIEWMODEL;
}
// If we're zoomed in with a Sniper scope or r_drawviewmodel is false, early-out.
if (!cvar("r_drawviewmodel") || getstatf(STAT_WEAPONZOOM) == 2)
return;
cl_viewent.origin = cl_viewent2.origin = '0 0 0';
// Bob while in motion
ViewModel_MotionBob(cl_viewent);
ViewModel_MotionBob(cl_viewent2);
// Adjust viewmodel position based on ADS value.
vector viewent_ads_position = ViewModel_GetADSPosition();
cl_viewent.origin += viewent_ads_position;
cl_viewent2.origin += viewent_ads_position;
// Animate and Interpolate
ViewModel_Animate(cl_viewent);
ViewModel_Animate(cl_viewent2);
// Have the View Model "lag behind" the camera a bit.
cl_viewent.angles = ViewModel_CalcSlack();
// Send the viewents to engine for drawing.
addentity(cl_viewent);
addentity(cl_viewent2);
};

View file

@ -674,7 +674,7 @@ void() PathfindToEnemy =
#ifdef FTE #ifdef FTE
bprint(PRINT_HIGH, "FirstPathfind Failure\n"); //bprint(PRINT_HIGH, "FirstPathfind Failure\n");
#endif // FTE #endif // FTE

View file

@ -150,50 +150,6 @@ void SetPerk(entity client, float to)
#endif // FTE #endif // FTE
} }
void(float to) SwitchWeapon =
{
#ifdef FTE
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_WEAPONCHANGE);
WriteByte(MSG_MULTICAST, to);
msg_entity = self;
multicast('0 0 0', MULTICAST_ONE);
// hotfix for weapon2models not reseting
self.weapon2model = GetWeapon2Model(to);
#endif // FTE
}
void(string to, float skin) UpdateVmodel =
{
#ifdef FTE
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_UPDATEVMODEL);
WriteString(MSG_MULTICAST, to);
WriteByte(MSG_MULTICAST, skin);
msg_entity = self;
multicast('0 0 0', MULTICAST_ONE);
#endif // FTE
}
void(string to, float skin) UpdateV2model =
{
#ifdef FTE
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_UPDATEV2MODEL);
WriteString(MSG_MULTICAST, to);
WriteByte(MSG_MULTICAST, skin);
msg_entity = self;
multicast('0 0 0', MULTICAST_ONE);
#endif // FTE
}
void(float index, float state) ChangeReviveIconState = void(float index, float state) ChangeReviveIconState =
{ {
#ifdef FTE #ifdef FTE

View file

@ -104,9 +104,6 @@ void() startspectate =
self.downed = 0; self.downed = 0;
self.frame = 0; self.frame = 0;
UpdateVmodel(self.weaponmodel, GetWepSkin(self.weapon));
UpdateV2model(self.weapon2model, GetWepSkin(self.weapon));
SpectatorSpawn(); SpectatorSpawn();
} }
@ -148,7 +145,6 @@ void() EndGameSetup =
} }
game_over = true; game_over = true;
SetPerk(self, self.perks); SetPerk(self, self.perks);
SwitchWeapon(0);
addmoney(self, -self.points, 0); addmoney(self, -self.points, 0);
addmoney(self, self.score, 0); addmoney(self, self.score, 0);
return; return;
@ -333,7 +329,6 @@ void() GetDown =
// Play Switch Animation // Play Switch Animation
self.weaponmodel = GetWeaponModel(self.weapon, 0); self.weaponmodel = GetWeaponModel(self.weapon, 0);
SwitchWeapon(self.weapon);
float startframe = GetFrame(self.weapon,TAKE_OUT_START); float startframe = GetFrame(self.weapon,TAKE_OUT_START);
float endframe = GetFrame(self.weapon,TAKE_OUT_END); float endframe = GetFrame(self.weapon,TAKE_OUT_END);

View file

@ -154,7 +154,6 @@ void() W_SprintStop;
.float hunt_count; // How many Hellhounds are hunting a client .float hunt_count; // How many Hellhounds are hunting a client
//Weaponsystem defines //Weaponsystem defines
void SwitchWeapon(float to);
void GetUp(); void GetUp();
void WeaponCore_ClientLogic(); void WeaponCore_ClientLogic();
void (float shotcount, float sprd, float Damage, float side) FireTrace; void (float shotcount, float sprd, float Damage, float side) FireTrace;
@ -181,6 +180,12 @@ void (float shotcount, float sprd, float Damage, float side) FireTrace;
.float reloadinterupted; .float reloadinterupted;
.float hitcount; .float hitcount;
#ifdef FTE
.float weapon2modelindex;
#endif // FTE
#define SEMIACTION_FIRE_RIGHT 1 #define SEMIACTION_FIRE_RIGHT 1
#define SEMIACTION_FIRE_LEFT 2 #define SEMIACTION_FIRE_LEFT 2
#define SEMIACTION_USE 4 #define SEMIACTION_USE 4

View file

@ -231,7 +231,6 @@ void(entity pap, entity buyer) PAP_UpgradeWeapon =
W_HideCrosshair(self); W_HideCrosshair(self);
Set_W_Frame (0, 39, 2.0, 0, 0, W_PutOutHack, "models/machines/v_pap.mdl", true, S_BOTH); Set_W_Frame (0, 39, 2.0, 0, 0, W_PutOutHack, "models/machines/v_pap.mdl", true, S_BOTH);
self.weapon2model = ""; self.weapon2model = "";
UpdateV2model(self.weapon2model, 0);
#ifndef FTE #ifndef FTE

View file

@ -326,7 +326,8 @@ void() worldspawn =
clientstat(STAT_CURRENTMAG2, EV_FLOAT, weapons[0].weapon_magazine_left); clientstat(STAT_CURRENTMAG2, EV_FLOAT, weapons[0].weapon_magazine_left);
clientstat(STAT_POINTS, EV_FLOAT, points); clientstat(STAT_POINTS, EV_FLOAT, points);
clientstat(STAT_WEAPON2FRAME, EV_FLOAT, weapon2frame); clientstat(STAT_WEAPON2FRAME, EV_FLOAT, weapon2frame);
clientstat(STAT_WEAPON2MODEL, EV_STRING, weapon2model); clientstat(STAT_WEAPON2MODELI, EV_FLOAT, weapon2modelindex);
clientstat(STAT_WEAPONSKIN, EV_FLOAT, weaponskin);
clientstat(STAT_GRENADES, EV_FLOAT, primary_grenades); clientstat(STAT_GRENADES, EV_FLOAT, primary_grenades);
clientstat(STAT_SECGRENADES, EV_FLOAT, secondary_grenades); clientstat(STAT_SECGRENADES, EV_FLOAT, secondary_grenades);
clientstat(STAT_PROGRESSBAR, EV_FLOAT, progress_bar_percent); clientstat(STAT_PROGRESSBAR, EV_FLOAT, progress_bar_percent);

View file

@ -890,8 +890,6 @@ void() PlayerSpawn =
self.weaponmodel = GetWeaponModel(self.weapon, 0);// Give weapon model self.weaponmodel = GetWeaponModel(self.weapon, 0);// Give weapon model
self.weapon2model = GetWeapon2Model(self.weapon); self.weapon2model = GetWeapon2Model(self.weapon);
SwitchWeapon(self.weapon);
self.stamina = 3; self.stamina = 3;
self.reviving = 0; self.reviving = 0;
self.perks = G_PERKS; self.perks = G_PERKS;
@ -907,8 +905,6 @@ void() PlayerSpawn =
#ifdef FTE #ifdef FTE
UpdateV2model("", 0);
stuffcmd(self, "cl_gunx 8;cl_guny 16;cl_gunz 25\n");
SetRound(self, G_STARTROUND); SetRound(self, G_STARTROUND);
self.viewzoom = 1; self.viewzoom = 1;
self.SendEntity = Player_SendEntity; self.SendEntity = Player_SendEntity;

View file

@ -201,10 +201,7 @@ void (float animation_type, void(optional float t) end_function, float playback_
} }
self.switch_delay = self.reload_delay2 = self.fire_delay2 = self.reload_delay = self.fire_delay = self.knife_delay = time + (duration - 0.1); self.switch_delay = self.reload_delay2 = self.fire_delay2 = self.reload_delay = self.fire_delay = self.knife_delay = time + (duration - 0.1);
UpdateVmodel(self.weaponmodel, GetWepSkin(self.weapon));
self.weapon2model = GetWeapon2Model(self.weapon); self.weapon2model = GetWeapon2Model(self.weapon);
UpdateV2model(self.weapon2model, GetWepSkin(self.weapon));
W_AimOut(); W_AimOut();
Set_W_Frame(start_frame, end_frame, playback_duration, 0, 0, end_function, GetWeaponModel(self.weapon, 0), false, S_BOTH); Set_W_Frame(start_frame, end_frame, playback_duration, 0, 0, end_function, GetWeaponModel(self.weapon, 0), false, S_BOTH);
@ -261,13 +258,14 @@ void Weapon_SwapWeapons(float play_animation)
// Properly update the weapon ID // Properly update the weapon ID
self.weapon = self.weapons[0].weapon_id; self.weapon = self.weapons[0].weapon_id;
SwitchWeapon(self.weapon);
W_HideCrosshair(self); W_HideCrosshair(self);
Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0);
#ifndef FTE
self.weaponskin = self.weapons[0].weapon_skin; self.weaponskin = self.weapons[0].weapon_skin;
#ifndef FTE
self.weapon2skin = self.weapons[0].weapon_skin; self.weapon2skin = self.weapons[0].weapon_skin;
self.Weapon_Name = GetWeaponName(self.weapon); self.Weapon_Name = GetWeaponName(self.weapon);
self.Flash_Offset = GetWeaponFlash_Offset(self.weapon); self.Flash_Offset = GetWeaponFlash_Offset(self.weapon);
@ -293,16 +291,15 @@ void Weapon_SetActiveInSlot(float slot, float play_first_raise)
// Properly update the weapon ID // Properly update the weapon ID
self.weapon = self.weapons[0].weapon_id; self.weapon = self.weapons[0].weapon_id;
SwitchWeapon(self.weapon);
if (GetFrame(self.weapon, FIRST_TAKE_START) != 0 && play_first_raise == true) if (GetFrame(self.weapon, FIRST_TAKE_START) != 0 && play_first_raise == true)
Weapon_PlayViewModelAnimation(ANIM_FIRST_TAKE, ReturnWeaponModel, 0); Weapon_PlayViewModelAnimation(ANIM_FIRST_TAKE, ReturnWeaponModel, 0);
else else
Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0);
self.weaponskin = self.weapons[0].weapon_skin;
#ifndef FTE #ifndef FTE
self.weaponskin = self.weapons[0].weapon_skin;
self.weapon2skin = self.weapons[0].weapon_skin; self.weapon2skin = self.weapons[0].weapon_skin;
self.Weapon_Name = GetWeaponName(self.weapon); self.Weapon_Name = GetWeaponName(self.weapon);
self.Flash_Offset = GetWeaponFlash_Offset(self.weapon); self.Flash_Offset = GetWeaponFlash_Offset(self.weapon);

View file

@ -136,7 +136,6 @@ void () W_Frame_Update =
} }
else if (self.weaponmodel == "progs/VModels/v_knife.mdl" || self.weaponmodel == "models/machines/v_perk.mdl") { else if (self.weaponmodel == "progs/VModels/v_knife.mdl" || self.weaponmodel == "models/machines/v_perk.mdl") {
self.weapon2model = ""; self.weapon2model = "";
UpdateV2model(self.weapon2model, 0);
} }
if (self.callfuncat) if (self.callfuncat)
@ -237,24 +236,15 @@ void Set_W_Frame (float startframe, float endframe, float duration, float funcca
if ((startframe != endframe) && !(self.zoom == 2)) { // naievil -- latter used for checkhold if ((startframe != endframe) && !(self.zoom == 2)) { // naievil -- latter used for checkhold
if (side == S_LEFT) { if (side == S_LEFT) {
self.weapon2model = set_model; self.weapon2model = set_model;
UpdateV2model(self.weapon2model, GetWepSkin(self.weapon));
} else { } else {
self.weaponmodel = set_model; self.weaponmodel = set_model;
if (set_model != "models/machines/v_perk.mdl")
UpdateVmodel(self.weaponmodel, GetWepSkin(self.weapon));
else
UpdateVmodel(self.weaponmodel, self.weaponskin);
if (model_should_hide_weapon2(set_model) == true) { if (model_should_hide_weapon2(set_model) == true) {
self.weapon2model = ""; self.weapon2model = "";
UpdateV2model(self.weapon2model, 0);
} else if (self.weapon == W_KAR_SCOPE) { } else if (self.weapon == W_KAR_SCOPE) {
self.weapon2model = "models/weapons/kar/v_karscope.mdl"; self.weapon2model = "models/weapons/kar/v_karscope.mdl";
UpdateV2model(self.weapon2model, 0);
} else if (IsDualWeapon(self.weapon)) { } else if (IsDualWeapon(self.weapon)) {
self.weapon2model = GetLeftWeaponModel(self.weapon); self.weapon2model = GetLeftWeaponModel(self.weapon);
UpdateV2model(self.weapon2model, 0);
} }
} }
} }

View file

@ -87,12 +87,8 @@ void() ReturnWeaponModel =
self.weapon2model = GetLeftWeaponModel(self.weapon); self.weapon2model = GetLeftWeaponModel(self.weapon);
} else if (self.weapon == W_KAR_SCOPE || self.weapon == W_HEADCRACKER) { } else if (self.weapon == W_KAR_SCOPE || self.weapon == W_HEADCRACKER) {
self.weapon2model = "models/weapons/kar/v_karscope.mdl"; self.weapon2model = "models/weapons/kar/v_karscope.mdl";
UpdateV2model(self.weapon2model, 0);
} }
UpdateVmodel(self.weaponmodel, GetWepSkin(self.weapon));
UpdateV2model(self.weapon2model, GetWepSkin(self.weapon));
// Always try to reload after any action. // Always try to reload after any action.
if (self.weapons[0].weapon_magazine == 0 && self.weapons[0].weapon_reserve != 0) if (self.weapons[0].weapon_magazine == 0 && self.weapons[0].weapon_reserve != 0)
W_Reload(S_RIGHT); W_Reload(S_RIGHT);
@ -1242,8 +1238,6 @@ void() WeaponCore_Melee =
void() end_func; void() end_func;
if (!WepDef_IsMeleeWeapon(self.weapon)) { if (!WepDef_IsMeleeWeapon(self.weapon)) {
end_func = W_PlayTakeOut; end_func = W_PlayTakeOut;
// Additionally, assume since it's separate model, that it uses one skin exclusively.
self.weaponskin = 0;
} else { } else {
end_func = __NULL__; end_func = __NULL__;
} }
@ -1942,6 +1936,14 @@ inline void() WeaponCore_UpdateWeaponStats =
self.currentammo = self.weapons[0].weapon_reserve; // Weapon Reserve Ammo self.currentammo = self.weapons[0].weapon_reserve; // Weapon Reserve Ammo
self.currentmag = self.weapons[0].weapon_magazine; // Weapon Magazine self.currentmag = self.weapons[0].weapon_magazine; // Weapon Magazine
self.currentmag2 = self.weapons[0].weapon_magazine_left; // Left-side Weapon Magazine self.currentmag2 = self.weapons[0].weapon_magazine_left; // Left-side Weapon Magazine
// FTE-specific - update weapon2modelindex to simplify protocol
// and data exchange.
#ifdef FTE
self.weapon2modelindex = getmodelindex(self.weapon2model);
#endif // FTE
}; };
// //

View file

@ -28,41 +28,37 @@
#define true 1 #define true 1
#define false 0 #define false 0
const float EVENT_WEAPONCHANGE = 9; #define EVENT_PISTOLFIRE 10
const float EVENT_PISTOLFIRE = 10; #define EVENT_USEPRINT 11
const float EVENT_USEPRINT = 11; #define EVENT_NEWROUND 12
const float EVENT_NEWROUND = 12; #define EVENT_SETROUND 13
const float EVENT_SETROUND = 13; #define EVENT_PERK 22
const float EVENT_UPDATEVMODEL = 20; #define EVENT_UPDATE 23
const float EVENT_UPDATEV2MODEL = 21; #define EVENT_BROADCAST 24
const float EVENT_PERK = 22; #define EVENT_POINTUPDATE 25
const float EVENT_UPDATE = 23; #define EVENT_BLACKOUT 26
const float EVENT_BROADCAST = 24; #define EVENT_SCROLLTEXT 28
const float EVENT_POINTUPDATE = 25; #define EVENT_WORLDDATA 29
const float EVENT_BLACKOUT = 26; #define EVENT_ACHIEVEMENT 30
//const float EVENT_PUNCHANGLE = 27; #define EVENT_PLAYERUPDATE 31
const float EVENT_SCROLLTEXT = 28; #define EVENT_WEAPONUPDATE 32
const float EVENT_WORLDDATA = 29; #define EVENT_HUDUPDATE 33
const float EVENT_ACHIEVEMENT = 30; #define EVENT_EXPLOSION 34
const float EVENT_PLAYERUPDATE = 31; #define EVENT_BLOOD 35
const float EVENT_WEAPONUPDATE = 32; #define EVENT_ACHIEVEMENTPROGRESS 36
const float EVENT_HUDUPDATE = 33; #define EVENT_REVIVEON 37
const float EVENT_EXPLOSION = 34; #define EVENT_REVIVEOFF 38
const float EVENT_BLOOD = 35; #define EVENT_REVIVECHANGE 39
const float EVENT_ACHIEVEMENTPROGRESS = 36; #define EVENT_WEAPONRECOIL 40
const float EVENT_REVIVEON = 37; #define EVENT_SONGPLAY 41
const float EVENT_REVIVEOFF = 38; #define EVENT_GRENADEPULSE 42
const float EVENT_REVIVECHANGE = 39; #define EVENT_BETTYPROMPT 43
const float EVENT_WEAPONRECOIL = 40; #define EVENT_LIMBGIB 44
const float EVENT_SONGPLAY = 41; #define EVENT_CHATMESSAGE 45
const float EVENT_GRENADEPULSE = 42; #define EVENT_DOUBLETAPUPDATE 46
const float EVENT_BETTYPROMPT = 43; #define EVENT_FLAME 47
const float EVENT_LIMBGIB = 44; #define EVENT_ENDGAME 48
const float EVENT_CHATMESSAGE = 45; #define EVENT_MAPTYPE 49
const float EVENT_DOUBLETAPUPDATE = 46;
const float EVENT_FLAME = 47;
const float EVENT_ENDGAME = 48;
const float EVENT_MAPTYPE = 49;
// Define our FTE platform // Define our FTE platform
#ifndef STANDARD #ifndef STANDARD
@ -244,7 +240,7 @@ float map_compatibility_mode;
#define STAT_CURRENTMAG2 51 #define STAT_CURRENTMAG2 51
#define STAT_POINTS 52 #define STAT_POINTS 52
#define STAT_WEAPON2FRAME 53 #define STAT_WEAPON2FRAME 53
#define STAT_WEAPON2MODEL 54 #define STAT_WEAPON2MODELI 54
#define STAT_GRENADES 55 #define STAT_GRENADES 55
#define STAT_SECGRENADES 56 #define STAT_SECGRENADES 56
#define STAT_PROGRESSBAR 57 #define STAT_PROGRESSBAR 57
@ -259,6 +255,7 @@ float map_compatibility_mode;
#define STAT_FACINGENEMY 66 #define STAT_FACINGENEMY 66
#define STAT_MAXHEALTH 67 #define STAT_MAXHEALTH 67
#define STAT_PLAYERNAME 68 #define STAT_PLAYERNAME 68
#define STAT_WEAPONSKIN 69
.float playernum; .float playernum;
float game_over; float game_over;

View file

@ -1534,86 +1534,6 @@ float GetWeaponWalkSpeed(float perks, float weapon)
return speed_multiplier; return speed_multiplier;
} }
// forward/back,right/left,down/up
vector GetWeaponADSPos(float wep) {
switch (wep) {
case W_COLT:
return [-2.99, 2.75, 0.92]; //ironsight is accurate, model rotation is not
case W_KAR:
case W_ARMAGEDDON:
return [-2.19, 2.76, 1.57];
case W_SPRING:
case W_PULVERIZER:
return [-2.19, 2.67, 1.6];
case W_THOMPSON:
case W_GIBS:
return [0.5, 3.08, 1.76];
case W_357:
case W_KILLU:
return [-2.6, 4.16, 0.55];
case W_BAR:
case W_WIDOW:
return [2.7, 2.0, 1.27]; //ironsight is accurate, model rotation is not
case W_BROWNING:
case W_ACCELERATOR:
return [-4.6, 4.0, 1.68]; //ironsight is accurate, model rotation is not
case W_DB:
case W_BORE:
case W_SAWNOFF:
return [2.0, 2.9, 1.51];
case W_FG:
case W_IMPELLER:
return [-6.5, 5.92, .88];
case W_GEWEHR:
case W_COMPRESSOR:
return [-0.2, 2.58, 2.6];
case W_KAR_SCOPE:
case W_HEADCRACKER:
return [-2.19, 2.67, 0.42];
case W_M1:
case W_M1000:
return [-1.6, 3.86, 1.12];
case W_M1A1:
case W_WIDDER:
return [-3.0, 2.71, 1.55]; //ironsight is accurate, model rotation is not
case W_MP40:
case W_AFTERBURNER:
return [0.01, 5.73, 3.29];
case W_MP5K:
case W_KOLLIDER:
return [-5.19, 5.24, 2.76];
case W_TYPE:
case W_SAMURAI:
return [0, 0.2, 0.36];
case W_MG:
case W_BARRACUDA:
return [-2.0, 3.38, 1.87]; //ironsight is accurate, model rotation is not
case W_PPSH:
case W_REAPER:
return [-2.0, 3.76, 1.49];
case W_PTRS:
case W_PENETRATOR:
return [-2.79, 3.6, 0.40];
case W_STG:
case W_SPATZ:
return [-9.79, 4.92, 1.54];
case W_TRENCH:
case W_GUT:
return [0, 2.80, 1.25];
case W_M2:
case W_FIW:
return [6.0, 4.3, 1.02];
case W_RAY:
case W_PORTER:
return [-1.50, 6.25, 0.87];
case W_PANZER:
case W_LONGINUS:
return [-11.9, 3.85, 1.62];
default:
return [0, 0, 0];
}
}
/* /*
=========================== ===========================