Radio messages are now being cast in a bandwidth friendly way

Added ability for mapobjects to respawn (only useful on ones that move/die)
Fixed bug that would "draw" the weapon twice, causing a double-soundcast on the SDL audio driver of FTEQW
This commit is contained in:
Marco Hladik 2016-12-07 20:38:26 +01:00
parent db0a11de32
commit 1290fb0daf
23 changed files with 305 additions and 86 deletions

View file

@ -105,6 +105,8 @@ void CSQC_Parse_Event( void ) {
vCameraAngle_z = readcoord();
fCameraTime = time + readfloat();
} else if ( fHeader == EV_RADIOMSG ) {
Radio_BroadcastMessage( readbyte() );
}
}

View file

@ -32,6 +32,8 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
precache_model( sViewModels[ i ] );
}
Radio_InitSounds();
CSQC_ConsoleCommand_Init();
CSQC_VGUI_Init();
}

View file

@ -36,6 +36,7 @@ Defs.h
../Shared/WeaponBase.c
../Shared/Weapons.c
../Shared/Effects.c
../Shared/Radio.c
../Server/AmbientSound.c

View file

@ -166,7 +166,8 @@ enum {
EV_WEAPON_SECONDARYATTACK,
EV_WEAPON_RELOAD,
EV_MODELGIB,
EV_CAMERATRIGGER
EV_CAMERATRIGGER,
EV_RADIOMSG
};
// Submodel materials

View file

@ -27,7 +27,7 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos
pointparticles( EFFECT_BLOOD, vHitPos, v_forward * -1, 1 );
}
entity eOld = self;
eOld = self;
self = eTarget;
if ( eTarget.health <= 0 ) {

View file

@ -72,6 +72,7 @@ int iBuyRestriction; // For info_map_parameters
.int iBleeds;
.void() vPain;
.void() vDeath;
.float fRespawns;
// All about +use
entity eActivator;
@ -115,5 +116,10 @@ float Player_GetMaxSpeed( float fWeapon );
void TraceAttack_FireBullets( int iShots );
void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius );
void Entities_InitRespawnable( void() vRespawnFunc );
void Entities_Respawn( void );
entity eOld;
// WIP
string __fullspawndata;

View file

