This is a massive change. Check the full msg here:

https://icculus.org/~marco/txt/nuclide_may2022.txt
This commit is contained in:
Marco Cawthorne 2022-03-15 19:33:11 -07:00
parent 519035d349
commit 96f3a1224a
Signed by: eukara
GPG Key ID: C196CD8BA993248A
26 changed files with 291 additions and 201 deletions

View File

@ -24,8 +24,3 @@ ClientGame_EntityUpdate(float id, float new)
return (1);
}
void
ClientGame_EntityRemove(void)
{
}

View File

@ -15,10 +15,8 @@
*/
void
View_UpdateWeapon(entity vm, entity mflash)
View_UpdateWeapon(player pl, entity vm, entity mflash)
{
player pl = (player)pSeat->m_ePlayer;
/* only bother upon change */
if (pSeat->m_iLastWeapon == pl.activeweapon) {
return;
@ -31,7 +29,7 @@ View_UpdateWeapon(entity vm, entity mflash)
}
/* hack, we changed the wep, move this into Game_Input/PMove */
Weapons_Draw();
Weapons_Draw(pl);
/* we forced a weapon call outside the prediction,
* thus we need to update all the net variables to

View File

@ -97,7 +97,7 @@ Player_UseUp(void) {
}
}
void Weapons_Draw(void);
void Weapons_Draw(player);
void
CSEv_PlayerSwitchWeapon_i(int w)
@ -106,7 +106,7 @@ CSEv_PlayerSwitchWeapon_i(int w)
if (pl.activeweapon != w) {
pl.activeweapon = w;
Weapons_Draw();
Weapons_Draw(pl);
}
}

View File

@ -15,7 +15,7 @@
*/
#ifdef SERVER
#define CORPSES_MAX 32
#define CORPSES_MAX 16
entity g_bodies;
void

View File

@ -15,7 +15,7 @@
*/
void
Game_Input(void)
Game_Input(player pl)
{
#ifdef SERVER
CGameRules rules = (CGameRules)g_grMode;
@ -30,18 +30,18 @@ Game_Input(void)
else
Player_UseUp();
if (self.impulse == 100)
if (pl.impulse == 100)
Flashlight_Toggle();
self.impulse = 0;
pl.impulse = 0;
#endif
if (input_buttons & INPUT_BUTTON0)
Weapons_Primary();
Weapons_Primary(pl);
else if (input_buttons & INPUT_BUTTON4)
Weapons_Reload();
Weapons_Reload(pl);
else if (input_buttons & INPUT_BUTTON3)
Weapons_Secondary();
Weapons_Secondary(pl);
else
Weapons_Release();
Weapons_Release(pl);
}

View File

@ -17,7 +17,7 @@ w_basemelee_fire(int d, int w)
return (MELEE_FAILED);
}
Weapons_MakeVectors();
Weapons_MakeVectors(pl);
src = pl.origin + pl.view_ofs;
/* make sure we can gib corpses */

View File

@ -23,10 +23,8 @@ enum
};
int
w_baseprojectile_fire(int w, .int mag, void() spawnfunc)
w_baseprojectile_fire(player pl, int w, .int mag, void(player) spawnfunc)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return (SEMI_FIRE_FAILED);
}
@ -40,7 +38,7 @@ w_baseprojectile_fire(int w, .int mag, void() spawnfunc)
pl.(mag)--;
#ifdef SERVER
spawnfunc();
spawnfunc(pl);
#endif
if (pl.(mag) == 0)

View File

