From aa34fcb8c1ca8263ebe4226c9021a9002390bf94 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sun, 9 Oct 2016 19:46:17 +0000 Subject: [PATCH] Lock spawnpoints to maps, new interface, touch menu --- dlls/client.cpp | 39 +++++++++++++++++- dlls/gamerules.cpp | 1 + dlls/h_export.cpp | 51 +++++++++++++++++++++++ dlls/items.cpp | 13 +++--- dlls/multiplay_gamerules.cpp | 50 +++++++++++++++------- dlls/player.cpp | 26 +++++++++++- dlls/player.h | 1 + dlls/subs.cpp | 4 ++ dlls/triggers.cpp | 80 +++++++++++++++++++++++++----------- 9 files changed, 220 insertions(+), 45 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 0801dd7c..d00448f5 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -207,6 +207,7 @@ void ClientPutInServer( edict_t *pEntity ) pPlayer->pev->iuser1 = 0; pPlayer->pev->iuser2 = 0; + g_engfuncs.pfnQueryClientCvarValue2( pEntity, "touch_enable", 111 ); } @@ -375,7 +376,6 @@ void Host_Say( edict_t *pEntity, int teamonly ) } } - /* =========== ClientCommand @@ -503,6 +503,31 @@ void ClientCommand( edict_t *pEntity ) if ( mp_coop.value ) UTIL_CleanSpawnPoint( pev->origin, 150 ); } + else if( FStrEq(pcmd, "m1")) + { +#define MENU_STR(VAR) (#VAR) + CLIENT_COMMAND( pEntity, + MENU_STR(touch_addbutton "_coops" "*black" "" 0.15 0.1 0.4 0.72 0 0 0 128 334\ntouch_addbutton "_coopst" "#COOP MENU" "" 0.16 0.11 0.41 0.3 0 255 0 255 78 1.5\nm2\n) + ); + } + else if( FStrEq(pcmd, "m2")) + { + CLIENT_COMMAND( pEntity, + MENU_STR(touch_addbutton "_coops1" "#1. Join coop" "menuselect 1;touch_hide _coops*" 0.16 0.21 0.39 0.3 255 255 255 255 334 1.5\ntouch_addbutton "_coops2" "#2. Become spectator" "menuselect 2;touch_hide _coops*" 0.16 0.31 0.39 0.4 255 255 255 255 334 1.5\nm3\n) + ); + } + else if( FStrEq(pcmd, "m3")) + { + CLIENT_COMMAND( pEntity, + MENU_STR(touch_addbutton "_coops3" "#" "menuselect 3;touch_hide _coops*" 0.16 0.41 0.39 0.5 255 255 255 255 335 1.5\ntouch_addbutton "_coops4" "#" "menuselect 4;touch_hide _coops*" 0.16 0.51 0.39 0.6 255 255 255 255 335 1.5\nm4\n) + ); + } + else if( FStrEq(pcmd, "m4")) + { + CLIENT_COMMAND( pEntity, + MENU_STR(touch_addbutton "_coops5" "#" "menuselect 5;touch_hide _coops*" 0.16 0.61 0.39 0.7 255 255 255 255 335 1.5;wait;slot10\n) +); + } else { // tell the user they entered an unknown command @@ -1812,6 +1837,18 @@ void CreateInstancedBaselines ( void ) //UTIL_Remove( pc ); } +void CvarValue2( const edict_t *pEnt, int requestID, const char *cvarName, const char *value ) +{ + if( pEnt && requestID == 111 && FStrEq( cvarName , "touch_enable" ) && atoi( value) ) + { + CBasePlayer *player = (CBasePlayer * ) CBaseEntity::Instance( (edict_t*)pEnt ); + player->m_fTouchMenu = !!atof( value ); + CLIENT_COMMAND((edict_t*)pEnt, "touch_addbutton \"_coopm\" \"*black\" \"coopmenu\" 0 0.77 0.15 0.83 0 0 0 128 335\ntouch_addbutton \"_coopmt\" \"#COOP MENU\" \"\" 0 0.77 0.16 0.83 255 255 127 255 79 2\nm1\n"); + } + +} + + /* ================================ InconsistentFile diff --git a/dlls/gamerules.cpp b/dlls/gamerules.cpp index 25ce240b..cca9e4dd 100644 --- a/dlls/gamerules.cpp +++ b/dlls/gamerules.cpp @@ -93,6 +93,7 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) pPlayer->pev->velocity = g_vecZero; pPlayer->pev->angles = VARS( pentSpawnSpot )->angles; pPlayer->pev->punchangle = g_vecZero; + if( !(pPlayer->pev->flags & FL_SPECTATOR ) ) if( mp_coop_changelevel.value && !CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles )) CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles ); pPlayer->pev->fixangle = TRUE; diff --git a/dlls/h_export.cpp b/dlls/h_export.cpp index a3f4f35e..5fec1929 100644 --- a/dlls/h_export.cpp +++ b/dlls/h_export.cpp @@ -55,3 +55,54 @@ extern "C" void DLLEXPORT EXPORT2 GiveFnptrsToDll( enginefuncs_t *pengfuncsFromE memcpy( &g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t) ); gpGlobals = pGlobals; } + +int ShouldCollide( edict_t *pentTouched, edict_t *pentOther ) +{ + return 1; +} + +void OnFreeEntPrivateData(edict_s *pEdict) +{ +#if 0 + if(pEdict && pEdict->pvPrivateData) + { + ((CBaseEntity*)pEdict->pvPrivateData)->~CBaseEntity(); + } +#endif +} + +void GameShutdown(void) +{ + +} + +void CvarValue( const edict_t *pEnt, const char *value ) +{ +} + +void CvarValue2( const edict_t *pEnt, int requestID, const char *cvarName, const char *value ); + + + +NEW_DLL_FUNCTIONS gNewDLLFunctions = +{ + OnFreeEntPrivateData, //pfnOnFreeEntPrivateData + GameShutdown, //pfnGameShutdown + ShouldCollide, //pfnShouldCollide + CvarValue, + CvarValue2 +}; + + +extern "C" int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) +{ + if(!pFunctionTable || *interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) + { + *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; + return FALSE; + } + memcpy(pFunctionTable, &gNewDLLFunctions, sizeof(gNewDLLFunctions)); + return TRUE; +} + + diff --git a/dlls/items.cpp b/dlls/items.cpp index 3ac6ba55..5a42ebec 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -261,11 +261,14 @@ class CItemSuit : public CItem if( !mp_coop.value && pPlayer->pev->weapons & ( 1<spawnflags & SF_SUIT_SHORTLOGON ) - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon, - else - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon - + // no sounds in coop + if( !mp_coop.value ) + { + if( pev->spawnflags & SF_SUIT_SHORTLOGON ) + EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon, + else + EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon + } pPlayer->pev->weapons |= ( 1 << WEAPON_SUIT ); return TRUE; } diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 901a90d5..e9e680a4 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -121,6 +121,7 @@ void SpawnPlayer( CBasePlayer *pPlayer ) pPlayer->pev->flags &= ~FL_SPECTATOR; pPlayer->pev->movetype = MOVETYPE_WALK; pPlayer->Spawn(); + CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" ); } @@ -128,21 +129,36 @@ extern int gmsgShowMenu; void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 ) { - char buf[128], *pbuf = buf; - short int flags = 1<<9; - pbuf += sprintf( pbuf, "^2%s:\n", title ); - for( int i = 0; i < count; i++ ) + if( pPlayer->m_fTouchMenu) { - pbuf += sprintf( pbuf, "^3%d.^7 %s\n", i+1, slot[i]); - flags |= 1<edict(), buf); + for( int i = 0; i < count; i++ ) + { + sprintf( buf, MENU_STR(touch_settexture _coops%d "#%d. %s"\ntouch_show _coops%d\n), i+1, i+1, slot[i], i + 1 ); + CLIENT_COMMAND( pPlayer->edict(), buf); + } } - MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pPlayer->pev); - WRITE_SHORT( flags ); // slots - WRITE_CHAR( time ); // show time - WRITE_BYTE( 0 ); // need more - WRITE_STRING( buf ); - MESSAGE_END(); - CLIENT_COMMAND( pPlayer->edict(), "exec touch_default/numbers.cfg\n"); + else + { + char buf[128], *pbuf = buf; + short int flags = 1<<9; + pbuf += sprintf( pbuf, "^2%s:\n", title ); + for( int i = 0; i < count; i++ ) + { + pbuf += sprintf( pbuf, "^3%d.^7 %s\n", i+1, slot[i]); + flags |= 1<pev); + WRITE_SHORT( flags ); // slots + WRITE_CHAR( time ); // show time + WRITE_BYTE( 0 ); // need more + WRITE_STRING( buf ); + MESSAGE_END(); + } + //CLIENT_COMMAND( pPlayer->edict(), "exec touch_default/numbers.cfg\n"); } void CoopMenu( CBasePlayer *pPlayer ); @@ -229,11 +245,14 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) if( imenu == 1 ) { SpawnPlayer( pPlayer ); + pPlayer->m_state = STATE_SPAWNED; } if( imenu == 2 ) { pPlayer->m_state = STATE_SPECTATOR; + CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" ); } + break; case STATE_SPAWNED: if( g_iMenu ) { @@ -242,6 +261,7 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) } if( imenu == 1 ) { + pPlayer->RemoveAllItems( TRUE ); SpawnPlayer( pPlayer ); } if( imenu == 2 ) @@ -252,6 +272,7 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { pPlayer->RemoveAllItems( TRUE ); BecomeSpectator( pPlayer ); + pPlayer->m_state = STATE_SPECTATOR; } if( imenu == 4 ) { @@ -726,7 +747,7 @@ void CHalfLifeMultiplay::PlayerThink( CBasePlayer *pPlayer ) pPlayer->m_afButtonReleased = 0; } } - +extern EHANDLE g_pLastSpawn; //========================================================= //========================================================= void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer ) @@ -737,6 +758,7 @@ void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer ) if( pPlayer->m_state == STATE_CONNECTED ) { pPlayer->m_state = STATE_SPECTATOR_BEGIN; + pPlayer->RemoveAllItems( TRUE ); BecomeSpectator( pPlayer ); return; } diff --git a/dlls/player.cpp b/dlls/player.cpp index cbf207cb..d43db7c4 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -2684,9 +2684,20 @@ edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ) while( pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_start" ) ) { TraceResult tr; + if( FNullEnt( pSpot ) ) + continue; + // only spawnpoints from current map are valid + if( !FStrEq( STRING( pSpot->pev->netname ), STRING( gpGlobals->mapname ) ) ) + continue; + // check if it is placed in wall UTIL_TraceHull( pSpot->pev->origin, pSpot->pev->origin , missile, human_hull, NULL, &tr ); - if( !tr.fStartSolid && !tr.fAllSolid && !FNullEnt( pSpot ) ) - goto ReturnSpot; + if( tr.fStartSolid || tr.fAllSolid ) + continue; + // trace down to find if there is no floor + UTIL_TraceHull( pSpot->pev->origin, pSpot->pev->origin - Vector( 0, 0, -200 ) , missile, human_hull, NULL, &tr ); + if( tr.vecEndPos.z - pSpot->pev->origin.z < -190 ) + continue; + goto ReturnSpot; } } // landmark may still exists when no spawn spot @@ -2869,9 +2880,12 @@ void CBasePlayer::RenewItems( void ) int CBasePlayer::Restore( CRestore &restore ) { + + if( !CBaseMonster::Restore( restore ) ) return 0; + int status = restore.ReadFields( "PLAYER", this, m_playerSaveData, ARRAYSIZE( m_playerSaveData ) ); SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData; @@ -2926,6 +2940,14 @@ int CBasePlayer::Restore( CRestore &restore ) // Barring that, we clear it out here instead of using the incorrect restored time value. m_flNextAttack = UTIL_WeaponTimeBase(); #endif + + // restored player has some bugs untill respawned + if( mp_coop_changelevel.value ) + { + m_state = STATE_CONNECTED; + SetThink( &CBasePlayer::Spawn ); + pev->nextthink = gpGlobals->time + 0.5; + } return status; } diff --git a/dlls/player.h b/dlls/player.h index 5aad4a41..e6bb437f 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -321,6 +321,7 @@ public: virtual float TouchGravGun( CBaseEntity *attacker, int stage ); float m_flSpawnTime; PlayerState m_state; + bool m_fTouchMenu; }; #define AUTOAIM_2DEGREES 0.0348994967025 diff --git a/dlls/subs.cpp b/dlls/subs.cpp index ba55e029..8914f9f7 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -68,6 +68,10 @@ class CBasePlayerStart : public CPointEntity public: // prevent transition as FCAP_ACROSS_TRANSITION does not help //virtual int ObjectCaps( void ) { return CPointEntity::ObjectCaps() | FCAP_DONT_SAVE; } + void Spawn() + { + pev->netname = gpGlobals->mapname; + } private: }; diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index ba4f706a..4cb3788f 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1425,27 +1425,6 @@ void CChangeLevel::Spawn( void ) //ALERT( at_console, "TRANSITION: %s (%s)\n", m_szMapName, m_szLandmarkName ); } -void CChangeLevel::UpdateColor( void ) -{ - Vector origin = VecBModelOrigin(pev); - Vector point, angles; - CBaseEntity *pPlayer; - pev->nextthink = gpGlobals->time + 30; - - if( !m_fIsBack && (pPlayer = UTIL_FindEntityByClassname( NULL, "info_player_start" )) ) - if( (origin - pPlayer->pev->origin).Length() < 500 ) - m_fIsBack = true; - if( !m_fIsBack && CoopGetSpawnPoint( &point, &angles ) ) - if( (origin - point).Length() < 500 ) - m_fIsBack = true; - pev->rendercolor.x = 0; - if( m_fIsBack ) - pev->rendercolor.z = 255; - else - pev->rendercolor.y = 255; - -} - void CChangeLevel::ExecuteChangeLevel( void ) { MESSAGE_BEGIN( MSG_ALL, SVC_CDTRACK ); @@ -1642,6 +1621,34 @@ public: }; GlobalMenu g_GlobalMenu; + + +void CChangeLevel::UpdateColor( void ) +{ + Vector origin = VecBModelOrigin(pev); + Vector point, angles; + CBaseEntity *pPlayer; + pev->nextthink = gpGlobals->time + 30; + + if( !m_fIsBack && (pPlayer = UTIL_FindEntityByClassname( NULL, "info_player_start" )) ) + if( (origin - pPlayer->pev->origin).Length() < 500 ) + m_fIsBack = true; + if( !m_fIsBack && CoopGetSpawnPoint( &point, &angles ) ) + if( (origin - point).Length() < 500 ) + m_fIsBack = true; + pev->rendercolor = g_vecZero; + if( m_fIsBack ) + pev->rendercolor.z = 255; + else + pev->rendercolor.y = 255; + if( gpGlobals->time - g_GlobalMenu.m_flTime > 30 ) + { + g_iMenu = 0; + g_GlobalMenu.m_iConfirm = 0; + } + +} + void CoopVoteMenu( CBasePlayer *pPlayer ) { int count = 0; @@ -1746,12 +1753,14 @@ bool CoopGetSpawnPoint( Vector *origin, Vector *angles) if( g_SavedCoords.trainsaved ) { CBaseEntity *train = UTIL_FindEntityByString( NULL, "globalname", g_SavedCoords.trainglobal ); + if( !train ) train = UTIL_FindEntityByString( NULL, "classname", g_SavedCoords.trainglobal ); if( train ) { *angles = g_SavedCoords.triggerangles; *origin = VecBModelOrigin(train->pev) + g_SavedCoords.trainoffset; return true; } + ALERT( at_console, "Failed to get train %s (map design error?)\n", g_SavedCoords.trainglobal ); } Vector point = g_SavedCoords.triggerorigin; *angles = g_SavedCoords.triggerangles; @@ -1769,11 +1778,13 @@ bool CoopGetSpawnPoint( Vector *origin, Vector *angles) { g_SavedCoords.triggerorigin = tr.vecEndPos; g_SavedCoords.validspawnpoint = true; + if( tr.pHit && FClassnameIs( tr.pHit, "func_door" ) ) + tr.pHit->v.solid = SOLID_NOT; } else { g_SavedCoords.valid = false; - ALERT( at_console, "CoopGetSpawnPoint: trace failed"); + ALERT( at_console, "CoopGetSpawnPoint: trace failed\n"); return false; } } @@ -1807,12 +1818,17 @@ void CoopSaveTrain( CBaseEntity *pPlayer, SavedCoords *coords) CBaseEntity *train = CoopGetPlayerTrain(pPlayer); if( !train ) + { + ALERT( at_console, "^1NO TRAIN!\n"); return; + } + ALERT( at_console, "^1TRAIN IS %s", STRING( train->pev->classname ) ); + strcpy( coords->trainglobal, STRING(train->pev->globalname) ); coords->trainoffset = pPlayer->pev->origin - VecBModelOrigin(train->pev); coords->trainsaved = true; } - +void BecomeSpectator( CBasePlayer *pPlayer ); void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) { edict_t *pentLandmark; @@ -1922,6 +1938,11 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) if( m_fIsBack ) { + if( gpGlobals->time - g_GlobalMenu.m_flTime > 30 ) + { + g_iMenu = 0; + g_GlobalMenu.m_iConfirm = 0; + } if( g_iMenu != 1 ) { g_GlobalMenu.ConfirmMenu( this, m_szMapName ); @@ -2014,6 +2035,19 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) //ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) ); ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot ); + // loop through all clients, count number of players + for( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *plr = (CBasePlayer*)UTIL_PlayerByIndex( i ); + + // reset all players state + if( plr ) + { + plr->m_state = STATE_CONNECTED; + plr->RemoveAllItems( TRUE ); + BecomeSpectator( plr ); + } + } CHANGE_LEVEL( st_szNextMap, st_szNextSpot ); }