bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue ) { if ( FStrEq(szKeyName, "style") || FStrEq(szKeyName, "height") || FStrEq(szKeyName, "value1") || FStrEq(szKeyName, "value2") || FStrEq(szKeyName, "value3")) { } else if (FStrEq(szKeyName, "dmdelay")) { m_iReactivate = atoi(szValue); } else { return BaseClass::KeyValue( szKeyName, szValue ); } return true; }
void CElectrifiedWire::KeyValue( KeyValueData* pkvd ) { if( FStrEq( pkvd->szKeyName, "sparkfrequency" ) ) { m_iTipSparkFrequency = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else if( FStrEq( pkvd->szKeyName, "bodysparkfrequency" ) ) { m_iBodySparkFrequency = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else if( FStrEq( pkvd->szKeyName, "lightningfrequency" ) ) { m_iLightningFrequency = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else if( FStrEq( pkvd->szKeyName, "xforce" ) ) { m_iXJoltForce = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else if( FStrEq( pkvd->szKeyName, "yforce" ) ) { m_iYJoltForce = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else if( FStrEq( pkvd->szKeyName, "zforce" ) ) { m_iZJoltForce = strtol( pkvd->szValue, nullptr, 10 ); pkvd->fHandled = true; } else BaseClass::KeyValue( pkvd ); }
int CSqueakGrenade::IRelationship( CBaseEntity *pTarget ) { if ( gameplayMods::snarkFriendlyToPlayer.isActive() ) { if ( FStrEq( "player", STRING( pTarget->pev->classname ) ) ) { return R_AL; } else if ( FStrEq( "monster_bullchicken", STRING( pTarget->pev->classname ) ) || FStrEq( "monster_alien_grunt", STRING( pTarget->pev->classname ) ) || FStrEq( "monster_alien_slave", STRING( pTarget->pev->classname ) ) ) { return R_DL; } } if ( gameplayMods::snarkFriendlyToAllies.isActive() && FStrEq( "monster_scientist", STRING( pTarget->pev->classname ) ) || FStrEq( "monster_barney", STRING( pTarget->pev->classname ) ) ) { return R_AL; } return CGrenade::IRelationship( pTarget ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudControlPointIcons::FireGameEvent( IGameEvent *event ) { const char *eventname = event->GetName(); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( FStrEq( "controlpoint_initialized", eventname ) ) { // Create our control points InitIcons(); return; } if ( FStrEq( "controlpoint_updateimages", eventname ) ) { // Update the images of our control point icons int iIndex = event->GetInt( "index" ); if ( iIndex == -1 ) { for (int i = 0; i < m_Icons.Count(); i++) { m_Icons[i]->UpdateImage(); } } else { // Only invalidate the specified cap point for (int i = 0; i < m_Icons.Count(); i++) { if ( m_Icons[i]->GetCapIndex() == iIndex ) { m_Icons[i]->UpdateImage(); } } } UpdateProgressBarFor( iIndex ); return; } if ( FStrEq( "controlpoint_updatelayout", eventname ) ) { // Update the layout of our control point icons int iIndex = event->GetInt( "index" ); if ( iIndex == -1 ) { InvalidateLayout(); } else { // Only invalidate the specified cap point for (int i = 0; i < m_Icons.Count(); i++) { if ( m_Icons[i]->GetCapIndex() == iIndex ) { m_Icons[i]->InvalidateLayout(); } } } UpdateProgressBarFor( iIndex ); return; } if ( FStrEq( "controlpoint_updatecapping", eventname ) ) { // Update the capping status of our control point icons int iIndex = event->GetInt( "index" ); if ( iIndex == -1 ) { for (int i = 0; i < m_Icons.Count(); i++) { m_Icons[i]->UpdateCapImage(); } } else { // Only invalidate the specified cap point for (int i = 0; i < m_Icons.Count(); i++) { if ( m_Icons[i]->GetCapIndex() == iIndex ) { m_Icons[i]->UpdateCapImage(); } } } UpdateProgressBarFor( iIndex ); return; } if ( FStrEq( "controlpoint_starttouch", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = event->GetInt( "area" ); UpdateProgressBarFor( m_iCurrentCP ); } } else if ( FStrEq( "controlpoint_endtouch", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = -1; UpdateProgressBarFor( m_iCurrentCP ); } } else if ( FStrEq( "controlpoint_pulse_element", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { for (int i = 0; i < m_Icons.Count(); i++) { m_Icons[i]->FakePulse( gpGlobals->curtime + (i * PULSE_TIME_PER_ICON) ); } } } else if ( FStrEq( "controlpoint_fake_capture", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = event->GetInt( "int_data" ); m_bFakingCapture = true; m_bFakingCaptureMult = false; m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE; UpdateProgressBarFor( -1 ); } } else if ( FStrEq( "controlpoint_fake_capture_mult", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = event->GetInt( "int_data" ); m_bFakingCapture = true; m_bFakingCaptureMult = true; m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE; UpdateProgressBarFor( -1 ); } } else if ( FStrEq( "intro_nextcamera", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = -1; m_bFakingCapture = false; m_bFakingCaptureMult = false; UpdateProgressBarFor( -1 ); } } else if ( FStrEq( "intro_finish", eventname ) ) { int iPlayer = event->GetInt( "player" ); if ( pPlayer && iPlayer == pPlayer->entindex() ) { m_iCurrentCP = -1; m_flPulseTime = 0; m_bFakingCapture = false; m_bFakingCaptureMult = false; InitIcons(); } } }
virtual void ParseKeyValue( void *pData, const char *pKey, const char *pValue ) { breakmodel_t *pModel = (breakmodel_t *)pData; if ( !strcmpi( pKey, "model" ) ) { ParseModelName( pModel, pValue ); } else if (!strcmpi( pKey, "ragdoll" ) ) { ParseModelName( pModel, pValue ); pModel->isRagdoll = true; } else if (!strcmpi( pKey, "motiondisabled" ) ) { pModel->isMotionDisabled = true; } else if ( !strcmpi( pKey, "offset" ) ) { UTIL_StringToVector( pModel->offset.Base(), pValue ); } else if ( !strcmpi( pKey, "health" ) ) { pModel->health = atof(pValue); } else if ( !strcmpi( pKey, "fadetime" ) ) { pModel->fadeTime = atof(pValue); if ( !m_wroteCollisionGroup ) { pModel->collisionGroup = COLLISION_GROUP_DEBRIS; } } else if ( !strcmpi( pKey, "fademindist" ) ) { pModel->fadeMinDist = atof(pValue); } else if ( !strcmpi( pKey, "fademaxdist" ) ) { pModel->fadeMaxDist = atof(pValue); } else if ( !strcmpi( pKey, "debris" ) ) { pModel->collisionGroup = atoi(pValue) > 0 ? COLLISION_GROUP_DEBRIS : COLLISION_GROUP_INTERACTIVE; m_wroteCollisionGroup = true; } else if ( !strcmpi( pKey, "burst" ) ) { pModel->burstScale = atof( pValue ); } else if ( !strcmpi( pKey, "placementbone" ) ) { Q_strncpy( pModel->placementName, pValue, sizeof(pModel->placementName) ); pModel->placementIsBone = true; } else if ( !strcmpi( pKey, "placementattachment" ) ) { Q_strncpy( pModel->placementName, pValue, sizeof(pModel->placementName) ); pModel->placementIsBone = false; } else if ( !strcmpi( pKey, "multiplayer_break" ) ) { if ( FStrEq( pValue, "server" ) ) { pModel->mpBreakMode = MULTIPLAYER_BREAK_SERVERSIDE; } else if ( FStrEq( pValue, "client" ) ) { pModel->mpBreakMode = MULTIPLAYER_BREAK_CLIENTSIDE; } } else if ( !strcmpi( pKey, "velocity" ) ) { UTIL_StringToVector( pModel->velocity.Base(), pValue ); } }
//========================================================= // // SquadRecruit(), get some monsters of my classification and // link them as a group. returns the group size // //========================================================= int CSquadMonster :: SquadRecruit( int searchRadius, int maxMembers ) { int squadCount; int iMyClass = Classify();// cache this monster's class // Don't recruit if I'm already in a group if ( InSquad() ) return 0; if ( maxMembers < 2 ) return 0; // I am my own leader m_hSquadLeader = this; squadCount = 1; CBaseEntity *pEntity = NULL; if ( !FStringNull( pev->netname ) ) { // I have a netname, so unconditionally recruit everyone else with that name. pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) ); while ( pEntity ) { CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer(); if ( pRecruit ) { if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass && pRecruit != this ) { // minimum protection here against user error.in worldcraft. if (!SquadAdd( pRecruit )) break; squadCount++; } } pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) ); } } else { while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, searchRadius )) != NULL) { CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer( ); if ( pRecruit && pRecruit != this && pRecruit->IsAlive() && !pRecruit->m_pCine ) { // Can we recruit this guy? if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass && ( (iMyClass != CLASS_ALIEN_MONSTER) || FStrEq(STRING(pev->classname), STRING(pRecruit->pev->classname))) && FStringNull( pRecruit->pev->netname ) ) { TraceResult tr; UTIL_TraceLine( pev->origin + pev->view_ofs, pRecruit->pev->origin + pev->view_ofs, ignore_monsters, pRecruit->edict(), &tr );// try to hit recruit with a traceline. if ( tr.flFraction == 1.0 ) { if (!SquadAdd( pRecruit )) break; squadCount++; } } } } } // no single member squads if (squadCount == 1) { m_hSquadLeader = NULL; } return squadCount; }
bool RadioCreate( edict_t *pEntity ) { // Create the radio and stick to the wall entvars_t *pPev = VARS( pEntity ); if (pPev->iuser1 > 0) return 0; // make sure we dont already have a radio int radiocount = 0; int i = 1; char *pClassname; edict_t *frontEnt; for (i; i < 1025; i++) { frontEnt = INDEXENT ( i ); if (frontEnt) { pClassname = (char *)STRING(frontEnt->v.classname); if (FStrEq("building_radio", pClassname)) { if (frontEnt->v.euser4 == pEntity) { radiocount++; } } } } if (AdminLoggedIn[ENTINDEX(pEntity)] == 0) { if (radiocount >= 2) { ClientPrint( pPev, HUD_PRINTTALK, "* Cant have more than 2 radios!\n"); return 0; } } UTIL_MakeVectors( pPev->v_angle + pPev->punchangle ); Vector vecSrc = GetGunPosition( pEntity ); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; UTIL_TraceLine( vecSrc, vecSrc + vecAiming * 128, dont_ignore_monsters, pEntity , &tr ); if (tr.flFraction < 1.0 || AdminLoggedIn[ENTINDEX(pEntity)]) { if (tr.pHit && !(tr.pHit->v.flags & FL_CONVEYOR) && (FStrEq((char *)STRING(tr.pHit->v.classname), "worldspawn") || FStrEq((char *)STRING(tr.pHit->v.classname), "func_wall") || AdminLoggedIn[ENTINDEX(pEntity)] || FStrEq((char *)STRING(tr.pHit->v.classname), "building_dancemachine"))) // Make sure it isnt a conveyor! { Vector angles = UTIL_VecToAngles( tr.vecPlaneNormal ); if ((angles.x > 30 || angles.x < -30) && AdminLoggedIn[ENTINDEX(pEntity)] == 0) { ClientPrint( pPev, HUD_PRINTTALK, "* Can't place radios on floors or cielings!\n"); return 0; } // Create the camera here! Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 14; //Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 15; int maxdist = (int)CVAR_GET_FLOAT("sa_radiospread"); // make sure we arent placing it within 400 units of another radio for (i=1; i < 1025; i++) { frontEnt = INDEXENT ( i ); if (frontEnt) { pClassname = (char *)STRING(frontEnt->v.classname); if (FStrEq("building_radio", pClassname)) { if ((frontEnt->v.origin - vecOri).Length() < maxdist && AdminLoggedIn[ENTINDEX(pEntity)] == 0) { ClientPrint( pPev, HUD_PRINTTALK, "* Can't place a radio so close to another radio!\n"); return 0; } } } } KeyValueData kvd; //edict_t *pent = CREATE_ENTITY(); //edict_t *pent = CREATE_NAMED_ENTITY(MAKE_STRING("info_target")); edict_t *tEntity; tEntity = CREATE_NAMED_ENTITY(MAKE_STRING("info_target")); entvars_t *pRunOnPev; pRunOnPev = VARS(tEntity); char buf[80]; sprintf( buf, "%s", "building_radio"); // Set the KEYVALUES here! kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = buf; DispatchKeyValue( tEntity, &kvd ); // place this in front pRunOnPev->origin = vecOri; SET_ORIGIN( tEntity , vecOri ); pRunOnPev->angles = angles; //DispatchSpawn( ENT( pRunOnPev ) ); pRunOnPev->solid = SOLID_BBOX; SET_MODEL( ENT( pRunOnPev ) , "avatar-x/avadd16.avfil"); UTIL_SetSize( pRunOnPev, Vector( -2, -2 ,-2) - (tr.vecPlaneNormal * 15), Vector(2, 2, 16) - (tr.vecPlaneNormal * 15)); pRunOnPev->takedamage = DAMAGE_YES; pRunOnPev->max_health = 40 + 10000; pRunOnPev->health = 40 + 10000; pRunOnPev->euser4 = pEntity; /* edict_t *pent; pent = CREATE_NAMED_ENTITY(MAKE_STRING("xen_tree")); entvars_t *pv = VARS( pent ); pv->origin = vecOri; SET_ORIGIN(pent, vecOri); kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = "xen_tree"; DispatchKeyValue( pent, &kvd ); DispatchSpawn(pent); //pev->angles = angles; */ //pev->iuser1 = angles.y; //pv->vuser3 = angles; // for now don't take damage //pev->takedamage = DAMAGE_YES; //pev->max_health = 40 + 10000; //pev->health = 40 + 10000; /* // Call the SPAWN routine to set more stuff kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = "building_radio"; //DispatchKeyValue( pent, &kvd ); kvd.fHandled = FALSE; */ RadioSpawn( tEntity ); return 1; } else { ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n"); return 0; } } else { ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n"); } return 0; }
// make the entity enter a scripted sequence void CCineMonster::PossessEntity(void) { CBaseEntity * pEntity = m_hTargetEnt; CBaseMonster *pTarget = NULL; if(pEntity) pTarget = pEntity->MyMonsterPointer(); if(pTarget) { // FindEntity() just checked this! #if 0 if ( !pTarget->CanPlaySequence( FCanOverrideState() ) ) { ALERT( at_aiconsole, "Can't possess entity %s\n", STRING(pTarget->pev->classname) ); return; } #endif pTarget->m_pGoalEnt = this; pTarget->m_pCine = this; pTarget->m_hTargetEnt = this; m_saved_movetype = pTarget->pev->movetype; m_saved_solid = pTarget->pev->solid; m_saved_effects = pTarget->pev->effects; pTarget->pev->effects |= pev->effects; switch(m_fMoveTo) { case 0: pTarget->m_scriptState = SCRIPT_WAIT; break; case 1: pTarget->m_scriptState = SCRIPT_WALK_TO_MARK; DelayStart(1); break; case 2: pTarget->m_scriptState = SCRIPT_RUN_TO_MARK; DelayStart(1); break; case 4: UTIL_SetOrigin(pTarget->pev, pev->origin); pTarget->pev->ideal_yaw = pev->angles.y; pTarget->pev->avelocity = Vector(0, 0, 0); pTarget->pev->velocity = Vector(0, 0, 0); pTarget->pev->effects |= EF_NOINTERP; pTarget->pev->angles.y = pev->angles.y; pTarget->m_scriptState = SCRIPT_WAIT; m_startTime = gpGlobals->time + 1E6; // UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters // pTarget->pev->flags &= ~FL_ONGROUND; break; } // ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->pev->targetname ), FBitSet(pev->spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" ); pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; if(m_iszIdle) { StartSequence(pTarget, m_iszIdle, FALSE); if(FStrEq(STRING(m_iszIdle), STRING(m_iszPlay))) { pTarget->pev->framerate = 0; } } } }
// Use CMD_ARGV, CMD_ARGV, and CMD_ARGC to get pointers the character string command. void ClientCommand( edict_t *pEntity ) { const char *pcmd = CMD_ARGV(0); const char *pstr; // Is the client spawned yet? if ( !pEntity->pvPrivateData ) return; entvars_t *pev = &pEntity->v; if ( FStrEq(pcmd, "say" ) ) { Host_Say( pEntity, 0 ); } else if ( FStrEq(pcmd, "say_team" ) ) { Host_Say( pEntity, 1 ); } else if ( FStrEq(pcmd, "fullupdate" ) ) { GetClassPtr((CBasePlayer *)pev)->ForceClientDllUpdate(); } else if ( FStrEq(pcmd, "give" ) ) { if ( g_flWeaponCheat != 0.0) { int iszItem = ALLOC_STRING( CMD_ARGV(1) ); // Make a copy of the classname GetClassPtr((CBasePlayer *)pev)->GiveNamedItem( STRING(iszItem) ); } } else if ( FStrEq(pcmd, "fire") ) { if ( g_flWeaponCheat != 0.0) { CBaseEntity *pPlayer = CBaseEntity::Instance(pEntity); if (CMD_ARGC() > 1) { FireTargets(CMD_ARGV(1), pPlayer, pPlayer, USE_TOGGLE, 0); } else { TraceResult tr; UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000, dont_ignore_monsters, pEntity, &tr ); if (tr.pHit) { CBaseEntity *pHitEnt = CBaseEntity::Instance(tr.pHit); if (pHitEnt) { pHitEnt->Use(pPlayer, pPlayer, USE_TOGGLE, 0); ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Fired %s \"%s\"\n", STRING(pHitEnt->pev->classname), STRING(pHitEnt->pev->targetname) ) ); } } } } } else if ( FStrEq(pcmd, "drop" ) ) { // player is dropping an item. GetClassPtr((CBasePlayer *)pev)->DropPlayerItem((char *)CMD_ARGV(1)); } else if ( FStrEq(pcmd, "fov" ) ) { if ( g_flWeaponCheat && CMD_ARGC() > 1) { GetClassPtr((CBasePlayer *)pev)->m_iFOV = atoi( CMD_ARGV(1) ); } else { CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs( "\"fov\" is \"%d\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_iFOV ) ); } } else if ( FStrEq(pcmd, "use" ) ) { GetClassPtr((CBasePlayer *)pev)->SelectItem((char *)CMD_ARGV(1)); } else if (((pstr = strstr(pcmd, "weapon_")) != NULL) && (pstr == pcmd)) { GetClassPtr((CBasePlayer *)pev)->SelectItem(pcmd); } else if (FStrEq(pcmd, "lastinv" )) { GetClassPtr((CBasePlayer *)pev)->SelectLastItem(); } else if ( FStrEq( pcmd, "spectate" ) && (pev->flags & FL_PROXY) ) // added for proxy support { CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev); edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); pPlayer->StartObserver( pev->origin, VARS(pentSpawnSpot)->angles); } else if ( g_pGameRules->ClientCommand( GetClassPtr((CBasePlayer *)pev), pcmd ) ) { // MenuSelect returns true only if the command is properly handled, so don't print a warning } else if ( FStrEq(pcmd, "VModEnable") ) { // clear 'Unknown command: VModEnable' in singleplayer return; } else { // tell the user they entered an unknown command char command[128]; // check the length of the command (prevents crash) // max total length is 192 ...and we're adding a string below ("Unknown command: %s\n") strncpy( command, pcmd, 127 ); command[127] = '\0'; // tell the user they entered an unknown command ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Unknown command: %s\n", command ) ); } }
//-------------------------------------------------------------------------------------------------------------- void BuyState::OnUpdate( CCSBot *me ) { char cmdBuffer[256]; // wait for a Navigation Mesh if (!TheNavMesh->IsLoaded()) return; // apparently we cant buy things in the first few seconds, so wait a bit if (m_isInitialDelay) { const float waitToBuyTime = 0.25f; if (gpGlobals->curtime - me->GetStateTimestamp() < waitToBuyTime) return; m_isInitialDelay = false; } // if we're done buying and still in the freeze period, wait if (m_doneBuying) { if (CSGameRules()->IsMultiplayer() && CSGameRules()->IsFreezePeriod()) { // make sure we're locked and loaded me->EquipBestWeapon( MUST_EQUIP ); me->Reload(); me->ResetStuckMonitor(); return; } me->Idle(); return; } // If we're supposed to buy a specific weapon for debugging, do so and then bail const char *cheatWeaponString = bot_loadout.GetString(); if ( cheatWeaponString && *cheatWeaponString ) { CUtlVector<char*, CUtlMemory<char*> > loadout; Q_SplitString( cheatWeaponString, " ", loadout ); for ( int i=0; i<loadout.Count(); ++i ) { const char *item = loadout[i]; if ( FStrEq( item, "vest" ) ) { me->GiveNamedItem( "item_kevlar" ); } else if ( FStrEq( item, "vesthelm" ) ) { me->GiveNamedItem( "item_assaultsuit" ); } else if ( FStrEq( item, "defuser" ) ) { if ( me->GetTeamNumber() == TEAM_CT ) { me->GiveDefuser(); } } else if ( FStrEq( item, "nvgs" ) ) { me->m_bHasNightVision = true; } else if ( FStrEq( item, "primammo" ) ) { me->AttemptToBuyAmmo( 0 ); } else if ( FStrEq( item, "secammo" ) ) { me->AttemptToBuyAmmo( 1 ); } else { me->GiveWeapon( item ); } } m_doneBuying = true; return; } if (!me->IsInBuyZone()) { m_doneBuying = true; CONSOLE_ECHO( "%s bot spawned outside of a buy zone (%d, %d, %d)\n", (me->GetTeamNumber() == TEAM_CT) ? "CT" : "Terrorist", (int)me->GetAbsOrigin().x, (int)me->GetAbsOrigin().y, (int)me->GetAbsOrigin().z ); return; } // try to buy some weapons const float buyInterval = 0.02f; if (gpGlobals->curtime - me->GetStateTimestamp() > buyInterval) { me->m_stateTimestamp = gpGlobals->curtime; bool isPreferredAllDisallowed = true; // try to buy our preferred weapons first if (m_prefIndex < me->GetProfile()->GetWeaponPreferenceCount() && bot_randombuy.GetBool() == false ) { // need to retry because sometimes first buy fails?? const int maxPrefRetries = 2; if (m_prefRetries >= maxPrefRetries) { // try to buy next preferred weapon ++m_prefIndex; m_prefRetries = 0; return; } int weaponPreference = me->GetProfile()->GetWeaponPreference( m_prefIndex ); // don't buy it again if we still have one from last round char weaponPreferenceName[32]; Q_snprintf( weaponPreferenceName, sizeof(weaponPreferenceName), "weapon_%s", me->GetProfile()->GetWeaponPreferenceAsString( m_prefIndex ) ); if( me->Weapon_OwnsThisType(weaponPreferenceName) )//Prefs and buyalias use the short version, this uses the long { // done with buying preferred weapon m_prefIndex = 9999; return; } if (me->HasShield() && weaponPreference == WEAPON_SHIELDGUN) { // done with buying preferred weapon m_prefIndex = 9999; return; } const char *buyAlias = NULL; if (weaponPreference == WEAPON_SHIELDGUN) { if (TheCSBots()->AllowTacticalShield()) buyAlias = "shield"; } else { buyAlias = WeaponIDToAlias( weaponPreference ); WeaponType type = GetWeaponType( buyAlias ); switch( type ) { case PISTOL: if (!TheCSBots()->AllowPistols()) buyAlias = NULL; break; case SHOTGUN: if (!TheCSBots()->AllowShotguns()) buyAlias = NULL; break; case SUB_MACHINE_GUN: if (!TheCSBots()->AllowSubMachineGuns()) buyAlias = NULL; break; case RIFLE: if (!TheCSBots()->AllowRifles()) buyAlias = NULL; break; case MACHINE_GUN: if (!TheCSBots()->AllowMachineGuns()) buyAlias = NULL; break; case SNIPER_RIFLE: if (!TheCSBots()->AllowSnipers()) buyAlias = NULL; break; } } if (buyAlias) { Q_snprintf( cmdBuffer, 256, "buy %s\n", buyAlias ); CCommand args; args.Tokenize( cmdBuffer ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy preferred weapon %s.\n", buyAlias ); isPreferredAllDisallowed = false; } ++m_prefRetries; // bail out so we dont waste money on other equipment // unless everything we prefer has been disallowed, then buy at random if (isPreferredAllDisallowed == false) return; } // if we have no preferred primary weapon (or everything we want is disallowed), buy at random if (!me->HasPrimaryWeapon() && (isPreferredAllDisallowed || !me->GetProfile()->HasPrimaryPreference())) { if (m_buyShield) { // buy a shield CCommand args; args.Tokenize( "buy shield" ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy a shield.\n" ); } else { // build list of allowable weapons to buy BuyInfo *masterPrimary = (me->GetTeamNumber() == TEAM_TERRORIST) ? primaryWeaponBuyInfoT : primaryWeaponBuyInfoCT; BuyInfo *stockPrimary[ PRIMARY_WEAPON_BUY_COUNT ]; int stockPrimaryCount = 0; // dont choose sniper rifles as often const float sniperRifleChance = 50.0f; bool wantSniper = (RandomFloat( 0, 100 ) < sniperRifleChance) ? true : false; if ( bot_randombuy.GetBool() ) { wantSniper = true; } for( int i=0; i<PRIMARY_WEAPON_BUY_COUNT; ++i ) { if ((masterPrimary[i].type == SHOTGUN && TheCSBots()->AllowShotguns()) || (masterPrimary[i].type == SUB_MACHINE_GUN && TheCSBots()->AllowSubMachineGuns()) || (masterPrimary[i].type == RIFLE && TheCSBots()->AllowRifles()) || (masterPrimary[i].type == SNIPER_RIFLE && TheCSBots()->AllowSnipers() && wantSniper) || (masterPrimary[i].type == MACHINE_GUN && TheCSBots()->AllowMachineGuns())) { stockPrimary[ stockPrimaryCount++ ] = &masterPrimary[i]; } } if (stockPrimaryCount) { // buy primary weapon if we don't have one int which; // on hard difficulty levels, bots try to buy preferred weapons on the first pass if (m_retries == 0 && TheCSBots()->GetDifficultyLevel() >= BOT_HARD && bot_randombuy.GetBool() == false ) { // count up available preferred weapons int prefCount = 0; for( which=0; which<stockPrimaryCount; ++which ) if (stockPrimary[which]->preferred) ++prefCount; if (prefCount) { int whichPref = RandomInt( 0, prefCount-1 ); for( which=0; which<stockPrimaryCount; ++which ) if (stockPrimary[which]->preferred && whichPref-- == 0) break; } else { // no preferred weapons available, just pick randomly which = RandomInt( 0, stockPrimaryCount-1 ); } } else { which = RandomInt( 0, stockPrimaryCount-1 ); } Q_snprintf( cmdBuffer, 256, "buy %s\n", stockPrimary[ which ]->buyAlias ); CCommand args; args.Tokenize( cmdBuffer ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy %s.\n", stockPrimary[ which ]->buyAlias ); } } } // // If we now have a weapon, or have tried for too long, we're done // if (me->HasPrimaryWeapon() || m_retries++ > 5) { // primary ammo CCommand args; if (me->HasPrimaryWeapon()) { args.Tokenize( "buy primammo" ); me->ClientCommand( args ); } // buy armor last, to make sure we bought a weapon first args.Tokenize( "buy vesthelm" ); me->ClientCommand( args ); args.Tokenize( "buy vest" ); me->ClientCommand( args ); // pistols - if we have no preferred pistol, buy at random if (TheCSBots()->AllowPistols() && !me->GetProfile()->HasPistolPreference()) { if (m_buyPistol) { int which = RandomInt( 0, SECONDARY_WEAPON_BUY_COUNT-1 ); const char *what = NULL; if (me->GetTeamNumber() == TEAM_TERRORIST) what = secondaryWeaponBuyInfoT[ which ].buyAlias; else what = secondaryWeaponBuyInfoCT[ which ].buyAlias; Q_snprintf( cmdBuffer, 256, "buy %s\n", what ); args.Tokenize( cmdBuffer ); me->ClientCommand( args ); // only buy one pistol m_buyPistol = false; } // make sure we have enough pistol ammo args.Tokenize( "buy secammo" ); me->ClientCommand( args ); } // buy a grenade if we wish, and we don't already have one if (m_buyGrenade && !me->HasGrenade()) { if (UTIL_IsTeamAllBots( me->GetTeamNumber() )) { // only allow Flashbangs if everyone on the team is a bot (dont want to blind our friendly humans) float rnd = RandomFloat( 0, 100 ); if (rnd < 10) { args.Tokenize( "buy smokegrenade" ); me->ClientCommand( args ); // smoke grenade } else if (rnd < 35) { args.Tokenize( "buy flashbang" ); me->ClientCommand( args ); // flashbang } else { args.Tokenize( "buy hegrenade" ); me->ClientCommand( args ); // he grenade } } else { if (RandomFloat( 0, 100 ) < 10) { args.Tokenize( "buy smokegrenade" ); // smoke grenade me->ClientCommand( args ); } else { args.Tokenize( "buy hegrenade" ); // he grenade me->ClientCommand( args ); } } } if (m_buyDefuseKit) { args.Tokenize( "buy defuser" ); me->ClientCommand( args ); } m_doneBuying = true; } } }
//--------------------------------------------------------------------------------- // Purpose: Load maps into memory //--------------------------------------------------------------------------------- void LoadMaps(const char *map_being_loaded) { FileHandle_t file_handle; char base_filename[512]; char map_name[128]; bool map_is_in_map_cycle; bool found_match; // Don't call FreeMaps() !!!! FreeList((void **) &map_list, &map_list_size); FreeList((void **) &votemap_list, &votemap_list_size); FreeList((void **) &map_in_cycle_list, &map_in_cycle_list_size); FreeList((void **) &map_not_in_cycle_list, &map_not_in_cycle_list_size); FindMapCVars(); // MMsg("************ LOADING MAP LISTS *************\n"); override_changelevel = 0; // MMsg("Loading Map [%s]\n", map_being_loaded); Q_strcpy(current_map, map_being_loaded); // Update last maps list last_map_index ++; if (last_map_index == MAX_LAST_MAPS) { last_map_index = 0; } Q_strcpy(last_map_list[last_map_index].map_name, current_map); time_t current_time; time(¤t_time); last_map_list[last_map_index].start_time = current_time; SetChangeLevelReason(""); Q_strcpy(last_map_list[last_map_index].end_reason, ""); // Reset force map stuff, mani_map_cycle_mode will set these if necessary // when server.cfg is run Q_strcpy(forced_nextmap,""); override_changelevel = 0; override_setnextmap = false; // Get nextmap on level change file_handle = filesystem->Open (mapcyclefile->GetString(),"rt",NULL); if (file_handle == NULL) { // MMsg("Failed to load %s\n", mapcyclefile->GetString()); Q_strcpy(next_map, map_being_loaded); mani_nextmap.SetValue(next_map); AddToList((void **) &map_in_cycle_list, sizeof(map_t), &map_in_cycle_list_size); Q_strcpy(map_in_cycle_list[map_in_cycle_list_size - 1].map_name, map_being_loaded); } else { // MMsg("Mapcycle list [%s]\n", mapcyclefile->GetString()); while (filesystem->ReadLine (map_name, sizeof(map_name), file_handle) != NULL) { if (!ParseLine(map_name, true, false)) { continue; } if (engine->IsMapValid(map_name) == 0) { // MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name); continue; } AddToList((void **) &map_in_cycle_list, sizeof(map_t), &map_in_cycle_list_size); Q_strcpy(map_in_cycle_list[map_in_cycle_list_size - 1].map_name, map_name); map_in_cycle_list[map_in_cycle_list_size - 1].selected_for_vote = false; // MMsg("[%s] ", map_name); } // MMsg("\n"); filesystem->Close(file_handle); } // Check if this map is in the map cycle map_is_in_map_cycle = false; for (int i = 0; i < map_in_cycle_list_size; i ++) { if (FStrEq(map_in_cycle_list[i].map_name, current_map)) { map_is_in_map_cycle = true; break; } } if (!map_is_in_map_cycle) { // Map loaded is not in the map cycle list // so hl2 will default the next map to // be the first on the map cycle list if (map_in_cycle_list_size != 0) { Q_strcpy(next_map, map_in_cycle_list[0].map_name); mani_nextmap.SetValue(next_map); } } else { // Search map cycle list for nextmap for (int i = 0; i < map_in_cycle_list_size; i ++) { if (FStrEq( map_in_cycle_list[i].map_name, current_map)) { if (i == (map_in_cycle_list_size - 1)) { // End of map list so we must use the first // in the list Q_strcpy(next_map, map_in_cycle_list[0].map_name); mani_nextmap.SetValue(next_map); } else { // Set next map Q_strcpy(next_map, map_in_cycle_list[i+1].map_name); mani_nextmap.SetValue(next_map); } Q_strcpy(last_map_in_cycle, current_map); break; } } } //Get Map list //Default to loading the new location if(filesystem->FileExists("cfg/mapcycle.txt",NULL)) { file_handle = filesystem->Open ("cfg/mapcycle.txt","rt",NULL); } //If that failed, load the default file from the new location else if(filesystem->FileExists("cfg/mapcycle_default.txt",NULL)) { file_handle = filesystem->Open ("cfg/mapcycle_default.txt","rt",NULL); } //fall back to the old location else { file_handle = filesystem->Open ("maplist.txt","rt",NULL); } if (file_handle == NULL) { MMsg("Failed to load maplist.txt/mapcycle.txt YOU MUST HAVE A MAPLIST.TXT FILE!\n"); } else { // MMsg("Map list\n"); while (filesystem->ReadLine (map_name, 128, file_handle) != NULL) { if (!ParseLine(map_name, true, false)) { // String is empty after parsing continue; } if ((!FStrEq( map_name, "test_speakers")) && (!FStrEq( map_name, "test_hardware"))) { if (engine->IsMapValid(map_name) == 0) { MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name); continue; } AddToList((void **) &map_list, sizeof(map_t), &map_list_size); Q_strcpy(map_list[map_list_size-1].map_name, map_name); map_list[map_list_size - 1].selected_for_vote = false; // MMsg("[%s] ", map_name); } } // MMsg("\n"); filesystem->Close(file_handle); } // MMsg("Maps not in [%s]\n", mapcyclefile->GetString()); // Calculate maps not in mapcycle for (int i = 0; i < map_list_size; i ++) { found_match = false; for (int j = 0; j < map_in_cycle_list_size; j++) { if (FStrEq(map_list[i].map_name, map_in_cycle_list[j].map_name)) { found_match = true; break; } } if (!found_match) { AddToList((void **) &map_not_in_cycle_list, sizeof(map_t), &map_not_in_cycle_list_size); Q_strcpy(map_not_in_cycle_list[map_not_in_cycle_list_size - 1].map_name, map_list[i].map_name); // MMsg("[%s] ", map_not_in_cycle_list[map_not_in_cycle_list_size - 1].map_name); } } // MMsg("\n"); // Check if votemaplist.txt exists, create a new one if it doesn't snprintf(base_filename, sizeof (base_filename), "./cfg/%s/votemaplist.txt", mani_path.GetString()); file_handle = filesystem->Open (base_filename,"rt",NULL); if (file_handle == NULL) { MMsg("Failed to load votemaplist.txt\n"); MMsg("Attempting to write a new votemaplist.txt file based on maplist.txt\n"); file_handle = filesystem->Open(base_filename,"wt",NULL); if (file_handle == NULL) { // MMsg("Failed to open votemaplist.txt for writing\n"); } else { // Write votemaplist.txt in human readable text format for (int i = 0; i < map_list_size; i ++) { char temp_string[512]; int temp_length = snprintf(temp_string, sizeof(temp_string), "%s\n", map_list[i].map_name); if (filesystem->Write((void *) temp_string, temp_length, file_handle) == 0) { MMsg("Failed to write map [%s] to votemaplist.txt!!\n", map_list[i].map_name); filesystem->Close(file_handle); break; } } MMsg("Wrote %i maps to votemaplist.txt\n", map_list_size); filesystem->Close(file_handle); } } else { filesystem->Close(file_handle); } // Read in votemaplist.txt file_handle = filesystem->Open (base_filename,"rt",NULL); if (file_handle == NULL) { // MMsg("Failed to load votemaplist.txt\n"); } else { // MMsg("Votemap list\n"); while (filesystem->ReadLine (map_name, sizeof(map_name), file_handle) != NULL) { if (!ParseLine(map_name, true, false)) { // String is empty after parsing continue; } if (engine->IsMapValid(map_name) == 0) { MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name); continue; } AddToList((void **) &votemap_list, sizeof(map_t), &votemap_list_size); Q_strcpy(votemap_list[votemap_list_size - 1].map_name, map_name); votemap_list[votemap_list_size - 1].selected_for_vote = false; // MMsg("[%s] ", map_name); } // MMsg("\n"); filesystem->Close(file_handle); } // Check if loaded map cycle file is different than // the persistent one bool rebuild_proper_map_cycle = false; if (map_in_cycle_list_size != proper_map_cycle_mode_list_size) { rebuild_proper_map_cycle = true; } else { // Both cycles the same size so check maps are in same // order for (int i = 0; i < map_in_cycle_list_size; i ++) { if (!FStrEq(map_in_cycle_list[i].map_name, proper_map_cycle_mode_list[i].map_name)) { rebuild_proper_map_cycle = true; break; } } } if (rebuild_proper_map_cycle) { // Free persistance map cycle and rebuild FreeList((void **) &proper_map_cycle_mode_list, &proper_map_cycle_mode_list_size); for (int i = 0; i < map_in_cycle_list_size; i++) { AddToList((void **) &proper_map_cycle_mode_list, sizeof(track_map_t), &proper_map_cycle_mode_list_size); Q_strcpy(proper_map_cycle_mode_list[i].map_name, map_in_cycle_list[i].map_name); proper_map_cycle_mode_list[i].played = false; if (FStrEq(proper_map_cycle_mode_list[i].map_name, current_map)) { proper_map_cycle_mode_list[i].played = true; } } } // MMsg("Persistant Map Cycle\n"); for (int i = 0; i < proper_map_cycle_mode_list_size; i++) { if (FStrEq(proper_map_cycle_mode_list[i].map_name, current_map)) { proper_map_cycle_mode_list[i].played = true; } if (proper_map_cycle_mode_list[i].played) { // MMsg("*[%s] ", proper_map_cycle_mode_list[i].map_name); } else { // MMsg("[%s] ", proper_map_cycle_mode_list[i].map_name); } } // MMsg("\n"); // MMsg("************ MAP LISTS LOADED *************\n"); }
// Create a custom particle system. Create a new template instead of reading // one off disk. void AvHCustomParticleSystemEntity::KeyValue( KeyValueData* inPkvd ) { // Read tag with ps name and create a new template using it if(FStrEq(inPkvd->szKeyName, kpscSystemName)) { // Custom particle systems shouldn't be specifying a system in the .ps to use ASSERT(false); } else if(FStrEq(inPkvd->szKeyName, kpscGenSource) || FStrEq(inPkvd->szKeyName, "particleGenerationSource")) { char* theEntityName = inPkvd->szValue; this->GetCustomTemplate()->SetGenerationEntityName(theEntityName); inPkvd->fHandled = TRUE; } else if(FStrEq(inPkvd->szKeyName, kpscGenShape) || FStrEq(inPkvd->szKeyName, "particleGenerationShape")) { int theGenerationShape = 0; if(sscanf(inPkvd->szValue, "%d", &theGenerationShape)) { ShapeType theShape = PS_Point; switch(theGenerationShape) { case 4: theShape = PS_Box; break; case 5: theShape = PS_Sphere; break; case 8: theShape = PS_Blob; break; } this->GetCustomTemplate()->SetGenerationShape(theShape); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscSprite) || FStrEq(inPkvd->szKeyName, "particleSprite")) { // relative path to sprite string theSpriteName(inPkvd->szValue); this->GetCustomTemplate()->SetSprite(theSpriteName); inPkvd->fHandled = TRUE; } else if(FStrEq(inPkvd->szKeyName, kpscSpriteNumFrames) || FStrEq(inPkvd->szKeyName, "particleSpriteNumFrames")) { // int number of frames int theNumFrames = 0; if(sscanf(inPkvd->szValue, "%d", &theNumFrames) == 1) { this->GetCustomTemplate()->SetNumSpriteFrames(theNumFrames); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscGenShapeParams) || FStrEq(inPkvd->szKeyName, "particleGenerationShapeParams")) { float theParameter = 0; if(sscanf(inPkvd->szValue, "%f", &theParameter) == 1) { this->GetCustomTemplate()->SetGenerationEntityParameter(theParameter); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscNumParticles) || FStrEq(inPkvd->szKeyName, "particleNumParticles")) { // max particles, or density int theNumParticles = 0; if(sscanf(inPkvd->szValue, "%d", &theNumParticles) == 1) { this->GetCustomTemplate()->SetMaxParticles(theNumParticles); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscGenRate) || FStrEq(inPkvd->szKeyName, "particleGenerationRate")) { // num particles per second int theNumParticles = 0; if(sscanf(inPkvd->szValue, "%d", &theNumParticles) == 1) { this->GetCustomTemplate()->SetGenerationRate(theNumParticles); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscSize) || FStrEq(inPkvd->szKeyName, "particleSize")) { // float particle size float theParticleSize = 0; if(sscanf(inPkvd->szValue, "%f", &theParticleSize) == 1) { this->GetCustomTemplate()->SetParticleSize(theParticleSize); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscSystemLifetime) || FStrEq(inPkvd->szKeyName, "particleSystemLifetime")) { // string system lifetime float theLifetime = -1; if(sscanf(inPkvd->szValue, "%f", &theLifetime) == 1) { this->GetCustomTemplate()->SetParticleSystemLifetime(theLifetime); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscAnimationSpeed) || FStrEq(inPkvd->szKeyName, "particleAnimationSpeed")) { // Sprite animation speed float theAnimSpeed = 1.0f; if(sscanf(inPkvd->szValue, "%f", &theAnimSpeed) == 1) { this->GetCustomTemplate()->SetAnimationSpeed(theAnimSpeed); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscParticleLifetime) || FStrEq(inPkvd->szKeyName, "particleLifetime")) { // string particle lifetime float theLifetime = -1; if(sscanf(inPkvd->szValue, "%f", &theLifetime) == 1) { this->GetCustomTemplate()->SetParticleLifetime(theLifetime); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscVelocityShape) || FStrEq(inPkvd->szKeyName, "particleStartingVelocityShape")) { int theVelocityShape = 0; if(sscanf(inPkvd->szValue, "%d", &theVelocityShape)) { ShapeType theShape = PS_Point; switch(theVelocityShape) { case 1: theShape = PS_Point; break; case 2: theShape = PS_Box; break; case 3: theShape = PS_Sphere; break; case 4: theShape = PS_Blob; break; } this->GetCustomTemplate()->SetStartingVelocityShape(theShape); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscVelocityParams) || FStrEq(inPkvd->szKeyName, "particleStartingVelParams")) { // string, 8 comma-delimited parms ParticleParams theVelParms; if(sscanf(inPkvd->szValue, "%d,%d,%d,%d,%d,%d,%d,%d", theVelParms + 0, theVelParms + 1, theVelParms + 2, theVelParms + 3, theVelParms + 4, theVelParms + 5, theVelParms + 6, theVelParms + 7) == 8) { this->GetCustomTemplate()->SetStartingVelocityParams(theVelParms); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscScale) || FStrEq(inPkvd->szKeyName, "particleScaling")) { // float/string particle scaling float theScaling = 1.0f; if(sscanf(inPkvd->szValue, "%f", &theScaling) == 1) { this->GetCustomTemplate()->SetParticleScaling(theScaling); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscRendermode) || FStrEq(inPkvd->szKeyName, "particleRenderMode")) { // 0-5 render mode int theRenderMode = 0; if(sscanf(inPkvd->szValue, "%d", &theRenderMode) == 1) { this->GetCustomTemplate()->SetRenderMode(theRenderMode); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscMaxAlpha) || FStrEq(inPkvd->szKeyName, "particleMaxAlpha")) { float theMaxAlpha = 1.0f; if(sscanf(inPkvd->szValue, "%f", &theMaxAlpha) == 1) { this->GetCustomTemplate()->SetMaxAlpha(theMaxAlpha); inPkvd->fHandled = TRUE; } } else if(FStrEq(inPkvd->szKeyName, kpscSystemToGen) || FStrEq(inPkvd->szKeyName, "particleSystemToGenerate")) { string theSystemToGenerate = inPkvd->szValue; this->GetCustomTemplate()->SetParticleSystemToGenerate(theSystemToGenerate); inPkvd->fHandled = TRUE; } else { // Call down to base class AvHParticleSystemEntity::KeyValue(inPkvd); } }
/* <36ace2> ../cstrike/dlls/bot/cs_bot_manager.cpp:484 */ void CCSBotManager::__MAKE_VHOOK(ServerCommand)(const char *pcmd) { if (!m_bServerActive || !UTIL_IsGame("czero")) return; char buffer[400]; const char *msg = CMD_ARGV(1); if (FStrEq(pcmd, "bot_about")) { Q_sprintf(buffer, "\n--------------------------------------------------------------------------\nThe Official Counter-Strike Bot V%d.%02d\nCreated by Michael S. Booth\nWeb: www.turtlerockstudios.com\\csbot\nE-mail: [email protected]\n--------------------------------------------------------------------------\n\n", CSBOT_VERSION_MAJOR, CSBOT_VERSION_MINOR); CONSOLE_ECHO(buffer); HintMessageToAllPlayers(buffer); } else if (FStrEq(pcmd, "bot_add")) { BotAddCommand(BOT_TEAM_ANY); } else if (FStrEq(pcmd, "bot_add_t")) { BotAddCommand(BOT_TEAM_T); } else if (FStrEq(pcmd, "bot_add_ct")) { BotAddCommand(BOT_TEAM_CT); } else if (FStrEq(pcmd, "bot_kill")) { bool killThemAll; if (CMD_ARGC() == 1 || FStrEq(msg, "all")) killThemAll = true; else killThemAll = false; for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex); if (pPlayer == NULL) continue; if (FNullEnt(pPlayer->pev)) continue; const char *name = STRING(pPlayer->pev->netname); if (FStrEq(name, "")) continue; if (pPlayer->IsBot()) { if (killThemAll || FStrEq(name, msg)) { pPlayer->TakeDamage(pPlayer->pev, pPlayer->pev, 9999.9f, DMG_CRUSH); } } } } else if (FStrEq(pcmd, "bot_kick")) { bool kickThemAll; if (CMD_ARGC() == 1 || FStrEq(msg, "all")) kickThemAll = true; else kickThemAll = false; for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex); if (pPlayer == NULL) continue; if (FNullEnt(pPlayer->pev)) continue; const char *name = STRING(pPlayer->pev->netname); if (FStrEq(name, "")) continue; if (pPlayer->IsBot()) { if (kickThemAll || FStrEq(name, msg)) { SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", name)); CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1); } } } if (kickThemAll || cv_bot_quota.value < 0.0f) { CVAR_SET_FLOAT("bot_quota", 0); } } else if (FStrEq(pcmd, "bot_knives_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 0); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 0); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_pistols_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 0); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_snipers_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 1); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_all_weapons")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 1); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 1); CVAR_SET_FLOAT("bot_allow_rifles", 1); CVAR_SET_FLOAT("bot_allow_machine_guns", 1); CVAR_SET_FLOAT("bot_allow_grenades", 1); CVAR_SET_FLOAT("bot_allow_snipers", 1); CVAR_SET_FLOAT("bot_allow_shield", 1); } else if (FStrEq(pcmd, "entity_dump")) { PrintAllEntities(); } else if (FStrEq(pcmd, "bot_nav_delete")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DELETE; } else if (FStrEq(pcmd, "bot_nav_split")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLIT; } else if (FStrEq(pcmd, "bot_nav_merge")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MERGE; } else if (FStrEq(pcmd, "bot_nav_mark")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK; } else if (FStrEq(pcmd, "bot_nav_begin_area")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_BEGIN_AREA; } else if (FStrEq(pcmd, "bot_nav_end_area")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_END_AREA; } else if (FStrEq(pcmd, "bot_nav_connect")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_CONNECT; } else if (FStrEq(pcmd, "bot_nav_disconnect")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DISCONNECT; } else if (FStrEq(pcmd, "bot_nav_splice")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLICE; } else if (FStrEq(pcmd, "bot_nav_crouch")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_CROUCH; } else if (FStrEq(pcmd, "bot_nav_jump")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_JUMP; } else if (FStrEq(pcmd, "bot_nav_precise")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_PRECISE; } else if (FStrEq(pcmd, "bot_nav_no_jump")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_NO_JUMP; } else if (FStrEq(pcmd, "bot_nav_analyze")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_isAnalysisRequested) = true; } else if (FStrEq(pcmd, "bot_nav_strip")) { StripNavigationAreas();// TODO: reverse me } else if (FStrEq(pcmd, "bot_nav_save")) { GET_GAME_DIR(buffer); buffer[ Q_strlen(buffer) ] = '\\'; Q_strcat(buffer, CBotManager::GetNavMapFilename()); if (SaveNavigationMap(buffer))// TODO: reverse me CONSOLE_ECHO("Navigation map '%s' saved.\n", buffer); else CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", buffer); } else if (FStrEq(pcmd, "bot_nav_load")) { ValidateMapData(); } else if (FStrEq(pcmd, "bot_nav_use_place")) { if (CMD_ARGC() == 1) { int i = 0; const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter, i++) { if ((*iter)->GetID() == GetNavPlace()) CONSOLE_ECHO("--> %-26s", (*iter)->GetName()); else CONSOLE_ECHO("%-30s", (*iter)->GetName()); if (!(i % 3)) CONSOLE_ECHO("\n"); } CONSOLE_ECHO("\n"); } else { const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); const BotPhrase *found = NULL; bool isAmbiguous = false; for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter) { if (!Q_strnicmp((*iter)->GetName(), msg, Q_strlen(msg))) { if (!Q_strcmp((*iter)->GetName(), msg)) { found = (*iter); break; } if (found != NULL) isAmbiguous = true; else found = (*iter); } } if (isAmbiguous) { CONSOLE_ECHO("Ambiguous\n"); return; } if (found != NULL) { CONSOLE_ECHO("Current place set to '%s'\n", found->GetName()); m_navPlace = found->GetID(); } } } else if (FStrEq(pcmd, "bot_nav_toggle_place_mode")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_MODE; } else if (FStrEq(pcmd, "bot_nav_place_floodfill")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_FLOODFILL; } else if (FStrEq(pcmd, "bot_nav_place_pick")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_PICK; } else if (FStrEq(pcmd, "bot_nav_toggle_place_painting")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_PAINTING; } else if (FStrEq(pcmd, "bot_goto_mark")) { // tell the first bot we find to go to our marked area CNavArea *area = GetMarkedArea();// TODO: reverse me if (area != NULL) { CBaseEntity *pEntity = NULL; while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL) { if (!pEntity->IsPlayer()) continue; if ((pEntity->pev->flags & FL_DORMANT) == FL_DORMANT) continue; CBasePlayer *playerOrBot = GetClassPtr((CBasePlayer *)pEntity->pev); if (playerOrBot->IsBot()) { CCSBot *bot = reinterpret_cast<CCSBot *>(playerOrBot); bot->MoveTo(&area->m_center, FASTEST_ROUTE);// TODO: reverse me return; } } } } else if (FStrEq(pcmd, "bot_memory_usage")) { CONSOLE_ECHO("Memory usage:\n"); CONSOLE_ECHO(" %d bytes per bot\b", sizeof(CCSBot)); CONSOLE_ECHO(" %d Navigation Areas @ %d bytes each = %d bytes\n", TheNavAreaGrid.GetNavAreaCount(), sizeof(CNavArea), TheNavAreaGrid.GetNavAreaCount() * sizeof(CNavArea)); CONSOLE_ECHO(" %d Hiding Spots @ %d bytes each = %d bytes\n", TheHidingSpotList.size(), sizeof(HidingSpot), sizeof(HidingSpot) * TheHidingSpotList.size()); unsigned int encounterMem = 0; for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { CNavArea *area = (*iter); for (SpotEncounterList::iterator siter = area->m_spotEncounterList.begin(); siter != area->m_spotEncounterList.end(); ++siter) { // TODO: Fix me, this is crashed in HOOK_GAMEDLL SpotEncounter se = (*siter); encounterMem += sizeof(SpotEncounter); encounterMem += sizeof(SpotOrder) * se.spotList.size(); } } CONSOLE_ECHO(" Encounter Spot data = %d bytes\n", encounterMem); } else if (FStrEq(pcmd, "bot_nav_mark_unnamed")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK_UNNAMED; } else if (FStrEq(pcmd, "bot_nav_warp")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_WARP_TO_MARK; } else if (FStrEq(pcmd, "bot_nav_corner_select")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SELECT_CORNER; } else if (FStrEq(pcmd, "bot_nav_corner_raise")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_RAISE_CORNER; } else if (FStrEq(pcmd, "bot_nav_corner_lower")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_LOWER_CORNER; } else if (FStrEq(pcmd, "bot_nav_check_consistency")) { if (CMD_ARGC() != 2) { CONSOLE_ECHO("usage: bot_nav_check_consistency <filename>\n"); return; } SanityCheckNavigationMap(msg);// TODO: reverse me } }
void CLightning::KeyValue( KeyValueData *pkvd ) { if (FStrEq(pkvd->szKeyName, "LightningStart")) { m_iszStartEntity = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "LightningEnd")) { m_iszEndEntity = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "life")) { m_life = atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "BoltWidth")) { m_boltWidth = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) { m_noiseAmplitude = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "TextureScroll")) { m_speed = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "StrikeTime")) { m_restrike = atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "texture")) { m_iszSpriteName = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "framestart")) { m_frameStart = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "Radius")) { m_radius = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "damage")) { pev->dmg = atof(pkvd->szValue); pkvd->fHandled = TRUE; } else CBeam::KeyValue( pkvd ); }
void RadioUseCheck( edict_t *pEntity ) { // Elaborate and stupid function to see if the player is pressing USE, // cause if we dont do this we cant catch it cause its really handled by the TFC DLL int MyNumber = ENTINDEX( pEntity ); entvars_t *pev = VARS( pEntity ); int buttonsChanged = (lastButtons[MyNumber] ^ pev->button); // These buttons have changed this frame int m_afButtonPressed = buttonsChanged & pev->button; // The changed ones still down are "pressed" int m_afButtonReleased = buttonsChanged & (~pev->button); // The ones not down are "released" lastButtons[MyNumber] = pev->button; // Was use pressed or released? if ( !(buttonsChanged & IN_USE)) return; CBaseEntity *pObject = NULL; CBaseEntity *pClosest = NULL; Vector vecLOS; float flMaxDot = VIEW_FIELD_NARROW; float flDot; UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing while ((pObject = UTIL_FindEntityInSphere( pObject, pev->origin, PLAYER_SEARCH_RADIUS )) != NULL) { char *pClassname = (char *)STRING(pObject->pev->classname); if (FStrEq(pClassname, "building_radio")) { vecLOS = ((pObject->pev->absmin + ( pObject->pev->size * 0.5 )) - (pev->origin + pev->view_ofs)); vecLOS = UTIL_ClampVectorToBox( vecLOS, pObject->pev->size * 0.5 ); flDot = DotProduct (vecLOS , gpGlobals->v_forward); if (flDot > flMaxDot ) { pClosest = pObject; flMaxDot = flDot; } } } pObject = pClosest; // Found an object if (pObject ) { if (m_afButtonPressed & IN_USE) { char *pClassname = (char *)STRING(pObject->pev->classname); if (FStrEq(pClassname, "building_radio")) { // It's a radio. Do the RADIO USE thingummy, letting the radio decide what use does. RadioUse( pObject->edict(), pEntity ); } } } }
void RadioHandleMenuItem(edict_t *pEntity, const char *itm) { int ind = ENTINDEX(pEntity); if (!pEntity) return; // Cant use camera in spec mode if (pEntity->v.iuser1 > 0) return; // Are we even supposed to hangle this? if (menushow2[ind] != 0 && (gpGlobals->time <= menushow2[ind])) { menushow2[ind] = 0; edict_t *pentUsed = INDEXENT(lastMenuEnt[ind]); if (FNullEnt(pentUsed)) return; // dont use if radio is tuning if (pentUsed->v.iuser1 == 1) return; // See what they pressed. // menu page 1 if (lastMenuPage[ind] == 1 || lastMenuPage[ind] == 2) { if (lastMenuPage[ind] == 1) { if (FStrEq(itm, "1")) { RadioSwitchToSong(1, lastMenuEnt[ind]); } else if (FStrEq(itm, "2")) { RadioSwitchToSong(2, lastMenuEnt[ind]); } else if (FStrEq(itm, "3")) { RadioSwitchToSong(3, lastMenuEnt[ind]); } else if (FStrEq(itm, "4")) { RadioSwitchToSong(4, lastMenuEnt[ind]); } else if (FStrEq(itm, "5")) { RadioSwitchToSong(5, lastMenuEnt[ind]); } else if (FStrEq(itm, "6")) { RadioShowMenu( pEntity, pentUsed, 2 ); } } else if (lastMenuPage[ind] == 2) { // menu page 2 if (FStrEq(itm, "1")) { RadioSwitchToSong(6, lastMenuEnt[ind]); } else if (FStrEq(itm, "2")) { RadioSwitchToSong(7, lastMenuEnt[ind]); } else if (FStrEq(itm, "3")) { RadioSwitchToSong(8, lastMenuEnt[ind]); } else if (FStrEq(itm, "4")) { RadioSwitchToSong(9, lastMenuEnt[ind]); } else if (FStrEq(itm, "5")) { RadioSwitchToSong(10, lastMenuEnt[ind]); } else if (FStrEq(itm, "6")) { RadioShowMenu( pEntity, pentUsed, 1 ); } } if (FStrEq(itm, "7")) { RadioSwitchToSong(100, lastMenuEnt[ind]); } else if (FStrEq(itm, "8")) { RadioSwitchToSong(101, lastMenuEnt[ind]); } else if (FStrEq(itm, "9")) { RadioShowMenu( pEntity, pentUsed, 3 ); } } else if (lastMenuPage[ind] == 3) { if (FStrEq(itm, "1")) { RadioChangeSongPitch(100, pentUsed); } else if (FStrEq(itm, "2")) { RadioChangeSongPitch(50, pentUsed); } else if (FStrEq(itm, "3")) { RadioChangeSongPitch(80, pentUsed); } else if (FStrEq(itm, "4")) { RadioChangeSongPitch(120, pentUsed); } else if (FStrEq(itm, "5")) { RadioChangeSongPitch(140, pentUsed); } else if (FStrEq(itm, "6")) { RadioChangeSongPitch(150, pentUsed); } else if (FStrEq(itm, "7")) { RadioChangeSongPitch(180, pentUsed); } else if (FStrEq(itm, "8")) { RadioChangeSongPitch(200, pentUsed); } else if (FStrEq(itm, "9")) { RadioShowMenu( pEntity, pentUsed, 1 ); } } } }
bool CBotMod::IsSteamFolder(char *szSteamFolder) { return FStrEq(m_szSteamFolder, szSteamFolder); }
//--------------------------------------------------------------------------------- // Purpose: Process the ma_maphistory command //--------------------------------------------------------------------------------- PLUGIN_RESULT ProcessMaMapHistory(player_t *player_ptr, const char *command_name, const int help_id, const int command_type) { last_map_t *last_maps_list = NULL; int number_of_maps = 0; if (player_ptr) { // Check if player is admin if (!gpManiClient->HasAccess(player_ptr->index, ADMIN, ADMIN_BASIC_ADMIN, war_mode)) return PLUGIN_BAD_ADMIN; } last_maps_list = GetLastMapsPlayed (&number_of_maps, MAX_LAST_MAPS); if (number_of_maps == 0) { OutputToConsole(player_ptr, "No Previous maps played!\n"); return PLUGIN_STOP; } OutputToConsole(player_ptr, "Last %i maps played\n\n", number_of_maps); int count = 1; for (int i = 0; i < number_of_maps; i++) { if (FStrEq(last_maps_list[i].map_name,"")) { continue; } struct tm *time_now; time_now = localtime(&(last_maps_list[i].start_time)); char temp_string[64]; snprintf(temp_string, sizeof(temp_string), "%02i:%02i:%02i", time_now->tm_hour, time_now->tm_min, time_now->tm_sec); if (i == 0) { OutputToConsole(player_ptr, "%02i. %s %s (Current Map)\n", count++, last_maps_list[i].map_name, temp_string); } else { int t_length = last_maps_list[i - 1].start_time - last_maps_list[i].start_time; int seconds = (int)(t_length % 60); int minutes = (int)(t_length / 60 % 60); int hours = (int)(t_length / 3600 % 24); int days = (int)(t_length / 3600 / 24); char time_online[128]; if (days > 0) { snprintf (time_online, sizeof (time_online), "%id %ih %im %is", days, hours, minutes, seconds); } else if (hours > 0) { snprintf (time_online, sizeof (time_online), "%ih %im %is", hours, minutes, seconds); } else if (minutes > 0) { snprintf (time_online, sizeof (time_online), "%im %is", minutes, seconds); } else { snprintf (time_online, sizeof (time_online), "%is", seconds); } OutputToConsole(player_ptr, "%02i. %s %s %s %s\n", count++, last_maps_list[i].map_name, temp_string, time_online, last_maps_list[i].end_reason); } } return PLUGIN_STOP; }
bool CBotMod::IsModFolder(char *szModFolder) { return FStrEq(m_szModFolder, szModFolder); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CCSPlayerResource::UpdatePlayerData( void ) { int i; m_iPlayerC4 = 0; m_iPlayerVIP = 0; for ( i = 1; i <= gpGlobals->maxClients; i++ ) { CCSPlayer *pPlayer = (CCSPlayer*)UTIL_PlayerByIndex( i ); if ( pPlayer && pPlayer->IsConnected() ) { if ( pPlayer->IsVIP() ) { // we should only have one VIP Assert( m_iPlayerVIP == 0 ); m_iPlayerVIP = i; } if ( pPlayer->HasC4() ) { // we should only have one bomb m_iPlayerC4 = i; } } } CBaseEntity *c4 = NULL; if ( m_iPlayerC4 == 0 ) { // no player has C4, update C4 position if ( g_C4s.Count() > 0 ) { c4 = g_C4s[0]; m_vecC4 = c4->GetAbsOrigin(); } else { m_vecC4.Init(); } } //int numHostages = g_Hostages.Count(); for ( i = 0; i < MAX_HOSTAGES; i++ ) { /*if ( i >= numHostages ) { // engine->Con_NPrintf( i, "Dead" ); m_bHostageAlive.Set( i, false ); m_isHostageFollowingSomeone.Set( i, false ); continue; } // CHostage* pHostage = g_Hostages[i]; //m_bHostageAlive.Set( i, pHostage->IsRescuable() ); /*if ( pHostage->IsValid() ) { m_iHostageX.Set( i, (int) pHostage->GetAbsOrigin().x ); m_iHostageY.Set( i, (int) pHostage->GetAbsOrigin().y ); m_iHostageZ.Set( i, (int) pHostage->GetAbsOrigin().z ); m_iHostageEntityIDs.Set( i, pHostage->entindex() ); //m_isHostageFollowingSomeone.Set( i, pHostage->IsFollowingSomeone() ); // engine->Con_NPrintf( i, "ID:%d Pos:(%.0f,%.0f,%.0f)", pHostage->entindex(), pHostage->GetAbsOrigin().x, pHostage->GetAbsOrigin().y, pHostage->GetAbsOrigin().z ); } else { // engine->Con_NPrintf( i, "Invalid" ); }*/ } if( !m_foundGoalPositions ) { // We only need to update these once a map, but we need the client to know about them. CBaseEntity* ent = NULL; while ( ( ent = gEntList.FindEntityByClassname( ent, "func_bomb_target" ) ) != NULL ) { const Vector &pos = ent->WorldSpaceCenter(); CNavArea *area = TheNavMesh->GetNearestNavArea( pos, true ); const char *placeName = (area) ? TheNavMesh->PlaceToName( area->GetPlace() ) : NULL; if ( placeName == NULL ) { // The bomb site has no area or place name, so just choose A then B if ( m_bombsiteCenterA.Get().IsZero() ) { m_bombsiteCenterA = pos; } else { m_bombsiteCenterB = pos; } } else { // The bomb site has a place name, so choose accordingly if( FStrEq( placeName, "BombsiteA" ) ) { m_bombsiteCenterA = pos; } else { m_bombsiteCenterB = pos; } } m_foundGoalPositions = true; } int hostageRescue = 0; while ( (( ent = gEntList.FindEntityByClassname( ent, "func_hostage_rescue" ) ) != NULL) && (hostageRescue < MAX_HOSTAGE_RESCUES) ) { const Vector &pos = ent->WorldSpaceCenter(); m_hostageRescueX.Set( hostageRescue, (int) pos.x ); m_hostageRescueY.Set( hostageRescue, (int) pos.y ); m_hostageRescueZ.Set( hostageRescue, (int) pos.z ); hostageRescue++; m_foundGoalPositions = true; } } bool bombSpotted = false; if ( c4 ) { Spotter spotter( c4, m_vecC4, TEAM_CT ); ForEachPlayer( spotter ); if ( spotter.Spotted() ) { bombSpotted = true; } } for ( int i=0; i < MAX_PLAYERS+1; i++ ) { CCSPlayer *target = ToCSPlayer( UTIL_PlayerByIndex( i ) ); if ( !target || !target->IsAlive() ) { m_bPlayerSpotted.Set( i, 0 ); continue; } Spotter spotter( target, target->EyePosition(), (target->GetTeamNumber()==TEAM_CT) ? TEAM_TERRORIST : TEAM_CT ); ForEachPlayer( spotter ); if ( spotter.Spotted() ) { if ( target->HasC4() ) { bombSpotted = true; } m_bPlayerSpotted.Set( i, 1 ); } else { m_bPlayerSpotted.Set( i, 0 ); } } if ( bombSpotted ) { m_bBombSpotted = true; } else { m_bBombSpotted = false; } BaseClass::UpdatePlayerData(); }
void CPathTrack::SetPrevious( CPathTrack *pprev ) { // Only set previous if this isn't my alternate path if ( pprev && !FStrEq( STRING(pprev->GetEntityName()), STRING(m_altName) ) ) m_pprevious = pprev; }
void CASW_EquipmentList::LoadEquipmentList() { m_iNumRegular = 0; m_iNumExtra = 0; KeyValues *kv = new KeyValues("Equipment"); // load equipment if (kv->LoadFromFile(filesystem, "resource/Equipment.res")) { int iNumEquip = 0; KeyValues *pKeys = kv; while ( pKeys ) { for (KeyValues *details = pKeys->GetFirstSubKey(); details; details = details->GetNextKey()) { if ( FStrEq( details->GetName(), "Regular" ) ) { //Msg("adding regular equip %s\n", MAKE_STRING( details->GetString() )); CASW_EquipItem* equip = new CASW_EquipItem(); equip->m_EquipClass = MAKE_STRING( details->GetString() ); equip->m_iItemIndex = iNumEquip; equip->m_bSelectableInBriefing = true; m_Regular.AddToTail(equip); m_iNumRegular++; iNumEquip++; } else if ( FStrEq( details->GetName(), "Extra" ) ) { //Msg("adding extra equip %s\n", MAKE_STRING( details->GetString() )); CASW_EquipItem* equip = new CASW_EquipItem(); equip->m_EquipClass = MAKE_STRING( details->GetString() ); equip->m_iItemIndex = iNumEquip; equip->m_bSelectableInBriefing = true; m_Extra.AddToTail(equip); m_iNumExtra++; iNumEquip++; } // hidden equip else if ( FStrEq( details->GetName(), "RegularOther" ) ) { //Msg("adding regular equip %s\n", MAKE_STRING( details->GetString() )); CASW_EquipItem* equip = new CASW_EquipItem(); equip->m_EquipClass = MAKE_STRING( details->GetString() ); equip->m_iItemIndex = iNumEquip; equip->m_bSelectableInBriefing = false; m_Regular.AddToTail(equip); iNumEquip++; } else if ( FStrEq( details->GetName(), "ExtraOther" ) ) { //Msg("adding extra equip %s\n", MAKE_STRING( details->GetString() )); CASW_EquipItem* equip = new CASW_EquipItem(); equip->m_EquipClass = MAKE_STRING( details->GetString() ); equip->m_iItemIndex = iNumEquip; equip->m_bSelectableInBriefing = false; m_Extra.AddToTail(equip); iNumEquip++; } } pKeys = pKeys->GetNextKey(); } } }
int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity) { CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); if(pEntity && pSaveData) { entvars_t tmpVars; Vector oldOffset; CRestore restoreHelper(pSaveData); if(globalEntity) { CRestore tmpRestore(pSaveData); tmpRestore.PrecacheMode(0); tmpRestore.ReadEntVars("ENTVARS", &tmpVars); // HACKHACK - reset the save pointers, we're going to restore for real this time pSaveData->size = pSaveData->pTable[pSaveData->currentIndex].location; pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size; // ------------------- const globalentity_t *pGlobal = gGlobalState.EntityFromTable(tmpVars.globalname); // Don't overlay any instance of the global that isn't the latest // pSaveData->szCurrentMapName is the level this entity is coming from // pGlobla->levelName is the last level the global entity was active in. // If they aren't the same, then this global update is out of date. if(!FStrEq(pSaveData->szCurrentMapName, pGlobal->levelName)) return 0; // Compute the new global offset oldOffset = pSaveData->vecLandmarkOffset; CBaseEntity *pNewEntity = FindGlobalEntity(tmpVars.classname, tmpVars.globalname); if(pNewEntity) { // ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) ); // Tell the restore code we're overlaying a global entity from another level restoreHelper.SetGlobalMode(1); // Don't overwrite global fields pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins; pEntity = pNewEntity; // we're going to restore this data OVER the old entity pent = ENT(pEntity->pev); // Update the global table to say that the global definition of this entity should come from this level gGlobalState.EntityUpdate(pEntity->pev->globalname, gpGlobals->mapname); } else { // This entity will be freed automatically by the engine. If we don't do a restore on a matching entity (below) // or call EntityUpdate() to move it to this level, we haven't changed global state at all. return 0; } } if(pEntity->ObjectCaps() & FCAP_MUST_SPAWN) { pEntity->Restore(restoreHelper); pEntity->Spawn(); } else { pEntity->Restore(restoreHelper); pEntity->Precache(); } // Again, could be deleted, get the pointer again. pEntity = (CBaseEntity *)GET_PRIVATE(pent); #if 0 if ( pEntity && pEntity->pev->globalname && globalEntity ) { ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) ); } #endif // Is this an overriding global entity (coming over the transition), or one restoring in a level if(globalEntity) { // ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) ); pSaveData->vecLandmarkOffset = oldOffset; if(pEntity) { UTIL_SetOrigin(pEntity->pev, pEntity->pev->origin); pEntity->OverrideReset(); } } else if(pEntity && pEntity->pev->globalname) { const globalentity_t *pGlobal = gGlobalState.EntityFromTable(pEntity->pev->globalname); if(pGlobal) { // Already dead? delete if(pGlobal->state == GLOBAL_DEAD) return -1; else if(!FStrEq(STRING(gpGlobals->mapname), pGlobal->levelName)) { pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive } // In this level & not dead, continue on as normal } else { ALERT(at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname)); // Spawned entities default to 'On' gGlobalState.EntityAdd(pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON); } } } return 0; }
void CBaseDoor::Spawn( void ) { if( pev->skin == CONTENTS_NONE ) { // normal door if( FBitSet( pev->spawnflags, SF_DOOR_PASSABLE )) pev->solid = SOLID_NOT; else pev->solid = SOLID_BSP; } else { SetBits( pev->spawnflags, SF_DOOR_SILENT ); pev->solid = SOLID_NOT; // special contents } Precache(); pev->movetype = MOVETYPE_PUSH; SET_MODEL( edict(), GetModel() ); // NOTE: original Half-Life was contain a bug in LinearMove function // while m_flWait was equal 0 then object has stopped forever. See code from quake: /* void LinearMove( Vector vecDest, float flSpeed ) { ... ... ... if( flTravelTime < 0.1f ) { pev->velocity = g_vecZero; pev->nextthink = pev->ltime + 0.1f; return; } } */ // this block was removed from Half-Life and there no difference // between wait = 0 and wait = -1. But in Xash this bug was fixed // and level-designer errors is now actual. I'm set m_flWait to -1 for compatibility if( m_flWait == 0.0f ) m_flWait = -1; if( pev->speed == 0 ) pev->speed = 100; if( pev->movedir == g_vecZero ) pev->movedir = Vector( 1.0f, 0.0f, 0.0f ); m_vecPosition1 = GetLocalOrigin(); // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big Vector vecSize = pev->size - Vector( 2, 2, 2 ); m_vecPosition2 = m_vecPosition1 + (pev->movedir * (DotProductAbs( pev->movedir, vecSize ) - m_flLip)); ASSERTSZ( m_vecPosition1 != m_vecPosition2, "door start/end positions are equal" ); if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN )) { UTIL_SetOrigin( this, m_vecPosition2 ); m_vecPosition2 = m_vecPosition1; m_vecPosition1 = GetLocalOrigin(); } else { UTIL_SetOrigin( this, m_vecPosition1 ); } // another hack: PhysX 2.8.4.0 crashed while trying to created kinematic body from this brush-model if ( FStrEq( STRING( gpGlobals->mapname ), "c2a5e" ) && FStrEq( STRING( pev->model ), "*103" )); else m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); m_iState = STATE_OFF; // if the door is flagged for USE button activation only, use NULL touch function if( FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY )) { SetTouch( NULL ); } else { // touchable button SetTouch( DoorTouch ); } }
//--------------------------------------------------------------------------------- // Purpose: called when a client types in a command (only a subset of commands however, not CON_COMMAND's) //--------------------------------------------------------------------------------- PLUGIN_RESULT CEmptyServerPlugin::ClientCommand( edict_t *pEntity ) { const char *pcmd = engine->Cmd_Argv(0); if ( !pEntity || pEntity->IsFree() ) { return PLUGIN_CONTINUE; } if ( FStrEq( pcmd, "menu" ) ) { KeyValues *kv = new KeyValues( "menu" ); kv->SetString( "title", "You've got options, hit ESC" ); kv->SetInt( "level", 1 ); kv->SetColor( "color", Color( 255, 0, 0, 255 )); kv->SetInt( "time", 20 ); kv->SetString( "msg", "Pick an option\nOr don't." ); for( int i = 1; i < 9; i++ ) { char num[10], msg[10], cmd[10]; Q_snprintf( num, sizeof(num), "%i", i ); Q_snprintf( msg, sizeof(msg), "Option %i", i ); Q_snprintf( cmd, sizeof(cmd), "option%i", i ); KeyValues *item1 = kv->FindKey( num, true ); item1->SetString( "msg", msg ); item1->SetString( "command", cmd ); } helpers->CreateMessage( pEntity, DIALOG_MENU, kv, this ); kv->deleteThis(); return PLUGIN_STOP; // we handled this function } else if ( FStrEq( pcmd, "rich" ) ) { KeyValues *kv = new KeyValues( "menu" ); kv->SetString( "title", "A rich message" ); kv->SetInt( "level", 1 ); kv->SetInt( "time", 20 ); kv->SetString( "msg", "This is a long long long text string.\n\nIt also has line breaks." ); helpers->CreateMessage( pEntity, DIALOG_TEXT, kv, this ); kv->deleteThis(); return PLUGIN_STOP; // we handled this function } else if ( FStrEq( pcmd, "msg" ) ) { KeyValues *kv = new KeyValues( "menu" ); kv->SetString( "title", "Just a simple hello" ); kv->SetInt( "level", 1 ); kv->SetInt( "time", 20 ); helpers->CreateMessage( pEntity, DIALOG_MSG, kv, this ); kv->deleteThis(); return PLUGIN_STOP; // we handled this function } else if ( FStrEq( pcmd, "entry" ) ) { KeyValues *kv = new KeyValues( "entry" ); kv->SetString( "title", "Stuff" ); kv->SetString( "msg", "Enter something" ); kv->SetString( "command", "say" ); // anything they enter into the dialog turns into a say command kv->SetInt( "level", 1 ); kv->SetInt( "time", 20 ); helpers->CreateMessage( pEntity, DIALOG_ENTRY, kv, this ); kv->deleteThis(); return PLUGIN_STOP; // we handled this function } return PLUGIN_CONTINUE; }
//--------------------------------------------------------------------------------- // Purpose: Check Player on connect //--------------------------------------------------------------------------------- bool ManiReservedSlot::NetworkIDValidated(player_t *player_ptr) { bool is_reserve_player = false; player_t temp_player; int allowed_players; int total_players; m_iUnaccountedPlayers--; if ((war_mode) || (!mani_reserve_slots.GetBool()) || (mani_reserve_slots_number_of_slots.GetInt() == 0)) // with the other method ( zero slots ) { // other player is kicked BEFORE return true; // NetworkIDValidated } total_players = m_iUnaccountedPlayers + GetNumberOfActivePlayers(true); // DirectLogCommand("[DEBUG] Total players on server [%i]\n", total_players); if (total_players <= (max_players - mani_reserve_slots_number_of_slots.GetInt())) { // DirectLogCommand("[DEBUG] No reserve slot action required\n"); return true; } GetIPAddressFromPlayer(player_ptr); Q_strcpy (player_ptr->steam_id, engine->GetPlayerNetworkIDString(player_ptr->entity)); IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(player_ptr->entity); if (playerinfo && playerinfo->IsConnected()) { Q_strcpy(player_ptr->name, playerinfo->GetName()); } else { Q_strcpy(player_ptr->name,""); } if (FStrEq("BOT", player_ptr->steam_id)) return true; player_ptr->is_bot = false; if (IsPlayerInReserveList(player_ptr)) is_reserve_player = true; else if (mani_reserve_slots_include_admin.GetBool() && gpManiClient->HasAccess(player_ptr->index, ADMIN, ADMIN_BASIC_ADMIN)) is_reserve_player = true; if (mani_reserve_slots_allow_slot_fill.GetInt() != 1) { // Keep reserve slots free at all times allowed_players = max_players - mani_reserve_slots_number_of_slots.GetInt(); if (total_players > allowed_players) { if (!is_reserve_player) { DisconnectPlayer(player_ptr); return false; } temp_player.index = FindPlayerToKick(); FindPlayerByIndex(&temp_player); DisconnectPlayer(&temp_player); } } return true; }
// // Just to ignore the "wad" field. // void CWorld :: KeyValue( KeyValueData *pkvd ) { if ( FStrEq(pkvd->szKeyName, "skyname") ) { // Sent over net now. CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "sounds") ) { gpGlobals->cdAudioTrack = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "WaveHeight") ) { // Sent over net now. pev->scale = atof(pkvd->szValue) * (1.0/8.0); pkvd->fHandled = TRUE; CVAR_SET_FLOAT( "sv_wateramp", pev->scale ); } else if ( FStrEq(pkvd->szKeyName, "MaxRange") ) { pev->speed = atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "chaptertitle") ) { pev->netname = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "startdark") ) { // UNDONE: This is a gross hack!!! The CVAR is NOT sent over the client/sever link // but it will work for single player int flag = atoi(pkvd->szValue); pkvd->fHandled = TRUE; if ( flag ) pev->spawnflags |= SF_WORLD_DARK; } else if ( FStrEq(pkvd->szKeyName, "newunit") ) { // Single player only. Clear save directory if set if ( atoi(pkvd->szValue) ) CVAR_SET_FLOAT( "sv_newunit", 1 ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "gametitle") ) { if ( atoi(pkvd->szValue) ) pev->spawnflags |= SF_WORLD_TITLE; pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "mapteams") ) { pev->team = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "defaultteam") ) { if ( atoi(pkvd->szValue) ) { pev->spawnflags |= SF_WORLD_FORCETEAM; } pkvd->fHandled = TRUE; } // Discwar else if ( FStrEq(pkvd->szKeyName, "playersperteam") ) { g_iPlayersPerTeam = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "no_arena") ) { if ( atoi(pkvd->szValue) ) m_iArenaOff = TRUE; pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue( pkvd ); }
//========================================================= // Start task - selects the correct activity and performs // any necessary calculations to start the next task on the // schedule. //========================================================= void CBaseMonster :: StartTask ( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TURN_RIGHT: { float flCurrentYaw; flCurrentYaw = UTIL_AngleMod( pev->angles.y ); pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw - pTask->flData ); SetTurnActivity(); break; } case TASK_TURN_LEFT: { float flCurrentYaw; flCurrentYaw = UTIL_AngleMod( pev->angles.y ); pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw + pTask->flData ); SetTurnActivity(); break; } case TASK_REMEMBER: { Remember ( (int)pTask->flData ); TaskComplete(); break; } case TASK_FORGET: { Forget ( (int)pTask->flData ); TaskComplete(); break; } case TASK_FIND_HINTNODE: { m_iHintNode = FindHintNode(); if ( m_iHintNode != NO_NODE ) { TaskComplete(); } else { TaskFail(); } break; } case TASK_STORE_LASTPOSITION: { m_vecLastPosition = pev->origin; TaskComplete(); break; } case TASK_CLEAR_LASTPOSITION: { m_vecLastPosition = g_vecZero; TaskComplete(); break; } case TASK_CLEAR_HINTNODE: { m_iHintNode = NO_NODE; TaskComplete(); break; } case TASK_STOP_MOVING: { if ( m_IdealActivity == m_movementActivity ) { m_IdealActivity = GetStoppedActivity(); } RouteClear(); TaskComplete(); break; } case TASK_PLAY_SEQUENCE_FACE_ENEMY: case TASK_PLAY_SEQUENCE_FACE_TARGET: case TASK_PLAY_SEQUENCE: { m_IdealActivity = ( Activity )( int )pTask->flData; break; } case TASK_PLAY_ACTIVE_IDLE: { // monsters verify that they have a sequence for the node's activity BEFORE // moving towards the node, so it's ok to just set the activity without checking here. m_IdealActivity = ( Activity )WorldGraph.m_pNodes[ m_iHintNode ].m_sHintActivity; break; } case TASK_SET_SCHEDULE: { Schedule_t *pNewSchedule; pNewSchedule = GetScheduleOfType( (int)pTask->flData ); if ( pNewSchedule ) { ChangeSchedule( pNewSchedule ); } else { TaskFail(); } break; } case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, pTask->flData ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, pTask->flData, CoverRadius() ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, CoverRadius() ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_COVER_FROM_ENEMY: { entvars_t *pevCover; if ( m_hEnemy == NULL ) { // Find cover from self if no enemy available pevCover = pev; // TaskFail(); // return; } else pevCover = m_hEnemy->pev; if ( FindLateralCover( pevCover->origin, pevCover->view_ofs ) ) { // try lateral first m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else if ( FindCover( pevCover->origin, pevCover->view_ofs, 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_COVER_FROM_ORIGIN: { if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no cover! TaskFail(); } } break; case TASK_FIND_COVER_FROM_BEST_SOUND: { CSound *pBestSound; pBestSound = PBestSound(); ASSERT( pBestSound != NULL ); /* if ( pBestSound && FindLateralCover( pBestSound->m_vecOrigin, g_vecZero ) ) { // try lateral first m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } */ if ( pBestSound && FindCover( pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no coverwhatsoever. or no sound in list TaskFail(); } break; } case TASK_FACE_HINTNODE: { pev->ideal_yaw = WorldGraph.m_pNodes[ m_iHintNode ].m_flHintYaw; SetTurnActivity(); break; } case TASK_FACE_LASTPOSITION: MakeIdealYaw ( m_vecLastPosition ); SetTurnActivity(); break; case TASK_FACE_TARGET: if ( m_hTargetEnt != NULL ) { MakeIdealYaw ( m_hTargetEnt->pev->origin ); SetTurnActivity(); } else TaskFail(); break; case TASK_FACE_ENEMY: { MakeIdealYaw ( m_vecEnemyLKP ); SetTurnActivity(); break; } case TASK_FACE_IDEAL: { SetTurnActivity(); break; } case TASK_FACE_ROUTE: { if (FRouteClear()) { ALERT(at_aiconsole, "No route to face!\n"); TaskFail(); } else { MakeIdealYaw(m_Route[m_iRouteIndex].vecLocation); SetTurnActivity(); } break; } case TASK_WAIT_PVS: case TASK_WAIT_INDEFINITE: { // don't do anything. break; } case TASK_WAIT: case TASK_WAIT_FACE_ENEMY: {// set a future time that tells us when the wait is over. m_flWaitFinished = gpGlobals->time + pTask->flData; break; } case TASK_WAIT_RANDOM: {// set a future time that tells us when the wait is over. m_flWaitFinished = gpGlobals->time + RANDOM_FLOAT( 0.1, pTask->flData ); break; } case TASK_MOVE_TO_TARGET_RANGE: { if ( (m_hTargetEnt->pev->origin - pev->origin).Length() < 1 ) TaskComplete(); else { m_vecMoveGoal = m_hTargetEnt->pev->origin; if ( !MoveToTarget( ACT_WALK, 2 ) ) TaskFail(); } break; } case TASK_RUN_TO_SCRIPT: case TASK_WALK_TO_SCRIPT: { Activity newActivity; if ( !m_pGoalEnt || (m_pGoalEnt->pev->origin - pev->origin).Length() < 1 ) TaskComplete(); else { if ( pTask->iTask == TASK_WALK_TO_SCRIPT ) newActivity = ACT_WALK; else newActivity = ACT_RUN; // This monster can't do this! if ( LookupActivity( newActivity ) == ACTIVITY_NOT_AVAILABLE ) TaskComplete(); else { if ( m_pGoalEnt != NULL ) { Vector vecDest; vecDest = m_pGoalEnt->pev->origin; if ( !MoveToLocation( newActivity, 2, vecDest ) ) { TaskFail(); ALERT( at_aiconsole, "%s Failed to reach script!!!\n", STRING(pev->classname) ); RouteClear(); } } else { TaskFail(); ALERT( at_aiconsole, "%s: MoveTarget is missing!?!\n", STRING(pev->classname) ); RouteClear(); } } } TaskComplete(); break; } case TASK_CLEAR_MOVE_WAIT: { m_flMoveWaitFinished = gpGlobals->time; TaskComplete(); break; } case TASK_MELEE_ATTACK1_NOTURN: case TASK_MELEE_ATTACK1: { m_IdealActivity = ACT_MELEE_ATTACK1; break; } case TASK_MELEE_ATTACK2_NOTURN: case TASK_MELEE_ATTACK2: { m_IdealActivity = ACT_MELEE_ATTACK2; break; } case TASK_RANGE_ATTACK1_NOTURN: case TASK_RANGE_ATTACK1: { m_IdealActivity = ACT_RANGE_ATTACK1; break; } case TASK_RANGE_ATTACK2_NOTURN: case TASK_RANGE_ATTACK2: { m_IdealActivity = ACT_RANGE_ATTACK2; break; } case TASK_RELOAD_NOTURN: case TASK_RELOAD: { m_IdealActivity = ACT_RELOAD; break; } case TASK_SPECIAL_ATTACK1: { m_IdealActivity = ACT_SPECIAL_ATTACK1; break; } case TASK_SPECIAL_ATTACK2: { m_IdealActivity = ACT_SPECIAL_ATTACK2; break; } case TASK_SET_ACTIVITY: { m_IdealActivity = (Activity)(int)pTask->flData; TaskComplete(); break; } case TASK_GET_PATH_TO_ENEMY_LKP: { if ( BuildRoute ( m_vecEnemyLKP, bits_MF_TO_LOCATION, NULL ) ) { TaskComplete(); } else if (BuildNearestRoute( m_vecEnemyLKP, pev->view_ofs, 0, (m_vecEnemyLKP - pev->origin).Length() )) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToEnemyLKP failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_ENEMY: { CBaseEntity *pEnemy = m_hEnemy; if ( pEnemy == NULL ) { TaskFail(); return; } if ( BuildRoute ( pEnemy->pev->origin, bits_MF_TO_ENEMY, pEnemy ) ) { TaskComplete(); } else if (BuildNearestRoute( pEnemy->pev->origin, pEnemy->pev->view_ofs, 0, (pEnemy->pev->origin - pev->origin).Length() )) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_ENEMY_CORPSE: { UTIL_MakeVectors( pev->angles ); if ( BuildRoute ( m_vecEnemyLKP - gpGlobals->v_forward * 64, bits_MF_TO_LOCATION, NULL ) ) { TaskComplete(); } else { ALERT ( at_aiconsole, "GetPathToEnemyCorpse failed!!\n" ); TaskFail(); } } break; case TASK_GET_PATH_TO_SPOT: { CBaseEntity *pPlayer = UTIL_FindEntityByClassname( NULL, "player" ); if ( BuildRoute ( m_vecMoveGoal, bits_MF_TO_LOCATION, pPlayer ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_TARGET: { RouteClear(); if ( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_SCRIPT: { RouteClear(); if ( m_pCine != NULL && MoveToLocation( m_movementActivity, 1, m_pCine->pev->origin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_HINTNODE:// for active idles! { if ( MoveToLocation( m_movementActivity, 2, WorldGraph.m_pNodes[ m_iHintNode ].m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToHintNode failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_LASTPOSITION: { m_vecMoveGoal = m_vecLastPosition; if ( MoveToLocation( m_movementActivity, 2, m_vecMoveGoal ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToLastPosition failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_BESTSOUND: { CSound *pSound; pSound = PBestSound(); if ( pSound && MoveToLocation( m_movementActivity, 2, pSound->m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToBestSound failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_BESTSCENT: { CSound *pScent; pScent = PBestScent(); if ( pScent && MoveToLocation( m_movementActivity, 2, pScent->m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToBestScent failed!!\n" ); TaskFail(); } break; } case TASK_RUN_PATH: { // UNDONE: This is in some default AI and some monsters can't run? -- walk instead? if ( LookupActivity( ACT_RUN ) != ACTIVITY_NOT_AVAILABLE ) { m_movementActivity = ACT_RUN; } else { m_movementActivity = ACT_WALK; } TaskComplete(); break; } case TASK_WALK_PATH: { if ( pev->movetype == MOVETYPE_FLY ) { m_movementActivity = ACT_FLY; } if ( LookupActivity( ACT_WALK ) != ACTIVITY_NOT_AVAILABLE ) { m_movementActivity = ACT_WALK; } else { m_movementActivity = ACT_RUN; } TaskComplete(); break; } case TASK_STRAFE_PATH: { Vector2D vec2DirToPoint; Vector2D vec2RightSide; // to start strafing, we have to first figure out if the target is on the left side or right side UTIL_MakeVectors ( pev->angles ); vec2DirToPoint = ( m_Route[ 0 ].vecLocation - pev->origin ).Make2D().Normalize(); vec2RightSide = gpGlobals->v_right.Make2D().Normalize(); if ( DotProduct ( vec2DirToPoint, vec2RightSide ) > 0 ) { // strafe right m_movementActivity = ACT_STRAFE_RIGHT; } else { // strafe left m_movementActivity = ACT_STRAFE_LEFT; } TaskComplete(); break; } case TASK_WAIT_FOR_MOVEMENT: { if (FRouteClear()) { TaskComplete(); } break; } case TASK_EAT: { Eat( pTask->flData ); TaskComplete(); break; } case TASK_SMALL_FLINCH: { m_IdealActivity = GetSmallFlinchActivity(); break; } case TASK_DIE: { RouteClear(); m_IdealActivity = GetDeathActivity(); pev->deadflag = DEAD_DYING; break; } case TASK_SOUND_WAKE: { AlertSound(); TaskComplete(); break; } case TASK_SOUND_DIE: { DeathSound(); TaskComplete(); break; } case TASK_SOUND_IDLE: { IdleSound(); TaskComplete(); break; } case TASK_SOUND_PAIN: { PainSound(); TaskComplete(); break; } case TASK_SOUND_DEATH: { DeathSound(); TaskComplete(); break; } case TASK_SOUND_ANGRY: { // sounds are complete as soon as we get here, cause we've already played them. ALERT ( at_aiconsole, "SOUND\n" ); TaskComplete(); break; } case TASK_WAIT_FOR_SCRIPT: { if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime ) { TaskComplete(); //LRC - start playing immediately } else if (!m_pCine->IsAction() && m_pCine->m_iszIdle) { m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszIdle, FALSE ); if (FStrEq( STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay))) { pev->framerate = 0; } } else m_IdealActivity = ACT_IDLE; break; } case TASK_PLAY_SCRIPT: { if (m_pCine->IsAction()) { //ALERT(at_console,"PlayScript: setting idealactivity %d\n",m_pCine->m_fAction); switch(m_pCine->m_fAction) { case 0: m_IdealActivity = ACT_RANGE_ATTACK1; break; case 1: m_IdealActivity = ACT_RANGE_ATTACK2; break; case 2: m_IdealActivity = ACT_MELEE_ATTACK1; break; case 3: m_IdealActivity = ACT_MELEE_ATTACK2; break; case 4: m_IdealActivity = ACT_SPECIAL_ATTACK1; break; case 5: m_IdealActivity = ACT_SPECIAL_ATTACK2; break; case 6: m_IdealActivity = ACT_RELOAD; break; case 7: m_IdealActivity = ACT_HOP; break; } pev->framerate = 1.0; // shouldn't be needed, but just in case pev->movetype = MOVETYPE_FLY; ClearBits(pev->flags, FL_ONGROUND); } else { m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszPlay, TRUE ); if ( m_fSequenceFinished ) ClearSchedule(); pev->framerate = 1.0; //ALERT( at_aiconsole, "Script %s has begun for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) ); } m_scriptState = SCRIPT_PLAYING; break; } case TASK_ENABLE_SCRIPT: { m_pCine->DelayStart( 0 ); TaskComplete(); break; } //LRC case TASK_END_SCRIPT: { m_pCine->SequenceDone( this ); TaskComplete(); break; } case TASK_PLANT_ON_SCRIPT: { if ( m_pCine != NULL ) { // Plant on script // LRC - if it's a teleport script, do the turn too if (m_pCine->m_fMoveTo == 4 || m_pCine->m_fMoveTo == 6) { if (m_pCine->m_fTurnType == 0) //LRC pev->angles.y = m_hTargetEnt->pev->angles.y; else if (m_pCine->m_fTurnType == 1) pev->angles.y = UTIL_VecToYaw(m_hTargetEnt->pev->origin - pev->origin); pev->ideal_yaw = pev->angles.y; pev->avelocity = Vector( 0, 0, 0 ); pev->velocity = Vector( 0, 0, 0 ); pev->effects |= EF_NOINTERP; } if (m_pCine->m_fMoveTo != 6) pev->origin = m_pGoalEnt->pev->origin; } TaskComplete(); break; } case TASK_FACE_SCRIPT: { if ( m_pCine != NULL && m_pCine->m_fMoveTo != 0) // movetype "no move" makes us ignore turntype { switch (m_pCine->m_fTurnType) { case 0: pev->ideal_yaw = UTIL_AngleMod( m_pCine->pev->angles.y ); break; case 1: // yes, this is inconsistent- turn to face uses the "target" and turn to angle uses the "cine". if (m_hTargetEnt) MakeIdealYaw ( m_hTargetEnt->pev->origin ); else MakeIdealYaw ( m_pCine->pev->origin ); break; // default: don't turn } } TaskComplete(); m_IdealActivity = ACT_IDLE; RouteClear(); break; } case TASK_SUGGEST_STATE: { m_IdealMonsterState = (MONSTERSTATE)(int)pTask->flData; TaskComplete(); break; } case TASK_SET_FAIL_SCHEDULE: m_failSchedule = (int)pTask->flData; TaskComplete(); break; case TASK_CLEAR_FAIL_SCHEDULE: m_failSchedule = SCHED_NONE; TaskComplete(); break; default: { ALERT ( at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask ); break; } } }
/* <8e19e> ../cstrike/dlls/func_tank.cpp:214 */ void CFuncTank::__MAKE_VHOOK(KeyValue)(KeyValueData *pkvd) { if (FStrEq(pkvd->szKeyName, "yawrate")) { m_yawRate = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "yawrange")) { m_yawRange = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "yawtolerance")) { m_yawTolerance = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchrange")) { m_pitchRange = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchrate")) { m_pitchRate = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchtolerance")) { m_pitchTolerance = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firerate")) { m_fireRate = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrel")) { m_barrelPos.x = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrely")) { m_barrelPos.y = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrelz")) { m_barrelPos.z = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spritescale")) { m_spriteScale = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spritesmoke")) { m_iszSpriteSmoke = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spriteflash")) { m_iszSpriteFlash = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "rotatesound")) { pev->noise = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "persistence")) { m_persist = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bullet")) { m_bulletType = (TANKBULLET)Q_atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bullet_damage")) { m_iBulletDamage = Q_atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firespread")) { m_spread = Q_atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "minRange")) { m_minRange = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "maxRange")) { m_maxRange = Q_atof(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "master")) { m_iszMaster = ALLOC_STRING(pkvd->szValue); pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); }
//----------------------------------------------------------------------------- // Purpose: Parse a keyvalues section into the prop // // pInteractionSection is a bit of jiggery-pokery to get around the unfortunate // fact that the interaction KV sections ("physgun_interactions", "fire_interactions", etc) // are OUTSIDE the "prop_data" KV section in the model, but may be contained WITHIN the // specified Base's "prop_data" section (i.e. in propdata.txt) //----------------------------------------------------------------------------- int CPropData::ParsePropFromKV( CBaseEntity *pProp, KeyValues *pSection, KeyValues *pInteractionSection ) { IBreakableWithPropData *pBreakableInterface = dynamic_cast<IBreakableWithPropData*>(pProp); if ( !pBreakableInterface ) return PARSE_FAILED_BAD_DATA; if ( !pBreakableInterface ) return PARSE_FAILED_BAD_DATA; int iBaseResult = PARSE_SUCCEEDED; // Do we have a base? char const *pszBase = pSection->GetString( "base" ); if ( pszBase && pszBase[0] ) { iBaseResult = ParsePropFromBase( pProp, pszBase ); if ( (iBaseResult != PARSE_SUCCEEDED) && (iBaseResult != PARSE_SUCCEEDED_ALLOWED_STATIC) ) return iBaseResult; } // Allow overriding of Block LOS int iBlockLOS = pSection->GetFloat( "blockLOS", -1 ); if ( iBlockLOS != -1 ) { pBreakableInterface->SetPropDataBlocksLOS( iBlockLOS != 0 ); } // Set whether AI can walk on this prop int iIsWalkable = pSection->GetFloat( "AIWalkable", -1 ); if ( iIsWalkable != -1 ) { pBreakableInterface->SetPropDataIsAIWalkable( iIsWalkable != 0 ); } // Set custom damage table const char *pszTableName; if ( pBreakableInterface->GetPhysicsDamageTable() == NULL_STRING ) { pszTableName = pSection->GetString( "damage_table", NULL ); } else { pszTableName = pSection->GetString( "damage_table", STRING(pBreakableInterface->GetPhysicsDamageTable()) ); } if ( pszTableName && pszTableName[0] ) { pBreakableInterface->SetPhysicsDamageTable( AllocPooledString( pszTableName ) ); } else { pBreakableInterface->SetPhysicsDamageTable( NULL_STRING ); } // Get multiplayer physics mode if not set by map pBreakableInterface->SetPhysicsMode( pSection->GetInt( "physicsmode", pBreakableInterface->GetPhysicsMode() ) ); const char *multiplayer_break = pSection->GetString( "multiplayer_break", NULL ); if ( multiplayer_break ) { mp_break_t mode = MULTIPLAYER_BREAK_DEFAULT; if ( FStrEq( multiplayer_break, "server" ) ) { mode = MULTIPLAYER_BREAK_SERVERSIDE; } else if ( FStrEq( multiplayer_break, "client" ) ) { mode = MULTIPLAYER_BREAK_CLIENTSIDE; } else if ( FStrEq( multiplayer_break, "both" ) ) { mode = MULTIPLAYER_BREAK_BOTH; } pBreakableInterface->SetMultiplayerBreakMode( mode ); } // Get damage modifiers, but only if they're specified, because our base may have already overridden them. pBreakableInterface->SetDmgModBullet( pSection->GetFloat( "dmg.bullets", pBreakableInterface->GetDmgModBullet() ) ); pBreakableInterface->SetDmgModClub( pSection->GetFloat( "dmg.club", pBreakableInterface->GetDmgModClub() ) ); pBreakableInterface->SetDmgModExplosive( pSection->GetFloat( "dmg.explosive", pBreakableInterface->GetDmgModExplosive() ) ); // Get the health (unless this is an override prop) if ( !FClassnameIs( pProp, "prop_physics_override" ) && !FClassnameIs( pProp, "prop_dynamic_override" ) ) { pProp->SetHealth( pSection->GetInt( "health", pProp->GetHealth() ) ); // Explosive? pBreakableInterface->SetExplosiveDamage( pSection->GetFloat( "explosive_damage", pBreakableInterface->GetExplosiveDamage() ) ); pBreakableInterface->SetExplosiveRadius( pSection->GetFloat( "explosive_radius", pBreakableInterface->GetExplosiveRadius() ) ); #ifdef GAME_DLL // If we now have health, we're not allowed to ignore physics damage if ( pProp->GetHealth() ) { pProp->RemoveSpawnFlags( SF_PHYSPROP_DONT_TAKE_PHYSICS_DAMAGE ); } #endif } const char *pszBreakableModel; if ( pBreakableInterface->GetBreakableModel() == NULL_STRING ) { pszBreakableModel = pSection->GetString( "breakable_model", NULL ); } else { pszBreakableModel = pSection->GetString( "breakable_model", STRING(pBreakableInterface->GetBreakableModel()) ); } if ( pszBreakableModel && pszBreakableModel[0] ) { pBreakableInterface->SetBreakableModel( AllocPooledString( pszBreakableModel ) ); } else { pBreakableInterface->SetBreakableModel( NULL_STRING ); } pBreakableInterface->SetBreakableSkin( pSection->GetInt( "breakable_skin", pBreakableInterface->GetBreakableSkin() ) ); pBreakableInterface->SetBreakableCount( pSection->GetInt( "breakable_count", pBreakableInterface->GetBreakableCount() ) ); // Calculate the maximum size of the breakables this breakable will produce Vector vecSize = pProp->CollisionProp()->OBBSize(); // Throw away the smallest coord int iSmallest = SmallestAxis(vecSize); vecSize[iSmallest] = 1; float flVolume = vecSize.x * vecSize.y * vecSize.z; int iMaxSize = floor( flVolume / (32.0*32.0) ); pBreakableInterface->SetMaxBreakableSize( iMaxSize ); // Now parse our interactions for ( int i = 0; i < PROPINTER_NUM_INTERACTIONS; i++ ) { // If we hit this assert, we have too many interactions for our current storage solution to handle Assert( i < 32 ); propdata_interaction_s *pInteraction = &sPropdataInteractionSections[i]; KeyValues *pkvCurrentInter = pInteractionSection->FindKey( pInteraction->pszSectionName ); if ( pkvCurrentInter ) { char const *pszInterBase = pkvCurrentInter->GetString( pInteraction->pszKeyName ); if ( pszInterBase && pszInterBase[0] && !stricmp( pszInterBase, pInteraction->pszValue ) ) { pBreakableInterface->SetInteraction( (propdata_interactions_t)i ); } } } // If the base said we're allowed to be static, return that if ( iBaseResult == PARSE_SUCCEEDED_ALLOWED_STATIC ) return PARSE_SUCCEEDED_ALLOWED_STATIC; // Otherwise, see if our propdata says we are allowed to be static if ( pSection->GetInt( "allowstatic", 0 ) ) return PARSE_SUCCEEDED_ALLOWED_STATIC; return PARSE_SUCCEEDED; }