@ -20,7 +20,9 @@ typedef enum
WPNTYPE_INVALID, /* no logic */
WPNTYPE_RANGED, /* will want to keep their distance mostly */
WPNTYPE_THROW, /* has to keep some distance, but not too far */
WPNTYPE_CLOSE /* have to get really close */
WPNTYPE_CLOSE, /* have to get really close */
WPNTYPE_FULLAUTO, /* for things that need to be held down */
WPNTYPE_SEMI /* semi automatic */
} weapontype_t;
typedef struct
@ -31,48 +33,47 @@ typedef struct
int slot_pos;
int allow_drop;
int weight; /* required for bestweapon */
weapontype_t(void) type; /* required for bot-AI */
void(void) draw;
void(void) holster;
void(void) primary;
void(void) secondary;
void(void) reload;
void(void) release;
void(int) predraw; /* predraw... */
void(void) crosshair; /* postdraw... */
int(void) isempty; /* kinda handy */
void(void) precache;
int(int, int) pickup;
void(player) updateammo;
string() wmodel;
string() pmodel;
string() deathmsg;
float() aimanim;
void(int, vector, float) hudpic;
/* player specific */
string(player) pmodel;
float(player) aimanim;
weapontype_t(player) type; /* required for bot-AI */
void(player) draw;
void(player) holster;
void(player) primary;
void(player) secondary;
void(player) reload;
void(player) release;
int(player, int, int) pickup;
void(player) updateammo;
void(player, int) predraw; /* predraw... */
void(player) postdraw; /* postdraw... */
int(player) isempty; /* kinda handy */
void(player, int, vector, float) hudpic;
} weapon_t;
void Weapons_Holster(void);
void Weapons_Primary(void);
void Weapons_Secondary(void);
void Weapons_Reload(void);
void Weapons_Release(void);
void Weapons_PreDraw(int);
void Weapons_Holster(player pl);
void Weapons_Primary(player pl);
void Weapons_Secondary(player pl);
void Weapons_Reload(player pl);
void Weapons_Release(player pl);
void Weapons_PreDraw(player pl, int);
float Weapons_GetAim(int);
void Weapons_Reload(void);
float Weapons_GetAim(player, int);
int Weapons_IsEmpty(player, int);
void Weapons_DrawCrosshair(void);
void Weapons_MakeVectors(void);
vector Weapons_GetCameraPos(void);
void Weapons_ViewAnimation(int);
void Weapons_ViewPunchAngle(vector);
void Weapons_DrawCrosshair(player pl);
void Weapons_MakeVectors(player pl);
vector Weapons_GetCameraPos(player pl);
void Weapons_ViewAnimation(player pl, int);
void Weapons_ViewPunchAngle(player pl, vector);
int Weapons_IsPresent(player, int);
void Weapons_UpdateAmmo(base_player, int, int, int);
int Weapons_GetAnimation(void);
int Weapons_GetAnimation(player pl);
void Weapons_EnableModel(void);
void Weapons_DisableModel(void);
weapontype_t Weapons_GetType(player, int);
@ -90,6 +91,6 @@ void Weapons_SetModel(string);
void Weapons_Sound(entity, float, string);
#ifdef CLIENT
string Weapons_GetPlayermodel(int);
void Weapons_HUDPic(int, int, vector, float);
string Weapons_GetPlayermodel(player, int);
void Weapons_HUDPic(player, int, int, vector, float);
#endif

View File

