function setCombatIndex($defenderId) { $combatLog = ""; $battle = Battle::getBattle(); $combatRules = $battle->combatRules; $combats = $battle->combatRules->combats->{$defenderId}; /* @var Force $force */ $force = $battle->force; $hexagon = $battle->force->units[$defenderId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $attackStrength = 0; $combatLog .= "Attackers<br>"; foreach ($combats->attackers as $id => $v) { $unit = $force->units[$id]; $combatLog .= $unit->strength . " " . $unit->class . " "; $attackStrength += $unit->strength; } $defenseStrength = 0; $combatLog .= " = {$attackStrength}<br>Defenders<br> "; foreach ($defenders as $defId => $defender) { $unit = $battle->force->units[$defId]; $combatLog .= $unit->strength . " " . $unit->class . " "; $defenseStrength += $unit->defStrength; $combatLog .= "<br>"; } $combatLog .= " = {$defenseStrength}"; $combatIndex = $this->getCombatIndex($attackStrength, $defenseStrength); /* Do this before terrain effects */ if ($combatIndex >= $this->maxCombatIndex) { $combatIndex = $this->maxCombatIndex; } /* @var $combatRules CombatRules */ // $terrainCombatEffect = $combatRules->getDefenderTerrainCombatEffect($defenderId); // $combatIndex -= $terrainCombatEffect; $combats->attackStrength = $attackStrength; $combats->defenseStrength = $defenseStrength; // $combats->terrainCombatEffect = $terrainCombatEffect; $combats->terrainCombatEffect = 0; $combats->index = $combatIndex; $combats->combatLog = $combatLog; }
protected function unitSupplyEffects($unit, $goal, $bias, $supplyLen) { $b = Battle::getBattle(); $id = $unit->id; if ($b->gameRules->mode == REPLACING_MODE) { if ($unit->status == STATUS_CAN_UPGRADE) { $unit->supplied = $b->moveRules->calcSupply($unit->id, $goal, $bias, $supplyLen); if (!$unit->supplied) { /* TODO: make this not cry (call a method) */ $unit->status = STATUS_STOPPED; } } return; } if ($unit->status == STATUS_READY || $unit->status == STATUS_UNAVAIL_THIS_PHASE) { $unit->supplied = $b->moveRules->calcSupply($unit->id, $goal, $bias, $supplyLen); } else { return; } if (!$unit->supplied && !isset($this->movementCache->{$id})) { $this->movementCache->{$id} = $unit->maxMove; $unit->maxMove = floor($unit->maxMove / 2); } if ($unit->supplied && isset($this->movementCache->{$id})) { $unit->maxMove = $this->movementCache->{$id}; unset($this->movementCache->{$id}); } if ($unit->status == STATUS_READY || $unit->status == STATUS_DEFENDING || $unit->status == STATUS_UNAVAIL_THIS_PHASE) { $unit->supplied = $b->moveRules->calcSupply($unit->id, $goal, $bias, $supplyLen); } else { return; } if (($this->unsuppliedDefenderHalved || $unit->forceId == $b->gameRules->attackingForceId) && !$unit->supplied && !isset($this->combatCache->{$id})) { $this->combatCache->{$id} = true; $unit->addAdjustment('supply', 'half'); // $unit->strength = floor($unit->strength / 2); } if ($unit->supplied && isset($this->combatCache->{$id})) { $unit->removeAdjustment('supply'); // $unit->strength = $this->combatCache->$id; unset($this->combatCache->{$id}); } }
function setCombatIndex($defenderId) { $combatLog = ""; $battle = Battle::getBattle(); $combatRules = $battle->combatRules; $combats = $battle->combatRules->combats->{$defenderId}; /* @var Force $force */ $force = $battle->force; $hexagon = $battle->force->units[$defenderId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $attackingForceId = $battle->force->attackingForceId; $attackingForceName = preg_replace("/ /", "-", Battle::$forceName[$attackingForceId]); $defendingForceId = $battle->force->defendingForceId; $defendingForceName = preg_replace("/ /", "-", Battle::$forceName[$defendingForceId]); if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $isTown = $isHill = $isForest = $isSwamp = $attackerIsSunkenRoad = $isRedoubt = $isElevated = false; foreach ($defenders as $defId => $defender) { $hexagon = $battle->force->units[$defId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $isTown |= $battle->terrain->terrainIs($hexpart, 'town'); $isHill |= $battle->terrain->terrainIs($hexpart, 'hill'); $isForest |= $battle->terrain->terrainIs($hexpart, 'forest'); $isSwamp |= $battle->terrain->terrainIs($hexpart, 'swamp'); $isElevated |= $battle->terrain->terrainIs($hexpart, 'elevation'); } $isClear = true; if ($isTown || $isForest || $isHill || $isSwamp) { $isClear = false; } $attackStrength = 0; $combatLog .= "<span class='combatants {$attackingForceName}'>Attackers</span><br>"; foreach ($combats->attackers as $attackerId => $v) { $unit = $force->units[$attackerId]; $combatLog .= $unit->class . " " . $unit->strength . "<br>"; $acrossRiver = false; foreach ($defenders as $defId => $defender) { if ($battle->combatRules->thisAttackAcrossRiver($defId, $attackerId)) { $acrossRiver = true; } } $strength = $unit->strength; if ($acrossRiver) { $strength /= 2; $combatLog .= " halved across river or wadi {$strength}<br>"; } $attackStrength += $strength; } $defenseStrength = 0; $combatLog .= " total {$attackStrength}<br>"; $combatLog .= "<br><span class='combatants {$defendingForceName}'>Defenders</span><br>"; foreach ($defenders as $defId => $defender) { $unit = $battle->force->units[$defId]; $combatLog .= $unit->class . " " . $unit->defStrength . "<br>"; $defenseStrength += $unit->defStrength; } if ($isTown) { $defenseStrength *= 2; $combatLog .= "In Town doubled {$defenseStrength}<br>"; } $combatLog .= " Total {$defenseStrength}<br>"; $combatIndex = $this->getCombatIndex($attackStrength, $defenseStrength); if ($combatIndex >= $this->maxCombatIndex) { $combatIndex = $this->maxCombatIndex; } $combats->attackStrength = $attackStrength; $combats->defenseStrength = $defenseStrength; $combats->index = $combatIndex; $combats->combatLog = $combatLog; }
function applyCRTResults($defenderId, $attackers, $combatResults, $dieRoll, $force) { $battle = Battle::getBattle(); $distance = 1; list($defenderId, $attackers, $combatResults, $dieRoll) = $battle->victory->preCombatResults($defenderId, $attackers, $combatResults, $dieRoll); $vacated = false; $exchangeMultiplier = 1; if ($combatResults === EX02) { $distance = 0; $combatResults = EX; $exchangeMultiplier = 2; } if ($combatResults === EX03) { $distance = 0; $combatResults = EX; $exchangeMultiplier = 3; } if ($combatResults === EX0) { $distance = 0; $combatResults = EX; } $defUnit = $force->units[$defenderId]; switch ($combatResults) { case EX2: $distance = 2; case EX: $eliminated = $defUnit->damageUnit($force->exchangesKill); if (!$eliminated) { if ($distance) { $defUnit->status = STATUS_CAN_RETREAT; } else { $force->clearAdvancing(); $defUnit->status = STATUS_EXCHANGED; } $defUnit->retreatCountRequired = $distance; } else { $defUnit->moveCount = 0; $force->addToRetreatHexagonList($defenderId, $force->getUnitHexagon($defenderId)); } $force->exchangeAmount += $defUnit->defExchangeAmount * $exchangeMultiplier; $defUnit->moveCount = 0; break; case DD: $defUnit->status = STATUS_DEFENDED; $defUnit->retreatCountRequired = 0; $defUnit->disruptUnit($battle->gameRules->phase); $battle->victory->disruptUnit($defUnit); break; case AL: case ALF: $defUnit->status = STATUS_DEFENDED; $defUnit->retreatCountRequired = 0; break; case AE: $defUnit->status = STATUS_DEFENDED; $defUnit->retreatCountRequired = 0; break; case AR: $defUnit->status = STATUS_DEFENDED; $defUnit->retreatCountRequired = 0; break; case DE: $defUnit->status = STATUS_ELIMINATING; $defUnit->retreatCountRequired = $distance; $defUnit->moveCount = 0; $force->addToRetreatHexagonList($defenderId, $force->getUnitHexagon($defenderId)); break; case DRL2: $distance = 2; case DRL: case DLR: case DLF: case DL2R: $eliminated = $defUnit->damageUnit(); if ($combatResults === DL2R && !$eliminated) { $eliminated = $defUnit->damageUnit(); } if ($eliminated) { $defUnit->moveCount = 0; $force->addToRetreatHexagonList($defenderId, $force->getUnitHexagon($defenderId)); } else { $defUnit->status = STATUS_CAN_RETREAT; } $defUnit->retreatCountRequired = $distance; break; case DR2: $distance = 2; case DR: $defUnit->status = STATUS_CAN_RETREAT; $defUnit->retreatCountRequired = $distance; break; case NE: case MISS: $defUnit->status = STATUS_NO_RESULT; $defUnit->retreatCountRequired = 0; $battle->victory->noEffectUnit($defUnit); break; case DL: case BL: case DL2: $eliminated = $defUnit->damageUnit(); if ($combatResults === DL2 && !$eliminated) { $eliminated = $defUnit->damageUnit(); } if ($eliminated) { $vacated = true; $defUnit->retreatCountRequired = 0; $defUnit->moveCount = 0; $force->addToRetreatHexagonList($defenderId, $force->getUnitHexagon($defenderId)); } else { $defUnit->status = STATUS_DEFENDED; $defUnit->retreatCountRequired = 0; } break; default: break; } $defUnit->combatResults = $combatResults; $defUnit->dieRoll = $dieRoll; $defUnit->combatNumber = 0; $defUnit->moveCount = 0; foreach ($attackers as $attacker => $val) { $attackingUnit = $force->units[$attacker]; if ($attackingUnit->status == STATUS_BOMBARDING) { $attackingUnit->status = STATUS_ATTACKED; $attackingUnit->retreatCountRequired = 0; $attackingUnit->combatResults = $combatResults; $attackingUnit->dieRoll = $dieRoll; $attackingUnit->combatNumber = 0; $attackingUnit->moveCount = 0; } if ($attackingUnit->status == STATUS_ATTACKING) { switch ($combatResults) { case EX2: case EX: $attackingUnit->status = STATUS_CAN_EXCHANGE; $attackingUnit->retreatCountRequired = 0; break; case AE: $attackingUnit->status = STATUS_ELIMINATING; $defUnit->retreatCountRequired = 0; break; case AL: case AL2: case ALF: case BL: $attackingUnit->status = STATUS_CAN_ATTACK_LOSE; $attackingUnit->retreatCountRequired = 0; $force->exchangeAmount = 1; if ($combatResults === AL2) { $force->exchangeAmount = ceil(ceil($attackingUnit->getUnmodifiedStrength() / 2) + 0.1); } break; case DE: $attackingUnit->status = STATUS_CAN_ADVANCE; $attackingUnit->retreatCountRequired = 0; break; case AR: $attackingUnit->status = STATUS_CAN_RETREAT; $attackingUnit->retreatCountRequired = $distance; break; case DRL2: case DR2: case DRL: case DLR: case DR: case DLF: if ($attackingUnit->status !== STATUS_NO_RESULT) { $attackingUnit->status = STATUS_CAN_ADVANCE; } $attackingUnit->retreatCountRequired = 0; break; case DL: /* for multi defender combats */ if ($vacated || $attackingUnit->status == STATUS_CAN_ADVANCE) { $attackingUnit->status = STATUS_CAN_ADVANCE; } else { $attackingUnit->status = STATUS_NO_RESULT; } $attackingUnit->retreatCountRequired = 0; break; case NE: $attackingUnit->status = STATUS_NO_RESULT; $attackingUnit->retreatCountRequired = 0; break; default: break; } $attackingUnit->combatResults = $combatResults; $attackingUnit->dieRoll = $dieRoll; $attackingUnit->combatNumber = 0; $attackingUnit->moveCount = 0; } } $gameRules = $battle->gameRules; $mapData = $battle->mapData; $mapData->breadcrumbCombat($defenderId, $force->attackingForceId, $gameRules->turn, $gameRules->phase, $gameRules->mode, $combatResults, $dieRoll, $force->getUnitHexagon($defenderId)->name); $battle->victory->postCombatResults($defenderId, $attackers, $combatResults, $dieRoll); $force->removeEliminatingUnits(); }
function damageUnit($kill = false) { $battle = Battle::getBattle(); $this->status = STATUS_ELIMINATING; $this->exchangeAmount = $this->getUnmodifiedStrength(); $this->defExchangeAmount = $this->getUnmodifiedDefStrength(); return true; }
function damageUnit($kill = false) { $battle = Battle::getBattle(); if ($this->isReduced || $kill) { $this->status = STATUS_ELIMINATING; $this->exchangeAmount = $this->getUnmodifiedStrength(); $this->defExchangeAmount = $this->getUnmodifiedDefStrength(); return true; } else { $this->damage = $this->maxStrength - $this->minStrength; $battle->victory->reduceUnit($this); $this->isReduced = true; $this->exchangeAmount = $this->damage; $this->defExchangeAmount = $this->damage; } return false; }
function setCombatIndex($defenderId) { $combatLog = ""; $battle = Battle::getBattle(); $combatRules = $battle->combatRules; $combats = $battle->combatRules->combats->{$defenderId}; /* @var Force $force */ $force = $battle->force; $hexagon = $battle->force->units[$defenderId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $isTown = $isHill = $isForest = $isSwamp = $attackerIsSunkenRoad = $isRedoubt = $isElevated = false; $totalDefense = 1; $terrain = $battle->terrain; $defCombatLog = ""; foreach ($defenders as $defId => $defender) { $hexagon = $battle->force->units[$defId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $thisHex = []; $thisLog = ""; $hexName = $hexagon->name; if ($battle->mapData->getMapSymbol($hexagon->name, 'westwall')) { $thisHex['forta'] = 2; $thisLog .= "2x defend in westwall<br>"; } if ($terrain->terrainIs($hexpart, 'roughone')) { $thisHex['roughone'] = 2; $thisLog .= "2x defend in rough<br>"; } if ($terrain->terrainIs($hexpart, 'roughtwo')) { $thisHex['roughtwo'] = 3; $thisLog .= "3x defend in mountain<br>"; } if ($battle->combatRules->allAreAttackingAcrossRiver($defId)) { $thisHex['river'] = 2; $thisLog .= "2x defend behind river<br>"; } $multiple = count($thisHex); $defense = array_sum($thisHex); if ($multiple > 1) { $defense--; } if ($defense > $totalDefense) { $totalDefense = $defense; $defCombatLog = $thisLog . "total def {$defense}x<br>"; } } $attackStrength = 0; $combatLog .= "Attackers<br>"; foreach ($combats->attackers as $attackerId => $v) { $unit = $force->units[$attackerId]; $combatLog .= $unit->strength . " " . $unit->class . "<br>"; $strength = $unit->strength; $attackStrength += $strength; } $defenseStrength = 0; $combatLog .= " = {$attackStrength}<br><br>Defenders<br> "; $unitDefenseStrength = 0; foreach ($defenders as $defId => $defender) { $unit = $battle->force->units[$defId]; $combatLog .= $unit->defStrength . " " . $unit->class . " "; $unitDefenseStrength += $unit->defStrength; $defenseStrength += $unit->defStrength * $totalDefense; $combatLog .= "<br>"; } $combatLog .= "= {$unitDefenseStrength}<br>"; $combatLog .= $defCombatLog; $combatLog .= " = {$defenseStrength}<br><br>"; $combatIndex = $this->getCombatIndex($attackStrength, $defenseStrength); /* Do this before terrain effects */ if ($combatIndex >= $this->maxCombatIndex) { $combatIndex = $this->maxCombatIndex; } /* @var $combatRules CombatRules */ // $terrainCombatEffect = $combatRules->getDefenderTerrainCombatEffect($defenderId); // $combatIndex -= $terrainCombatEffect; $combats->attackStrength = $attackStrength; $combats->defenseStrength = $defenseStrength; $combats->terrainCombatEffect = 0; $combats->index = $combatIndex; $combats->combatLog = $combatLog; }
function setCombatIndex($defenderId) { $combatLog = ""; $battle = Battle::getBattle(); $combatRules = $battle->combatRules; $combats = $battle->combatRules->combats->{$defenderId}; /* @var Force $force */ $force = $battle->force; $hexagon = $battle->force->units[$defenderId]->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $attackStrength = 0; $combatLog .= "Attackers<br>"; $attackers = 0; foreach ($combats->attackers as $id => $v) { $attackers++; $unit = $force->units[$id]; $los = new Los(); $los->setOrigin($force->getUnitHexagon($id)); $los->setEndPoint($force->getUnitHexagon($defenderId)); $range = (int) $los->getRange(); $strength = $unit->strength; $combatLog .= $strength . " " . $unit->class; if ($battle->gameRules->phase == BLUE_TORP_COMBAT_PHASE || $battle->gameRules->phase == RED_TORP_COMBAT_PHASE) { if ($range > 2 * $unit->range) { $strength /= 3; $combatLog .= " One third for extended Range {$strength}"; } elseif ($range > $unit->range) { $strength /= 2; $combatLog .= " Halved for extended Range {$strength}"; } if ($range === 1) { $strength *= 2; $combatLog .= " Doubled for close Range {$strength}"; } if ($range === 2 && $unit->nationality === 'ijn') { $strength *= 2; $combatLog .= " Doubled for close Range {$strength}"; } } else { if ($range > $unit->range) { $strength /= 2; $combatLog .= " Halved for extended Range {$strength}"; } if ($range <= $unit->range / 2) { if ($range <= 2) { $strength *= 3; $combatLog .= " Tripled for range 2 or less {$strength}"; } else { $strength *= 2; $combatLog .= " Doubled for Range less than half normal {$strength}"; } } } $combatLog .= "<br>"; $attackStrength += $strength; } if ($attackers > 1 && !($battle->gameRules->phase == BLUE_TORP_COMBAT_PHASE || $battle->gameRules->phase == RED_TORP_COMBAT_PHASE)) { $beforeStr = $attackStrength; $attackStrength /= 2; $combatLog .= "{$beforeStr} Attack strength halved fore multi ship attack {$attackStrength}<br>"; } $defenseStrength = 0; $combatLog .= " = {$attackStrength}<br>Defenders<br> "; foreach ($defenders as $defId => $defender) { $unit = $battle->force->units[$defId]; $combatLog .= " " . $unit->class . " "; $defenseStrength += $unit->defStrength; $combatLog .= "<br>"; } if ($battle->gameRules->phase == BLUE_TORP_COMBAT_PHASE || $battle->gameRules->phase == RED_TORP_COMBAT_PHASE) { $combats->unitDefenseStrength = $defenseStrength; $combats->oneHitCol = $this->getOneHitColumn($defenseStrength); $combats->twoHitCol = $this->getTwoHitColumn($defenseStrength); $defenseStrength = $unit->maxMove + 1; } $combatLog .= " = {$defenseStrength}"; $combatIndex = $this->getCombatIndex($attackStrength, $defenseStrength); /* Do this before terrain effects */ if ($combatIndex >= $this->maxCombatIndex) { $combatIndex = $this->maxCombatIndex; } /* @var $combatRules CombatRules */ $combats->attackStrength = $attackStrength; $combats->defenseStrength = $defenseStrength; $combats->terrainCombatEffect = 0; $combats->index = $combatIndex; $combats->combatLog = $combatLog; }
function unitIsInRange($id, $argRange = false) { $b = Battle::getBattle(); $isInRange = false; $range = $this->units[$id]->range; $unitRange = $range * 2; if ($b->gameRules->phase == BLUE_TORP_COMBAT_PHASE || $b->gameRules->phase == RED_TORP_COMBAT_PHASE) { $unitRange = $range * 3; } $range = $unitRange; if ($argRange !== false) { $range = $argRange; } $los = new Los(); $los->setOrigin($this->units[$id]->hexagon); for ($i = 0; $i < count($this->units); $i++) { /* hexagons without names are off map */ if (!$this->units[$i]->hexagon->name) { continue; } $los->setEndPoint($this->units[$i]->hexagon); $losRange = $los->getRange(); if ($losRange <= $range && $this->units[$i]->forceId != $this->units[$id]->forceId && $this->units[$i]->status != STATUS_CAN_REINFORCE && $this->units[$i]->status != STATUS_ELIMINATED) { if ($b->combatRules->checkBlocked($los, $id)) { $isInRange = true; break; } } } return $isInRange; }
public function playerTurnChange($arg) { $attackingId = $arg[0]; $battle = Battle::getBattle(); $mapData = $battle->mapData; $vp = $this->victoryPoints; $specialHexes = $mapData->specialHexes; $gameRules = $battle->gameRules; if ($gameRules->phase == BLUE_MECH_PHASE || $gameRules->phase == RED_MECH_PHASE) { $gameRules->flashMessages[] = "@hide crt"; } if ($attackingId == REBEL_FORCE) { $gameRules->flashMessages[] = "Rebel Player Turn"; $gameRules->replacementsAvail = 1; } if ($attackingId == LOYALIST_FORCE) { $gameRules->flashMessages[] = "Loyalist Player Turn"; $gameRules->replacementsAvail = 10; } /*only get special VPs' at end of first Movement Phase */ $this->victoryPoints = $vp; }
function updateMoveStatus($hexagon, $moveAmount) { $battle = Battle::getBattle(); $gameRules = $battle->gameRules; /* @var MapData $mapData */ $mapData = $battle->mapData; $attackingForceId = $battle->force->attackingForceId; // $mapData = MapData::getInstance(); /* @var MapHex $mapHex */ $fromHex = $this->hexagon->getName(); $toHex = $hexagon->getName(); $mapHex = $mapData->getHex($this->hexagon->getName()); if ($mapHex) { $mapHex->unsetUnit($this->forceId, $this->id); } $this->hexagon = $hexagon; $this->dirty = true; $mapData->breadcrumbMove($this->id, $attackingForceId, $gameRules->turn, $gameRules->phase, $gameRules->mode, $fromHex, $toHex); $mapHex = $mapData->getHex($this->hexagon->getName()); if ($mapHex) { $mapHex->setUnit($this->forceId, $this); $mapHexName = $mapHex->name; if (isset($mapData->specialHexes->{$mapHexName})) { if ($mapData->specialHexes->{$mapHexName} >= 0 && $mapData->specialHexes->{$mapHexName} != $this->forceId) { $victory = $battle->victory; $mapData->specialHexesChanges->{$mapHexName} = true; $victory->specialHexChange($mapHexName, $this->forceId); $mapData->alterSpecialHex($mapHexName, $this->forceId); } } if ($mapData->getMapSymbols($mapHexName) !== false) { $victory = $battle->victory; $victory->enterMapSymbol($mapHexName, $this); } } $this->moveCount++; $this->moveAmountUsed = $this->moveAmountUsed + $moveAmount; }