//----------------------------------------------------------------------------- // Purpose: Parse data found from npcData keyValue... //----------------------------------------------------------------------------- void CNPC_Monster::ParseNPCScript( const char *szScript ) { // Get our data and make sure it is not NULL... KeyValues *pkvMyNPCData = pkvNPCData(szScript); if (!pkvMyNPCData) { Warning("NPC_MONSTER linked to %s.txt was removed, no such script exist!\n", szScript); UTIL_Remove(this); return; } // Parse our data: KeyValues *pkvInfoField = pkvMyNPCData->FindKey("Info"); KeyValues *pkvModelField = pkvMyNPCData->FindKey("Model"); KeyValues *pkvRandomModelsField = pkvMyNPCData->FindKey("Models"); bool bRandomModel = false; if (pkvInfoField) { cEntName = MAKE_STRING(ReadAndAllocStringValue(pkvInfoField, "Name")); cSoundScript = MAKE_STRING(ReadAndAllocStringValue(pkvInfoField, "SoundScript")); m_iHealth = pkvInfoField->GetInt("Health", 100); m_iDamage[0] = pkvInfoField->GetInt("DamageOneHand", 10); m_iDamage[1] = pkvInfoField->GetInt("DamageBothHands", 10); m_flAttackRange = pkvInfoField->GetFloat("AttackRange", 70.0f); m_iMaxHealth = m_iHealth; m_bCanOpenDoors = ((pkvInfoField->GetInt("CanOpenDoors") >= 1) ? true : false); } if (pkvModelField) { bRandomModel = (!pkvModelField->FindKey("Path")); if (!bRandomModel) cModel = MAKE_STRING(ReadAndAllocStringValue(pkvModelField, "Path")); m_fIsTorso = ((pkvModelField->GetInt("IsTorso") >= 1) ? true : false); if (!strcmp(pkvModelField->GetString("Skin"), "random")) m_iSkin = random->RandomInt(0, pkvModelField->GetInt("MaxSkins")); else m_iSkin = pkvModelField->GetInt("Skin"); SetBloodColor(pkvModelField->GetInt("BloodType")); } if (pkvRandomModelsField && bRandomModel) cModel = MAKE_STRING(GetRandomModel(pkvRandomModelsField)); Precache(); pkvMyNPCData->deleteThis(); }
//----------------------------------------------------------------------------- // Purpose: Return a random model in the Models key. //----------------------------------------------------------------------------- const char *CNPC_Monster::GetRandomModel(KeyValues *pkvValues) { const char *szModel = NULL; int iCount = 0, iFind = 0; for (KeyValues *sub = pkvValues->GetFirstSubKey(); sub; sub = sub->GetNextKey()) iCount++; iFind = random->RandomInt(1, iCount); iCount = 0; for (KeyValues *sub = pkvValues->GetFirstSubKey(); sub; sub = sub->GetNextKey()) { iCount++; if (iCount == iFind) { szModel = ReadAndAllocStringValue(pkvValues, sub->GetName()); break; } } return szModel; }
void LoadObjectInfos( IBaseFileSystem *pFileSystem ) { const char *pFilename = "scripts/objects.txt"; // Make sure this stuff hasn't already been loaded. Assert( !AreObjectInfosLoaded() ); KeyValues *pValues = new KeyValues( "Object descriptions" ); if ( !pValues->LoadFromFile( pFileSystem, pFilename, "GAME" ) ) { Error( "Can't open %s for object info.", pFilename ); pValues->deleteThis(); return; } // Now read each class's information in. for ( int iObj=0; iObj < ARRAYSIZE( g_ObjectInfos ); iObj++ ) { CObjectInfo *pInfo = &g_ObjectInfos[iObj]; KeyValues *pSub = pValues->FindKey( pInfo->m_pObjectName ); if ( !pSub ) { Error( "Missing section '%s' from %s.", pInfo->m_pObjectName, pFilename ); pValues->deleteThis(); return; } // Read all the info in. if ( (pInfo->m_flBuildTime = pSub->GetFloat( "BuildTime", -999 )) == -999 || (pInfo->m_nMaxObjects = pSub->GetInt( "MaxObjects", -999 )) == -999 || (pInfo->m_Cost = pSub->GetInt( "Cost", -999 )) == -999 || (pInfo->m_CostMultiplierPerInstance = pSub->GetFloat( "CostMultiplier", -999 )) == -999 || (pInfo->m_UpgradeCost = pSub->GetInt( "UpgradeCost", -999 )) == -999 || (pInfo->m_MaxUpgradeLevel = pSub->GetInt( "MaxUpgradeLevel", -999 )) == -999 || (pInfo->m_SelectionSlot = pSub->GetInt( "SelectionSlot", -999 )) == -999 || (pInfo->m_SelectionPosition = pSub->GetInt( "SelectionPosition", -999 )) == -999 ) { Error( "Missing data for object '%s' in %s.", pInfo->m_pObjectName, pFilename ); pValues->deleteThis(); return; } pInfo->m_pClassName = ReadAndAllocStringValue( pSub, "ClassName", pFilename ); pInfo->m_pStatusName = ReadAndAllocStringValue( pSub, "StatusName", pFilename ); pInfo->m_pBuilderWeaponName = ReadAndAllocStringValue( pSub, "BuilderWeaponName", pFilename ); pInfo->m_pBuilderPlacementString = ReadAndAllocStringValue( pSub, "BuilderPlacementString", pFilename ); pInfo->m_bSolidToPlayerMovement = pSub->GetInt( "SolidToPlayerMovement", 0 ) ? true : false; pInfo->m_pIconActive = ReadAndAllocStringValue( pSub, "IconActive", pFilename ); pInfo->m_pIconInactive = ReadAndAllocStringValue( pSub, "IconInactive", pFilename ); pInfo->m_pViewModel = ReadAndAllocStringValue( pSub, "Viewmodel", pFilename ); pInfo->m_pPlayerModel = ReadAndAllocStringValue( pSub, "Playermodel", pFilename ); pInfo->m_iDisplayPriority = pSub->GetInt( "DisplayPriority", 0 ); pInfo->m_pHudStatusIcon = ReadAndAllocStringValue( pSub, "HudStatusIcon", pFilename ); pInfo->m_bVisibleInWeaponSelection = ( pSub->GetInt( "VisibleInWeaponSelection", 1 ) > 0 ); pInfo->m_pExplodeSound = ReadAndAllocStringValue( pSub, "ExplodeSound", pFilename ); pInfo->m_pExplosionParticleEffect = ReadAndAllocStringValue( pSub, "ExplodeEffect", pFilename ); pInfo->m_bAutoSwitchTo = ( pSub->GetInt( "autoswitchto", 0 ) > 0 ); pInfo->m_iMetalToDropInGibs = pSub->GetInt( "MetalToDropInGibs", 0 ); } pValues->deleteThis(); }
void LoadObjectInfos( IBaseFileSystem *pFileSystem ) { const char *pFilename = "scripts/objects.txt"; // Make sure this stuff hasn't already been loaded. Assert( !AreObjectInfosLoaded() ); KeyValues *pValues = new KeyValues( "Object descriptions" ); if ( !pValues->LoadFromFile( pFileSystem, pFilename, "GAME" ) ) { Error( "Can't open %s for object info.", pFilename ); pValues->deleteThis(); return; } // Now read each class's information in. for ( int iObj=0; iObj < ARRAYSIZE( g_ObjectInfos ); iObj++ ) { CObjectInfo *pInfo = &g_ObjectInfos[iObj]; KeyValues *pSub = pValues->FindKey( pInfo->m_pObjectName ); if ( !pSub ) { Error( "Missing section '%s' from %s.", pInfo->m_pObjectName, pFilename ); pValues->deleteThis(); return; } // Read all the info in. if ( (pInfo->m_flBuildTime = pSub->GetFloat( "BuildTime", -999 )) == -999 || (pInfo->m_nMaxObjects = pSub->GetInt( "MaxObjects", -999 )) == -999 || (pInfo->m_Cost = pSub->GetInt( "Cost", -999 )) == -999 || (pInfo->m_CostMultiplierPerInstance = pSub->GetFloat( "CostMultiplier", -999 )) == -999 || (pInfo->m_UpgradeCost = pSub->GetInt( "UpgradeCost", -999 )) == -999 || (pInfo->m_flUpgradeDuration = pSub->GetFloat( "UpgradeDuration", -999)) == -999 || (pInfo->m_MaxUpgradeLevel = pSub->GetInt( "MaxUpgradeLevel", -999 )) == -999 || (pInfo->m_SelectionSlot = pSub->GetInt( "SelectionSlot", -999 )) == -999 || (pInfo->m_BuildCount = pSub->GetInt( "BuildCount", -999 )) == -999 || (pInfo->m_SelectionPosition = pSub->GetInt( "SelectionPosition", -999 )) == -999 ) { Error( "Missing data for object '%s' in %s.", pInfo->m_pObjectName, pFilename ); pValues->deleteThis(); return; } pInfo->m_pClassName = ReadAndAllocStringValue( pSub, "ClassName", pFilename ); pInfo->m_pStatusName = ReadAndAllocStringValue( pSub, "StatusName", pFilename ); pInfo->m_pBuilderWeaponName = ReadAndAllocStringValue( pSub, "BuilderWeaponName", pFilename ); pInfo->m_pBuilderPlacementString = ReadAndAllocStringValue( pSub, "BuilderPlacementString", pFilename ); pInfo->m_bSolidToPlayerMovement = pSub->GetInt( "SolidToPlayerMovement", 0 ) ? true : false; pInfo->m_pIconActive = ReadAndAllocStringValue( pSub, "IconActive", pFilename ); pInfo->m_pIconInactive = ReadAndAllocStringValue( pSub, "IconInactive", pFilename ); pInfo->m_pIconMenu = ReadAndAllocStringValue( pSub, "IconMenu", pFilename ); pInfo->m_bUseItemInfo = pSub->GetInt( "UseItemInfo", 0 ) ? true : false; pInfo->m_pViewModel = ReadAndAllocStringValue( pSub, "Viewmodel", pFilename ); pInfo->m_pPlayerModel = ReadAndAllocStringValue( pSub, "Playermodel", pFilename ); pInfo->m_iDisplayPriority = pSub->GetInt( "DisplayPriority", 0 ); pInfo->m_pHudStatusIcon = ReadAndAllocStringValue( pSub, "HudStatusIcon", pFilename ); pInfo->m_bVisibleInWeaponSelection = ( pSub->GetInt( "VisibleInWeaponSelection", 1 ) > 0 ); pInfo->m_pExplodeSound = ReadAndAllocStringValue( pSub, "ExplodeSound", pFilename ); pInfo->m_pUpgradeSound = ReadAndAllocStringValue( pSub, "UpgradeSound", pFilename ); pInfo->m_pExplosionParticleEffect = ReadAndAllocStringValue( pSub, "ExplodeEffect", pFilename ); pInfo->m_bAutoSwitchTo = ( pSub->GetInt( "autoswitchto", 0 ) > 0 ); pInfo->m_iMetalToDropInGibs = pSub->GetInt( "MetalToDropInGibs", 0 ); pInfo->m_bRequiresOwnBuilder = pSub->GetBool( "RequiresOwnBuilder", 0 ); // PistonMiner: Added Object Mode key KeyValues *pAltModes = pSub->FindKey("AltModes"); if (pAltModes) { for (int i = 0; i < 4; ++i) // load at most 4 object modes { char altModeBuffer[256]; // Max size of 0x100 V_snprintf(altModeBuffer, ARRAYSIZE(altModeBuffer), "AltMode%d", i); KeyValues *pCurAltMode = pAltModes->FindKey(altModeBuffer); if (!pCurAltMode) break; // Save logic here pInfo->m_AltModes.AddToTail(ReadAndAllocStringValue( pCurAltMode, "StatusName", pFilename )); pInfo->m_AltModes.AddToTail(ReadAndAllocStringValue( pCurAltMode, "ModeName", pFilename )); pInfo->m_AltModes.AddToTail(ReadAndAllocStringValue( pCurAltMode, "IconMenu", pFilename )); } } } pValues->deleteThis(); }