// int thePlayerIndex, string string (in titles.txt), returns success static int sendMessage(lua_State* inState) { bool theSuccess = false; int theNumArgs = lua_gettop(inState); if(theNumArgs == 2) { int thePlayerIndex = lua_tonumber(inState, 1); const char* theCString = lua_tostring(inState, 2); if(theCString) { char theCharArray[kMaxStrLen]; strcpy(theCharArray, theCString); CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(thePlayerIndex)); if(theEntity) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer) { thePlayer->SendMessage(theCString, TOOLTIP); theSuccess = true; } } } } lua_pushnumber(inState, theSuccess); return 1; }
void AvHBasePlayerWeapon::UpdateInventoryEnabledState(int inNumActiveHives) { // Process here int theEnabledState = 1; ItemInfo theItemInfo; if(this->GetItemInfo(&theItemInfo) != 0) { int theWeaponFlags = theItemInfo.iFlags; AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); ASSERT(thePlayer); // If we don't have the hives required, or we're ensnared if (/*thePlayer->GetIsTemporarilyInvulnerable() ||*/ !thePlayer->GetIsAbleToAct() || ((inNumActiveHives < 1) && (theWeaponFlags & ONE_HIVE_REQUIRED)) || ((inNumActiveHives < 2) && (theWeaponFlags & TWO_HIVES_REQUIRED)) || ((inNumActiveHives < 3) && (theWeaponFlags & THREE_HIVES_REQUIRED)) || (this->GetResourceCost() > thePlayer->GetResources(false)) ) { // Disable it theEnabledState = 0; } else { int a = 0; } } // puzl: 497 save the state for when we send the CurWeapon message this->m_iEnabled = theEnabledState; }
bool AvHTurret::GetIsValidTarget(CBaseEntity* inEntity) const { bool theTargetIsValid = false; if((inEntity->pev->team != this->pev->team) && (inEntity->pev->team != 0) && (inEntity->pev->takedamage)) { float theDistanceToCurrentEnemy = AvHSUEyeToBodyXYDistance(this->pev, inEntity); if(theDistanceToCurrentEnemy <= this->GetXYRange()) { // Players are targettable when AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(inEntity); if(!thePlayer || !thePlayer->GetIsCloaked() || !thePlayer->GetIsBeingDigested()) //added digestion - elven { // TODO: Check to be sure enemy is still visible theTargetIsValid = true; } else { AvHCloakable* theCloakable = dynamic_cast<AvHCloakable*>(inEntity); if(!theCloakable || (theCloakable->GetOpacity() > 0.0f)) { theTargetIsValid = true; } } } } return theTargetIsValid; }
// This function takes a lot of CPU, so make sure it's not called often! Don't call this function directly, use UpdateEnemy instead whenever possible. CBaseEntity* AvHTurret::FindBestEnemy() { PROFILE_START() CBaseEntity* theEntityList[100]; int theMaxRange = this->GetXYRange(); Vector delta = Vector(theMaxRange, theMaxRange, theMaxRange); CBaseEntity* theCurrentEntity = NULL; CBaseEntity* theBestPlayer = NULL; CBaseEntity* theBestStructure = NULL; float theCurrentEntityRange = 100000; // Find only monsters/clients in box, NOT limited to PVS int theCount = UTIL_EntitiesInBox(theEntityList, 100, this->pev->origin - delta, this->pev->origin + delta, FL_CLIENT | FL_MONSTER); for(int i = 0; i < theCount; i++ ) { theCurrentEntity = theEntityList[i]; if((theCurrentEntity != this) && theCurrentEntity->IsAlive()) { // the looker will want to consider this entity // don't check anything else about an entity that can't be seen, or an entity that you don't care about. if(this->IRelationship(theCurrentEntity ) != R_NO && FInViewCone(theCurrentEntity) && !FBitSet(theCurrentEntity->pev->flags, FL_NOTARGET)) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theCurrentEntity); if(!thePlayer || thePlayer->GetCanBeAffectedByEnemies()) { if(this->GetIsValidTarget(theCurrentEntity)) { // Find nearest enemy float theRangeToTarget = VectorDistance2D(this->pev->origin, theCurrentEntity->pev->origin); if(theRangeToTarget < theCurrentEntityRange) { // FVisible is expensive, so defer until necessary if(!this->GetRequiresLOS() || FVisible(theCurrentEntity)) { theCurrentEntityRange = theRangeToTarget; if ( thePlayer ) { theBestPlayer = theCurrentEntity; } else { theBestStructure = theCurrentEntity; } } } } } } } } PROFILE_END(kAvHTurretFindBestEnemy); return (theBestPlayer != NULL ) ? theBestPlayer : theBestStructure; }
void AvHBaseBuildable::Killed(entvars_t* pevAttacker, int iGib) { bool theInReset = GetGameRules()->GetIsGameInReset(); AvHBaseBuildable::SetHasBeenKilled(); GetGameRules()->RemoveEntityUnderAttack( this->entindex() ); this->mKilled = true; this->mInternalSetConstructionComplete = false; this->mTimeOfLastAutoHeal = -1; if (!theInReset) { // : 980 // Less smoke for recycled buildings this->TriggerDeathAudioVisuals(iGib == GIB_RECYCLED); if(!this->GetIsOrganic()) { // More sparks for recycled buildings int numSparks = ( iGib == GIB_RECYCLED ) ? 7 : 3; for ( int i=0; i < numSparks; i++ ) { Vector vecSrc = Vector( (float)RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ), (float)RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ), (float)0 ); vecSrc = vecSrc + Vector( (float)0, (float)0, (float)RANDOM_FLOAT( pev->origin.z, pev->absmax.z ) ); UTIL_Sparks(vecSrc); } } // : } this->TriggerRemoveTech(); AvHSURemoveEntityFromHotgroupsAndSelection(this->entindex()); if(pevAttacker) { const char* theClassName = STRING(this->pev->classname); AvHPlayer* inPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(ENT(pevAttacker))); if(inPlayer && theClassName) { inPlayer->LogPlayerAction("structure_destroyed", theClassName); GetGameRules()->RewardPlayerForKill(inPlayer, this); } } if(this->GetIsPersistent()) { this->SetInactive(); } else { CBaseAnimating::Killed(pevAttacker, iGib); } }
void AvHMovementChamber::EnergyAliensThink() { // Don't teleport until it's "warmed up" SetUse(&AvHMovementChamber::TeleportUse); // Loop through all players CBaseEntity* theBaseEntity = NULL; int theNumEntsProcessed = 0; while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kMovementChamberEnergyRange))) != NULL) && (theNumEntsProcessed < BALANCE_VAR(kAlienChamberMaxPlayers))) { if(theBaseEntity->pev->team == this->pev->team) { float theEnergizeAmount = BALANCE_VAR(kMovementChamberEnergyAmount); AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theBaseEntity); AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity); if(thePlayer && thePlayer->IsAlive()) { if(thePlayer->Energize(theEnergizeAmount)) { theNumEntsProcessed++; } } // Energize alien buildables // else if(theBuildable) // { // if(theBuildable->Energize(theEnergizeAmount)) // { // theNumEntsProcessed++; // } // } } } // Play an animation (spin the arms if energizing) int theIdle = this->GetIdle2Animation(); // Play sound if(theNumEntsProcessed > 0) { EMIT_SOUND(this->edict(), CHAN_AUTO, kAlienEnergySound, 1.0f, ATTN_NORM); theIdle = this->GetIdle1Animation(); } this->PlayAnimationAtIndex(theIdle); // Set next think this->pev->nextthink = gpGlobals->time + BALANCE_VAR(kMovementChamberThinkInterval); }
void AvHLeap::FireProjectiles(void) { #ifdef AVH_SERVER AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); if(thePlayer) { thePlayer->TriggerUncloak(); } #endif #ifdef AVH_CLIENT if(g_runfuncs) { //IN_Attack2Down(); //CBasePlayerWeapon::SendWeaponAnim(3); gHUD.SetAlienAbility(this->GetAbilityImpulse()); } #endif }
void AvHDefenseChamber::RegenAliensThink() { // Loop through all players CBaseEntity* theBaseEntity = NULL; int theNumEntsHealed = 0; while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kDefensiveChamberHealRange))) != NULL) && (theNumEntsHealed < BALANCE_VAR(kAlienChamberMaxPlayers))) { if(theBaseEntity->pev->team == this->pev->team) { AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theBaseEntity); AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity); float thePercent=BALANCE_VAR(kDefensiveChamberRegenPercent)/100.0f; float amount=BALANCE_VAR(kDefensiveChamberRegenAmount) + (theBaseEntity->pev->max_health*thePercent); if(thePlayer && thePlayer->IsAlive()) { if(thePlayer->Heal(amount, true, true)) { theNumEntsHealed++; } } else if(theBuildable && theBuildable->GetIsBuilt() && (theBuildable != this)) { if(theBuildable->Regenerate(amount, true, true)) { theNumEntsHealed++; } } } } // Set next think this->pev->nextthink = gpGlobals->time + BALANCE_VAR(kDefenseChamberThinkInterval); // Play a random idle animation int theIdle = this->GetIdle1Animation(); if(RANDOM_LONG(0, 1)) { theIdle = this->GetIdle2Animation(); } this->PlayAnimationAtIndex(theIdle); }
void AvHHive::ProcessHealing() { // Regenerate nearby friendly aliens CBaseEntity* theEntity = NULL; const int theHiveHealRadius = BALANCE_VAR(kHiveHealRadius); while((theEntity = UTIL_FindEntityInSphere(theEntity, this->pev->origin, theHiveHealRadius)) != NULL) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer) { if(thePlayer->GetIsRelevant() && (thePlayer->GetTeam() == this->GetTeamNumber()) && !thePlayer->GetIsBeingDigested()) { // Hive heals percentage of player health float theRegenPercentage = BALANCE_VAR(kHiveRegenerationPercentage); int theMaxHealth = AvHPlayerUpgrade::GetMaxHealth(thePlayer->pev->iuser4, (AvHUser3)thePlayer->pev->iuser3, thePlayer->GetExperienceLevel()); float theRegenAmount = (theRegenPercentage*theMaxHealth); thePlayer->Heal(theRegenAmount, true); } } } // Regenerate self bool theDidHeal = false; // If we aren't at full health, heal health if(this->pev->health < this->mMaxHitPoints) { float theHiveRegenAmount = BALANCE_VAR(kHiveRegenerationAmount); float theCombatModeScalar = /*GetGameRules()->GetIsCombatMode() ? (1.0f/BALANCE_VAR(kCombatModeTimeScalar)) :*/ 1.0f; this->pev->health = min((float)this->mMaxHitPoints, this->pev->health + theHiveRegenAmount*theCombatModeScalar); theDidHeal = true; } // Play regen event if(theDidHeal) { // Play regeneration event PLAYBACK_EVENT_FULL(0, this->edict(), gRegenerationEventID, 0, this->pev->origin, (float *)&g_vecZero, 1.0f, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 ); } }
void AvHGamerules::AwardExperience(AvHPlayer* inPlayer, int inTargetLevel, bool inAwardFriendliesInRange) { PlayerListType thePlayerList; thePlayerList.push_back(inPlayer); if(inAwardFriendliesInRange) { // Award experience to player, and any other players nearby int theExperienceRadius = BALANCE_IVAR(kCombatFriendlyNearbyRange); // Make list of players to split it between. If a player is at full experience, extra is wasted. CBaseEntity* theEntity = NULL; while ((theEntity = UTIL_FindEntityInSphere(theEntity, inPlayer->pev->origin, theExperienceRadius)) != NULL) { const char* theClassName = STRING(theEntity->pev->classname); if(!AvHSUGetIsExternalClassName(theClassName)) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer && (thePlayer != inPlayer) && (thePlayer->pev->team == inPlayer->pev->team) && thePlayer->GetIsRelevant() && !thePlayer->GetIsBeingDigested()) { thePlayerList.push_back(thePlayer); } } } } ASSERT(thePlayerList.size() > 0); float theExperienceFactor = GetGameRules()->GetIsIronMan() ? BALANCE_FVAR(kCombatIronManExperienceScalar) : 1.0f; int theExperienceToAward = BALANCE_IVAR(kCombatExperienceBaseAward) + inTargetLevel*BALANCE_IVAR(kCombatExperienceLevelAward); float theExperienceForEach = (theExperienceToAward/(float)thePlayerList.size() + BALANCE_IVAR(kCombatExperienceCrowdAward))*theExperienceFactor; for(PlayerListType::iterator thePlayerIter = thePlayerList.begin(); thePlayerIter != thePlayerList.end(); thePlayerIter++) { AvHPlayer* theCurrentPlayer = (*thePlayerIter); theCurrentPlayer->SetExperience(theCurrentPlayer->GetExperience() + theExperienceForEach); } }
void AvHHive::DonateUse(CBaseEntity* inActivator, CBaseEntity* inCaller, USE_TYPE inUseType, float inValue) { // Player is trying to donate his resources to the pool if(this->GetIsActive()) { AvHPlayer* inActivatingPlayer = dynamic_cast<AvHPlayer*>(inActivator); if(inActivatingPlayer && (inActivator->pev->team == this->pev->team)) { // Take some resources, give some resources const float kResourcesToDonatePerUse = .4f; float theResourcesToGive = min(inActivatingPlayer->GetResources(), kResourcesToDonatePerUse); if(theResourcesToGive > 0.0f) { AvHTeam* theTeam = inActivatingPlayer->GetTeamPointer(); if(theTeam) { inActivatingPlayer->SetResources(inActivatingPlayer->GetResources() - theResourcesToGive); theTeam->SetTeamResources(theTeam->GetTeamResources() + theResourcesToGive); if(g_engfuncs.pfnRandomLong(0, 20) == 0) { PLAYBACK_EVENT_FULL(0, this->edict(), gRegenerationEventID, 0, this->pev->origin, (float *)&g_vecZero, 1.0f, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 ); // Just say "resources donated" inActivatingPlayer->PlaybackNumericalEvent(kNumericalInfoResourcesDonatedEvent, 0); } } } } } }
int BabblerProjectile::IRelationship(CBaseEntity* inTarget) { int theRelationship = R_NO; // Don't attack cloaked players AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(inTarget); if(thePlayer && thePlayer->GetIsCloaked()) { theRelationship = R_NO; } else { // Attack all monsters that aren't on our team CBaseMonster* theMonsterPointer = dynamic_cast<CBaseMonster*>(inTarget); if(theMonsterPointer && (theMonsterPointer->pev->team != this->pev->team)) { theRelationship = R_DL; } else { // Look at own team vs. incoming team AvHTeamNumber inTeam = (AvHTeamNumber)inTarget->pev->team; if(inTeam != TEAM_IND) { if(inTeam == this->pev->team) { theRelationship = R_AL; } else { // Don't keep switching targets constantly theRelationship = R_DL; } } } } return theRelationship; }
void AvHBasePlayerWeapon::DeductCostForShot(void) { this->m_iClip--; // On a successful attack, decloak the player if needed #ifdef AVH_SERVER AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); if(thePlayer) { thePlayer->TriggerUncloak(); } int theResourceCost = this->GetResourceCost(); if(theResourceCost > 0) { float theNewResources = (thePlayer->GetResources(false) - theResourceCost); theNewResources = max(theNewResources, 0.0f); thePlayer->SetResources(theNewResources); } #endif }
void AvHBlinkGun::FireProjectiles(void) { #ifdef AVH_CLIENT if(g_runfuncs) { gHUD.SetAlienAbility(this->GetAbilityImpulse()); } #endif #ifdef AVH_SERVER AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); if(thePlayer) { thePlayer->TriggerUncloak(); } #endif // if(this->mTimeOfNextBlinkEvent <= 0) // { // const float kEventDelay = 2.0f; // this->PlaybackEvent(this->mBlinkSuccessEvent, this->GetShootAnimation()); // this->mTimeOfNextBlinkEvent = UTIL_WeaponTimeBase() + kEventDelay; // } }
void AvHParalysisGun::FireProjectiles(void) { #ifdef AVH_SERVER UTIL_MakeVectors(this->m_pPlayer->pev->v_angle); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = this->m_pPlayer->GetGunPosition( ) + vecAiming; Vector vecEnd = vecSrc + vecAiming*kParalysisRange; const float kParalysisTime = 6; // Treat damage upgrade as modifier onto paralysis //int theTracerFreq; //float theDamageMultiplier; //AvHPlayerUpgrade::GetWeaponUpgrade(this->m_pPlayer->pev->iuser4, &theDamageMultiplier, &theTracerFreq); // Perform trace to hit victim TraceResult tr; UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, dont_ignore_glass, this->m_pPlayer->edict(), &tr); CBaseEntity* theEntityHit = CBaseEntity::Instance(tr.pHit); if(theEntityHit) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntityHit); if(thePlayer) { // Check teams (hit friendly in tourny mode) if((thePlayer->pev->team != this->m_pPlayer->pev->team) || (GetGameRules()->GetIsTournamentMode())) { thePlayer->SetIsParalyzed(true, kParalysisTime/**theDamageMultiplier*/); // Play hit event PLAYBACK_EVENT_FULL(0, thePlayer->edict(), gParalysisStartEventID, 0, thePlayer->pev->origin, (float *)&g_vecZero, 0.0, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0); } } } #endif }
void AvHEggLayer::FireProjectiles(void) { #ifdef AVH_SERVER // Make sure we have enough points to shoot this thing AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); ASSERT(thePlayer); if(thePlayer->GetResources() > kEggLayerPointCost) { // Now check to make sure the space is big enough to hold the egg UTIL_MakeVectors(this->m_pPlayer->pev->v_angle); //Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = this->m_pPlayer->GetGunPosition();// + vecAiming; if(AvHSUIsAreaFree(vecSrc, kEggRadius, this->m_pPlayer)) { // Decrement kEggLayerPointCost points thePlayer->SetResources(thePlayer->GetResources() - kEggLayerPointCost); AvHEgg* theEgg = GetClassPtr((AvHEgg*)NULL ); theEgg->Spawn(); theEgg->pev->angles.x = 0; theEgg->pev->angles.z = 0; //theEgg->pev->velocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100; UTIL_SetOrigin(theEgg->pev, vecSrc); // Set owner //theEgg->pev->owner = ENT(this->m_pPlayer->pev); // Set egg's team theEgg->pev->team = this->m_pPlayer->pev->team; } } #endif }
void AvHHive::TeleportUse(CBaseEntity* inActivator, CBaseEntity* inCaller, USE_TYPE inUseType, float inValue) { if ( this->GetIsSpawning() ) { this->SetEmergencyUse(); return; } const float kHiveScanInterval = 1.0f; AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(inActivator); if(thePlayer && (thePlayer->pev->team == this->pev->team) && (thePlayer->GetUser3() != AVH_USER3_ALIEN_EMBRYO) && thePlayer->GetCanUseHive() ) { vector<int> theHives; vector<int> theHivesUnderAttack; if((this->mLastTimeScannedHives == -1) || (gpGlobals->time > (this->mLastTimeScannedHives + kHiveScanInterval))) { this->mTeleportHiveIndex = -1; float theFarthestDistance = 0.0f; //sqrt((kMaxMapDimension*2)*(kMaxMapDimension*2)); // Loop through the hives for this team, look for the farthest one (hives under attack take precedence) FOR_ALL_ENTITIES(kesTeamHive, AvHHive*) if((theEntity->pev->team == this->pev->team) && theEntity != this ) { bool theHiveIsUnderAttack = GetGameRules()->GetIsEntityUnderAttack(theEntity->entindex()); // allow teleport to any built hive, or unbuilt hives under attack. if(!theEntity->GetIsSpawning() || ( theEntity->GetIsSpawning() && ( theHiveIsUnderAttack || theEntity->GetEmergencyUse()) ) ) { theHives.push_back(theEntity->entindex()); if ( theHiveIsUnderAttack ) theHivesUnderAttack.push_back(theEntity->entindex()); } } END_FOR_ALL_ENTITIES(kesTeamHive) this->mLastTimeScannedHives = gpGlobals->time; }
int AvHBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) { // Can we predict weapon pick-ups? I bet we can. int theAddedToPlayer = 0; #ifdef AVH_SERVER AvHPlayer* inPlayer = dynamic_cast<AvHPlayer*>(pPlayer); ASSERT(inPlayer != NULL); if(this->GetAllowedForUser3(inPlayer->GetUser3())) { // Make sure player doesn't have this weapon already if(!pPlayer->HasItem(this)) { // If weapon was placed by mapper if(this->GetIsPersistent()) { // Create a new weapon and give it to the player pPlayer->GiveNamedItem(STRING(this->pev->classname)); this->DestroyItem(); } else { theAddedToPlayer = CBasePlayerWeapon::AddToPlayer(pPlayer); if(theAddedToPlayer) { // Make sure it's not set for expiration SetThink(NULL); } } } } #endif return theAddedToPlayer; }
void AvHCocoon::FireProjectiles(void) { #ifdef AVH_SERVER // Make sure we have enough points to shoot this thing AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); ASSERT(thePlayer); vec3_t theNewPoint = this->pev->origin; TraceResult tr; // Do a traceline to see who to cocoon UTIL_MakeVectors(this->pev->angles); Vector theForwardDir = (gpGlobals->v_forward + gpGlobals->v_right + gpGlobals->v_up); UTIL_TraceLine(this->pev->origin + this->pev->view_ofs, this->pev->origin + this->pev->view_ofs + theForwardDir*128, dont_ignore_monsters, ENT(this->m_pPlayer->pev), &tr); if(tr.flFraction != 1.0) { CBaseEntity* theEntity = CBaseEntity::Instance(tr.pHit); if(theEntity) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer /*&& (thePlayer->pev->team != this->pev->team)*/ && (thePlayer->GetRole() != ROLE_GESTATING) && (thePlayer->GetRole() != ROLE_COCOONED)) { GetGameRules()->MarkDramaticEvent(kCocoonPriority, thePlayer, this->m_pPlayer); // Play successful cocoon sound! EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, kCocoonSound2, 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-3,3) ); // Yes! thePlayer->StartCocooning(); } } } #endif }
// int inEntityID, string itemName static int giveNamedItem(lua_State* inState) { // Get entity index int theIndex = lua_tonumber(inState, 1); if(theIndex > 0) { // Look it up CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex)); if(theEntity) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer) { const char* theItemName = lua_tostring(inState, 2); if(theItemName != NULL) { thePlayer->GiveNamedItem(theItemName); } } } } return 0; }
static int runClientScript(lua_State* inState) { // Get entity index int theIndex = lua_tonumber(inState, 1); if(theIndex > 0) { // Look it up CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex)); if(theEntity) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity); if(thePlayer) { const char* theScript = lua_tostring(inState, 2); if(theScript != NULL) { thePlayer->RunClientScript(theScript); } } } } return 0; }
bool AvHOrder::Update() { bool theOrderJustCompleted = false; ASSERT(this->GetReceiver() != -1 ); if(this->GetOrderActive()) { bool theOrderIsComplete = false; AvHPlayer* thePlayer = NULL; vec3_t theOrderLocation; this->GetLocation(theOrderLocation); EntityInfo theReceiver = this->GetReceiver(); float theDistance; const float kMoveToDistance = 90; const float kPickupDistance = 20; CBaseEntity* theTargetEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(this->mTargetIndex)); AvHBaseBuildable* theTargetBuildable = dynamic_cast<AvHBaseBuildable*>(theTargetEntity); AvHPlayer* theTargetPlayer = dynamic_cast<AvHPlayer*>(theTargetEntity); AvHWeldable* theWeldable = dynamic_cast<AvHWeldable*>(theTargetEntity); switch(this->mOrderType) { case ORDERTYPE_UNDEFINED: default: break; case ORDERTYPEL_MOVE: // set true if all receivers are within a certain distance of move to order theTargetPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theReceiver))); if(theTargetPlayer) { theOrderIsComplete = true; theDistance = VectorDistance(theTargetPlayer->pev->origin, theOrderLocation); if(!theTargetPlayer->GetIsRelevant() || (theDistance > kMoveToDistance)) { theOrderIsComplete = false; } } if(theOrderIsComplete) { this->mOrderStatus = kOrderStatusComplete; } break; case ORDERTYPET_GET: // set true if all receivers are within a certain distance of item theTargetPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theReceiver))); if(theTargetPlayer) { // If one of the players in the group is near enough to pick it up theDistance = VectorDistance(theTargetPlayer->pev->origin, theOrderLocation); if(theTargetPlayer->GetIsRelevant() && (theDistance < kPickupDistance)) { theOrderIsComplete = true; } } // If the item is gone, the order is done if(!theTargetEntity) { this->mOrderStatus = kOrderStatusCancelled; } break; case ORDERTYPET_ATTACK: // set true if target is dead or not relevant if(!theTargetEntity || (theTargetPlayer && !theTargetPlayer->GetIsRelevant())) { this->mOrderStatus = kOrderStatusCancelled; theOrderIsComplete = true; } else if(theTargetEntity && !theTargetEntity->IsAlive()) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } break; case ORDERTYPET_BUILD: if(!theTargetEntity || !theTargetEntity->IsAlive()) { this->mOrderStatus = kOrderStatusCancelled; theOrderIsComplete = true; } else if(theTargetBuildable && theTargetBuildable->GetIsBuilt()) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } else { if(theTargetEntity) { bool theIsBuilding; bool theIsResearching; float thePercentage; AvHSHUGetBuildResearchState(theTargetEntity->pev->iuser3, theTargetEntity->pev->iuser4, theTargetEntity->pev->fuser1, theIsBuilding, theIsResearching, thePercentage); if(!theIsBuilding && (thePercentage == 1.0f)) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } } } break; case ORDERTYPET_GUARD: theOrderIsComplete = false; if(!theTargetEntity ||!theTargetEntity->IsAlive()) { this->mOrderStatus = kOrderStatusCancelled; theOrderIsComplete = true; } break; case ORDERTYPET_WELD: //ALERT(at_console, "Checking weldables "); // set true when target is fully welded if(!theTargetEntity ||!theTargetEntity->IsAlive()) { this->mOrderStatus = kOrderStatusCancelled; theOrderIsComplete = true; } if(theWeldable && theWeldable->GetIsWelded()) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } else if ( !theWeldable ) { if ( theTargetEntity->pev->iuser3 == AVH_USER3_MARINE_PLAYER ) { // Players are welded if they have full armour if ( theTargetEntity->pev->armorvalue == AvHPlayerUpgrade::GetMaxArmorLevel(theTargetEntity->pev->iuser4, (AvHUser3)theTargetEntity->pev->iuser3)) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } } else { // Structures are welded if they have full health if ( theTargetEntity->pev->health == theTargetEntity->pev->max_health ) { this->mOrderStatus = kOrderStatusComplete; theOrderIsComplete = true; } } } break; } if(theOrderIsComplete) { this->SetOrderCompleted(); theOrderJustCompleted = true; } } return theOrderJustCompleted; }
int AvHBaseBuildable::TakeDamage(entvars_t* inInflictor, entvars_t* inAttacker, float inDamage, int inBitsDamageType) { if(GetGameRules()->GetIsCheatEnabled(kcHighDamage)) { inDamage *= 50; } if(!inAttacker) { inAttacker = inInflictor; } if(!inInflictor) { inInflictor = inAttacker; } // Take into account handicap AvHTeam* theTeam = GetGameRules()->GetTeam(AvHTeamNumber(inAttacker->team)); if(theTeam) { float theHandicap = theTeam->GetHandicap(); inDamage *= theHandicap; } CBaseEntity* inInflictorEntity = CBaseEntity::Instance(inInflictor); float theDamage = 0; // Take half damage from piercing if(inBitsDamageType & NS_DMG_PIERCING) { inDamage /= 2.0f; } // Take double damage from blast if(inBitsDamageType & NS_DMG_BLAST) { inDamage *= 2.0f; } if((inBitsDamageType & NS_DMG_ORGANIC) && !this->GetIsOrganic()) { inDamage = 0.0f; } theDamage = AvHPlayerUpgrade::CalculateDamageLessArmor((AvHUser3)this->pev->iuser3, this->pev->iuser4, inDamage, this->pev->armorvalue, inBitsDamageType, GetGameRules()->GetNumActiveHives((AvHTeamNumber)this->pev->team)); if(theDamage > 0) { int theAnimationIndex = this->GetTakeDamageAnimation(); if(theAnimationIndex >= 0) { this->PlayAnimationAtIndex(theAnimationIndex, true); } // Award experience to attacker CBaseEntity* theEntity = CBaseEntity::Instance(ENT(inAttacker)); AvHPlayer* inAttacker = dynamic_cast<AvHPlayer*>(theEntity); if(inAttacker && (inAttacker->pev->team != this->pev->team)) { inAttacker->AwardExperienceForObjective(theDamage, this->GetMessageID()); } } int theReturnValue = 0; if(theDamage > 0.0f) { if(this->GetTriggerAlertOnDamage()) GetGameRules()->TriggerAlert((AvHTeamNumber)this->pev->team, ALERT_UNDER_ATTACK, this->entindex()); theDamage = CBaseAnimating::TakeDamage(inInflictor, inAttacker, inDamage, inBitsDamageType); bool theDrawDamage = (CVAR_GET_FLOAT(kvDrawDamage) > 0); if(theDrawDamage) { Vector theMinSize; Vector theMaxSize; AvHSHUGetSizeForTech(this->GetMessageID(), theMinSize, theMaxSize); Vector theStartPos = this->pev->origin; theStartPos.z += theMaxSize.z; // Draw for everyone (team is 0 after inDamage parameter) AvHSUPlayNumericEvent(-inDamage, this->edict(), theStartPos, 0, kNumericalInfoHealthEvent, 0); } } // Structures uncloak when damaged this->Uncloak(); this->HealthChanged(); return theDamage; }
void AvHEntityHierarchy::BuildForSpec(BaseEntityListType& inBaseEntityList) { this->Clear(); // Loop through all entities in the world for(BaseEntityListType::iterator theIter = inBaseEntityList.begin(); theIter != inBaseEntityList.end(); theIter++) { CBaseEntity* theBaseEntity = *theIter; int theEntityIndex = theBaseEntity->entindex(); bool theEntityIsVisible = false; if ( theBaseEntity->pev->team == TEAM_ONE || theBaseEntity->pev->team == TEAM_TWO || theBaseEntity->pev->team == TEAM_THREE || theBaseEntity->pev->team == TEAM_FOUR ) theEntityIsVisible=true; bool theEntityIsUnderAttack = GetGameRules()->GetIsEntityUnderAttack(theEntityIndex); // Don't send ammo, health, weapons, or scans bool theIsTransient = ((AvHUser3)(theBaseEntity->pev->iuser3) == AVH_USER3_MARINEITEM) || (theBaseEntity->pev->classname == MAKE_STRING(kwsScan)); MapEntity mapEntity; mapEntity.mX = theBaseEntity->pev->origin.x; mapEntity.mY = theBaseEntity->pev->origin.y; mapEntity.mUser3 = (AvHUser3)(theBaseEntity->pev->iuser3); mapEntity.mAngle = theBaseEntity->pev->angles[1]; mapEntity.mTeam = (AvHTeamNumber)(theBaseEntity->pev->team); mapEntity.mSquadNumber = 0; mapEntity.mUnderAttack = theEntityIsUnderAttack ? 1 : 0; bool sendEntity = false; if (mapEntity.mUser3 == AVH_USER3_HIVE) { if (!theEntityIsVisible) { mapEntity.mTeam = TEAM_IND; } sendEntity = true; } else if (mapEntity.mUser3 == AVH_USER3_WELD) { vec3_t theEntityOrigin = AvHSHUGetRealLocation(theBaseEntity->pev->origin, theBaseEntity->pev->mins, theBaseEntity->pev->maxs); mapEntity.mX = theEntityOrigin.x; mapEntity.mY = theEntityOrigin.y; sendEntity = true; } else if (mapEntity.mUser3 == AVH_USER3_FUNC_RESOURCE) { sendEntity = true; } else if (theEntityIsVisible && !(theBaseEntity->pev->effects & EF_NODRAW) && !theIsTransient) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity); if (thePlayer) { ASSERT(theEntityIndex > 0); ASSERT(theEntityIndex <= 32); mapEntity.mSquadNumber = GetHotkeyGroupContainingPlayer(thePlayer) + 1; if ((thePlayer->GetPlayMode() == PLAYMODE_PLAYING) && !thePlayer->GetIsSpectator()) { sendEntity = true; // If the player has the heavy armor upgrade switch the // user3 to something that will let us reconstruct that later. if (thePlayer->pev->iuser3 == AVH_USER3_MARINE_PLAYER && GetHasUpgrade(thePlayer->pev->iuser4, MASK_UPGRADE_13)) { mapEntity.mUser3 = AVH_USER3_HEAVY; } } } else { if (mapEntity.mUser3 != AVH_USER3_HEAVY) { sendEntity = true; } } } if (sendEntity) { //const AvHMapExtents& theMapExtents = GetGameRules()->GetMapExtents(); // commented this out here, commented out corresponding shift in AvHOverviewMap::Draw at line 771 // float theMinMapX = theMapExtents.GetMinMapX(); // float theMinMapY = theMapExtents.GetMinMapY(); // mapEntity.mX -= theMinMapX; // mapEntity.mY -= theMinMapY; mEntityList[theEntityIndex] = mapEntity; // debug the entity hierarchy message size // if ( mapEntity.mUser3 == AVH_USER3_COMMANDER_STATION ) { // for (int i=0; i<200; i++ ) { // mEntityList[100+i] = mapEntity; // } // } } } }
void AvHEntityHierarchy::BuildFromTeam(const AvHTeam* inTeam, BaseEntityListType& inBaseEntityList) { this->Clear(); int mc=0, sc=0, dc=0; if (inTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE || inTeam->GetTeamType() == AVH_CLASS_TYPE_ALIEN) { // Loop through all entities in the world for(BaseEntityListType::iterator theIter = inBaseEntityList.begin(); theIter != inBaseEntityList.end(); theIter++) { CBaseEntity* theBaseEntity = *theIter; int theEntityIndex = theBaseEntity->entindex(); bool theEntityIsVisible = (theBaseEntity->pev->team == (int)(inTeam->GetTeamNumber())) || GetHasUpgrade(theBaseEntity->pev->iuser4, MASK_VIS_SIGHTED); bool theEntityIsDetected = GetHasUpgrade(theBaseEntity->pev->iuser4, MASK_VIS_DETECTED); bool theEntityIsUnderAttack = GetGameRules()->GetIsEntityUnderAttack(theEntityIndex); if ( theEntityIsUnderAttack ) { int a=0; } // Don't send ammo, health, weapons, or scans bool theIsTransient = ((AvHUser3)(theBaseEntity->pev->iuser3) == AVH_USER3_MARINEITEM) || (theBaseEntity->pev->classname == MAKE_STRING(kwsScan)); if ( inTeam->GetTeamType() == AVH_CLASS_TYPE_ALIEN && theBaseEntity->pev->team == (int)(inTeam->GetTeamNumber()) ) { AvHBuildable *theBuildable=dynamic_cast<AvHBuildable *>(theBaseEntity); if ( theBuildable && theBuildable->GetHasBeenBuilt() ) { if ( theBaseEntity->pev->iuser3 == AVH_USER3_MOVEMENT_CHAMBER ) { mc++; } if ( theBaseEntity->pev->iuser3 == AVH_USER3_SENSORY_CHAMBER ) { sc++; } if ( theBaseEntity->pev->iuser3 == AVH_USER3_DEFENSE_CHAMBER ) { dc++; } } } MapEntity mapEntity; mapEntity.mX = theBaseEntity->pev->origin.x; mapEntity.mY = theBaseEntity->pev->origin.y; mapEntity.mUser3 = (AvHUser3)(theBaseEntity->pev->iuser3); // Don't draw detected blips as their real selves if(!theEntityIsVisible && theEntityIsDetected) mapEntity.mUser3 = AVH_USER3_UNKNOWN; mapEntity.mAngle = theBaseEntity->pev->angles[1]; mapEntity.mTeam = (AvHTeamNumber)(theBaseEntity->pev->team); mapEntity.mSquadNumber = 0; mapEntity.mUnderAttack = theEntityIsUnderAttack ? 1 : 0; bool sendEntity = false; if (mapEntity.mUser3 == AVH_USER3_HIVE) { if (!theEntityIsVisible) { mapEntity.mTeam = TEAM_IND; } sendEntity = true; } else if (mapEntity.mUser3 == AVH_USER3_WELD) { vec3_t theEntityOrigin = AvHSHUGetRealLocation(theBaseEntity->pev->origin, theBaseEntity->pev->mins, theBaseEntity->pev->maxs); mapEntity.mX = theEntityOrigin.x; mapEntity.mY = theEntityOrigin.y; sendEntity = true; } else if (mapEntity.mUser3 == AVH_USER3_FUNC_RESOURCE) { sendEntity = true; } else if ((theEntityIsVisible || theEntityIsDetected) && !(theBaseEntity->pev->effects & EF_NODRAW) && !theIsTransient) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity); if (thePlayer) { ASSERT(theEntityIndex > 0); ASSERT(theEntityIndex <= 32); mapEntity.mSquadNumber = GetHotkeyGroupContainingPlayer(thePlayer) + 1; if ((thePlayer->GetPlayMode() == PLAYMODE_PLAYING) && !thePlayer->GetIsSpectator()) { sendEntity = true; // If the player has the heavy armor upgrade switch the // user3 to something that will let us reconstruct that later. if (thePlayer->pev->iuser3 == AVH_USER3_MARINE_PLAYER && GetHasUpgrade(thePlayer->pev->iuser4, MASK_UPGRADE_13)) { mapEntity.mUser3 = AVH_USER3_HEAVY; } } } else { if (mapEntity.mUser3 != AVH_USER3_HEAVY) { sendEntity = true; } } } if (sendEntity) { const AvHMapExtents& theMapExtents = GetGameRules()->GetMapExtents(); // commented this out here, commented out corresponding shift in AvHOverviewMap::Draw at line 771 // float theMinMapX = theMapExtents.GetMinMapX(); // float theMinMapY = theMapExtents.GetMinMapY(); // mapEntity.mX -= theMinMapX; // mapEntity.mY -= theMinMapY; mEntityList[theEntityIndex] = mapEntity; } } if ( inTeam->GetTeamType() == AVH_CLASS_TYPE_ALIEN ) { sc=min(3, sc); dc=min(3,dc); mc=min(3,mc); if ( this->mNumSensory != sc || this->mNumDefence != dc || this->mNumMovement != mc ) { this->mNumSensory=sc; this->mNumDefence=dc; this->mNumMovement=mc; } } } }
void AvHHealingSpray::FireProjectiles(void) { #ifdef AVH_SERVER // Look for entities in cone CBaseEntity* theCurrentEntity = NULL; vec3_t theOriginatingPosition = this->m_pPlayer->GetGunPosition(); while((theCurrentEntity = UTIL_FindEntityInSphere(theCurrentEntity, theOriginatingPosition, kHealingSprayRange)) != NULL) { bool isSelf=(theCurrentEntity == this->m_pPlayer); // Can't affect self // if(theCurrentEntity != this->m_pPlayer) // { // If entity is in view cone, and within range if(isSelf || this->m_pPlayer->FInViewCone(&theCurrentEntity->pev->origin) ) { // UTIL_FindEntityInSphere doesn't seem to take height into account. Make sure the entity is within range. float theMaxEntitySize = max(Length(theCurrentEntity->pev->mins), Length(theCurrentEntity->pev->maxs)); vec3_t theVectorDiff; VectorSubtract(theCurrentEntity->pev->origin, theOriginatingPosition, theVectorDiff); float theDiff = Length(theVectorDiff) - theMaxEntitySize; if(theDiff < kHealingSprayRange/2) { // Make sure entity is in line of fire TraceResult tr; UTIL_TraceLine(theOriginatingPosition, theCurrentEntity->Center(), dont_ignore_monsters, dont_ignore_glass, ENT(pev)/*pentIgnore*/, &tr); CBaseEntity* theBlockedByEntity = CBaseEntity::Instance(tr.pHit); if((tr.flFraction == 1.0) || (theBlockedByEntity == theCurrentEntity)) { // Heal friendly player or building in range float theFocusAmount = 1.0f; if(AvHSHUGetIsWeaponFocusable(AvHWeaponID(this->m_iId))) { theFocusAmount = AvHPlayerUpgrade::GetFocusDamageUpgrade(this->m_pPlayer->pev->iuser4); } float theDamage = this->mDamage*theFocusAmount; AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theCurrentEntity); if(theCurrentEntity->pev->team == this->m_pPlayer->pev->team) { // Players and buildables heal armor too AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theCurrentEntity); const int theBuildableHealingSprayScalar = BALANCE_VAR(kHealingSprayBuildableScalar); if(thePlayer) { // Players heal by base amount, plus percentage of health float thePercentage = BALANCE_VAR(kHealingSprayPlayerPercent)/100.0f; theDamage += thePercentage*theCurrentEntity->pev->max_health; if ( isSelf ) theDamage *= 0.5f; thePlayer->Heal(theDamage, true); } else if(theBuildable) { // Structures heal base amount times scalar float theAmount = theDamage*(float)theBuildableHealingSprayScalar; if(theBuildable->Regenerate(theAmount, true)) { // Award experience for healing the hive. Might award a little more if barely wounded, but that seems OK. if(GetGameRules()->GetIsCombatMode() && (theBuildable->pev->iuser3 == AVH_USER3_HIVE)) { AvHPlayer* theHealsprayingPlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer); if(theHealsprayingPlayer && (theHealsprayingPlayer->pev->team == theBuildable->pev->team)) { float theCombatHealExperienceScalar = BALANCE_VAR(kCombatHealExperienceScalar); theHealsprayingPlayer->AwardExperienceForObjective(theAmount*theCombatHealExperienceScalar, theBuildable->GetMessageID()); } } } } else { theCurrentEntity->TakeHealth(theDamage, this->GetDamageType()); } } else if(thePlayer) { thePlayer->TakeDamage(this->pev, this->m_pPlayer->pev, theDamage, this->GetDamageType()); } } } } // } } #endif }
void AvHBaseBuildable::ConstructUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { bool theSuccess = false; bool theIsBuilding = false; bool theIsResearching = false; float thePercentage = 0.0f; AvHSHUGetBuildResearchState(this->pev->iuser3, this->pev->iuser4, this->pev->fuser1, theIsBuilding, theIsResearching, thePercentage); // Only allow players to help along building, not researching if(theIsBuilding) { // Only allow users from same team as turret deployer float thePercentage = this->GetNormalizedBuildPercentage(); if(pActivator->pev->team == this->pev->team && (thePercentage < 1.0f)) { AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(pActivator); ASSERT(thePlayer); // Only soldiers and builders can build if(thePlayer->GetIsAbleToAct() && ((thePlayer->pev->iuser3 == AVH_USER3_MARINE_PLAYER) || (thePlayer->pev->iuser3 == AVH_USER3_ALIEN_PLAYER2))) { AvHBasePlayerWeapon* theWeapon = dynamic_cast<AvHBasePlayerWeapon*>(thePlayer->m_pActiveItem); if(!theWeapon || theWeapon->CanHolster()) { thePlayer->PlayerConstructUse(); bool thePlaySound = false; // Ensure that buildings are never absolutely painful to create int theBuildTime = max(GetGameRules()->GetBuildTimeForMessageID(this->mMessageID), 1); if((GetGameRules()->GetIsTesting() || GetGameRules()->GetCheatsEnabled()) && !GetGameRules()->GetIsCheatEnabled(kcSlowResearch)) { theBuildTime = 2; } // Make non-frame-rate dependent const float kDefaultInterval = .1f; float theTimeOfLastConstructUse = thePlayer->GetTimeOfLastConstructUse(); float theInterval = min(max(gpGlobals->time - theTimeOfLastConstructUse, 0.0f), kDefaultInterval); thePercentage += (theInterval/(float)theBuildTime); thePlayer->SetTimeOfLastConstructUse(gpGlobals->time); if(gpGlobals->time > (this->mLastTimePlayedSound + this->mAverageUseSoundLength)) { AvHSUPlayRandomConstructionEffect(thePlayer, this); this->mLastTimePlayedSound = gpGlobals->time; } // Given the number of constructors, what's chance of starting a new sound? float theChanceForNewSound = (gpGlobals->frametime/(this->mAverageUseSoundLength));// /2.0f)); float theRandomFloat = RANDOM_FLOAT(0.0f, 1.0f); if(theRandomFloat < theChanceForNewSound) { AvHSUPlayRandomConstructionEffect(thePlayer, this); } //if(RANDOM_LONG(0, 20) == 0) //{ // char theMessage[128]; // sprintf(theMessage, "Time passed: %f, ticks: %d, rate: %f\n", theTimePassed, this->mPreThinkTicks, this->mPreThinkFrameRate); // UTIL_SayText(theMessage, this); //} this->SetNormalizedBuildPercentage(thePercentage); theSuccess = true; // GHOSTBUILD: Manifest structure. pev->renderamt = 255; pev->rendermode = kRenderNormal; pev->solid = SOLID_BBOX; this->mGhost = false; } } } } // Clear out +use sound when ineffective if(!theSuccess) { EMIT_SOUND(pActivator->edict(), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM); } }
void AvHMovementChamber::TeleportUse(CBaseEntity* inActivator, CBaseEntity* inCaller, USE_TYPE inUseType, float inValue) { const float kHiveScanInterval = 1.0f; AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(inActivator); if(thePlayer && (thePlayer->pev->team == this->pev->team) && (thePlayer->GetUser3() != AVH_USER3_ALIEN_EMBRYO)) { if((this->mLastTimeScannedHives == -1) || (gpGlobals->time > (this->mLastTimeScannedHives + kHiveScanInterval))) { this->mTeleportHiveIndex = -1; float theFarthestDistance = 0.0f; //sqrt((kMaxMapDimension*2)*(kMaxMapDimension*2)); bool theIsDone = false; // Loop through the hives for this team, look for the farthest one (hives under attack take precedence) FOR_ALL_ENTITIES(kesTeamHive, AvHHive*) if((theEntity->pev->team == this->pev->team) && !theIsDone) { bool theHiveIsUnderAttack = GetGameRules()->GetIsEntityUnderAttack(theEntity->entindex()); if(theEntity->GetIsActive() || theHiveIsUnderAttack || theEntity->GetEmergencyUse() ) { float theCurrentDistance = VectorDistance(theEntity->pev->origin, inActivator->pev->origin); bool theHiveIsFarther = (theCurrentDistance > theFarthestDistance); // Undefined which attacked hive is chosen if multiples are under attack if((this->mTeleportHiveIndex == -1) || theHiveIsFarther || theHiveIsUnderAttack) { this->mTeleportHiveIndex = theEntity->entindex(); theFarthestDistance = theCurrentDistance; // If there's a hive under attack, we're done if(theHiveIsUnderAttack) { theIsDone = true; } } } } END_FOR_ALL_ENTITIES(kesTeamHive) this->mLastTimeScannedHives = gpGlobals->time; } // If we have a valid hive index, jump the player to it if(this->mTeleportHiveIndex != -1) { // Play sound at this entity EMIT_SOUND(this->edict(), CHAN_AUTO, kAlienSightOnSound, 1.0f, ATTN_NORM); // Move him to it! AvHHive* theHive = NULL; AvHSUGetEntityFromIndex(this->mTeleportHiveIndex, theHive); if(theHive) { CBaseEntity* theSpawnEntity = GetGameRules()->GetRandomHiveSpawnPoint(thePlayer, theHive->pev->origin, theHive->GetMaxSpawnDistance()); if(theSpawnEntity) { Vector theMinSize; Vector theMaxSize; thePlayer->GetSize(theMinSize, theMaxSize); int theOffset = AvHMUGetOriginOffsetForUser3(AvHUser3(thePlayer->pev->iuser3)); Vector theOriginToSpawn = theSpawnEntity->pev->origin; theOriginToSpawn.z += theOffset; if(AvHSUGetIsEnoughRoomForHull(theOriginToSpawn, AvHMUGetHull(false, thePlayer->pev->iuser3), thePlayer->edict())) { thePlayer->SetPosition(theOriginToSpawn); thePlayer->pev->velocity = Vector(0, 0, 0); thePlayer->TriggerUncloak(); // Play teleport sound before and after EMIT_SOUND(inActivator->edict(), CHAN_AUTO, kAlienSightOffSound, 1.0f, ATTN_NORM); } } } } }
bool AvHSUGetInViewOfEnemy(CBaseEntity* inEntity, int& outSightedStatus) { bool theInViewOfEnemy = false; if(inEntity->pev->iuser4 & MASK_TOPDOWN) { // Top down players are never visible } else { if(GetGameRules()->GetDrawInvisibleEntities()) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; } else if(GetGameRules()->GetIsCheatEnabled(kcDetectAll)) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; } else { // Make all hives always visible //AvHHive* theHive = dynamic_cast<AvHHive*>(inEntity); //if(theHive) //{ // int a = 0; //} //if(theHive && (theHive->GetIsActive() || theHive->GetIsSpawning())) //{ // outSightedStatus = MASK_VIS_SIGHTED; // theInViewOfEnemy = true; //} //else //{ AvHPlayer* theInPlayer = dynamic_cast<AvHPlayer*>(inEntity); AvHCloakable* theCloakable = dynamic_cast<AvHCloakable*>(inEntity); if(!theInPlayer || !theInPlayer->GetIsCloaked()) { if(!theCloakable || (theCloakable->GetOpacity() > 0.0f)) { // Loop through enemy players, check if we are in view of any of them //FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*) for(AvHPlayerListType::iterator thePlayerIter = gPlayerList.begin(); thePlayerIter != gPlayerList.end(); thePlayerIter++) { if((*thePlayerIter)->GetTeam() != inEntity->pev->team) { // Commanders can't "see" enemies if(((*thePlayerIter)->GetUser3() != AVH_USER3_COMMANDER_PLAYER) && ((*thePlayerIter)->GetIsRelevant())) { if((*thePlayerIter)->GetIsEntityInSight(inEntity)) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; //char theErrorString[256]; //sprintf(theErrorString, "Entity %s is in sight of player %d.\n", STRING(inEntity->pev->classname), (*thePlayerIter)->entindex()); //ALERT(at_logged, theErrorString); break; } } } } } //END_FOR_ALL_ENTITIES(kAvHPlayerClassName) // Loop through observatories, uncloaking and detecting all enemy players in range //FOR_ALL_ENTITIES(kwsObservatory, AvHObservatory*) for(AvHObservatoryListType::iterator theObservatoryIter = gObservatoryList.begin(); theObservatoryIter != gObservatoryList.end(); theObservatoryIter++) { if((*theObservatoryIter)->pev->team != inEntity->pev->team && !(*theObservatoryIter)->GetIsRecycling() ) { // Check that entity is in range of scan (only check XY distance, for commander's purposes) float theDistance = VectorDistance2D((*theObservatoryIter)->pev->origin, inEntity->pev->origin); if(theDistance < BALANCE_IVAR(kObservatoryXYDetectionRadius)) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; if(theCloakable) { theCloakable->Uncloak(); } break; } } } //END_FOR_ALL_ENTITIES(kwsObservatory) // Loop through all active scans on our team //FOR_ALL_ENTITIES(kwsScan, AvHScan*) for(AvHScanListType::iterator theScanIter = gScanList.begin(); theScanIter != gScanList.end(); theScanIter++) { if((*theScanIter)->pev->team != inEntity->pev->team) { // Check that entity is in range of scan float theDistance = VectorDistance((*theScanIter)->pev->origin, inEntity->pev->origin); if(theDistance < BALANCE_IVAR(kScanRadius)) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; break; } } } //END_FOR_ALL_ENTITIES(kwsScan) // Loop through active sensory chambers //FOR_ALL_ENTITIES(kwsSensoryChamber, AvHSensoryChamber*) // for(AvHSensoryChamberListType::iterator theSensoryChamberIter = gSensoryChamberList.begin(); theSensoryChamberIter != gSensoryChamberList.end(); theSensoryChamberIter++) // { // if(((*theSensoryChamberIter)->pev->team != inEntity->pev->team) && (inEntity->pev->team != 0)) // { // // Make sure it's built // if((*theSensoryChamberIter)->GetIsBuilt()) // { // //if((*theSensoryChamberIter)->GetIsEntityInSight(inEntity)) // float theDistance = VectorDistance2D((*theSensoryChamberIter)->pev->origin, inEntity->pev->origin); // if(theDistance < kSensoryChamber2DSightRange) // { // // Trigger alert // GetGameRules()->TriggerAlert(AvHTeamNumber((*theSensoryChamberIter)->pev->team), ALERT_ENEMY_APPROACHES, inEntity->entindex()); // // outSightedStatus = MASK_VIS_SIGHTED; // theInViewOfEnemy = true; // break; // } // } // } // } //END_FOR_ALL_ENTITIES(kwsSensoryChamber) // } } } // If not in sight, check for motion-tracking if(!theInViewOfEnemy) { bool theEnemyTeamHasMotionTracking = false; if((inEntity->pev->team == TEAM_ONE) || (inEntity->pev->team == TEAM_TWO)) { AvHTeamNumber theEnemyTeamNumber = (inEntity->pev->team == TEAM_ONE) ? TEAM_TWO : TEAM_ONE; AvHTeam* theEnemyTeam = GetGameRules()->GetTeam(theEnemyTeamNumber); if(theEnemyTeam) { if(theEnemyTeam->GetResearchManager().GetTechNodes().GetIsTechResearched(TECH_RESEARCH_MOTIONTRACK) || GetGameRules()->GetIsCombatMode()) { //char theErrorString[256]; //const char* theEntityName = "unknown"; //if(inEntity && inEntity->pev) //{ // const char* theTentativeEntityName = NULL; // theTentativeEntityName = STRING(inEntity->pev->classname); // if(theTentativeEntityName) // { // theEntityName = theTentativeEntityName; // } //} // Motion-tracking doesn't pick up cloaked entities (players) bool theIsCloaked = false; AvHCloakable* theCloakable = dynamic_cast<AvHCloakable*>(inEntity); if(theCloakable && (theCloakable->GetOpacity() < 0.1f)) { theIsCloaked = true; } float theVelocity = inEntity->pev->velocity.Length(); //sprintf(theErrorString, "Entity %s has velocity %f.\n", theEntityName, theVelocity); //ALERT(at_logged, theErrorString); //ELVEN - WE HAVE TO CHECK FOR EXISTANT OBSERVATORIES BEFORE WE CAN FLAG THIS. //voogru: Fixed combat mode problems & slight perfoamance issue (no need to loop thru every obs). bool obsExists = false; if(!GetGameRules()->GetIsCombatMode()) { FOR_ALL_ENTITIES(kwsObservatory, AvHObservatory*) if(theEntity->GetIsBuilt()) { obsExists = true; break; } END_FOR_ALL_ENTITIES(kwsObservatory) } else { obsExists = true; } if((theVelocity > kMovementVisibilityThreshold) && !theIsCloaked && obsExists) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; } }
bool AvHSUGetInViewOfEnemy(CBaseEntity* inEntity, int& outSightedStatus) { bool theInViewOfEnemy = false; if(inEntity->pev->iuser4 & MASK_TOPDOWN) { // Top down players are never visible } else { if(GetGameRules()->GetDrawInvisibleEntities()) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; } else if(GetGameRules()->GetIsCheatEnabled(kcDetectAll)) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; } else { AvHPlayer* theInPlayer = dynamic_cast<AvHPlayer*>(inEntity); AvHCloakable* theCloakable = dynamic_cast<AvHCloakable*>(inEntity); if(!theInPlayer || !theInPlayer->GetIsCloaked()) { if(!theCloakable || (theCloakable->GetOpacity() > 0.0f)) { // Loop through enemy players, check if we are in view of any of them for(AvHPlayerListType::iterator thePlayerIter = gPlayerList.begin(); thePlayerIter != gPlayerList.end(); thePlayerIter++) { if((*thePlayerIter)->GetTeam() != inEntity->pev->team) { // Commanders can't "see" enemies if(((*thePlayerIter)->GetUser3() != AVH_USER3_COMMANDER_PLAYER) && ((*thePlayerIter)->GetIsRelevant())) { if((*thePlayerIter)->GetIsEntityInSight(inEntity)) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; break; } } } } } // Loop through observatories, uncloaking and detecting all enemy players in range for(AvHObservatoryListType::iterator theObservatoryIter = gObservatoryList.begin(); theObservatoryIter != gObservatoryList.end(); theObservatoryIter++) { if((*theObservatoryIter)->pev->team != inEntity->pev->team && ( inEntity->pev->team != TEAM_IND ) && !(*theObservatoryIter)->GetIsRecycling() ) { // Check that entity is in range of scan (only check XY distance, for commander's purposes) float theDistance = VectorDistance2D((*theObservatoryIter)->pev->origin, inEntity->pev->origin); if(theDistance < BALANCE_VAR(kObservatoryXYDetectionRadius)) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; if(theCloakable) { theCloakable->Uncloak(); } break; } } } // Loop through all active scans on our team for(AvHScanListType::iterator theScanIter = gScanList.begin(); theScanIter != gScanList.end(); theScanIter++) { if((*theScanIter)->pev->team != inEntity->pev->team) { // Check that entity is in range of scan float theDistance = VectorDistance((*theScanIter)->pev->origin, inEntity->pev->origin); if(theDistance < BALANCE_VAR(kScanRadius)) { outSightedStatus |= MASK_VIS_SIGHTED; theInViewOfEnemy = true; break; } } } } } // If not in sight, check for motion-tracking if(!theInViewOfEnemy) { bool theEnemyTeamHasMotionTracking = false; AvHTeamNumber teamA = GetGameRules()->GetTeamA()->GetTeamNumber(); AvHTeamNumber teamB = GetGameRules()->GetTeamB()->GetTeamNumber(); if((inEntity->pev->team == teamA) || (inEntity->pev->team == teamB)) { AvHTeamNumber theEnemyTeamNumber = (inEntity->pev->team == teamA) ? teamB : teamA; AvHTeam* theEnemyTeam = GetGameRules()->GetTeam(theEnemyTeamNumber); if(theEnemyTeam) { if(theEnemyTeam->GetResearchManager().GetTechNodes().GetIsTechResearched(TECH_RESEARCH_MOTIONTRACK) || GetGameRules()->GetIsCombatMode()) { // Motion-tracking doesn't pick up cloaked entities (players) bool theIsCloaked = false; AvHCloakable* theCloakable = dynamic_cast<AvHCloakable*>(inEntity); if(theCloakable && (theCloakable->GetOpacity() < 0.1f)) { theIsCloaked = true; } float theVelocity = inEntity->pev->velocity.Length(); //ELVEN - WE HAVE TO CHECK FOR EXISTANT OBSERVATORIES BEFORE WE CAN FLAG THIS. //voogru: Fixed combat mode problems & slight perfoamance issue (no need to loop thru every obs). bool obsExists = false; if(!GetGameRules()->GetIsCombatMode()) { FOR_ALL_ENTITIES(kwsObservatory, AvHObservatory*) if(theEntity->GetIsBuilt()) { obsExists = true; break; } END_FOR_ALL_ENTITIES(kwsObservatory) } else { obsExists = true; } if((theVelocity > kMovementVisibilityThreshold) && !theIsCloaked && obsExists) { outSightedStatus |= MASK_VIS_DETECTED; theInViewOfEnemy = true; } }