public static function GetTuningData($AbilityId = null, $Key = null)
 {
     $TuningData = Server::GetTuningData('abilities');
     if ($AbilityId === null) {
         return $TuningData;
     } else {
         if ($Key === null) {
             return $TuningData[$AbilityId];
         } else {
             if (!isset($TuningData[$AbilityId][$Key])) {
                 return null;
             }
         }
     }
     return $TuningData[$AbilityId][$Key];
 }
Example #2
0
 private function GetTuningData($Key = null)
 {
     $TuningData = Server::GetTuningData('player');
     if ($Key === null) {
         return $TuningData;
     } else {
         if (!array_key_exists($Key, $TuningData)) {
             return null;
         }
     }
     return $TuningData[$Key];
 }
Example #3
0
 public function Update($SecondsPassed = false)
 {
     $this->Time = time();
     if (!$this->IsRunning()) {
         Server::GetLogger()->debug('Game #' . $this->GameId . ' is not running, canceling update');
         return;
     }
     Server::GetLogger()->debug('Updating game #' . $this->GameId);
     $SecondPassed = $SecondsPassed !== false && $SecondsPassed > 0;
     $LaneDps = [0 => 0, 1 => 0, 2 => 0];
     foreach ($this->Players as $Player) {
         $Player->ClearLoot($this->Time);
         $Player->CheckActiveAbilities($this);
         if ($SecondPassed && !$Player->IsDead()) {
             // Deal DPS damage to current target
             $Lane = $this->Lanes[$Player->GetCurrentLane()];
             $Enemy = $Lane->GetEnemy($Player->GetTarget());
             if ($Enemy === null || $Enemy->IsDead()) {
                 $Enemy = $Lane->GetAliveEnemy();
                 if ($Enemy !== null) {
                     $Player->SetTarget($Enemy->GetPosition());
                 }
             }
             if ($Enemy !== null) {
                 $DealtDpsDamage = $Player->GetTechTree()->GetDps() * $Player->GetTechTree()->GetExtraDamageMultipliers($this->Lanes[$Player->GetCurrentLane()]->GetElement()) * $this->Lanes[$Player->GetCurrentLane()]->GetDamageMultiplier() * $SecondsPassed;
                 if ($this->Lanes[$Player->GetCurrentLane()]->HasActivePlayerAbilityMaxElementalDamage()) {
                     $DealtDpsDamage *= $Player->GetTechTree()->GetHighestElementalMultiplier();
                 }
                 if ($Player->GetCritDamage() > 0) {
                     $DealtDpsDamage *= $Player->GetTechTree()->GetDamageMultiplierCrit();
                     $Player->Stats->CritDamageDealt += $DealtDpsDamage;
                     $Player->CritDamage = 0;
                 }
                 $Player->Stats->DpsDamageDealt += $DealtDpsDamage;
                 $Enemy->DpsDamageTaken += $DealtDpsDamage;
                 if ($DealtDpsDamage > 0) {
                     Server::GetLogger()->debug('Player ' . $Player->PlayerName . ' (#' . $Player->GetAccountId() . ')' . ' did ' . $DealtDpsDamage . ' DPS damage to enemy #' . $Enemy->GetId());
                 }
                 foreach ($Player->LaneDamageBuffer as $LaneId => $LaneDamage) {
                     $LaneDps[$LaneId] += $LaneDamage / $SecondsPassed;
                     // TODO: This is damage done by clicks, not per second, remove or keep?
                     $Player->LaneDamageBuffer[$LaneId] = 0;
                 }
                 $LaneDps[$Player->GetCurrentLane()] += $Player->GetTechTree()->GetDps() * $SecondsPassed;
                 #TODO: $DealtDpsDamage?
             }
         }
         if ($Player->IsDead() && $Player->CanRespawn($this->Time, true)) {
             // Respawn player
             $Player->Respawn();
         }
     }
     // Loop through lanes and deal damage etc
     $DeadLanes = 0;
     foreach ($this->Lanes as $LaneId => $Lane) {
         if ($SecondPassed) {
             # TODO: Apply this in Lane::CheckActivePlayerAbilities instead?
             $ReflectDamageMultiplier = $Lane->GetReflectDamageMultiplier();
             $NapalmDamageMultiplier = $Lane->GetNapalmDamageMultiplier();
         }
         $DeadEnemies = 0;
         $EnemyCount = count($Lane->Enemies);
         $EnemyDpsDamage = 0;
         foreach ($Lane->Enemies as $Enemy) {
             if ($Enemy->IsDead()) {
                 if ($Enemy->GetDpsHpDifference() > 0) {
                     // Find next enemy to deal the rest of the DPS damage to
                     $NextEnemy = $Lane->GetAliveEnemy();
                     if ($NextEnemy !== null) {
                         Server::GetLogger()->debug('Enemy #' . $Enemy->GetId() . ' is dead. Passing on ' . $Enemy->GetDpsHpDifference() . ' DPS damage to enemy #' . $NextEnemy->GetId());
                         $NextEnemy->DpsDamageTaken += $Enemy->GetDpsHpDifference();
                     }
                 }
                 $DeadEnemies++;
             } else {
                 if ($SecondPassed) {
                     # TODO: Apply this in Lane::CheckActivePlayerAbilities instead?
                     # TODO: Check if $ReflectDamageMultiplier is 0.5% or 50%, 0.5% would make more sense if it stacks..
                     if ($ReflectDamageMultiplier > 0) {
                         $Enemy->AbilityDamageTaken += $Enemy->GetHp() * $ReflectDamageMultiplier * $SecondsPassed;
                     }
                     if ($NapalmDamageMultiplier > 0) {
                         $Damage = $Enemy->GetMaxHp() * $NapalmDamageMultiplier * $SecondsPassed;
                         $Enemy->AbilityDamageTaken += $Damage;
                     }
                 }
                 $Enemy->Hp -= $Enemy->DpsDamageTaken;
                 if ($Enemy->GetDpsHpDifference() > 0) {
                     // Find next enemy to deal the rest of the DPS damage to
                     $NextEnemy = $Lane->GetAliveEnemy();
                     if ($NextEnemy !== null) {
                         Server::GetLogger()->debug('Enemy #' . $Enemy->GetId() . ' is dead. Passing on ' . $Enemy->GetDpsHpDifference() . ' DPS damage to enemy #' . $NextEnemy->GetId());
                         $NextEnemy->DpsDamageTaken += $Enemy->GetDpsHpDifference();
                     }
                 }
                 $Enemy->Hp -= $Enemy->ClickDamageTaken;
                 $Enemy->Hp -= $Enemy->AbilityDamageTaken;
                 if ($Enemy->IsDead()) {
                     $this->IncreaseEnemiesKilled($Enemy);
                     $Enemy->SetHp(0);
                     $DeadEnemies++;
                     $EnemyGold = $Enemy->GetGold() * $Lane->GetEnemyGoldMultiplier();
                     Server::GetLogger()->debug('Enemy #' . $Enemy->GetId() . ' is dead. Giving ' . $EnemyGold . ' gold (Multiplier: ' . $Lane->GetEnemyGoldMultiplier() . ') to players in lane #' . $Lane->GetLaneId());
                     $Lane->GiveGoldToPlayers($this, $EnemyGold);
                 } else {
                     $EnemyDpsDamage += $Enemy->GetDps();
                 }
             }
             $Enemy->DpsDamageTaken = 0;
             $Enemy->ClickDamageTaken = 0;
             $Enemy->AbilityDamageTaken = 0;
             if ($Enemy->HasTimer() && $Enemy->IsTimerEnabled() && $Enemy->HasTimerRanOut($SecondsPassed)) {
                 switch ($Enemy->GetType()) {
                     case Enums\EEnemyType::Tower:
                         if ($Enemy->IsDead()) {
                             continue;
                         }
                         // Revive dead mobs in the lane if the tower timer ran out
                         Server::GetLogger()->debug('Respawn timer has ran out in lane #' . $Lane->GetLaneId() . ', reviving dead mobs in the lane');
                         foreach ($Lane->GetDeadEnemies(Enums\EEnemyType::Mob) as $DeadEnemy) {
                             $DeadEnemy->ResetHp();
                         }
                         break;
                     case Enums\EEnemyType::MiniBoss:
                         if (!$Enemy->IsDead()) {
                             continue;
                         }
                         // Revive dead miniboss if he's dead and the timer ran out
                         Server::GetLogger()->debug('Respawn timer has ran out for miniboss #' . $Enemy->GetId() . ' in lane #' . $Lane->GetLaneId() . ', reviving dead miniboss');
                         $Enemy->ResetHp();
                         break;
                     case Enums\EEnemyType::TreasureMob:
                         if ($Enemy->IsDead()) {
                             continue;
                         }
                         // Kill the treasure mob and set gold to 0 if the timer (lifetime) ran out
                         Server::GetLogger()->debug('Treasure mob #' . $Enemy->GetId() . ' timer has ran out in lane #' . $Lane->GetLaneId() . ', killing treasure mob');
                         $Enemy->SetHp(0);
                         $Enemy->SetGold(0);
                         $Enemy->DisableTimer();
                         $this->AddChatEntry('server', '', 'You were too slow to kill the treasure, it has despawned');
                         break;
                 }
                 $Enemy->ResetTimer();
             }
         }
         $DeadLanes += $DeadEnemies === count($Lane->Enemies) ? 1 : 0;
         // Deal damage to players in lane
         $PlayersInLane = [];
         foreach ($this->Players as $Player) {
             if ($Player->GetCurrentLane() === $LaneId) {
                 $PlayersInLane[] = $Player;
                 if ($Player->IsInvulnerable()) {
                     continue;
                 }
                 if ($SecondPassed && !$Player->IsDead()) {
                     $EnemyDamage = $EnemyDpsDamage * $SecondsPassed;
                     $PlayerHp = $Player->Hp - $EnemyDamage;
                     if ($PlayerHp > 0) {
                         $Player->Stats->DamageTaken += $EnemyDamage;
                         $Player->Hp = $PlayerHp;
                     } else {
                         $Player->Stats->DamageTaken += $Player->Hp;
                         $Player->Hp = 0;
                         $Player->Kill($this->Time);
                     }
                 }
             }
         }
         $Lane->Dps = $LaneDps[$LaneId];
         $Lane->CheckActivePlayerAbilities($this, $SecondsPassed);
         $Lane->UpdateHpBuckets($this->Time, $PlayersInLane);
     }
     if ($DeadLanes === 3) {
         if ($this->WormholeCount > 0) {
             if ($this->IsGoldHelmBossLevel()) {
                 $this->WormholeCount *= 10;
             }
             $this->Level += $this->WormholeCount;
             $BadgePoints = Util::FloorToMultipleOf(10, $this->WormholeCount * 0.1);
             $AbilityGold = AbilityItem::GetGoldMultiplier(Enums\EAbility::Item_SkipLevels);
             $Players = $this->GetPlayers();
             foreach ($Players as $Player) {
                 $Player->IncreaseGold($AbilityGold * $this->WormholeCount);
                 # TODO: Is gold stackable as well?
                 if ($BadgePoints > 0) {
                     $Player->GetTechTree()->IncreaseBadgePoints($BadgePoints);
                 }
             }
             $this->AddChatEntry('server', '', 'Skipped ' . number_format($this->WormholeCount) . ' level' . ($this->WormholeCount === 1 ? '' : 's'));
             $this->WormholeCount = 0;
             foreach ($this->Lanes as $Lane) {
                 $Lane->RemoveActiveWormholes();
             }
         }
         $this->GenerateNewLevel();
     }
 }
Example #4
0
 public static function GetTuningData($UpgradeId, $Key = null)
 {
     $TuningData = Server::GetTuningData('upgrades');
     if ($UpgradeId === null) {
         return $TuningData;
     } else {
         if ($Key === null) {
             return $TuningData[$UpgradeId];
         } else {
             if (!isset($TuningData[$UpgradeId][$Key])) {
                 return null;
             }
         }
     }
     return $TuningData[$UpgradeId][$Key];
 }