grenade and ejected shell entity, unused FX cleanup, texture hit sounds restored, network issue noticed

This commit is contained in:
Christopher Dawalt 2021-08-10 09:14:46 -04:00
parent a0a70e7c9e
commit bfafbec9ad
52 changed files with 940 additions and 1343 deletions

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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);

View File

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

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -316,7 +316,7 @@ TSMultiplayerRules::PlayerDeath(base_player pp)
}// excess negative health gib check
printfline("setInventoryEquippedIndex Flag Z");
TS_resetViewModel(pl);
pl.setInventoryEquippedIndex(-1);

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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
}

View File

@ -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);

View File

@ -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,

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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

View File

@ -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);

View File

@ -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.
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -1,3 +0,0 @@
name "16"
font "gfx/shell/arial.ttf"
size "16"

View File

@ -1,3 +0,0 @@
name "cr"
font "gfx/shell/arial.ttf"
size "20"

View File

@ -1,3 +0,0 @@
name "font"
font ""
size "12"

View File

@ -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)

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,7 +0,0 @@
fx.explosion
{
sample weapons/explode3.wav
sample weapons/explode4.wav
sample weapons/explode5.wav
shakes 1.5
}

View File

@ -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
}

View File

@ -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
}

View File

@ -0,0 +1,8 @@
weapon_m61grenade.bounce
{
sample weapons/grenbounce1.wav
sample weapons/grenbounce2.wav
sample weapons/grenbounce3.wav
sample weapons/grenbounce4.wav
}