@ -164,9 +164,8 @@ Weapons_SetGeomset(string set)
}
void
Weapons_Draw(void)
Weapons_Draw(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
pl.w_attack_next = 0.5f;
@ -183,33 +182,31 @@ Weapons_Draw(void)
pl.a_ammo1 = pl.a_ammo2 = pl.a_ammo3 = 0;
if (g_weapons[i].draw != __NULL__)
g_weapons[i].draw();
g_weapons[i].draw(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Holster(void)
Weapons_Holster(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].holster != __NULL__)
g_weapons[i].holster();
g_weapons[i].holster(pl);
}
void
Weapons_Primary(void)
Weapons_Primary(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].primary != __NULL__)
g_weapons[i].primary();
g_weapons[i].primary(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
@ -227,57 +224,53 @@ Weapons_AmmoUpdate(entity target)
}
void
Weapons_Secondary(void)
Weapons_Secondary(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].secondary != __NULL__)
g_weapons[i].secondary();
g_weapons[i].secondary(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Reload(void)
Weapons_Reload(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].reload != __NULL__)
g_weapons[i].reload();
g_weapons[i].reload(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Release(void)
Weapons_Release(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].release != __NULL__)
g_weapons[i].release();
g_weapons[i].release(pl);
pl.gflags &= ~GF_SEMI_TOGGLED;
}
void
Weapons_PreDraw(int thirdperson)
Weapons_PreDraw(player pl, int thirdperson)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].predraw != __NULL__)
g_weapons[i].predraw(thirdperson);
g_weapons[i].predraw(pl, thirdperson);
}
int
@ -289,7 +282,7 @@ Weapons_IsEmpty(player pl, int w)
self = pl;
if (g_weapons[w].isempty != __NULL__)
r = g_weapons[w].isempty();
r = g_weapons[w].isempty(pl);
self = oself;
@ -306,7 +299,7 @@ Weapons_GetType(player pl, int w)
self = pl;
if (g_weapons[w].type != __NULL__)
r = g_weapons[w].type();
r = g_weapons[w].type(pl);
self = oself;
@ -314,13 +307,12 @@ Weapons_GetType(player pl, int w)
}
void
Weapons_DrawCrosshair(void)
Weapons_DrawCrosshair(player pl)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].crosshair != __NULL__)
g_weapons[i].crosshair();
if (g_weapons[i].postdraw != __NULL__)
g_weapons[i].postdraw(pl);
}
string
@ -333,10 +325,10 @@ Weapons_GetWorldmodel(int id)
}
string
Weapons_GetPlayermodel(int id)
Weapons_GetPlayermodel(player pl, int id)
{
if (g_weapons[id].pmodel != __NULL__)
return g_weapons[id].pmodel();
return g_weapons[id].pmodel(pl);
return "";
}
@ -351,28 +343,27 @@ Weapons_GetDeathmessage(int id)
}
float
Weapons_GetAim(int id)
Weapons_GetAim(player pl, int id)
{
if (g_weapons[id].aimanim != __NULL__)
return g_weapons[id].aimanim();
return g_weapons[id].aimanim(pl);
return (0);
}
#ifdef CLIENT
void
Weapons_HUDPic(int id, int s, vector pos, float a)
Weapons_HUDPic(player pl, int id, int s, vector pos, float a)
{
if (g_weapons[id].hudpic != __NULL__)
g_weapons[id].hudpic(s, pos, a);
g_weapons[id].hudpic(pl, s, pos, a);
}
#endif
void
Weapons_MakeVectors(void)
Weapons_MakeVectors(player pl)
{
#ifdef SERVER
player pl = (player)self;
makevectors(pl.v_angle);
#else
makevectors(view_angles);
@ -380,22 +371,22 @@ Weapons_MakeVectors(void)
}
vector
Weapons_GetCameraPos(void)
Weapons_GetCameraPos(player pl)
{
#ifdef SERVER
return (self.origin + self.view_ofs);
return (pl.origin + pl.view_ofs);
#else
return getproperty(VF_ORIGIN);
#endif
}
void
Weapons_ViewAnimation(int i)
Weapons_ViewAnimation(player pl, int i)
{
player pl = (player)self;
#ifdef CLIENT
#if 0
View_PlayAnimation(i);
#endif
pl.weaponframe = i;
pl.weapontime = 0.0f;
}
@ -404,19 +395,14 @@ int View_GetAnimation(void);
#endif
int
Weapons_GetAnimation(void)
Weapons_GetAnimation(player pl)
{
#ifdef CLIENT
return View_GetAnimation();
#else
return (0);
#endif
return pl.weaponframe;
}
void
Weapons_ViewPunchAngle(vector add)
Weapons_ViewPunchAngle(player pl, vector add)
{
player pl = (player)self;
pl.punchangle += add;
}
@ -465,9 +451,9 @@ Weapons_UpdateAmmo(base_player pl, int a1, int a2, int a3)
a3 = pl.a_ammo3;
/* networked as bytes, since we don't need more. Clamp to avoid errors */
pl.a_ammo1 = bound(0, a1, 255);
pl.a_ammo2 = bound(0, a2, 255);
pl.a_ammo3 = bound(0, a3, 255);
pl.a_ammo1 = a1;
pl.a_ammo2 = a2;
pl.a_ammo3 = a3;
}
void

