muzzleflash struct, zoom var cleanup, entity renaming, network latency experimental

This commit is contained in:
Christopher Dawalt 2021-08-11 05:18:29 -04:00
parent bfafbec9ad
commit 34ffbd54dc
69 changed files with 1971 additions and 1631 deletions

View File

@ -45,8 +45,9 @@ var float FONT_ARIAL_STD; //stands for "standard" ya hooligans.
var float FONT_ARIAL_NUMSLASH; var float FONT_ARIAL_NUMSLASH;
var float FONT_ARIAL_SCOPEMAG; var float FONT_ARIAL_SCOPEMAG;
// Be sure to keep this up to date with the font FONT_ARIAL_STD as it's loaded in _base/client/entry.c, // Be sure to keep this up to date with the font FONT_ARIAL_STD as it's loaded in
// notice this is always one less than the actual expected corresponding font. // ui.qc, notice this is always one less than the actual expected corresponding font.
// TODO - a some things may be unused at this point, check.
const vector vButtonFontSize = [13, 13, 0]; const vector vButtonFontSize = [13, 13, 0];
const vector vFontSizeNumSlash = [15, 15, 0]; const vector vFontSizeNumSlash = [15, 15, 0];
const vector vFontArialScopeMag = [16, 16, 0]; const vector vFontArialScopeMag = [16, 16, 0];

View File

@ -1,13 +1,16 @@
// for ejected shells to use // for ejected shells to use
class CShellEject{ class CTSShellEject{
// what to use for info. Saved to a var since this must be known // what to use for info. Saved to a var since this must be known
// between being spawned and when the event is picked, not going to // between being spawned and when the event is picked, not going to
// try and guess how that works knowing FTE // try and guess how that works knowing FTE
int iShellEjectType; int iShellEjectType;
void(void) CShellEject; void(void) CTSShellEject;
static void(void) precache; static void(void) precache;
static CShellEject(int arg_iShellEjectType) generate; static CTSShellEject(int arg_iShellEjectType) generateForViewmodel;
static CTSShellEject(int arg_iShellEjectType, vector arg_vOrigin, vector arg_vDir) generate;
virtual void(void) touch; virtual void(void) touch;
}; };

View File

