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 ); } }
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; }
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); } }