function skirmish($aforce, $dforce) { global $t, $options, $submerged; //conduct opening fire step $ofsaresolved = false; $ofsdresolved = false; $killsfireback = false; $air_a = false; $air_d = false; $avals = array('totalhits' => 0); $dvals = array('totalhits' => 0); $alost = array(); $dlost = array(); if ($options['seabattle']) { //if sea battle: if (has_sub($aforce)) { $avals['ofs'] = subattack($aforce, 'attack'); } //handle attack subs if (has_sub($dforce)) { $dvals['ofs'] = subattack($dforce, 'defend'); } } else { if ($t == 1 && ($_REQUEST['ruleset'] == 'Classic' || $_REQUEST['ruleset'] == 'Revised')) { //check for other opening fire //the amphibious assault casualties for AA50 and AA1942 are moved into the regular take casualities section if (has_land($aforce) && can_bombard($aforce)) { //Amphibious assault #debug ('Bombarding'); $avals['ofs'] = bombard($aforce); if (isset($aforce['Bat'])) { $submerged['att']['Bat'] = $aforce['Bat']; unset($aforce['Bat']); } if (isset($aforce['Des'])) { $submerged['att']['Des'] = $aforce['Des']; unset($aforce['Des']); } } } } if ($t == 1) { if (aa_present() && has_air($aforce)) { $dvals['ofs'] = aa_fire($aforce); } } if (isset($avals['ofs'])) { $ofsd_triaged = triage($dforce, $avals['ofs'], $dlost, 'def'); //determine what the casualties will be from OFS for each side: $dlost = $ofsd_triaged['lost']; $avals['totalhits'] += $avals['ofs']['hits']; if (!$options['seabattle'] or $options['seabattle'] && !isset($dforce['Des'])) { //resolve casualties if OFS victims are not saved by destroyers $dforce = $ofsd_triaged['force']; $ofsdresolved = true; } } //lather, rinse, repeat for defender. if (isset($dvals['ofs'])) { //triage attacking casualties from OFS $ofsa_triaged = triage($aforce, $dvals['ofs'], $alost, 'att'); $alost = $ofsa_triaged['lost']; $dvals['totalhits'] += $dvals['ofs']['hits']; if (!$options['seabattle'] or $options['seabattle'] && (!isset($aforce['Des']) && $_REQUEST['ruleset'] !== 'Europe')) { #take hits right away $aforce = $ofsa_triaged['force']; $ofsaresolved = true; } } // for all but sub sneak attacks vs a force with DDs and AA50/AA1942 bombardment, OFS casualties already taken. //for AA50 and AA1942, taking casualties from bombardment - if it is round 1 if ($t == 1 && ($_REQUEST['ruleset'] == 'AA50' || $_REQUEST['ruleset'] == 'AA1942')) { if (has_land($aforce) && can_bombard($aforce)) { //Amphibious assault attacker has to have land units //bombards can hit air units now in the AA50 and AA1942 editions. #debug ('Bombarding'); $killsfireback = true; $avals['ofs'] = bombard($aforce); #print_r ($avals['ofs']); $avals['totalhits'] += $avals['ofs']['hits']; if (isset($aforce['Bat'])) { $submerged['att']['Bat'] = $aforce['Bat']; unset($aforce['Bat']); } if (isset($aforce['Cru'])) { $submerged['att']['Cru'] = $aforce['Cru']; unset($aforce['Cru']); } } } //if AA50/AA1942 AND attacker has air, but no destroyer, and defender has subs, then //find hits scored by air (so their hits can be applied to subs or not with DD interaction) $air_a = false; //reset boolean flags that keep track if air have already fired in this round of combat $air_d = false; if ($_REQUEST['ruleset'] == 'AA50' or $_REQUEST['ruleset'] == 'AA1942') { if (has_air($aforce) && !isset($aforce['Des']) && has_sub($dforce)) { //if there are nonsubs in the defenders, then roll for attacking air units if (nonsubs($dforce)) { $avals['norm'] = airattack($aforce, 'attack'); $avals['totalhits'] += $avals['norm']['hits']; //store result from airattack function in a temp array to be merged with the takeshots results later $airavals = $avals; } //set boolean flag to indicate air have fired in this round already $air_a = true; } if (has_air($dforce) && !isset($dforce['Des']) && has_sub($aforce)) { //if there are nonsubs in the attackers, then roll for defending air units if (nonsubs($aforce)) { $dvals['norm'] = airattack($dforce, 'defend'); $dvals['totalhits'] += $dvals['norm']['hits']; //store result from airattack function in a temp array to be merged with the takeshots results later $airdvals = $dvals; } //set boolean flag to indicate air have fired in this round already $air_d = true; } } //find number of hits scored by all regular remaining units if (nonsubs($aforce)) { $avals['norm'] = takeshots($aforce, 'attack', $air_a); //pass tracking flag if air has already fired $avals['totalhits'] += $avals['norm']['hits']; } if (nonsubs($dforce) or $options['AA']) { $dvals['norm'] = takeshots($dforce, 'defend', $air_d); //pass tracking flag if air has already fired $dvals['totalhits'] += $dvals['norm']['hits']; } //Having allowed the counterattack for sub victims saved by destroyers, now take them off before other casualties are taken if (isset($ofsa_triaged) && !$ofsaresolved) { $aforce = $ofsa_triaged['force']; } if (isset($ofsd_triaged) && !$ofsdresolved) { $dforce = $ofsd_triaged['force']; } //triage casualties from bombardment for AA50 and AA1942, so use all other OFS hits besides subs if ($_REQUEST['ruleset'] == 'AA50' || $_REQUEST['ruleset'] == 'AA1942') { if (nonsubs($aforce) && nonsubs($dforce) && $killsfireback) { if (isset($avals['ofs'])) { $d_triaged = triage($dforce, $avals['ofs'], $dlost, 'def'); $dforce = $d_triaged['force']; $dlost = $d_triaged['lost']; } } } //Now triagecasualties from air attack //determine air casualties for defender if ($air_a && isset($airavals['norm'])) { $aird_triaged = triage($dforce, $airavals['norm'], $dlost, 'def'); //determine defender's casualties from air attack $dforce = $aird_triaged['force']; $dlost = $aird_triaged['lost']; } //determine air casualties for attacker if ($air_d && isset($airdvals['norm'])) { $aira_triaged = triage($aforce, $airdvals['norm'], $alost, 'att'); //determine attacker's casualties from air attack $aforce = $aira_triaged['force']; $alost = $aira_triaged['lost']; } //Now, triage all other casualties if (isset($avals['norm'])) { $d_triaged = triage($dforce, $avals['norm'], $dlost, 'def'); $dforce = $d_triaged['force']; $dlost = $d_triaged['lost']; } if (isset($dvals['norm'])) { $a_triaged = triage($aforce, $dvals['norm'], $alost, 'att'); $aforce = $a_triaged['force']; $alost = $a_triaged['lost']; } //merge the attacker airvals and vals arrays into one so dice get displayed correctly. if ($air_a && isset($airavals['norm'])) { $avals["totalhits"] += $airavals["totalhits"]; $avals["norm"]["hits"] += $airavals["norm"]["hits"]; $avals["norm"]["punch"] += $airavals["norm"]["punch"]; $avals["norm"]["dice"]["rolled"] += $airavals["norm"]["dice"]["rolled"]; //ADD dice rolls at 1 3 4 5 (possible dice rolls for air units) //may not need dice rolls at 2 or 6 until air is listed to hit at 2 or 6. $index = array(1, 3, 4, 5); foreach ($index as $v) { if (array_key_exists($v, $airavals["norm"]["dice"]) && array_key_exists($v, $avals["norm"]["dice"])) { $avals["norm"]["dice"][$v] = array_merge($airavals["norm"]["dice"][$v], $avals["norm"]["dice"][$v]); } elseif (array_key_exists($v, $airavals["norm"]["dice"])) { $avals["norm"]["dice"][$v] = $airavals["norm"]["dice"][$v]; } } ksort($avals["norm"]["dice"]); } //merge the defender airvals and vals arrays into one so dice get displayed correctly. if ($air_d && isset($airdvals['norm'])) { $dvals["totalhits"] += $airdvals["totalhits"]; $dvals["norm"]["hits"] += $airdvals["norm"]["hits"]; $dvals["norm"]["punch"] += $airdvals["norm"]["punch"]; $dvals["norm"]["dice"]["rolled"] += $airdvals["norm"]["dice"]["rolled"]; //ADD dice rolls at 1 3 4 5 (possible dice rolls for air units) //may not need dice rolls at 2 or 6 until air is listed to hit at 2 or 6. $index = array(1, 3, 4, 5); foreach ($index as $v) { if (array_key_exists($v, $airdvals["norm"]["dice"]) && array_key_exists($v, $dvals["norm"]["dice"])) { $dvals["norm"]["dice"][$v] = array_merge($airdvals["norm"]["dice"][$v], $dvals["norm"]["dice"][$v]); } elseif (array_key_exists($v, $airdvals["norm"]["dice"])) { $dvals["norm"]["dice"][$v] = $airdvals["norm"]["dice"][$v]; } } ksort($dvals["norm"]["dice"]); } return array('att' => array('force' => $aforce, 'lost' => $alost, 'vals' => $avals), 'def' => array('force' => $dforce, 'lost' => $dlost, 'vals' => $dvals)); }
function getformdata($posted) { global $options, $canhit, $rounds, $sides, $ool, $baseool, $mustland, $round, $abortratio, $unitspecs; $customOOL = array(); $valid = true; $options['tech'] = (isset($_REQUEST['toggletechs']) && $_REQUEST['toggletechs'] == "Enable techs" or isset($_REQUEST['techs']) && (!isset($_REQUEST['toggletechs']) or $_REQUEST['toggletechs'] !== 'Disable techs')); #debugarray ($options); if ($options['tech']) { $units = allunits(); } else { $units = notechunits(); } /* DO NOT NEED IF NOT STORING GAMES ANYMORE? #validate gameid: #$gameid=$_REQUEST['gameid']; if ($gameid!=='') { #$gameid=intval($gameid); #if (strval($gameid)!==$_REQUEST['gameid']) { # echo 'No non-numeric characters permitted in Game ID #<p>'; # $gameid=''; #} else $options['gameidok']=false; if (!file_exists('makegame/games/'.$gameid.'.php')) { echo "No record exists for game ID # $gameid.<p>"; $gameid=''; } else if ($_REQUEST['territory']=='' or $_REQUEST['turnid']=='') { echo "<div style=\"color: red\"><b>Error:</b> You must specify a territory and a Turn ID for the game record.</div>"; $_REQUEST['pbem']=''; } else { #Game ID is valid and file exists include ('makegame/games/'.$gameid.'.php'); if ($_REQUEST['password']==$data['password']) { $_REQUEST['ruleset']=$data['ruleset']; $_REQUEST['luck']=$data['luck']; if (isset ($_REQUEST['pbem']) && strlen($_REQUEST['pbem']) > 6 ) { # User has entered a game id but also entered e-mail addresses $_REQUEST['pbem']=str_replace (array($data['player1'],$data['player2']), '', $_REQUEST['pbem']).' '.$data['player1'].' '.$data['player2']; #Previous line strips out the e-mail addresses from the pbem field that are already saved in game ID. } else { $_REQUEST['pbem']=$data['player1'].' '.$data['player2']; # This line preloads the saved e-mail addresses. } $_REQUEST['reps']=1; $_REQUEST['gameid']=$gameid; $turnid=$_REQUEST['turnid']; $options['gameidok']=true; } else { echo "The password provided did not match.<p>"; $_REQUEST['gameid']=''; } } } */ /* OLD OPTIONS FOR OTHER RULESETS...SHOULD BE PUT IN THE UPDATEUNITS FUNCTION IF WE WANT BACK IN if (isset($_REQUEST['ruleset'])) { if ($_REQUEST['ruleset'] == 'LHTR' ) { #$unitspecs['HBom']['attack']=5.33; $unitspecs['SSub']['defend']=3; $unitspecs['HBom']['attackdice']=1; if ($_REQUEST['luck']!=='pure') $unitspecs['HBom']['attack']=5.33; #debug ($_REQUEST['luck']); } if ($_REQUEST['ruleset'] == 'Europe' ) { $unitspecs['Fig']['cost']=12; $unitspecs['Arm']['defend']=2; $unitspecs['Car']['cost']=18; } }*/ if (isset($_REQUEST['round'])) { $round = intval($_REQUEST['round']); } foreach ($sides as $side => $name) { $string = trim($_REQUEST['ool_' . $side]); $string = str_replace(' ', '-', $string); $replacechars = array(' ', ' ', ',', '.', '<', '>', '?', '/', '\\', '!'); $string = str_replace($replacechars, '', $string); $array = explode('-', $string); //find if any elements are missing or changed names foreach ($baseool as $type) { if (!in_array($type, $array)) { $valid = false; } } //find if number of elements is the the same if (count($array) !== count($baseool)) { $valid = false; } $customOOL[$side] = $array; } if ($valid) { $ool = $customOOL; $warned = false; foreach ($sides as $side => $name) { //prevent battleships being killed first if Classic ruleset used and Bat's listed first in OOL if ($_REQUEST['ruleset'] == 'Classic' && $ool[$side][0] == 'Bat') { #debug ("Saving $side's battleships!"); if (!$warned) { echo "<b>Notice:</b> OOL adjusted to prevent battleships being killed first."; } $warned = true; } $string = implode('-', $ool[$side]); #setcookie ('ool_'.$side, $string, +31536000); } } else { echo "<p><strong>Error</strong> - elements in the custom Order of Loss should be separated only by dashes.\n\t\t\tThe elements themselves should not be edited, deleted or added to.</p>"; } $mustland = 0; if (isset($_REQUEST['mustland']) && $_REQUEST['mustland'] !== '' && !isset($_REQUEST['Clear'])) { $_REQUEST['mustland'] = intval($_REQUEST['mustland']); $mustland = $_REQUEST['mustland']; } $abortratio = intval($_REQUEST['abortratio']); if ($abortratio > 1000 or $abortratio < 1) { $abortratio = 0; } $options['legal'] = false; $_REQUEST['reps'] = intval($_REQUEST['reps']); $options['AA'] = (isset($_REQUEST['AA']) or isset($_REQUEST['AAr'])); $_REQUEST['pbem'] = str_replace(array(',', ';'), ' ', $_REQUEST['pbem']); $_REQUEST['pbem'] = explode(' ', $_REQUEST['pbem']); foreach ($_REQUEST['pbem'] as $key => $val) { if (!valid_email($val)) { unset($_REQUEST['pbem'][$key]); } } if ($_REQUEST['reps'] > 1 && ($_REQUEST['luck'] == 'none' or $_REQUEST['battle'] == 'Evaluate units')) { echo '<p><strong>Note:</strong> in No Luck mode or Evaluate Units mode, every battle turns out the same (so not much point running it 1000x). Battle has only been run once.</p>'; $_REQUEST['reps'] = 1; } foreach ($posted as $key => $value) { if ((!isset($value) or $value == '') && $key !== 'rounds') { $posted[$key] = 0; } else { $posted[$key] = intval($value); } } $forces = array('att' => array(), 'def' => array()); foreach ($units as $type) { if ($posted['a' . $type] > 0) { $forces['att'][$type] = $posted['a' . $type]; } if ($posted['d' . $type] > 0) { $forces['def'][$type] = $posted['d' . $type]; } } //check that both sides have units: $options['nounits'] = count($forces['att']) == 0 && count($forces['def']) == 0; if (!$options['nounits']) { //seabattle boolean conditions. check if seabattle or not. $options['seabattle'] = (has_sea($forces['def']) or has_sea($forces['att'])) && !has_land($forces['att']) && !has_land($forces['def']) && !isset($forces['def']['Bom']) && !isset($forces['def']['HBom']); //landbattle boolean must also be set to true if a shore bombardment is possible $options['landbattle'] = (has_land($forces['def']) or has_land($forces['att']) or has_air($forces['def']) or has_air($forces['att'])); if (isset($forces['att']['Bat'])) { $options['landbattle'] = $options['landbattle'] && has_land($forces['att']); } //if AA50 or AA1942, add Des as invalid attacker and Cru as valid attacker into landbattle option if ($_REQUEST['ruleset'] == 'AA50' || $_REQUEST['ruleset'] == 'AA1942') { if (isset($forces['att']['Cru'])) { $options['landbattle'] = $options['landbattle'] && has_land($forces['att']); } $options['landbattle'] = $options['landbattle'] && !isset($forces['att']['Des']); } //if Revised, add Des as valid attacker into landbattle option -- No need to address Cru since it's not on Revised form if ($_REQUEST['ruleset'] == 'Revised') { if (isset($forces['att']['Des'])) { $options['landbattle'] = $options['landbattle'] && has_land($forces['att']); } } //no need to address Cru and Des in Classic either since they are not on the Classic form now //finish list of requirements for landbattle to not include any of the following $options['landbattle'] = $options['landbattle'] && !has_sea($forces['def']) && !isset($forces['att']['Tra']) && !isset($forces['att']['Sub']) && !isset($forces['att']['SSub']) && !isset($forces['att']['Car']) && !isset($forces['att']['dBat']); // check if attacker has combined standard and upgraded units of the same class: $illegalattackcomb = (isset($forces['att']['Art']) && isset($forces['att']['AArt']) or isset($forces['att']['Bom']) && isset($forces['att']['HBom']) or isset($forces['att']['Fig']) && isset($forces['att']['JFig']) or isset($forces['att']['Sub']) && isset($forces['att']['SSub'])); $options['legal'] = $options['landbattle'] + $options['seabattle'] !== 2 && $options['landbattle'] + $options['seabattle'] !== 0 && $illegalattackcomb == false; } return $forces; }
//DRAW condition where only subs vs only air are left. } elseif (has_sub($att[$t]['force']) && !nonsubs($att[$t]['force']) && has_air($def[$t]['force']) && !nonair($def[$t]['force']) or has_sub($def[$t]['force']) && !nonsubs($def[$t]['force']) && has_air($att[$t]['force']) && !nonair($att[$t]['force'])) { $draw = true; $outcome = array('att' => array('force' => $att[$t]['force'], 'lost' => array(), 'vals' => array()), 'def' => array('force' => $def[$t]['force'], 'lost' => array(), 'vals' => array())); } else { $outcome = skirmish($att[$t]['force'], $def[$t]['force']); } } else { $outcome = skirmish($att[$t]['force'], $def[$t]['force']); } //condition to void subs dice rolls for an only sub attack force vs an only air defense force. if (has_sub($att[$t]['force']) && !nonsubs($att[$t]['force']) && has_air($def[$t]['force']) && !nonair($def[$t]['force'])) { $outcome['att']['vals'] = array(); } //condition to void subs dice rolls for an only air attack force vs an only sub defense force. if (has_sub($def[$t]['force']) && !nonsubs($def[$t]['force']) && has_air($att[$t]['force']) && !nonair($att[$t]['force'])) { $outcome['def']['vals'] = array(); } $history[$t] = $outcome; $stalemate = $_REQUEST['luck'] == 'none' && $t > 0 && $outcome['att']['vals']['totalhits'] + $outcome['def']['vals']['totalhits'] == 0; $t++; $att[$t]['force'] = $outcome['att']['force']; $def[$t]['force'] = $outcome['def']['force']; $astats = assess($att[$t]['force'], 'attack'); $dstats = assess($def[$t]['force'], 'defend'); $abort = ($astats['count'] - round(($dstats['punch'] + 3) / 6) < $saveunits && $saveunits > 0 or $dstats['count'] - round(($astats['punch'] + 3) / 6) < $strafeunits && $strafeunits > 0 or $dstats['punch'] > 0 and $astats['punch'] / $dstats['punch'] * 100 < $abortratio); if (!$stalemate) { if (!has_sea($def[$t]['force']) && (!nonsubs($att[$t]['force']) or isset($_REQUEST['asubschicken'])) && has_sub($att[$t]['force'])) { $submerged['att'] = array(); if (isset($att[$t]['force']['Sub'])) { $submerged['att']['Sub'] = $att[$t]['force']['Sub'];