View File

@ -92,3 +92,14 @@ class bot:player
};
entity Bot_AddQuick(void);
void
Bot_RandomColormap(bot target)
{
vector x = hsv2rgb(random() * 360, 100, 100);
float top = x[2] + (x[1] << 8) + (x[0] << 16);
x = hsv2rgb(random() * 360, 100, 100);
float bottom = x[2] + (x[1] << 8) + (x[0] << 16);
forceinfokey(target, "topcolor", sprintf("0x%x", top));
forceinfokey(target, "bottomcolor", sprintf("0x%x", bottom));
}

View File

@ -73,6 +73,7 @@ bot::WeaponAttack(void)
{
int should_attack = 0;
/* only attack when the type's suggested distance makes sense to */
if (m_wtWeaponType == WPNTYPE_RANGED) {
if (m_flEnemyDist <= 1024)
should_attack = 1;
@ -83,21 +84,27 @@ bot::WeaponAttack(void)
if (m_flEnemyDist <= 128)
should_attack = 1;
} else {
should_attack = 1;
if (m_flEnemyDist <= 1024)
should_attack = 1;
}
if (should_attack && m_flAttackTime < time) {
if (!m_iAttackMode) {
input_buttons |= INPUT_BUTTON0;
}
m_flAttackTime = time + 0.1f;
if (m_wtWeaponType != WPNTYPE_FULLAUTO)
m_flAttackTime = time + 0.1f;
} else {
input_buttons &= ~INPUT_BUTTON0;
input_buttons &= ~INPUT_BUTTON4;
input_buttons &= ~INPUT_BUTTON5;
}
m_iAttackMode = 1 - m_iAttackMode;
if (m_wtWeaponType != WPNTYPE_FULLAUTO)
m_iAttackMode = 1 - m_iAttackMode;
else
m_iAttackMode = 0;
}
var float g_botalert_timer;

View File

