PageRenderTime 61ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/GameEngine/Battle.php

https://bitbucket.org/Dzoki/travianx
PHP | 836 lines | 649 code | 72 blank | 115 comment | 261 complexity | b1f426fe6803d969097f1fc765a49aa5 MD5 | raw file
  1. <?php
  2. #################################################################################
  3. ## ##
  4. ## -= YOU MUST NOT REMOVE OR CHANGE THIS NOTICE =- ##
  5. ## ##
  6. ## --------------------------------------------------------------------------- ##
  7. ## ##
  8. ## Project: ZravianX ##
  9. ## Version: 2011.11.21 ##
  10. ## Filename: GameEngine/Battle.php ##
  11. ## Developed by: Dzoki & Dixie ##
  12. ## Reworked by: Advocaite ##
  13. ## Thanks to: Akakori & Elmar ##
  14. ## Edited by: ZZJHONS ##
  15. ## License: Creative Commons BY-NC-SA 3.0 ##
  16. ## Copyright: ZravianX (c) 2011 - All rights reserved ##
  17. ## URLs: http://zravianx.zzjhons.com ##
  18. ## Source code: http://www.github.com/ZZJHONS/ZravianX ##
  19. ## ##
  20. #################################################################################
  21. class Battle {
  22. public function procSim($post) {
  23. global $form;
  24. // Recivimos el formulario y procesamos
  25. if(isset($post['a1_v']) && (isset($post['a2_v1']) || isset($post['a2_v2']) || isset($post['a2_v3']) || isset($post['a2_v4']))) {
  26. $_POST['mytribe'] = $post['a1_v'];
  27. $target = array();
  28. if(isset($post['a2_v1'])) {
  29. array_push($target,1);
  30. }
  31. if(isset($post['a2_v2'])) {
  32. array_push($target,2);
  33. }
  34. if(isset($post['a2_v3'])) {
  35. array_push($target,3);
  36. }
  37. if(isset($post['a2_v4'])) {
  38. array_push($target,4);
  39. }
  40. if(isset($post['a2_v5'])) {
  41. array_push($target,5);
  42. }
  43. $_POST['target'] = $target;
  44. if(isset($post['a1_1'])) {
  45. $sum = $sum2 = 0;
  46. for($i=1;$i<=10;$i++) {
  47. $sum += $post['a1_'.$i];
  48. }
  49. if($sum > 0) {
  50. if($post['palast'] == "") {
  51. $post['palast'] = 0;
  52. }
  53. if(isset($post['wall1']) && $post['wall1'] == "") {
  54. $post['wall1'] = 0;
  55. }
  56. if(isset($post['wall2']) && $post['wall2'] == "") {
  57. $post['wall2'] = 0;
  58. }
  59. if(isset($post['wall3']) && $post['wall3'] == "") {
  60. $post['wall3'] = 0;
  61. }if(isset($post['wall4']) && $post['wall4'] == "") {
  62. $post['wall4'] = 0;
  63. }if(isset($post['wall5']) && $post['wall5'] == "") {
  64. $post['wall5'] = 0;
  65. }
  66. ($_POST['wall1']>0? $wall1=$_POST['wall1']:($_POST['wall2']>0? $wall2=$_POST['wall2'] :($_POST['wall3']>0? $wall3=$_POST['wall3']:$wall1=$wall2=$wall3=0)));
  67. $post['tribe'] = $target[0];
  68. $post['deftribe'] = ($_POST['wall1']>0? '1':($_POST['wall2']>0? '2' :($_POST['wall3']>0? '3':'1')));
  69. $_POST['result'] = $this->simulate($post);
  70. $form->valuearray = $post;
  71. }
  72. }
  73. }
  74. }
  75. private function getBattleHero($uid) {
  76. global $database;
  77. $heroarray = $database->getHero($uid);
  78. $herodata = $GLOBALS["h".$heroarray[0]['unit']];
  79. $h_atk = $herodata['atk'] + 5 * floor($heroarray[0]['attack'] * $herodata['atkp'] / 5);
  80. $h_di = $herodata['di'] + 5 * floor($heroarray[0]['defence'] * $herodata['dip'] / 5);
  81. $h_dc = $herodata['dc'] + 5 * floor($heroarray[0]['defence'] * $herodata['dcp'] / 5);
  82. $h_ob = 1 + 0.002 * $heroarray[0]['attackbonus'];
  83. $h_db = 1 + 0.002 * $heroarray[0]['defencebonus'];
  84. return array('heroid'=>$heroarray[0]['heroid'],'unit'=>$heroarray[0]['unit'],'atk'=>$h_atk,'di'=>$h_di,'dc'=>$h_dc,'ob'=>$h_ob,'db'=>$h_db,'health'=>$heroarray['health']);
  85. }
  86. private function simulate($post) {
  87. // Establecemos los arrays con las unidades del atacante y defensor
  88. $attacker = array('u1'=>0,'u2'=>0,'u3'=>0,'u4'=>0,'u5'=>0,'u6'=>0,'u7'=>0,'u8'=>0,'u9'=>0,'u10'=>0,'u11'=>0,'u12'=>0,'u13'=>0,'u14'=>0,'u15'=>0,'u16'=>0,'u17'=>0,'u18'=>0,'u19'=>0,'u20'=>0,'u21'=>0,'u22'=>0,'u23'=>0,'u24'=>0,'u25'=>0,'u26'=>0,'u27'=>0,'u28'=>0,'u29'=>0,'u30'=>0,'u31'=>0,'u32'=>0,'u33'=>0,'u34'=>0,'u35'=>0,'u36'=>0,'u37'=>0,'u38'=>0,'u39'=>0,'u40'=>0,'u41'=>0,'u42'=>0,'u43'=>0,'u44'=>0,'u45'=>0,'u46'=>0,'u47'=>0,'u48'=>0,'u49'=>0,'u50'=>0);
  89. $start = ($post['a1_v']-1)*10+1;
  90. $att_ab = array('a1'=>0,'a2'=>0,'a3'=>0,'a4'=>0,'a5'=>0,'a6'=>0,'a7'=>0,'a8'=>0);
  91. $def_ab = array('b1'=>0,'b2'=>0,'b3'=>0,'b4'=>0,'b5'=>0,'b6'=>0,'b7'=>0,'b8'=>0);
  92. $index = 1;
  93. for($i=$start;$i<=($start+9);$i++) {
  94. $attacker['u'.$i] = $post['a1_'.$index];
  95. if($index <=8) {
  96. $att_ab['a'.$index] = $post['f1_'.$index];
  97. }
  98. $index += 1;
  99. }
  100. $defender = array();
  101. for($i=1;$i<=50;$i++) {
  102. if(isset($post['a2_'.$i]) && $post['a2_'.$i] != "") {
  103. $defender['u'.$i] = $post['a2_'.$i];
  104. }
  105. else {
  106. $defender['u'.$i] = 0;
  107. }
  108. }
  109. $deftribe = $post['deftribe'];
  110. $wall = 0;
  111. switch($deftribe) {
  112. case 1:
  113. for($i=1;$i<=8;$i++) {
  114. $def_ab['b'.$i] = $post['f2_'.$i];
  115. }
  116. $wall = $post['wall1'];
  117. break;
  118. case 2:
  119. for($i=11;$i<=18;$i++) {
  120. $def_ab['b'.$i] = $post['f2_'.$i];
  121. }
  122. $wall = $post['wall2'];
  123. break;
  124. case 3:
  125. for($i=21;$i<=28;$i++) {
  126. $def_ab['b'.$i] = $post['f2_'.$i];
  127. }
  128. $wall = $post['wall3'];
  129. break;
  130. case 4:
  131. for($i=31;$i<=38;$i++) {
  132. $def_ab['b'.$i] = $post['f2_'.$i];
  133. }
  134. $wall = $post['wall4'];
  135. break;
  136. case 5:
  137. for($i=41;$i<=48;$i++) {
  138. $def_ab['b'.$i] = $post['f2_'.$i];
  139. }
  140. $wall = $post['wall5'];
  141. break;
  142. }
  143. if($post['kata'] == "") {
  144. $post['kata'] = 0;
  145. }
  146. // check scout
  147. $scout = 1;
  148. for($i=$start;$i<=($start+9);$i++) {
  149. if($i == 4 || $i == 14 || $i == 23 || $i == 34 || $i == 44)
  150. {}
  151. else{
  152. if($attacker['u'.$i]>0) {
  153. $scout = 0;
  154. break;
  155. }
  156. }
  157. }
  158. //var_dump($post);
  159. echo "return $this->calculateBattle(".$attacker.",".$defender.",".$wall.",".$post['a1_v'].",".$deftribe.",".$post['palast'].",".$post['ew1'].",".$post['ew2'].",".$post['ktyp']."+3,".$def_ab.",".$att_ab.",".$post['kata'].",1);<br>\n";
  160. // echo 'calculateBattle($Attacker,$Defender,$def_wall,$att_tribe,$def_tribe,$residence,$attpop,$defpop,$type,$def_ab,$att_ab,$tblevel,$stonemason,$walllevel)';
  161. if(!$scout)
  162. return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$post['palast'],$post['ew1'],$post['ew2'],$post['ktyp']+3,$def_ab,$att_ab,$post['kata'],1,$wall);
  163. else
  164. return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$post['palast'],$post['ew1'],$post['ew2'],1,$def_ab,$att_ab,$post['kata'],1,$wall);
  165. }
  166. //1 raid 0 normal
  167. function calculateBattle($Attacker,$Defender,$def_wall,$att_tribe,$def_tribe,$residence,$attpop,$defpop,$type,$def_ab,$att_ab,$tblevel,$stonemason,$walllevel) {
  168. global $bid34;
  169. // Definieer de array met de eenheden
  170. $calvary = array(4,5,6,15,16,23,24,25,26,35,36,45,46);
  171. $catapult = array(8,18,28,38,48);
  172. $rams = array(7,17,27,37,47);
  173. $catp = $ram = 0;
  174. // Array om terug te keren met het resultaat van de berekening
  175. $result = array();
  176. $involve = 0;
  177. $winner = false;
  178. // bij 0 alle deelresultaten
  179. $cap = $ap = $dp = $cdp = $rap = $rdp = 0;
  180. //exit($type);
  181. if ($Attacker['uhero'] != 0)
  182. {
  183. //exit($Attacker['id']);
  184. $atkhero= $this->getBattleHero($Attacker['id']);
  185. }
  186. //$defhero= $this->getBattleHero($Defender['id']);
  187. //
  188. // Berekenen het totaal aantal punten van Aanvaller
  189. //
  190. $start = ($att_tribe-1)*10+1;
  191. $end = ($att_tribe*10);
  192. $abcount = 1;
  193. if($type == 1)
  194. {
  195. for($i=$start;$i<=$end;$i++) {
  196. global ${'u'.$i};
  197. if($abcount <= 8 && $att_ab['a'.$abcount] > 0) {
  198. $ap += (35 + ( 35 + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, $att_ab['a'.$abcount]) - 1)) * $Attacker['u'.$i];
  199. }
  200. else {
  201. $ap += $Attacker['u'.$i] * 35;
  202. }
  203. $abcount +=1;
  204. $units['Att_unit'][$i] = $Attacker['u'.$i];
  205. }
  206. if ($Attacker['uhero'] != 0){
  207. $ap += $atkhero['atk'] * 35;
  208. $ap = $ap * $atkhero['ob'];
  209. }
  210. }
  211. else
  212. {
  213. for($i=$start;$i<=$end;$i++) {
  214. global ${'u'.$i};
  215. if($abcount <= 8 && $att_ab['a'.$abcount] > 0) {
  216. if(in_array($i,$calvary)) {
  217. $cap += (${'u'.$i}['atk'] + (${'u'.$i}['atk'] + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, $att_ab['a'.$abcount]) - 1)) * $Attacker['u'.$i];
  218. }
  219. else {
  220. $ap += (${'u'.$i}['atk'] + (${'u'.$i}['atk'] + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, $att_ab['a'.$abcount]) - 1)) * $Attacker['u'.$i];
  221. }
  222. }
  223. else {
  224. if(in_array($i,$calvary)) {
  225. $cap += $Attacker['u'.$i]*${'u'.$i}['atk'];
  226. }
  227. else {
  228. $ap += $Attacker['u'.$i]*${'u'.$i}['atk'];
  229. }
  230. }
  231. $abcount +=1;
  232. // Punten van de catavult van de aanvaller
  233. if(in_array($i,$catapult)) {
  234. $catp += $Attacker['u'.$i];
  235. }
  236. // Punten van de Rammen van de aanvaller
  237. if(in_array($i,$rams))
  238. {
  239. $ram += $Attacker['u'.$i];
  240. }
  241. $involve += $Attacker['u'.$i];
  242. $units['Att_unit'][$i] = $Attacker['u'.$i];
  243. }
  244. if ($Attacker['uhero'] != 0)
  245. {
  246. $units['Att_unit']['hero'] = $Attacker['uhero'];
  247. $cap += $Attacker['uhero']*$atkhero['atk'];
  248. $ap += $Attacker['uhero']*$atkhero['atk'];
  249. $ap = $ap * $atkhero['ob'];
  250. $cap = $cap * $atkhero['ob'];
  251. }
  252. }
  253. //
  254. // Berekent het totaal aantal punten van de Defender
  255. //
  256. $start = ($def_tribe-1)*10+1;
  257. $end = ($def_tribe*10);
  258. $abcount = 1;
  259. if($type == 1)
  260. {
  261. for($y=4;$y<=44;$y++) {
  262. if($y == 4 || $y == 14 || $y == 23 || $y == 34 || $y == 44)
  263. {
  264. global ${'u'.$y};
  265. if($y >= $start && $y <= ($end-2) && $def_ab['b'.$abcount] > 0) {
  266. $dp += (20 + (20 + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab['b'.$y]) - 1)) * $Defender['u'.$y];
  267. $abcount +=1;
  268. }
  269. else {
  270. $dp += $Defender['u'.$y]*20;
  271. }
  272. $units['Def_unit'][$y] = $Defender['u'.$y];
  273. }
  274. }
  275. }
  276. else
  277. {
  278. for($y=1;$y<=50;$y++) {
  279. global ${'u'.$y};
  280. if($y >= $start && $y <= ($end-2) && $def_ab['b'.$abcount] > 0) {
  281. $dp += (${'u'.$y}['di'] + (${'u'.$y}['di'] + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab['b'.$y]) - 1)) * $Defender['u'.$y];
  282. $cdp += (${'u'.$y}['dc'] + (${'u'.$y}['dc'] + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab['b'.$y]) - 1)) * $Defender['u'.$y];
  283. $abcount +=1;
  284. }
  285. else {
  286. $dp += $Defender['u'.$y]*${'u'.$y}['di'];
  287. $cdp += $Defender['u'.$y]*${'u'.$y}['dc'];
  288. }
  289. $involve += $Defender['u'.$y];
  290. $units['Def_unit'][$y] = $Defender['u'.$y];
  291. }
  292. }
  293. //
  294. // Formule voor de berekening van de bonus verdedigingsmuur "en" Residence ";
  295. //
  296. if($def_wall > 0) {
  297. // Stel de factor berekening voor de "Muur" als het type van de beschaving
  298. // Factor = 1030 Romeinse muur
  299. // Factor = 1020 Wall Germanen
  300. // Factor = 1025 Wall Galliers
  301. $factor = ($def_tribe == 1)? 1.030 : (($def_tribe == 2)? 1.020 : 1.025);
  302. // Defense Infanterie = infanterie * Muur (%)
  303. ///echo"$factor,$def_wall";
  304. $dp *= pow($factor,$def_wall);
  305. //echo"||| =$dp dp|||";
  306. // Defensa Cavelerie = Cavelerie * Muur (%)
  307. $cdp *= pow($factor,$def_wall);
  308. //echo"||| =$cdp cdp|||";
  309. // Berekening van de Basic defence bonus "Residence"
  310. $dp += ((2*(pow($residence,2)))*(pow($factor,$def_wall)));
  311. //echo"||| $residence=$dp dp2|||";
  312. $cdp += ((2*(pow($residence,2)))*(pow($factor,$def_wall)));
  313. //echo"||| $residence=$cdp cdp2|||";
  314. }
  315. else
  316. {
  317. // Berekening van de Basic defence bonus "Residence"
  318. $dp += (2*(pow($residence,2)));
  319. $cdp += (2*(pow($residence,2)));
  320. }
  321. //
  322. // Formule voor het berekenen van punten aanvallers (Infanterie & Cavalry)
  323. //
  324. $rap = $ap+$cap;
  325. //
  326. // Formule voor de berekening van Defensive Punten
  327. //
  328. if ($rap==0)
  329. $rdp = ($dp) + ($cdp) + 10;
  330. else
  331. $rdp = ($dp * ($ap/$rap)) + ($cdp * ($cap/$rap)) + 10;
  332. //
  333. // En de Winnaar is....:
  334. //
  335. $result['Attack_points'] = $rap;
  336. $result['Defend_points'] = $rdp;
  337. $winner = ($rap > $rdp);
  338. $result['Winner'] = ($winner)? "attacker" : "defender";
  339. // Formule voor de berekening van de Moraal
  340. if($attpop > $defpop) {
  341. if ($rap < $rdp) {
  342. $moralbonus = min(1.5, pow($attpop / $defpop, (0.2*($rap/$rdp))));
  343. }
  344. else {
  345. $moralbonus = min(1.5, pow($attpop / $defpop, 0.2));
  346. }
  347. }
  348. else {
  349. $moralbonus = 1.0;
  350. }
  351. if($involve >= 1000) {
  352. $Mfactor = round(2*(1.8592-pow($involve,0.015)),4);
  353. }
  354. else {
  355. $Mfactor = 1.5;
  356. }
  357. // Formule voor het berekenen verloren drives
  358. // $type = 1 Raid, 0 Normal
  359. if($type == 1)
  360. {
  361. $holder = pow((($rdp*$moralbonus)/$rap),$Mfactor);
  362. $holder = $holder / (1 + $holder);
  363. // Attacker
  364. $result[1] = $holder;
  365. // Defender
  366. $result[2] = 0;
  367. }
  368. else if($type == 2)
  369. {
  370. }
  371. else if($type == 4) {
  372. $holder = ($winner) ? pow((($rdp*$moralbonus)/$rap),$Mfactor) : pow(($rap/($rdp*$moralbonus)),$Mfactor);
  373. $holder = $holder / (1 + $holder);
  374. // Attacker
  375. $result[1] = $winner ? $holder : 1 - $holder;
  376. // Defender
  377. $result[2] = $winner ? 1 - $holder : $holder;
  378. $ram -= round($ram*$result[1]/100);
  379. $catp -= round($catp*$result[1]/100);
  380. }
  381. else if($type == 3)
  382. {
  383. // Attacker
  384. $result[1] = ($winner)? pow((($rdp*$moralbonus)/$rap),$Mfactor) : 1;
  385. $result[1] = round($result[1],8);
  386. // Defender
  387. $result[2] = (!$winner)? pow(($rap/($rdp*$moralbonus)),$Mfactor) : 1;
  388. $result[2] = round($result[2],8);
  389. // Als aangevallen met "Hero"
  390. $ku = ($att_tribe-1)*10+9;
  391. $kings = $Attacker['u'.$ku];
  392. $aviables= $kings-round($kings*$result[1]);
  393. if ($aviables>0){
  394. switch($aviables){
  395. case 1:
  396. $fealthy = rand(20,30);
  397. break;
  398. case 2:
  399. $fealthy = rand(40,60);
  400. break;
  401. case 3:
  402. $fealthy = rand(60,80);
  403. break;
  404. case 4:
  405. $fealthy = rand(80,100);
  406. break;
  407. default:
  408. $fealthy = 100;
  409. break;
  410. }
  411. $result['hero_fealthy'] = $fealthy;
  412. }
  413. $ram -= ($winner)? round($ram*$result[1]/100) : round($ram*$result[2]/100);
  414. $catp -= ($winner)? round($catp*$result[1]/100) : round($catp*$result[2]/100);
  415. }
  416. // Formule voor de berekening van katapulten nodig
  417. if($catp > 0 && $tblevel != 0) {
  418. $wctp = pow(($rap/$rdp),1.5);
  419. $wctp = ($wctp >= 1)? 1-0.5/$wctp : 0.5*$wctp;
  420. $wctp *= $catp;
  421. $need = round((($moralbonus * (pow($tblevel,2) + $tblevel + 1)) / (8 * (round(200 * pow(1.0205,$att_ab['a8']))/200) / (1 * $bid34[$stonemason]['attri']/100))) + 0.5);
  422. // Aantal katapulten om het gebouw neer te halen
  423. $result[3] = $need;
  424. // Aantal Katapulten die handeling
  425. $result[4] = $wctp;
  426. $result[5] = $moralbonus;
  427. $result[6] = $att_ab['a8'];
  428. }
  429. if($ram > 0 && $walllevel != 0) {
  430. $wctp = pow(($rap/$rdp),1.5);
  431. echo $wctp."=pow((".$rap."/".$rdp."),1.5);";
  432. $wctp = ($wctp >= 1)? 1-0.5/$wctp : 0.5*$wctp;
  433. echo "{".$wctp."}";
  434. $wctp *= $ram;
  435. echo "}".$ram.":".$wctp."{";
  436. $tribewall = ($def_tribe==1? '1':($def_tribe==2? '5' : ($def_tribe==3? '2' : '1')));
  437. $l2=round(($walllevel1)/2);
  438. echo ">>".$tribewall."<<";
  439. $need = ($walllevel*($walllevel+1)/8 + 5 + (24.875 + 0.625*$l2)*$l2/2);
  440. // $need = round((($moralbonus * (pow($walllevel,2) + $walllevel + 1)) / (8 * (round(200 * pow(1.0205,$att_ab['a7']))/200) / (1 * $bid34[$stonemason]['attri']/100))) + 0.5);
  441. $need *= $tribewall;
  442. // Aantal katapulten om het gebouw neer te halen
  443. $result[7] = $need;
  444. //DDR = DC * { L*(L+1)/8 + 5 + (24.875 + 0.625*L2)*L2/2 } (10)
  445. //L2 = round{ (L – 1) / 2 }
  446. //L — starting level of wall.
  447. //DDR — Demolition Damage of Rams, equals percent of worked rams (9).
  448. //DC — Durability coefficient, depends on tribe, stonemason, rams' upgrades and durability artifact.
  449. // Aantal Katapulten die handeling
  450. $result[8] = round(($wctp*(100-$need))/100);
  451. }
  452. $result[6] = pow($rap/$rdp*$moralbonus,$Mfactor);
  453. $total_att_units = count($units['Att_unit']);
  454. $start = intval(($att_tribe-1)*10+1);
  455. $end = intval(($att_tribe*10));
  456. //exit($start."|".$end."|".$att_tribe);
  457. //$y=1;
  458. for($i=$start;$i <= $end;$i++)
  459. {
  460. $y = $i-(($att_tribe-1)*10);
  461. //exit(intval("$y"));
  462. $result['casualties_attacker'][$y] = round($result[1]*$units['Att_unit'][$i]);
  463. //$y++;
  464. //exit($result['casualties_attacker'][$y]);
  465. }
  466. //$result['casualties_attacker']['11'] = 0;
  467. //exit($result['casualties_attacker']['2']);
  468. //$_hero=11;
  469. // var_dump($units);
  470. //echo"1111111111111";
  471. if ($units['Att_unit']['hero']>0)
  472. {
  473. // echo"22222222222222222";
  474. //echo "select `owner` from " . TB_PREFIX . "vdata where `wref`='".$Attacker['from']."'";
  475. $_result=mysql_query("select `owner` from " . TB_PREFIX . "vdata where `wref`='".$Attacker['from']."'");
  476. $fdb = mysql_fetch_array($_result);
  477. $hero_owner=$fdb['owner'];
  478. // echo"<pre>";var_dump($Attacker);echo"</pre>";
  479. //echo "select * from " . TB_PREFIX . "hero where `dead`='0' and `uid`='".$hero_owner."'";
  480. $_result=mysql_query("select * from " . TB_PREFIX . "hero where `dead`='0' and `uid`='".$hero_owner."'");
  481. $fdb = mysql_fetch_array($_result);
  482. $hero_id=$fdb['heroid'];
  483. $hero_health=$fdb['health'];
  484. $damage_health=round(100*$result[1]);
  485. //exit($damage_health."|".$hero_health."|".$hero_owner);
  486. // echo "$hero_health<=$damage_health";
  487. if ($hero_health<=$damage_health)
  488. {
  489. //hero die
  490. // echo "hero_die";
  491. $result['casualties_attacker']['11'] = 1;
  492. mysql_query("update " . TB_PREFIX . "hero set `dead`='1' where `heroid`='".$hero_id."'");
  493. }
  494. else
  495. {
  496. $result['casualties_attacker']['11'] = 0;
  497. mysql_query("update " . TB_PREFIX . "hero set `health`=`health`-".$damage_health." where `heroid`='".$hero_id."'");
  498. }
  499. }
  500. //exit($result['casualties_attacker']['11']);
  501. //$result['casualties_attacker'][11] = round($result[1]*$units['Att_unit']['hero']);
  502. // Work out bounty
  503. $start = ($att_tribe-1)*10+1;
  504. $end = ($att_tribe*10);
  505. $max_bounty = 0;
  506. for($i=$start;$i<=$end;$i++) {
  507. $y = $i-(($att_tribe-1)*10);
  508. $max_bounty += ($Attacker['u'.$i]-$result['casualties_attacker'][$y])*${'u'.$i}['cap'];
  509. }
  510. $result['bounty'] = $max_bounty;
  511. return $result;
  512. }
  513. public function resolveConflict($data) {
  514. global $database,$units,$unitsbytype;
  515. $UnitChief = $UnitRam = $UnitCatapult = 0;
  516. $attacker_count = $attack_infantry = $attack_cavalry = $attack_scout = $rams = $catapults = 0;
  517. $defender_count = $defense_infantry = $defense_cavalry = $defense_scout = $defense_heros = 0;
  518. $DefenderFieldsArray = $ResourceImprovementArray = $TrapperArray = array();
  519. $FieldPalRes = $BonusPalRes = $BonusStoneMason = $BonusArtefactDurability = 0;
  520. $ExperienceAttacker = $ExperienceDefender = 0;
  521. $RecountReqd = $AllDefendersDead = False;
  522. $AttackArrivalTime = $data['endtime'];
  523. $AttackerData = $database->getVillageBattleData($data['from']);
  524. $AttackerData['pop'] = $database->getPopulation($AttackerData['id']);
  525. $Blacksmith = $database->getABTech($data['from']);
  526. for($i=1;$i<=11;$i++) { $attacker_count += $data['t'.$i]; }
  527. if($data['type'] != 1) {
  528. // Trap attacking troops if this is not a scouting mission
  529. }
  530. for($i=1;$i<=10;$i++) {
  531. if($data['t'.$i] > 0) {
  532. $unit = ($AttackerData['tribe']-1)*10+$i;
  533. $unitdata = $GLOBALS['u'.$unit];
  534. if(in_array($unit,$unitsbytype['cavalry'])) {
  535. $attack_cavalry += $data['t'.$i] * ($unitdata['atk'] + ($unitdata['atk'] + 300 * $unitdata['pop'] / 7) * (pow(1.007,$Blacksmith['b'.$i]) - 1));
  536. } else {
  537. $attack_infantry += $data['t'.$i] * ($unitdata['atk'] + ($unitdata['atk'] + 300 * $unitdata['pop'] / 7) * (pow(1.007,$Blacksmith['b'.$i]) - 1));
  538. }
  539. if(in_array($unit,$unitsbytype['scout'])) {
  540. $attack_scout = $data['t'.$i] * 35 * pow(1.021,$Blacksmith['b'.$i]);
  541. }
  542. if(in_array($unit,$unitsbytype['chief'])) { $UnitChief = $i; }
  543. if(in_array($unit,$unitsbytype['ram'])) { $UnitRam = $i; }
  544. if(in_array($unit,$unitsbytype['catapult'])) { $UnitCatapult = $i; }
  545. }
  546. }
  547. if($data['t11'] == 1 && $data['type'] != 1) {
  548. $heroarrayAttacker = $this->getBattleHero($AttackerData['id']);
  549. if(in_array($heroarrayAttacker['unit'],$unitsbytype['cavalry'])) {
  550. $attack_cavalry += $heroarrayAttacker['atk'];
  551. } else {
  552. $attack_infantry += $heroarrayAttacker['atk'];
  553. }
  554. $attack_infantry *= $heroarrayAttacker['ob'];
  555. $attack_cavalry *= $heroarrayAttacker['ob'];
  556. }
  557. $attack_total = $attack_infantry + $attack_cavalry;
  558. if($attacker_count == 1 && $attack_total < 83 && $data['type'] != 1) {
  559. // kill the single non-scout low level attacker due to basic village defense
  560. }
  561. if ($database->isVillageOases($id) == 0) {
  562. $DefenderData = $database->getVillageBattleData($data['to']);
  563. $DefenderData['pop'] = $database->getPopulation($DefenderData['id']);
  564. $IsOasis = False;
  565. } else {
  566. $OasisData = $database->getOMInfo($data['to']);
  567. $IsOasis = True;
  568. if($OasisData['conqured'] == 0) {
  569. $DefenderData['pop'] = 500;
  570. } else {
  571. $DefenderData['pop'] = $database->getPopulation($OasisData['conqured']);
  572. }
  573. $DefenderData['tribe'] = 4;
  574. $DefenderData['wall'] = 0;
  575. }
  576. $DefenderUnits = $database->getUnit($data['to']);
  577. $DefendersAll = $database->getEnforceVillage($data['to'],0);
  578. array_unshift($DefendersAll,$DefenderUnits);
  579. foreach($DefendersAll as $defenders) {
  580. $definf = $defcav = 0;
  581. if(!empty($Armoury)) { reset($Armoury); }
  582. $Armoury = $defenders['from'] != $defenders['vref'] ? $database->getABTech($defenders['from']) : $database->getABTech($defenders['vref']);
  583. for($i=1;$i<=50;$i++) {
  584. if($defenders['u'.$i] > 0) {
  585. if(!empty($unitdata)) { reset($unitdata); }
  586. $unitdata = $GLOBALS['u'.$i];
  587. $definf += $defenders['u'.$i] * ($unitdata['di'] + ($unitdata['di'] + 300 * $unitdata['pop'] / 7) * (pow(1.007,$Armoury['a'.($i%10)]) - 1));
  588. $defcav += $defenders['u'.$i] * ($unitdata['dc'] + ($unitdata['dc'] + 300 * $unitdata['pop'] / 7) * (pow(1.007,$Armoury['a'.($i%10)]) - 1));
  589. if(in_array($i,$unitsbytype['scout'])) {
  590. $defense_scout += $defenders['u'.$i] * 20 * pow(1.03,$Armoury['a'.($i%10)]);
  591. }
  592. $defender_count += $defenders['u'.$i];
  593. }
  594. }
  595. if($defenders['hero'] == 1 && $data['type'] != 1) {
  596. if(!empty($heroarray)) { reset($heroarray); }
  597. if($defender['vref'] == $data['to']) {
  598. $heroarray = $this->getBattleHero($DefenderData['id']);
  599. } else {
  600. $ReinforcerData = $database->getVillageBattleData($defenders['from']);
  601. $heroarray = $this->getBattleHero($ReinforcerData['id']);
  602. }
  603. $definf = ($definf + $heroarray['di']) * $heroarray['db'];
  604. $defcav = ($defcav + $heroarray['dc']) * $heroarray['db'];
  605. $defense_heros++;
  606. }
  607. $defense_infantry += $definf;
  608. $defense_cavalry += $defcav;
  609. }
  610. if($data['type'] == 1) {
  611. if($attack_scout > $defense_scout) {
  612. $attack_scout_casualties = pow(($defense_scout / $attack_scout),1.5);
  613. // generate scout report and process casualties
  614. } else {
  615. $attack_scout_casualties = 1;
  616. // kill all scouts
  617. }
  618. } else {
  619. $defense_total = $attack_infantry * $defense_infantry / $attack_total + $attack_cavalry * $defense_cavalry / $attack_total;
  620. if($DefenderData['pop'] < $AttackerData['pop']) {
  621. $defense_total *= min(1.5,pow($AttackerData['pop']/$DefenderData['pop'],0.2));
  622. }
  623. $DefenderFields = $database->getResourceLevel($data['to']);
  624. for($i=1;$i<=38;$i++) {
  625. if($DefenderFields['f'.$i] > 0) { $DefenderFieldsArray[] = $i; }
  626. if($DefenderFields['f'.$i.'t'] == 25 || $DefenderFields['f'.$i.'t'] == 26) {
  627. $BonusPalRes = 2 * pow($DefenderFields['f'.$i],2);
  628. $FieldPalRes = $i;
  629. }
  630. if($DefenderFields['f'.$i.'t'] == 34) {
  631. $BonusStoneMason = $DefenderFields['f'.$i] / 10 + 1;
  632. }
  633. if($DefenderFields['f'.$i.'t'] >= 5 && $DefenderFields['f'.$i.'t'] <= 9) {
  634. $ResourceImprovementArray[] = $i;
  635. }
  636. if($DefenderFields['f'.$i.'t'] == 36) {
  637. $TrapperArray[] = $i;
  638. }
  639. if($DefenderFields['f'.$i.'t'] == $data['ctar1'] && $data['ctar1'] != 0) {
  640. $ctarf[1] = $i;
  641. }
  642. if($DefenderFields['f'.$i.'t'] == $data['ctar2'] && $data['ctar2'] != 0 && ($data['ctar1'] != $data['ctar2'] || $data['ctar2'] <= 18)) {
  643. $ctarf[2]= $i;
  644. }
  645. }
  646. $defense_total += $BonusPalRes;
  647. $BonusWall = $DefenderData['tribe'] == 1 ? 1.03 : ($DefenderData['tribe'] == 2 ? 1.02 : 1.025);
  648. $defense_total *= pow($BonusWall,$DefenderData['wall']);
  649. if($attacker_count + $defender_count + $defense_heros > 1000) {
  650. $DiffModifier = 2 * (1.8592 - pow(($attacker_count + $defender_count + $defense_heros),0.015));
  651. } else {
  652. $DiffModifier = 1.5;
  653. }
  654. $attack_casualties = $defense_casualties = 1;
  655. if($attack_total > $defense_total) {
  656. $attack_casualties = pow(($defense_total / $attack_total),$DiffModifier);
  657. if($data['type'] == 4) {
  658. $attack_casualties = $attack_casualties / (1 + $attack_casualties);
  659. $defense_casualties = 1 - $attack_casualties;
  660. }
  661. } else {
  662. $defense_casualties = pow(($attack_total / $defense_total),$DiffModifier);
  663. if($data['type'] == 4) {
  664. $defense_casualties = $defense_casualties / (1 + $defense_casualties);
  665. $attack_casualties = 1 - $defense_casualties;
  666. }
  667. }
  668. if($rams > 0 && $DefenderData['wall'] > 0) {
  669. if($attack_casualties < 1) {
  670. $database->setVillageLevel($data['to'],'f40t',0);
  671. $database->setVillageLevel($data['to'],'f40',0);
  672. } else {
  673. $RequiredRams=array(1=>array(1,2,2,3,4,6,7,10,12,14,17,20,23,27,31,35,39,43,48,53),array(1,4,8,13,19,27,36,46,57,69,83,98,114,132,151,171,192,214,238,263),array(1,2,4,6,8,11,15,19,23,28,34,40,46,53,61,69,77,86,96,106));
  674. $DC = max(1,$BonusStoneMason) * max(1,$BonusPalRes) / (pow(1.015,$Blacksmith['b'.$UnitRam])) ;
  675. $L = $DefenderData['wall'];
  676. $L2 = round(($DefenderData['wall'] - 1) /2);
  677. $DDR = $DC / ( $L*($L+1)/8 + 5 + (24.875 + 0.625*$L2)*$L2/2 );
  678. //calculate damage to wall based on surviving rams
  679. }
  680. $RecountReqd = True;
  681. }
  682. if($catapults > 0 && !$IsOasis) {
  683. $BuildLevelStrength=array(1=>1,2,2,3,4,6,8,10,12,14,17,20,23,27,31,35,39,43,48,53);
  684. $RequiredCatapults = $RequiredCatapultsMax = $BuildingLevelMax = array();
  685. if(!empty($RequiredCatapults)) { reset($RequiredCatapults); }
  686. for($i=1;$i<=2;$i++) {
  687. if($data['ctar'.$i] == 0 || $ctarf[$i] == 0) {
  688. $data['ctar'.$i] = $DefenderFieldsArray[rand(0,count($DefenderFieldsArray)-1)];
  689. if($data['ctar2'] == 0 && $i == 1) { $data['ctar2'] = $data['ctar1']; }
  690. }
  691. $RequiredCatapults[$i] = round((($DefenderData['pop'] < $AttackerData['pop'] ? min(3,pow($AttackerData['pop'] / $DefenderData['pop'],0.3)) : 1) * (pow($DefenderField['f'.$ctarf[$i]],2) + $DefenderField['f'.$ctarf[$i]] + 1) / (8 * (round(200 * pow(1.0205,$Blacksmith['b'.$UnitCatapult])) / 200) / max(1,($data['ctar'.$i]>=18?max(1,$BonusStoneMason + $BonusArtefactDurability):1)))) + 0.5);
  692. $BuildingLevelMax[$i] = 20;
  693. if($DefenderData['capital'] != 1 && $data['ctar'.$i] <= 18 || in_array($data['ctar'.$i],$TrapperArray)) { $BuildingLevelMax[$i] = 10; }
  694. if(in_array($data['ctar'.$i],$ResourceImprovementArray)) { $BuildingLevelMax[$i] = 5; }
  695. $RequiredCatapultsMax[$i] = round((($DefenderData['pop'] < $AttackerData['pop'] ? min(3,pow($AttackerData['pop'] / $DefenderData['pop'],0.3)) : 1) * (pow($BuildingLevelMax[$i],2) + $BuildingLevelMax[$i] + 1) / (8 * (round(200 * pow(1.0205,$Blacksmith['b'.$UnitCatapult])) / 200) / max(1,($data['ctar'.$i]>=18?max(1,$BonusStoneMason + $BonusArtefactDurability):1)))) + 0.5);
  696. }
  697. $CatapultsFiring = pow($attack_total / $defense_total,1.5);
  698. if($CatapultsFiring > 1) {
  699. $CatapultsFiring = 1 - 0.5 / $CatapultsFiring;
  700. } else {
  701. $CatapultsFiring = 0.5 * $CatapultsFiring;
  702. }
  703. $CatapultsFiring *= $data['t'.$UnitCatapult];
  704. for($i=1;$i=($data['ctar1']==$data['ctar2']?1:2);$i++) {
  705. $BuildingLevelOld[$i] = $DefenderField['f'.$data['ctar'.$i]];
  706. if($data['ctar1']!=$data['ctar2'] && $i==1) { $CatapultsFiring /= 2; }
  707. if($CatapultsFiring >= $RequiredCatapults[$i]) {
  708. if($DefenderField['f'.$data['ctar'.$i]] == $FieldPalRes) { $DestroyedPalRes = True; }
  709. if($data['ctar'.$i] >= 19) { $database->setVillageLevel($data['to'],'f'.$data['ctar'.$i].'t',0); }
  710. $database->setVillageLevel($data['to'],'f'.$data['ctar'.$i],0);
  711. $BuildingLevelNow[$i] = 0;
  712. $RecountReqd = True;
  713. } else {
  714. $BuildLevelCount = 0;
  715. for($j=$DefenderField['f'.$data['ctar'.$i]];$j=1;$j--) {
  716. $BuildLevelCount += ($BuildLevelStrength[$j] - $BuildLevelStrength[$j-1]) * $RequiredCatapultsMax[$i] / $BuildLevelStrength[$BuildingLevelMax[$i]];
  717. if($CatapultsFiring < $BuildLevelCount) {
  718. $BuildingLevelNow[$i] = $j;
  719. break;
  720. }
  721. $database->setVillageLevel($data['to'],'f'.$data['ctar'.$i],$BuildingLevelNow[$i]);
  722. $RecountReqd = True;
  723. }
  724. }
  725. }
  726. }
  727. for($i=1;$i<=10;$i++) {
  728. $attack_casualties_array[$i] = round($data['t'.$i] * $attack_casualties);
  729. if(!empty($unitdata)) { reset($unitdata); }
  730. $unitdata = $GLOBALS['u'.(($AttackerData['tribe']-1)*10+$i)];
  731. $ExperienceDefender += $attack_casualties_array[$i] * $unitdata['pop'];
  732. }
  733. if($data['t11'] == 1) {
  734. if($attack_casualties < 0.9) {
  735. if($heroarrayAttacker['health']-100*$attack_casualties > 0) {
  736. $database->modifyHero('health',(100*$attack_casualties),$heroarrayAttacker['heroid'],2);
  737. $database->modifyHero('lastupdate',time(),$heroarrayAttacker['heroid'],0);
  738. } else {
  739. $database->modifyHero('health',0,$heroarrayAttacker['heroid'],0);
  740. $database->modifyHero('dead',1,$heroarrayAttacker['heroid'],0);
  741. $database->modifyHero('lastupdate',time(),$heroarrayAttacker['heroid'],0);
  742. }
  743. } else {
  744. $database->modifyHero('health',0,$heroarrayAttacker['heroid'],0);
  745. $database->modifyHero('dead',1,$heroarrayAttacker['heroid'],0);
  746. $database->modifyHero('lastupdate',time(),$heroarrayAttacker['heroid'],0);
  747. }
  748. }
  749. // send surviving attackers and hero home, report.
  750. // calculate defensive casualties, hero damage and experience (all heroes), modify units and reinforcements, report.
  751. // damage buildings report
  752. // Chiefing logic including wall and tribal specific building removal
  753. if($IsOasis && $data['t11'] == 1 && $AllDefendersDead) {
  754. $database->modifyOasisLoyalty($data['to']);
  755. if($database->canConquerOasis($data['from'],$data['to'])) {
  756. $database->conquerOasis($data['to'],$data['from'],$AttackerData['id']);
  757. }
  758. }
  759. if($RecountReqd) { $automation->recountPop($data['to']); }
  760. }
  761. }
  762. };
  763. $battle = new Battle;
  764. ?>