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