u6 battle engine code research
尚未解讀完成<?php
//計算戰鬥函數
//參數:攻擊方艦隊資料(陣列),防禦方船艦和防禦資料(陣列),艦隊變渣機率(數字:30),防禦變渣機率(數字:0)
function calculateAttack(&$attackers, &$defenders, $FleetTF, $DefTF)
{
//全域變數:船艦和防禦造價,船艦和防禦戰鬥參數,資料表欄位
global $pricelist, $CombatCaps, $resource;
$TRES = array('attacker' => 0, 'defender' => 0);
//攻擊方廢墟
$ARES = array('metal' => 0, 'crystal' => 0);
//防禦方廢墟
$DRES = array('metal' => 0, 'crystal' => 0);
//儲存每回合戰鬥結果的陣列
$ROUND = array();
//船艦和防禦的快速射擊
$RF = array();
//攻擊方資料循環
foreach ($attackers as $fleetID => $attacker)
{
//攻擊方艦隊資料循環,key:船艦編號,vaule:船艦數量
foreach ($attacker['unit'] as $element => $amount)
{
$ARES['metal'] += $pricelist[$element]['cost'] * $amount;
$ARES['crystal'] += $pricelist[$element]['cost'] * $amount;
}
}
//循環戰鬥資料陣列
/* $e=擁有速射船艦或防禦的編號
$t=被快速射擊的船艦防禦編號
$sd=速射值 */
foreach($CombatCaps as $e => $arr) {
//若船艦或防禦沒有速射則跳過
if(!isset($arr['sd'])) continue;
//找出快速射擊資料並放到變數裡
foreach($arr['sd'] as $t => $sd) {
//若船艦或防禦沒有速射則跳過
if($sd == 0) continue;
$RF[$t][$e] = $sd;
}
}
$TRES['attacker'] = $ARES['metal'] * 0.25 + $ARES['crystal'] * 0.5;
foreach ($defenders as $fleetID => $defender)
{
foreach ($defender['unit'] as $element => $amount)
{
if ($element < 300) {
$DRES['metal'] += $pricelist[$element]['cost'] * $amount;
$DRES['crystal'] += $pricelist[$element]['cost'] * $amount ;
$TRES['defender'] += $pricelist[$element]['cost'] * 0.25 * $amount;
$TRES['defender'] += $pricelist[$element]['cost'] * 0.5 * $amount;
} else {
if (!isset($STARTDEF[$element]))
$STARTDEF[$element] = 0;
$STARTDEF[$element] += $amount;
$TRES['defender'] += $pricelist[$element]['cost'] * 0.25 * $amount;
$TRES['defender'] += $pricelist[$element]['cost'] * 0.5 * $amount;
}
}
}
//開始戰鬥回合循環(預設為6回合)
for ($ROUNDC = 0; $ROUNDC <= MAX_ATTACK_ROUNDS; $ROUNDC++)
{
//攻擊方傷害值
$attackDamage= array('total' => 0);
//攻擊方護盾值
$attackShield= array('total' => 0);
//攻擊方船艦數量
$attackAmount= array('total' => 0);
//防禦方傷害值
$defenseDamage = array('total' => 0);
//防禦方護盾值
$defenseShield = array('total' => 0);
//防禦方船艦或防禦數量
$defenseAmount = array('total' => 0);
//
$attArray = array();
$defArray = array();
foreach ($attackers as $fleetID => $attacker) {
$attackDamage[$fleetID] = 0;
$attackShield[$fleetID] = 0;
$attackAmount[$fleetID] = 0;
$attTech = (1 + (0.1 * $attacker['player']['military_tech']) + $attacker['player']['factor']['Attack']); //attaque
$defTech = (1 + (0.1 * $attacker['player']['defence_tech']) + $attacker['player']['factor']['Defensive']); //bouclier
$shieldTech = (1 + (0.1 * $attacker['player']['shield_tech']) + $attacker['player']['factor']['Shield']); //coque
$attackers[$fleetID]['techs'] = array($attTech, $defTech, $shieldTech);
foreach ($attacker['unit'] as $element => $amount) {
$thisAtt = $amount * ($CombatCaps[$element]['attack']) * $attTech * (rand(80, 120) / 100); //attaque
$thisDef = $amount * ($CombatCaps[$element]['shield']) * $defTech ; //bouclier
$thisShield = $amount * ($pricelist[$element]['cost'] + $pricelist[$element]['cost']) / 10 * $shieldTech; //coque
$attArray[$fleetID][$element] = array('def' => $thisDef, 'shield' => $thisShield, 'att' => $thisAtt);
$attackDamage[$fleetID] += $thisAtt;
$attackDamage['total'] += $thisAtt;
$attackShield[$fleetID] += $thisDef;
$attackShield['total'] += $thisDef;
$attackAmount[$fleetID] += $amount;
$attackAmount['total'] += $amount;
}
}
foreach ($defenders as $fleetID => $defender) {
$defenseDamage[$fleetID] = 0;
$defenseShield[$fleetID] = 0;
$defenseAmount[$fleetID] = 0;
$attTech = (1 + (0.1 * $defender['player']['military_tech']) + $defender['player']['factor']['Attack']); //attaquue
$defTech = (1 + (0.1 * $defender['player']['defence_tech']) + $defender['player']['factor']['Defensive']); //bouclier
$shieldTech = (1 + (0.1 * $defender['player']['shield_tech']) + $defender['player']['factor']['Shield']); //coque
$defenders[$fleetID]['techs'] = array($attTech, $defTech, $shieldTech);
foreach ($defender['unit'] as $element => $amount) {
$thisAtt = $amount * ($CombatCaps[$element]['attack']) * $attTech * (rand(80, 120) / 100); //attaque
$thisDef = $amount * ($CombatCaps[$element]['shield']) * $defTech ; //bouclier
$thisShield = $amount * ($pricelist[$element]['cost'] + $pricelist[$element]['cost']) / 10 * $shieldTech; //coque
if ($element == 407 || $element == 408 || $element == 409) $thisAtt = 0;
$defArray[$fleetID][$element] = array('def' => $thisDef, 'shield' => $thisShield, 'att' => $thisAtt);
$defenseDamage[$fleetID] += $thisAtt;
$defenseDamage['total'] += $thisAtt;
$defenseShield[$fleetID] += $thisDef;
$defenseShield['total'] += $thisDef;
$defenseAmount[$fleetID] += $amount;
$defenseAmount['total'] += $amount;
}
}
$ROUND[$ROUNDC] = array('attackers' => $attackers, 'defenders' => $defenders, 'attackA' => $attackAmount, 'defenseA' => $defenseAmount, 'infoA' => $attArray, 'infoD' => $defArray);
if ($ROUNDC >= MAX_ATTACK_ROUNDS || $defenseAmount['total'] <= 0 || $attackAmount['total'] <= 0) {
break;
}
// Calculate hit percentages (ACS only but ok)
$attackPct = array();
foreach ($attackAmount as $fleetID => $amount) {
if (!is_numeric($fleetID)) continue;
$attackPct[$fleetID] = $amount / $attackAmount['total'];
}
$defensePct = array();
foreach ($defenseAmount as $fleetID => $amount) {
if (!is_numeric($fleetID)) continue;
$defensePct[$fleetID] = $amount / $defenseAmount['total'];
}
// CALCUL DES PERTES !!!
$attacker_n = array();
$attacker_shield = 0;
$defenderAttack = 0;
foreach ($attackers as $fleetID => $attacker) {
$attacker_n[$fleetID] = array();
foreach($attacker['unit'] as $element => $amount) {
if ($amount <= 0) {
$attacker_n[$fleetID][$element] = 0;
continue;
}
$defender_moc = $amount * ($defenseDamage['total'] * $attackPct[$fleetID]) / $attackAmount[$fleetID];
if(isset($RF[$element])) {
foreach($RF[$element] as $shooter => $shots) {
foreach($defArray as $fID => $rfdef) {
if(empty($rfdef[$shooter]['att']) || $attackAmount[$fleetID] <= 0) continue;
$defender_moc += $rfdef[$shooter]['att'] * $shots / ($amount / $attackAmount[$fleetID] * $attackPct[$fleetID]);
$defenseAmount['total'] += $defenders[$fID]['unit'][$shooter] * $shots;
}
}
}
$defenderAttack += $defender_moc;
if (($attArray[$fleetID][$element]['def'] / $amount) >= $defender_moc) {
$attacker_n[$fleetID][$element] = round($amount);
$attacker_shield += $defender_moc;
continue;
}
$max_removePoints = floor($amount * $defenseAmount['total'] / $attackAmount[$fleetID] * $attackPct[$fleetID]);
$attacker_shield += min($attArray[$fleetID][$element]['def'], $defender_moc);
$defender_moc -= min($attArray[$fleetID][$element]['def'], $defender_moc);
$ile_removePoints = max(min($max_removePoints, $amount * min($defender_moc / $attArray[$fleetID][$element]['shield'] * (rand(0, 200) / 100), 1)), 0);
$attacker_n[$fleetID][$element] = max(ceil($amount - $ile_removePoints), 0);
}
}
$defender_n = array();
$defender_shield = 0;
$attackerAttack = 0;
foreach ($defenders as $fleetID => $defender) {
$defender_n[$fleetID] = array();
foreach($defender['unit'] as $element => $amount) {
if ($amount <= 0) {
$defender_n[$fleetID][$element] = 0;
continue;
}
$attacker_moc = $amount * ($attackDamage['total'] * $defensePct[$fleetID]) / $defenseAmount[$fleetID];
if (isset($RF[$element])) {
foreach($RF[$element] as $shooter => $shots) {
foreach($attArray as $fID => $rfatt) {
if (empty($rfatt[$shooter]['att']) || $defenseAmount[$fleetID] <= 0 ) continue;
$attacker_moc += $rfatt[$shooter]['att'] * $shots / ($amount / $defenseAmount[$fleetID] * $defensePct[$fleetID]);
$attackAmount['total'] += $attackers[$fID]['unit'][$shooter] * $shots;
}
}
}
$attackerAttack += $attacker_moc;
if (($defArray[$fleetID][$element]['def'] / $amount) >= $attacker_moc) {
$defender_n[$fleetID][$element] = round($amount);
$defender_shield += $attacker_moc;
continue;
}
$max_removePoints = floor($amount * $attackAmount['total'] / $defenseAmount[$fleetID] * $defensePct[$fleetID]);
$defender_shield += min($defArray[$fleetID][$element]['def'], $attacker_moc);
$attacker_moc -= min($defArray[$fleetID][$element]['def'], $attacker_moc);
$ile_removePoints = max(min($max_removePoints, $amount * min($attacker_moc / $defArray[$fleetID][$element]['shield'] * (rand(0, 200) / 100), 1)), 0);
$defender_n[$fleetID][$element] = max(ceil($amount - $ile_removePoints), 0);
}
}
$ROUND[$ROUNDC]['attack'] = $attackerAttack;
$ROUND[$ROUNDC]['defense'] = $defenderAttack;
$ROUND[$ROUNDC]['attackShield'] = $attacker_shield;
$ROUND[$ROUNDC]['defShield'] = $defender_shield;
foreach ($attackers as $fleetID => $attacker) {
$attackers[$fleetID]['unit'] = array_map('round', $attacker_n[$fleetID]);
}
foreach ($defenders as $fleetID => $defender) {
$defenders[$fleetID]['unit'] = array_map('round', $defender_n[$fleetID]);
}
}
if ($attackAmount['total'] <= 0 && $defenseAmount['total'] > 0) {
$won = "r"; // defender
} elseif ($attackAmount['total'] > 0 && $defenseAmount['total'] <= 0) {
$won = "a"; // attacker
} else {
$won = "w"; // draw
}
// CDR
foreach ($attackers as $fleetID => $attacker) { // flotte attaquant en CDR
foreach ($attacker['unit'] as $element => $amount) {
$TRES['attacker'] -= $pricelist[$element]['cost'] * 0.25 * $amount ;
$TRES['attacker'] -= $pricelist[$element]['cost'] * 0.5 * $amount ;
$ARES['metal'] -= $pricelist[$element]['cost'] * $amount ;
$ARES['crystal'] -= $pricelist[$element]['cost'] * $amount ;
}
}
$DRESDefs = array('metal' => 0, 'crystal' => 0);
foreach ($defenders as $fleetID => $defender) {
foreach ($defender['unit'] as $element => $amount) {
if ($element < 300) { // flotte defenseur en CDR
$DRES['metal'] -= $pricelist[$element]['cost'] * $amount ;
$DRES['crystal'] -= $pricelist[$element]['cost'] * $amount ;
$TRES['defender'] -= $pricelist[$element]['cost'] * 0.25 * $amount ;
$TRES['defender'] -= $pricelist[$element]['cost'] * 0.5 * $amount ;
} else { // defs defenseur en CDR + reconstruction
$TRES['defender'] -= $pricelist[$element]['cost'] * 0.25 * $amount ;
$TRES['defender'] -= $pricelist[$element]['cost'] * 0.5 * $amount ;
$lost = $STARTDEF[$element] - $amount;
$giveback = round($lost * (rand(72, 84) / 100));
$defenders[$fleetID]['unit'][$element] += $giveback;
$DRESDefs['metal'] += $pricelist[$element]['cost'] * ($lost - $giveback) ;
$DRESDefs['crystal'] += $pricelist[$element]['cost'] * ($lost - $giveback) ;
}
}
}
$ARES['metal'] = max($ARES['metal'], 0);
$ARES['crystal'] = max($ARES['crystal'], 0);
$DRES['metal'] = max($DRES['metal'], 0);
$DRES['crystal'] = max($DRES['crystal'], 0);
$TRES['attacker'] = max($TRES['attacker'], 0);
$TRES['defender'] = max($TRES['defender'], 0);
$totalLost = array('attacker' => $TRES['attacker'], 'defender' => $TRES['defender']);
$debAttMet = ($ARES['metal'] * ($FleetTF / 100));
$debAttCry = ($ARES['crystal'] * ($FleetTF / 100));
$debDefMet = ($DRES['metal'] * ($FleetTF / 100)) + ($DRESDefs['metal'] * ($DefTF / 100));
$debDefCry = ($DRES['crystal'] * ($FleetTF / 100)) + ($DRESDefs['crystal'] * ($DefTF / 100));
return array('won' => $won, 'debris' => array('attacker' => array(901 => $debAttMet, 902 => $debAttCry), 'defender' => array(901 => $debDefMet, 902 => $debDefCry)), 'rw' => $ROUND, 'unitLost' => $totalLost);
}
戰鬥模擬器有將速射計算在內嗎?
Dexterclub 發表於 2016-8-16 10:10 AM
戰鬥模擬器有將速射計算在內嗎?
戰鬥模擬器的資料傳入戰鬥引擎後
就會開始進行戰鬥計算
也就是說
戰鬥模擬器跟實際戰鬥
都是用同一個檔案(戰鬥引擎)
戰鬥引擎裡面有包含速射
那麼模擬結果自然會包含速射
....
require_once('includes/classes/missions/calculateAttack.php');
require_once('includes/classes/missions/calculateSteal.php');
require_once('includes/classes/missions/GenerateReport.php');
$combatResult = calculateAttack($attackers, $defenders, Config::get('Fleet_Cdr'), Config::get('Defs_Cdr'));
a950216t 發表於 2016-8-15 07:08 PM
戰鬥模擬器的資料傳入戰鬥引擎後
就會開始進行戰鬥計算
原來有包含速射啊
原先以為實際戰鬥結果 跟 戰鬥模擬器的模擬結果 差距過大 是因為沒計算速射
看來我錯了
那速射效果有一種情形是 兩軍交戰低階砲灰的數量太少的那一方低階砲灰爆炸後 速射的連環效應還沒結束 會拖累高階戰艦or防禦設施一起爆炸
不知道這種情形 戰鬥模擬器有沒有計算在內?
Dexterclub 發表於 2016-8-16 11:22 AM
原來有包含速射啊
原先以為實際戰鬥結果 跟 戰鬥模擬器的模擬結果 差距過大 是因為沒計算速射
看來我錯了 ...
魔鬼藏在細節之中
上面那段代碼
包含了所有答案
那段就是戰鬥的關鍵
不懂沒關係
之後會逐行解釋
並做個總結
再不懂就畫圖說明
遊戲的關鍵點
遲早會被破解
战斗这块真是核心中的核心,目前U6的模拟器和实际战斗结果不一样 lindaren 發表於 2016-8-17 04:55 PM
战斗这块真是核心中的核心,目前U6的模拟器和实际战斗结果不一样
探险机制都已经通了这个战斗计算其实不远了
系统如何运作的?
其实很简单
首先要有数据,数据是最重要的
攻击方船舰种类和数量,科技加成,事务官加成,商店加成
防御方船舰/防御种类和数量,科技加成,事务官加成,商店加成
然后就是一连串的计算后 产生结果
頁:
[1]