function unitIsInRange($id, $argRange = false) { $b = Battle::getBattle(); $isInRange = false; $range = $this->units[$id]->range; if ($argRange !== false) { $range = $argRange; } if ($range <= 1) { return false; } if ($this->ZOCrule == true) { $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; }
function rangeIsOneHexagon($startHexagon, $endHexagon) { $rangeIsOne = false; $los = new Los(); $los->setOrigin($startHexagon); $los->setEndPoint($endHexagon); if ($los->getRange() == 1) { $rangeIsOne = true; } return $rangeIsOne; }
public function setCombatIndex($defenderId) { $combatLog = ""; $battle = Battle::getBattle(); $scenario = $battle->scenario; $combats = $battle->combatRules->combats->{$defenderId}; if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $isCrest = $isCavalry = $isTown = $isHill = $isForest = $isSwamp = $attackerIsSunkenRoad = $isRedoubt = $isElevated = false; $combats->index = []; foreach ($defenders as $defId => $defender) { $defUnit = $battle->force->units[$defId]; $hexagon = $defUnit->hexagon; if ($defUnit->class === 'cavalry') { $isCavalry = true; } $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $isTown |= $battle->terrain->terrainIs($hexpart, 'town'); $isForest |= $battle->terrain->terrainIs($hexpart, 'forest'); if ($battle->terrain->terrainIs($hexpart, 'elevation')) { $isElevated = 1; } if ($battle->terrain->terrainIs($hexpart, 'elevation2')) { $isElevated = 2; } $defenseStrength = $defUnit->defenseStrength; } $isClear = true; if ($isTown || $isForest || $isHill || $isSwamp) { $isClear = false; } $attackers = $combats->attackers; $attackStrength = 0; $attackersCav = false; $combinedArms = array(); $combatLog .= "<br>"; foreach ($attackers as $attackerId => $attacker) { $terrainReason = ""; $unit = $battle->force->units[$attackerId]; $unitStrength = $unit->strength; $hexagon = $unit->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $los = new Los(); $los->setOrigin($battle->force->getUnitHexagon($attackerId)); $los->setEndPoint($battle->force->getUnitHexagon($defenderId)); $range = $los->getRange(); $hexParts = $los->getlosList(); $targetHex = array_pop($hexParts); $targetHexSide = array_pop($hexParts); if ($battle->terrain->terrainIs($targetHexSide, "crest")) { $isCrest = true; } $combatLog .= $unit->strength . " " . $unit->class . " = " . $unit->strength . "<br>"; if ($range == 1) { $isCloseAssault = false; if ($unit->weapons === ModernTacticalUnit::SM_WEAPONS) { if ($defenderId !== false) { $defUnit = $battle->force->units[$defenderId]; if ($defUnit->target === ModernTacticalUnit::HARD_TARGET) { $isCloseAssault = true; } } } if (!$isCloseAssault) { $unitStrength *= 2; $combatLog .= "range 1, doubled = {$unitStrength}<br>"; } else { $combatLog .= "close assult no range attenuation = {$unitStrength}<br>"; } } if ($range >= 4 && $range <= 5) { $unitStrength -= 1; $combatLog .= " -1 range attentuation = {$unitStrength}<br>"; } if ($range >= 6 && $range <= 8) { $unitStrength -= 2; $combatLog .= " -2 range attentuation = {$unitStrength}<br>"; } if ($range >= 9 && $range <= 10) { $unitStrength -= 3; $combatLog .= " -3 range attentuation = {$unitStrength}<br>"; } if ($range >= 11) { $unitStrength -= 6; $combatLog .= "-6 range attentuation = {$unitStrength}<br>"; } $attackerIsElevated = false; if ($battle->terrain->terrainIs($hexpart, 'elevation')) { $attackerIsElevated = 1; } if ($battle->terrain->terrainIs($hexpart, 'elevation2')) { $attackerIsElevated = 2; } $unitStrength -= $defenseStrength; $combatLog .= " - {$defenseStrength} defender = {$unitStrength}<br>"; if ($isForest) { $unitStrength--; $combatLog .= " in forest - 1 = <span class='fixed-width' >{$unitStrength}</span><br>"; } if ($isTown) { $unitStrength -= 2; $combatLog .= " in town - 2 = <span class='fixed-width' >{$unitStrength}</span><br>"; } if ($isCrest) { $unitStrength -= 1; $combatLog .= " in crest - 1 = <span class='fixed-width' >{$unitStrength}</span><br>"; } $combatLog .= "final = {$unitStrength}<br><br>"; $combats->index[] = $unitStrength; } $combats->combatLog = $combatLog; }
function checkBombardment($cd = false) { if ($cd === false) { $cd = $this->currentDefender; } $attackers = $this->combats->{$cd}->attackers; $defenders = $this->combats->{$cd}->defenders; foreach ($defenders as $defenderId => $defender) { foreach ($this->combats->{$cd}->attackers as $attackerId => $attacker) { $los = new Los(); $los->setOrigin($this->force->getUnitHexagon($attackerId)); $los->setEndPoint($this->force->getUnitHexagon($defenderId)); $range = $los->getRange(); if ($range == 1) { $this->combats->{$cd}->isBombardment = false; return; } } } $this->combats->{$cd}->isBombardment = true; $this->combats->{$cd}->useDetermined = false; }
function setupCombat($id, $shift = false) { $battle = Battle::getBattle(); $victory = $battle->victory; $unit = $battle->force->units[$id]; $cd = $this->currentDefender; if ($this->force->unitIsEnemy($id) == true) { if (empty($this->dayTime) && $unit->spotted === false) { return false; } // defender is already in combatRules, so make it currently selected // if(isset($this->defenders->$id)){ // $id = $this->defenders->$id; // } $combats = $combatId = false; if (isset($this->defenders->{$id})) { $combatId = $this->defenders->{$id}; $combats = $this->combats->{$combatId}; } if ($combats) { // if(count($this->combats->$this->currnetDefender->attackers) == 0){ // unset($this->currnetDefender[$id]); // } if ($this->currentDefender === false) { $this->currentDefender = $this->defenders->{$id}; } else { if ($shift) { if (isset($this->defenders->{$id})) { if ($combatId === $this->currentDefender) { foreach ($combats->attackers as $attackerId => $attacker) { $this->force->undoAttackerSetup($attackerId); unset($this->attackers->{$attackerId}); $victory->postUnsetAttacker($this->units[$attackerId]); } foreach ($combats->defenders as $defenderId => $defender) { $unit = $this->force->getUnit($defenderId); $unit->setStatus(STATUS_READY); unset($this->defenders->{$defenderId}); $victory->postUnsetDefender($unit); } unset($this->combats->{$combatId}); $this->currentDefender = false; } else { $this->currentDefender = $combatId; } } } else { if ($combatId === $this->currentDefender) { $this->currentDefender = false; } else { $this->currentDefender = $combatId; } } } } else { if ($shift) { if ($this->currentDefender !== false) { foreach ($this->combats->{$this->currentDefender}->attackers as $attackerId => $attacker) { $this->force->undoAttackerSetup($attackerId); unset($this->attackers->{$attackerId}); unset($this->combats->{$cd}->attackers->{$attackerId}); unset($this->combats->{$cd}->thetas->{$attackerId}); $victory->postUnsetAttacker($this->units[$attackerId]); } $this->defenders->{$id} = $this->currentDefender; } else { $this->currentDefender = $id; $this->defenders->{$id} = $id; } } else { $mapHex = $battle->mapData->getHex($unit->hexagon->getName()); $forces = $mapHex->getForces($unit->forceId); $this->currentDefender = $id; foreach ($forces as $force) { $this->defenders->{$force} = $id; if ($force != $id) { $cd = $this->currentDefender; $this->force->setupDefender($force); if (!$this->combats) { $this->combats = new stdClass(); } if (!$this->combats->{$cd}) { $this->combats->{$cd} = new Combat(); } $this->combats->{$cd}->defenders->{$force} = $id; } } } $cd = $this->currentDefender; // $this->defenders->{$this->currentDefender} = $id; $this->force->setupDefender($id); if (!$this->combats) { $this->combats = new stdClass(); } if (empty($this->combats->{$cd})) { $this->combats->{$cd} = new Combat(); } $this->combats->{$cd}->defenders->{$id} = $id; // $victory->postSetDefender($this->force->units[$id]); } } else { if ($this->currentDefender !== false && $this->force->units[$id]->status != STATUS_UNAVAIL_THIS_PHASE) { if (isset($this->combats->{$cd}->attackers->{$id}) && $this->combats->{$cd}->attackers->{$id} !== false && $this->attackers->{$id} === $cd) { $this->force->undoAttackerSetup($id); unset($this->attackers->{$id}); unset($this->combats->{$cd}->attackers->{$id}); unset($this->combats->{$cd}->thetas->{$id}); $victory->postUnsetAttacker($this->force->units[$id]); $this->crt->setCombatIndex($cd); } else { $good = true; foreach ($this->combats->{$this->currentDefender}->defenders as $defenderId => $defender) { $los = new Los(); $los->setOrigin($this->force->getUnitHexagon($id)); $los->setEndPoint($this->force->getUnitHexagon($defenderId)); $range = $los->getRange(); $unitRange = $unit->getRange($id) * 2; if ($battle->gameRules->phase == BLUE_TORP_COMBAT_PHASE || $battle->gameRules->phase == RED_TORP_COMBAT_PHASE) { $unitRange = $unit->getRange($id) * 3; } if ($range > $unitRange) { $good = false; break; } if ($range >= 1) { $good = $this->checkBlocked($los, $id); } } if ($good) { foreach ($this->combats->{$this->currentDefender}->defenders as $defenderId => $defender) { $los = new Los(); $los->setOrigin($this->force->getUnitHexagon($id)); $los->setEndPoint($this->force->getUnitHexagon($defenderId)); $range = $los->getRange(); $bearing = $los->getBearing(); if ($range <= $unitRange) { $this->force->setupAttacker($id, $range); if (isset($this->attackers->{$id}) && $this->attackers->{$id} !== $cd) { /* move unit to other attack */ $oldCd = $this->attackers->{$id}; unset($this->combats->{$oldCd}->attackers->{$id}); unset($this->combats->{$oldCd}->thetas->{$id}); $this->crt->setCombatIndex($oldCd); $this->checkBombardment($oldCd); } $this->attackers->{$id} = $cd; $this->combats->{$cd}->attackers->{$id} = $bearing; $this->combats->{$cd}->defenders->{$defenderId} = $bearing; if (empty($this->combats->{$cd}->thetas->{$id})) { $this->combats->{$cd}->thetas->{$id} = new stdClass(); } $this->combats->{$cd}->thetas->{$id}->{$defenderId} = $bearing; $victory->postSetDefender($this->force->units[$defenderId]); $this->crt->setCombatIndex($cd); } } $victory->postSetAttacker($this->force->units[$id]); } } $this->checkBombardment(); } } $this->cleanUpAttacklessDefenders(); }
public function setCombatIndex($defenderId) { $combatLog = ""; /* @var JagCore $battle */ $battle = Battle::getBattle(); $scenario = $battle->scenario; $combats = $battle->combatRules->combats->{$defenderId}; if (count((array) $combats->attackers) == 0) { $combats->index = null; $combats->attackStrength = null; $combats->defenseStrength = null; $combats->terrainCombatEffect = null; return; } $defenders = $combats->defenders; $isCavalry = $isTown = $isHill = $isForest = $isSwamp = $attackerIsSunkenRoad = $isRedoubt = $isElevated = false; foreach ($defenders as $defId => $defender) { $defUnit = $battle->force->units[$defId]; $hexagon = $defUnit->hexagon; if ($defUnit->class === 'cavalry') { $isCavalry = true; } $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $isTown |= $battle->terrain->terrainIs($hexpart, 'town'); $isForest |= $battle->terrain->terrainIs($hexpart, 'forest'); if ($battle->terrain->terrainIs($hexpart, 'elevation')) { $isElevated = 1; } if ($battle->terrain->terrainIs($hexpart, 'elevation2')) { $isElevated = 2; } } $isClear = true; if ($isTown || $isForest || $isHill || $isSwamp) { $isClear = false; } $attackers = $combats->attackers; $attackStrength = 0; $attackersCav = false; $combinedArms = array(); $combatLog .= "Attackers<br>"; foreach ($attackers as $attackerId => $attacker) { $terrainReason = ""; $unit = $battle->force->units[$attackerId]; $unitStrength = $unit->strength; $hexagon = $unit->hexagon; $hexpart = new Hexpart(); $hexpart->setXYwithNameAndType($hexagon->name, HEXAGON_CENTER); $los = new Los(); $los->setOrigin($battle->force->getUnitHexagon($attackerId)); $los->setEndPoint($battle->force->getUnitHexagon($defenderId)); $range = $los->getRange(); $combatLog .= $unit->strength . " " . $unit->class . " "; if ($isCavalry) { $combatLog .= "defender is cavalry, doubled "; $unitStrength *= 2; } if ($unit->class === "infantry" && $range == 1) { $combatLog .= "infantry at range 1, doubled "; $unitStrength *= 2; } if ($unit->class === "mg" && $range <= 3) { $combatLog .= "machine gun at range 3 or less, doubled "; $unitStrength *= 2; } if ($isTown || $isForest) { if ($range > 1) { $combatLog .= "using observation fire, halved "; $unitStrength /= 2; } } $attackerIsElevated = false; if ($battle->terrain->terrainIs($hexpart, 'elevation')) { $attackerIsElevated = 1; } if ($battle->terrain->terrainIs($hexpart, 'elevation2')) { $attackerIsElevated = 2; } $combatLog .= "<br>"; $attackStrength += $unitStrength; } $combatLog .= " = {$attackStrength}<br>Defenders<br>"; $defenseStrength = 0; foreach ($defenders as $defId => $defender) { $unitStrength = 2; $terrain = ''; $unit = $battle->force->units[$defId]; $class = $unit->class; $clearHex = false; $notClearHex = false; $hexagon = $unit->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'); $terran = ""; if ($attackerIsElevated < $isElevated) { $unitStrength = 4; $terrain = "uphill "; } if ($isTown) { $terrain = "in town "; $unitStrength = 8; } if ($isForest) { $terrain = "in forest "; $unitStrength = 5; } if ($unit->isImproved) { $unitStrength *= 2; $terrain .= "Improved "; } $combatLog .= "{$unitStrength} " . $unit->class . " {$terrain}"; $defenseStrength += $unitStrength; $combatLog .= "<br>"; } $combatLog .= " = {$defenseStrength}"; $combatIndex = $this->getCombatIndex($attackStrength, $defenseStrength); /* Do this before terrain effects */ if ($combatIndex >= $this->maxCombatIndex) { $combatIndex = $this->maxCombatIndex; } // $terrainCombatEffect = $battle->combatRules->getDefenderTerrainCombatEffect($defenderId); // $combatIndex -= $terrainCombatEffect; $combats->attackStrength = $attackStrength; $combats->defenseStrength = $defenseStrength; $combats->terrainCombatEffect = 0; // // if($combats->pinCRT !== false){ // $pinIndex = $combats->pinCRT; // if($combatIndex > $pinIndex){ // $combatLog .= "<br>Pinned to {$this->combatResultsHeader[$pinIndex]} "; // }else{ // $combats->pinCRT = false; // } // } $combats->index = $combatIndex; $combats->useAlt = false; $combats->combatLog = $combatLog; }
function unitIsInRange($id) { $isZOC = false; $range = $this->units[$id]->range; if ($range <= 1) { return false; } if ($this->ZOCrule == true) { $los = new Los(); $los->setOrigin($this->units[$id]->hexagon); for ($i = 0; $i < count($this->units); $i++) { $los->setEndPoint($this->units[$i]->hexagon); if ($los->getRange() <= $range && $this->units[$i]->forceId != $this->units[$id]->forceId && $this->units[$i]->status != STATUS_CAN_REINFORCE && $this->units[$i]->status != STATUS_ELIMINATED) { $isZOC = true; break; } } } return $isZOC; }
public function checkLos(\Wargame\Los $los, $defenderId = false) { $b = Battle::getBattle(); if ($this->weapons === ModernTacticalUnit::SM_WEAPONS) { if ($defenderId !== false) { $defUnit = $b->force->units[$defenderId]; if ($defUnit->target === ModernTacticalUnit::HARD_TARGET) { if ($los->getRange() > 1) { return false; } } } } return true; }
public function checkCommand($unit) { $id = $unit->id; $b = Battle::getBattle(); $cmdRange = 8; if ($b->gameRules->phase == RED_MOVE_PHASE || $b->gameRules->phase == BLUE_MOVE_PHASE) { foreach ($this->headQuarters as $hq) { if ($id == $hq) { return; } $los = new Los(); $los->setOrigin($b->force->getUnitHexagon($id)); $los->setEndPoint($b->force->getUnitHexagon($hq)); $range = $los->getRange(); if ($range <= $cmdRange) { return; } } $unit->status = STATUS_UNAVAIL_THIS_PHASE; return; } }