@ -1,10 +1,11 @@
void void
CShellEject::CShellEject(void){ CTSShellEject::CTSShellEject(void){
} }
void void
CShellEject::precache(void){ CTSShellEject::precache(void)
{
Sound_Precache("modelevent_shell.land"); Sound_Precache("modelevent_shell.land");
Sound_Precache("modelevent_shotgunshell.land"); Sound_Precache("modelevent_shotgunshell.land");
// no need, handled in soundscript preaches // no need, handled in soundscript preaches
@ -16,6 +17,16 @@ CShellEject::precache(void){
precache_sound("weapons/sshell3.wav"); precache_sound("weapons/sshell3.wav");
*/ */
// whoops, forgot looping through the struct and precaching that way would've worked,
// but keeping individual precaches if just for some comments.
// Also - could do it the getmodleindex way and record ID's, but don't see a benefit
// to that.
/*
for(i = 0; i < SHELLEJECT_ID::LAST_ID; i++){
ary_shellEjectData[i].iModelPrecacheID = (int)getmodelindex(ary_shellEjectData[i].sModelPath);
}
*/
// nearly identical..? // nearly identical..?
precache_model("models/56_shell.mdl"); precache_model("models/56_shell.mdl");
precache_model("models/556_shell.mdl"); precache_model("models/556_shell.mdl");
@ -34,9 +45,10 @@ CShellEject::precache(void){
// The practical constructor, manually call this after spawning. // The practical constructor, manually call this after spawning.
// NOTE: assumes pSeat->m_eViewModel is valid for involving in determining // NOTE: assumes pSeat->m_eViewModel is valid for involving in determining
// origin, angles, velocity // origin, angles, velocity
CShellEject CTSShellEject
CShellEject::generate(int arg_iShellEjectType){ CTSShellEject::generateForViewmodel(int arg_iShellEjectType)
CShellEject eShell = spawn(CShellEject); {
CTSShellEject eShell = spawn(CTSShellEject);
vector vOrigin; // tempvar vector vOrigin; // tempvar
@ -68,7 +80,8 @@ CShellEject::generate(int arg_iShellEjectType){
// viewmodel laser-start or flashlight sprite glow effect in the right place. // viewmodel laser-start or flashlight sprite glow effect in the right place.
// FreeHL way (forget all the rest if so) // FreeHL way (forget all the rest if so)
vOrigin = pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4); //vOrigin = pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4);
/* /*
// way #1 // way #1
@ -94,10 +107,47 @@ CShellEject::generate(int arg_iShellEjectType){
// or only be vOffset // or only be vOffset
vOrigin = vOffset; vOrigin = vOffset;
*/ */
// way #4:
vector gunpos;
vector gunpos_tempEnd;
vector dirGun;
vector angGun;
gunpos = gettaginfo(pSeat->m_eViewModel, pSeat->m_iVMBones + 0i);
gunpos_tempEnd = gettaginfo(pSeat->m_eViewModel, pSeat->m_iVMBones + 3i);
dirGun = normalize(gunpos_tempEnd - gunpos);
angGun = vectoangles(dirGun);
makevectors(angGun);
//TODO: No idea what consistent formula would put shell ejections across the right place
// of all weapons. Might just have to be a piece of weapondata for what relative forward, up,
// and right multiples to apply to relative vectors here. Or maybe only the multiple on v_forward
// is necessary, would have to check the attachment points of everything
// ALSO, TODO: Check for being akimbo and per weapon. oh dear... we need a paramter for what
// weapon, left or right to use then (LEFT always a default, even if non-akimbo is ok too),
// see weapons for that AKIMBOCHOICE thing
vOrigin = gunpos;
vOrigin += v_forward * -3.5;
vOrigin += v_up * -0.02;
vOrigin += v_right * 0.00;
setorigin(eShell, vOrigin); setorigin(eShell, vOrigin);
} }
void CShellEject::touch(void){ // TODO. For playermodels as seen in thirdperson (local one) or looking at other players
// that called for shell ejecting.
CTSShellEject
CTSShellEject::generate(int arg_iShellEjectType, vector arg_vOrigin, vector arg_vDir){
}
void
CTSShellEject::touch(void)
{
if(other == world){ if(other == world){
shellejectdata_t* mySED = ary_shellEjectData[iShellEjectType]; shellejectdata_t* mySED = ary_shellEjectData[iShellEjectType];
// self? this? Is there a difference in this context? // self? this? Is there a difference in this context?

View File

@ -187,6 +187,9 @@ ClientGame_EventParse(float fHeader)
case EVENT_TS::PLAYER_DEATH: case EVENT_TS::PLAYER_DEATH:
EV_PlayerDeath(); EV_PlayerDeath();
break; break;
case EVENT_TS::EQUIP_CALLBACK:
EV_EquipCallback();
break;
case EVENT_TS::SOUNDPITCHED: case EVENT_TS::SOUNDPITCHED:
SoundPitched_Receive(); SoundPitched_Receive();
break; break;
@ -195,7 +198,7 @@ ClientGame_EventParse(float fHeader)
break; break;
/* /*
// can this even happen anymore? // can this even happen anymore?
// If a drop-weapon call can be signaled by the server, not shared with th // If a drop-weapon call can be signaled by the server, not shared with the
// client and server reaching a drop call independently, then yes. // client and server reaching a drop call independently, then yes.
case EVENT_TS::DROP_WEAPON: case EVENT_TS::DROP_WEAPON:
EV_TS_playerDropWeapon(pl); EV_TS_playerDropWeapon(pl);

View File

@ -15,12 +15,27 @@
*/ */
// Nope, HUD/UI-related precaches in client/precache.qc instead
// ...mostly, keeping this one here?
void void
HUD_Init(void) HUD_Init(void)
{ {
// leftover HL precache that's used in scoreboard.qc it seems,
// haven't looked into what TS does for that yet.
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f); g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
precache_model("sprites/player/crouched.spr");
precache_model("sprites/player/divestepb.spr");
precache_model("sprites/player/divestepc.spr");
precache_model("sprites/player/divestept.spr");
precache_model("sprites/player/health.spr");
precache_model("sprites/player/kevlar.spr");
precache_model("sprites/player/kungfu.spr");
precache_model("sprites/player/movement.spr");
precache_model("sprites/player/prone.spr");
precache_model("sprites/player/run.spr");
precache_model("sprites/player/stand.spr");
precache_model("sprites/weapons/item_installed.spr");
precache_model("sprites/weapons/item_not_installed.spr");
} }
@ -71,8 +86,8 @@ HUD_Draw(void)
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
//View_HandleZoom(); //View_HandleZoom();
//printfline("SCOPE LEVEL %.2f", pl.flZoomLevel); //printfline("SCOPE LEVEL %.2f", pl.flZoomCurrent);
if(pl.flZoomLevel < 0.5){ //is this < 40? yes. if(pl.flZoomCurrent < 0.5){ //is this < 40? yes.
HUD_DrawScope(); HUD_DrawScope();
}else{ }else{
// We'll leave details like extra details for the lasersight and the // We'll leave details like extra details for the lasersight and the

View File

@ -41,7 +41,7 @@ void HUD_DrawScope_Pic( vector vPos, vector vSize, string sSprite ) {
================= =================
HUD_DrawScope HUD_DrawScope
Tries to draw a scope whenever viewzoom < 1.0f Tries to draw a scope
================= =================
*/ */
void HUD_DrawScope( void ) { void HUD_DrawScope( void ) {
@ -167,7 +167,7 @@ void HUD_DrawScope( void ) {
int magAmount = (int)(1.0f / (pl.flZoomLevel )); int magAmount = (int)(1.0f / (pl.flZoomCurrent ));
//int xOffset = drawSpriteNumber(ary_LCD_numberSet, 24, 24, magAmount, 3, BITS_DIGITOPT_NONE, clrPaleBlue, 0.88f); //int xOffset = drawSpriteNumber(ary_LCD_numberSet, 24, 24, magAmount, 3, BITS_DIGITOPT_NONE, clrPaleBlue, 0.88f);
//[24 + xOffset + 1, 24 + 4] //[24 + xOffset + 1, 24 + 4]
Gfx_Text( [24, 27], sprintf("%ix", magAmount), vFontArialScopeMag, clrPaleBlue, 0.95f, DRAWFLAG_ADDITIVE, FONT_ARIAL_SCOPEMAG ); Gfx_Text( [24, 27], sprintf("%ix", magAmount), vFontArialScopeMag, clrPaleBlue, 0.95f, DRAWFLAG_ADDITIVE, FONT_ARIAL_SCOPEMAG );

View File

@ -173,20 +173,4 @@ ClientGame_RendererRestart(string rstr)
// Hook into precache.qc // Hook into precache.qc
ClientGame_Precache(); ClientGame_Precache();
Obituary_Precache();
// All forked effects!
FX_Blood_Init();
FX_BreakModel_Init();
FX_Explosion_Init();
FX_GibHuman_Init();
FX_Spark_Init();
FX_Impact_Init();
// NEW
FX_TS_Explosion_Grenade_Init();
FX_Impact_Melee_Init();
} }

View File

@ -1,5 +1,3 @@
//var int MUZZLE_CUSTOM;
void ClientGame_Precache(void); void ClientGame_Precache(void);

View File

@ -8,41 +8,32 @@ void ClientGame_Precache(void){
SharedGame_Precache(); SharedGame_Precache();
// Example of loading a muzzle flash sprite // things from ClientGame_RendererRestart from FreeHL mostly for referred-to effects
//MUZZLE_CUSTOM = (int)getmodelindex("sprites/muzzleCUSTOM.spr"); ////////////////////////////////////////////////////////////////////////////////////
Obituary_Precache();
// All forked effects!
FX_Blood_Init();
FX_BreakModel_Init();
FX_Explosion_Init();
FX_GibHuman_Init();
FX_Spark_Init();
FX_Impact_Init();
////////////////////////////////////////////////////////////////////////////////////
// NEW
CTSShellEject::precache();
FX_TS_Explosion_Grenade_Init();
FX_Impact_Melee_Init();
MuzzleFlash_precache();
CShellEject::precache();
//TAGGG - From FreeHL.
// Does TS use something else?
////////////////////////////////////////////////////////////
precache_model("sprites/muzzleflash1.spr");
precache_model("sprites/muzzleflash2.spr");
precache_model("sprites/muzzleflash3.spr");
////////////////////////////////////////////////////////////
precache_sound("weapons/draw.wav"); precache_sound("weapons/draw.wav");
precache_model("sprites/mapsprites/ts_gpc1.spr"); precache_model("sprites/mapsprites/ts_gpc1.spr");
precache_model("sprites/mapsprites/ts_gpc2.spr"); precache_model("sprites/mapsprites/ts_gpc2.spr");
precache_model("sprites/player/crouched.spr");
precache_model("sprites/player/divestepb.spr");
precache_model("sprites/player/divestepc.spr");
precache_model("sprites/player/divestept.spr");
precache_model("sprites/player/health.spr");
precache_model("sprites/player/kevlar.spr");
precache_model("sprites/player/kungfu.spr");
precache_model("sprites/player/movement.spr");
precache_model("sprites/player/prone.spr");
precache_model("sprites/player/run.spr");
precache_model("sprites/player/stand.spr");
precache_model("sprites/weapons/item_installed.spr");
precache_model("sprites/weapons/item_not_installed.spr");
precache_model("sprites/wires/bwire.spr"); precache_model("sprites/wires/bwire.spr");
precache_model("sprites/wires/bwirecutted.spr"); precache_model("sprites/wires/bwirecutted.spr");

View File

@ -31,7 +31,9 @@ defs.h
../shared/weapons.h ../shared/weapons.h
../shared/player.h ../shared/player.h
../shared/powerup.h ../shared/powerup.h
entity/shelleject.h ../shared/sound_pitched.h
entity/ts_shelleject.h
clientinfo.h clientinfo.h
seatlocal.h seatlocal.h
@ -58,7 +60,7 @@ hud.h
../shared/player.qc ../shared/player.qc
../shared/inventory_logic.qc ../shared/inventory_logic.qc
entity/shelleject.qc entity/ts_shelleject.qc
// old location of UI draw stuff // old location of UI draw stuff
@ -93,13 +95,10 @@ scoreboard.qc
../../../base/src/client/modelevent.qc ../../../base/src/client/modelevent.qc
../shared/util.qc
../shared/precache.qc
util.qc util.qc
precache.qc precache.qc
//../_base/client/voice.c
//../_base/client/sound.c
//../_base/client/music.c
//../_base/client/prints.c
//../_base/client/util.c
../../../src/client/include.src ../../../src/client/include.src

View File

@ -118,11 +118,13 @@ UI_MOTD_Draw(void)
{ {
#ifdef MOTD_NEW_VGUI #ifdef MOTD_NEW_VGUI
if(!(UI_MOTD_win.m_iFlags & 1) && !g_UI_MOTD_everClosed){ if(!(UI_MOTD_win.m_iFlags & 1) /*&& !g_UI_MOTD_everClosed*/){
// this means the window was hidden by closing with the X button. // this means the window was hidden by closing with the X button.
// The OK button sets that flag so that this can't be reached that way. // The OK button sets that flag so that this can't be reached that way.
// The point is, closing the MoTD the first time by any means should lead // The point is, closing the MoTD the first time by any means should lead
// to the buy menu // to the buy menu
// ACTUALLY, leaving that up to btnOK to determine. Still want to solidly set
// the current screen to NONE regardless of closing the MoTD for the first time.
UI_MOTD_btnOK_Clicked(); UI_MOTD_btnOK_Clicked();
} }

View File

@ -97,6 +97,9 @@ TS_SetViewModelFromStats(void)
SAVE_STATE(pl.w_idle_next); SAVE_STATE(pl.w_idle_next);
SAVE_STATE(pl.viewzoom); SAVE_STATE(pl.viewzoom);
SAVE_STATE(pl.weapontime); SAVE_STATE(pl.weapontime);
//TAGGG - NEW VAR
SAVE_STATE(pl.w_attack_akimbo_next);
SAVE_STATE(pl.flZoomTarget);
skel_delete( mflash.skeletonindex ); skel_delete( mflash.skeletonindex );
mflash.skeletonindex = skel_create( vm.modelindex ); mflash.skeletonindex = skel_create( vm.modelindex );
@ -206,6 +209,7 @@ View_UpdateWeapon(entity vm, entity mflash)
SAVE_STATE(pl.weapontime); SAVE_STATE(pl.weapontime);
//TAGGG - NEW VAR. //TAGGG - NEW VAR.
SAVE_STATE(pl.w_attack_akimbo_next); SAVE_STATE(pl.w_attack_akimbo_next);
SAVE_STATE(pl.flZoomTarget);
//TAGGG - also new line. It is a good idea to reset the event //TAGGG - also new line. It is a good idea to reset the event
// on changing models, right? // on changing models, right?
@ -258,17 +262,34 @@ void View_HandleZoom(void){
return; return;
} }
//TAGGG - any references to STAT_VIEWZOOM are now garbage. // test
// Rely on pl.flTargetZoom instead, it's sent to the client every frame /*
// and should be handled serverside anyway. pl.flZoomCurrent = pl.flZoomTarget;
// flCurrentZoom is actually the "target" zoom we want to reach. pl.viewzoom = pl.flZoomTarget;
// flOldZoom is the zoom we started at, at the time of the change. printfline("flZoomTarget: %.2f", pl.flZoomTarget);
// flZoomLerp is how far along we are from oldZoom to currentZoom. return;
// flZoomLevel is the actual zoom we are at this very moment. */
if (pl.flCurrentZoom != pl.flTargetZoom ) { //printfline("WHATS GOING ON %.2f %.2f %.2f %.2f %.2f", pl.flZoomEnd, pl.flZoomTarget, pl.flZoomStart, pl.flZoomLerp, pl.flZoomCurrent);
pl.flOldZoom = pl.flCurrentZoom;
pl.flCurrentZoom = pl.flTargetZoom ; //TAGGG - any references to STAT_VIEWZOOM are now garbage.
// Rely on pl.flZoomTarget instead, it's sent to the client every frame
// and should be handled serverside anyway.
// flZoomEnd is actually the "target" zoom we want to reach.
// flZoomStart is the zoom we started at, at the time of the change.
// flZoomLerp is how far along we are from oldZoom to currentZoom.
// flZoomCurrent is the actual zoom we are at this very moment.
if (pl.flZoomEnd != pl.flZoomTarget ) {
// is setting flZoomStart to flZoomEnd or flZoomCurrent a better idea?
// at flZoomEnd means, on changing before the current lerp has finished, it jumps to beginning
// at the end point of the lerp in progress. But starting at flZoomCurrent might be smoother?
// if it isn't glitchy that could be nice. Trying that out.
pl.flZoomStart = pl.flZoomCurrent;
//pl.flZoomStart = pl.flZoomEnd;
pl.flZoomEnd = pl.flZoomTarget;
pl.flZoomLerp = 0.0f; pl.flZoomLerp = 0.0f;
} }
@ -277,24 +298,24 @@ void View_HandleZoom(void){
// 0.8 can be safe. // 0.8 can be safe.
// The Wastes default was 4. // The Wastes default was 4.
pl.flZoomLerp += clframetime * 8; pl.flZoomLerp += clframetime * 5.7;
if(pl.flZoomLerp >= 1.0){ if(pl.flZoomLerp >= 1.0){
//enforce the cap. //enforce the cap.
pl.flZoomLerp = 1.0; pl.flZoomLerp = 1.0;
} }
//pl.flZoomLevel = getstatf(STAT_VIEWZOOM); //pl.flZoomCurrent = getstatf(STAT_VIEWZOOM);
pl.flZoomLevel = Math_Lerp(pl.flOldZoom, pl.flCurrentZoom, pl.flZoomLerp); pl.flZoomCurrent = Math_Lerp(pl.flZoomStart, pl.flZoomEnd, pl.flZoomLerp);
} }
// Set this, since Nuclide will read it in and apply instantly. // Set this, since Nuclide will read it in and apply instantly.
// So same effect without having to edit Nuclide, this pipes it over for it // So same effect without having to edit Nuclide, this pipes it over for it
// to do the setproperty thing below to apply // to do the setproperty thing below to apply
pl.viewzoom = pl.flZoomLevel; pl.viewzoom = pl.flZoomCurrent;
////setproperty(VF_AFOV, DEFAULT_FOV * pl.flZoomLevel); ////setproperty(VF_AFOV, DEFAULT_FOV * pl.flZoomCurrent);
////setsensitivityscaler(pl.flZoomLevel); ////setsensitivityscaler(pl.flZoomCurrent);
// here's the way old FreeCS did it // here's the way old FreeCS did it
//setproperty(VF_AFOV, cvar("fov") * pl.viewzoom); //setproperty(VF_AFOV, cvar("fov") * pl.viewzoom);
@ -329,5 +350,3 @@ View_ShowMuzzleflash(int index)
} }

View File

@ -1,2 +0,0 @@
class TSAmmoPack;

View File

@ -1,9 +0,0 @@
class TSGrenadeProjectile{
void(void) TSGrenadeProjectile;
static void(void) precache;
static TSGrenadeProjectile(player arg_player, vector arg_vOrigin, vector arg_vThrowDir, vector arg_vPlayerForward, int arg_weaponTypeID) generate;
virtual void(void) touch;
};
void TSGrenadeProjectile_Explode(void);

View File

@ -0,0 +1,2 @@
class CTSAmmoPack;

View File

@ -1,237 +1,237 @@
class TSAmmoPack{ class CTSAmmoPack{
// After being recently accessed by a player but not deleted, // After being recently accessed by a player but not deleted,
// I enforce a cooldown time before any other player (including the same one) // I enforce a cooldown time before any other player (including the same one)
// can try to pick me up again. This stops spamming inventory scans every // can try to pick me up again. This stops spamming inventory scans every
// single frame if a player stands over a weapon they can't pick up. // single frame if a player stands over a weapon they can't pick up.
float accessibleCooldownTime; float accessibleCooldownTime;
// To avoid server clutter over time, a pickup will delete itself // To avoid server clutter over time, a pickup will delete itself
float expireTime; float expireTime;
//myInfo //myInfo
int ary_ammoTotal[AMMO_ID::LAST_ID]; int ary_ammoTotal[AMMO_ID::LAST_ID];
void(void) TSAmmoPack; void(void) CTSAmmoPack;
virtual void() Think; virtual void() Think;
virtual void() Touch; virtual void() Touch;
virtual void() PlayerUse; virtual void() PlayerUse;
static TSAmmoPack(player arg_player) generate; static CTSAmmoPack(player arg_player) generate;
virtual void(player arg_player) copyFrom; virtual void(player arg_player) copyFrom;
virtual BOOLEAN(player arg_player) copyTo; virtual BOOLEAN(player arg_player) copyTo;
//static Container_STR_ptr *Event::commandList; //static Container_STR_ptr *Event::commandList;
/* /*
// in-class constructor. // in-class constructor.
void(void) TSAmmoPack = { void(void) CTSAmmoPack = {
// can do stuff here too. // can do stuff here too.
}; };
*/ */
/* /*
// in-class method. // in-class method.
virtual int (int arg1, int arg2) doMath = { virtual int (int arg1, int arg2) doMath = {
return arg1 + arg2; return arg1 + arg2;
}; };
*/ */
}; };
static var int TSAmmoPack::testStaticVar = 0; static var int CTSAmmoPack::testStaticVar = 0;
void TSAmmoPack::TSAmmoPack(void){ void CTSAmmoPack::CTSAmmoPack(void){
accessibleCooldownTime = -1; accessibleCooldownTime = -1;
for(int i = 0; i < AMMO_ID::LAST_ID; i++){ for(int i = 0; i < AMMO_ID::LAST_ID; i++){
ary_ammoTotal[i] = 0; //safe default ary_ammoTotal[i] = 0; //safe default
} }
} }
// Static method called from elsewhere to create and initialize a // Static method called from elsewhere to create and initialize a
// weapon drop entity, given a player and what weapon to copy information from. // weapon drop entity, given a player and what weapon to copy information from.
TSAmmoPack TSAmmoPack::generate(player arg_player){ CTSAmmoPack CTSAmmoPack::generate(player arg_player){
TSAmmoPack eDrop = spawn(TSAmmoPack); CTSAmmoPack eDrop = spawn(CTSAmmoPack);
TSAmmoPack::testStaticVar++; CTSAmmoPack::testStaticVar++;
//printfline("AmmoPacks ever dropped: %i", testStaticVar); //printfline("AmmoPacks ever dropped: %i", testStaticVar);
//eDrop.setup(arg_player, arg_weaponID); //eDrop.setup(arg_player, arg_weaponID);
//TSAmmoPack eDrop = spawn(TSAmmoPack); //CTSAmmoPack eDrop = spawn(CTSAmmoPack);
setorigin( eDrop, arg_player.origin + arg_player.view_ofs ); setorigin( eDrop, arg_player.origin + arg_player.view_ofs );
setmodel( eDrop, "models/ammopack.mdl"); setmodel( eDrop, "models/ammopack.mdl");
eDrop.classname = "remove_me"; eDrop.classname = "remove_me";
eDrop.owner = arg_player; eDrop.owner = arg_player;
eDrop.movetype = MOVETYPE_TOSS; eDrop.movetype = MOVETYPE_TOSS;
eDrop.solid = SOLID_TRIGGER; //or CORPSE eDrop.solid = SOLID_TRIGGER; //or CORPSE
//eDrop.weapon = dynaRefPRE.weaponID; //eDrop.weapon = dynaRefPRE.weaponID;
eDrop.think = TSAmmoPack::Think; eDrop.think = CTSAmmoPack::Think;
eDrop.touch = TSAmmoPack::Touch; eDrop.touch = CTSAmmoPack::Touch;
eDrop.nextthink = time + 0.5f; eDrop.nextthink = time + 0.5f;
eDrop.copyFrom(arg_player); eDrop.copyFrom(arg_player);
//uhh.. ok, sure //uhh.. ok, sure
eDrop.health = 1; eDrop.health = 1;
setsize( eDrop, '-16 -16 0', '16 16 16' ); setsize( eDrop, '-16 -16 0', '16 16 16' );
//is this v_forward sometimes bad.. ? //is this v_forward sometimes bad.. ?
makevectors( arg_player.v_angle ); makevectors( arg_player.v_angle );
eDrop.velocity = arg_player.velocity + v_forward * 256; eDrop.velocity = arg_player.velocity + v_forward * 256;
//And lastly, assume I need to expire at some point. //And lastly, assume I need to expire at some point.
eDrop.expireTime = time + autocvar_weaponstay; //autocvar_weaponstay eDrop.expireTime = time + autocvar_weaponstay; //autocvar_weaponstay
eDrop.PlayerUse = TSAmmoPack::PlayerUse; eDrop.PlayerUse = CTSAmmoPack::PlayerUse;
return eDrop; return eDrop;
}//END OF generate }//END OF generate
// Pack all the player's ammo pools into me. // Pack all the player's ammo pools into me.
void TSAmmoPack::copyFrom(player arg_player){ void CTSAmmoPack::copyFrom(player arg_player){
for(int i = 0; i < AMMO_ID::LAST_ID; i++){ for(int i = 0; i < AMMO_ID::LAST_ID; i++){
this.ary_ammoTotal[i] = arg_player.ary_ammoTotal[i]; //take it all. this.ary_ammoTotal[i] = arg_player.ary_ammoTotal[i]; //take it all.
arg_player.ary_ammoTotal[i] = 0; arg_player.ary_ammoTotal[i] = 0;
} }
}//END OF copyFrom }//END OF copyFrom
// Give this player my ammo pools, whatever will fit. // Give this player my ammo pools, whatever will fit.
// Returns whether any ammo transaction happened (pretty likely) // Returns whether any ammo transaction happened (pretty likely)
BOOLEAN TSAmmoPack::copyTo(player arg_player){ BOOLEAN CTSAmmoPack::copyTo(player arg_player){
ammodata_t ammoRef; ammodata_t ammoRef;
BOOLEAN anyAmmoTaken = FALSE; BOOLEAN anyAmmoTaken = FALSE;
for(int i = 0; i < AMMO_ID::LAST_ID; i++){ for(int i = 0; i < AMMO_ID::LAST_ID; i++){
ammoRef = *ary_ammoData[i]; ammoRef = *ary_ammoData[i];
//How much can I give to the player? //How much can I give to the player?
//this.ary_ammoTotal[i] = arg_player.ary_ammoTotal[i]; //take it all. //this.ary_ammoTotal[i] = arg_player.ary_ammoTotal[i]; //take it all.
//arg_player.ary_ammoTotal[i] = 0; //arg_player.ary_ammoTotal[i] = 0;
int amountToTake; int amountToTake;
int existingCount = arg_player.ary_ammoTotal[i]; int existingCount = arg_player.ary_ammoTotal[i];
int pickupCount = this.ary_ammoTotal[i]; int pickupCount = this.ary_ammoTotal[i];
if(existingCount + pickupCount <= ammoRef.iMax){ if(existingCount + pickupCount <= ammoRef.iMax){
//absorb it all. //absorb it all.
amountToTake = pickupCount; amountToTake = pickupCount;
}else{ }else{
//too much in the pickup? this is ok, take as much as we can. //too much in the pickup? this is ok, take as much as we can.
amountToTake = ammoRef.iMax - existingCount; amountToTake = ammoRef.iMax - existingCount;
} }
if(amountToTake > 0){ if(amountToTake > 0){
anyAmmoTaken = TRUE; anyAmmoTaken = TRUE;
}else{ }else{
} }
arg_player.ary_ammoTotal[i] += amountToTake; arg_player.ary_ammoTotal[i] += amountToTake;
//arg_pickupRef.myInfo.iCount -= amountToTake; //arg_pickupRef.myInfo.iCount -= amountToTake;
this.ary_ammoTotal[i]-= amountToTake; this.ary_ammoTotal[i]-= amountToTake;
}//END OF for loop through ammo types }//END OF for loop through ammo types
if(anyAmmoTaken){ if(anyAmmoTaken){
sound(arg_player, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON ); sound(arg_player, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON );
}else{ }else{
//sound( arg_player, CHAN_ITEM, "common/wpn_select.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON ); //sound( arg_player, CHAN_ITEM, "common/wpn_select.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON );
} }
return anyAmmoTaken; return anyAmmoTaken;
}//END OF copyTo }//END OF copyTo
void TSAmmoPack::Touch( void ) { void CTSAmmoPack::Touch( void ) {
if ( other.classname != "player" ) { if ( other.classname != "player" ) {
// assume it's the world.. play this sound? // assume it's the world.. play this sound?
//printfline("the thing I touched is %s", other.classname); //printfline("the thing I touched is %s", other.classname);
// TODO - any others we need to keep track of for making the drop? // TODO - any others we need to keep track of for making the drop?
if(other.classname == "worldspawn" || other.classname == "func_breakable"){ if(other.classname == "worldspawn" || other.classname == "func_breakable"){
sound( this, CHAN_ITEM, "items/weapondrop1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON ); sound( this, CHAN_ITEM, "items/weapondrop1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_PLAYER_COMMON );
} }
return; return;
} }
//entity eOld = self; //entity eOld = self;
//TSAmmoPack selfRef = (TSAmmoPack)self; //CTSAmmoPack selfRef = (CTSAmmoPack)self;
//self = other; //self = other;
player otherPlayerRef = (player)other; //safe assumption now. player otherPlayerRef = (player)other; //safe assumption now.
BOOLEAN shouldDelete; BOOLEAN shouldDelete;
if(time >= this.accessibleCooldownTime){ if(time >= this.accessibleCooldownTime){
shouldDelete = copyTo(otherPlayerRef); shouldDelete = copyTo(otherPlayerRef);
this.accessibleCooldownTime = time + 0.8; this.accessibleCooldownTime = time + 0.8;
}else{ }else{
shouldDelete = FALSE; shouldDelete = FALSE;
} }
//self = eOld; //self = eOld;
if(shouldDelete){ if(shouldDelete){
remove(this); remove(this);
} }
}//END OF touch method }//END OF touch method
void TSAmmoPack::PlayerUse( void ) { void CTSAmmoPack::PlayerUse( void ) {
} }
void TSAmmoPack::Think( void ) { void CTSAmmoPack::Think( void ) {
//TSAmmoPack selfRef = (TSAmmoPack)self; //CTSAmmoPack selfRef = (CTSAmmoPack)self;
// oh.. this makes the weapon collidable with the original dropper // oh.. this makes the weapon collidable with the original dropper
// again. // again.
if(time >= this.expireTime){ if(time >= this.expireTime){
//expire. //expire.
remove(this); remove(this);
}else{ }else{
this.owner = world; this.owner = world;
//set the next think to aim around this time then. //set the next think to aim around this time then.
this.nextthink = this.expireTime + 0.1; this.nextthink = this.expireTime + 0.1;
} }
} }

View File

@ -0,0 +1,9 @@
class TS_GrenadeProjectile{
void(void) TS_GrenadeProjectile;
static void(void) precache;
static TS_GrenadeProjectile(player arg_player, vector arg_vOrigin, vector arg_vThrowDir, vector arg_vPlayerForward, int arg_weaponTypeID) generate;
virtual void(void) touch;
};
void TS_GrenadeProjectile_Explode(void);

View File

@ -1,21 +1,21 @@
void void
TSGrenadeProjectile::TSGrenadeProjectile(void){ TS_GrenadeProjectile::TS_GrenadeProjectile(void){
} }
void void
TSGrenadeProjectile::precache(void) TS_GrenadeProjectile::precache(void)
{ {
Sound_Precache("weapon_m61grenade.bounce"); Sound_Precache("weapon_m61grenade.bounce");
// Explosion sound is already precached in fx_ts_explosion_grenade.qc // Explosion sound is already precached in fx_ts_explosion_grenade.qc
// And the projectile model uses the world model, so that is also already handled // And the projectile model uses the world model, so that is also already handled
} }
TSGrenadeProjectile TS_GrenadeProjectile
TSGrenadeProjectile::generate( TS_GrenadeProjectile::generate(
player arg_player, vector arg_vOrigin, vector arg_vThrowDir, player arg_player, vector arg_vOrigin, vector arg_vThrowDir,
vector arg_vPlayerForward, int arg_weaponTypeID vector arg_vPlayerForward, int arg_weaponTypeID
){ ){
TSGrenadeProjectile eNade = spawn(TSGrenadeProjectile); TS_GrenadeProjectile eNade = spawn(TS_GrenadeProjectile);
weapondata_throwable_t* basicP = ((weapondata_throwable_t*)ary_weaponData[arg_weaponTypeID]); weapondata_throwable_t* basicP = ((weapondata_throwable_t*)ary_weaponData[arg_weaponTypeID]);
@ -37,14 +37,14 @@ TSGrenadeProjectile::generate(
eNade.movetype = MOVETYPE_BOUNCE; eNade.movetype = MOVETYPE_BOUNCE;
eNade.gravity = 0.5f; eNade.gravity = 0.5f;
eNade.think = TSGrenadeProjectile_Explode; eNade.think = TS_GrenadeProjectile_Explode;
eNade.nextthink = time + 3.0f; eNade.nextthink = time + 3.0f;
return eNade; return eNade;
} }
void void
TSGrenadeProjectile::touch(void){ TS_GrenadeProjectile::touch(void){
if ( other.solid == SOLID_TRIGGER ) { if ( other.solid == SOLID_TRIGGER ) {
return; return;
} }
@ -62,7 +62,7 @@ TSGrenadeProjectile::touch(void){
void void
TSGrenadeProjectile_Explode(void){ TS_GrenadeProjectile_Explode(void){
//float randomChoice; //float randomChoice;
// Also - don't worry about the shakes, sound script file for the // Also - don't worry about the shakes, sound script file for the
@ -92,22 +92,6 @@ TSGrenadeProjectile_Explode(void){
//Damage_Apply( self, world, fFallDamage, 0, DMG_FALL); //Damage_Apply( self, world, fFallDamage, 0, DMG_FALL);
/*
randomChoice = random();
if(randomChoice < 0.2){
SoundPitched_Send(self, SNDP_EXPLODE);
}else if(randomChoice < 0.4){
SoundPitched_Send(self, SNDP_EXPLODE1);
}else if(randomChoice < 0.6){
SoundPitched_Send(self, SNDP_EXPLODE2);
}else if(randomChoice < 0.8){
SoundPitched_Send(self, SNDP_EXPLODE3);
}else{
SoundPitched_Send(self, SNDP_EXPLODE4);
}
*/
// delay this so damage indicators can figure out where I came from! // delay this so damage indicators can figure out where I came from!
// ...weird, I know. // ...weird, I know.
//remove( self ); //remove( self );

View File

@ -21,7 +21,7 @@ enum pwuptype_choice{
#ifdef SERVER #ifdef SERVER
class ts_powerup:CBaseEntity{ class CTSPowerUp:CBaseEntity{
//key values? //key values?
pwuptype_choice m_ePwuptype; pwuptype_choice m_ePwuptype;
@ -41,7 +41,7 @@ class ts_powerup:CBaseEntity{
vector mem_origin; vector mem_origin;
void(void) ts_powerup; void(void) CTSPowerUp;
static void(void) precache; static void(void) precache;
virtual void(void) CustomInit; virtual void(void) CustomInit;
//virtual void(void) restartAnim; //virtual void(void) restartAnim;
@ -56,7 +56,7 @@ class ts_powerup:CBaseEntity{
void void
ts_powerup::ts_powerup(void) CTSPowerUp::CTSPowerUp(void)
{ {
// And why don't we just receive these as name/value pairs like clientside does? // And why don't we just receive these as name/value pairs like clientside does?
@ -64,7 +64,7 @@ ts_powerup::ts_powerup(void)
// And is it a problem we never call CBaseEntity's constructor? // And is it a problem we never call CBaseEntity's constructor?
// If we did it would read every single field that way, in addition to us // If we did it would read every single field that way, in addition to us
// reading every single field here, just to get info that the CBaseEntity expects // reading every single field here, just to get info that the CBaseEntity expects
// (origin) and what ts_powerup expects. Not efficient! // (origin) and what CTSPowerUp expects. Not efficient!
int nfields = tokenize( __fullspawndata ); int nfields = tokenize( __fullspawndata );
@ -98,15 +98,9 @@ ts_powerup::ts_powerup(void)
}// constructor }// constructor
void
ts_powerup::precache(void)
{
precache_model(POWERUP_MODEL_PATH);
}
void void
ts_powerup::CustomInit(void) CTSPowerUp::CustomInit(void)
{ {
@ -131,8 +125,8 @@ ts_powerup::CustomInit(void)
//customphysics? //customphysics?
//eDrop.think = ts_powerup::Think; //eDrop.think = CTSPowerUp::Think;
//eDrop.touch = ts_powerup::Touch; //eDrop.touch = CTSPowerUp::Touch;
//this.nextthink = time + 0.5f; //this.nextthink = time + 0.5f;
//uhh.. ok, sure //uhh.. ok, sure
@ -192,8 +186,8 @@ ts_powerup::CustomInit(void)
this.SendEntity = send; this.SendEntity = send;
this.SendFlags = 1; this.SendFlags = 1;
//this.touch = ts_powerup::Touch; //this.touch = CTSPowerUp::Touch;
//this.think = ts_powerup::Think; //this.think = CTSPowerUp::Think;
this.nextthink = time + 0; this.nextthink = time + 0;
// ??? SERVERTEST // ??? SERVERTEST
@ -206,7 +200,7 @@ ts_powerup::CustomInit(void)
float ts_powerup::send(entity pvsent, float cflags) float CTSPowerUp::send(entity pvsent, float cflags)
{ {
WriteByte(MSG_ENTITY, ENT_POWERUP); WriteByte(MSG_ENTITY, ENT_POWERUP);
WriteCoord(MSG_ENTITY, this.origin[0]); WriteCoord(MSG_ENTITY, this.origin[0]);
@ -232,7 +226,7 @@ float ts_powerup::send(entity pvsent, float cflags)
void void
ts_powerup::Respawn(void) CTSPowerUp::Respawn(void)
{ {
CustomInit(); CustomInit();
@ -243,7 +237,7 @@ ts_powerup::Respawn(void)
void void
ts_powerup::think(void) CTSPowerUp::think(void)
{ {
//TAGGG - CRITICAL. DISCUSS. //TAGGG - CRITICAL. DISCUSS.
@ -274,7 +268,7 @@ ts_powerup::think(void)
void void
ts_powerup::touch(void) CTSPowerUp::touch(void)
{ {
@ -312,7 +306,7 @@ ts_powerup::touch(void)
void void
ts_powerup::determineDataID(void) CTSPowerUp::determineDataID(void)
{ {
int bitsToChoose[9]; int bitsToChoose[9];
@ -429,7 +423,7 @@ ts_powerup::determineDataID(void)
void void
ts_powerup::declareDisposable(void) CTSPowerUp::declareDisposable(void)
{ {
// Since we clearly weren't spawned by the map for this method to be called, // Since we clearly weren't spawned by the map for this method to be called,
@ -465,7 +459,7 @@ ts_powerup::declareDisposable(void)
#ifdef CLIENT #ifdef CLIENT
class ts_powerup:CBaseEntity{ class CTSPowerUp:CBaseEntity{
//key values? //key values?
pwuptype_choice m_ePwuptype; pwuptype_choice m_ePwuptype;
@ -476,7 +470,8 @@ class ts_powerup:CBaseEntity{
POWERUP_ID dataID; POWERUP_ID dataID;
BOOL alreadyPickedUp; BOOL alreadyPickedUp;
void(void) ts_powerup; void(void) CTSPowerUp;
static void(void) precache;
virtual void(void) Initialized; virtual void(void) Initialized;
virtual void(void) updateAnim; virtual void(void) updateAnim;
virtual void(string strField, string strKey) SpawnKey; virtual void(string strField, string strKey) SpawnKey;
@ -493,14 +488,14 @@ class ts_powerup:CBaseEntity{
void void
ts_powerup::ts_powerup(void) CTSPowerUp::CTSPowerUp(void)
{ {
} }
// Use me instead for startup stuff expected after reading spawnflags. // Use me instead for startup stuff expected after reading spawnflags.
void void
ts_powerup::Initialized(void) CTSPowerUp::Initialized(void)
{ {
//base method is empty, this is pointless //base method is empty, this is pointless
//CBaseEntity::Initialized(); //CBaseEntity::Initialized();
@ -529,7 +524,7 @@ ts_powerup::Initialized(void)
//this.think = updateAnim; //this.think = updateAnim;
//this.nextthink = time + (31-1)/50; //this.nextthink = time + (31-1)/50;
//ts_powerup selfRef = this; //CTSPowerUp selfRef = this;
}// Initialized }// Initialized
@ -537,13 +532,13 @@ ts_powerup::Initialized(void)
void void
ts_powerup::updateAnim(void) CTSPowerUp::updateAnim(void)
{ {
//this.lerpfrac = 1; //this.lerpfrac = 1;
//this.baseframe1time = 0; //this.baseframe1time = 0;
//this.frame1time = 0; //this.frame1time = 0;
//printfline("ts_powerup::updateAnim %0.2f", this.frame1time); //printfline("CTSPowerUp::updateAnim %0.2f", this.frame1time);
//this.frame1time += clframetime; //this.frame1time += clframetime;
//resets the anim frame. //resets the anim frame.
@ -570,7 +565,7 @@ void
Powerup_Parse(void) Powerup_Parse(void)
{ {
ts_powerup selfRef; CTSPowerUp selfRef;
/* convert us to an object of type decal */ /* convert us to an object of type decal */
@ -579,11 +574,11 @@ Powerup_Parse(void)
if(self.classname != "ts_powerup"){ if(self.classname != "ts_powerup"){
//is this really persistent? //is this really persistent?
//printfline("ts_powerup: Powerup_Parse. MY CLASSNAME IS INCORRECT: %s", self.classname); //printfline("ts_powerup: Powerup_Parse. MY CLASSNAME IS INCORRECT: %s", self.classname);
spawnfunc_ts_powerup(); spawnfunc_CTSPowerUp();
self.classname = "ts_powerup"; self.classname = "ts_powerup";
} }
selfRef = (ts_powerup)self; selfRef = (CTSPowerUp)self;
BOOL mem_alreadyPickedUp = selfRef.alreadyPickedUp; BOOL mem_alreadyPickedUp = selfRef.alreadyPickedUp;
@ -631,7 +626,7 @@ Powerup_Parse(void)
if(isRespawnCall || (!selfRef.alreadyPickedUp && (mem_alreadyPickedUp != selfRef.alreadyPickedUp))){ if(isRespawnCall || (!selfRef.alreadyPickedUp && (mem_alreadyPickedUp != selfRef.alreadyPickedUp))){
// forcively respawned, or appearing since being hidden? Force animation time to 0 (start at beginning) // forcively respawned, or appearing since being hidden? Force animation time to 0 (start at beginning)
selfRef.frame1time = 0; selfRef.frame1time = 0;
selfRef.think = ts_powerup::updateAnim; selfRef.think = CTSPowerUp::updateAnim;
selfRef.nextthink = time + (31-1)/20 - 0.005; selfRef.nextthink = time + (31-1)/20 - 0.005;
} }
@ -659,12 +654,12 @@ Powerup_Parse(void)
} }
//selfRef.customphysics = ts_powerup::Physics; //selfRef.customphysics = CTSPowerUp::Physics;
//selfRef.think = ts_powerup::Think; //selfRef.think = CTSPowerUp::Think;
//selfRef.nextthink = time + 0; //selfRef.nextthink = time + 0;
// unnecessary. // unnecessary.
//selfRef.predraw = ts_powerup::predraw; //selfRef.predraw = CTSPowerUp::predraw;
// Why do we have to do this in Powerup_Parse and not just once in "Initialized?" // Why do we have to do this in Powerup_Parse and not just once in "Initialized?"
selfRef.drawmask = MASK_ENGINE; selfRef.drawmask = MASK_ENGINE;
@ -675,9 +670,9 @@ Powerup_Parse(void)
float float
ts_powerup::predraw(void) CTSPowerUp::predraw(void)
{ {
ts_powerup selfRef = (ts_powerup)self; CTSPowerUp selfRef = (CTSPowerUp)self;
selfRef.frame1time += clframetime; selfRef.frame1time += clframetime;
@ -689,13 +684,13 @@ ts_powerup::predraw(void)
/* /*
void ts_powerup::Physics(void){ void CTSPowerUp::Physics(void){
this.frame1time += clframetime; this.frame1time += clframetime;
}// Physics }// Physics
void ts_powerup::Think(void){ void CTSPowerUp::Think(void){
this.frame1time += clframetime; this.frame1time += clframetime;
this.nextthink = time + 0; this.nextthink = time + 0;
@ -706,9 +701,9 @@ void ts_powerup::Think(void){
void void
ts_powerup::SpawnKey(string strField, string strKey) CTSPowerUp::SpawnKey(string strField, string strKey)
{ {
//printfline("SpawnKey:: ts_powerup: (%s: %s)", strField, strKey); //printfline("SpawnKey:: CTSPowerUp: (%s: %s)", strField, strKey);
switch (strField) { switch (strField) {
case "pwuptype": case "pwuptype":
@ -717,7 +712,8 @@ ts_powerup::SpawnKey(string strField, string strKey)
case "pwupduration": case "pwupduration":
m_iPwupduration = stoi(strKey); m_iPwupduration = stoi(strKey);
break; break;
case "message":m_strMessage = strKey; case "message":
m_strMessage = strKey;
break; break;
@ -754,3 +750,17 @@ ts_powerup::SpawnKey(string strField, string strKey)
#endif #endif
// SHARED?
void
CTSPowerUp::precache(void)
{
precache_model(POWERUP_MODEL_PATH);
}
// ent name on maps is ts_powerup
void
ts_powerup(void)
{
spawnfunc_CTSPowerUp();
}

View File

@ -1,36 +1,36 @@
// NOTE - this was not a type in the original TS, just seemed convenient to make. // NOTE - this was not a type in the original TS, just seemed convenient to make.
//class TSThrownProjectile; //class CTSThrownProjectile;
class TSThrownProjectile : TSWorldGun{ class CTSThrownProjectile : CTSWorldGun{
void(void) TSThrownProjectile; void(void) CTSThrownProjectile;
virtual void() Think; virtual void() Think;
virtual void() Touch; virtual void() Touch;
virtual void() PlayerUse; virtual void() PlayerUse;
static TSThrownProjectile (player arg_player, int arg_weaponID) generate; static CTSThrownProjectile (player arg_player, int arg_weaponID) generate;
static TSThrownProjectile (player arg_player, weapondynamic_t dynaRefPRE) generate2; static CTSThrownProjectile (player arg_player, weapondynamic_t dynaRefPRE) generate2;
virtual void (player arg_player, int arg_weaponID) copyFrom; virtual void (player arg_player, int arg_weaponID) copyFrom;
virtual void (player arg_player, weapondynamic_t tempRef) copyFrom2; virtual void (player arg_player, weapondynamic_t tempRef) copyFrom2;
virtual void (player arg_player, int arg_weaponID) copyTo; virtual void (player arg_player, int arg_weaponID) copyTo;
virtual void (BOOL becomeStuck, optional vector dir, optional entity stuckTo, BOOL touchedBreakableGlass)becomePickupable; virtual void (BOOL becomeStuck, optional vector dir, optional entity stuckTo, BOOL touchedBreakableGlass)becomePickupable;
// Like FTE's supplied 'owner' field, but for keeping track of who threw this knife after // Like FTE's supplied 'owner' field, but for keeping track of who threw this knife after
// the 'owner' field gets reset to still keep track of who should be blamed for damage inflicted. // the 'owner' field gets reset to still keep track of who should be blamed for damage inflicted.
entity m_owner; entity m_owner;
float startAngularVelocityDelay; float startAngularVelocityDelay;
//vector vPreviousVelocity; //vector vPreviousVelocity;
float forceBecomePickupableTime; float forceBecomePickupableTime;
vector queuedVelocity; vector queuedVelocity;
float queuedVelocityApplyTime; float queuedVelocityApplyTime;
float switchToNormalPickupBoundsTime; float switchToNormalPickupBoundsTime;
}; };

View File

@ -1,36 +1,36 @@
//class TSWorldGun; //class CTSWorldGun;
// not inheriting from CBaseEntity... this wasn't made with that in mind, // not inheriting from CBaseEntity... this wasn't made with that in mind,
// and it doesn't look like it needs anything from there. // and it doesn't look like it needs anything from there.
// If there were a version of this to be respawnable, it may make sense to make it a child of // If there were a version of this to be respawnable, it may make sense to make it a child of
// CBaseEntiy and then remove the GF_CANRESPAWN flag gflags added to all CBaseEntities by default // CBaseEntiy and then remove the GF_CANRESPAWN flag gflags added to all CBaseEntities by default
// (I think)... since changed to the IDENTITY_CANRESPAWN flag of ".identity" for CBaseEntity's // (I think)... since changed to the IDENTITY_CANRESPAWN flag of ".identity" for CBaseEntity's
class TSWorldGun{ class CTSWorldGun{
// After being recently accessed by a player but not deleted, // After being recently accessed by a player but not deleted,
// I enforce a cooldown time before any other player (including the same one) // I enforce a cooldown time before any other player (including the same one)
// can try to pick me up again. This stops spamming inventory scans every // can try to pick me up again. This stops spamming inventory scans every
// single frame if a player stands over a weapon they can't pick up. // single frame if a player stands over a weapon they can't pick up.
float accessibleCooldownTime; float accessibleCooldownTime;
// To avoid server clutter over time, a pickup will delete itself // To avoid server clutter over time, a pickup will delete itself
float expireTime; float expireTime;
weapondynamic_t myInfo; weapondynamic_t myInfo;
void(void) TSWorldGun; void(void) CTSWorldGun;
virtual void() Think; virtual void() Think;
virtual void() Touch; virtual void() Touch;
virtual void() PlayerUse; virtual void() PlayerUse;
static TSWorldGun (player arg_player, int arg_weaponID) generate; static CTSWorldGun (player arg_player, int arg_weaponID) generate;
static TSWorldGun (player arg_player, weapondynamic_t dynaRefPRE) generate2; static CTSWorldGun (player arg_player, weapondynamic_t dynaRefPRE) generate2;
virtual void (player arg_player, int arg_weaponID) copyFrom; virtual void (player arg_player, int arg_weaponID) copyFrom;
virtual void (player arg_player, weapondynamic_t tempRef) copyFrom2; virtual void (player arg_player, weapondynamic_t tempRef) copyFrom2;
virtual void (player arg_player, int arg_weaponID) copyTo; virtual void (player arg_player, int arg_weaponID) copyTo;
}; };

View File

@ -1,259 +1,259 @@
void TSWorldGun::TSWorldGun(void){ void CTSWorldGun::CTSWorldGun(void){
accessibleCooldownTime = -1; accessibleCooldownTime = -1;
myInfo = spawn(weapondynamic_t); myInfo = spawn(weapondynamic_t);
} }
TSWorldGun TSWorldGun::generate(player arg_player, int arg_weaponID){ CTSWorldGun CTSWorldGun::generate(player arg_player, int arg_weaponID){
weapondynamic_t dynaRefPRE = arg_player.ary_myWeapons[arg_weaponID]; weapondynamic_t dynaRefPRE = arg_player.ary_myWeapons[arg_weaponID];
return TSWorldGun::generate2(arg_player, dynaRefPRE); return CTSWorldGun::generate2(arg_player, dynaRefPRE);
} }
// Static method called from elsewhere to create and initialize a // Static method called from elsewhere to create and initialize a
// weapon drop entity, given a player and what weapon to copy information from. // weapon drop entity, given a player and what weapon to copy information from.
TSWorldGun TSWorldGun::generate2(player arg_player, weapondynamic_t dynaRefPRE){ CTSWorldGun CTSWorldGun::generate2(player arg_player, weapondynamic_t dynaRefPRE){
TSWorldGun eDrop = spawn(TSWorldGun); CTSWorldGun eDrop = spawn(CTSWorldGun);
//eDrop.setup(arg_player, arg_weaponID); //eDrop.setup(arg_player, arg_weaponID);
//weapondynamic_t dynaRefPRE = arg_player.ary_myWeapons[arg_weaponID]; //weapondynamic_t dynaRefPRE = arg_player.ary_myWeapons[arg_weaponID];
weapondata_basic_t* basicPointerPRE = (weapondata_basic_t*) ary_weaponData[dynaRefPRE.weaponID]; weapondata_basic_t* basicPointerPRE = (weapondata_basic_t*) ary_weaponData[dynaRefPRE.weaponID];
weapondata_basic_t basicRefPRE = *(basicPointerPRE); weapondata_basic_t basicRefPRE = *(basicPointerPRE);
eDrop.movetype = MOVETYPE_TOSS; eDrop.movetype = MOVETYPE_TOSS;
eDrop.solid = SOLID_TRIGGER; //or CORPSE eDrop.solid = SOLID_TRIGGER; //or CORPSE
//TSWorldGun eDrop = spawn(TSWorldGun); //CTSWorldGun eDrop = spawn(CTSWorldGun);
setorigin( eDrop, arg_player.origin + arg_player.view_ofs ); setorigin( eDrop, arg_player.origin + arg_player.view_ofs );
setmodel( eDrop, basicRefPRE.sWorldModelPath ); setmodel( eDrop, basicRefPRE.sWorldModelPath );
eDrop.angles = [0, randomInRange_f(0, 360), 0]; eDrop.angles = [0, randomInRange_f(0, 360), 0];
eDrop.avelocity = [0, randomInRange_f(100, 500), 0]; eDrop.avelocity = [0, randomInRange_f(100, 500), 0];
eDrop.classname = "remove_me"; eDrop.classname = "remove_me";
eDrop.owner = arg_player; eDrop.owner = arg_player;
//eDrop.weapon = dynaRefPRE.weaponID; //eDrop.weapon = dynaRefPRE.weaponID;
eDrop.think = TSWorldGun::Think; eDrop.think = CTSWorldGun::Think;
eDrop.touch = TSWorldGun::Touch; eDrop.touch = CTSWorldGun::Touch;
eDrop.nextthink = time + 0.5f; eDrop.nextthink = time + 0.5f;
eDrop.copyFrom2(arg_player, dynaRefPRE); eDrop.copyFrom2(arg_player, dynaRefPRE);
//uhh.. ok, sure //uhh.. ok, sure
eDrop.health = 1; eDrop.health = 1;
setsize( eDrop, '-16 -16 0', '16 16 16' ); setsize( eDrop, '-16 -16 0', '16 16 16' );
//is this v_forward sometimes bad.. ? //is this v_forward sometimes bad.. ?
makevectors( arg_player.v_angle ); makevectors( arg_player.v_angle );
eDrop.velocity = arg_player.velocity + v_forward * 320; //256? eDrop.velocity = arg_player.velocity + v_forward * 320; //256?
eDrop.gravity = 0.9; eDrop.gravity = 0.9;
//And lastly, assume I need to expire at some point. //And lastly, assume I need to expire at some point.
eDrop.expireTime = time + autocvar_weaponstay; //autocvar_weaponstay eDrop.expireTime = time + autocvar_weaponstay; //autocvar_weaponstay
eDrop.PlayerUse = TSWorldGun::PlayerUse; eDrop.PlayerUse = CTSWorldGun::PlayerUse;
return eDrop; return eDrop;
}//END OF generate }//END OF generate
void TSWorldGun::copyFrom(player arg_player, int arg_weaponID){ void CTSWorldGun::copyFrom(player arg_player, int arg_weaponID){
weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID]; weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID];
copyFrom2(arg_player, tempRef); copyFrom2(arg_player, tempRef);
} }
// From what index in the player's inventory should I copy stats from? // From what index in the player's inventory should I copy stats from?
// Called as we're being filled to be thrown from the player. // Called as we're being filled to be thrown from the player.
void TSWorldGun::copyFrom2(player arg_player, weapondynamic_t tempRef){ void CTSWorldGun::copyFrom2(player arg_player, weapondynamic_t tempRef){
//weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID]; //weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID];
COPYVARFROM(weaponID) COPYVARFROM(weaponID)
COPYVARFROM(weaponTypeID) COPYVARFROM(weaponTypeID)
//COPYVARFROM(iBitsUpgrade) //COPYVARFROM(iBitsUpgrade)
//actually want to exclude the AKIMBO and FULLLOAD bits. They were only for the shop really. //actually want to exclude the AKIMBO and FULLLOAD bits. They were only for the shop really.
myInfo.iBitsUpgrade = tempRef.iBitsUpgrade & ~(BITS_WEAPONOPT_AKIMBO | BITS_WEAPONOPT_FULLLOAD); myInfo.iBitsUpgrade = tempRef.iBitsUpgrade & ~(BITS_WEAPONOPT_AKIMBO | BITS_WEAPONOPT_FULLLOAD);
//COPYVARFROM(iCount) //COPYVARFROM(iCount)
weapondata_basic_t* weaponPointer = ary_weaponData[tempRef.weaponID]; weapondata_basic_t* weaponPointer = ary_weaponData[tempRef.weaponID];
weapondata_basic_t basicRef = *((weapondata_basic_t*) weaponPointer); weapondata_basic_t basicRef = *((weapondata_basic_t*) weaponPointer);
if(basicRef.typeID == WEAPONDATA_TYPEID_THROWABLE){ if(basicRef.typeID == WEAPONDATA_TYPEID_THROWABLE){
//we're a throwable? Send the count over. //we're a throwable? Send the count over.
COPYVARFROM(iCount) COPYVARFROM(iCount)
}else{ }else{
// Always a count of 1. Any dropped weapon from akimbo is really just "one" of the two pickups needed. // Always a count of 1. Any dropped weapon from akimbo is really just "one" of the two pickups needed.
// Even weapons that only come in akimbo, like goldencolts, don't hurt by being called a count of "1". // Even weapons that only come in akimbo, like goldencolts, don't hurt by being called a count of "1".
// They keep the same shop stats, which is really the point here. // They keep the same shop stats, which is really the point here.
myInfo.iCount = 1; myInfo.iCount = 1;
} }
COPYVARFROM(iPrice) //who cares. COPYVARFROM(iPrice) //who cares.
//COPYVARFROM(iSlots) //COPYVARFROM(iSlots)
//re-calculate the slots now. //re-calculate the slots now.
myInfo.iSlots = myInfo.iCount * basicRef.iSlots; myInfo.iSlots = myInfo.iCount * basicRef.iSlots;
//Hold on... this isn't so simple. //Hold on... this isn't so simple.
if(basicRef.typeID == WEAPONDATA_TYPEID_GUN || basicRef.typeID == WEAPONDATA_TYPEID_IRONSIGHT){ if(basicRef.typeID == WEAPONDATA_TYPEID_GUN || basicRef.typeID == WEAPONDATA_TYPEID_IRONSIGHT){
if(basicRef.iBitsUpgradeAuto & BITS_WEAPONOPT_AKIMBO){ if(basicRef.iBitsUpgradeAuto & BITS_WEAPONOPT_AKIMBO){
//If the weapon we're spawned from is forced akimbo, the intuitive way works. //If the weapon we're spawned from is forced akimbo, the intuitive way works.
//iClipLeft & iClipAkimboLeft can be filled, this is a singular drop to represent akimbo. //iClipLeft & iClipAkimboLeft can be filled, this is a singular drop to represent akimbo.
COPYVARFROM(iClipLeft) COPYVARFROM(iClipLeft)
COPYVARFROM(iClipAkimboLeft) COPYVARFROM(iClipAkimboLeft)
}else if(basicRef.iBitsUpgrade & BITS_WEAPONOPT_AKIMBO && tempRef.iBitsUpgrade & BITS_WEAPONOPT_AKIMBO){ }else if(basicRef.iBitsUpgrade & BITS_WEAPONOPT_AKIMBO && tempRef.iBitsUpgrade & BITS_WEAPONOPT_AKIMBO){
//If the weapon supports akimbo and we have it, assume the thing dropped is the 2nd weapon. //If the weapon supports akimbo and we have it, assume the thing dropped is the 2nd weapon.
//That is, the one tied to "iClipAkimboLeft". //That is, the one tied to "iClipAkimboLeft".
if(arg_player.weaponEquippedAkimbo){ if(arg_player.weaponEquippedAkimbo){
myInfo.iClipLeft = tempRef.iClipAkimboLeft; myInfo.iClipLeft = tempRef.iClipAkimboLeft;
myInfo.iClipAkimboLeft = 0; myInfo.iClipAkimboLeft = 0;
}else{ }else{
//oh.. drop the singular varient's ammo count then. //oh.. drop the singular varient's ammo count then.
myInfo.iClipLeft = tempRef.iClipLeft; myInfo.iClipLeft = tempRef.iClipLeft;
myInfo.iClipAkimboLeft = 0; myInfo.iClipAkimboLeft = 0;
} }
}else{ }else{
//not akimbo or doesn't support it? Only this one. //not akimbo or doesn't support it? Only this one.
myInfo.iClipLeft = tempRef.iClipLeft; myInfo.iClipLeft = tempRef.iClipLeft;
myInfo.iClipAkimboLeft = 0; myInfo.iClipAkimboLeft = 0;
} }
}else{ }else{
//doesn't use these. //doesn't use these.
myInfo.iClipLeft = 0; myInfo.iClipLeft = 0;
myInfo.iClipAkimboLeft = 0; myInfo.iClipAkimboLeft = 0;
} }
COPYVARFROM(iBitsUpgrade_on) COPYVARFROM(iBitsUpgrade_on)
COPYVARFROM(iFireMode) //we can always copy both firemodes to any individual weapon, can't really hurt. COPYVARFROM(iFireMode) //we can always copy both firemodes to any individual weapon, can't really hurt.
COPYVARFROM(iFireModeAkimbo) COPYVARFROM(iFireModeAkimbo)
//COPYVARFROM(iIronSight) //COPYVARFROM(iIronSight)
COPYVARFROM(forceBodygroup1Submodel) COPYVARFROM(forceBodygroup1Submodel)
myInfo.iIronSight = 0; //default: not using it. myInfo.iIronSight = 0; //default: not using it.
}//END OF copyFrom }//END OF copyFrom
// From what index in the player's inventory should I copy stats from? // From what index in the player's inventory should I copy stats from?
// Called as we're being picked up by a player to fill one of their weapon slots. // Called as we're being picked up by a player to fill one of their weapon slots.
void TSWorldGun::copyTo(player arg_player, int arg_weaponID){ void CTSWorldGun::copyTo(player arg_player, int arg_weaponID){
weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID]; weapondynamic_t tempRef = arg_player.ary_myWeapons[arg_weaponID];
COPYVARTO(weaponID) COPYVARTO(weaponID)
COPYVARTO(weaponTypeID) COPYVARTO(weaponTypeID)
//COPYVARTO(iBitsUpgrade) //COPYVARTO(iBitsUpgrade)
//COPYVARTO(iCount) //COPYVARTO(iCount)
COPYVARTO(iPrice) //no one cares. COPYVARTO(iPrice) //no one cares.
//COPYVARTO(iSlots) //re-calculated. //COPYVARTO(iSlots) //re-calculated.
//COPYVARTO(iClipLeft) //COPYVARTO(iClipLeft)
//COPYVARTO(iClipAkimboLeft) //COPYVARTO(iClipAkimboLeft)
//COPYVARTO(iBitsUpgrade_on) //COPYVARTO(iBitsUpgrade_on)
//COPYVARTO(iFireMode) //COPYVARTO(iFireMode)
//COPYVARTO(iFireModeAkimbo) //COPYVARTO(iFireModeAkimbo)
//COPYVARTO(iIronSight) //COPYVARTO(iIronSight)
COPYVARTO(forceBodygroup1Submodel) COPYVARTO(forceBodygroup1Submodel)
tempRef.iIronSight = 0; //default: not using it. tempRef.iIronSight = 0; //default: not using it.
}//END OF copyTo }//END OF copyTo
void TSWorldGun::Touch( void ) { void CTSWorldGun::Touch( void ) {
if ( other.classname != "player" ) { if ( other.classname != "player" ) {
// assume it's the world.. play this sound? // assume it's the world.. play this sound?
//printfline("the thing I touched is %s", other.classname); //printfline("the thing I touched is %s", other.classname);
// TODO - any others we need to keep track of for making the drop? // TODO - any others we need to keep track of for making the drop?
if(other.classname == "worldspawn" || other.classname == "func_breakable"){ if(other.classname == "worldspawn" || other.classname == "func_breakable"){
sound( this, CHAN_ITEM, "items/weapondrop1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_FOLLOW ); sound( this, CHAN_ITEM, "items/weapondrop1.wav", 1, ATTN_NORM, 100, SOUNDFLAG_FOLLOW );
} }
return; return;
} }
}//END OF touch method }//END OF touch method
void TSWorldGun::PlayerUse( void ) { void CTSWorldGun::PlayerUse( void ) {
//laziness. //laziness.
//entity other = eActivator; //entity other = eActivator;
//...no, hides a global, not wise. //...no, hides a global, not wise.
other = eActivator; //this however should be fine? other = eActivator; //this however should be fine?
// !!! IMPORTANT !!! // !!! IMPORTANT !!!
// Want to be able to pick me up rapidly? You have to remove this check too, // Want to be able to pick me up rapidly? You have to remove this check too,
// or setting the owner to "player" on generation. // or setting the owner to "player" on generation.
// This means the player that spawend me can't pick me up for a little while. // This means the player that spawend me can't pick me up for a little while.
// This is completely independent of accessibleCooldownTime, which prevents // This is completely independent of accessibleCooldownTime, which prevents
// all players from picking me up too soon instead. // all players from picking me up too soon instead.
if ( other.classname != "player" ) { if ( other.classname != "player" ) {
return; return;
} else if ( other == this.owner ) { } else if ( other == this.owner ) {
return; return;
} }
//entity eOld = self; //entity eOld = self;
//TSWorldGun selfRef = (TSWorldGun)self; //CTSWorldGun selfRef = (CTSWorldGun)self;
//self = other; //self = other;
player otherPlayerRef = (player)other; //safe assumption now. player otherPlayerRef = (player)other; //safe assumption now.
BOOLEAN shouldDelete; BOOLEAN shouldDelete;
if(time >= this.accessibleCooldownTime){ if(time >= this.accessibleCooldownTime){
shouldDelete = otherPlayerRef.attemptAddWeaponFromPickup(this); shouldDelete = otherPlayerRef.attemptAddWeaponFromPickup(this);
this.accessibleCooldownTime = time + 0.8; this.accessibleCooldownTime = time + 0.8;
}else{ }else{
shouldDelete = FALSE; shouldDelete = FALSE;
} }
//self = eOld; //self = eOld;
if(shouldDelete){ if(shouldDelete){
remove(this); remove(this);
} }
} }
void TSWorldGun::Think( void ) { void CTSWorldGun::Think( void ) {
//TSWorldGun selfRef = (TSWorldGun)self; //CTSWorldGun selfRef = (CTSWorldGun)self;
// oh.. this makes the weapon collidable with the original dropper // oh.. this makes the weapon collidable with the original dropper
// again. // again.
if(time >= this.expireTime){ if(time >= this.expireTime){
//expire. //expire.
remove(this); remove(this);
}else{ }else{
this.owner = world; this.owner = world;
//set the next think to aim around this time then. //set the next think to aim around this time then.
this.nextthink = this.expireTime + 0.1; this.nextthink = this.expireTime + 0.1;
} }
} }

View File

@ -3,5 +3,5 @@
// Likely never used by the map as it's not mentioned in ts_fgd.ffd, // Likely never used by the map as it's not mentioned in ts_fgd.ffd,
// and our own logic for weapons does not use an entity anyway. // and our own logic for weapons does not use an entity anyway.
// This was likely used to represent a weapon in the player's // This was likely used to represent a weapon in the player's
// inventory in the original game, since TSWorldGun is clearly the // inventory in the original game, since CTSWorldGun is clearly the
// in-world pickup. // in-world pickup.

View File

@ -319,6 +319,9 @@ TSMultiplayerRules::PlayerDeath(base_player pp)
printfline("setInventoryEquippedIndex Flag Z"); printfline("setInventoryEquippedIndex Flag Z");
TS_resetViewModel(pl); TS_resetViewModel(pl);
pl.setInventoryEquippedIndex(-1); pl.setInventoryEquippedIndex(-1);
pl.resetZoom();
for(int i = pl.ary_myWeapons_softMax-1; i >= 0; i--){ for(int i = pl.ary_myWeapons_softMax-1; i >= 0; i--){
pl.dropWeapon(i, TRUE); pl.dropWeapon(i, TRUE);

View File

@ -17,7 +17,7 @@
/* PICKUP ITEMS */ /* PICKUP ITEMS */
// Bare minimum to compile with what Nuclide's src/server/weapons.qc expects. // Bare minimum to compile with what Nuclide's src/server/weapons.qc expects.
// TS already has its own weapons-pickup class: TSWorldGun. // TS already has its own weapons-pickup class: CTSWorldGun.
// Although that could fill in Nuclide's expected item_pickup and let anything in-map // Although that could fill in Nuclide's expected item_pickup and let anything in-map
// redirect to this if that were preferred. // redirect to this if that were preferred.

View File

@ -5,6 +5,9 @@ void ServerGame_Precache(void){
printfline("***ServerGame_Precache called***"); printfline("***ServerGame_Precache called***");
SharedGame_Precache(); SharedGame_Precache();
// yes, a serverside to this for now, the sound call is from serverside for the time being
FX_TS_Explosion_Grenade_Init();
//TAGGG - From FreeHL. Anything that ends up unused by FreeTS can be removed, //TAGGG - From FreeHL. Anything that ends up unused by FreeTS can be removed,
// including sound config files that are then unused. // including sound config files that are then unused.
@ -17,8 +20,7 @@ void ServerGame_Precache(void){
precache_model("models/player.mdl"); precache_model("models/player.mdl");
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
TSGrenadeProjectile::precache(); TS_GrenadeProjectile::precache();
ts_powerup::precache();
precache_model("models/powerup.mdl"); precache_model("models/powerup.mdl");

View File

@ -59,15 +59,16 @@ defs.h
../shared/weapons.h ../shared/weapons.h
../shared/player.h ../shared/player.h
../shared/powerup.h ../shared/powerup.h
../shared/sound_pitched.h
precache.h precache.h
entity/ts_powerup.h entity/ts_powerup.h
//player.c
entity/TSWorldGun.h entity/ts_worldgun.h
entity/TSThrownProjectile.h entity/ts_thrownprojectile.h
entity/TSGrenadeProjectile.h entity/ts_ammopack.h
entity/ts_grenadeprojectile.h
../shared/include.src ../shared/include.src
@ -85,10 +86,10 @@ entity/ts_slowmotionpoint.qc
entity/ts_teamescape.qc entity/ts_teamescape.qc
entity/ts_trigger.qc entity/ts_trigger.qc
entity/ts_wingiver.qc entity/ts_wingiver.qc
entity/TSWorldGun.qc entity/ts_worldgun.qc
entity/TSThrownProjectile.qc entity/ts_thrownprojectile.qc
entity/TSAmmoPack.qc entity/ts_ammopack.qc
entity/TSGrenadeProjectile.qc entity/ts_grenadeprojectile.qc
../shared/player.qc ../shared/player.qc
../shared/inventory_logic.qc ../shared/inventory_logic.qc
@ -117,9 +118,10 @@ spawn.qc
../shared/util.qc
../shared/precache.qc
// no server util.qc
precache.qc precache.qc
//money.qc
//spectator.qc

View File

@ -5,6 +5,9 @@
#define ASSIGN_SHELLEJECTDATA(arg_constName) ary_shellEjectData[SHELLEJECT_ID::##arg_constName] = (shellejectdata_t*) &shelleject_##arg_constName; #define ASSIGN_SHELLEJECTDATA(arg_constName) ary_shellEjectData[SHELLEJECT_ID::##arg_constName] = (shellejectdata_t*) &shelleject_##arg_constName;
#define DECLARE_SHELLEJECTDATA(arg_varName, arg_sModelPath, arg_sTouchSound) shellejectdata_t shelleject_##arg_varName = {arg_sModelPath, arg_sTouchSound}; #define DECLARE_SHELLEJECTDATA(arg_varName, arg_sModelPath, arg_sTouchSound) shellejectdata_t shelleject_##arg_varName = {arg_sModelPath, arg_sTouchSound};
#define ASSIGN_MUZZLEFLASHDATA(arg_constName) ary_muzzleFlashData[MUZZLEFLASH_ID::##arg_constName] = (muzzleflashdata_t*) &muzzleflash_##arg_constName;
#define DECLARE_MUZZLEFLASHDATA(arg_varName, arg_sSpritePath) var muzzleflashdata_t muzzleflash_##arg_varName = {0, arg_sSpritePath};
enum AMMO_ID{ enum AMMO_ID{
NONE = 0, NONE = 0,
@ -69,6 +72,12 @@ enum SHELLEJECT_ID{
}; };
// For now, ShellEject and MuzzleFlash structs are clientside only.
// ENUMs to let calls to related shared methods be dummied serverside for now
#ifdef CLIENT
// any other info tied to shell choice? // any other info tied to shell choice?
typedef struct{ typedef struct{
string sModelPath; string sModelPath;
@ -76,4 +85,41 @@ typedef struct{
string sTouchSound; string sTouchSound;
} shellejectdata_t; } shellejectdata_t;
#endif
// first three are the default HL muzzle flashes, which might even be skiped by TS.
// TS does come with its own muzzleflash sprites, haven't look into those much yet
enum MUZZLEFLASH_ID{
NONE = 0,
RIFLE,
SMALL,
WEIRD,
LAST_ID
};
// NOTE! iSpritePrecacheID is only for clientside so far, not precached serverside.
// This is based off how FreeHL does muzzleflash sprite precaches: only clientside.
// Structure is here in case they ever become shared.
#ifdef CLIENT
// Not much to a muzzle flash
typedef struct{
int iSpritePrecacheID;
string sSpritePath;
} muzzleflashdata_t;
void MuzzleFlash_precache(void);
#endif
// shared
void setupAmmoData(void);

View File

@ -15,6 +15,8 @@ DECLARE_AMMODATA(_32ACP, ".32 ACP", 0.5, 300)
DECLARE_AMMODATA(_7P62X51MM, "7.62 x 51mm", 30, 35) DECLARE_AMMODATA(_7P62X51MM, "7.62 x 51mm", 30, 35)
#ifdef CLIENT
DECLARE_SHELLEJECTDATA(NONE, "", "") DECLARE_SHELLEJECTDATA(NONE, "", "")
DECLARE_SHELLEJECTDATA(_56, "models/56_shell.mdl", "modelevent_shell.land") DECLARE_SHELLEJECTDATA(_56, "models/56_shell.mdl", "modelevent_shell.land")
DECLARE_SHELLEJECTDATA(_556, "models/556_shell.mdl", "modelevent_shell.land") DECLARE_SHELLEJECTDATA(_556, "models/556_shell.mdl", "modelevent_shell.land")
@ -25,3 +27,102 @@ DECLARE_SHELLEJECTDATA(_SHOTGUN, "models/shotgun_shell.mdl", "modelevent_shotgun
DECLARE_SHELLEJECTDATA(_SHOTGUN_BLUE, "models/shotgun_shell_blue.mdl", "modelevent_shotgunshell.land") DECLARE_SHELLEJECTDATA(_SHOTGUN_BLUE, "models/shotgun_shell_blue.mdl", "modelevent_shotgunshell.land")
DECLARE_SHELLEJECTDATA(_SHOTGUN_GOLD, "models/shotgun_shell_gold.mdl", "modelevent_shotgunshell.land") DECLARE_SHELLEJECTDATA(_SHOTGUN_GOLD, "models/shotgun_shell_gold.mdl", "modelevent_shotgunshell.land")
DECLARE_MUZZLEFLASHDATA(NONE, "")
DECLARE_MUZZLEFLASHDATA(RIFLE, "sprites/muzzleflash1.spr")
DECLARE_MUZZLEFLASHDATA(SMALL, "sprites/muzzleflash2.spr")
DECLARE_MUZZLEFLASHDATA(WEIRD, "sprites/muzzleflash3.spr")
// some muzzleflash candidates from TS files:
/*
gun_muzzle.spr
gun_muzzle2.spr
shotgun_pellets.spr a glowing effect? what?
ts_muzzleflash1.spr
ts_muzzleflash1h.spr
ts_muzzleflash1s.spr
ts_muzzleflash2h.spr
ts_muzzleflash6.spr
ts_muzzleflash6b.spr
*/
// In here since the MuzzleFlash isn't getting a class.
// Also, only clientside for now.
void MuzzleFlash_precache(void){
int i;
// taking these from Nuclide for now, may as well.
// Wait, why precache these if Nuclide already does getmodelindex to fetch the ID's?
//precache_model("sprites/muzzleflash1.spr");
//precache_model("sprites/muzzleflash2.spr");
//precache_model("sprites/muzzleflash3.spr");
// oh hey, arrow operator works in QuakeC.
// ... don't tell me how long this has been the case, alright.
(ary_muzzleFlashData[MUZZLEFLASH_ID::RIFLE])->iSpritePrecacheID = MUZZLE_RIFLE;
(ary_muzzleFlashData[MUZZLEFLASH_ID::SMALL])->iSpritePrecacheID = MUZZLE_SMALL;
(ary_muzzleFlashData[MUZZLEFLASH_ID::WEIRD])->iSpritePrecacheID = MUZZLE_WEIRD;
// NOTE - lines like this:
// (*whatever).var = thing
// will not save the change! Or, sometimes it seems they do? Maybe this rarely comes up
// For the rest, do the whole process
// start at 4 because 0 is for NONE, then 1,2,3's prechaches are handled by Nuclide
for(i = 4; i < MUZZLEFLASH_ID::LAST_ID; i++){
muzzleflashdata_t* tempRef = ary_muzzleFlashData[i];
int theModelIndex;
if((*tempRef).sSpritePath != NULL){
theModelIndex = (int)getmodelindex((*tempRef).sSpritePath);
}else{
theModelIndex = 0;
}
tempRef->iSpritePrecacheID = theModelIndex;
}
}
#endif
// for ammodata structs and all the other oddities
void setupAmmoData(void){
ASSIGN_AMMODATA(NONE)
ASSIGN_AMMODATA(_9X19MM)
ASSIGN_AMMODATA(_45ACP)
ASSIGN_AMMODATA(_P50AE)
ASSIGN_AMMODATA(_5P7X28)
ASSIGN_AMMODATA(_10MMAUTO)
ASSIGN_AMMODATA(_P22LR)
ASSIGN_AMMODATA(_P454CASULL)
ASSIGN_AMMODATA(_5P56NATO)
ASSIGN_AMMODATA(_7P62X39MM)
ASSIGN_AMMODATA(_50BMG)
ASSIGN_AMMODATA(_SHELLS)
ASSIGN_AMMODATA(_32ACP)
ASSIGN_AMMODATA(_7P62X51MM)
#ifdef CLIENT
ASSIGN_SHELLEJECTDATA(NONE)
ASSIGN_SHELLEJECTDATA(_56)
ASSIGN_SHELLEJECTDATA(_556)
ASSIGN_SHELLEJECTDATA(_22)
ASSIGN_SHELLEJECTDATA(_9MM)
ASSIGN_SHELLEJECTDATA(_GENERIC)
ASSIGN_SHELLEJECTDATA(_SHOTGUN)
ASSIGN_SHELLEJECTDATA(_SHOTGUN_BLUE)
ASSIGN_SHELLEJECTDATA(_SHOTGUN_GOLD)
printfline("ASSIGNMENT HAPPENED");
ASSIGN_MUZZLEFLASHDATA(NONE)
ASSIGN_MUZZLEFLASHDATA(SMALL)
ASSIGN_MUZZLEFLASHDATA(RIFLE)
ASSIGN_MUZZLEFLASHDATA(WEIRD)
#endif
}// setupAmmoData

View File

@ -43,19 +43,6 @@ enum TS_Team{
//TAGGG
//FLAG. Rename of the same value used by FL_SEMI_TOGGLED, since that name isn't used in The Specialists
//now. It will instead tell whether this is the first time firing since a release or not.
// One for secondary added too. hope that's a good idea
// ...unfortunately using these for flag values might've been a bad idea.
// Even in the old version, "1<<21" was already used for something else.
// They've been offset in the new version (base FreeCS by the way).
// So these will just be player bool's instead.
//#define FL_PRIMARY_FIRE_FIRST_FRAME (1<<20)
//#define FL_SECONDARY_FIRE_FIRST_FRAME (1<<21)
// MODERN FREECS STATS (in case they're needed for the sake of being // MODERN FREECS STATS (in case they're needed for the sake of being
// an extensive gamemod, but seeing as FreeHL has none of these, I doubt // an extensive gamemod, but seeing as FreeHL has none of these, I doubt
// that) // that)

View File

@ -10,15 +10,12 @@ void TS_playerEquippedWeapon_Shared(player pl, int newWeaponEquipped, BOOL useAk
#ifdef CLIENT #ifdef CLIENT
void _TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo); void _TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo);
void TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo); void TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo);
void EV_EquipCallback(void);
#endif #endif
#ifdef SERVER #ifdef SERVER
void _TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo); void _TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo);
void TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo); void TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo);
void CSEv_TS_playerEquippedWeapon_ii(int newWeaponEquipped, BOOL useAkimbo); void CSEv_TS_playerEquippedWeapon_ii(int newWeaponEquipped, BOOL useAkimbo);
#endif #endif

View File

@ -37,7 +37,8 @@ TS_Weapon_Draw_extra(void){
printfline("PLAYER DREW WEAPON: invID:%i (g_weapons ID:%d)", pl.inventoryEquippedIndex, pl.activeweapon); printfline("PLAYER DREW WEAPON: invID:%i (g_weapons ID:%d)", pl.inventoryEquippedIndex, pl.activeweapon);
pl.currentZoomChoice = -1; pl.resetZoom();
pl.aryNextBurstShotTime_softLength = 0; pl.aryNextBurstShotTime_softLength = 0;
pl.aryNextBurstShotTime_listenIndex = -1; pl.aryNextBurstShotTime_listenIndex = -1;
@ -180,6 +181,32 @@ TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo){
_TS_playerEquippedWeapon(pl, newWeaponEquipped, useAkimbo); _TS_playerEquippedWeapon(pl, newWeaponEquipped, useAkimbo);
sendevent("TS_playerEquippedWeapon", "ii", newWeaponEquipped, (int)useAkimbo); sendevent("TS_playerEquippedWeapon", "ii", newWeaponEquipped, (int)useAkimbo);
// EXPERIMENTAL
pl.equippedWeaponWaitingForCallback = TRUE;
// Not sure how you'd deal with a ping worse than 0.5 seconds
pl.equippedWeaponWaitingForCallback_maxWaitTime = time + 0.6;
}
// EXPERIMENTAL. If the currently equipped weapon has been changed, reject
// messages received between the time I sent an order to change the current wepaon
// and the time it takes to get a response that the new weapon was seen by the server.
// This stops out-of-date calls coming in from reverting the zoom (or whatever other var)
// back to the old state.
// Or, example:
// Var A is networked (server sends updates to the client of its current value to keep it
// from going too far out of sync).
// var A starts at 30 both places. Say the ping is 500 milliseconds.
// Client sets var A to 12, sends a message to the server to have it changed too.
// But, during those 500 milliseconds to reach the server, messages sent from the server
// with the old A value (30), sent before the client sent the A-update to the server, reach
// the client and rever the value of A back to that 30.
// Only after the A-update of 12 reaches the server and the server updates the client back
// does that stop.
void
EV_EquipCallback(void){
player pl = (player)self;
pl.equippedWeaponWaitingForCallback = FALSE;
} }
#endif #endif
@ -200,8 +227,16 @@ TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo){
//pl.activeweapon_net = 255; //pl.activeweapon_net = 255;
//pl.inventoryEquippedIndex_net = 255; //pl.inventoryEquippedIndex_net = 255;
// The client is waiting for a callback? Go on!
// Trying the reliable (_R) version for now
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EVENT_TS::EQUIP_CALLBACK );
msg_entity = pl;
multicast( [0,0,0], MULTICAST_ONE_R );
} }
// This is a received call from the client. // This is a received call from the client.
// We do need to let the server update first, which then tells the client // We do need to let the server update first, which then tells the client
// of the updated state. Even though the client initiated the call in this case. // of the updated state. Even though the client initiated the call in this case.
@ -305,6 +340,10 @@ EV_PlayerDeath(void){
// after this PlayerDeath one, somehow. Stopping damage-drawing on the "*dead" key // after this PlayerDeath one, somehow. Stopping damage-drawing on the "*dead" key
// being 1 works. // being 1 works.
//pSeat->m_flDamageAlpha = 0; //pSeat->m_flDamageAlpha = 0;
player pl = (player)self;
pl.resetZoom();
} }
#endif #endif

View File

@ -10,6 +10,7 @@ enum EVENT_TS{
EV_IMPACT_MELEE, EV_IMPACT_MELEE,
//DROP_WEAPON, //DROP_WEAPON,
FX_TS_EXPLOSION_GRENADE, FX_TS_EXPLOSION_GRENADE,
EQUIP_CALLBACK,
SOUNDPITCHED, SOUNDPITCHED,
SOUNDPITCHED_CHANNEL, SOUNDPITCHED_CHANNEL,
TEST, TEST,

View File

@ -250,8 +250,9 @@ FX_Impact_Melee(int iType, vector vecPos, vector vNormal)
multicast(vecPos, MULTICAST_PVS); multicast(vecPos, MULTICAST_PVS);
#else #else
//TAGGG - TODO. See _base\server\footsteps.c for other pl_... sounds to use //TAGGG - TODO. See Nuclide's footsteps.qc for other pl_... sounds to use
// as TS did for various surfaces hit by melee. // as TS did for various surfaces hit by melee. Used in sound script files.
// Or that might be all done now.
float impactSoundVolume = 0.55; float impactSoundVolume = 0.55;

View File

@ -10,9 +10,19 @@ var int FX_TS_EXPLOSION_PARTICLE;
void void
FX_TS_Explosion_Grenade_Init(void) FX_TS_Explosion_Grenade_Init(void)
{ {
Sound_Precache("fx.ts_explosion_grenade"); //Sound_Precache("fx.ts_explosion_grenade");
FX_TS_EXPLOSION_PARTICLE = particleeffectnum("ts_fx_explosion_grenade.explosion_grenade"); FX_TS_EXPLOSION_PARTICLE = particleeffectnum("ts_fx_explosion_grenade.explosion_grenade");
} }
#else
// sound only
void
FX_TS_Explosion_Grenade_Init(void)
{
Sound_Precache("fx.ts_explosion_grenade");
}
#endif #endif
@ -47,10 +57,30 @@ FX_TS_Explosion_Grenade(vector vecPos)
#ifdef SERVER #ifdef SERVER
// call me around a FX_TS_Explosion_Grenade call in TSGrenadeProjectile // call me around a FX_TS_Explosion_Grenade call in TS_GrenadeProjectile
void void
FX_TS_Explosion_Grenade_PlaySound(entity ePlayer){ FX_TS_Explosion_Grenade_PlaySound(entity eSelf){
Sound_Play(ePlayer, CHAN_WEAPON, "fx.ts_explosion_grenade"); //Sound_Play(eSelf, CHAN_WEAPON, "fx.ts_explosion_grenade");
// if we're not using the sound-script, do it by a manual call
//Client_ShakeOnce(vector pos, float radius, float duration, float frequency, float amplitude)
// there is a command, soundlength("x") that takes a path to a .wav file I think?
// Probably unnecessary
Client_ShakeOnce(eSelf.origin, 512, 1.7, 2.1, 3.4);
float randomChoice = random();
if(randomChoice < 0.2){
SoundPitched_Channel_Send(eSelf, SNDP_EXPLODE, CHAN_AUTO);
}else if(randomChoice < 0.4){
SoundPitched_Channel_Send(eSelf, SNDP_EXPLODE1, CHAN_AUTO);
}else if(randomChoice < 0.6){
SoundPitched_Channel_Send(eSelf, SNDP_EXPLODE2, CHAN_AUTO);
}else if(randomChoice < 0.8){
SoundPitched_Channel_Send(eSelf, SNDP_EXPLODE3, CHAN_AUTO);
}else{
SoundPitched_Channel_Send(eSelf, SNDP_EXPLODE4, CHAN_AUTO);
}
} }
#endif #endif

View File

@ -1,6 +1,5 @@
// If enabled, pressing left and right fire within a small amount of time // If enabled, pressing left and right fire within a small amount of time
// (more forgiving than the default "same-frame only" timing) lets firing // (more forgiving than the default "same-frame only" timing) lets firing
// immediately change into the akimbo dual-fire animation. // immediately change into the akimbo dual-fire animation.
@ -15,7 +14,6 @@
#includelist #includelist
//TAGGG - NEW
init.h init.h
entities.h entities.h
@ -41,7 +39,6 @@ precache.h
inventory_logic.h inventory_logic.h
event_enum.h event_enum.h
event_custom.h event_custom.h
//init.h
// Nope! Leave this one up to per-project. // Nope! Leave this one up to per-project.
@ -72,20 +69,13 @@ fx_ts_explosion_grenade.qc
event_custom.qc event_custom.qc
// leaving these up to client/server projects too now
util.qc //util.qc
precache.qc //precache.qc
sound_pitched.qc sound_pitched.qc
//fx_impact.h
//pmove.c
//animations.c
//items.h
//weapons.h
// <half life weapons files were here>
weapons/weapon_karate.qc weapons/weapon_karate.qc
weapons/weapon_glock18.qc weapons/weapon_glock18.qc
weapons/weapon_socommk23.qc weapons/weapon_socommk23.qc

View File

@ -1,5 +1,12 @@
// for client and serverside individually, data structs never need to be assigned
// more than once. However, this does not necessarily apply to precaches, the client
// renderer may restart sometimes.
// This is why precache calls should be handled elsewhere in precache methods
// that get called when needed.
var BOOL g_bDataStructsInit = FALSE;
// NOTE - for clientside, not called in ClientGame_RendererRestart, only // NOTE - for clientside, not called in ClientGame_RendererRestart, only
// once in ClientGame_Init. // once in ClientGame_Init.
@ -10,8 +17,13 @@ void SharedGame_Init(void){
// those had to lead here to be reached (SharedGame_Init is not called by // those had to lead here to be reached (SharedGame_Init is not called by
// Nuclide's src directly). // Nuclide's src directly).
setupWeaponData(); if(!g_bDataStructsInit){
setupPowerupData(); g_bDataStructsInit = TRUE;
setupWeaponData();
setupPowerupData();
setupAmmoData();
}
} }

View File

@ -96,7 +96,7 @@ BOOL attemptBuyWeapon(player pl, int arg_weaponID, int arg_iBitsUpgrade, int iCo
#endif #endif
#ifdef SERVER #ifdef SERVER
int addWeaponToInventory(player pl, TSWorldGun arg_pickupRef); int addWeaponToInventory(player pl, CTSWorldGun arg_pickupRef);
#endif #endif
#ifdef CLIENT #ifdef CLIENT

View File

@ -1467,7 +1467,7 @@ BOOL attemptBuyWeapon(player pl, int arg_weaponID, int arg_iBitsUpgrade, int iCo
//TAGGG - TODO. Could this even be shared? //TAGGG - TODO. Could this even be shared?
// It is only called by the player picking up weapons ingame, which only happens serverside. // It is only called by the player picking up weapons ingame, which only happens serverside.
// The client does not even receive the implementation details of TSWorldGun. // The client does not even receive the implementation details of CTSWorldGun.
#ifdef SERVER #ifdef SERVER
// This method may only be used by the server ingame, not at all buy-related. // This method may only be used by the server ingame, not at all buy-related.
@ -1480,7 +1480,7 @@ BOOL attemptBuyWeapon(player pl, int arg_weaponID, int arg_iBitsUpgrade, int iCo
// if there is room for it... this should not call this method at all) // if there is room for it... this should not call this method at all)
// Picking up the new weapon cannot put the player overbudget for slots (default 81). If so, we deny the pickup. // Picking up the new weapon cannot put the player overbudget for slots (default 81). If so, we deny the pickup.
//int addWeaponToInventory(player pl, int arg_weaponID, int arg_iClip, int arg_iClipAkimbo, int arg_iBitsUpgrade, int iCount){ //int addWeaponToInventory(player pl, int arg_weaponID, int arg_iClip, int arg_iClipAkimbo, int arg_iBitsUpgrade, int iCount){
int addWeaponToInventory(player pl, TSWorldGun arg_pickupRef){ int addWeaponToInventory(player pl, CTSWorldGun arg_pickupRef){
//safe assumption... for now. //safe assumption... for now.
//NOTICE that this doesn't mean anything if we return -1, //NOTICE that this doesn't mean anything if we return -1,

View File

@ -1,6 +1,6 @@
//TAGGG - NEW. Header file for gamemod player //TAGGG - NEW. Header file for gamemod player
class TSWorldGun; class CTSWorldGun;
// NOTE- // NOTE-
@ -100,13 +100,38 @@ class player:base_player
// Should this be predicted? Unsure, I doubt it. // Should this be predicted? Unsure, I doubt it.
float maxspeed_raw; float maxspeed_raw;
// ZOOM VARS
////////////////////////////////
// Don't use viewzoom, that's used by Nucldie to enforce the real zoom.
// The closest thing is flZoomCurrent further down, the raw value even after the current
// state of lerp to be given to viewzoom.
// The current choice of zoom of some incremental number offered by the current weapon.
// 0 is the default (no zoom). There is no standard for what zoom value there is for each
// zoom level in general, that is up to the equipped weapon's secondaryfire method to fill
// on right-clicking to change the zoom level.
PREDICTED_INT(iZoomLevel);
// Set this (or the setZoom method) to tap into the lerp system properly.
// When noticed (client/view.qc), the current zoom value goes to flZoomStart and
// flZoomTarget goes to flZoomEnd. The lerp goes from Start to End for a smooth transition.
PREDICTED_FLOAT(flZoomTarget);
#ifdef CLIENT #ifdef CLIENT
//TAGGG - related to how to handle FOV changes. float flZoomEnd;
float flCurrentZoom; float flZoomStart;
float flOldZoom;
float flZoomLerp; float flZoomLerp;
float flZoomLevel; float flZoomCurrent;
#endif
////////////////////////////////
#ifdef CLIENT
BOOL equippedWeaponWaitingForCallback;
float equippedWeaponWaitingForCallback_maxWaitTime;
// For telling how long it's been since I've been on the ground. // For telling how long it's been since I've been on the ground.
// Don't oscillate the view model bob on going down short steps. // Don't oscillate the view model bob on going down short steps.
@ -163,10 +188,6 @@ class player:base_player
#endif #endif
// shared zoom var! Don't use viewzoom, that's used by Nucldie to enforce the real zoom
PREDICTED_FLOAT(flTargetZoom);
float flKarateBlockCooldown; float flKarateBlockCooldown;
@ -257,11 +278,7 @@ class player:base_player
BOOL inputPrimaryReleasedQueue; BOOL inputPrimaryReleasedQueue;
BOOL inputSecondaryReleasedQueue; BOOL inputSecondaryReleasedQueue;
// -1 means not using a scope, regardless of whether the weapon has it.
// We'll keep this serverside too, since that's the one relaying the decisions to the
// client.
int currentZoomChoice;
// Shared, but don't network! I think? // Shared, but don't network! I think?
int aryNextBurstShotTime_softLength; int aryNextBurstShotTime_softLength;
float aryNextBurstShotTime[5]; float aryNextBurstShotTime[5];
@ -449,6 +466,8 @@ class player:base_player
virtual void (void)handleAccuracyKickback; virtual void (void)handleAccuracyKickback;
virtual void(float arg_theZoom) setZoom; virtual void(float arg_theZoom) setZoom;
virtual void(void) resetZoom;
virtual void(int arg_newIndex) setInventoryEquippedIndex; virtual void(int arg_newIndex) setInventoryEquippedIndex;
virtual void(int arg_newIndex, BOOL useAkimbo) setInventoryEquippedIndex_Akimbo; virtual void(int arg_newIndex, BOOL useAkimbo) setInventoryEquippedIndex_Akimbo;
@ -493,9 +512,9 @@ class player:base_player
//virtual void () frameThink; //virtual void () frameThink;
//TAGGG - QUESTION. Does this need to be separate from postThink at all? Same for above, //TAGGG - QUESTION. Does this need to be separate from postThink at all? Same for above,
// forget what these are for // forget what these are for
virtual void () frameThink_fromServer; virtual void(void) frameThink_fromServer;
virtual BOOL(TSWorldGun arg_pickup) attemptAddWeaponFromPickup; virtual BOOL(CTSWorldGun arg_pickup) attemptAddWeaponFromPickup;
virtual void(int arg_weaponID, BOOL completeDrop) dropWeapon; virtual void(int arg_weaponID, BOOL completeDrop) dropWeapon;
virtual BOOL(void) anyAmmoPoolNonEmpty; virtual BOOL(void) anyAmmoPoolNonEmpty;
virtual void(void) dropAmmo; virtual void(void) dropAmmo;

View File

@ -13,6 +13,12 @@
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
//#define FORCE_NETWORK_ALL_INVENTORY
/* all potential SendFlags bits we can possibly send */ /* all potential SendFlags bits we can possibly send */
enumflags enumflags
@ -180,7 +186,20 @@ player::ReceiveEntity(float new, float fl)
w_attack_akimbo_next = readfloat(); w_attack_akimbo_next = readfloat();
isReloading = readbyte(); isReloading = readbyte();
isChangingIronsight = readbyte(); isChangingIronsight = readbyte();
flTargetZoom = readfloat();
//flZoomTarget = readfloat();
float tempThing = readfloat();
/*
if(tempThing != flZoomTarget){
printfline("flZoomTarget change! %.2f - %.2f", flZoomTarget, tempThing);
}
*/
// That's a good thing, yes?
if(!equippedWeaponWaitingForCallback){
flZoomTarget = tempThing;
}
iZoomLevel = readbyte();
nextAkimboAttackPreference = readbyte(); nextAkimboAttackPreference = readbyte();
akimboDualFireToleranceTime = readfloat(); akimboDualFireToleranceTime = readfloat();
grenadeFireIndex = readbyte() - 1; grenadeFireIndex = readbyte() - 1;
@ -212,7 +231,6 @@ player::ReceiveEntity(float new, float fl)
//doFiremodeChange = readbyte(); //doFiremodeChange = readbyte();
currentZoomChoice = readbyte() - 1;
ary_myWeapons_softMax = readbyte(); ary_myWeapons_softMax = readbyte();
@ -358,7 +376,8 @@ player::PredictPreFrame(void)
SAVE_STATE(w_attack_akimbo_next); SAVE_STATE(w_attack_akimbo_next);
SAVE_STATE(isReloading); SAVE_STATE(isReloading);
SAVE_STATE(isChangingIronsight); SAVE_STATE(isChangingIronsight);
SAVE_STATE(flTargetZoom); SAVE_STATE(flZoomTarget);
SAVE_STATE(iZoomLevel);
SAVE_STATE(nextAkimboAttackPreference); SAVE_STATE(nextAkimboAttackPreference);
SAVE_STATE(akimboDualFireToleranceTime); SAVE_STATE(akimboDualFireToleranceTime);
SAVE_STATE(grenadeFireIndex); SAVE_STATE(grenadeFireIndex);
@ -456,7 +475,8 @@ player::PredictPostFrame(void)
ROLL_BACK(w_attack_akimbo_next); ROLL_BACK(w_attack_akimbo_next);
ROLL_BACK(isReloading); ROLL_BACK(isReloading);
ROLL_BACK(isChangingIronsight); ROLL_BACK(isChangingIronsight);
ROLL_BACK(flTargetZoom); ROLL_BACK(flZoomTarget);
ROLL_BACK(iZoomLevel);
ROLL_BACK(nextAkimboAttackPreference); ROLL_BACK(nextAkimboAttackPreference);
ROLL_BACK(akimboDualFireToleranceTime); ROLL_BACK(akimboDualFireToleranceTime);
ROLL_BACK(grenadeFireIndex); ROLL_BACK(grenadeFireIndex);
@ -505,6 +525,7 @@ player::EvaluateEntity(void)
base_player::EvaluateEntity(); base_player::EvaluateEntity();
int i; int i;
int myAmmoType;
/* animation */ /* animation */
if (ATTR_CHANGED(anim_bottom) || ATTR_CHANGED(anim_bottom_time)) if (ATTR_CHANGED(anim_bottom) || ATTR_CHANGED(anim_bottom_time))
@ -613,7 +634,7 @@ player::EvaluateEntity(void)
if(ATTR_CHANGED(ary_myWeapons[i].iIronSight)) SendFlags |= PLAYER_UNUSED1; if(ATTR_CHANGED(ary_myWeapons[i].iIronSight)) SendFlags |= PLAYER_UNUSED1;
if(ATTR_CHANGED(ary_myWeapons[i].forceBodygroup1Submodel)) SendFlags |= PLAYER_UNUSED1; if(ATTR_CHANGED(ary_myWeapons[i].forceBodygroup1Submodel)) SendFlags |= PLAYER_UNUSED1;
//} //}
int myAmmoType = getAmmoTypeOfWeapon(this.activeweapon); myAmmoType = getAmmoTypeOfWeapon(this.activeweapon);
if(myAmmoType != -1){ if(myAmmoType != -1){
i = myAmmoType; i = myAmmoType;
//UNNECESSARY. This array is of fixed length, so known at all times. //UNNECESSARY. This array is of fixed length, so known at all times.
@ -642,7 +663,8 @@ player::EvaluateEntity(void)
SAVE_STATE(w_attack_akimbo_next); SAVE_STATE(w_attack_akimbo_next);
SAVE_STATE(isReloading); SAVE_STATE(isReloading);
SAVE_STATE(isChangingIronsight); SAVE_STATE(isChangingIronsight);
SAVE_STATE(flTargetZoom); SAVE_STATE(flZoomTarget);
SAVE_STATE(iZoomLevel);
SAVE_STATE(nextAkimboAttackPreference); SAVE_STATE(nextAkimboAttackPreference);
SAVE_STATE(akimboDualFireToleranceTime); SAVE_STATE(akimboDualFireToleranceTime);
SAVE_STATE(grenadeFireIndex); SAVE_STATE(grenadeFireIndex);
@ -680,7 +702,7 @@ player::EvaluateEntity(void)
//} //}
int myAmmoType = getAmmoTypeOfWeapon(this.activeweapon); myAmmoType = getAmmoTypeOfWeapon(this.activeweapon);
if(myAmmoType != -1){ if(myAmmoType != -1){
i = myAmmoType; i = myAmmoType;
//UNNECESSARY. This array is of fixed length, so known at all times. //UNNECESSARY. This array is of fixed length, so known at all times.
@ -796,7 +818,8 @@ player::SendEntity(entity ePEnt, float fChanged)
WriteFloat(MSG_ENTITY, w_attack_akimbo_next ); WriteFloat(MSG_ENTITY, w_attack_akimbo_next );
WriteByte(MSG_ENTITY, isReloading ); WriteByte(MSG_ENTITY, isReloading );
WriteByte(MSG_ENTITY, isChangingIronsight ); WriteByte(MSG_ENTITY, isChangingIronsight );
WriteFloat(MSG_ENTITY, flTargetZoom); WriteFloat(MSG_ENTITY, flZoomTarget);
WriteByte(MSG_ENTITY, iZoomLevel);
WriteByte(MSG_ENTITY, nextAkimboAttackPreference); WriteByte(MSG_ENTITY, nextAkimboAttackPreference);
WriteFloat(MSG_ENTITY, akimboDualFireToleranceTime); WriteFloat(MSG_ENTITY, akimboDualFireToleranceTime);
WriteByte(MSG_ENTITY, grenadeFireIndex + 1); WriteByte(MSG_ENTITY, grenadeFireIndex + 1);
@ -828,7 +851,6 @@ player::SendEntity(entity ePEnt, float fChanged)
//WriteByte(MSG_ENTITY, doFiremodeChange); //WriteByte(MSG_ENTITY, doFiremodeChange);
WriteByte(MSG_ENTITY, currentZoomChoice + 1 );
//weapondynamic_t ary_myWeapons[ary_myWeapons_length]; //weapondynamic_t ary_myWeapons[ary_myWeapons_length];
@ -933,10 +955,6 @@ player::player(void){
flag_lastWeaponAkimbo = FALSE; flag_lastWeaponAkimbo = FALSE;
flCurrentZoom = 1;
flOldZoom = 1;
flZoomLerp = 0;
flZoomLevel = 0;
#endif #endif
flKarateBlockCooldown = 0; flKarateBlockCooldown = 0;
@ -1014,63 +1032,55 @@ player::reset(BOOL resetInventory){
// should this even make any assumptions about this? // should this even make any assumptions about this?
//iState = ?; //iState = ?;
resetZoom();
#ifdef CLIENT #ifdef CLIENT
// For safety, doing this. // For safety, doing this.
// If anywhere that ever calls for this method clientside has this set // If anywhere that ever calls for this method clientside has this set
// properly before the call to here, (whatever event-method in base files leads // properly before the call to here, (whatever event-method in base files leads
// to here most likely), this is not necessary. // to here most likely), this is not necessary.
// Also, no need for pSeatLocal yet, but add in if that changes. // Also, no need for pSeatLocal yet, but add in if that changes.
int s = (float)getproperty(VF_ACTIVESEAT); int s = (float)getproperty(VF_ACTIVESEAT);
pSeat = &g_seats[s]; pSeat = &g_seats[s];
pSeat->m_flHUDWeaponSelectTime = -1; pSeat->m_flHUDWeaponSelectTime = -1;
// we don't want damage related to the death / between spawns carrying over // we don't want damage related to the death / between spawns carrying over
// at the start of the next spawn. // at the start of the next spawn.
pSeat->m_flDamageAlpha = 0; pSeat->m_flDamageAlpha = 0;
// doing this in reset too to avoid a little glitch. // doing this in reset too to avoid a little glitch.
weaponSelectHighlightID = -1; weaponSelectHighlightID = -1;
w_freeze_idle_next = -1; w_freeze_idle_next = -1;
flOldZoom = 1; flRecentGroundTime = 0;
flCurrentZoom = 1;
flZoomLevel = 1; //TAGGG - BobNEW.
// Reset the vars here? Or only on an inventory wipe?
pViewBob = &g_viewBobVars[s];
flRecentGroundTime = 0; pViewBob->m_flBobTime = 0;
pViewBob->m_flBob = 0;
//TAGGG - BobNEW. pViewBob->m_flBobCycle = 0;
// Reset the vars here? Or only on an inventory wipe? pViewBob->m_flSpeed = 0;
pViewBob = &g_viewBobVars[s]; pViewBob->m_vCam = [0,0,0];
pViewBob->m_flBobTime = 0; /////////////////////////////////////////////////////
pViewBob->m_flBob = 0;
pViewBob->m_flBobCycle = 0;
pViewBob->m_flSpeed = 0; flViewShake = 0;
pViewBob->m_vCam = [0,0,0];
///////////////////////////////////////////////////// recentLaserHitPosSet = FALSE;
lasersightUnlockTime = FALSE;
flViewShake = 0; forceViewModelUpdate = FALSE;
prev_forceBodygroup1Submodel = 0;
recentLaserHitPosSet = FALSE;
lasersightUnlockTime = FALSE;
forceViewModelUpdate = FALSE;
prev_forceBodygroup1Submodel = 0;
#endif #endif
#ifdef SERVER #ifdef SERVER
switchToRecentlyAddedWeapon = FALSE; switchToRecentlyAddedWeapon = FALSE;
nextUseCooldown = 0; nextUseCooldown = 0;
#endif #endif
currentZoomChoice = -1;
setZoom(1.0f);
viewzoom = 1.0f; // and apply instantly.
// Shared, but don't network! I think? // Shared, but don't network! I think?
aryNextBurstShotTime_softLength = 0; aryNextBurstShotTime_softLength = 0;
@ -1103,9 +1113,6 @@ player::reset(BOOL resetInventory){
shotgunReloadIndex = 0; shotgunReloadIndex = 0;
shotgunAddAmmoTime = -1; shotgunAddAmmoTime = -1;
shotgunAddAmmoSoundTime = -1; shotgunAddAmmoSoundTime = -1;
#ifdef CLIENT
//shotgunAddAmmoTime_cooldownSetTime = -1;
#endif
doFiremodeChange = FALSE; doFiremodeChange = FALSE;
@ -1119,14 +1126,6 @@ player::reset(BOOL resetInventory){
isReloading = FALSE; isReloading = FALSE;
isChangingIronsight = FALSE; isChangingIronsight = FALSE;
// maybe not necessary, but I don't think
// the client gets any benefit from this.
#ifdef SERVER
//the first time you fire will be the first frame of firing.
//flags = flags | FL_PRIMARY_FIRE_FIRST_FRAME;
//flags = flags | FL_SECONDARY_FIRE_FIRST_FRAME;
#endif
nextAkimboAttackPreference = BITS_AKIMBOCHOICE_LEFT; nextAkimboAttackPreference = BITS_AKIMBOCHOICE_LEFT;
recentAttackHadAmmo = FALSE; recentAttackHadAmmo = FALSE;
@ -1143,6 +1142,8 @@ player::reset(BOOL resetInventory){
if(resetInventory){ if(resetInventory){
// could this be done for resets outside of resetInventory? unsure // could this be done for resets outside of resetInventory? unsure
flags = 0; flags = 0;
gflags = 0; gflags = 0;
@ -1155,6 +1156,10 @@ player::reset(BOOL resetInventory){
shotgunWaitingForPump = FALSE; shotgunWaitingForPump = FALSE;
#ifdef CLIENT
equippedWeaponWaitingForCallback = FALSE;
#endif
#ifdef SERVER #ifdef SERVER
// other projects do that so sure? // other projects do that so sure?
weapon = 0; weapon = 0;
@ -1247,7 +1252,28 @@ player::handleAccuracyKickback(void){
void void
player::setZoom(float arg_theZoom) player::setZoom(float arg_theZoom)
{ {
flTargetZoom = arg_theZoom; printfline("ORDER! %.2f", arg_theZoom);
flZoomTarget = arg_theZoom;
}
// forget any zoom-related settings instantly.
// Unsure if a message should be sent to the client if called from the server, or assume the
// calls coincide.
void
player::resetZoom(void)
{
iZoomLevel = 0;
viewzoom = 1.0f;
setZoom(1.0f); // sets flZoomTarget
#ifdef CLIENT
// IMPORTANT! ZoomLerp under 0 tries to involve flZoomOld, set or not
flZoomLerp = 1.0f;
SAVE_STATE(iZoomLevel);
SAVE_STATE(viewzoom);
SAVE_STATE(flZoomTarget);
flZoomEnd = 1.0f;
flZoomCurrent = 1.0f;
#endif
} }
void void
@ -1337,16 +1363,17 @@ player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
// ... Marvelous. But at least that's a completely separate issue, again with or without below. // ... Marvelous. But at least that's a completely separate issue, again with or without below.
// (force a sendoff, expect it area) // (force a sendoff, expect it area)
/*
#ifdef SERVER #ifdef SERVER
// Force a sendoff! // Force a sendoff!
//SendFlags |= PLAYER_WEAPON; SendFlags |= PLAYER_WEAPON;
#else #else
SAVE_STATE(activeweapon); SAVE_STATE(activeweapon);
// unsure if this one's needed // unsure if this one's needed
//SAVE_STATE(inventoryEquippedIndex); SAVE_STATE(inventoryEquippedIndex);
#endif #endif
*/
} }
@ -1510,7 +1537,7 @@ player::frameThink_fromServer(void){
#ifdef CLIENT #ifdef CLIENT
// Note that these pre/postThink's aren't game events, they're just called by _base/entry.c // Note that these pre/postThink's aren't game events, they're just called
// before/after prediction accordingly, and every single rendered frame. // before/after prediction accordingly, and every single rendered frame.
// Unlike serverside preThink / postThink, which (I think?) are called independent of any // Unlike serverside preThink / postThink, which (I think?) are called independent of any
// logic frame-rate on the server. // logic frame-rate on the server.
@ -1524,6 +1551,11 @@ player::preThink(void){
} }
if(time >= equippedWeaponWaitingForCallback_maxWaitTime){
// stop then
equippedWeaponWaitingForCallback = FALSE;
}
// Called before rendering, so this is an acceptable place. // Called before rendering, so this is an acceptable place.
View_HandleZoom(); View_HandleZoom();
@ -1649,7 +1681,7 @@ player::postThink(void){
#ifdef SERVER #ifdef SERVER
BOOL BOOL
player::attemptAddWeaponFromPickup(TSWorldGun arg_pickup){ player::attemptAddWeaponFromPickup(CTSWorldGun arg_pickup){
//int existingMatchingIndex = findWeaponInConfig((player)other, (int)arg_pickup.myInfo.weaponID); //int existingMatchingIndex = findWeaponInConfig((player)other, (int)arg_pickup.myInfo.weaponID);
@ -1723,7 +1755,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
// record the number of slots lost for removing from the total later, // record the number of slots lost for removing from the total later,
// typically those of the 'eDrop' entity. Adjust for being more than one. // typically those of the 'eDrop' entity. Adjust for being more than one.
int iSlotsDropped = 0; int iSlotsDropped = 0;
TSWorldGun eDrop = NULL; CTSWorldGun eDrop = NULL;
// there is a "TS_playerDropWeapon" method in event_custom.c we could call if needed. // there is a "TS_playerDropWeapon" method in event_custom.c we could call if needed.
// Looks like we never really intended for it to go anywhere though, no need for that. // Looks like we never really intended for it to go anywhere though, no need for that.
@ -1795,7 +1827,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
// basicRefX.iAkimboID > 0 // basicRefX.iAkimboID > 0
if((*basicPS).iBitsUpgradeAuto & BITS_WEAPONOPT_AKIMBO){ if((*basicPS).iBitsUpgradeAuto & BITS_WEAPONOPT_AKIMBO){
// singular akimbo? dropping removes. // singular akimbo? dropping removes.
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
removeWeaponFromInventory(this, arg_weaponID); removeWeaponFromInventory(this, arg_weaponID);
if(!completeDrop){ if(!completeDrop){
playerEquipIdealSafe(this); playerEquipIdealSafe(this);
@ -1812,7 +1844,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
// WAIT NOT JUST YET. The weapon drop will think we're dropping the weapon while it // WAIT NOT JUST YET. The weapon drop will think we're dropping the weapon while it
// didn't have akimbo. // didn't have akimbo.
if(!completeDrop){ if(!completeDrop){
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
if(weaponEquippedAkimbo){ if(weaponEquippedAkimbo){
// safety. dynaRefPRE.iClipLeft stays as it is, just enforcing that the akimbo one was dropped. // safety. dynaRefPRE.iClipLeft stays as it is, just enforcing that the akimbo one was dropped.
@ -1849,10 +1881,10 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
// Player is dying? Remove this weapon and drop two copies. // Player is dying? Remove this weapon and drop two copies.
// Pretty simple. // Pretty simple.
// ...but we need to override how they get ammo. // ...but we need to override how they get ammo.
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
eDrop.myInfo.iClipLeft = dynaRefPRE.iClipLeft; eDrop.myInfo.iClipLeft = dynaRefPRE.iClipLeft;
eDrop.myInfo.iClipAkimboLeft = 0; eDrop.myInfo.iClipAkimboLeft = 0;
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
eDrop.myInfo.iClipLeft = dynaRefPRE.iClipAkimboLeft; eDrop.myInfo.iClipLeft = dynaRefPRE.iClipAkimboLeft;
eDrop.myInfo.iClipAkimboLeft = 0; eDrop.myInfo.iClipAkimboLeft = 0;
@ -1865,7 +1897,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
}else{ }else{
// doesn't support akimbo or not akimbo? remove. // doesn't support akimbo or not akimbo? remove.
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
removeWeaponFromInventory(this, arg_weaponID); removeWeaponFromInventory(this, arg_weaponID);
if(!completeDrop){ if(!completeDrop){
playerEquipIdealSafe(this); playerEquipIdealSafe(this);
@ -1875,7 +1907,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
//drop away //drop away
if(!completeDrop){ if(!completeDrop){
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
eDrop.myInfo.iCount = 1; eDrop.myInfo.iCount = 1;
eDrop.myInfo.iSlots = (*basicPS).iSlots * 1; eDrop.myInfo.iSlots = (*basicPS).iSlots * 1;
@ -1894,7 +1926,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
}else{ }else{
// combine them all, happens naturally. // combine them all, happens naturally.
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
removeWeaponFromInventory(this, arg_weaponID); removeWeaponFromInventory(this, arg_weaponID);
playerEquipIdealSafe(this); playerEquipIdealSafe(this);
} }
@ -1902,7 +1934,7 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
}else{ // if((*basicPS).typeID == WEAPONDATA_TYPEID_MELEE) }else{ // if((*basicPS).typeID == WEAPONDATA_TYPEID_MELEE)
eDrop = TSWorldGun::generate(this, arg_weaponID); eDrop = CTSWorldGun::generate(this, arg_weaponID);
removeWeaponFromInventory(this, arg_weaponID); removeWeaponFromInventory(this, arg_weaponID);
if(!completeDrop){ if(!completeDrop){
playerEquipIdealSafe(this); playerEquipIdealSafe(this);
@ -1941,8 +1973,8 @@ player::anyAmmoPoolNonEmpty(void){
// oh.. I guess that's it. // oh.. I guess that's it.
void void
player::dropAmmo(void){ player::dropAmmo(void){
//TSAmmoPack eDrop = //CTSAmmoPack eDrop =
TSAmmoPack::generate(this); CTSAmmoPack::generate(this);
}// dropAmmo }// dropAmmo

View File

@ -13,8 +13,10 @@
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
// !!! IMPORTANT NOTE. // NOTE - Physics_WaterMove is in pmove_water.qc instead
// !!! IMPORTANT
// Any methods starting with "Game" in here are no longer called by Nuclide. // Any methods starting with "Game" in here are no longer called by Nuclide.
// Most methods have been changed to player-methods instead, see much further // Most methods have been changed to player-methods instead, see much further
// down. Keeping mine as they are to be inserted as needed. // down. Keeping mine as they are to be inserted as needed.
@ -264,13 +266,6 @@ player::Physics_WaterJump(void)
} }
void
player::Physics_WaterMove(void)
{
base_player::Physics_WaterMove();
}
float float
player::Physics_MaxSpeed(void) player::Physics_MaxSpeed(void)
{ {

View File

@ -14,65 +14,73 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
//TAGGG - Clone of FreeHL's way, which is a clone of Nuclide's way
// (base_player::Physics_WaterMove). I'll keep this as a copy too then?
void void
GamePMove_WaterMove(player target) player::Physics_WaterMove(void)
{ {
if (target.movetype == MOVETYPE_NOCLIP) { if (movetype == MOVETYPE_NOCLIP) {
return; return;
} }
#ifdef SERVER #ifdef SERVER
if (target.health < 0) { if (health < 0) {
return; return;
} }
/* we've just exited water */ /* we've just exited water */
if (target.waterlevel != 3) { if (waterlevel != 3) {
if (target.underwater_time < time) { if (underwater_time < time) {
Sound_Play(target, CHAN_BODY, "player.gasplight"); Sound_Play(this, CHAN_BODY, "player.gasplight");
} else if (target.underwater_time < time + 9) { } else if (underwater_time < time + 9) {
Sound_Play(target, CHAN_BODY, "player.gaspheavy"); Sound_Play(this, CHAN_BODY, "player.gaspheavy");
} }
target.underwater_time = time + 12; underwater_time = time + 12;
} else if (target.underwater_time < time) { } else if (underwater_time < time) {
/* we've been underwater... for too long. */ /* we've been underwater... for too long. */
if (target.pain_time < time) { if (pain_time < time) {
Damage_Apply(target, world, 5, DMG_DROWN, 0); Damage_Apply(this, world, 5, DMG_DROWN, 0);
target.pain_time = time + 1; pain_time = time + 1;
} }
} }
#endif #endif
if (!target.waterlevel){ if (!waterlevel){
if (target.flags & FL_INWATER) { if (flags & FL_INWATER) {
#ifdef SERVER #ifdef SERVER
Sound_Play(target, CHAN_BODY, "player.waterexit"); Sound_Play(this, CHAN_BODY, "player.waterexit");
#endif #endif
target.flags &= ~FL_INWATER; flags &= ~FL_INWATER;
} }
return; return;
} }
#ifdef SERVER #ifdef SERVER
if (target.watertype == CONTENT_LAVA) { if (watertype == CONTENT_LAVA) {
if (target.pain_time < time) { if (pain_time < time) {
target.pain_time = time + 0.2; pain_time = time + 0.2;
Damage_Apply(target, world, 10*target.waterlevel, DMG_BURN, 0); Damage_Apply(this, world, 10*waterlevel, DMG_BURN, 0);
} }
} else if (target.watertype == CONTENT_SLIME) { } else if (watertype == CONTENT_SLIME) {
if (target.pain_time < time) { if (pain_time < time) {
target.pain_time = time + 1; pain_time = time + 1;
Damage_Apply(target, world, 4*target.waterlevel, DMG_ACID, 0); Damage_Apply(this, world, 4*waterlevel, DMG_ACID, 0);
} }
} }
#endif #endif
if (!(target.flags & FL_INWATER)) { if (!(flags & FL_INWATER)) {
#ifdef SERVER #ifdef SERVER
Sound_Play(target, CHAN_BODY, "player.waterenter"); Sound_Play(this, CHAN_BODY, "player.waterenter");
target.pain_time = 0; pain_time = 0;
#endif #endif
target.flags |= FL_INWATER; flags |= FL_INWATER;
}
/* we might need to apply extra-velocity to get out of water-volumes */
if (waterlevel >= 2) {
Physics_WaterJump();
} }
} }

View File

@ -93,8 +93,8 @@ powerupdata_basic_t* ary_powerupData[POWERUP_ID::LAST_ID];
#ifdef SERVER #ifdef SERVER
class ts_powerup; class CTSPowerUp;
extern void powerup_linkToStruct(ts_powerup arg_entity, POWERUP_ID arg_id); extern void powerup_linkToStruct(CTSPowerUp arg_entity, POWERUP_ID arg_id);
#endif #endif
extern void setupPowerupData(void); extern void setupPowerupData(void);

View File

@ -16,9 +16,12 @@ void SharedGame_Precache(void){
//printfline("***SharedGame_Precache called***"); //printfline("***SharedGame_Precache called***");
// good idea to have precache shared? Unsure, but it has script client and serverside
CTSPowerUp::precache();
precache_model("models/powerup.mdl"); precache_model("models/powerup.mdl");
// In FreeTS, looks like shell eject effects are precached both client & serverside // In FreeTS, looks like shell eject effects are precached both client and serverside
// (so here in shared/precache.qc is good). // (so here in shared/precache.qc is good).
// physics-related / slow-mo? // physics-related / slow-mo?

View File

@ -0,0 +1,66 @@
void SoundPitched_Send(entity ent, int id);
void SoundPitched_Channel_Send(entity ent, int id, float chan);
#ifdef CLIENT
void SoundPitched_Receive(void);
void SoundPitched_Channel_Receive(void);
#endif
typedef enum
{
SNDP_AK47_FIRE,
SNDP_AKIMBOCOLTS_FIRE,
SNDP_BARRETTM82_FIRE,
SNDP_BENELLIM3_FIRE,
SNDP_BERETTA_FIRE,
SNDP_BERETTA_FIRE_SIL,
SNDP_CONTENDERG2_FIRE,
SNDP_DESERTEAGLE_FIRE,
SNDP_DESERTEAGLE_FIRE_SIL,
SNDP_FIVESEVEN_FIRE,
SNDP_FIVESEVEN_FIRE_SIL,
SNDP_GLOCK18_FIRE,
SNDP_GLOCK18_FIRE_SIL,
SNDP_GLOCK20_FIRE,
SNDP_GLOCK20_FIRE_SIL,
SNDP_HKPDW_FIRE,
SNDP_HKPDW_FIRE_SIL,
SNDP_KATANA_MISS,
SNDP_KATANA_MISS1,
SNDP_M4A1_FIRE,
SNDP_M4A1_FIRE_SIL,
SNDP_M16A4_FIRE,
SNDP_M60_FIRE,
SNDP_MAC10_FIRE,
SNDP_MAC10_FIRE_SIL,
SNDP_MINIUZI_FIRE,
SNDP_MINIUZI_FIRE_SIL,
SNDP_MOSSBERG500_FIRE,
SNDP_MP5K_FIRE,
SNDP_MP5K_FIRE_SIL,
SNDP_MP5SD_FIRE,
SNDP_RAGINGBULL_FIRE,
SNDP_RUGERMK1_FIRE,
SNDP_SAWEDOFF_FIRE,
SNDP_SKORPION_FIRE,
SNDP_SOCOMMK23_FIRE,
SNDP_SOCOMMK23_FIRE_SIL,
SNDP_SPAS12_FIRE,
SNDP_STEYRAUG_FIRE,
SNDP_STEYRAUG_FIRE_SIL,
SNDP_STEYRTMP_FIRE,
SNDP_STEYRTMP_FIRE_SIL,
SNDP_UMP_FIRE,
SNDP_UMP_FIRE_SIL,
SNDP_USAS12_FIRE,
SNDP_EXPLODE,
SNDP_EXPLODE1,
SNDP_EXPLODE2,
SNDP_EXPLODE3,
SNDP_EXPLODE4
} sfx_pitched_t;

View File

@ -20,61 +20,8 @@
// katana sounds except miss and miss1 are pitched normally in the // katana sounds except miss and miss1 are pitched normally in the
// as-is sound files. // as-is sound files.
typedef enum
{
SNDP_AK47_FIRE,
SNDP_AKIMBOCOLTS_FIRE,
SNDP_BARRETTM82_FIRE,
SNDP_BENELLIM3_FIRE,
SNDP_BERETTA_FIRE,
SNDP_BERETTA_FIRE_SIL,
SNDP_CONTENDERG2_FIRE,
SNDP_DESERTEAGLE_FIRE,
SNDP_DESERTEAGLE_FIRE_SIL,
SNDP_FIVESEVEN_FIRE,
SNDP_FIVESEVEN_FIRE_SIL,
SNDP_GLOCK18_FIRE,
SNDP_GLOCK18_FIRE_SIL,
SNDP_GLOCK20_FIRE,
SNDP_GLOCK20_FIRE_SIL,
SNDP_HKPDW_FIRE,
SNDP_HKPDW_FIRE_SIL,
SNDP_KATANA_MISS,
SNDP_KATANA_MISS1,
SNDP_M4A1_FIRE,
SNDP_M4A1_FIRE_SIL,
SNDP_M16A4_FIRE,
SNDP_M60_FIRE,
SNDP_MAC10_FIRE,
SNDP_MAC10_FIRE_SIL,
SNDP_MINIUZI_FIRE,
SNDP_MINIUZI_FIRE_SIL,
SNDP_MOSSBERG500_FIRE,
SNDP_MP5K_FIRE,
SNDP_MP5K_FIRE_SIL,
SNDP_MP5SD_FIRE,
SNDP_RAGINGBULL_FIRE,
SNDP_RUGERMK1_FIRE,
SNDP_SAWEDOFF_FIRE,
SNDP_SKORPION_FIRE,
SNDP_SOCOMMK23_FIRE,
SNDP_SOCOMMK23_FIRE_SIL,
SNDP_SPAS12_FIRE,
SNDP_STEYRAUG_FIRE,
SNDP_STEYRAUG_FIRE_SIL,
SNDP_STEYRTMP_FIRE,
SNDP_STEYRTMP_FIRE_SIL,
SNDP_UMP_FIRE,
SNDP_UMP_FIRE_SIL,
SNDP_USAS12_FIRE/*,
SNDP_EXPLODE,
SNDP_EXPLODE1,
SNDP_EXPLODE2,
SNDP_EXPLODE3,
SNDP_EXPLODE4
*/
} sfx_pitched_t;
//#define SOUNDPITCHED_SEND_ALL_DEBUG
void void
@ -109,6 +56,8 @@ SoundPitched_Channel_Send(entity ent, int id, float chan)
#endif #endif
} }
#ifdef CLIENT #ifdef CLIENT
const string sfx_pitched_s[] = const string sfx_pitched_s[] =
{ {
@ -156,13 +105,12 @@ const string sfx_pitched_s[] =
"weapons/tmp/fire-sil.wav", "weapons/tmp/fire-sil.wav",
"weapons/ump/ump-fire.wav", "weapons/ump/ump-fire.wav",
"weapons/ump/ump-fire-sil.wav", "weapons/ump/ump-fire-sil.wav",
"weapons/usas/usas-fire.wav"/*, "weapons/usas/usas-fire.wav",
"explo/explode.wav", "explo/explode.wav",
"explo/explode1.wav", "explo/explode1.wav",
"explo/explode2.wav", "explo/explode2.wav",
"explo/explode3.wav", "explo/explode3.wav",
"explo/explode4.wav" "explo/explode4.wav"
*/
}; };
void void
@ -177,6 +125,8 @@ SoundPitched_Receive(void)
sound(ent, CHAN_WEAPON, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW); sound(ent, CHAN_WEAPON, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW);
} }
#ifndef SOUNDPITCHED_SEND_ALL_DEBUG
void void
SoundPitched_Channel_Receive(void) SoundPitched_Channel_Receive(void)
{ {
@ -188,7 +138,9 @@ SoundPitched_Channel_Receive(void)
sound(ent, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW); sound(ent, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW);
} }
/*
#else
// ISSUE: sounds seem to play only for the entity that called for // ISSUE: sounds seem to play only for the entity that called for
// the message to be played from serverside. If it's a spawned entity // the message to be played from serverside. If it's a spawned entity
// (like a grenade sending itself to make the explosion sound), no player // (like a grenade sending itself to make the explosion sound), no player
@ -217,6 +169,7 @@ SoundPitched_Channel_Receive(void)
// sound(ent, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW); // sound(ent, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW);
sound(self, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW); sound(self, chan, sfx_pitched_s[id], 1.0f, ATTN_NORM, 400, SOUNDFLAG_FOLLOW);
} }
*/
#endif #endif// SOUNDPITCHED_SEND_ALL_DEBUG
#endif// CLIENT

View File

@ -80,7 +80,7 @@
#endif #endif
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// situational, see TSWorldGun and TSThrownProjectile. // situational, see CTSWorldGun and CTSThrownProjectile.
// (consider unpacking, this is kinda unnecessary) // (consider unpacking, this is kinda unnecessary)
// anywhere in inventory_logic.qc still do something like that?? I forget. // anywhere in inventory_logic.qc still do something like that?? I forget.
#define COPYVARFROM(varName) myInfo.##varName = tempRef.##varName; #define COPYVARFROM(varName) myInfo.##varName = tempRef.##varName;

View File

@ -772,7 +772,10 @@ typedef struct{
//TODO. Is extern'ing these earlier possible? //TODO. Is extern'ing these earlier possible?
ammodata_t* ary_ammoData[AMMO_ID::LAST_ID]; ammodata_t* ary_ammoData[AMMO_ID::LAST_ID];
#ifdef CLIENT
shellejectdata_t* ary_shellEjectData[SHELLEJECT_ID::LAST_ID]; shellejectdata_t* ary_shellEjectData[SHELLEJECT_ID::LAST_ID];
muzzleflashdata_t* ary_muzzleFlashData[MUZZLEFLASH_ID::LAST_ID];
#endif
//weapondata_normal_t* ary_weaponData[WEAPON_ID::LAST_ID]; //weapondata_normal_t* ary_weaponData[WEAPON_ID::LAST_ID];
//Void pointer should be fine, right? Cast to the right weapondata_ struct above (typeID tells what that is). //Void pointer should be fine, right? Cast to the right weapondata_ struct above (typeID tells what that is).
@ -847,7 +850,8 @@ void weapon_gun_onDrawHUD(player pl, weapondata_gun_t* basePRef, weapondynamic_t
void weapon_throwable_onDrawHUD(player pl, weapondata_throwable_t* basePRef, weapondynamic_t arg_thisWeapon); void weapon_throwable_onDrawHUD(player pl, weapondata_throwable_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t arg_thisWeapon); void weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_ejectShell(int arg_shellEjectType); void weapon_ShowMuzzleFlash(int arg_muzzleFlashTypeID);
void weapon_EjectShell(int arg_shellEjectType);
void weapon_precache(weapondata_basic_t* basePRef); void weapon_precache(weapondata_basic_t* basePRef);
@ -948,10 +952,11 @@ int getAmmoTypeOfWeapon(int arg_weaponID);
#ifdef CLIENT #ifdef CLIENT
void viewEv_playShotgunInsertShellSound(void); void viewEv_playShotgunInsertShellSound(void);
// TEMP DUMMY
// dummy
void w_ejectshell_pistol(void){}; void w_ejectshell_pistol(void){};
void viewEv_weapon_ejectShell(void); void viewEv_weapon_EjectShell(void);
void copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src); void copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src);
void copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src); void copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src);

View File

@ -497,8 +497,7 @@ weapon_shotgun_reload(
} }
pl.isChangingIronsight = FALSE; pl.isChangingIronsight = FALSE;
pl.currentZoomChoice = -1; pl.resetZoom();
pl.setZoom(1.00f);
pl.aryNextBurstShotTime_softLength = 0; pl.aryNextBurstShotTime_softLength = 0;
pl.aryNextBurstShotTime_listenIndex = -1; pl.aryNextBurstShotTime_listenIndex = -1;
@ -1364,8 +1363,7 @@ weapon_gun_Reload(
} }
pl.isChangingIronsight = FALSE; pl.isChangingIronsight = FALSE;
pl.currentZoomChoice = -1; pl.resetZoom();
pl.setZoom(1.00f);
pl.aryNextBurstShotTime_softLength = 0; pl.aryNextBurstShotTime_softLength = 0;
pl.aryNextBurstShotTime_listenIndex = -1; pl.aryNextBurstShotTime_listenIndex = -1;
pl.isReloading = TRUE; pl.isReloading = TRUE;
@ -1408,8 +1406,7 @@ weapon_gun_Reload_CustomSequence(
} }
pl.isChangingIronsight = FALSE; pl.isChangingIronsight = FALSE;
pl.currentZoomChoice = -1; pl.resetZoom();
pl.setZoom(1.00f);
pl.aryNextBurstShotTime_softLength = 0; pl.aryNextBurstShotTime_softLength = 0;
pl.aryNextBurstShotTime_listenIndex = -1; pl.aryNextBurstShotTime_listenIndex = -1;
pl.isReloading = TRUE; pl.isReloading = TRUE;
@ -1455,8 +1452,7 @@ weapon_ironsight_Reload(
} }
pl.isChangingIronsight = FALSE; pl.isChangingIronsight = FALSE;
pl.currentZoomChoice = -1; pl.resetZoom();
pl.setZoom(1.00f);
pl.aryNextBurstShotTime_softLength = 0; pl.aryNextBurstShotTime_softLength = 0;
pl.aryNextBurstShotTime_listenIndex = -1; pl.aryNextBurstShotTime_listenIndex = -1;
pl.isReloading = TRUE; pl.isReloading = TRUE;
@ -1830,16 +1826,33 @@ weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t
}// weapon_throwable_onDrawHUD }// weapon_throwable_onDrawHUD
void
weapon_ShowMuzzleFlash(int arg_muzzleFlashTypeID){
#ifdef CLIENT
if(arg_muzzleFlashTypeID != MUZZLEFLASH_ID::NONE){
muzzleflashdata_t* tempRef = ary_muzzleFlashData[arg_muzzleFlashTypeID];
View_ShowMuzzleflash((*tempRef).iSpritePrecacheID);
}
#else
// anything for other players to see, or will this be per animation in clientside rendering
// (player predraw) for whoever sees another player firing?
#endif
}
// Not to be confused with the clientside-only event "viewEv_weapon_ejectShell".
// Not to be confused with the clientside-only event "viewEv_weapon_EjectShell".
// This is called by weapons to add the event, handles setting the shell-type global // This is called by weapons to add the event, handles setting the shell-type global
// for it to see. If shell-ejects are done serverside, that would not be an amazing // for it to see. If shell-ejects are done serverside, that would not be an amazing
// idea. Per-player would be better. // idea. Per-player would be better.
void weapon_ejectShell(int arg_shellEjectType){ void
weapon_EjectShell(int arg_shellEjectType)
{
#ifdef CLIENT #ifdef CLIENT
player pl = (player)self; player pl = (player)self;
pl.iShellEjectType = arg_shellEjectType; pl.iShellEjectType = arg_shellEjectType;
View_AddEvent(viewEv_weapon_ejectShell, 0.0f); View_AddEvent(viewEv_weapon_EjectShell, 0.0f);
#else #else
// anything for the playermodel? Also only do that for all players except the // anything for the playermodel? Also only do that for all players except the
// localplayer if using a viewmodel. // localplayer if using a viewmodel.
@ -1848,11 +1861,14 @@ void weapon_ejectShell(int arg_shellEjectType){
#endif #endif
} }
// Precache models and the HUD icon given in FreeTS weapondata. // Precache models and the HUD icon given in FreeTS weapondata.
// Weapon sounds and anything else not in the struct shuold be precached // Weapon sounds and anything else not in the struct shuold be precached
// in the weapon's own precache method or globally (precache.qc) if reused // in the weapon's own precache method or globally (precache.qc) if reused
// between different weapons like shell models/sounds. // between different weapons like shell models/sounds.
void weapon_precache(weapondata_basic_t* basePRef){ void
weapon_precache(weapondata_basic_t* basePRef)
{
#ifdef SERVER #ifdef SERVER
if((*basePRef).sWorldModelPath != NULL){ if((*basePRef).sWorldModelPath != NULL){
precache_model((*basePRef).sWorldModelPath); precache_model((*basePRef).sWorldModelPath);
@ -1886,7 +1902,9 @@ void weapon_gun_updateAmmo(player pl, weapondata_gun_t* basePRef, weapondynamic_
} }
*/ */
// Easier way for the caller. // Easier way for the caller.
void weapon_gun_updateAmmo(player pl, int weaponTypeID){ void
weapon_gun_updateAmmo(player pl, int weaponTypeID)
{
if(pl.inventoryEquippedIndex != -1){ if(pl.inventoryEquippedIndex != -1){
weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex];
// no need to hardcode ammo names when they're given by weapondata // no need to hardcode ammo names when they're given by weapondata
@ -2110,35 +2128,6 @@ setupWeaponData(void){
ary_shotgunExtra[SHOTGUN_EXTRA_ID::SPAS12] = &weapon_spas12_shotgunExtra; ary_shotgunExtra[SHOTGUN_EXTRA_ID::SPAS12] = &weapon_spas12_shotgunExtra;
ASSIGN_AMMODATA(NONE)
ASSIGN_AMMODATA(_9X19MM)
ASSIGN_AMMODATA(_45ACP)
ASSIGN_AMMODATA(_P50AE)
ASSIGN_AMMODATA(_5P7X28)
ASSIGN_AMMODATA(_10MMAUTO)
ASSIGN_AMMODATA(_P22LR)
ASSIGN_AMMODATA(_P454CASULL)
ASSIGN_AMMODATA(_5P56NATO)
ASSIGN_AMMODATA(_7P62X39MM)
ASSIGN_AMMODATA(_50BMG)
ASSIGN_AMMODATA(_SHELLS)
ASSIGN_AMMODATA(_32ACP)
ASSIGN_AMMODATA(_7P62X51MM)
ASSIGN_SHELLEJECTDATA(NONE)
ASSIGN_SHELLEJECTDATA(_56)
ASSIGN_SHELLEJECTDATA(_556)
ASSIGN_SHELLEJECTDATA(_22)
ASSIGN_SHELLEJECTDATA(_9MM)
ASSIGN_SHELLEJECTDATA(_GENERIC)
ASSIGN_SHELLEJECTDATA(_SHOTGUN)
ASSIGN_SHELLEJECTDATA(_SHOTGUN_BLUE)
ASSIGN_SHELLEJECTDATA(_SHOTGUN_GOLD)
}//setupWeaponData }//setupWeaponData
@ -2249,11 +2238,15 @@ viewEv_playShotgunInsertShellSound(void)
} }
void void
viewEv_weapon_ejectShell(void) viewEv_weapon_EjectShell(void)
{ {
player pl = (player)pSeat->m_ePlayer; player pl = (player)pSeat->m_ePlayer;
CShellEject::generate(pl.iShellEjectType); // TODO - how about a first-person check? Doesn't make sense if in thirdperson.
}//viewEv_weapon_ejectShell // Although that might've been needed earlier unless this event-thing works fine for being
// a playermodel too. Players other than the local one being rendered and needing to drop
// shells, that sounds like a whole other story
CTSShellEject::generateForViewmodel(pl.iShellEjectType);
}
// also clientside only, dealing with configs // also clientside only, dealing with configs

View File

@ -159,8 +159,8 @@ w_ak47_primary(void)
} }
#ifdef CLIENT #ifdef CLIENT
View_ShowMuzzleflash(MUZZLE_SMALL); weapon_ShowMuzzleFlash(MUZZLEFLASH_ID::RIFLE);
View_AddEvent(w_ejectshell_pistol, 0.0f); weapon_EjectShell(SHELLEJECT_ID::_56);
#endif #endif
weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::AK47], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::AK47], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT);
@ -189,21 +189,16 @@ w_ak47_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ pl.iZoomLevel = (pl.iZoomLevel + 1) % 3;
case -1:{ switch(pl.iZoomLevel){
//pl.viewzoom = 32/80;
pl.setZoom(0.4f);
pl.currentZoomChoice++;
break;}
case 0:{ case 0:{
//pl.viewzoom = 13/80; pl.setZoom(1.00f);
pl.setZoom(0.1625f);
pl.currentZoomChoice++;
break;} break;}
case 1:{ case 1:{
//pl.viewzoom = 0; pl.setZoom(0.4f);
pl.setZoom(1.00f); break;}
pl.currentZoomChoice = -1; case 2:{
pl.setZoom(0.1625f);
break;} break;}
}//END OF switch }//END OF switch

View File

@ -182,21 +182,21 @@ w_barrettm82_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 32/80; //pl.viewzoom = 32/80;
pl.setZoom(0.4f); pl.setZoom(0.4f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 8/80; //pl.viewzoom = 8/80;
pl.setZoom(0.10f); pl.setZoom(0.10f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 1:{ case 1:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -254,15 +254,15 @@ w_benellim3_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 40/80; //pl.viewzoom = 40/80;
pl.setZoom(0.5f); pl.setZoom(0.5f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -185,7 +185,7 @@ w_combatknife_secondary(void)
arg_thisWeapon.forceBodygroup1Submodel = 1; //reset, new knife is not bloody. arg_thisWeapon.forceBodygroup1Submodel = 1; //reset, new knife is not bloody.
TS_Weapons_PlaySoundDirect(pl, "weapons/knife/knife_miss.wav"); TS_Weapons_PlaySoundDirect(pl, "weapons/knife/knife_miss.wav");
#ifdef SERVER #ifdef SERVER
TSThrownProjectile::generate2(pl, arg_thisWeapon); CTSThrownProjectile::generate2(pl, arg_thisWeapon);
#endif #endif
} }

View File

@ -182,16 +182,16 @@ w_contenderg2_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 26/80; //pl.viewzoom = 26/80;
pl.setZoom(0.325f); pl.setZoom(0.325f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -226,15 +226,15 @@ w_deserteagle_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 60/80; //pl.viewzoom = 60/80;
pl.setZoom(0.75f); pl.setZoom(0.75f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -173,14 +173,11 @@ w_glock18_primary(void)
TS_Weapons_ViewAnimation(weaponseq_glock18::shootempty, (31.0f/30.0f) ); TS_Weapons_ViewAnimation(weaponseq_glock18::shootempty, (31.0f/30.0f) );
} }
// TODO.
#ifdef CLIENT // For now using lazy HL defaults for muzzle flashes, I'll leave
View_ShowMuzzleflash(MUZZLE_SMALL); // TS's own muzzle flashes, whichever ones are even used, for another time
// TODO: weapon_ShowMuzzleFlash(MUZZLEFLASH_ID::SMALL);
//weapon_showMuzzleFlash(MUZZLE_SMALL); weapon_EjectShell(SHELLEJECT_ID::_9MM);
#endif
weapon_ejectShell(SHELLEJECT_ID::_9MM);
weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::GLOCK18], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::GLOCK18], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT);

View File

@ -189,16 +189,16 @@ w_hkpdw_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 40/80; //pl.viewzoom = 40/80;
pl.setZoom(0.50f); pl.setZoom(0.50f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -241,21 +241,21 @@ w_m16a4_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 32/80; //pl.viewzoom = 32/80;
pl.setZoom(0.4f); pl.setZoom(0.4f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 8/80; //pl.viewzoom = 8/80;
pl.setZoom(0.10f); pl.setZoom(0.10f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 1:{ case 1:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -246,16 +246,16 @@ w_m4a1_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 26/80; //pl.viewzoom = 26/80;
pl.setZoom(0.325f); pl.setZoom(0.325f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -27,7 +27,7 @@ void weapon_m61grenade_spawnProjectile(player pl, weapondynamic_t arg_thisWeapon
vector vGrenadeOrigin = (pl.origin + pl.view_ofs) + (v_forward * 16); vector vGrenadeOrigin = (pl.origin + pl.view_ofs) + (v_forward * 16);
vector vDir = aim ( pl, 100000 ); vector vDir = aim ( pl, 100000 );
TSGrenadeProjectile::generate(pl, vGrenadeOrigin, vDir, v_forward, WEAPON_ID::M61GRENADE); TS_GrenadeProjectile::generate(pl, vGrenadeOrigin, vDir, v_forward, WEAPON_ID::M61GRENADE);
} }
#endif #endif
@ -239,7 +239,7 @@ w_m61grenade_precache(void)
weapon_precache(ary_weaponData[WEAPON_ID::M61GRENADE]); weapon_precache(ary_weaponData[WEAPON_ID::M61GRENADE]);
#ifdef SERVER #ifdef SERVER
// grenade-bounce and explode sounds are precached in // grenade-bounce and explode sounds are precached in
// TSGrenadeProjectile::precache and fx_ts_explosion_grenade_Init respectively // TS_GrenadeProjectile::precache and fx_ts_explosion_grenade_Init respectively
//precache_sound("weapons/gr_pull.wav"); //precache_sound("weapons/gr_pull.wav");
//precache_sound("weapons/gr_safe.wav"); //precache_sound("weapons/gr_safe.wav");
#else #else

View File

@ -230,16 +230,16 @@ w_mp5k_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 32/80; //pl.viewzoom = 32/80;
pl.setZoom(0.40f); pl.setZoom(0.40f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -205,16 +205,16 @@ w_mp5sd_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 32/80; //pl.viewzoom = 32/80;
pl.setZoom(0.40f); pl.setZoom(0.40f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -178,16 +178,16 @@ w_ragingbull_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 40/80; //pl.viewzoom = 40/80;
pl.setZoom(0.5f); pl.setZoom(0.5f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -177,7 +177,7 @@ w_sealknife_secondary(void)
arg_thisWeapon.forceBodygroup1Submodel = 1; //reset, new knife is not bloody. arg_thisWeapon.forceBodygroup1Submodel = 1; //reset, new knife is not bloody.
TS_Weapons_PlaySoundDirect(pl, "weapons/knife/knife_miss.wav"); TS_Weapons_PlaySoundDirect(pl, "weapons/knife/knife_miss.wav");
#ifdef SERVER #ifdef SERVER
TSThrownProjectile::generate2(pl, arg_thisWeapon); CTSThrownProjectile::generate2(pl, arg_thisWeapon);
#endif #endif
} }

View File

@ -181,16 +181,16 @@ w_steyraug_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 40/80; //pl.viewzoom = 40/80;
pl.setZoom(0.5f); pl.setZoom(0.5f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -191,16 +191,16 @@ w_ump_secondary(void)
if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){ if(arg_thisWeapon.iBitsUpgrade & BITS_WEAPONOPT_SCOPE){
// toggle through the zoom. // toggle through the zoom.
switch(pl.currentZoomChoice){ switch(pl.iZoomLevel){
case -1:{ case -1:{
//pl.viewzoom = 40/80; //pl.viewzoom = 40/80;
pl.setZoom(0.50f); pl.setZoom(0.50f);
pl.currentZoomChoice++; pl.iZoomLevel++;
break;} break;}
case 0:{ case 0:{
//pl.viewzoom = 0; //pl.viewzoom = 0;
pl.setZoom(1.00f); pl.setZoom(1.00f);
pl.currentZoomChoice = -1; pl.iZoomLevel = -1;
break;} break;}
}//END OF switch }//END OF switch

View File

@ -1,7 +1,11 @@
// And yes, pitch is a decimal, 0.5 to 4.0 is likely the allowed range
// Unfortuantely this isn't quite there, the greatest pitch mod allowed
// this way is 200%. Strange, have to use sound_pitched.qc instead
//
fx.ts_explosion_grenade fx.ts_explosion_grenade
{ {
pitch 400 pitch 4
shakes 2.7 shakes 3.5
sample explo/explode.wav sample explo/explode.wav
sample explo/explode1.wav sample explo/explode1.wav
sample explo/explode2.wav sample explo/explode2.wav