grenade and ejected shell entity, unused FX cleanup, texture hit sounds restored, network issue noticed
This commit is contained in:
parent
a0a70e7c9e
commit
bfafbec9ad
|
@ -0,0 +1,13 @@
|
|||
|
||||
// for ejected shells to use
|
||||
class CShellEject{
|
||||
// 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
|
||||
// try and guess how that works knowing FTE
|
||||
int iShellEjectType;
|
||||
|
||||
void(void) CShellEject;
|
||||
static void(void) precache;
|
||||
static CShellEject(int arg_iShellEjectType) generate;
|
||||
virtual void(void) touch;
|
||||
};
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
void
|
||||
CShellEject::CShellEject(void){
|
||||
}
|
||||
|
||||
void
|
||||
CShellEject::precache(void){
|
||||
Sound_Precache("modelevent_shell.land");
|
||||
Sound_Precache("modelevent_shotgunshell.land");
|
||||
// no need, handled in soundscript preaches
|
||||
/*
|
||||
precache_sound("weapons/shell.wav");
|
||||
precache_sound("weapons/sshell.wav");
|
||||
precache_sound("weapons/sshell1.wav");
|
||||
precache_sound("weapons/sshell2.wav");
|
||||
precache_sound("weapons/sshell3.wav");
|
||||
*/
|
||||
|
||||
// nearly identical..?
|
||||
precache_model("models/56_shell.mdl");
|
||||
precache_model("models/556_shell.mdl");
|
||||
|
||||
// identical..?
|
||||
precache_model("models/22_shell.mdl");
|
||||
precache_model("models/9mm_shell.mdl");
|
||||
precache_model("models/shell.mdl");
|
||||
|
||||
precache_model("models/shotgun_shell.mdl");
|
||||
precache_model("models/shotgun_shell_blue.mdl");
|
||||
precache_model("models/shotgun_shell_gold.mdl");
|
||||
|
||||
}
|
||||
|
||||
// The practical constructor, manually call this after spawning.
|
||||
// NOTE: assumes pSeat->m_eViewModel is valid for involving in determining
|
||||
// origin, angles, velocity
|
||||
CShellEject
|
||||
CShellEject::generate(int arg_iShellEjectType){
|
||||
CShellEject eShell = spawn(CShellEject);
|
||||
|
||||
vector vOrigin; // tempvar
|
||||
|
||||
eShell.iShellEjectType = arg_iShellEjectType;
|
||||
|
||||
//setmodel(eShell, "models/shell.mdl");
|
||||
shellejectdata_t* mySED = ary_shellEjectData[eShell.iShellEjectType];
|
||||
setmodel(eShell, (*mySED).sModelPath);
|
||||
|
||||
eShell.solid = SOLID_BBOX;
|
||||
eShell.movetype = MOVETYPE_BOUNCE;
|
||||
eShell.drawmask = MASK_ENGINE;
|
||||
eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0];
|
||||
eShell.velocity = pSeat->m_vecPredictedVelocity;
|
||||
|
||||
makevectors(pSeat->m_eViewModel.angles);
|
||||
eShell.velocity += (v_forward * 0);
|
||||
eShell.velocity += (v_right * 80);
|
||||
eShell.velocity += (v_up * 100);
|
||||
|
||||
eShell.avelocity = [0,45,900];
|
||||
eShell.think = entity_removeSelf;
|
||||
// shells last longer than 2.5 seconds in TS, going for 10 for now
|
||||
eShell.nextthink = time + 10.0f;
|
||||
setsize(eShell, [0,0,0], [0,0,0]);
|
||||
|
||||
// TODO: I think attachments supply a direction too, fuzzy on the details,
|
||||
// player predraw (client/player.qc) definitely has something like that to put the
|
||||
// viewmodel laser-start or flashlight sprite glow effect in the right place.
|
||||
|
||||
// FreeHL way (forget all the rest if so)
|
||||
vOrigin = pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4);
|
||||
|
||||
/*
|
||||
// way #1
|
||||
//vOrigin = pSeat->m_eViewModel.origin;
|
||||
// way #2: old codebase way?
|
||||
//vOrigin = pSeat->m_vecPredictedOrigin + [0, 0, getstatf(STAT_VIEWHEIGHT)];
|
||||
|
||||
// way #3
|
||||
// "pSeat->m_iVMBones + 1" gets the first attachment, add more to get other
|
||||
// attachments, or places on the model that can be helpful to tie into
|
||||
// Although this is still making shell ejections happen at the end of the muzzle
|
||||
// and the other attachments just go further out?
|
||||
vector vOffset = gettaginfo(pSeat->m_eViewModel, pSeat->m_iVMBones + 1);
|
||||
printfline("WHAT?! %.2f %.2f %.2f", vOffset[0], vOffset[1], vOffset[2]);
|
||||
|
||||
// way #3a
|
||||
// assumes a vOrigin provided by earlier
|
||||
//vOrigin += (v_forward * vOffset[0]);
|
||||
//vOrigin += (v_right * -vOffset[1]);
|
||||
//vOrigin += (v_up * vOffset[2]) ;
|
||||
|
||||
// way #3b
|
||||
// or only be vOffset
|
||||
vOrigin = vOffset;
|
||||
*/
|
||||
setorigin(eShell, vOrigin);
|
||||
}
|
||||
|
||||
void CShellEject::touch(void){
|
||||
if(other == world){
|
||||
shellejectdata_t* mySED = ary_shellEjectData[iShellEjectType];
|
||||
// self? this? Is there a difference in this context?
|
||||
// TODO: should shell-toucch sounds have reduced volume? Unsure
|
||||
Sound_Play(this, CHAN_BODY, (*mySED).sTouchSound);
|
||||
}
|
||||
}
|
|
@ -73,6 +73,15 @@ ClientGame_EventParse(float fHeader)
|
|||
|
||||
FX_Explosion(vExploPos);
|
||||
break;
|
||||
case EVENT_TS::FX_TS_EXPLOSION_GRENADE:
|
||||
vector vExploPos2;
|
||||
|
||||
vExploPos2[0] = readcoord();
|
||||
vExploPos2[1] = readcoord();
|
||||
vExploPos2[2] = readcoord();
|
||||
|
||||
FX_TS_Explosion_Grenade(vExploPos2);
|
||||
break;
|
||||
case EV_MODELGIB:
|
||||
vector vecPos;
|
||||
vecPos[0] = readcoord();
|
||||
|
@ -178,20 +187,6 @@ ClientGame_EventParse(float fHeader)
|
|||
case EVENT_TS::PLAYER_DEATH:
|
||||
EV_PlayerDeath();
|
||||
break;
|
||||
case EVENT_TS::EFFECT_EXPLOSION:
|
||||
vecOrigin[0] = readcoord();
|
||||
vecOrigin[1] = readcoord();
|
||||
vecOrigin[2] = readcoord();
|
||||
EV_Effect_Explosion( vecOrigin );
|
||||
break;
|
||||
case EVENT_TS::EFFECT_SHAKE:
|
||||
iType = readbyte();
|
||||
EV_Effect_ScreenShake( iType );
|
||||
break;
|
||||
case EVENT_TS::TEST:
|
||||
//printfline("EVENT_TS::TEST HAPPENED");
|
||||
//clearscene();
|
||||
break;
|
||||
case EVENT_TS::SOUNDPITCHED:
|
||||
SoundPitched_Receive();
|
||||
break;
|
||||
|
@ -200,12 +195,16 @@ ClientGame_EventParse(float fHeader)
|
|||
break;
|
||||
/*
|
||||
// can this even happen anymore?
|
||||
// If a drop-weapon call can be signaled by the server, not shared with the client & server
|
||||
// reaching a drop call independently, then yes.
|
||||
// If a drop-weapon call can be signaled by the server, not shared with th
|
||||
// client and server reaching a drop call independently, then yes.
|
||||
case EVENT_TS::DROP_WEAPON:
|
||||
EV_TS_playerDropWeapon(pl);
|
||||
break;
|
||||
*/
|
||||
case EVENT_TS::TEST:
|
||||
//printfline("EVENT_TS::TEST HAPPENED");
|
||||
//clearscene();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,18 +170,23 @@ ClientGame_RendererRestart(string rstr)
|
|||
}
|
||||
|
||||
|
||||
|
||||
//TAGGG - Hook into precache.qc
|
||||
// Hook into precache.qc
|
||||
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();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -472,7 +472,7 @@ Player_PreDraw(base_player pp, int thirdperson)
|
|||
makevectors(angView);
|
||||
|
||||
//trace_endpos += trace_plane_normal * fsizeDot[0]/6;
|
||||
R_BeginPolygon("sprites/new/glow02.spr_0.tga", 1, 0);
|
||||
R_BeginPolygon("sprites/glow02.spr_0.tga", 1, 0);
|
||||
R_PolygonVertex(flashPos + v_right * fsizeFlashlightMuzzleGlow[0] - v_up * fsizeFlashlightMuzzleGlow[1], [1,1], [1,1,1], 0.45f);
|
||||
R_PolygonVertex(flashPos - v_right * fsizeFlashlightMuzzleGlow[0] - v_up * fsizeFlashlightMuzzleGlow[1], [0,1], [1,1,1], 0.45f);
|
||||
R_PolygonVertex(flashPos - v_right * fsizeFlashlightMuzzleGlow[0] + v_up * fsizeFlashlightMuzzleGlow[1], [0,0], [1,1,1], 0.45f);
|
||||
|
@ -547,7 +547,7 @@ Player_PreDraw(base_player pp, int thirdperson)
|
|||
makevectors(angView);
|
||||
|
||||
//trace_endpos += trace_plane_normal * fsizeDot[0]/6;
|
||||
R_BeginPolygon("sprites/new/glow02.spr_0.tga", 1, 0);
|
||||
R_BeginPolygon("sprites/glow02.spr_0.tga", 1, 0);
|
||||
R_PolygonVertex(flashPos + v_right * fsizeFlashlightMuzzleGlow[0] - v_up * fsizeFlashlightMuzzleGlow[1], [1,1], [1,1,1], 0.45f);
|
||||
R_PolygonVertex(flashPos - v_right * fsizeFlashlightMuzzleGlow[0] - v_up * fsizeFlashlightMuzzleGlow[1], [0,1], [1,1,1], 0.45f);
|
||||
R_PolygonVertex(flashPos - v_right * fsizeFlashlightMuzzleGlow[0] + v_up * fsizeFlashlightMuzzleGlow[1], [0,0], [1,1,1], 0.45f);
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
|
||||
var int PART_EXPLOSION;
|
||||
|
||||
//var int MUZZLE_CUSTOM;
|
||||
|
||||
void ClientGame_Precache(void);
|
||||
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@ void ClientGame_Precache(void){
|
|||
printfline("***ClientGame_Precache called***");
|
||||
SharedGame_Precache();
|
||||
|
||||
// these might be redundant with shell sounds being precached, but then
|
||||
// again some are from the valve gamemod
|
||||
Sound_Precache("modelevent_shell.land");
|
||||
Sound_Precache("modelevent_shotgunshell.land");
|
||||
|
||||
// Example of loading a muzzle flash sprite
|
||||
//MUZZLE_CUSTOM = (int)getmodelindex("sprites/muzzleCUSTOM.spr");
|
||||
|
||||
|
||||
CShellEject::precache();
|
||||
|
||||
//TAGGG - From FreeHL.
|
||||
// Does TS use something else?
|
||||
|
@ -22,10 +24,6 @@ void ClientGame_Precache(void){
|
|||
|
||||
precache_sound("weapons/draw.wav");
|
||||
|
||||
|
||||
PART_EXPLOSION = particleeffectnum("explosion.explosion_grenade");
|
||||
|
||||
|
||||
precache_model("sprites/mapsprites/ts_gpc1.spr");
|
||||
precache_model("sprites/mapsprites/ts_gpc2.spr");
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#define CSQC
|
||||
#define CLIENT
|
||||
#define TS
|
||||
//TAGGG - do we want this? FreeHL had it I think, FreeCS definitely does
|
||||
#define CLASSIC_VGUI
|
||||
#define GS_RENDERFX
|
||||
|
||||
|
@ -23,7 +22,6 @@
|
|||
../../../src/shared/defs.h
|
||||
../../../src/client/defs.h
|
||||
|
||||
//TAGGG - NEW
|
||||
../shared/util.h
|
||||
util.h
|
||||
../shared/defs.h
|
||||
|
@ -33,11 +31,11 @@ defs.h
|
|||
../shared/weapons.h
|
||||
../shared/player.h
|
||||
../shared/powerup.h
|
||||
entity/shelleject.h
|
||||
|
||||
clientinfo.h
|
||||
seatlocal.h
|
||||
|
||||
//TAGGG - NEW
|
||||
precache.h
|
||||
ui.h
|
||||
ui_eventgrabber.h
|
||||
|
@ -60,8 +58,8 @@ hud.h
|
|||
|
||||
../shared/player.qc
|
||||
../shared/inventory_logic.qc
|
||||
entity/shelleject.qc
|
||||
|
||||
//TAGGG - NEW
|
||||
// old location of UI draw stuff
|
||||
|
||||
hud_crosshair.qc
|
||||
|
@ -95,7 +93,6 @@ scoreboard.qc
|
|||
../../../base/src/client/modelevent.qc
|
||||
|
||||
|
||||
//TAGGG - NEW
|
||||
util.qc
|
||||
precache.qc
|
||||
//../_base/client/voice.c
|
||||
|
|
|
@ -325,8 +325,12 @@ UI_determineDrawGlobals(void){
|
|||
void
|
||||
UI_Draw(void)
|
||||
{
|
||||
if ( pSeatLocal->m_flUI_Display == UI_SCREEN::NONE ) {
|
||||
setcursormode( FALSE );
|
||||
if(pSeatLocal->m_flUI_Display == UI_SCREEN::NONE ){
|
||||
// Not effective for the new version of game executable fteglqw64.exe?
|
||||
// Well that's just dandy
|
||||
// (this is supposed to let clicking after closing the buy menu without moving the
|
||||
// mouse mouse work).
|
||||
setcursormode(FALSE, "gfx/cursor", [0,0,0], 1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,5 @@ void View_RoutineCheck(void);
|
|||
void View_UpdateWeapon(entity vm, entity mflash);
|
||||
void resetViewModel(void);
|
||||
void View_HandleZoom(void);
|
||||
vector View_ShakeCalculate(vector vecInputAngles);
|
||||
void View_ShakeCreate(int iLevel);
|
||||
|
||||
void View_ShowMuzzleflash(int index);
|
||||
|
|
|
@ -15,17 +15,15 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
// Also, Nuclide offers Weapons_SetGeomset for calling "setcustomskin" too, but one string
|
||||
// at a time. Don't really know if that way or the current way (cumulative string for
|
||||
// many commands delimited in one setcustomskin call) is any better, so leaving this as
|
||||
// it is for now.
|
||||
|
||||
|
||||
|
||||
// NEW
|
||||
void TS_SetViewModelFromStats(){
|
||||
|
||||
void
|
||||
TS_SetViewModelFromStats(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
entity vm = pSeat->m_eViewModel;
|
||||
entity mflash = pSeat->m_eMuzzleflash;
|
||||
|
@ -112,8 +110,9 @@ void TS_SetViewModelFromStats(){
|
|||
|
||||
|
||||
// On any frame, see if something about the current viewmodel needs to be changed
|
||||
void View_RoutineCheck(void){
|
||||
|
||||
void
|
||||
View_RoutineCheck(void)
|
||||
{
|
||||
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
entity vm = pSeat->m_eViewModel;
|
||||
|
@ -126,7 +125,6 @@ void View_RoutineCheck(void){
|
|||
|
||||
dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex];
|
||||
|
||||
|
||||
if(pl.prev_forceBodygroup1Submodel != dynaRef.forceBodygroup1Submodel){
|
||||
|
||||
if(dynaRef.forceBodygroup1Submodel > 0){
|
||||
|
@ -137,25 +135,40 @@ void View_RoutineCheck(void){
|
|||
pl.prev_forceBodygroup1Submodel = dynaRef.forceBodygroup1Submodel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}//View_RoutineCheck
|
||||
|
||||
|
||||
|
||||
// vm is pSeat->m_eViewModel passed along from Nuclide's View_DrawViewModel
|
||||
void
|
||||
View_UpdateWeapon(entity vm, entity mflash)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
|
||||
if(autocvar_cl_printoutspam == 1){
|
||||
printfline("STATUS: %i==%d - %i", pSeat->m_iLastWeapon, pl.activeweapon, pl.inventoryEquippedIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* only bother upon change */
|
||||
if (pSeat->m_iLastWeapon == pl.activeweapon) {
|
||||
|
||||
/*
|
||||
if(pl.activeweapon == 0 && pl.inventoryEquippedIndex != -1){
|
||||
// what??
|
||||
pl.setInventoryEquippedIndex(pl.inventoryEquippedIndex);
|
||||
}else{
|
||||
View_RoutineCheck();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
View_RoutineCheck();
|
||||
return;
|
||||
}
|
||||
printfline("View_UpdateWeapon: change detected: %i -> %d", pSeat->m_iLastWeapon, pl.activeweapon);
|
||||
printfline("and how about the others %d %i", pl.activeweapon, pl.inventoryEquippedIndex);
|
||||
|
||||
|
||||
pSeat->m_iOldWeapon = pSeat->m_iLastWeapon;
|
||||
pSeat->m_iLastWeapon = pl.activeweapon;
|
||||
|
@ -166,7 +179,6 @@ View_UpdateWeapon(entity vm, entity mflash)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
//printfline("View_UpdateWeapon: change: %d vs %d", pSeat->m_iLastWeapon, pl.activeweapon);
|
||||
|
||||
// Call this to do a few other things for any weapon change
|
||||
|
@ -178,6 +190,8 @@ View_UpdateWeapon(entity vm, entity mflash)
|
|||
Weapons_Draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//No longer a var! Oops
|
||||
//pSeat->m_iVMEjectBone = pSeat->m_iVMBones + 1;
|
||||
|
||||
|
@ -193,6 +207,10 @@ View_UpdateWeapon(entity vm, entity mflash)
|
|||
//TAGGG - NEW VAR.
|
||||
SAVE_STATE(pl.w_attack_akimbo_next);
|
||||
|
||||
//TAGGG - also new line. It is a good idea to reset the event
|
||||
// on changing models, right?
|
||||
pSeat->m_pEventCall = NULL;
|
||||
|
||||
skel_delete( mflash.skeletonindex );
|
||||
mflash.skeletonindex = skel_create( vm.modelindex );
|
||||
pSeat->m_iVMBones = skel_get_numbones( mflash.skeletonindex ) + 1;
|
||||
|
@ -202,18 +220,9 @@ View_UpdateWeapon(entity vm, entity mflash)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TAGGG - NEW METHODS
|
||||
void
|
||||
resetViewModel(void)
|
||||
{
|
||||
|
||||
//TAGGG - CRITICAL. NOT ANYMORE!!!
|
||||
//return;
|
||||
|
||||
|
||||
printfline("resetViewModel called.");
|
||||
|
||||
if(pSeat->m_ePlayer == NULL){
|
||||
|
@ -237,7 +246,7 @@ resetViewModel(void)
|
|||
pl.setInventoryEquippedIndex(-1); //do we have to?
|
||||
*/
|
||||
|
||||
}//END OF resetViewModel
|
||||
}// resetViewModel
|
||||
|
||||
|
||||
|
||||
|
@ -249,33 +258,6 @@ void View_HandleZoom(void){
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if(getplayerkeyvalue(player_localnum, "*spec") != "0"){
|
||||
|
||||
//TAGGG - CRITICAL.
|
||||
// WAIT! This is a spectator, so...? can we even trust pSeat->ePlayer to be a player?
|
||||
// Confusing.
|
||||
// That leads me to believe that either zoom-related vars should be
|
||||
// pSeat-><clienttdata> - specific, or not handled here at all.
|
||||
|
||||
// If our FOV was anything but 1, force it so.
|
||||
// Spectator mode instantly forgets any scope-related FOV mods.
|
||||
// Nuclide might not be calling setsensitivityscaler, so doing it here.
|
||||
// No problem if the setproperty is a little redundant as that might be happening.
|
||||
if(pl.flZoomLevel < 1.0 || pl.viewzoom < 1.0){
|
||||
pl.flZoomLerp = 0;
|
||||
pl.flZoomLevel = 1;
|
||||
pl.viewzoom = 1;
|
||||
setproperty(VF_AFOV, cvar("fov") * pl.flZoomLevel);
|
||||
setsensitivityscaler(pl.flZoomLevel);
|
||||
}
|
||||
// No further zoom logic
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//TAGGG - any references to STAT_VIEWZOOM are now garbage.
|
||||
// Rely on pl.flTargetZoom instead, it's sent to the client every frame
|
||||
// and should be handled serverside anyway.
|
||||
|
@ -320,34 +302,6 @@ void View_HandleZoom(void){
|
|||
}
|
||||
|
||||
|
||||
vector
|
||||
View_ShakeCalculate(vector vecInputAngles)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
if(pl == NULL)return vecInputAngles; //forget this
|
||||
|
||||
// you might not want to force this every frame unless you like vomiting.
|
||||
//pl.flViewShake = 2;
|
||||
|
||||
if (pl.flViewShake > 0.0f) {
|
||||
vecInputAngles[0] += (random() * pl.flViewShake) * 3;
|
||||
vecInputAngles[1] += (random() * pl.flViewShake) * 3;
|
||||
vecInputAngles[2] += (random() * pl.flViewShake) * 3;
|
||||
pl.flViewShake -= clframetime;
|
||||
}
|
||||
|
||||
return vecInputAngles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
View_ShakeCreate(int iLevel)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
pl.flViewShake = iLevel / 128;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TAGGG - NEW. Similar to Nuclide's provided "View_SetMuzzleflash", but also acts
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
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);
|
|
@ -0,0 +1,116 @@
|
|||
void
|
||||
TSGrenadeProjectile::TSGrenadeProjectile(void){
|
||||
}
|
||||
|
||||
void
|
||||
TSGrenadeProjectile::precache(void)
|
||||
{
|
||||
Sound_Precache("weapon_m61grenade.bounce");
|
||||
// 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
|
||||
}
|
||||
|
||||
TSGrenadeProjectile
|
||||
TSGrenadeProjectile::generate(
|
||||
player arg_player, vector arg_vOrigin, vector arg_vThrowDir,
|
||||
vector arg_vPlayerForward, int arg_weaponTypeID
|
||||
){
|
||||
TSGrenadeProjectile eNade = spawn(TSGrenadeProjectile);
|
||||
|
||||
weapondata_throwable_t* basicP = ((weapondata_throwable_t*)ary_weaponData[arg_weaponTypeID]);
|
||||
|
||||
setorigin(eNade, arg_vOrigin);
|
||||
setmodel(eNade, (*basicP).sWorldModelPath);
|
||||
setsize(eNade, [-1, -1, -1], [1, 1, 1]);
|
||||
|
||||
eNade.owner = arg_player;
|
||||
eNade.classname = "remove_me";
|
||||
eNade.solid = SOLID_TRIGGER; // This is so grenades will not get slowed down by windows they touch
|
||||
eNade.angles = vectoangles( arg_vThrowDir );
|
||||
|
||||
// TODO - CRITICAL.
|
||||
// Factor in wasToss, heldDuration (out of 3, small minimum from clicking without holding down while
|
||||
// some of the toss anim plays)?
|
||||
eNade.velocity = (arg_vThrowDir * 200); //was 1000
|
||||
|
||||
eNade.avelocity = (arg_vPlayerForward * 1000);
|
||||
eNade.movetype = MOVETYPE_BOUNCE;
|
||||
eNade.gravity = 0.5f;
|
||||
|
||||
eNade.think = TSGrenadeProjectile_Explode;
|
||||
eNade.nextthink = time + 3.0f;
|
||||
|
||||
return eNade;
|
||||
}
|
||||
|
||||
void
|
||||
TSGrenadeProjectile::touch(void){
|
||||
if ( other.solid == SOLID_TRIGGER ) {
|
||||
return;
|
||||
}
|
||||
if ( other == this.owner ) {
|
||||
return;
|
||||
}
|
||||
if ( ( other.classname == "func_breakable" ) && ( other.material == GSMATERIAL_GLASS ) ) {
|
||||
// this means, insta-break the breakable glass we hit.
|
||||
// Calling this BLUNT I guess? The grenade is really a rock at this point.
|
||||
Damage_Apply( other, this.owner, other.health, WEAPON_ID::M61GRENADE, DMG_BLUNT);
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_WEAPON, "weapon_m61grenade.bounce");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TSGrenadeProjectile_Explode(void){
|
||||
//float randomChoice;
|
||||
|
||||
// Also - don't worry about the shakes, sound script file for the
|
||||
// explosion sound has a shake parameter that handles that.
|
||||
// FX_Explosion also counts the sound to play.
|
||||
FX_TS_Explosion_Grenade_PlaySound(self);
|
||||
FX_TS_Explosion_Grenade(self.origin);
|
||||
|
||||
//!!! THIS IS THE COUNTERSTRIKE EFFECT.
|
||||
// Comment/uncomment as needed.
|
||||
// we redirect this to the new lines for TS. Easier to keep
|
||||
// the change to env_explosion and func_breakables that explode.
|
||||
////////////Effect_CreateExplosion( self.origin );
|
||||
|
||||
// Is this accurate? I just know a grenade can kill a player with around
|
||||
// 150 health from a powerup, and takes 100 down to 20 from a good distance.
|
||||
// CHANGE! Don't we want to tell who attacked (who threw the grenade), not just give
|
||||
// the grenade itself for the 2nd "eAttacker" parameter?
|
||||
Damage_Radius(self.origin, self.owner, 160, 380, TRUE, WEAPON_ID::M61GRENADE);
|
||||
//Damage_Radius( self.origin, self, 75, 550, TRUE, WEAPON_ID::M61GRENADE );
|
||||
|
||||
//Damage_Apply(other, this, m_iDamage, WEAPON_ID::M61GRENADE, DMG_GENERIC);
|
||||
|
||||
// this is mad old
|
||||
//Damage_Apply(plPlayer, world, plPlayer.dmg, DAMAGE_DROWNING, WEAPON_NONE);
|
||||
//Damage_Apply(target, world, 5, DMG_DROWN, 0);
|
||||
|
||||
//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!
|
||||
// ...weird, I know.
|
||||
//remove( self );
|
||||
removeSelfDelayed(self);
|
||||
}
|
||||
|
|
@ -19,13 +19,10 @@ enum pwuptype_choice{
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
|
||||
class ts_powerup:CBaseEntity{
|
||||
|
||||
|
||||
//key values?
|
||||
pwuptype_choice m_ePwuptype;
|
||||
int m_iPwupduration;
|
||||
|
@ -45,19 +42,22 @@ class ts_powerup:CBaseEntity{
|
|||
vector mem_origin;
|
||||
|
||||
void(void) ts_powerup;
|
||||
static void(void) precache;
|
||||
virtual void(void) CustomInit;
|
||||
//virtual void(void) restartAnim;
|
||||
virtual float(entity pvsent, float cflags) send;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Think;
|
||||
virtual void(void) Touch;
|
||||
virtual void(void) think;
|
||||
virtual void(void) touch;
|
||||
virtual void(void) determineDataID;
|
||||
virtual void(void) declareDisposable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void ts_powerup::ts_powerup(void){
|
||||
void
|
||||
ts_powerup::ts_powerup(void)
|
||||
{
|
||||
|
||||
// And why don't we just receive these as name/value pairs like clientside does?
|
||||
// I HAVE NO CLUE.
|
||||
|
@ -96,10 +96,18 @@ void ts_powerup::ts_powerup(void){
|
|||
|
||||
//gflags |= GF_CANRESPAWN;
|
||||
|
||||
}//END OF constructor
|
||||
}// constructor
|
||||
|
||||
void
|
||||
ts_powerup::precache(void)
|
||||
{
|
||||
precache_model(POWERUP_MODEL_PATH);
|
||||
}
|
||||
|
||||
|
||||
void ts_powerup::CustomInit(void){
|
||||
void
|
||||
ts_powerup::CustomInit(void)
|
||||
{
|
||||
|
||||
|
||||
expireTime = -1; //assumption.
|
||||
|
@ -184,8 +192,8 @@ void ts_powerup::CustomInit(void){
|
|||
this.SendEntity = send;
|
||||
this.SendFlags = 1;
|
||||
|
||||
this.touch = ts_powerup::Touch;
|
||||
think = ts_powerup::Think;
|
||||
//this.touch = ts_powerup::Touch;
|
||||
//this.think = ts_powerup::Think;
|
||||
this.nextthink = time + 0;
|
||||
|
||||
// ??? SERVERTEST
|
||||
|
@ -194,7 +202,7 @@ void ts_powerup::CustomInit(void){
|
|||
//m_oldModel = POWERUP_MODEL_PATH;
|
||||
//RendermodeUpdate();
|
||||
|
||||
}//END OF CustomInit
|
||||
}// CustomInit
|
||||
|
||||
|
||||
|
||||
|
@ -223,16 +231,20 @@ float ts_powerup::send(entity pvsent, float cflags)
|
|||
|
||||
|
||||
|
||||
void ts_powerup::Respawn(void){
|
||||
void
|
||||
ts_powerup::Respawn(void)
|
||||
{
|
||||
|
||||
CustomInit();
|
||||
|
||||
}//END OF Respawn
|
||||
}// Respawn
|
||||
|
||||
|
||||
|
||||
|
||||
void ts_powerup::Think(void){
|
||||
void
|
||||
ts_powerup::think(void)
|
||||
{
|
||||
|
||||
//TAGGG - CRITICAL. DISCUSS.
|
||||
// Is it ok to resend the entity to the client(s) just because our position changed?
|
||||
|
@ -258,10 +270,12 @@ void ts_powerup::Think(void){
|
|||
|
||||
this.nextthink = time + 0.01;
|
||||
|
||||
}//END OF think
|
||||
}// think
|
||||
|
||||
|
||||
void ts_powerup::Touch(void){
|
||||
void
|
||||
ts_powerup::touch(void)
|
||||
{
|
||||
|
||||
|
||||
if(other.classname != "player"){
|
||||
|
@ -289,15 +303,17 @@ void ts_powerup::Touch(void){
|
|||
this.SendFlags = 1;
|
||||
}else{
|
||||
//We were going to expire at some point? Do so now then, no need to hide to never be respawned and deleted later.
|
||||
remove(self);
|
||||
remove(this);
|
||||
}
|
||||
|
||||
}//END OF Touch
|
||||
}// touch
|
||||
|
||||
|
||||
|
||||
|
||||
void ts_powerup::determineDataID(void){
|
||||
void
|
||||
ts_powerup::determineDataID(void)
|
||||
{
|
||||
int bitsToChoose[9];
|
||||
|
||||
// really.. this is just setting bitsToChoose[0] to 0. Stops a 'uninitialized variable'
|
||||
|
@ -409,10 +425,12 @@ void ts_powerup::determineDataID(void){
|
|||
}
|
||||
|
||||
|
||||
}//END OF determineDataID
|
||||
}// determineDataID
|
||||
|
||||
|
||||
void ts_powerup::declareDisposable(void){
|
||||
void
|
||||
ts_powerup::declareDisposable(void)
|
||||
{
|
||||
|
||||
// Since we clearly weren't spawned by the map for this method to be called,
|
||||
// we need to do what "Respawn" would. The would-be constructor stuff.
|
||||
|
@ -438,7 +456,7 @@ void ts_powerup::declareDisposable(void){
|
|||
entityRemoveRespawnFlag(this);
|
||||
|
||||
|
||||
}//END OF declareDisposable
|
||||
}// declareDisposable
|
||||
|
||||
|
||||
|
||||
|
@ -464,19 +482,26 @@ class ts_powerup:CBaseEntity{
|
|||
virtual void(string strField, string strKey) SpawnKey;
|
||||
|
||||
virtual float(void) predraw;
|
||||
|
||||
// Change to customphysics to override that without needing to hook it up
|
||||
// at startup, if this is ever needed?
|
||||
//virtual void(void)Physics;
|
||||
//virtual void(void)Think;
|
||||
|
||||
//virtual void(void)think;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void ts_powerup::ts_powerup(void){
|
||||
|
||||
}//END OF constructor
|
||||
void
|
||||
ts_powerup::ts_powerup(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Use me instead for startup stuff expected after reading spawnflags.
|
||||
void ts_powerup::Initialized(void){
|
||||
void
|
||||
ts_powerup::Initialized(void)
|
||||
{
|
||||
//base method is empty, this is pointless
|
||||
//CBaseEntity::Initialized();
|
||||
|
||||
|
@ -506,12 +531,14 @@ void ts_powerup::Initialized(void){
|
|||
|
||||
//ts_powerup selfRef = this;
|
||||
|
||||
}//END OF Initialized
|
||||
}// Initialized
|
||||
|
||||
|
||||
|
||||
|
||||
void ts_powerup::updateAnim(void){
|
||||
void
|
||||
ts_powerup::updateAnim(void)
|
||||
{
|
||||
|
||||
//this.lerpfrac = 1;
|
||||
//this.baseframe1time = 0;
|
||||
|
@ -534,12 +561,14 @@ void ts_powerup::updateAnim(void){
|
|||
//this.nextthink = time + 0.017;
|
||||
//this.nextthink = time + 0.0;
|
||||
|
||||
}//END OF restartAnim
|
||||
}// restartAnim
|
||||
|
||||
|
||||
|
||||
|
||||
void Powerup_Parse(void){
|
||||
void
|
||||
Powerup_Parse(void)
|
||||
{
|
||||
|
||||
ts_powerup selfRef;
|
||||
|
||||
|
@ -641,11 +670,12 @@ void Powerup_Parse(void){
|
|||
selfRef.drawmask = MASK_ENGINE;
|
||||
|
||||
|
||||
}//END OF Powerup_Parse
|
||||
}// Powerup_Parse
|
||||
|
||||
|
||||
|
||||
float ts_powerup::predraw(void)
|
||||
float
|
||||
ts_powerup::predraw(void)
|
||||
{
|
||||
ts_powerup selfRef = (ts_powerup)self;
|
||||
|
||||
|
@ -663,19 +693,20 @@ void ts_powerup::Physics(void){
|
|||
|
||||
this.frame1time += clframetime;
|
||||
|
||||
}//END OF Physics
|
||||
}// Physics
|
||||
|
||||
void ts_powerup::Think(void){
|
||||
|
||||
this.frame1time += clframetime;
|
||||
this.nextthink = time + 0;
|
||||
|
||||
}//END OF Physics
|
||||
}// Physics
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void ts_powerup::SpawnKey(string strField, string strKey)
|
||||
void
|
||||
ts_powerup::SpawnKey(string strField, string strKey)
|
||||
{
|
||||
//printfline("SpawnKey:: ts_powerup: (%s: %s)", strField, strKey);
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ TSMultiplayerRules::PlayerDeath(base_player pp)
|
|||
}// excess negative health gib check
|
||||
|
||||
|
||||
|
||||
printfline("setInventoryEquippedIndex Flag Z");
|
||||
TS_resetViewModel(pl);
|
||||
pl.setInventoryEquippedIndex(-1);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ void ServerGame_Precache(void){
|
|||
precache_model("models/player.mdl");
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
TSGrenadeProjectile::precache();
|
||||
ts_powerup::precache();
|
||||
|
||||
precache_model("models/powerup.mdl");
|
||||
|
||||
|
@ -54,17 +56,6 @@ void ServerGame_Precache(void){
|
|||
precache_sound("player/pain3.wav");
|
||||
precache_sound("player/pain4.wav");
|
||||
|
||||
// for the grenade only so far.
|
||||
precache_sound("weapons/grenbounce1.wav");
|
||||
precache_sound("weapons/grenbounce2.wav");
|
||||
precache_sound("weapons/grenbounce3.wav");
|
||||
precache_sound("weapons/grenbounce4.wav");
|
||||
precache_sound("explo/explode.wav");
|
||||
precache_sound("explo/explode1.wav");
|
||||
precache_sound("explo/explode2.wav");
|
||||
precache_sound("explo/explode3.wav");
|
||||
precache_sound("explo/explode4.wav");
|
||||
|
||||
precache_sound("goslow.wav");
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#define SERVER
|
||||
#define TS
|
||||
|
||||
//TAGGG - NEW. TS definitely has penetration, and so should this then.
|
||||
// TS definitely has penetration, and so should this then.
|
||||
#define BULLETPENETRATION
|
||||
//TAGGG - NEW. FreeCS also has this. Do we want/need it? Keeping for now.
|
||||
|
||||
// NEW. FreeCS also has this. Do we want/need it? Keeping for now.
|
||||
// NEVERMIND, requires a new var "cs_shotmultiplier" and any other prediction-related tie-ins as seen
|
||||
// in freeCS's shared/player.qc.
|
||||
// Would like to know what BULLETPATTERNS even does to see if FreeTS had anything like that.
|
||||
|
@ -49,7 +50,7 @@
|
|||
../../../src/gs-entbase/server.src
|
||||
../../../src/gs-entbase/shared.src
|
||||
|
||||
//TAGGG - NEW
|
||||
|
||||
../shared/util.h
|
||||
../shared/defs.h
|
||||
defs.h
|
||||
|
@ -66,13 +67,10 @@ entity/ts_powerup.h
|
|||
|
||||
entity/TSWorldGun.h
|
||||
entity/TSThrownProjectile.h
|
||||
|
||||
entity/TSGrenadeProjectile.h
|
||||
|
||||
../shared/include.src
|
||||
|
||||
// <HL monster includes were here>
|
||||
|
||||
//TAGGG - NEW
|
||||
entity/ts_bomb.qc
|
||||
entity/ts_dmhill.qc
|
||||
entity/ts_groundweapon.qc
|
||||
|
@ -90,6 +88,7 @@ entity/ts_wingiver.qc
|
|||
entity/TSWorldGun.qc
|
||||
entity/TSThrownProjectile.qc
|
||||
entity/TSAmmoPack.qc
|
||||
entity/TSGrenadeProjectile.qc
|
||||
|
||||
../shared/player.qc
|
||||
../shared/inventory_logic.qc
|
||||
|
@ -118,9 +117,6 @@ spawn.qc
|
|||
|
||||
|
||||
|
||||
//TAGGG - NEW
|
||||
// no server util.h/.qc, yet?
|
||||
//util.qc
|
||||
precache.qc
|
||||
//money.qc
|
||||
//spectator.qc
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
|
||||
#ifdef SERVER
|
||||
void Effect_Explosion(vector vecOrigin );
|
||||
#else
|
||||
void EV_Effect_Explosion(vector vecOrigin );
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
//TAGGG - Thank you The Wastes!
|
||||
void Effect_ScreenShake(vector vecOrigin, float fRadius, float fStrength );
|
||||
#else
|
||||
void EV_Effect_ScreenShake(int iType);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void Effect_CreateExplosion(vector vPos);
|
|
@ -1,124 +0,0 @@
|
|||
|
||||
// New file.
|
||||
|
||||
// Try copying from _base/shared/effects.c. From the up to date repository
|
||||
// or the old one, dunno.
|
||||
// ...this comment has aged terribly.
|
||||
// No clue, these effects are due for a complete overhaul to better resemble
|
||||
// TS sometime anyway.
|
||||
|
||||
#ifdef SERVER
|
||||
void Effect_Explosion(vector vecOrigin )
|
||||
{
|
||||
//the specialists explosion does not do this, strangely enough.
|
||||
//Decals_PlaceScorch(vecOrigin);
|
||||
|
||||
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
|
||||
WriteByte( MSG_MULTICAST, EVENT_TS::EFFECT_EXPLOSION );
|
||||
WriteCoord( MSG_MULTICAST, vecOrigin[0] );
|
||||
WriteCoord( MSG_MULTICAST, vecOrigin[1] );
|
||||
WriteCoord( MSG_MULTICAST, vecOrigin[2] );
|
||||
|
||||
msg_entity = world;
|
||||
multicast( vecOrigin, MULTICAST_PVS );
|
||||
|
||||
}
|
||||
#else
|
||||
void EV_Effect_Explosion(vector vecOrigin ){
|
||||
pointparticles( PART_EXPLOSION, vecOrigin, [0,0,0], 1 );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
//TAGGG - Thank you The Wastes!
|
||||
void Effect_ScreenShake(vector vecOrigin, float fRadius, float fStrength )
|
||||
{
|
||||
entity eDChain = findradius( vecOrigin, fRadius );
|
||||
while( eDChain ) {
|
||||
if ( eDChain.classname == "player" ) {
|
||||
float fDiff = vlen( vecOrigin - eDChain.origin );
|
||||
|
||||
fDiff = ( fRadius - fDiff ) / fRadius;
|
||||
fStrength = fStrength * fDiff;
|
||||
|
||||
if ( fDiff > 0 ) {
|
||||
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
|
||||
WriteByte( MSG_MULTICAST, EVENT_TS::EFFECT_SHAKE );
|
||||
WriteByte( MSG_MULTICAST, (int)fStrength );
|
||||
|
||||
msg_entity = eDChain;
|
||||
multicast( [0,0,0], MULTICAST_ONE );
|
||||
}
|
||||
}
|
||||
eDChain = eDChain.chain;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//void EV_Effect_ScreenShake(vector vecOrigin, float fRadius, float fStrength ){
|
||||
// no, works a bit differently.
|
||||
void EV_Effect_ScreenShake(int iType){
|
||||
|
||||
View_ShakeCreate( iType );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//TAGGG - for the specialists, redirecting this to some other logic.
|
||||
void
|
||||
Effect_CreateExplosion(vector vPos)
|
||||
{
|
||||
|
||||
|
||||
#ifdef TS
|
||||
|
||||
#ifdef SERVER
|
||||
Effect_ScreenShake( vPos, 2048, 255 );
|
||||
Effect_Explosion( vPos + [0,0,16] );
|
||||
#else
|
||||
printfline("WARNING!!! Effect_CreateExplosion called clientside, but not supposed to be!");
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_EXPLOSION);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[0]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[1]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[2]);
|
||||
msg_entity = self;
|
||||
multicast(vecPos, MULTICAST_PVS);
|
||||
#else
|
||||
Decals_Place(vecPos, sprintf("{scorch%d", floor(random(1,4))));
|
||||
vecPos[2] += 48;
|
||||
env_sprite eExplosion = spawn(env_sprite);
|
||||
setorigin(eExplosion, vecPos);
|
||||
setmodel(eExplosion, "sprites/fexplo.spr");
|
||||
sound(eExplosion, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 3) + 3), 1, ATTN_NORM);
|
||||
|
||||
//eExplosion.think = FX_Explosion_Animate;
|
||||
eExplosion.effects = EF_ADDITIVE;
|
||||
eExplosion.drawmask = MASK_ENGINE;
|
||||
eExplosion.maxframe = modelframecount(eExplosion.modelindex);
|
||||
eExplosion.loops = 0;
|
||||
eExplosion.framerate = 20;
|
||||
eExplosion.nextthink = time + 0.05f;
|
||||
|
||||
pointparticles(FX_EXPLOSION_MAIN, vecPos, [0,0,0], 1);
|
||||
pointparticles(FX_EXPLOSION_BS, vecPos, [0,0,0], 1);
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ TS_Weapon_Draw(player pl, int weaponEquipped, BOOL useAkimbo ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
printfline("setInventoryEquipped Flag E");
|
||||
pl.setInventoryEquippedIndex_Akimbo(weaponEquipped, useAkimbo);
|
||||
// actually no, I guess we just let rendering pick up on this to know when to call draw
|
||||
// MMMMMmmmmmm sounds odd if Draw containts non-rendering-related startup script,
|
||||
|
@ -122,8 +122,8 @@ TS_Weapon_Drop() {
|
|||
|
||||
|
||||
|
||||
// CRITICAL! TS_playerEquippedWeapon methods dummied out to stop conflicts with
|
||||
// the new Nuclide way
|
||||
// This version does not send a message to the client. It assumes the server and client
|
||||
// are running the same commands so there is no need for that.
|
||||
void
|
||||
TS_playerEquippedWeapon_Shared(player pl, int newWeaponEquipped, BOOL useAkimbo){
|
||||
/*
|
||||
|
@ -197,8 +197,8 @@ TS_playerEquippedWeapon(player pl, int newWeaponEquipped, BOOL useAkimbo){
|
|||
_TS_playerEquippedWeapon(pl, newWeaponEquipped, useAkimbo);
|
||||
|
||||
// force a sendoff soon!
|
||||
pl.activeweapon_net = 255;
|
||||
pl.inventoryEquippedIndex_net = 255;
|
||||
//pl.activeweapon_net = 255;
|
||||
//pl.inventoryEquippedIndex_net = 255;
|
||||
|
||||
}
|
||||
|
||||
|
@ -316,9 +316,7 @@ EV_PlayerDeath(void){
|
|||
// This needs no clientside logic equivalent to be mirrored.
|
||||
/*
|
||||
void _TS_playerDropWeapon(player pl){
|
||||
|
||||
TS_Weapon_Drop();
|
||||
|
||||
}
|
||||
*/
|
||||
// TODO. Do anything clientside here too, maybe? Unsure.
|
||||
|
@ -327,13 +325,10 @@ void _TS_playerDropWeapon(player pl){
|
|||
void
|
||||
TS_playerDropWeapon(void){
|
||||
sendevent("TS_playerDropWeapon", "");
|
||||
}// TS_playerDropWeapon
|
||||
}
|
||||
/*
|
||||
//This is a received call from the server - no need to update it back
|
||||
//NOTICE - this is the callback telling us to do something. Yes do something.
|
||||
void EV_TS_playerDropWeapon(player pl){
|
||||
//pSeat->ePlayer = self = findfloat(world, entnum, player_localentnum);
|
||||
|
||||
_TS_playerDropWeapon(pl);
|
||||
}
|
||||
*/
|
||||
|
@ -348,31 +343,30 @@ _TS_playerDropWeapon(void){
|
|||
|
||||
}//_TS_playerDropWeapon
|
||||
|
||||
//The server set the equippedWeapon, and needs to tell the client to keep it in synch
|
||||
// Will this ever be needed? When weapons can be knocked out of other player's
|
||||
// hands by some karate attacks and possibly cold-cocking (I forget), probably.
|
||||
void
|
||||
TS_playerDropWeapon(void){
|
||||
player pl = (player)self;
|
||||
//pSeat->ePlayer = self = findfloat(world, entnum, player_localentnum);
|
||||
_TS_playerDropWeapon();
|
||||
|
||||
|
||||
// No need for this message, the changed weapon value should be
|
||||
// cause for an update that handles that.
|
||||
// Unless there were anything special about losing a weapon that way
|
||||
// that the client neets to be aware of? Can't think of anything though.
|
||||
/*
|
||||
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
|
||||
WriteByte( MSG_MULTICAST, EVENT_TS::DROP_WEAPON );
|
||||
msg_entity = pl;
|
||||
multicast( [0,0,0], MULTICAST_ONE );
|
||||
*/
|
||||
}
|
||||
|
||||
//This is a received call from 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.
|
||||
//The server can initiate the call too.
|
||||
//Either side can call "TS_playerEquippedWeapon" to get the orders right.
|
||||
// This is a received call from the client.
|
||||
void
|
||||
CSEv_TS_playerDropWeapon_(){
|
||||
player pl = (player)self;
|
||||
|
||||
TS_playerDropWeapon();
|
||||
|
||||
_TS_playerDropWeapon();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -978,6 +972,7 @@ playerEquipIdeal(player pl){
|
|||
// Could anywhere else benefit from TS_playerEquippedWeapon being changed to
|
||||
// TS_playerEquippedWeapon_Shared ?
|
||||
|
||||
printfline("setInventoryEquippedIndex: FLAG D");
|
||||
TS_playerEquippedWeapon_Shared(pl, weaponDynamicID_toEquip, TRUE);
|
||||
|
||||
}//playerEquipIdeal
|
||||
|
@ -987,6 +982,7 @@ playerEquipIdeal(player pl){
|
|||
void
|
||||
playerEquipIdealSafe(player pl){
|
||||
TS_resetViewModel(pl);
|
||||
printfline("setInventoryEquippedIndex: FLAG C");
|
||||
pl.setInventoryEquippedIndex(-1);
|
||||
playerEquipIdeal(pl);
|
||||
|
||||
|
|
|
@ -7,12 +7,9 @@ enum EVENT_TS{
|
|||
RESET_VIEW_MODEL,
|
||||
RESET_PLAYER,
|
||||
PLAYER_DEATH,
|
||||
EFFECT_EXPLOSION,
|
||||
EFFECT_SHAKE,
|
||||
DROP_WEAPON,
|
||||
// NEW. Like EV_IMPACT but to paint a decal only.
|
||||
EV_PLACEDECAL,
|
||||
EV_IMPACT_MELEE,
|
||||
//DROP_WEAPON,
|
||||
FX_TS_EXPLOSION_GRENADE,
|
||||
SOUNDPITCHED,
|
||||
SOUNDPITCHED_CHANNEL,
|
||||
TEST,
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
var float PARTICLE_BLOOD;
|
||||
var int DECAL_BLOOD;
|
||||
|
||||
void
|
||||
FX_Blood_Init(void)
|
||||
{
|
||||
precache_model("sprites/bloodspray.spr");
|
||||
precache_model("sprites/blood.spr");
|
||||
PARTICLE_BLOOD = particleeffectnum("part_blood");
|
||||
DECAL_BLOOD = particleeffectnum("decal_blood.effect");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FX_Blood(vector pos, vector color)
|
||||
{
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_BLOOD);
|
||||
WriteCoord(MSG_MULTICAST, pos[0]);
|
||||
WriteCoord(MSG_MULTICAST, pos[1]);
|
||||
WriteCoord(MSG_MULTICAST, pos[2]);
|
||||
WriteByte(MSG_MULTICAST, color[0] * 255);
|
||||
WriteByte(MSG_MULTICAST, color[1] * 255);
|
||||
WriteByte(MSG_MULTICAST, color[2] * 255);
|
||||
msg_entity = self;
|
||||
multicast(pos, MULTICAST_PVS);
|
||||
#else
|
||||
static void Blood_Touch(void)
|
||||
{
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_HL)
|
||||
Decals_Place(self.origin, sprintf("{blood%d", floor(random(1,9))));
|
||||
else {
|
||||
decal_pickwall(self, self.origin);
|
||||
pointparticles(DECAL_BLOOD, g_tracedDecal.endpos, g_tracedDecal.normal, 1);
|
||||
}
|
||||
remove(self);
|
||||
}
|
||||
|
||||
if (cvar("violence_hblood") <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
env_sprite eBlood = spawn(env_sprite);
|
||||
setorigin(eBlood, pos);
|
||||
setmodel(eBlood, "sprites/bloodspray.spr");
|
||||
|
||||
eBlood.drawmask = MASK_ENGINE;
|
||||
eBlood.maxframe = modelframecount(eBlood.modelindex);
|
||||
eBlood.loops = 0;
|
||||
eBlood.scale = 1.0f;
|
||||
|
||||
#ifdef GS_RENDERFX
|
||||
eBlood.m_vecRenderColor = color;
|
||||
eBlood.m_iRenderMode = RM_COLOR;
|
||||
eBlood.m_flRenderAmt = 1.0f;
|
||||
#else
|
||||
eBlood.colormod = color;
|
||||
#endif
|
||||
|
||||
eBlood.framerate = 20;
|
||||
eBlood.nextthink = time + 0.05f;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
env_sprite ePart = spawn(env_sprite);
|
||||
setorigin(ePart, pos);
|
||||
setmodel(ePart, "sprites/blood.spr");
|
||||
ePart.movetype = MOVETYPE_BOUNCE;
|
||||
ePart.gravity = 0.5f;
|
||||
ePart.scale = 0.5f;
|
||||
ePart.drawmask = MASK_ENGINE;
|
||||
ePart.maxframe = modelframecount(ePart.modelindex);
|
||||
ePart.loops = 0;
|
||||
|
||||
#ifdef GS_RENDERFX
|
||||
ePart.m_vecRenderColor = color;
|
||||
ePart.m_iRenderMode = RM_COLOR;
|
||||
ePart.m_flRenderAmt = 1.0f;
|
||||
#else
|
||||
ePart.colormod = color;
|
||||
#endif
|
||||
ePart.framerate = 15;
|
||||
ePart.nextthink = time + 0.1f;
|
||||
ePart.velocity = randomvec() * 64;
|
||||
ePart.touch = Blood_Touch;
|
||||
ePart.solid = SOLID_BBOX;
|
||||
/* ignore player physics */
|
||||
ePart.dimension_solid = 1;
|
||||
ePart.dimension_hit = 1;
|
||||
setsize(ePart, [0,0,0], [0,0,0]);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
FX_BreakModel_Init(void)
|
||||
{
|
||||
precache_model("models/glassgibs.mdl");
|
||||
precache_model("models/woodgibs.mdl");
|
||||
precache_model("models/metalplategibs.mdl");
|
||||
precache_model("models/fleshgibs.mdl");
|
||||
precache_model("models/ceilinggibs.mdl");
|
||||
precache_model("models/computergibs.mdl");
|
||||
precache_model("models/rockgibs.mdl");
|
||||
precache_model("models/cindergibs.mdl");
|
||||
precache_sound("debris/bustglass1.wav");
|
||||
precache_sound("debris/bustglass2.wav");
|
||||
precache_sound("debris/bustglass3.wav");
|
||||
precache_sound("debris/bustcrate1.wav");
|
||||
precache_sound("debris/bustcrate2.wav");
|
||||
precache_sound("debris/bustcrate3.wav");
|
||||
precache_sound("debris/bustmetal1.wav");
|
||||
precache_sound("debris/bustmetal2.wav");
|
||||
precache_sound("debris/bustflesh1.wav");
|
||||
precache_sound("debris/bustflesh2.wav");
|
||||
precache_sound("debris/bustconcrete1.wav");
|
||||
precache_sound("debris/bustconcrete2.wav");
|
||||
precache_sound("debris/bustceiling.wav");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FX_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float fStyle)
|
||||
{
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_MODELGIB);
|
||||
WriteCoord(MSG_MULTICAST, vMins[0]);
|
||||
WriteCoord(MSG_MULTICAST, vMins[1]);
|
||||
WriteCoord(MSG_MULTICAST, vMins[2]);
|
||||
WriteCoord(MSG_MULTICAST, vMaxs[0]);
|
||||
WriteCoord(MSG_MULTICAST, vMaxs[1]);
|
||||
WriteCoord(MSG_MULTICAST, vMaxs[2]);
|
||||
WriteByte(MSG_MULTICAST, fStyle);
|
||||
WriteByte(MSG_MULTICAST, count);
|
||||
|
||||
msg_entity = self;
|
||||
|
||||
vector vWorldPos;
|
||||
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
|
||||
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
|
||||
vWorldPos[2] = vMins[2] + (0.5 * (vMaxs[2] - vMins[2]));
|
||||
multicast(vWorldPos, MULTICAST_PVS);
|
||||
#else
|
||||
static void FX_BreakModel_Remove(void) { remove(self) ; }
|
||||
|
||||
float fModelCount = 0;
|
||||
vector vecPos;
|
||||
string sModel = "";
|
||||
|
||||
switch (fStyle) {
|
||||
case GSMATERIAL_GLASS:
|
||||
case GSMATERIAL_GLASS_UNBREAKABLE:
|
||||
sModel = "models/glassgibs.mdl";
|
||||
fModelCount = 8;
|
||||
break;
|
||||
case GSMATERIAL_WOOD:
|
||||
sModel = "models/woodgibs.mdl";
|
||||
fModelCount = 3;
|
||||
break;
|
||||
case GSMATERIAL_METAL:
|
||||
sModel = "models/metalplategibs.mdl";
|
||||
fModelCount = 13;
|
||||
break;
|
||||
case GSMATERIAL_FLESH:
|
||||
sModel = "models/fleshgibs.mdl";
|
||||
fModelCount = 4;
|
||||
break;
|
||||
case GSMATERIAL_TILE:
|
||||
sModel = "models/ceilinggibs.mdl";
|
||||
fModelCount = 4;
|
||||
break;
|
||||
case GSMATERIAL_COMPUTER:
|
||||
sModel = "models/computergibs.mdl";
|
||||
fModelCount = 15;
|
||||
break;
|
||||
case GSMATERIAL_ROCK:
|
||||
sModel = "models/rockgibs.mdl";
|
||||
fModelCount = 3;
|
||||
break;
|
||||
default:
|
||||
case GSMATERIAL_CINDER:
|
||||
sModel = "models/cindergibs.mdl";
|
||||
fModelCount = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
vector vWorldPos;
|
||||
vWorldPos = vMins + (0.5 * (vMaxs - vMins));
|
||||
|
||||
switch (fStyle) {
|
||||
case GSMATERIAL_GLASS:
|
||||
pointsound(vWorldPos, sprintf("debris/bustglass%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
|
||||
break;
|
||||
case GSMATERIAL_WOOD:
|
||||
pointsound(vWorldPos, sprintf("debris/bustcrate%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
|
||||
break;
|
||||
case GSMATERIAL_METAL:
|
||||
case GSMATERIAL_COMPUTER:
|
||||
pointsound(vWorldPos, sprintf("debris/bustmetal%d.wav", random(1, 3)), 1.0f, ATTN_NORM);
|
||||
break;
|
||||
case GSMATERIAL_FLESH:
|
||||
pointsound(vWorldPos, sprintf("debris/bustflesh%d.wav", random(1, 3)), 1.0f, ATTN_NORM);
|
||||
break;
|
||||
case GSMATERIAL_CINDER:
|
||||
case GSMATERIAL_ROCK:
|
||||
pointsound(vWorldPos, sprintf("debris/bustconcrete%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
|
||||
break;
|
||||
case GSMATERIAL_TILE:
|
||||
pointsound(vWorldPos, "debris/bustceiling.wav", 1.0f, ATTN_NORM);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
entity eGib = spawn();
|
||||
eGib.classname = "gib";
|
||||
|
||||
vecPos[0] = vMins[0] + (random() * (vMaxs[0] - vMins[0]));
|
||||
vecPos[1] = vMins[1] + (random() * (vMaxs[1] - vMins[1]));
|
||||
vecPos[2] = vMins[2] + (random() * (vMaxs[2] - vMins[2]));
|
||||
|
||||
setorigin(eGib, vecPos);
|
||||
setmodel(eGib, sModel);
|
||||
setcustomskin(eGib, "", sprintf("geomset 0 %f\n", random(1, fModelCount + 1)));
|
||||
eGib.movetype = MOVETYPE_BOUNCE;
|
||||
eGib.solid = SOLID_NOT;
|
||||
|
||||
eGib.avelocity[0] = random()*600;
|
||||
eGib.avelocity[1] = random()*600;
|
||||
eGib.avelocity[2] = random()*600;
|
||||
eGib.think = FX_BreakModel_Remove;
|
||||
eGib.nextthink = time + 10;
|
||||
|
||||
if ((fStyle == GSMATERIAL_GLASS) || (fStyle == GSMATERIAL_GLASS_UNBREAKABLE)) {
|
||||
eGib.alpha = 0.5f;
|
||||
}
|
||||
|
||||
eGib.drawmask = MASK_ENGINE;
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
var int FX_EXPLOSION_MAIN;
|
||||
var int FX_EXPLOSION_BS;
|
||||
|
||||
void
|
||||
FX_Explosion_Init(void)
|
||||
{
|
||||
Sound_Precache("fx.explosion");
|
||||
precache_model("sprites/fexplo.spr");
|
||||
FX_EXPLOSION_MAIN = particleeffectnum("fx_explosion.main");
|
||||
FX_EXPLOSION_BS = particleeffectnum("fx_explosion.blacksmoke");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FX_Explosion(vector vecPos)
|
||||
{
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_EXPLOSION);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[0]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[1]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[2]);
|
||||
msg_entity = self;
|
||||
multicast(vecPos, MULTICAST_PVS);
|
||||
#else
|
||||
Decals_Place(vecPos, sprintf("{scorch%d", floor(random(1,4))));
|
||||
vecPos[2] += 48;
|
||||
env_sprite eExplosion = spawn(env_sprite);
|
||||
setorigin(eExplosion, vecPos);
|
||||
setmodel(eExplosion, "sprites/fexplo.spr");
|
||||
Sound_Play(eExplosion, CHAN_WEAPON, "fx.explosion");
|
||||
|
||||
//eExplosion.think = FX_Explosion_Animate;
|
||||
eExplosion.effects = EF_ADDITIVE;
|
||||
eExplosion.drawmask = MASK_ENGINE;
|
||||
eExplosion.maxframe = modelframecount(eExplosion.modelindex);
|
||||
eExplosion.loops = 0;
|
||||
eExplosion.framerate = 20;
|
||||
eExplosion.nextthink = time + 0.05f;
|
||||
|
||||
pointparticles(FX_EXPLOSION_MAIN, vecPos, [0,0,0], 1);
|
||||
pointparticles(FX_EXPLOSION_BS, vecPos, [0,0,0], 1);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
string g_hgibs[] = {
|
||||
"models/gib_b_bone.mdl",
|
||||
"models/gib_legbone.mdl",
|
||||
"models/gib_lung.mdl",
|
||||
"models/gib_skull.mdl",
|
||||
"models/gib_b_gib.mdl"
|
||||
};
|
||||
|
||||
void
|
||||
FX_GibHuman_Init(void)
|
||||
{
|
||||
precache_model("models/gib_b_bone.mdl");
|
||||
precache_model("models/gib_legbone.mdl");
|
||||
precache_model("models/gib_lung.mdl");
|
||||
precache_model("models/gib_skull.mdl");
|
||||
precache_model("models/gib_b_gib.mdl");
|
||||
precache_sound("common/bodysplat.wav");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FX_GibHuman(vector pos)
|
||||
{
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_GIBHUMAN);
|
||||
WriteCoord(MSG_MULTICAST, pos[0]);
|
||||
WriteCoord(MSG_MULTICAST, pos[1]);
|
||||
WriteCoord(MSG_MULTICAST, pos[2]);
|
||||
msg_entity = __NULL__;
|
||||
multicast(pos, MULTICAST_PVS);
|
||||
#else
|
||||
static void Gib_Remove(void) {
|
||||
remove(self);
|
||||
}
|
||||
static void Gib_Touch(void)
|
||||
{
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_HL)
|
||||
Decals_Place(self.origin, sprintf("{blood%d", floor(random(1,9))));
|
||||
else {
|
||||
decal_pickwall(self, self.origin);
|
||||
pointparticles(DECAL_BLOOD, g_tracedDecal.endpos, g_tracedDecal.normal, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (cvar("violence_hgibs") <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
vector vel;
|
||||
vel[0] = random(-128,128);
|
||||
vel[1] = random(-128,128);
|
||||
vel[2] = (300 + random() * 64);
|
||||
|
||||
entity gibb = spawn();
|
||||
setmodel(gibb, g_hgibs[i]);
|
||||
setorigin(gibb, pos);
|
||||
gibb.movetype = MOVETYPE_BOUNCE;
|
||||
gibb.solid = SOLID_BBOX;
|
||||
setsize(gibb, [0,0,0], [0,0,0]);
|
||||
gibb.velocity = vel;
|
||||
gibb.avelocity = vectoangles(gibb.velocity);
|
||||
gibb.think = Gib_Remove;
|
||||
gibb.touch = Gib_Touch;
|
||||
gibb.nextthink = time + 5.0f;
|
||||
gibb.drawmask = MASK_ENGINE;
|
||||
}
|
||||
pointsound(pos, "common/bodysplat.wav", 1, ATTN_NORM);
|
||||
#endif
|
||||
}
|
|
@ -13,6 +13,11 @@
|
|||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// NOTE - unlike the other Half-Life borrowed effects, this one is staying forked.
|
||||
// For sounds, yes, but I can't imagine TS's hit-effects being replicated by re-using
|
||||
// FreeHL's fx_impact.qc file.
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
var int FX_IMPACT_BLACKBITS;
|
||||
|
@ -131,19 +136,19 @@ FX_Impact(impactType_t iType, vector vecPos, vector vNormal)
|
|||
}
|
||||
}
|
||||
|
||||
//TAGGG - NOTE. In original TS, hit dirt makes a smoke effect too
|
||||
|
||||
switch (iType) {
|
||||
case IMPACT_MELEE:
|
||||
case IMPACT_EXPLOSION:
|
||||
break;
|
||||
// !!!
|
||||
//case IMPACT_DIRT:
|
||||
// ...
|
||||
// break;
|
||||
case IMPACT_GLASS:
|
||||
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
|
||||
break;
|
||||
//TAGGG - NEW. Clone of wood for now as it used to be...
|
||||
case IMPACT_DIRT:
|
||||
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
|
||||
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
|
||||
pointparticles(FX_IMPACT_SMOKE_BROWN, vecPos, vNormal, 1);
|
||||
break;
|
||||
case IMPACT_WOOD:
|
||||
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
|
||||
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
|
||||
|
@ -164,15 +169,6 @@ FX_Impact(impactType_t iType, vector vecPos, vector vNormal)
|
|||
}
|
||||
|
||||
switch (iType) {
|
||||
|
||||
//TAGGG - NEW. Just to be dummied out, but see the new way nelow if putting back in
|
||||
case IMPACT_MELEE:
|
||||
//oh... pointsound doesn't support pitchshift. of... course. What ever was I thinking.
|
||||
//pointsound(vecPos, "player/closecombat.wav", impactSoundVolume, ATTN_NORM+0.1, randomInRange_f(92, 100), SOUNDFLAG_FOLLOW);
|
||||
//pointsound(vecPos, "player/closecombat.wav", impactSoundVolume, ATTN_NORM+0.1);
|
||||
|
||||
break;
|
||||
|
||||
case IMPACT_ALIEN:
|
||||
Sound_PlayAt(vecPos, "sfx_impact.alien");
|
||||
break;
|
||||
|
@ -219,37 +215,30 @@ FX_Impact(impactType_t iType, vector vecPos, vector vNormal)
|
|||
Sound_PlayAt(vecPos, "sfx_impact.default");
|
||||
break;
|
||||
}
|
||||
|
||||
//TAGGG - NEW
|
||||
/*
|
||||
if(iType != IMPACT_FLESH && iType != IMPACT_MELEE){
|
||||
if(random() < 0.53){
|
||||
//TAGGG - TODO! Meant to depend on player sound factor... whatever var.
|
||||
pointsound(vecPos, sprintf("debris/ric%i.wav", randomInRange_i(1, 5)), impactSoundVolume-0.12, ATTN_NORM+0.1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TAGGG - NEW.
|
||||
// Version of FX_Impact for melee weapons to use instead, some get different sounds on
|
||||
// some surfaces.
|
||||
#ifdef CLIENT
|
||||
void
|
||||
FX_Impact_Melee_Init(void)
|
||||
{
|
||||
Sound_Precache("sfx_impact_melee.default");
|
||||
Sound_Precache("sfx_impact_melee.dirt");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FX_Impact_Melee(int iType, vector vecPos, vector vNormal)
|
||||
{
|
||||
|
||||
|
||||
//TAGGG - NOTE YOUR CHANGES SWEET CHRIST.
|
||||
// (this is a note to myself)
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_IMPACT_MELEE);
|
||||
WriteByte(MSG_MULTICAST, EVENT_TS::EV_IMPACT_MELEE);
|
||||
WriteByte(MSG_MULTICAST, (float)iType);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[0]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[1]);
|
||||
|
@ -267,26 +256,26 @@ FX_Impact_Melee(int iType, vector vecPos, vector vNormal)
|
|||
float impactSoundVolume = 0.55;
|
||||
|
||||
switch (iType) {
|
||||
// Too generic, don't use this, use any other IMPACT.
|
||||
case IMPACT_MELEE:
|
||||
//oh... pointsound doesn't support pitchshift. of... course. What ever was I thinking.
|
||||
// oh, pointsound doesn't support pitchshift.
|
||||
//pointsound(vecPos, "player/closecombat.wav", impactSoundVolume, ATTN_NORM+0.1, randomInRange_f(92, 100), SOUNDFLAG_FOLLOW);
|
||||
//pointsound(vecPos, "player/closecombat.wav", impactSoundVolume, ATTN_NORM+0.1);
|
||||
|
||||
break;
|
||||
case IMPACT_COMPUTER:
|
||||
Sound_PlayAt(vecPos, "sfx_impact.computer");
|
||||
break;
|
||||
case IMPACT_GLASS:
|
||||
Sound_PlayAt(vecPos, "sfx_impact.glass");
|
||||
|
||||
break;
|
||||
case IMPACT_FLESH:
|
||||
// should something else be used? Leave it up to specific melee weapons to play their
|
||||
// own sound? Don't know, this is HL flesh sounds
|
||||
Sound_PlayAt(vecPos, "sfx_impact.flesh");
|
||||
break;
|
||||
case IMPACT_DIRT:
|
||||
//pointsound(vecPos, sprintf("debris/gravel%i.wav", randomInRange_i(1, 4)), impactSoundVolume, ATTN_NORM+0.1);
|
||||
//sound(self, CHAN_BODY, sprintf("player/pl_%s1.wav", sMaterial), fVol, ATTN_STATIC)
|
||||
|
||||
// Unique? Keep to the old way for now
|
||||
pointsound(vecPos, sprintf("player/pl_dirt%i.wav", randomInRange_i(1, 4)), impactSoundVolume, ATTN_NORM+0.1);
|
||||
|
||||
Sound_PlayAt(vecPos, "sfx_impact_melee.dirt");
|
||||
break;
|
||||
case IMPACT_WOOD:
|
||||
Sound_PlayAt(vecPos, "sfx_impact.wood");
|
||||
|
@ -295,16 +284,9 @@ FX_Impact_Melee(int iType, vector vecPos, vector vNormal)
|
|||
Sound_PlayAt(vecPos, "sfx_impact.metal");
|
||||
break;
|
||||
default:
|
||||
//cement... yes, the default if no other is specified. Stated right in materials.txt, even.
|
||||
//pointsound(vecPos, sprintf("weapons/ric%d.wav", floor((random() * 5) + 1)), 1, ATTN_STATIC);
|
||||
//pointsound(vecPos, sprintf("debris/cement%i.wav", randomInRange_i(1, 6)), impactSoundVolume, ATTN_NORM+0.1);
|
||||
|
||||
// Unique? Keep to the old way for now
|
||||
pointsound(vecPos, sprintf("player/pl_step%i.wav", randomInRange_i(1, 4)), impactSoundVolume, ATTN_NORM+0.1);
|
||||
|
||||
Sound_PlayAt(vecPos, "sfx_impact_melee.default");
|
||||
break;
|
||||
}//END OF switch
|
||||
|
||||
}// switch
|
||||
|
||||
/*
|
||||
if(iType != IMPACT_FLESH && iType != IMPACT_MELEE){
|
||||
|
@ -320,5 +302,3 @@ FX_Impact_Melee(int iType, vector vecPos, vector vNormal)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
// TS-grenade explosion, not to be confused with the default HL one
|
||||
// (FX_Explosion). Referring to the Valve one instead by file, no
|
||||
// need to fork that.
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
var int FX_TS_EXPLOSION_PARTICLE;
|
||||
|
||||
void
|
||||
FX_TS_Explosion_Grenade_Init(void)
|
||||
{
|
||||
Sound_Precache("fx.ts_explosion_grenade");
|
||||
FX_TS_EXPLOSION_PARTICLE = particleeffectnum("ts_fx_explosion_grenade.explosion_grenade");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TS uses a unique explosion for grenades, but still retains the default
|
||||
// HL explosion + sound for other things like map-driven events
|
||||
// (see shooting the explosives barrel in the basement of ts_bikini.bsp).
|
||||
// Unsure if anything else uses this same effect.
|
||||
void
|
||||
FX_TS_Explosion_Grenade(vector vecPos)
|
||||
{
|
||||
#ifdef SERVER
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EVENT_TS::FX_TS_EXPLOSION_GRENADE);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[0]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[1]);
|
||||
WriteCoord(MSG_MULTICAST, vecPos[2]);
|
||||
msg_entity = self;
|
||||
multicast(vecPos, MULTICAST_PVS);
|
||||
#else
|
||||
pointparticles(FX_TS_EXPLOSION_PARTICLE, vecPos, [0,0,0], 1);
|
||||
// uh-oh, no generated entity to play the sound on.
|
||||
// Leaving it up to the greande itself to do that then
|
||||
|
||||
// oh wait would this work?
|
||||
// The FTE built-in method pointsound that this leads to does not support pitch-shift.
|
||||
// Because... FTE. So, no. Grenade explosion sounds come pitch-shifted and have
|
||||
// to be adjusted to play normally
|
||||
//Sound_PlayAt(vecPos, "fx.ts_explosion_grenade");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
// call me around a FX_TS_Explosion_Grenade call in TSGrenadeProjectile
|
||||
void
|
||||
FX_TS_Explosion_Grenade_PlaySound(entity ePlayer){
|
||||
Sound_Play(ePlayer, CHAN_WEAPON, "fx.ts_explosion_grenade");
|
||||
}
|
||||
#endif
|
||||
|
|
@ -21,11 +21,9 @@ init.h
|
|||
entities.h
|
||||
flags.h
|
||||
// old player.h location
|
||||
//TAGGG - weapon_common REMOVAL.
|
||||
../../../base/src/shared/weapon_common.h
|
||||
|
||||
|
||||
//TAGGG - NEW
|
||||
//gamerules.h
|
||||
precache.h
|
||||
|
||||
|
@ -38,16 +36,12 @@ precache.h
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
//TAGGG - NEW
|
||||
//player.h
|
||||
//animations.h
|
||||
inventory_logic.h
|
||||
event_enum.h
|
||||
event_custom.h
|
||||
//init.h
|
||||
effects.h
|
||||
|
||||
|
||||
// Nope! Leave this one up to per-project.
|
||||
|
@ -59,21 +53,26 @@ animations.qc
|
|||
pmove.qc
|
||||
pmove_water.qc
|
||||
|
||||
fx_blood.qc
|
||||
fx_breakmodel.qc
|
||||
fx_explosion.qc
|
||||
fx_gibhuman.qc
|
||||
//TAGGG
|
||||
// refer to the FreeHL fx_ files instead of forking
|
||||
// (remove any that turn out to never be involved)
|
||||
../../../valve/src/shared/fx_blood.qc
|
||||
../../../valve/src/shared/fx_breakmodel.qc
|
||||
../../../valve/src/shared/fx_explosion.qc
|
||||
../../../valve/src/shared/fx_gibhuman.qc
|
||||
../../../base/src/shared/fx_spark.qc
|
||||
// except that one
|
||||
fx_impact.qc
|
||||
// NEW
|
||||
fx_ts_explosion_grenade.qc
|
||||
|
||||
|
||||
// Nope! Leave this one up to per-project.
|
||||
//inventory_logic.qc
|
||||
event_custom.qc
|
||||
effects.qc
|
||||
|
||||
|
||||
|
||||
//TAGGG - NEW
|
||||
util.qc
|
||||
precache.qc
|
||||
sound_pitched.qc
|
||||
|
@ -135,7 +134,6 @@ weapons/weapon_sealknife.qc
|
|||
ammo.qc
|
||||
weapons.qc
|
||||
powerup.qc
|
||||
//TAGGG - weapon_common REMOVAL.
|
||||
../../../base/src/shared/weapon_common.qc
|
||||
input.qc
|
||||
|
||||
|
|
|
@ -435,10 +435,8 @@ class player:base_player
|
|||
float ignoreFiremodeReceiveTime;
|
||||
#endif
|
||||
|
||||
//TAGGG - NEW, constructor
|
||||
void(void) player;
|
||||
|
||||
//TAGGG - NEW.
|
||||
virtual void(void) preThink;
|
||||
virtual void(void) postThink;
|
||||
|
||||
|
|
|
@ -165,8 +165,17 @@ player::ReceiveEntity(float new, float fl)
|
|||
// printfline("WELL hey WHAT:%i new:%i", oldPlayerWeapEq, inventoryEquippedIndex);
|
||||
//}
|
||||
|
||||
//setInventoryEquippedIndex(inventoryEquippedIndex_temp);
|
||||
// important to keep pl.activeweapon in sync
|
||||
inventoryEquippedIndex = inventoryEquippedIndex_temp;
|
||||
//setInventoryEquippedIndex(inventoryEquippedIndex_temp);
|
||||
|
||||
// Somehow this is atrocious.
|
||||
/*
|
||||
if(inventoryEquippedIndex_temp != inventoryEquippedIndex){
|
||||
setInventoryEquippedIndex(inventoryEquippedIndex_temp);
|
||||
}
|
||||
*/
|
||||
|
||||
weaponEquippedAkimbo = readbyte();
|
||||
w_attack_akimbo_next = readfloat();
|
||||
isReloading = readbyte();
|
||||
|
@ -211,6 +220,10 @@ player::ReceiveEntity(float new, float fl)
|
|||
|
||||
this.completeInventorySend = readbyte();
|
||||
|
||||
#ifdef FORCE_NETWORK_ALL_INVENTORY
|
||||
completeInventorySend = TRUE;
|
||||
#endif
|
||||
|
||||
if(this.completeInventorySend){
|
||||
for(i = 0; i < ary_myWeapons_softMax; i++){
|
||||
ReceiveEntity_ary_myWeapons(i);
|
||||
|
@ -825,6 +838,10 @@ player::SendEntity(entity ePEnt, float fChanged)
|
|||
|
||||
WriteByte(MSG_ENTITY, this.completeInventorySend );
|
||||
|
||||
#ifdef FORCE_NETWORK_ALL_INVENTORY
|
||||
completeInventorySend = TRUE;
|
||||
#endif
|
||||
|
||||
if(this.completeInventorySend){
|
||||
for(i = 0; i < ary_myWeapons_softMax; i++){
|
||||
SendEntity_ary_myWeapons(i);
|
||||
|
@ -1132,7 +1149,8 @@ player::reset(BOOL resetInventory){
|
|||
|
||||
// sure? Not used for this game though.
|
||||
g_items = 0x0;
|
||||
|
||||
|
||||
printfline("setInventoryEquippedIndex: FLAG A");
|
||||
setInventoryEquippedIndex(-1);
|
||||
|
||||
shotgunWaitingForPump = FALSE;
|
||||
|
@ -1240,7 +1258,6 @@ player::setInventoryEquippedIndex(int arg_newIndex)
|
|||
|
||||
|
||||
// Extra version supplied 'useAkimbo'.
|
||||
// Also, setting to hte
|
||||
void
|
||||
player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
|
||||
{
|
||||
|
@ -1281,6 +1298,7 @@ player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
|
|||
weaponEquippedAkimbo = FALSE; // I guess?
|
||||
}
|
||||
|
||||
// - OLD COMMENT
|
||||
// NOTE, IMPORTANT.
|
||||
// Is this necessary?
|
||||
// Makes a decent example for paying attention to SAVE and ROLLBACKs in player script
|
||||
|
@ -1300,10 +1318,36 @@ player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
|
|||
// If this is the wrong way to go thinking about this, I need to know more.
|
||||
// ALSO - see other uses of SAVE_STATE, most are for both client & server,
|
||||
// especially the w_attack_next, or w_next_attack, in ts/shared/weapons.qc.
|
||||
#ifdef CLIENT
|
||||
/////////////////////////////////////
|
||||
|
||||
// - NEW COMMENTs
|
||||
// Looks like we at least want to do SAVE_STATE(activeweapon) to stop a rollback
|
||||
// from being undone that causes it to flicker back to what's about to be received.
|
||||
|
||||
// and we get 'iilegible server message' on very high pings.
|
||||
// S T E L L A R . although it's happenin without this too.
|
||||
// Although this can cause the weapon info to glich out, like a host of other stuff
|
||||
// needs to be sent / know not to change just yet too I'm guessing, a clientside SAVE_STATE
|
||||
// of all the next equipped weapon's stuff I'm guessing?
|
||||
// Make a method and test, with equippedID set to the new
|
||||
// (inventoryEquippedIndex and activeweapon as they are here)! TODO TODO TODO
|
||||
// #ifdef CLIENT saveWeaponState(inventoryEquippedIndex) ... ary_myWeapons ... #endif
|
||||
|
||||
// And the network-crash is from ... not sending the entire inventory every single frame.
|
||||
// ... Marvelous. But at least that's a completely separate issue, again with or without below.
|
||||
|
||||
// (force a sendoff, expect it area)
|
||||
/*
|
||||
#ifdef SERVER
|
||||
// Force a sendoff!
|
||||
//SendFlags |= PLAYER_WEAPON;
|
||||
#else
|
||||
SAVE_STATE(activeweapon);
|
||||
SAVE_STATE(inventoryEquippedIndex);
|
||||
// unsure if this one's needed
|
||||
//SAVE_STATE(inventoryEquippedIndex);
|
||||
#endif
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1447,8 +1491,10 @@ player::frameThink_fromServer(void){
|
|||
|
||||
if(autocvar_sv_printoutspam == 1){
|
||||
printfline("My state: %d", iState);
|
||||
printfline("STATUS: %d, %i", activeweapon, inventoryEquippedIndex);
|
||||
}
|
||||
|
||||
|
||||
if(fKarateStamina < 1.0){
|
||||
fKarateStamina = bound(0, fKarateStamina + frametime * 0.1667, 1);
|
||||
}
|
||||
|
@ -1779,6 +1825,8 @@ player::dropWeapon(int arg_weaponID, BOOL completeDrop){
|
|||
}
|
||||
|
||||
// playerEquipIdealSafe ? Not quite.
|
||||
|
||||
printfline("setInventoryEquippedIndex: FLAG B");
|
||||
TS_resetViewModel(this);
|
||||
setInventoryEquippedIndex(-1);
|
||||
weaponEquippedAkimbo = FALSE;
|
||||
|
|
|
@ -21,19 +21,6 @@ void SharedGame_Precache(void){
|
|||
// In FreeTS, looks like shell eject effects are precached both client & serverside
|
||||
// (so here in shared/precache.qc is good).
|
||||
|
||||
// nearly identical..?
|
||||
precache_model("models/56_shell.mdl");
|
||||
precache_model("models/556_shell.mdl");
|
||||
|
||||
// identical..?
|
||||
precache_model("models/22_shell.mdl");
|
||||
precache_model("models/9mm_shell.mdl");
|
||||
precache_model("models/shell.mdl");
|
||||
|
||||
precache_model("models/shotgun_shell.mdl");
|
||||
precache_model("models/shotgun_shell_blue.mdl");
|
||||
precache_model("models/shotgun_shell_gold.mdl");
|
||||
|
||||
// physics-related / slow-mo?
|
||||
precache_model("models/bullet.mdl");
|
||||
precache_model("models/long_bullet.mdl");
|
||||
|
@ -68,7 +55,7 @@ void SharedGame_Precache(void){
|
|||
precache_sound("items/gunpickup2.wav");
|
||||
|
||||
|
||||
//Needed, apparently.
|
||||
// Needed, apparently.
|
||||
precache_sound("common/null.wav");
|
||||
|
||||
//precache_sound("weapons/insert-shell.wav");
|
||||
|
@ -79,13 +66,9 @@ void SharedGame_Precache(void){
|
|||
// Same for others where that applies
|
||||
precache_sound("weapons/switch.wav");
|
||||
|
||||
precache_sound("weapons/shell.wav");
|
||||
precache_sound("weapons/sshell.wav");
|
||||
precache_sound("weapons/sshell1.wav");
|
||||
precache_sound("weapons/sshell2.wav");
|
||||
precache_sound("weapons/sshell3.wav");
|
||||
// from Valve, no need to clone this
|
||||
precache_model("sprites/glow02.spr");
|
||||
|
||||
precache_model("sprites/new/glow02.spr");
|
||||
//precache_sound("weapons/weapondrop.wav");
|
||||
|
||||
|
||||
|
@ -166,8 +149,4 @@ void SharedGame_Precache(void){
|
|||
//precache_sound("weapons/mp5/clipout.wav");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -66,12 +66,13 @@ typedef enum
|
|||
SNDP_STEYRTMP_FIRE_SIL,
|
||||
SNDP_UMP_FIRE,
|
||||
SNDP_UMP_FIRE_SIL,
|
||||
SNDP_USAS12_FIRE,
|
||||
SNDP_USAS12_FIRE/*,
|
||||
SNDP_EXPLODE,
|
||||
SNDP_EXPLODE1,
|
||||
SNDP_EXPLODE2,
|
||||
SNDP_EXPLODE3,
|
||||
SNDP_EXPLODE4
|
||||
*/
|
||||
} sfx_pitched_t;
|
||||
|
||||
|
||||
|
@ -155,12 +156,13 @@ const string sfx_pitched_s[] =
|
|||
"weapons/tmp/fire-sil.wav",
|
||||
"weapons/ump/ump-fire.wav",
|
||||
"weapons/ump/ump-fire-sil.wav",
|
||||
"weapons/usas/usas-fire.wav",
|
||||
"weapons/usas/usas-fire.wav"/*,
|
||||
"explo/explode.wav",
|
||||
"explo/explode1.wav",
|
||||
"explo/explode2.wav",
|
||||
"explo/explode3.wav",
|
||||
"explo/explode4.wav"
|
||||
*/
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -100,6 +100,11 @@
|
|||
// NOTE - if you do indeed want the current entity to become of the new type,
|
||||
// then moving around 'self' like this is unnecessary, just call the 'pawnfunc_'
|
||||
// as usual.
|
||||
// I'm fuzzy on the details between 'spawn(CLASSNAME)' and 'spawnfunc_CLASSNAME'.
|
||||
// If you don't know what you're doing just spawn a clean entity like the former
|
||||
// approach, this is actually for changing something already spawened into another
|
||||
// type. Parse functions may do this to turn a default entity they receive into
|
||||
// whatever their custom type is, as seen in ts_powerup
|
||||
#define SPAWN_ENTITY_SAFE(arg_dest, arg_class) \
|
||||
eold = self;\
|
||||
self = arg_dest;\
|
||||
|
@ -266,6 +271,7 @@ float safeRandom(void);
|
|||
#ifdef SERVER
|
||||
void removeSelfDelayed(entity entTarget);
|
||||
#endif
|
||||
void entity_removeSelf(void);
|
||||
|
||||
string floatToChar(float someFloat);
|
||||
|
||||
|
|
|
@ -140,9 +140,6 @@ float safeRandom(void){
|
|||
|
||||
|
||||
|
||||
static void entity_removeSelf(void);
|
||||
|
||||
|
||||
// Called for some things, like grenades, that don't behave as well
|
||||
// when removed instantly by "remove(self)".
|
||||
// This gives a slight delay so that the pain logic still receives
|
||||
|
@ -150,7 +147,7 @@ static void entity_removeSelf(void);
|
|||
// As for why we couldn't just send the coords of the grenade from the
|
||||
// server's end, no idea.
|
||||
// Only lets you specify the entity to GET a location from, and if the
|
||||
// entity disappears to soon, no location gets sent.
|
||||
// entity disappears too soon, no location gets sent.
|
||||
#ifdef SERVER
|
||||
void removeSelfDelayed(entity entTarget){
|
||||
|
||||
|
@ -180,7 +177,7 @@ void removeSelfDelayed(entity entTarget){
|
|||
}
|
||||
#endif
|
||||
|
||||
static void entity_removeSelf(void){
|
||||
void entity_removeSelf(void){
|
||||
remove(self); //that's it.
|
||||
}
|
||||
|
||||
|
|
|
@ -946,8 +946,12 @@ int getAmmoTypeOfWeapon(int arg_weaponID);
|
|||
|
||||
|
||||
#ifdef CLIENT
|
||||
void viewEv_playShotgunInsertShellSound(void);
|
||||
|
||||
void w_ejectshell_pistol(void);
|
||||
// TEMP DUMMY
|
||||
void w_ejectshell_pistol(void){};
|
||||
|
||||
void viewEv_weapon_ejectShell(void);
|
||||
|
||||
void copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src);
|
||||
void copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src);
|
||||
|
|
|
@ -156,97 +156,114 @@ weapon_base_onPrimaryAttack_melee_fromCustomDirection(
|
|||
|
||||
|
||||
if ( trace_fraction == 1.0 ) {
|
||||
//did not hit anything
|
||||
// did not hit anything
|
||||
return MELEE_HIT_RESPONSE::NONE;
|
||||
}
|
||||
|
||||
// ? For what purpose now?
|
||||
//vOrigin = trace_endpos - vTraceDirection * 2;
|
||||
|
||||
if ( trace_ent.takedamage ) {
|
||||
|
||||
if ( trace_ent.takedamage ){
|
||||
if ( trace_ent.iBleeds == TRUE ) {
|
||||
FX_Impact( IMPACT_FLESH, trace_endpos, trace_plane_normal );
|
||||
resultHit = MELEE_HIT_RESPONSE::FLESH;
|
||||
// end early!
|
||||
|
||||
//TAGGG - other Damage_Apply examples:
|
||||
// snark hit
|
||||
//Damage_Apply(this, world, 1, 0, DMG_GENERIC);
|
||||
// crossbow bolt touch
|
||||
//Damage_Apply(other, self.owner, Skill_GetValue("plr_xbow_bolt_monster", 50), WEAPON_CROSSBOW, DMG_BLUNT);
|
||||
|
||||
// Also calling the damage type 'SLASH' for now, all dedicated melee weapons are knife or sword-like
|
||||
Damage_Apply( trace_ent, pl, damageToDeal, (int)pl.activeweapon, DMG_SLASH);
|
||||
return resultHit;
|
||||
}else{
|
||||
//assume metal then?
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
// let the logic run as normal below, don't assume metal
|
||||
// resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
// return resultHit;
|
||||
}
|
||||
}
|
||||
|
||||
// Not very useful
|
||||
//FX_Impact( IMPACT_MELEE, trace_endpos, trace_plane_normal );
|
||||
|
||||
float surf;
|
||||
string tex;
|
||||
string texFilter;
|
||||
|
||||
surf = getsurfacenearpoint(trace_ent, trace_endpos);
|
||||
tex = getsurfacetexture(trace_ent, surf);
|
||||
|
||||
// no strtolower needed on tex first? Nuclide's shared/src/traceattack.qc doesn't
|
||||
texFilter = Materials_FixName(tex);
|
||||
|
||||
//--- HELPFUL PRINTOUT ---
|
||||
//printfline("I hit: %s ::: %s", floatToChar((float)hash_get(hashMaterials, texFilter)), texFilter );
|
||||
//printfline("weapon_base_onPrimaryAttack_melee_fromCustomDirection - I hit: %s", chr2str((float)hash_get(hashMaterials, texFilter)) );
|
||||
|
||||
|
||||
// FLESH, BLOODYFLESH, SLOSH, FOLIAGE, ALIEN, and CONCRETE are all guesses.
|
||||
// Several others might be anyway, just extra unsure of these, if any TS map
|
||||
// even uses them.
|
||||
switch ((float)hash_get(hashMaterials, texFilter)) {
|
||||
|
||||
//TAGGG - other Damage_Apply examples:
|
||||
// snark hit
|
||||
//Damage_Apply(this, world, 1, 0, DMG_GENERIC);
|
||||
// crossbow bolt touch
|
||||
//Damage_Apply(other, self.owner, Skill_GetValue("plr_xbow_bolt_monster", 50), WEAPON_CROSSBOW, DMG_BLUNT);
|
||||
|
||||
// Also calling the damage type 'SLASH' for now, all dedicated melee weapons are knife or sword-like
|
||||
case MATID_FLESH:
|
||||
case MATID_BLOODYFLESH:
|
||||
case MATID_SLOSH:
|
||||
case MATID_FOLIAGE:
|
||||
FX_Impact_Melee(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case MATID_ALIEN:
|
||||
case MATID_CONCRETE:
|
||||
case MATID_GRATE:
|
||||
case MATID_VENT:
|
||||
FX_Impact_Melee(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case MATID_METAL:
|
||||
FX_Impact_Melee(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case MATID_COMPUTER:
|
||||
FX_Impact_Melee(IMPACT_COMPUTER, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case MATID_DIRT:
|
||||
FX_Impact_Melee(IMPACT_DIRT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case MATID_WOOD:
|
||||
FX_Impact_Melee(IMPACT_WOOD, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case MATID_GLASS:
|
||||
FX_Impact_Melee(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case MATID_SNOW:
|
||||
//'N' means snow apparently.
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case MATID_TILE:
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
default:
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( trace_ent.takedamage ){
|
||||
// Deal it now then
|
||||
Damage_Apply( trace_ent, pl, damageToDeal, (int)pl.activeweapon, DMG_SLASH);
|
||||
} else {
|
||||
// not a damage-able? okay.
|
||||
//FX_Impact( IMPACT_MELEE, trace_endpos, trace_plane_normal );
|
||||
|
||||
float surf;
|
||||
string tex;
|
||||
|
||||
surf = getsurfacenearpoint(trace_ent, trace_endpos);
|
||||
tex = getsurfacetexture(trace_ent, surf);
|
||||
|
||||
|
||||
#ifndef TEXTURE_LENGTH_LIMIT
|
||||
//nothing to do here.
|
||||
#else
|
||||
//Enforce the cutoff.
|
||||
//...I know texture names above weren't enforced to be lowercase,
|
||||
// but isn't it a good idea to do it here anyway?
|
||||
tex = strtolower(substring(tex, 0, TEXTURE_LENGTH_LIMIT));
|
||||
#endif
|
||||
|
||||
//printfline("I hit: %s ::: %s", floatToChar((float)hash_get(hashMaterials, tex)), tex );
|
||||
printfline("weapon_base_onPrimaryAttack_melee_fromCustomDirection - I hit: %s", chr2str((float)hash_get(hashMaterials, tex)) );
|
||||
|
||||
switch ((float)hash_get(hashMaterials, tex)) {
|
||||
case 'G':
|
||||
case 'V':
|
||||
FX_Impact_Melee(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case 'M':
|
||||
FX_Impact_Melee(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break; //...why did we forget to put a break here? no reason, right?
|
||||
//TAGGG - handling computers separately.
|
||||
case 'P':
|
||||
FX_Impact_Melee(IMPACT_COMPUTER, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
//TAGGG - handle dirt separately.
|
||||
case 'D':
|
||||
FX_Impact_Melee(IMPACT_DIRT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case 'W':
|
||||
FX_Impact_Melee(IMPACT_WOOD, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case 'Y':
|
||||
FX_Impact_Melee(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
case 'N':
|
||||
//'N' means snow apparently.
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::SOFT;
|
||||
break;
|
||||
case 'T':
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
default:
|
||||
FX_Impact_Melee(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
resultHit = MELEE_HIT_RESPONSE::METAL;
|
||||
break;
|
||||
}
|
||||
|
||||
}// trace_ent.takedamage check
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return resultHit;
|
||||
|
@ -503,13 +520,6 @@ weapon_shotgun_reload(
|
|||
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
void viewEv_playShotgunInsertShellSound(void){
|
||||
player pl = (player)self;
|
||||
sound(pl, CHAN_AUTO, "weapons/insert-shell.wav", 1, ATTN_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// NOTICE - shotguns with typical shotgun reload logic should use this method at all
|
||||
// times. It includes checks for whether the shotgun is actually reloading or not
|
||||
|
@ -1821,17 +1831,15 @@ weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t
|
|||
|
||||
|
||||
|
||||
// Not to be confused with the clientside-only event "weapon_ejectShell_event".
|
||||
// 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
|
||||
// for it to see. If shell-ejects are done serverside, that would not be an amazing
|
||||
// idea. Per-player would be better.
|
||||
void weapon_ejectShell(int arg_shellEjectType){
|
||||
//ary_shellEjectData[arg_shellEjectType]...
|
||||
|
||||
#ifdef CLIENT
|
||||
player pl = (player)self;
|
||||
pl.iShellEjectType = arg_shellEjectType;
|
||||
View_AddEvent(w_ejectshell_pistol, 0.0f);
|
||||
View_AddEvent(viewEv_weapon_ejectShell, 0.0f);
|
||||
#else
|
||||
// anything for the playermodel? Also only do that for all players except the
|
||||
// localplayer if using a viewmodel.
|
||||
|
@ -2217,6 +2225,7 @@ getAmmoTypeOfWeapon(int arg_weaponID)
|
|||
|
||||
|
||||
|
||||
|
||||
// This is based off what the HL glock does, adjust with custom shell-choices per
|
||||
// different weapons that use them.
|
||||
// Is HL's "w_shotgun_ejectshell" even any different from this besides shell-model
|
||||
|
@ -2227,87 +2236,24 @@ getAmmoTypeOfWeapon(int arg_weaponID)
|
|||
// Try testing FreeHL or FreeCS, do you see your own shells in thirdperson on firing
|
||||
// and (multiplayer) do other players see your shells on firing?
|
||||
|
||||
// TODO: rename to weapon_ejectShell_event
|
||||
#ifdef CLIENT
|
||||
|
||||
void
|
||||
w_ejectshell_pistol(void)
|
||||
viewEv_playShotgunInsertShellSound(void)
|
||||
{
|
||||
|
||||
// is it wise to trust 'self' in events? No idea
|
||||
//player pl = (player)self;
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
static void weapon_ejectshell_remove(void) {
|
||||
remove(self);
|
||||
}
|
||||
static void weapon_ejectshell_touch(void) {
|
||||
if(other == world){
|
||||
// TODO, use custom
|
||||
Sound_Play(self, CHAN_BODY, "modelevent_shell.land");
|
||||
//shellejectdata_t* mySED = aryShellEjectData[pl.iShellEjectType];
|
||||
//Sound_Play(self, CHAN_BODY, (*mySED).sTouchSound);
|
||||
}
|
||||
}
|
||||
vector vOrigin;
|
||||
entity eShell = spawn();
|
||||
|
||||
// TODO, use custom
|
||||
setmodel(eShell, "models/shell.mdl");
|
||||
//shellejectdata_t* mySED2 = aryShellEjectData[pl.iShellEjectType];
|
||||
//setmodel(eShell, (*mySED2).sModelPath);
|
||||
|
||||
eShell.solid = SOLID_BBOX;
|
||||
eShell.movetype = MOVETYPE_BOUNCE;
|
||||
eShell.drawmask = MASK_ENGINE;
|
||||
eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0];
|
||||
eShell.velocity = pSeat->m_vecPredictedVelocity;
|
||||
sound(pl, CHAN_AUTO, "weapons/insert-shell.wav", 1, ATTN_NONE);
|
||||
}
|
||||
|
||||
makevectors(pSeat->m_eViewModel.angles);
|
||||
eShell.velocity += (v_forward * 0);
|
||||
eShell.velocity += (v_right * 80);
|
||||
eShell.velocity += (v_up * 100);
|
||||
|
||||
eShell.touch = weapon_ejectshell_touch;
|
||||
|
||||
eShell.avelocity = [0,45,900];
|
||||
eShell.think = weapon_ejectshell_remove;
|
||||
eShell.nextthink = time + 2.5f;
|
||||
setsize(eShell, [0,0,0], [0,0,0]);
|
||||
|
||||
|
||||
|
||||
// TODO: I think attachments supply a direction too, fuzzy on the details,
|
||||
// player predraw (client/player.qc) definitely has something like that to put the
|
||||
// viewmodel laser-start or flashlight sprite glow effect in the right place.
|
||||
|
||||
// FreeHL way (forget all the rest if so)
|
||||
vOrigin = pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4);
|
||||
|
||||
/*
|
||||
// way #1
|
||||
//vOrigin = pSeat->m_eViewModel.origin;
|
||||
// way #2: old codebase way?
|
||||
//vOrigin = pSeat->m_vecPredictedOrigin + [0, 0, getstatf(STAT_VIEWHEIGHT)];
|
||||
|
||||
// way #3
|
||||
// "pSeat->m_iVMBones + 1" gets the first attachment, add more to get other
|
||||
// attachments, or places on the model that can be helpful to tie into
|
||||
// Although this is still making shell ejections happen at the end of the muzzle
|
||||
// and the other attachments just go further out?
|
||||
vector vOffset = gettaginfo(pSeat->m_eViewModel, pSeat->m_iVMBones + 1);
|
||||
printfline("WHAT?! %.2f %.2f %.2f", vOffset[0], vOffset[1], vOffset[2]);
|
||||
|
||||
// way #3a
|
||||
// assumes a vOrigin provided by earlier
|
||||
//vOrigin += (v_forward * vOffset[0]);
|
||||
//vOrigin += (v_right * -vOffset[1]);
|
||||
//vOrigin += (v_up * vOffset[2]) ;
|
||||
|
||||
// way #3b
|
||||
// or only be vOffset
|
||||
vOrigin = vOffset;
|
||||
*/
|
||||
setorigin(eShell, vOrigin);
|
||||
|
||||
}//weapon_ejectShell_event
|
||||
void
|
||||
viewEv_weapon_ejectShell(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
CShellEject::generate(pl.iShellEjectType);
|
||||
}//viewEv_weapon_ejectShell
|
||||
|
||||
|
||||
// also clientside only, dealing with configs
|
||||
|
|
|
@ -176,11 +176,10 @@ w_glock18_primary(void)
|
|||
|
||||
#ifdef CLIENT
|
||||
View_ShowMuzzleflash(MUZZLE_SMALL);
|
||||
|
||||
View_AddEvent(w_ejectshell_pistol, 0.0f);
|
||||
// TODO:
|
||||
//weapon_showMuzzleFlash(MUZZLE_SMALL);
|
||||
#endif
|
||||
|
||||
// TODO: replace View_AddEvent
|
||||
weapon_ejectShell(SHELLEJECT_ID::_9MM);
|
||||
|
||||
|
||||
|
|
|
@ -20,114 +20,14 @@ void weapon_m61grenade_onSecondaryAttackRelease(player pl, weapondynamic_t arg_t
|
|||
|
||||
|
||||
//Serverside only method, generates an entity
|
||||
// TODO - just be an entity in its own file at this point.
|
||||
#ifdef SERVER
|
||||
|
||||
static void weapon_m61grenade_Touch( void );
|
||||
static void weapon_m61grenade_Explode( void );
|
||||
|
||||
void weapon_m61grenade_spawnProjectile(player pl, weapondynamic_t arg_thisWeapon, BOOL wasToss, float heldDuration){
|
||||
|
||||
weapondata_throwable_t basicRef = *((weapondata_throwable_t*)ary_weaponData[WEAPON_ID::M61GRENADE]);
|
||||
|
||||
makevectors( GET_VIEW_ANGLES );
|
||||
entity eNade = spawn();
|
||||
setorigin( eNade, ( pl.origin + pl.view_ofs ) + ( v_forward * 16 ) );
|
||||
setmodel( eNade, basicRef.sWorldModelPath );
|
||||
setsize( eNade, '-1 -1 -1', '1 1 1' );
|
||||
|
||||
makevectors( GET_VIEW_ANGLES );
|
||||
vector vGrenadeOrigin = (pl.origin + pl.view_ofs) + (v_forward * 16);
|
||||
vector vDir = aim ( pl, 100000 );
|
||||
eNade.owner = pl;
|
||||
eNade.classname = "remove_me";
|
||||
eNade.solid = SOLID_TRIGGER; // This is so grenades will not get slowed down by windows they touch
|
||||
eNade.angles = vectoangles( vDir );
|
||||
|
||||
// TODO, CRITICAL.
|
||||
// Factor in wasToss, heldDuration (out of 3, small minimum from clicking without holding down while
|
||||
// some of the toss anim plays)?
|
||||
eNade.velocity = ( vDir * 200 ); //was 1000
|
||||
|
||||
eNade.avelocity = ( v_forward * 1000 );
|
||||
eNade.movetype = MOVETYPE_BOUNCE;
|
||||
eNade.touch = weapon_m61grenade_Touch;
|
||||
eNade.gravity = 0.5f;
|
||||
|
||||
eNade.think = weapon_m61grenade_Explode;
|
||||
eNade.nextthink = time + 3.0f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void weapon_m61grenade_Touch( void ) {
|
||||
float randomChoice;
|
||||
if ( other.solid == SOLID_TRIGGER ) {
|
||||
return;
|
||||
}
|
||||
if ( other == self.owner ) {
|
||||
return;
|
||||
}
|
||||
if ( ( other.classname == "func_breakable" ) && ( other.material == GSMATERIAL_GLASS ) ) {
|
||||
// this means, insta-break the breakable glass we hit.
|
||||
// Calling this BLUNT I guess? The grenade is really a rock at this point.
|
||||
Damage_Apply( other, self.owner, other.health, WEAPON_ID::M61GRENADE, DMG_BLUNT);
|
||||
}
|
||||
|
||||
randomChoice = random();
|
||||
if(randomChoice < 0.25){
|
||||
sound(self, CHAN_WEAPON, "weapons/grenbounce1.wav", 1, ATTN_NORM);
|
||||
}else if(randomChoice < 0.5){
|
||||
sound(self, CHAN_WEAPON, "weapons/grenbounce2.wav", 1, ATTN_NORM);
|
||||
}else if(randomChoice < 0.75){
|
||||
sound(self, CHAN_WEAPON, "weapons/grenbounce3.wav", 1, ATTN_NORM);
|
||||
}else{
|
||||
sound(self, CHAN_WEAPON, "weapons/grenbounce4.wav", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void weapon_m61grenade_Explode( void ) {
|
||||
float randomChoice;
|
||||
|
||||
//!!! THIS IS THE COUNTERSTRIKE EFFECT.
|
||||
// Comment/uncomment as needed.
|
||||
// we redirect this to the new lines for TS. Easier to keep
|
||||
// the change to env_explosion and func_breakables that explode.
|
||||
Effect_CreateExplosion( self.origin );
|
||||
|
||||
//Effect_ScreenShake( self.origin, 2048, 255 );
|
||||
//Effect_Explosion( self.origin + [0,0,16] );
|
||||
|
||||
// Is this accurate? I just know a grenade can kill a player with around
|
||||
// 150 health from a powerup, and takes 100 down to 20 from a good distance.
|
||||
// CHANGE! Don't we want to tell who attacked (who threw the grenade), not just give
|
||||
// the grenade itself for the 2nd "eAttacker" parameter?
|
||||
Damage_Radius( self.origin, self.owner, 160, 380, TRUE, WEAPON_ID::M61GRENADE );
|
||||
//Damage_Radius( self.origin, self, 75, 550, TRUE, WEAPON_ID::M61GRENADE );
|
||||
|
||||
//Damage_Apply(other, this, m_iDamage, WEAPON_ID::M61GRENADE, DMG_GENERIC);
|
||||
|
||||
// this is mad old
|
||||
//Damage_Apply(plPlayer, world, plPlayer.dmg, DAMAGE_DROWNING, WEAPON_NONE);
|
||||
//Damage_Apply(target, world, 5, DMG_DROWN, 0);
|
||||
|
||||
//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!
|
||||
// ...weird, I know.
|
||||
//remove( self );
|
||||
removeSelfDelayed(self);
|
||||
TSGrenadeProjectile::generate(pl, vGrenadeOrigin, vDir, v_forward, WEAPON_ID::M61GRENADE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -338,8 +238,8 @@ w_m61grenade_precache(void)
|
|||
{
|
||||
weapon_precache(ary_weaponData[WEAPON_ID::M61GRENADE]);
|
||||
#ifdef SERVER
|
||||
// grenade-bounce and explode ones are done globally, I could see those
|
||||
// being re-used
|
||||
// grenade-bounce and explode sounds are precached in
|
||||
// TSGrenadeProjectile::precache and fx_ts_explosion_grenade_Init respectively
|
||||
//precache_sound("weapons/gr_pull.wav");
|
||||
//precache_sound("weapons/gr_safe.wav");
|
||||
#else
|
||||
|
|
|
@ -23,24 +23,19 @@ bind "MWHEELDOWN" "invnext"
|
|||
bind "MWHEELUP" "invprev"
|
||||
bind r +reload
|
||||
bind e +use
|
||||
bind n nightvision
|
||||
bind g drop
|
||||
bind TAB +showscores
|
||||
bind c radio3
|
||||
bind x radio2
|
||||
bind z radio1
|
||||
bind y messagemode
|
||||
bind u messagemode2
|
||||
bind t "impulse 201"
|
||||
bind f "impulse 100"
|
||||
|
||||
bind SPACE +jump
|
||||
bind CTRL +duck
|
||||
bind SHIFT +speed
|
||||
|
||||
bind b buy
|
||||
bind m chooseteam
|
||||
bind ESC togglemenu
|
||||
bind b "buy"
|
||||
bind m "chooseteam"
|
||||
bind ESC "togglemenu"
|
||||
|
||||
// Game variables
|
||||
seta maxplayers 8
|
||||
|
@ -80,7 +75,6 @@ seta vgui_color "255 170 0"
|
|||
seta cross_color "0 255 0"
|
||||
|
||||
hostname "Free Specialists Server"
|
||||
seta vid_conautoscale "1"
|
||||
|
||||
seta r_polygonoffset_submodel_offset "0"
|
||||
seta r_polygonoffset_submodel_factor "0"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
name "16"
|
||||
font "gfx/shell/arial.ttf"
|
||||
size "16"
|
|
@ -1,3 +0,0 @@
|
|||
name "cr"
|
||||
font "gfx/shell/arial.ttf"
|
||||
size "20"
|
|
@ -1,3 +0,0 @@
|
|||
name "font"
|
||||
font ""
|
||||
size "12"
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
fx_explosion, fx_impact, and fx_spark.cfg are copied from FreeHL ("valve" folder). If these end up unused by FreeTS, remove accordingly.
|
||||
|
||||
explosion.cfg is for a grenade explosion effect ripped from an old version of FreeCS I think (if not, The Wastes, but I doubt this).
|
||||
|
||||
Same for the sound script files (mirrored in the sound folder adjacent to this dir)
|
|
@ -1,69 +0,0 @@
|
|||
r_part ember
|
||||
{
|
||||
count 1
|
||||
texture "particles/fteparticlefont.tga"
|
||||
tcoords 97 97 191 191 256
|
||||
rgb 255 128 76
|
||||
alpha 0
|
||||
scale 15
|
||||
scalefactor 1
|
||||
friction 8
|
||||
gravity 50
|
||||
die 1.5
|
||||
blend add
|
||||
randomvel 5
|
||||
veladd 1
|
||||
rampmode delta
|
||||
ramp 0 0 0 -0.5 0
|
||||
ramp 0 0 0 0.1 0
|
||||
ramp 0 0 0 0.1 0
|
||||
ramp 0 0 0 0.1 0
|
||||
ramp 0 0 0 0.1 0
|
||||
ramp 0 0 0 0.1 0
|
||||
}
|
||||
|
||||
r_part expgib
|
||||
{
|
||||
cliptype expgib
|
||||
texture "particles/fteparticlefont.tga"
|
||||
tcoords 97 97 191 191 256
|
||||
alpha 0
|
||||
count 16
|
||||
die 1
|
||||
randomvel 128
|
||||
gravity 50
|
||||
friction 2
|
||||
emit ember
|
||||
emitinterval 0.01
|
||||
spawnmode circle
|
||||
}
|
||||
|
||||
r_part main
|
||||
{
|
||||
texture "particles/fteparticlefont.tga"
|
||||
tcoords 97 97 191 191 256
|
||||
count 1
|
||||
scale 200
|
||||
scalefactor 1
|
||||
die 1
|
||||
rgb 255 128 76
|
||||
rgbdelta 0 -32 -32
|
||||
friction 1
|
||||
blend add
|
||||
assoc expgib
|
||||
}
|
||||
|
||||
r_part blacksmoke
|
||||
{
|
||||
texture "particles/fteparticlefont.tga"
|
||||
tcoords 97 97 191 191 256
|
||||
count 1
|
||||
scale 324
|
||||
scalefactor 1
|
||||
die 3
|
||||
alpha 1
|
||||
rgb 0 0 0
|
||||
spawnmode ball
|
||||
gravity -25
|
||||
veladd -20
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
r_part spark
|
||||
{
|
||||
type texturedspark
|
||||
texture ball
|
||||
tcoords 1 65 31 95 256 8 32
|
||||
scale 1
|
||||
count 8
|
||||
scalefactor 1
|
||||
alpha 0.5
|
||||
die 0.8
|
||||
rgb 255 115 0
|
||||
blend add
|
||||
spawnmode ball
|
||||
spawnorg 1
|
||||
spawnvel 100
|
||||
veladd 100
|
||||
friction 0.5
|
||||
gravity 800
|
||||
}
|
||||
|
||||
r_part blackbits
|
||||
{
|
||||
type ball
|
||||
texture ball
|
||||
tcoords 1 65 31 95 256 8 32
|
||||
scale 4
|
||||
count 18
|
||||
scalefactor 1
|
||||
alpha 1
|
||||
die 0.8
|
||||
rgb 25 25 25
|
||||
spawnmode ball
|
||||
spawnorg 1
|
||||
spawnvel 100
|
||||
veladd 100
|
||||
friction 0.3
|
||||
gravity 800
|
||||
}
|
||||
|
||||
r_part smoke_brown
|
||||
{
|
||||
texture ball
|
||||
tcoords 1 65 31 95 256 8 32
|
||||
count 3
|
||||
scale 25
|
||||
scalefactor 1
|
||||
die 1
|
||||
alpha 0.5
|
||||
rgb 155 90 0
|
||||
blend add
|
||||
spawnmode ball
|
||||
spawnorg 2
|
||||
spawnvel 20
|
||||
veladd 20
|
||||
}
|
||||
|
||||
r_part smoke_grey
|
||||
{
|
||||
texture ball
|
||||
tcoords 1 65 31 95 256 8 32
|
||||
count 3
|
||||
scale 25
|
||||
scalefactor 1
|
||||
die 1
|
||||
alpha 0.5
|
||||
rgb 25 25 25
|
||||
blend add
|
||||
spawnmode ball
|
||||
spawnorg 2
|
||||
spawnvel 20
|
||||
veladd 20
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
r_part effect
|
||||
{
|
||||
type texturedspark
|
||||
texture ball
|
||||
tcoords 1 65 31 95 256 8 32
|
||||
scale 1
|
||||
count 8
|
||||
scalefactor 1
|
||||
alpha 0.5
|
||||
die 0.8
|
||||
rgb 255 115 0
|
||||
blend add
|
||||
spawnmode ball
|
||||
spawnorg 1
|
||||
spawnvel 100
|
||||
veladd 100
|
||||
friction 0.5
|
||||
gravity 800
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fx.ts_explosion_grenade
|
||||
{
|
||||
pitch 400
|
||||
shakes 2.7
|
||||
sample explo/explode.wav
|
||||
sample explo/explode1.wav
|
||||
sample explo/explode2.wav
|
||||
sample explo/explode3.wav
|
||||
sample explo/explode4.wav
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
fx.explosion
|
||||
{
|
||||
sample weapons/explode3.wav
|
||||
sample weapons/explode4.wav
|
||||
sample weapons/explode5.wav
|
||||
shakes 1.5
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
// Volume modifiers for most of these, up to taste.
|
||||
|
||||
sfx_impact.default
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/cement1.wav
|
||||
sample debris/cement2.wav
|
||||
sample debris/cement3.wav
|
||||
sample debris/cement4.wav
|
||||
sample debris/cement5.wav
|
||||
sample debris/cement6.wav
|
||||
}
|
||||
|
||||
// Half-life leftover but using the TS default anyway
|
||||
sfx_impact.alien
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/cement1.wav
|
||||
sample debris/cement2.wav
|
||||
sample debris/cement3.wav
|
||||
sample debris/cement4.wav
|
||||
sample debris/cement5.wav
|
||||
sample debris/cement6.wav
|
||||
}
|
||||
|
||||
// Half-Life leftover, I doubt any TS maps even use this
|
||||
sfx_impact.flesh
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/flesh1.wav
|
||||
sample debris/flesh2.wav
|
||||
sample debris/flesh3.wav
|
||||
sample debris/flesh5.wav
|
||||
sample debris/flesh6.wav
|
||||
sample debris/flesh7.wav
|
||||
}
|
||||
|
||||
// A guess?
|
||||
sfx_impact.foliage
|
||||
{
|
||||
volume 0.50
|
||||
attenuation normal
|
||||
sample debris/gravel1.wav
|
||||
sample debris/gravel2.wav
|
||||
sample debris/gravel3.wav
|
||||
sample debris/gravel4.wav
|
||||
}
|
||||
|
||||
// Strangely, some surfaces like the remote control and some stereo faces in ts_bikini sound
|
||||
// like glass when hit, and use the computer material. So we'll treat that as a rule.
|
||||
sfx_impact.computer
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/glass1.wav
|
||||
sample debris/glass2.wav
|
||||
sample debris/glass3.wav
|
||||
sample debris/glass4.wav
|
||||
}
|
||||
|
||||
sfx_impact.dirt
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/gravel1.wav
|
||||
sample debris/gravel2.wav
|
||||
sample debris/gravel3.wav
|
||||
sample debris/gravel4.wav
|
||||
}
|
||||
|
||||
sfx_impact.vent
|
||||
{
|
||||
volume 0.75
|
||||
attenuation normal
|
||||
sample debris/metal1.wav
|
||||
sample debris/metal2.wav
|
||||
sample debris/metal3.wav
|
||||
sample debris/metal4.wav
|
||||
sample debris/metal5.wav
|
||||
}
|
||||
|
||||
sfx_impact.grate
|
||||
{
|
||||
volume 0.75
|
||||
attenuation normal
|
||||
sample debris/metal1.wav
|
||||
sample debris/metal2.wav
|
||||
sample debris/metal3.wav
|
||||
sample debris/metal4.wav
|
||||
sample debris/metal5.wav
|
||||
}
|
||||
|
||||
sfx_impact.metal
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/metal1.wav
|
||||
sample debris/metal2.wav
|
||||
sample debris/metal3.wav
|
||||
sample debris/metal4.wav
|
||||
sample debris/metal5.wav
|
||||
}
|
||||
|
||||
sfx_impact.glass
|
||||
{
|
||||
volume 0.75
|
||||
attenuation normal
|
||||
sample debris/glass1.wav
|
||||
sample debris/glass2.wav
|
||||
sample debris/glass3.wav
|
||||
sample debris/glass4.wav
|
||||
}
|
||||
|
||||
// guess? This type is never even referred to
|
||||
sfx_impact.sand
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/gravel1.wav
|
||||
sample debris/gravel2.wav
|
||||
sample debris/gravel3.wav
|
||||
sample debris/gravel4.wav
|
||||
}
|
||||
|
||||
sfx_impact.slosh
|
||||
{
|
||||
volume 0.50
|
||||
attenuation normal
|
||||
sample debris/cement1.wav
|
||||
sample debris/cement2.wav
|
||||
sample debris/cement3.wav
|
||||
sample debris/cement4.wav
|
||||
sample debris/cement5.wav
|
||||
sample debris/cement6.wav
|
||||
}
|
||||
|
||||
sfx_impact.snow
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/gravel1.wav
|
||||
sample debris/gravel2.wav
|
||||
sample debris/gravel3.wav
|
||||
sample debris/gravel4.wav
|
||||
}
|
||||
|
||||
sfx_impact.tile
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/cement1.wav
|
||||
sample debris/cement2.wav
|
||||
sample debris/cement3.wav
|
||||
sample debris/cement4.wav
|
||||
sample debris/cement5.wav
|
||||
sample debris/cement6.wav
|
||||
}
|
||||
|
||||
sfx_impact.wood
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/wood1.wav
|
||||
sample debris/wood2.wav
|
||||
sample debris/wood3.wav
|
||||
}
|
||||
|
||||
sfx_impact.concrete
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample debris/cement1.wav
|
||||
sample debris/cement2.wav
|
||||
sample debris/cement3.wav
|
||||
sample debris/cement4.wav
|
||||
sample debris/cement5.wav
|
||||
sample debris/cement6.wav
|
||||
}
|
||||
|
||||
|
||||
sfx_impact_melee.default
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample player/pl_step1.wav
|
||||
sample player/pl_step2.wav
|
||||
sample player/pl_step3.wav
|
||||
sample player/pl_step4.wav
|
||||
}
|
||||
sfx_impact_melee.dirt
|
||||
{
|
||||
volume 0.65
|
||||
attenuation normal
|
||||
sample player/pl_dirt1.wav
|
||||
sample player/pl_dirt2.wav
|
||||
sample player/pl_dirt3.wav
|
||||
sample player/pl_dirt4.wav
|
||||
}
|
||||
|
||||
|
|
@ -1,15 +1,25 @@
|
|||
|
||||
//TAGGG - reducing volume all around a little
|
||||
|
||||
// from the Valve folder
|
||||
modelevent_shell.land
|
||||
{
|
||||
volume 0.65
|
||||
attenuation idle
|
||||
sample player/pl_shell1.wav
|
||||
sample player/pl_shell2.wav
|
||||
sample player/pl_shell3.wav
|
||||
}
|
||||
|
||||
//TAGGG - should we throw shell.wav and sshell.wav in there
|
||||
// from the TS files? Doing so for now.
|
||||
modelevent_shotgunshell.land
|
||||
{
|
||||
volume 0.4
|
||||
attenuation idle
|
||||
sample weapons/sshell1.wav
|
||||
sample weapons/sshell2.wav
|
||||
sample weapons/sshell3.wav
|
||||
sample weapons/sshell.wav
|
||||
sample weapons/shell.wav
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
weapon_m61grenade.bounce
|
||||
{
|
||||
sample weapons/grenbounce1.wav
|
||||
sample weapons/grenbounce2.wav
|
||||
sample weapons/grenbounce3.wav
|
||||
sample weapons/grenbounce4.wav
|
||||
}
|
Loading…
Reference in New Issue