@ -42,7 +42,7 @@ void hostage_pain( void ) {
// hosdown.wav
void hostage_die( void ) {
sound( world, CHAN_VOICE, "radio/hosdown.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_HOSDOWN );
self.frame = 30 + ceil( random() * 5);
self.solid = SOLID_NOT;
self.takedamage = DAMAGE_NO;
@ -160,26 +160,32 @@ Entry function for the hostages.
=================
*/
void hostage_entity( void ) {
precache_model( self.model );
setorigin( self, self.origin );
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_WALK;
setmodel( self, self.model );
setsize( self, VEC_HULL_MIN + '0 0 36', VEC_HULL_MAX + '0 0 36' );
self.customphysics = hostage_physics;
self.eUser = world;
self.eTargetPoint = world;
self.iUsable = TRUE;
self.iBleeds = TRUE;
self.takedamage = DAMAGE_YES;
self.vUse = hostage_use;
self.vPain = hostage_pain;
self.vDeath = hostage_die;
self.style = HOSTAGE_IDLE;
static void hostage_entity_respawn( void ) {
setorigin( self, self.origin );
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_WALK;
setmodel( self, self.model );
setsize( self, VEC_HULL_MIN + '0 0 36', VEC_HULL_MAX + '0 0 36' );
self.customphysics = hostage_physics;
self.eUser = world;
self.eTargetPoint = world;
self.iUsable = TRUE;
self.iBleeds = TRUE;
self.takedamage = DAMAGE_YES;
self.vUse = hostage_use;
self.vPain = hostage_pain;
self.vDeath = hostage_die;
self.style = HOSTAGE_IDLE;
self.frame = 13; // Idle frame
self.health = 100;
self.frame = 13; // Idle frame
self.health = 100;
}
precache_model( self.model );
hostage_entity_respawn();
iHostagesMax = iHostagesMax + 1; // Increase the global count of hostages
Entities_InitRespawnable( hostage_entity_respawn );
}

View file

@ -27,17 +27,23 @@ void Entities_UseTargets( void ) {
entity eFind = findchain( targetname, self.target );
while ( eFind ) {
entity eOldSelf = self;
eOld = self;
self = eFind;
eFind.vUse();
self = eOldSelf;
self = eOld;
eFind = eFind.chain;
}
}
/*
====================
Entities_UseTargets_Delay
====================
*/
void Entities_UseTargets_Delay( float fDelay ) {
static void Entities_UseTargets_Delay_Think( void ) {
entity eOld = self;
eOld = self;
self = self.owner;
Entities_UseTargets();
remove( eOld );
@ -52,12 +58,59 @@ void Entities_UseTargets_Delay( float fDelay ) {
/*
====================
Entities_Remove
Entities_InitRespawnable
Called
====================
*/
void Entities_Remove( void )
{
remove( self );
.string sOldModel;
.float fOldSolid;
.float fOldHealth;
.vector vOldOrigin;
.vector vOldAngle;
.float fOldAlpha;
.vector vOldColorMod;
.float fOldEffects;
.void() vRespawn;
void Entities_InitRespawnable( void() vRespawnFunc ) {
self.sOldModel = self.model;
self.fOldSolid = self.solid;
self.fOldHealth = self.health;
self.vOldOrigin = self.origin;
self.vOldAngle = self.angles;
self.fOldAlpha = self.alpha;
self.vOldColorMod = self.colormod;
self.fOldEffects = self.effects;
self.vRespawn = vRespawnFunc;
self.fRespawns = TRUE;
}
void Entities_Respawn( void ) {
self.model = self.sOldModel;
self.solid = self.fOldSolid;
self.health = self.fOldHealth;
self.origin = self.vOldOrigin;
self.angles = self.vOldAngle;
self.alpha = self.fOldAlpha;
self.colormod = self.vOldColorMod;
self.effects = self.fOldEffects;
self.vRespawn();
}
/*
====================
Entities_Remove
Technically, it doesn't remove everything
====================
*/
void Entities_Remove( void ) {
if ( self.fRespawns == TRUE ) {
self.solid = SOLID_NOT;
self.model = 0;
} else {
remove( self );
}
}
/*

View file

@ -79,8 +79,6 @@ void env_render( void ) {
entity eFind = findchain( targetname, self.target );
while ( eFind ) {
entity eOldSelf = self;
if ( !( self.spawnflags & SF_NORENDERMODE ) ) {
eFind.rendermode = self.rendermode;
}

View file

@ -113,8 +113,7 @@ void func_breakable_die( void ) {
Effect_BreakModel( self.absmin, self.absmax, self.velocity, self.material );
Entities_UseTargets();
remove( self );
Entities_Remove();
}
void func_breakable_touch( void ) {
@ -157,20 +156,25 @@ Entry function for the brushes that can die etc.
=================
*/
void func_breakable( void ) {
func_wall();
if ( self.spawnflags & SF_TRIGGER ) {
self.takedamage = DAMAGE_NO;
} else {
self.takedamage = DAMAGE_YES;
self.vPain = func_breakable_pain;
self.vDeath = func_breakable_die;
self.iBleeds = FALSE;
static void func_breakable_respawn( void ) {
if ( self.spawnflags & SF_TRIGGER ) {
self.takedamage = DAMAGE_NO;
} else {
self.takedamage = DAMAGE_YES;
self.vPain = func_breakable_pain;
self.vDeath = func_breakable_die;
self.iBleeds = FALSE;
}
if ( self.spawnflags & SF_TOUCH || self.spawnflags & SF_PRESSURE ) {
self.touch = func_breakable_touch;
}
self.vUse = func_breakable_die;
}
if ( self.spawnflags & SF_TOUCH || self.spawnflags & SF_PRESSURE ) {
self.touch = func_breakable_touch;
}
func_wall();
func_breakable_respawn();
self.vUse = func_breakable_die;
Entities_InitRespawnable( func_breakable_respawn );
}

View file

@ -62,7 +62,6 @@ Called by StartFrame if we somehow got no buy zones
=================
*/
void Game_CreateBuyZones( void ) {
entity eOldSelf;
entity eFind;
if ( iBuyRestriction == BUY_T || iBuyRestriction == BUY_BOTH ) {
@ -71,11 +70,11 @@ void Game_CreateBuyZones( void ) {
while ( eFind ) {
entity eBuyZoneT = spawn();
setorigin( eBuyZoneT, eFind.origin );
eOldSelf = self;
eOld = self;
self = eBuyZoneT;
func_buyzone();
self.team = TEAM_T;
self = eOldSelf;
self = eOld;
eFind = eFind.chain;
}
}
@ -87,11 +86,11 @@ void Game_CreateBuyZones( void ) {
entity eBuyZoneCT = spawn();
setorigin( eBuyZoneCT, eFind.origin );
eOldSelf = self;
eOld = self;
self = eBuyZoneCT;
func_buyzone();
self.team = TEAM_CT;
self = eOldSelf;
self = eOld;
eFind = eFind.chain;
}
}

View file

@ -28,14 +28,18 @@ void func_hostage_rescue_touch( void ) {
other.fInHostageZone = TRUE; // Note: this will be cleared every frame inside SV_RunClientCommand
} else if ( other.classname == "hostage_entity" ) {
sound( world, CHAN_VOICE, "radio/rescued.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_RESCUED );
iHostagesRescued++;
other.eUser.fMoney += 1000;
if ( other.eTargetPoint != other.eUser ) {
remove( other.eTargetPoint );
}
remove( other );
eOld = self;
self = other;
Entities_Remove();
self = eOld;
if ( iHostagesRescued >= iHostagesMax ) {
// TODO: Broadcast_Print: All Hostages have been rescued!
@ -88,10 +92,10 @@ void Game_CreateRescueZones( void ) {
entity eRescueZone = spawn();
setorigin( eRescueZone, eFind.origin );
entity eOldSelf = self;
eOld = self;
self = eRescueZone;
info_hostage_rescue();
self = eOldSelf;
self = eOld;
eFind = eFind.chain;
}
}

View file

@ -74,22 +74,17 @@ void worldspawn( void ) {
EFFECT_GUNSHOT = particleeffectnum( "te_gunshot" );
EFFECT_BLOOD = particleeffectnum( "te_blood" );
precache_sound( "radio/moveout.wav" );
precache_sound( "radio/letsgo.wav" );
precache_sound( "radio/locknload.wav" );
precache_sound( "radio/rescued.wav" );
precache_sound( "radio/hosdown.wav" );
precache_sound( "radio/terwin.wav" );
precache_sound( "radio/ctwin.wav" );
precache_sound( "radio/rounddraw.wav" );
precache_sound( "radio/bombpl.wav" );
precache_sound( "hostage/hos1.wav" );
precache_sound( "hostage/hos2.wav" );
precache_sound( "hostage/hos3.wav" );
precache_sound( "hostage/hos4.wav" );
precache_sound( "hostage/hos5.wav" );
precache_sound( "player/pl_step1.wav" );
precache_sound( "player/pl_step2.wav" );
precache_sound( "player/pl_step3.wav" );
precache_sound( "player/pl_step4.wav" );
precache_sound( "items/9mmclip1.wav" );
precache_sound( "weapons/ak47-1.wav" );

View file

@ -58,12 +58,10 @@ float Rules_BuyingPossible( void ) {
// Loop through all players and respawn them
void Rules_Restart( void ) {
//localcmd( "restart_ents" );
entity eOldSelf;
entity eFind = findchain( classname, "player" );
while ( eFind ) {
eOldSelf = self;
eOld = self;
self = eFind;
if ( self.health > 0 ) {
@ -72,7 +70,7 @@ void Rules_Restart( void ) {
Spawn_CreateClient( self.fCharModel );
}
self = eOldSelf;
self = eOld;
eFind = eFind.chain;
}
@ -88,10 +86,10 @@ void Rules_Restart( void ) {
iPicked++;
if ( iPicked == iRandomT ) {
eOldSelf = self;
eOld = self;
self = eFind;
Weapon_AddItem( WEAPON_C4BOMB );
self = eOldSelf;
self = eOld;
}
}
@ -100,6 +98,16 @@ void Rules_Restart( void ) {
}
}
// Respawn all the entities
eFind = findchainfloat( fRespawns , TRUE );
while ( eFind ) {
eOld = self;
self = eFind;
Entities_Respawn();
self = eOld;
eFind = eFind.chain;
}
Timer_Begin( cvar( "mp_freezetime" ), GAME_FREEZE );
}
@ -111,13 +119,13 @@ void Rules_RoundOver( int iTeamWon ) {
}
if ( iTeamWon == TEAM_T ) {
sound( world, CHAN_VOICE, "radio/terwin.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_TERWIN );
iWon_T++;
} else if ( iTeamWon == TEAM_CT ) {
sound( world, CHAN_VOICE, "radio/ctwin.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_CTWIN );
iWon_CT++;
} else {
sound( world, CHAN_VOICE, "radio/rounddraw.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_ROUNDDRAW );
}
Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts

View file

@ -98,7 +98,7 @@ void Spawn_CreateClient( float fCharModel ) {
Weapon_AddItem( WEAPON_KNIFE );
Weapon_AddItem( WEAPON_GLOCK18 );
Weapon_GiveAmmo( WEAPON_GLOCK18, 40 );
//Weapon_AddItem( WEAPON_C4BOMB );
Weapon_Draw( WEAPON_GLOCK18 );
} else {
self.team = TEAM_CT;
iAlivePlayers_CT++;
@ -106,6 +106,7 @@ void Spawn_CreateClient( float fCharModel ) {
Weapon_AddItem( WEAPON_KNIFE );
Weapon_AddItem( WEAPON_USP45 );
Weapon_GiveAmmo( WEAPON_USP45, 24 );
Weapon_Draw( WEAPON_GLOCK18 );
}
if( self.iInGame == FALSE ) {

View file

@ -61,11 +61,11 @@ void Timer_Update( void ) {
float fRand = ceil( random() * 3 );
if ( fRand == 1 ) {
sound(world, CHAN_VOICE, "radio/moveout.wav", 1, ATTN_NONE );
Radio_BroadcastMessage( RADIO_MOVEOUT );
} else if ( fRand == 2 ) {
sound(world, CHAN_VOICE, "radio/locknload.wav", 1, ATTN_NONE );
Radio_BroadcastMessage( RADIO_LOCKNLOAD );
} else {
sound(world, CHAN_VOICE, "radio/letsgo.wav", 1, ATTN_NONE );
Radio_BroadcastMessage( RADIO_LETSGO );
}
}
}

View file

@ -34,7 +34,10 @@ void trigger_multiple( void ) {
entity eFind = findchain( killtarget, self.target );
while ( eFind ) {
entity eRemoveMe = eFind;
remove( eRemoveMe );
eOld = self;
self = eRemoveMe;
Entities_Remove();
self = eOld;
eFind = eFind.chain;
}
}

View file

@ -8,6 +8,7 @@
../Math.h
Defs.h
../Shared/Radio.c
../Shared/WeaponAK47.c
../Shared/WeaponAUG.c
../Shared/WeaponAWP.c

138
Source/Shared/Radio.c Normal file
View file

@ -0,0 +1,138 @@
/*
OpenCS Project
Copyright (C) 2015 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
enum {
RADIO_MODE_ALL = 0,
RADIO_MODE_T,
RADIO_MODE_CT
};
enum {
RADIO_BLOW,
RADIO_BOMBDEF,
RADIO_BOMBPL,
RADIO_CIRCLEBACK,
RADIO_CLEAR,
RADIO_COM_FOLLOWCOM,
RADIO_COM_GETINPOS,
RADIO_COM_GO,
RADIO_COM_REPORTIN,
RADIO_CT_AFFIRM,
RADIO_CT_BACKUP,
RADIO_CT_COVERME,
RADIO_CT_ENEMYS,
RADIO_CT_FIREINHOLE,
RADIO_CT_IMHIT,
RADIO_CT_INPOS,
RADIO_CT_POINT,
RADIO_CT_REPORTINGIN,
RADIO_CTWIN,
RADIO_ENEMYDOWN,
RADIO_FALLBACK,
RADIO_FIREASSIS,
RADIO_FOLLOWME,
RADIO_GETOUT,
RADIO_GO,
RADIO_HITASSIST,
RADIO_HOSDOWN,
RADIO_LETSGO,
RADIO_LOCKNLOAD,
RADIO_MATEDOWN,
RADIO_MEETME,
RADIO_MOVEOUT,
RADIO_NEGATIVE,
RADIO_POSITION,
RADIO_REGROUP,
RADIO_RESCUED,
RADIO_ROGER,
RADIO_ROUNDDRAW,
RADIO_STICKTOG,
RADIO_STORMFRONT,
RADIO_TAKEPOINT,
RADIO_TERWIN,
RADIO_VIP,
};
#ifdef CSQC
string sRadioSamples[43] = {
"radio/blow.wav",
"radio/bombdef.wav",
"radio/bombpl.wav",
"radio/circleback.wav",
"radio/clear.wav",
"radio/com_followcom.wav",
"radio/com_getinpos.wav",
"radio/com_go.wav",
"radio/com_reportin.wav",
"radio/ct_affirm.wav",
"radio/ct_backup.wav",
"radio/ct_coverme.wav",
"radio/ct_enemys.wav",
"radio/ct_fireinhole.wav",
"radio/ct_imhit.wav",
"radio/ct_inpos.wav",
"radio/ct_point.wav",
"radio/ct_reportingin.wav",
"radio/ctwin.wav",
"radio/enemydown.wav",
"radio/fallback.wav",
"radio/fireassis.wav",
"radio/followme.wav",
"radio/getout.wav",
"radio/go.wav",
"radio/hitassist.wav",
"radio/hosdown.wav",
"radio/letsgo.wav",
"radio/locknload.wav",
"radio/matedown.wav",
"radio/meetme.wav",
"radio/moveout.wav",
"radio/negative.wav",
"radio/position.wav",
"radio/regroup.wav",
"radio/rescued.wav",
"radio/roger.wav",
"radio/rounddraw.wav",
"radio/sticktog.wav",
"radio/stormfront.wav",
"radio/takepoint.wav",
"radio/terwin.wav",
"radio/vip.wav"
};
void Radio_InitSounds( void ) {
for ( int i = 0; i < 43; i++ ) {
precache_sound( sRadioSamples[ i ] );
}
}
#endif
void Radio_BroadcastMessage( float fMessage ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_RADIOMSG );
WriteByte( MSG_MULTICAST, fMessage );
msg_entity = self;
multicast( '0 0 0', MSG_BROADCAST );
#else
sound( world, CHAN_VOICE, sRadioSamples[ fMessage ], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE );
#endif
}

View file

@ -51,9 +51,9 @@ weaponinfo_t wptTable[ CS_WEAPON_COUNT ] = {
#ifdef SSQC
void OpenCSGunBase_Draw( void ) {
self.iCurrentClip = self.(wptTable[ self.weapon ].iClipfld);
self.iCurrentCaliber = self.(wptTable[ self.weapon ].iCaliberfld);
Client_SendEvent( self, EV_WEAPON_DRAW );
self.iCurrentClip = self.(wptTable[ self.weapon ].iClipfld);
self.iCurrentCaliber = self.(wptTable[ self.weapon ].iCaliberfld);
Client_SendEvent( self, EV_WEAPON_DRAW );
}
void OpenCSGunBase_AccuracyCalc( void ) {

View file

@ -89,7 +89,7 @@ void WeaponC4BOMB_Drop( vector vBombPos ) {
eBomb.fAttackFinished = time + 45;
sound( eBomb, CHAN_WEAPON, "weapons/c4_plant.wav", 1.0, ATTN_IDLE );
sound( world, CHAN_VOICE, "radio/bombpl.wav", 1.0, ATTN_NONE );
Radio_BroadcastMessage( RADIO_BOMBPL );
Weapon_SwitchBest();
}

View file

@ -79,6 +79,7 @@ void WeaponUSP45_Draw( void ) {
}
Sound_Delayed( "weapons/usp_slideback.wav", 1.0, 0.5 );
print( "EXECUTED TWICE?????\n" );
#endif
}

View file

@ -147,10 +147,6 @@ void Weapon_AddItem( float fWeapon ) {
// Make sure we've got at least one full clip
self.(wptTable[ self.weapon ].iClipfld) = wptTable[ fWeapon ].iClipSize;
Weapon_UpdateCurrents();
Weapon_Draw( fWeapon );
}
void Weapon_GiveAmmo( float fWeapon, float fAmount ) {