@ -202,7 +202,7 @@ Route_SelectDestination(bot target)
dest = Route_SelectNearestEnemyTeam(BOTINFO_TEAM_GOALITEM, target.origin, target.team);
}
if (dest) {
if (dest != __NULL__) {
target.m_vecLastPOI = dest.origin;
return dest.origin + [0,0,32];
}
@ -215,7 +215,7 @@ Route_SelectDestination(bot target)
print(sprintf("%s going for health\n", target.netname));
dest = Route_SelectNearest(BOTINFO_HEALTH, target.origin, target.m_vecLastPOI);
if (dest) {
if (dest != __NULL__) {
target.m_vecLastPOI = dest.origin;
return dest.origin + [0,0,32];
}
@ -229,7 +229,7 @@ Route_SelectDestination(bot target)
print(sprintf("%s going for armor\n", target.netname));
dest = Route_SelectNearest(BOTINFO_ARMOR, target.origin, target.m_vecLastPOI);
if (dest) {
if (dest != __NULL__) {
target.m_vecLastPOI = dest.origin;
return dest.origin + [0,0,32];
}
@ -247,7 +247,7 @@ Route_SelectDestination(bot target)
else
dest = Route_SelectFarthest(BOTINFO_AMMO, target.origin, target.m_vecLastPOI);
if (dest) {
if (dest != __NULL__) {
target.m_vecLastPOI = dest.origin;
return dest.origin + [0,0,32];
}
@ -296,7 +296,7 @@ Route_GetNodeFlags(nodeslist_t *node)
vector
Route_GetJumpVelocity(vector vecFrom, vector vecTo, float flGravMod)
{
#if 0
#if 1
float flHeight, flGravity, flTime, flDistance, flDir;
vector vecJump = [0,0,0];

View File

@ -256,9 +256,16 @@ CSQC_UpdateView(float w, float h, float focus)
spec = (spectator)self;
Predict_SpectatorPreFrame(spec);
pSeat->m_vecPredictedOrigin = spec.origin;
pSeat->m_vecPredictedVelocity = spec.velocity;
pSeat->m_flPredictedFlags = spec.flags;
if (spec.spec_mode == SPECMODE_FIRSTPERSON || spec.spec_mode == SPECMODE_THIRDPERSON) {
entity c = findfloat(world, ::entnum, spec.spec_ent);
pSeat->m_vecPredictedOrigin = c.origin;
pSeat->m_vecPredictedVelocity = c.velocity;
pSeat->m_flPredictedFlags = c.flags;
} else {
pSeat->m_vecPredictedOrigin = spec.origin;
pSeat->m_vecPredictedVelocity = spec.velocity;
pSeat->m_flPredictedFlags = spec.flags;
}
}
#endif
@ -308,8 +315,7 @@ CSQC_UpdateView(float w, float h, float focus)
setproperty(VF_ORIGIN, trace_endpos + (v_forward * 5));
break;
case SPECMODE_FIRSTPERSON:
entity c;
c = findfloat(world, ::entnum, spec.spec_ent);
entity c = findfloat(world, ::entnum, spec.spec_ent);
if (c.classname == "player") {
player bp = (player)c;

View File

@ -37,6 +37,8 @@ player::draw(void)
float
player::predraw(void)
{
int this_us = 0;
super::predraw();
/* run animations regardless of rendering the player */
@ -45,12 +47,27 @@ player::predraw(void)
/* make sure we're enabling shadow rendering on us */
effects &= ~EF_NOSHADOW;
if (autocvar_cl_thirdperson == TRUE || this.entnum != player_localentnum) {
if (getplayerkeyvalue(pSeat->m_ePlayer.entnum-1, "*spec") == "1") {
spectator spec = (spectator)pSeat->m_ePlayer;
if (entnum == spec.spec_ent && spec.spec_mode == SPECMODE_FIRSTPERSON) {
this_us = 1;
}
} else {
if (entnum == player_localentnum) {
this_us = 1;
}
}
if (autocvar_cl_thirdperson == TRUE || !this_us) {
Voice_Draw3D(this);
Player_PreDraw(this, TRUE);
if (p_model)
addentity(p_model);
addentity(this);
} else {
Player_PreDraw(this, FALSE);
if (p_model)
removeentity(p_model);
removeentity(this);
}

View File

@ -106,6 +106,12 @@ View_CalcViewport(int s, float fWinWidth, float fWinHeight)
}
}
void
View_DrawViewmodel_Single(int weapon, float weapontime)
{
}
/*
====================
View_DrawViewModel
@ -122,21 +128,38 @@ View_DrawViewModel(void)
entity m_eViewModelL = pSeat->m_eViewModelL;
entity m_eMuzzleflashL = pSeat->m_eMuzzleflashL;
player pl = (player) self;
player pl = __NULL__;
if (pl.health <= 0) {
return;
/* it's either us or us spectating */
if (self.classname == "spectator") {
spectator spec = (spectator)self;
pl = (player)findfloat(world, ::entnum, spec.spec_ent);
if (spec.spec_mode != SPECMODE_FIRSTPERSON)
return;
} else {
pl = (player)self;
if (pl.health <= 0) {
return;
}
}
if (!pl)
return;
if (cvar("r_drawviewmodel") == 0 || autocvar_cl_thirdperson == TRUE) {
return;
}
View_UpdateWeapon(m_eViewModel, m_eMuzzleflash);
View_UpdateWeapon(m_eViewModelL, m_eMuzzleflashL);
// print(sprintf("%s: %f %d\n", pl.classname, pl.weapontime, pl.activeweapon));
View_UpdateWeapon(pl, m_eViewModel, m_eMuzzleflash);
View_UpdateWeapon(pl, m_eViewModelL, m_eMuzzleflashL);
float fBaseTime2 = m_eViewModel.frame1time;
float fBaseTime = m_eViewModel.frame1time;
m_eViewModel.frame = pl.weaponframe;
m_eViewModelL.frame1time =
m_eViewModelL.frame2time =
m_eViewModel.frame2time =

View File

@ -48,7 +48,8 @@ enum
RFX_FASTFLICKER = 13,
RFX_CONSTANTGLOW = 14,
RFX_DISTORT = 15,
RFX_HOLOGRAM = 16
RFX_HOLOGRAM = 16,
RFX_GLOWSHELL = 19
};
#endif

View File

@ -16,6 +16,11 @@
class NSProjectile:NSSurfacePropEntity
{
/* sprite animation gubbins */
int m_iProjectileAnimEnd;
int m_iProjectileAnimStart;
float m_flProjectileFramerate;
void(void) NSProjectile;
virtual void(entity, entity) m_pImpact = 0;
@ -23,4 +28,5 @@ class NSProjectile:NSSurfacePropEntity
virtual void(void(entity, entity)) SetImpact;
virtual void(string) SetModel;
virtual void(void) ProjectileTouch;
virtual void(int, int, float) Animate;
};

View File

@ -36,6 +36,28 @@ NSProjectile::SetModel(string mdl)
SetSize([0,0,0], [0,0,0]);
}
void
NSProjectile::AnimateThink(void)
{
frame++;
if (frame > (float)m_iProjectileAnimEnd)
frame = (float)m_iProjectileAnimStart;
nextthink = time + m_flProjectileFramerate;
}
void
NSProjectile::Animate(int startframe, int endframe, float framerate)
{
m_iProjectileAnimEnd = startframe;
m_iProjectileAnimStart = endframe;
m_flProjectileFramerate = framerate;
frame = startframe;
think = AnimateThink;
nextthink = time + m_flProjectileFramerate;
}
void
NSProjectile::NSProjectile(void)
{

View File

@ -92,64 +92,6 @@ cz_cbSprayChanged(void)
localcmd(sprintf("setinfoblob spray %s\n", mdl));
}
vector hsv2rgb(float h, float s, float v)
{
float i,f,p,q,t;
vector col = [0,0,0];
h = max(0.0, min(360.0, h));
s = max(0.0, min(100.0, s));
v = max(0.0, min(100.0, v));
s /= 100;
v /= 100;
if (s == 0) {
col[0] = col[1] = col[2] = rint(v*255);
return col;
}
h /= 60;
i = floor(h);
f = h - i;
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i) {
case 0:
col[0] = rint(255*v);
col[1] = rint(255*t);
col[2] = rint(255*p);
break;
case 1:
col[0] = rint(255*q);
col[1] = rint(255*v);
col[2] = rint(255*p);
break;
case 2:
col[0] = rint(255*p);
col[1] = rint(255*v);
col[2] = rint(255*t);
break;
case 3:
col[0] = rint(255*p);
col[1] = rint(255*q);
col[2] = rint(255*v);
break;
case 4:
col[0] = rint(255*t);
col[1] = rint(255*p);
col[2] = rint(255*v);
break;
default:
col[0] = rint(255*v);
col[1] = rint(255*p);
col[2] = rint(255*q);
}
return col;
}
void
cz_sldTopcolorChanged(float val)
{

View File

@ -48,7 +48,6 @@ void Client_ShakeOnce(vector, float, float, float, float);
void Game_ServerModelEvent(float, int, string);
void Event_ServerModelEvent(float, int, string);
void Game_Input(void);
int Rules_IsTeamPlay(void);
entity eActivator;

View File

@ -107,7 +107,7 @@ Weapons_SwitchBest(base_player pl, optional float skip = 0)
if (old == pl.activeweapon)
return;
Weapons_Draw();
Weapons_Draw((player)pl);
self = oldself;
pl.gflags |= GF_SEMI_TOGGLED;
}
@ -159,7 +159,7 @@ Weapons_AddItem(base_player pl, int w, int startammo)
/* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w;
Weapons_Draw();
Weapons_Draw((player)pl);
} else {
Weapons_PickupNotify(pl, w);
}
@ -168,21 +168,21 @@ Weapons_AddItem(base_player pl, int w, int startammo)
/* call pickup to handle the ammo */
if (pl.g_items & g_weapons[w].id) {
/* we have the item already, se let's see if we hit maxammo */
value = g_weapons[w].pickup(FALSE, startammo);
value = g_weapons[w].pickup((player)pl, FALSE, startammo);
/* FALSE means maxammo is hit */
if (!value)
return value;
} else {
/* new to our arsenal */
if (g_weapons[w].pickup(TRUE, startammo) == TRUE) {
if (g_weapons[w].pickup((player)pl, TRUE, startammo) == TRUE) {
pl.g_items |= g_weapons[w].id;
value = TRUE;
/* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w;
Weapons_Draw();
Weapons_Draw((player)pl);
} else {
Weapons_PickupNotify(pl, w);
}

View File

@ -23,3 +23,5 @@ vector Math_FixDeltaVector(vector);
vector Math_Reflect(vector v1, vector v2);
vector Math_RandomVector(float flyup);
vector Math_RotateAroundPivot(vector pos, vector pivot, float degr);
vector hsv2rgb(float h, float s, float v);

View File

@ -86,3 +86,61 @@ Math_RotateAroundPivot(vector pos, vector pivot, float degr)
new[1] = pivot[1] + (pos[0] - pivot[0]) * sin(degr) + (pos[1] - pivot[1]) * cos(degr);
return new;
}
vector hsv2rgb(float h, float s, float v)
{
float i,f,p,q,t;
vector col = [0,0,0];
h = max(0.0, min(360.0, h));
s = max(0.0, min(100.0, s));
v = max(0.0, min(100.0, v));
s /= 100;
v /= 100;
if (s == 0) {
col[0] = col[1] = col[2] = rint(v*255);
return col;
}
h /= 60;
i = floor(h);
f = h - i;
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i) {
case 0:
col[0] = rint(255*v);
col[1] = rint(255*t);
col[2] = rint(255*p);
break;
case 1:
col[0] = rint(255*q);
col[1] = rint(255*v);
col[2] = rint(255*p);
break;
case 2:
col[0] = rint(255*p);
col[1] = rint(255*v);
col[2] = rint(255*t);
break;
case 3:
col[0] = rint(255*p);
col[1] = rint(255*q);
col[2] = rint(255*v);
break;
case 4:
col[0] = rint(255*t);
col[1] = rint(255*p);
col[2] = rint(255*v);
break;
default:
col[0] = rint(255*v);
col[1] = rint(255*p);
col[2] = rint(255*q);
}
return col;
}

View File

@ -17,6 +17,7 @@
class
base_player:base_client
{
PREDICTED_INT(weaponframe);
PREDICTED_FLOAT(health);
PREDICTED_FLOAT(armor);

View File

@ -18,7 +18,8 @@
void
base_player::ClientRemove(void)
{
remove(p_model);
if (p_model)
remove(p_model);
}
/*
@ -109,8 +110,9 @@ base_player::ReceiveEntity(float new, float fl)
gravity = 1.0f;
}
if (fl & PLAYER_MODELINDEX)
if (fl & PLAYER_MODELINDEX) {
modelindex = readshort();
}
if (fl & PLAYER_ORIGIN) {
origin[0] = readcoord();
@ -150,8 +152,10 @@ base_player::ReceiveEntity(float new, float fl)
else
setsize(self, PHY_HULL_MIN, PHY_HULL_MAX);
}
if (fl & PLAYER_WEAPON)
if (fl & PLAYER_WEAPON) {
activeweapon = readbyte();
weaponframe = (int)readbyte();
}
if (fl & PLAYER_ITEMS)
g_items = (__variant)readfloat();
if (fl & PLAYER_HEALTH)
@ -207,6 +211,7 @@ base_player::PredictPreFrame(void)
/* TO OPTIMISE */
SAVE_STATE(teleport_time);
SAVE_STATE(viewzoom);
SAVE_STATE(weaponframe);
SAVE_STATE(weapontime);
SAVE_STATE(w_attack_next);
SAVE_STATE(w_idle_next);
@ -247,6 +252,7 @@ base_player::PredictPostFrame(void)
/* TO OPTIMISE */
ROLL_BACK(teleport_time);
ROLL_BACK(viewzoom);
ROLL_BACK(weaponframe);
ROLL_BACK(weapontime);
ROLL_BACK(w_attack_next);
ROLL_BACK(w_idle_next);
@ -275,6 +281,7 @@ base_player::Save(float handle)
SaveFloat(handle, "w_attack_next", w_attack_next);
SaveFloat(handle, "w_idle_next", w_idle_next);
SaveFloat(handle, "teleport_time", teleport_time);
SaveInt(handle, "weaponframe", weaponframe);
SaveFloat(handle, "weapontime", weapontime);
SaveInt(handle, "g_items", g_items);
SaveFloat(handle, "activeweapon", activeweapon);
@ -336,6 +343,9 @@ base_player::Restore(string strKey, string strValue)
case "teleport_time":
teleport_time = ReadFloat(strValue);
break;
case "weaponframe":
weaponframe = ReadInt(strValue);
break;
case "weapontime":
weapontime = ReadFloat(strValue);
break;
@ -516,6 +526,9 @@ base_player::EvaluateEntity(void)
if (ATTR_CHANGED(pmove_flags))
SetSendFlags(PLAYER_FLAGS);
if (ATTR_CHANGED(weaponframe))
SetSendFlags(PLAYER_WEAPON);
if (ATTR_CHANGED(activeweapon))
SetSendFlags(PLAYER_WEAPON);
@ -552,6 +565,7 @@ base_player::EvaluateEntity(void)
/* TO OPTIMISE */
SAVE_STATE(teleport_time);
SAVE_STATE(viewzoom);
SAVE_STATE(weaponframe);
SAVE_STATE(weapontime);
SAVE_STATE(w_attack_next);
SAVE_STATE(w_idle_next);
@ -572,8 +586,9 @@ float
base_player::SendEntity(entity ePEnt, float fChanged)
{
/* really trying to get our moneys worth with 23 bits of mantissa */
if (fChanged & PLAYER_MODELINDEX)
if (fChanged & PLAYER_MODELINDEX) {
WriteShort(MSG_ENTITY, modelindex);
}
/* if origin[0] changes, it's very likely [1] changes too, since
* we rarely ever walk in a straight line on the world grid */
@ -611,8 +626,10 @@ base_player::SendEntity(entity ePEnt, float fChanged)
WriteFloat(MSG_ENTITY, gflags);
WriteFloat(MSG_ENTITY, pmove_flags);
}
if (fChanged & PLAYER_WEAPON)
if (fChanged & PLAYER_WEAPON) {
WriteByte(MSG_ENTITY, activeweapon);
WriteByte(MSG_ENTITY, weaponframe);
}
/* g_items is a proper integer, so we can't let WriteFloat truncate it (hence __variant) */
if (fChanged & PLAYER_ITEMS)

View File

@ -269,7 +269,7 @@ base_player::Physics_InputPostMove(void)
Vehicle_Input(this);
/* weapon/item logic of what the player controls */
Game_Input();
Game_Input((player)this);
}
/* the main physics routine, the head */