PageRenderTime 168ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/php/postbattle.php

https://bitbucket.org/obsidian/selador
PHP | 1678 lines | 1312 code | 203 blank | 163 comment | 245 complexity | 815a9fb1d713137469bfabe3e6b657cc MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* postbattle.php - Back-end code that handles post-battle stuff: Report generation, troop return
  3. *
  4. * Copyright (C) 2006, 2007, 2008 Kevin Read, Simone Schaefer
  5. *
  6. * This file is part of Selador, a browser-based fantasy strategy game
  7. *
  8. * This program is distributed under the terms of the GNU Affero General Public License.
  9. *
  10. *
  11. * Selador is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as published by
  13. * the Free Software Foundation, either version 3 of the License, or
  14. * any later version.
  15. *
  16. * Selador is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with Selador. If not, see <http://www.gnu.org/licenses/>.
  23. **/
  24. // Fairly nice code
  25. // See method post_battle at the end of the file for what happens
  26. // here in what order
  27. require_once ("event.php");
  28. require_once ("unitmap.php");
  29. require_once("war_functions.php");
  30. define ("OUTPOST_SIEGE_DURATION", 48); // in hours
  31. define ("CITY_SIEGE_DURATION", 120); // in hours
  32. class Postbattle
  33. {
  34. public $village_obj; // This references the outside village object so ressources are really subtracted
  35. public $targetvill_obj;
  36. private $att_uid;
  37. private $att_vill;
  38. private $def_uid;
  39. private $def_vill;
  40. private $type;
  41. private $timediff;
  42. private $in_units;
  43. private $result;
  44. private $idmap;
  45. private $return_duration;
  46. private $capacity;
  47. private $report_spying;
  48. private $armyinfo;
  49. private $do_local;
  50. private $extra_results;
  51. private $att_troopid;
  52. private $att_class;
  53. private $survivors;
  54. private $defender_virtual_survivors = 0;
  55. private $total_survivors;
  56. private $total_cap;
  57. private $total_def;
  58. private $all_cap;
  59. // Stuff for housekeeping and data storage
  60. private $battleid;
  61. private $baids = array ();
  62. private $repqueries = array();
  63. private $score_sub = array ();
  64. private $receip_uids = array();
  65. private $receip_aids = array ();
  66. private $xp_by_uid = array ();
  67. private $unitvalue = array ();
  68. private $unitvalueloss = array ();
  69. private $return_event;
  70. private $bquery = null;
  71. private $def_hero_died = false;
  72. private $grattid = 0;
  73. private $wallscore = 0;
  74. private $outpostscore = 0;
  75. // Stuff for report generation
  76. private $loot_specials;
  77. private $reslosses; //<--------------verluste (array; 1.index = uid, 2. index rohstoffart
  78. private $resloot; // <----------------------resloot[$this_uid][$currency]
  79. private $rescosts;
  80. private $report_subject;
  81. private $loot_query;
  82. private $loot_prefix;
  83. private $army_has_hero = array ();
  84. // Which uids need to recalculate commanders?
  85. private $recalc_commanders;
  86. // Siege stuff
  87. private $notify_besieger;
  88. private $notify_besieged;
  89. private $post_state;
  90. private $attacker_returns;
  91. private $attuser;
  92. private $defuser;
  93. public $siege_successful = false;
  94. function __construct ($att_uid, $att_vill, $def_uid, $def_vill, $type, $timediff, $in_units, $result, $idmap, $return_duration, $capacity, &$village_obj, $report_spying, $armyinfo, $do_local, $extra_results, $att_troopid, $grattid, $tv_obj, &$attuser, &$defuser)
  95. {
  96. global $debug;
  97. if ($_SESSION['always_debug'])
  98. $debug = true;
  99. $this->attuser = $attuser;
  100. $this->defuser = $defuser;
  101. $this->att_uid = $att_uid;
  102. $this->att_vill = $att_vill;
  103. $this->def_uid = $def_uid;
  104. $this->def_vill = $def_vill;
  105. $this->type = $type;
  106. $this->timediff = $timediff;
  107. $this->in_units = $in_units;
  108. $this->result = $result;
  109. $this->idmap = $idmap;
  110. $this->return_duration = $return_duration;
  111. if ($capacity)
  112. $this->capacity = $capacity;
  113. else
  114. $this->fetch_capacity ();
  115. $this->village_obj = $village_obj;
  116. $this->targetvill_obj = $tv_obj;
  117. $this->report_spying = $report_spying;
  118. $this->armyinfo = $armyinfo;
  119. $this->do_local = $do_local;
  120. $this->extra_results = $extra_results;
  121. $this->att_troopid = $att_troopid;
  122. $this->grattid = $grattid;
  123. if ($debug)
  124. {
  125. echo "in_units:<br>\n";
  126. print_r ($this->in_units);
  127. echo "results:<br>\n";
  128. print_r ($this->result);
  129. echo "idmap:<br>\n";
  130. print_r ($this->idmap);
  131. echo "armyinfo:<br>\n";
  132. print_r ($this->armyinfo);
  133. echo "extra results:<br>\n";
  134. print_r ($this->extra_results);
  135. }
  136. $this->return_event = array();
  137. // We'll note the surviving units ordered by uid here later
  138. $this->survivors = array();
  139. // All survivors, to check if we need to calculate loot
  140. $this->total_survivors = 0;
  141. // Total carrying capacity of each side
  142. $this->total_cap = array ();
  143. // All carrying capacities summed up, to divide the loot
  144. $this->all_cap = 0;
  145. // Sanity checks
  146. if (!is_array ($this->idmap) || !count ($this->idmap))
  147. unset ($this->idmap);
  148. $query = "select A.user as off, A.class as attclass, B.user as def, B.aid from user A, user B where A.uid=".$this->att_uid." and B.uid=".$this->def_uid;
  149. if (!($res = mysql_query ($query)))
  150. {
  151. log_err ("Error while looking up names for report in user.inc.php. Query: ".$query.". Error: ".mysql_error());
  152. }
  153. else
  154. {
  155. if ($row = mysql_fetch_array ($res))
  156. {
  157. // If there were no defenders in the target village, result and idmap are empty
  158. // We will need to add the uid of the defender manually to in_units
  159. if (!isset ($this->armyinfo[$this->def_uid]))
  160. {
  161. $this->armyinfo[$this->def_uid][2000] = 1;
  162. $this->armyinfo[$this->def_uid][2003] = $row['aid'];
  163. $this->armyinfo[$this->def_uid][3000] = $this->armyinfo[$this->def_uid][3001] = $this->armyinfo[$this->def_uid][3002] = $this->armyinfo[$this->def_uid][3003];
  164. }
  165. $this->att_class = $row['attclass'];
  166. // Is this an attack on an outpost?
  167. if ($this->targetvill_obj)
  168. {
  169. $vname = $this->targetvill_obj->name;
  170. $vz = $this->targetvill_obj->give_z ();
  171. }
  172. else
  173. {
  174. $vname = $this->village_obj->name;
  175. $vz = $this->village_obj->give_z ();
  176. }
  177. // So now we have the name of the attacker and the owner of the attacked village
  178. if ($this->report_spying)
  179. {
  180. $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' sp&auml;ht <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def']).' aus');
  181. // If this was a spying attempt, also add a note to the user explaining the battle
  182. $this->loot_specials[$this->att_uid][70] = 1;
  183. $this->loot_specials[$this->def_uid][71] = 1;
  184. }
  185. else
  186. {
  187. switch ($this->type)
  188. {
  189. case ATTACK:
  190. $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' greift <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def'])."</a> an");
  191. break;
  192. case RAID:
  193. $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' raubt <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def'])."</a> aus");
  194. break;
  195. case SIEGE:
  196. $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' erobert <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def'])."</a>");
  197. break;
  198. case GROUPATTACK:
  199. $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' greift <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def'])."</a> gemeinsam an");
  200. break;
  201. }
  202. }
  203. // Next we insert a new battle entry
  204. $query = "insert into battles values (NULL, ".$this->type.")";
  205. if (!mysql_query ($query))
  206. {
  207. log_err ("Cannot insert battle entry. ".$query.", ".mysql_error());
  208. return (false);
  209. }
  210. else
  211. {
  212. $this->battleid = mysql_insert_id ();
  213. // Do stuff here
  214. }
  215. }
  216. else
  217. {
  218. log_err ("No names found while looking up names for report in user.inc.php. Query: ".$query);
  219. return (false);
  220. }
  221. }
  222. }
  223. private function fetch_capacity ()
  224. {
  225. $this->capacity = array ();
  226. $query = "select unitid, capacity from units";
  227. if (!($res = mysql_query ($query)))
  228. {
  229. log_err ("Cannot fetch capacity for all units. Query ".$query.", ".mysql_error ());
  230. }
  231. else
  232. {
  233. while ($row = mysql_fetch_row ($res))
  234. {
  235. $this->capacity[$row[0]] = $row[1];
  236. }
  237. }
  238. }
  239. private function insert_battle_army ($this_uid, $his_values)
  240. {
  241. if (!isset ($this->baids[$this_uid]))
  242. {
  243. $this->score_sub[$this_uid] = 0;
  244. if ($his_values[2000] == 1) // Is this a defender?
  245. $query = "insert into bat_armies values (".$this->battleid.", NULL, 1, ".$this_uid.", ".$this->def_vill.")";
  246. else
  247. $query = "insert into bat_armies values (".$this->battleid.", NULL, 0, ".$this_uid.", ".$this->att_vill.")";
  248. if (!mysql_query ($query))
  249. {
  250. log_err ("Cannot write bat_army entry. ".$query.", error: ".mysql_error());
  251. return (false);
  252. }
  253. else
  254. {
  255. // Now we need the troop entry for this army
  256. $this->baids[$this_uid] = $reparmyid = mysql_insert_id ();
  257. return ($reparmyid);
  258. }
  259. }
  260. else
  261. return ($this->baids[$this_uid]);
  262. }
  263. private function calc_armystate ($this_troopid, $this_uid, $his_values)
  264. {
  265. global $unitscoremap, $costmap, $debug, $xpmap;
  266. if (isset ($this->idmap[$this_troopid]))
  267. {
  268. foreach ($this->idmap[$this_troopid] as $unitid=>$resultid)
  269. {
  270. $returnquery_done = false;
  271. // The hero needs special treatment again though
  272. if ($unitid == 1000)
  273. {
  274. $this->army_has_hero[$this_uid] = true;
  275. // Only update hero entry when his health has changed
  276. if ($this->result[$resultid] < 1)
  277. {
  278. log_debug ("Hero health after battle for uid ".$his_values[2001]." defuid ".$this->def_uid.": ".$this->result[$resultid]);
  279. // Defending heroes don't die so badly :)
  280. if (($his_values[2001] == $this->def_uid) && ($this->result[$resultid] <= 0))
  281. {
  282. $hero_ret_time = rand (3, 6);
  283. $this->def_hero_died = true;
  284. }
  285. else
  286. $hero_ret_time = rand (12, 24);
  287. $new_hero_health = round ($this->result[$resultid] * $this->armyinfo[$this_uid][3500], 2);
  288. if ($his_values[2001] == $this->def_uid)
  289. $this->defuser->hero->health = $new_hero_health;
  290. if ($his_values[2001] == $this->att_uid)
  291. $this->attuser->hero->health = $new_hero_health;
  292. // If the health is 0 this means the hero is lost. He will take some time to return
  293. // This time is calculated by setting the health to a negative value. Once he has healed
  294. // enough, he will return
  295. if ($new_hero_health <= 0)
  296. {
  297. $new_hero_health = -($hero_ret_time * $this->armyinfo[$this_uid][3505]);
  298. $hero_new_location = $this->in_units[$this_troopid][2002];
  299. $query = "update user set changed=changed,last_healed=now(),hero_health=".$new_hero_health.",hero_troopid=0,hero_location=".$this->in_units[$this_troopid][2002]." where uid=".$this_uid;
  300. log_debug ("Hero went down under. New health is ".$new_hero_health.", now placed in ".$hero_new_location);
  301. $this->loot_specials[$this_uid][30] = 1;
  302. // Magick the hero to his home village, since he won't be available at the moment any way
  303. $hero_query = "replace into troops select troopid,1000,1 from armies where location=".$hero_new_location." and villageid=".$hero_new_location;
  304. log_debug ("Hero under query: ".$hero_query);
  305. if (!mysql_query ($hero_query))
  306. log_err ("Cannot magick hero back to home village. Query: ".$hero_query.", ".mysql_error ());
  307. }
  308. else
  309. $query = "update user set changed=changed,last_healed=now(),hero_health=".$new_hero_health." where uid=".$this_uid;
  310. if (!mysql_query ($query))
  311. log_err ("Cannot set new hero health: ".$query.", ".mysql_error ());
  312. if ($debug)
  313. {
  314. if (isset ($atthero))
  315. {
  316. echo "<pre>Atthero:\n";
  317. print_r ($atthero);
  318. }
  319. echo "\nSpecials:\n";
  320. print_r ($this->loot_specials);
  321. echo "Hero query: ".$query;
  322. }
  323. }
  324. if ($this_uid != $this->def_uid)
  325. {
  326. // Survivors and capacity are calculated differently for heroes
  327. if (!isset ($this->survivors[$this_troopid]))
  328. {
  329. $this->survivors[$this_troopid] = $surv = ceil ($this->result[$resultid]);
  330. $cap = $this->survivors[$this_troopid] * $this->capacity[1000+$this_uid];
  331. $this->total_cap[$this_uid] += $cap;
  332. }
  333. else
  334. {
  335. $surv = ceil ($this->result[$resultid]);
  336. $this->survivors[$this_troopid] += $surv;
  337. $cap = $surv * $this->capacity[1000 + $this_uid];
  338. $this->total_cap[$this_uid] += $cap;
  339. }
  340. }
  341. else
  342. {
  343. $returnquery_done = true;
  344. $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", 1)";
  345. $this->defender_virtual_survivors = 1;
  346. if (!isset ($this->survivors[$this_troopid]))
  347. {
  348. $this->survivors[$this_troopid] = $surv = 1;
  349. $cap = $this->survivors[$this_troopid] * $this->capacity[1000+$this_uid];
  350. $this->total_cap[$this_uid] += $cap;
  351. }
  352. else
  353. {
  354. $surv = 1;
  355. $this->survivors[$this_troopid] += $surv;
  356. $cap = $surv * $this->capacity[1000 + $this_uid];
  357. $this->total_cap[$this_uid] += $cap;
  358. }
  359. }
  360. // FIXME: What scope?
  361. if (!isset ($this->repqueries[$this_uid][$unitid][0]))
  362. $this->repqueries[$this_uid][$unitid][0] = $this->repqueries[$this_uid][$unitid][1] = 0;
  363. $this->repqueries[$this_uid][$unitid][0] += ceil ($this->in_units[$this_troopid][$unitid] * 100);
  364. $this->repqueries[$this_uid][$unitid][1] += ceil (($this->in_units[$this_troopid][$unitid] - $this->result[$resultid])*100);
  365. if (!$returnquery_done)
  366. $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", ".ceil ($this->result[$resultid]).")";
  367. }
  368. else
  369. {
  370. $losses = round ($this->in_units[$this_troopid][$unitid] - $this->result[$resultid]);
  371. // Calculate how much to subtract from the users score because of unit losses
  372. $this->score_sub[$this_uid] += $unitscoremap[$unitid] * $losses;
  373. // Calculate absolute costs for the units in this group
  374. if (!isset ($this->reslosses[$this_uid][1]))
  375. $this->reslosses[$this_uid][1] = $this->reslosses[$this_uid][2] = $this->reslosses[$this_uid][3] = $this->reslosses[$this_uid][4] = 0;
  376. if (!isset ($this->unitvalue[$this_uid]))
  377. $this->unitvalue[$this_uid] = $this->unitvalueloss[$this_uid] = 0;
  378. $this->reslosses[$this_uid][1] += $costmap[$unitid][1] * $losses;
  379. $this->reslosses[$this_uid][2] += $costmap[$unitid][2] * $losses;
  380. $this->reslosses[$this_uid][3] += $costmap[$unitid][3] * $losses;
  381. $this->reslosses[$this_uid][4] += $costmap[$unitid][4] * $losses;
  382. $this->unitvalue[$this_uid] += $xpmap[$unitid] * $this->in_units[$this_troopid][$unitid];
  383. $this->unitvalueloss[$this_uid] += $xpmap[$unitid] * $losses;
  384. if (!isset ($this->rescosts[$this_uid][1]))
  385. $this->rescosts[$this_uid][1] = $this->rescosts[$this_uid][2] = $this->rescosts[$this_uid][3] = $this->rescosts[$this_uid][4] = 0;
  386. // Calculate absolute ressource loss through unit loss for this group
  387. $this->rescosts[$this_uid][1] += $costmap[$unitid][1] * $this->in_units[$this_troopid][$unitid];
  388. $this->rescosts[$this_uid][2] += $costmap[$unitid][2] * $this->in_units[$this_troopid][$unitid];
  389. $this->rescosts[$this_uid][3] += $costmap[$unitid][3] * $this->in_units[$this_troopid][$unitid];
  390. $this->rescosts[$this_uid][4] += $costmap[$unitid][4] * $this->in_units[$this_troopid][$unitid];
  391. if ($debug)
  392. {
  393. echo "Units ".$unitid.": Score-Sub ".$this->score_sub[$this_uid].": ".$losses." * ".$unitscoremap[$unitid]."\n";
  394. if (!is_array ($xpmap))
  395. echo "Fail! No xpmap!";
  396. print_r ($xpmap);
  397. print_r ($unitscoremap);
  398. }
  399. if (!isset ($this->repqueries[$this_uid][$unitid][0]))
  400. $this->repqueries[$this_uid][$unitid][0] = $this->repqueries[$this_uid][$unitid][1] = 0;
  401. $this->repqueries[$this_uid][$unitid][0] += $this->in_units[$this_troopid][$unitid];
  402. $this->repqueries[$this_uid][$unitid][1] += $losses;
  403. $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", ".round ($this->result[$resultid]).")";
  404. if ($debug)
  405. {
  406. echo "\nAfter troopid ".$this_troopid.", unitid ".$unitid." retq is ";
  407. print_r ($this->returnquery);
  408. }
  409. // If commanders where decimated we recalculate them later on
  410. if (($unitid == 19) || ($unitid == 4))
  411. {
  412. if (round ($this->result[$resultid]) != $this->in_units[$this_troopid][$unitid])
  413. $this->recalc_commanders[$this_uid] = true;
  414. }
  415. // Take note of the number of survivors for each participant, so we don't record troops
  416. // that were destroyed
  417. $surv = round ($this->result[$resultid]);
  418. if (!isset ($this->survivors[$this_troopid]))
  419. $this->survivors[$this_troopid] = 0;
  420. $this->survivors[$this_troopid] += $surv;
  421. $cap = $surv * $this->capacity[$unitid];
  422. if (!isset ($this->total_cap[$this_uid]))
  423. $this->total_cap[$this_uid] = 0;
  424. $this->total_cap[$this_uid] += $cap;
  425. }
  426. if ($his_values[2000] == 0)
  427. { // Only count total survivors for attackers here
  428. $this->total_survivors += $surv;
  429. $this->all_cap += $cap;
  430. }
  431. else
  432. $this->total_def += $surv; //And these are the surviving defenders
  433. }
  434. }
  435. }
  436. private function fake_armystate ($this_troopid, $this_uid, $his_values)
  437. {
  438. global $unitscoremap, $costmap, $debug;
  439. $bquery = NULL;
  440. $this->total_def = 0;
  441. // Otherwise, we need to construct the query from the in_units
  442. foreach ($this->in_units[$this_troopid] as $unitid=>$amount)
  443. {
  444. if ($unitid <= 1000)
  445. {
  446. // Heroes use troop amount as health
  447. if ($unitid == 1000)
  448. $amount *= 100;
  449. if ($this->bquery)
  450. $this->bquery .= ",(".$this->baids[$this_uid].", ".$unitid.", ".$amount.", 0)";
  451. else
  452. $this->bquery = "(".$this->baids[$this_uid].", ".$unitid.", ".$amount.", 0)";
  453. if ($debug)
  454. {
  455. echo "Costs for unit ".$unitid.", of which we have ".$amount.": ".$this->bquery;
  456. }
  457. // Take note of the number of survivors for each participant, so we don't record troops
  458. // that were destroyed
  459. $this->survivors[$this_troopid] += $amount;
  460. $cap = $amount * $this->capacity[$unitid];
  461. $this->total_cap[$this_uid] += $cap;
  462. if ($his_values[2000] == 0)
  463. { // Only count survivors for attackers here
  464. $this->total_survivors += $amount;
  465. $this->all_cap += $cap;
  466. }
  467. // Calculate absolute ressource costs
  468. $this->rescosts[$this_uid][1] += $costmap[$unitid][1] * $amount;
  469. $this->rescosts[$this_uid][2] += $costmap[$unitid][2] * $amount;
  470. $this->rescosts[$this_uid][3] += $costmap[$unitid][3] * $amount;
  471. $this->rescosts[$this_uid][4] += $costmap[$unitid][4] * $amount;
  472. // print_r ($this->rescosts);
  473. }
  474. }
  475. // Costs is definitely empty :)
  476. $this->reslosses[$this_uid] = array (0,0,0,0,0);
  477. }
  478. private function calculate_xp ()
  479. {
  480. global $debug;
  481. $rescosts_by_side = array ();
  482. $reslosses_by_side = array ();
  483. $xp_by_side = array ();
  484. foreach ($this->armyinfo as $this_uid=>$his_info)
  485. {
  486. if (isset ($this->unitvalue[$this_uid]))
  487. $unitvalue_total += $this->unitvalue[$this_uid];
  488. if (isset ($this->unitvalueloss[$this_uid]))
  489. $unitvalueloss_total += $this->unitvalueloss[$this_uid];
  490. }
  491. foreach ($this->armyinfo as $this_uid=>$his_info)
  492. {
  493. if (isset ($this->unitvalue[$this_uid]))
  494. $this->xp_by_uid[$this_uid] += round ($unitvalueloss_total * ($this->unitvalue[$this_uid] / $unitvalue_total) * 1000);
  495. }
  496. if ($debug)
  497. {
  498. echo "<pre>:XP by uid:\n";
  499. print_r ($this->xp_by_uid);
  500. echo "</pre>";
  501. echo "<pre>:UV by uid:\n";
  502. print_r ($this->unitvalue);
  503. echo "</pre>";
  504. echo "<pre>:UVL by uid:\n";
  505. print_r ($this->unitvalueloss);
  506. echo "</pre>";
  507. echo "UVLT: ".$unitvalueloss_total.", UVT:".$unitvalue_total."<br>";
  508. }
  509. }
  510. private function fetch_xp_by_uid ($this_uid)
  511. {
  512. if (isset ($this->xp_by_uid[$this_uid]) && isset ($this->army_has_hero[$this_uid]))
  513. return ($this->xp_by_uid[$this_uid]);
  514. else
  515. return (0);
  516. }
  517. private function set_survivors ()
  518. {
  519. global $debug;
  520. if ($debug)
  521. {
  522. echo "<pre>Repqueries:\n";
  523. print_r ($this->repqueries);
  524. echo "</pre>";
  525. }
  526. // Still can't hurt to check if there WERE troops for this guy
  527. if (count ($this->repqueries))
  528. {
  529. foreach ($this->repqueries as $repuid=>$unitentry)
  530. {
  531. foreach ($unitentry as $repunitid=>$entry)
  532. {
  533. if (isset ($query))
  534. $query .= ", (".$this->baids[$repuid].", ".$repunitid.", ".$entry[0].", ".$entry[1].")";
  535. else
  536. $query = "(".$this->baids[$repuid].", ".$repunitid.", ".$entry[0].", ".$entry[1].")";
  537. }
  538. }
  539. $query = "insert into bat_troops values ".$query;
  540. if (!mysql_query ($query))
  541. {
  542. log_err ("Cannot insert troops in postbattle.php. Query: ".$query.", error: ".mysql_error ());
  543. // return (false);
  544. }
  545. log_debug ("Battletroops: ".$query);
  546. // We just send them homeward
  547. foreach ($this->in_units as $this_troopid => $his_values)
  548. {
  549. $this_uid = $his_values[2001];
  550. if ($debug)
  551. {
  552. echo "Survivors for T ".$this_troopid." (".$this_uid."): ".$this->survivors[$this_troopid]."<br>\n";
  553. print_r ($this->returnquery[$this_troopid]);
  554. }
  555. // Only update the remaining troops infos if some survived, or the party with these losses
  556. // was the owner of the attacked village (so he can rebuild troops without having
  557. // to recreate the db structures), but this only holds
  558. // if ((($this->survivors[$this_troopid] > 0) && is_array ($this->returnquery[$this_troopid])) || ($this_uid == $this->def_uid) && ($this->in_units[1] > 0))
  559. if (is_array ($this->returnquery[$this_troopid]))
  560. {
  561. $returnquery = "replace into troops values ".implode (",", $this->returnquery[$this_troopid]);
  562. log_debug ("Returnquery for tid ".$this_troopid.", uid ".$this_uid." is ".$returnquery);
  563. if ($debug)
  564. echo "\n".$returnquery;
  565. if (!mysql_query ($returnquery))
  566. {
  567. log_err ("Cannot insert remaining troops in postbattle.php. Query: ".$returnquery.", error: ".mysql_error ());
  568. // return (false);
  569. }
  570. }
  571. else
  572. log_debug ("We didn't replace troops for ".$this_uid." (TID: ".$this_troopid.") in battle ".$this->battleid.". He didn't have any surviving troops.");
  573. }
  574. }
  575. else
  576. log_err ("Participant ".$this_uid." in battle ".$this->battleid." didn't have any troops but idmap was set.");
  577. }
  578. private function fake_survivors ()
  579. {
  580. global $debug;
  581. // Still can't hurt to check if there WERE troops for this guy
  582. if ($this->bquery)
  583. {
  584. $query = "insert into bat_troops values ".$this->bquery;
  585. if ($debug)
  586. echo "\n".$query;
  587. // log_debug ("Returnquery for fake uid ".$this_uid." is ".$returnquery);
  588. if (!mysql_query ($query))
  589. {
  590. log_err ("Cannot insert troops in user.inc.php. Query: ".$query.", error: ".mysql_error ());
  591. // return (false);
  592. }
  593. }
  594. else
  595. log_debug ("Participant in battle ".$this->battleid." didn't have any troops. idmap wasn't set but we scoured in_units.");
  596. }
  597. //Funktion zum Berechnen der kriegs-Punkte
  598. //Funktion zum Berechnen der kriegs-Punkte
  599. private function calcuteWarTmpStats()
  600. {
  601. global $debug;
  602. $aid1 = $this->armyinfo[$this->att_uid][2003]; //Allianz-Id des Angreifers
  603. $aid2 = $this->armyinfo[$this->def_uid][2003]; // Allianz-Id des Verteidigers
  604. //ueberpruefen, ob die beiden allianzen im krieg sind
  605. $query= "SELECT aid1, aid2 FROM wars WHERE ((aid1=".$aid1." AND aid2=".$aid2.") OR (aid1=".$aid2." AND aid2=".$aid1.")) AND over=0";
  606. if (!$res=mysql_query($query))
  607. log_err("postbattle.php: Problem when checking war of two alliances: ".$query);
  608. else
  609. {
  610. if ($row = mysql_fetch_array($res))
  611. {
  612. //echo "Krieg gefunden!";
  613. $war_aid1 = $row['aid1'];
  614. $war_aid2 = $row['aid2'];
  615. }
  616. }
  617. //wenn die beiden allianzen im krieg sind, werden nun die punkte berechnet
  618. //beide Seiten bekommen gutgeschrieben, wieviele Einheiten sie (in Ressourcen) vernichtet haben
  619. //der Angreifer bekommt zusaetzlich die erbeuteten Rohstoffe als Punkte und ggf Punkte fĂźr die zerstĂśrte Mauer
  620. if (isset($war_aid1) && isset($war_aid2))
  621. {
  622. if ($debug)
  623. print_r($this->resloot);
  624. $losses_att = 0;
  625. $loot = 0;
  626. $losses_def = 0;
  627. //iterate over all participants to sum all troop losses
  628. foreach ($this->armyinfo as $this_uid =>$this_info)
  629. {
  630. if (($this->armyinfo[$this_uid][2003] == $war_aid1) || ($this->armyinfo[$this_uid][2003] == $war_aid2)) //count war points just for members of the allies
  631. {
  632. if ($this->armyinfo[$this_uid][2000] == 0) //this one is an attacker
  633. {
  634. $losses_att += array_sum($this->reslosses[$this_uid]);
  635. $loot += array_sum($this->resloot[$this_uid]);
  636. }
  637. else //we have a defender here
  638. {
  639. $losses_def += array_sum($this->reslosses[$this_uid]);
  640. }
  641. }
  642. }
  643. //if ($this->wallscore > 0)
  644. // $score += $this->wallscore;
  645. //$losses_att = array_sum($this->reslosses[$this->att_uid]); // verluste des angreifers
  646. //$losses_def = array_sum($this->reslosses[$this->def_uid]); // verluste des verteidigers
  647. $score = round(($loot + $losses_def + ($this->wallscore) + ($this->outpostscore)) / 1000); //Punkte des Angreifers insgesamt
  648. $score2 = round(($losses_att) / 1000); //Punkte des Angreifers insgesamt
  649. //if ($debug)
  650. // echo "Punkte des Angreifers: ".$score.", Punkte des Verteidigers: ".$score2;
  651. if ($aid1 == $war_aid1) //ist der angreifer aid1 aus der kriegstabelle?
  652. {
  653. $aid_string = " score1 ";
  654. $aid_string2 = "score2";
  655. }
  656. else
  657. {
  658. $aid_string = " score2 ";
  659. $aid_string2 = "score1";
  660. }
  661. $query = "update war_stats_tmp set ".$aid_string."=".$aid_string."+".$score.", ".$aid_string2."=".$aid_string2."+".$score2." where aid1=".$war_aid1." AND aid2=".$war_aid2 ;
  662. if (!mysql_query($query))
  663. {
  664. log_err("Postbattle.php: Could not give score to attacker. ".$query);
  665. }
  666. log_debug("Hurra! ".$query);
  667. }
  668. }
  669. private function calculateFlags()
  670. {
  671. global $debug;
  672. //mit spaehern allein soll man keine faehnchen klauen koennen
  673. if (!($this->report_spying))
  674. {
  675. if (($this->total_def < 1) || (($this->total_def == 1) && $this->def_hero_died))
  676. {
  677. $aid1 = $this->armyinfo[$this->att_uid][2003];
  678. $aid2 = $this->armyinfo[$this->def_uid][2003];
  679. //ueberpruefen, ob die beiden allianzen im krieg sind, und ob in diesem dorf eine flagge steht
  680. $query = "select A.aid1, A.aid2, A.flag_score1, A.flag_score2, B.current_villageid from wars as A, war_flags as B where ((A.aid1=".$aid2." AND A.aid2=".$aid1.") OR (A.aid1=".$aid1." AND A.aid2=".$aid2.")) AND B.current_villageid=".$this->def_vill." AND A.aid1=B.aid1 AND A.aid2=B.aid2 and B.current_troopid=0 and A.over=0";
  681. if ($debug)
  682. echo $query;
  683. log_debug ("Flagquery: ".$query);
  684. if (!$res=mysql_query ($query))
  685. log_err ("Cannot check war of these two allies. Query: ".$query.", error:".mysql_error());
  686. else
  687. {
  688. $in_war = false;
  689. if ($row_war = mysql_fetch_array($res))
  690. {
  691. $all_war[] = $row_war;
  692. $in_war = true;
  693. }
  694. if ($in_war == true)
  695. {
  696. //jetzt kommt die eigentliche faehnchen-behanldung
  697. $query = "update war_flags set current_villageid=".$this->att_vill.",current_troopid=".$this->att_troopid." where aid1=".$all_war[0]['aid1']." and aid2=".$all_war[0]['aid2']." and current_villageid=".$this->def_vill ;
  698. if(!mysql_query($query))
  699. {
  700. log_err ("Cannot steal flag! Query: ".$query.", error: ".mysql_error());
  701. }
  702. else
  703. {
  704. log_debug("F&auml;hcnhen klauen: ".$query);
  705. $this->loot_specials[$this->att_uid][50] = $this->def_vill; // fuer berichte->"Flagge gestohlen"
  706. //FIXME Platz fuer Optimierung
  707. //nun ueberpruefen, ob das schon das dritte geklaute faehnchen ist, wenn ja, ist der Krieg beendet
  708. $query="SELECT A.*, B.name, C.user, C.uid, C.aid, D.name as current_name, E.user as curr_user, E.uid as current_uid, E.aid as current_aid FROM war_flags AS A , village AS B, user AS C, village AS D, user as E WHERE (aid1=".$all_war[0]['aid1']." AND aid2=".$all_war[0]['aid2'].") AND A.villageid=B.villageid AND B.uid=C.uid and A.current_villageid=D.villageid AND D.uid=E.uid";
  709. if (!$res=mysql_query($query))
  710. {
  711. log_err ("postbattle.php: Postbattle: cannot check end of war???.. ".$query);
  712. }
  713. else
  714. {
  715. while ($row = mysql_fetch_array($res))
  716. {
  717. //if ($row['aid'] == $this->armyinfo[$this->def_uid][2003]) // aid der def-allianz?
  718. if ($row['aid1'] == $row['aid'])
  719. {
  720. if ($row['aid'] != $row['current_aid'])
  721. {
  722. $stolen_flags1[] = $row['current_villageid'];
  723. }
  724. }
  725. else //faehnchen der angreifer-allianzt ueberpruefen
  726. {
  727. if ($row['aid'] != $row['current_aid'])
  728. {
  729. $stolen_flags2[] = $row['current_villageid'];
  730. }
  731. }
  732. }
  733. if ((count ($stolen_flags1) >=3) || (count($stolen_flags2) >=3))
  734. {
  735. $this->loot_specials[$aid2][51] = $aid1; // fuer berichte->"Krieg vorbei"
  736. $query = "update wars set over=10, causer=".$this->armyinfo[$this->att_uid][2003].",end_of_war=now() where aid1=".$all_war[0]['aid1'] ." and aid2=".$all_war[0]['aid2'];
  737. if (!mysql_query($query))
  738. log_err ("Could not update war! ".$query);
  739. $query = "update war_stats_tmp set score1=score1+(".$all_war[0]['flag_score2']."*".count($stolen_flags2)."), score2=score2+(".$all_war[0]['flag_score1']."*".count($stolen_flags1).") where aid1=".$all_war[0]['aid1'] ." AND aid2=".$all_war[0]['aid2'];
  740. if (!mysql_query($query))
  741. log_err ("POstbattle.php: Could not update warstats! ".$query);
  742. // Add ally reload diplomacy event
  743. $query = "update user set changed=changed,flags=flags|4 where aid in (".$aid1.",".$aid2.")";
  744. if (!mysql_query ($query))
  745. log_err ("Cannot add ally reload diplomacy flags after diplomacy addition. Query: ".$query.", ".mysql_error ());
  746. $query = "insert into allyactions (aid1,aid2,uid1,uid2,stamp,type) values (".$aid1.", ".$aid2.", ".$this->att_uid.", NULL, now(), 22), (".$aid2.", ".$aid1.", NULL , ".$this->att_uid.", now(), 26)";
  747. if (!mysql_query($query))
  748. {
  749. log_err("postbattle.php: could not insert allynews when cancelling war: ".$query);
  750. }
  751. log_debug ("Cancel war: ". $query);
  752. $query = "update user set allymsgs=allymsgs+1 where aid in (".$aid1.", ".$aid2.")";
  753. if (!mysql_query ($query))
  754. log_err ("Cannot update ally msg counter. Query: ".$query.", ".mysql_error ());
  755. else
  756. {
  757. if (!mysql_affected_rows ())
  758. log_err ("After updating ally msg counter no rows where affected. Query: ".$query);
  759. //ueberpruefen, wieivele Punkte die allianz bekommt, dadurch dass sie den krieg fruehzeitig beendet hat
  760. calctimeDiff ($all_war[0]['aid1'], $all_war[0]['aid2'],$this->armyinfo[$this->att_uid][2003] );
  761. //Endstatistik updaten
  762. calcStats($all_war[0]['aid1'], $all_war[0]['aid2']);
  763. }
  764. }
  765. }
  766. }
  767. }
  768. }
  769. }
  770. else
  771. {
  772. if ($debug)
  773. echo "Survivors, won't do flags: ".$this->def_hero_died;
  774. }
  775. }
  776. }
  777. private function create_reports ()
  778. {
  779. global $debug;
  780. // Again we iterate through all participants, to create final reports
  781. foreach ($this->armyinfo as $this_uid => $his_values)
  782. {
  783. if (isset ($query))
  784. $query .= ", ";
  785. else
  786. $query = "";
  787. if (isset ($this->receip_aids[(int)$his_values[2003]]))
  788. $query .= "(NULL, ".$this->battleid.", ".$this_uid.", ".$this->att_uid.", ".$this->att_vill.", ".$this->def_uid.", ".$this->def_vill.", addtime(now(),sec_to_time(".$this->timediff.")), ".($his_values[2000]+2).", 0, 0, '".$this->report_subject."', 0, '')";
  789. else
  790. {
  791. $query .= "(NULL, ".$this->battleid.", ".$this_uid.", ".$this->att_uid.", ".$this->att_vill.", ".$this->def_uid.", ".$this->def_vill.", addtime(now(),sec_to_time(".$this->timediff.")), ".($his_values[2000]+2).", 0, 0, '".$this->report_subject."', ".(int)$his_values[2003].", '')";
  792. log_debug ("Formulating report for ally id ".(int)$his_values[2003]);
  793. }
  794. $this->receip_aids[(int)$his_values[2003]] = 1;
  795. $score_to_add = round ($this->fetch_xp_by_uid ($this_uid));
  796. // We also want to check if this guy has lost troops so we reduce his score
  797. if (($this->score_sub[$this_uid] > 0) || ($score_to_add > 0))
  798. {
  799. $scorequery = "update user set changed=changed,reports=reports+1";
  800. if ($this->score_sub[$this_uid] > 0)
  801. $scorequery .= ",score=score-".$this->score_sub[$this_uid];
  802. if ($this->fetch_xp_by_uid ($this_uid) > 0)
  803. $scorequery .= ",xp=xp+".$score_to_add;
  804. $this->loot_specials[$this_uid][60] = $score_to_add;
  805. $scorequery .= " where uid=".$this_uid;
  806. if ($debug)
  807. echo "<br>Scoresub query: ".$scorequery."<br>\n";
  808. if (!mysql_query ($scorequery))
  809. log_err ("Cannot reduce score in postbattle. Query: ".$scorequery.", ".mysql_error ());
  810. }
  811. else
  812. $this->receip_uids[] = $this_uid; // For the new report notification update
  813. }
  814. if (isset ($query))
  815. {
  816. // Now we create the report entries
  817. $query = "insert into reports values ".$query;
  818. if ($debug)
  819. echo "\n".$query;
  820. if (!mysql_query ($query))
  821. {
  822. log_err ("Cannot write report entry. ".$query.", error: ".mysql_error());
  823. return (false);
  824. }
  825. }
  826. else
  827. {
  828. log_err ("Report query was empty?? Battleid ".$this->battleid);
  829. return (false);
  830. }
  831. if (count ($this->receip_uids))
  832. {
  833. // And give them all an update on their unread report count
  834. $query = "update user set changed=changed,reports=reports+1 where uid in (".implode (",", $this->receip_uids).")";
  835. if (!mysql_query ($query))
  836. log_err ("Cannot update unread report cound in postbattle. Query: ".$query.", ".mysql_error());
  837. }
  838. }
  839. private function do_siege ()
  840. {
  841. global $debug;
  842. $this->loot_specials[$this->att_uid][32] = 1;
  843. // Change owner of villages
  844. $query = "update village set uid=".$this->att_uid.",original_uid=".$this->att_uid.",outpost_of=".$this->att_vill." where villageid=".$this->def_vill;
  845. if (!mysql_query ($query))
  846. log_err ("Cannot set village to new owner after siege. Query: ".$query.", ".mysql_error ());
  847. // Change owner of ress tiles
  848. $query = "update tileres set uid=".$this->att_uid.",time_exhaust=time_exhaust where villageid=".$this->def_vill;
  849. if (!mysql_query ($query))
  850. log_err ("Cannot set ress tiles to new owner after siege. Query: ".$query.", ".mysql_error ());
  851. // Change owner of army
  852. $query = "update armies set uid=".$this->att_uid." where flag=0 and villageid=".$this->def_vill;
  853. if (!mysql_query ($query))
  854. log_err ("Cannot set army to new owner after siege. Query: ".$query.", ".mysql_error ());
  855. // Now even for outposts there might be stray events for them
  856. $query = "update event set uid2=".$this->att_uid." where village2=".$this->def_vill;
  857. if (!mysql_query ($query))
  858. log_err ("Cannot set stray events to new owner after siege. Query: ".$query.", ".mysql_error ());
  859. //TBD: as this is a successful siege, the atacker gains additional war score for conquering this outpost
  860. //$costs = pow ($numvillages, 2)*5000; costs4/2
  861. $numvillages = count ($this->defuser->allvillageids);
  862. $costs = pow (($numvillages-1), 2)*5000; //costs4/2
  863. $this->outpostscore = ($costs*4) ;
  864. log_debug("additional war score for conquering outpost: ".$this->outpostscore);
  865. }
  866. private function send_troops_home_nobattle ()
  867. {
  868. // We just send them homeward
  869. foreach ($this->in_units as $this_troopid => $his_values)
  870. {
  871. // Is this an attacker? Defenders don't need to be set to RETURNING state
  872. if ($his_values[2000] == 0)
  873. {
  874. $this->post_state = 10;
  875. $this->add_event ($this_troopid, $his_values[2001], $his_values[2002]);
  876. }
  877. }
  878. }
  879. private function add_event ($this_troopid, $uid, $homevillage)
  880. {
  881. global $debug;
  882. if (($this->return_duration > abs ($this->timediff)) || !$this->do_local)
  883. {
  884. $event_query = "insert into event (uid1, village1, uid2, village2, timestamp, type, param, param2, flag) values (".$uid.", ".$homevillage.", 0, ".$this->def_vill.", addtime(now(), sec_to_time(".($this->timediff+$this->return_duration).")), 10, ".$this_troopid.", ".$this->battleid.", 0)";
  885. if ($debug) echo "\n".$event_query;
  886. }
  887. else
  888. {
  889. // If not, then we just concoct a local event
  890. $this->return_event[] = array ("eid"=>0, "timestamp"=>date ("Y-m-d H:i:s", time() + $this->timediff), "score"=>0,
  891. "uid1" => $uid, "village1" => $homevillage, "uid2" => 0, "village2" => $this->def_vill,
  892. "dif" => ($this->return_duration + $this->timediff), "type"=>10, "param"=>$this_troopid,
  893. "param2"=>$this->battleid, "flag"=>0);
  894. log_debug ("Adding local return event: ".array_to_str (end($this->return_event)));
  895. }
  896. // So units survived. Set them to returning/siege
  897. $query = "update armies set flag=".$this->post_state." where troopid=".$this_troopid;
  898. if ($debug)
  899. echo "\n".$query;
  900. if (!mysql_query ($query))
  901. {
  902. log_err ("Cannot set troops to ".$this->post_state." state in combat battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
  903. }
  904. // Insert the event for the trip home only if this won't be handled
  905. // by this event handler run
  906. if (($this->return_duration > abs ($this->timediff)) || !$this->do_local)
  907. {
  908. log_debug ("Adding return event ".$event_query);
  909. if (!@mysql_query ($event_query))
  910. {
  911. log_err ("Cannot insert ".$this->post_state." event: ".$event_query.", error: ".mysql_error ());
  912. return (false);
  913. }
  914. }
  915. }
  916. private function send_troops_home ()
  917. {
  918. global $debug;
  919. // Yes, there was a battle. Test each group to see if they were destroyed.
  920. foreach ($this->in_units as $this_troopid => $his_values)
  921. {
  922. // Differentiate between attackers and defenders. Defenders will retain their
  923. // army entry even if all members have died, so that the user can recruit easily again
  924. if ($his_values[2000] == 0)
  925. {
  926. if ($debug)
  927. echo "\nTroopid ".$this_troopid." is attacker and has ".$this->survivors[$this_troopid]." survivors";
  928. if ($this->survivors[$this_troopid] <= 0)
  929. {
  930. // This group has died. Delete the troopid (FIXME: OPTIMIZEME)
  931. $query = "delete from armies where troopid=".$this_troopid;
  932. if ($debug)
  933. echo "\n".$query;
  934. if (!mysql_query ($query))
  935. {
  936. log_err ("Cannot delete perished troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
  937. // return (false);
  938. }
  939. $query = "delete from troops where troopid=".$this_troopid;
  940. if ($debug)
  941. echo "\n".$query;
  942. if (!mysql_query ($query))
  943. {
  944. log_err ("Cannot delete perished troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
  945. // return (false);
  946. }
  947. log_debug ("Deleting perished troop ".$this_troopid." in battle ".$this->battleid);
  948. }
  949. else
  950. $this->add_event ($this_troopid, $his_values[2001], $his_values[2002]);
  951. }
  952. else
  953. {
  954. // For defenders, we only delete armies that where aiding somebody else, not the native army
  955. // of the city
  956. if (($this->survivors[$this_troopid] <= 0) && ($his_values[2002] != $this->def_vill))
  957. {
  958. if ($debug)
  959. {
  960. echo "Deleting this guy with ".$this->survivors[$this_troopid].":";
  961. print_r ($his_values);
  962. }
  963. // This group has died. Delete the troopid (FIXME: OPTIMIZEME)
  964. $query = "delete from armies where troopid=".$this_troopid;
  965. if ($debug)
  966. echo "\n".$query;
  967. if (!mysql_query ($query))
  968. {
  969. log_err ("Cannot delete perished aiding troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
  970. return (false);
  971. }
  972. $query = "delete from troops where troopid=".$this_troopid;
  973. if ($debug)
  974. echo "\n".$query;
  975. if (!mysql_query ($query))
  976. {
  977. log_err ("Cannot delete perished aiding troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
  978. return (false);
  979. }
  980. }
  981. }
  982. } // foreach
  983. }
  984. private function loot ()
  985. {
  986. global $debug;
  987. $this->loot_query = "";
  988. // We're also interested in loot, ain't we? :) But only if there where survivors
  989. if ($this->total_survivors > 0)
  990. {
  991. // We need to find out if there are thieves among the attackers
  992. $thieves_here = false;
  993. $best_looting = 0;
  994. foreach ($this->armyinfo as $this_uid => $his_values)
  995. {
  996. // Only check this for attackers
  997. if ($his_values[2000] == 0)
  998. {
  999. // Is it a thief, baggins?
  1000. if ($his_values[3520] == 2)
  1001. $thieves_here = true; // Yup
  1002. // Also check which of the attackers has the best hero loot ability
  1003. if ($his_values[3514] > $best_looting)
  1004. $best_looting = $his_values[3514];
  1005. }
  1006. }
  1007. // But max out loot bonus at 100%, we can't loot more than is there...
  1008. $best_looting = 1 + (min (100, $best_looting) / 100);
  1009. // The defending hero can also make sure that gold loot stays low
  1010. if ($this->armyinfo[$this->def_uid][3513] > 0)
  1011. $hero_hidden = max (0, 1 - ($this->armyinfo[$this->def_uid][3513] / 100));
  1012. else
  1013. $hero_hidden = 1;
  1014. $loot = array();
  1015. $total_loot = 0;
  1016. if ($debug)
  1017. echo "Thieves here is ".$thieves_here.", best_loot is ".$best_looting.", hero_hidden is ".$hero_hidden."\n";
  1018. // If this was an outpost that was just attacked, there are no hidden ressources
  1019. if ($this->def_vill != $this->village_obj->villageid)
  1020. {
  1021. if (!isset ($this->village_obj->outposts[$this->def_vill]))
  1022. log_err ("Outpost not there either in postbattle!!!");
  1023. else
  1024. {
  1025. // We should have the time since the last attack in the stamp field for outposts
  1026. $storage = min (3600, ($this->village_obj->outposts[$this->def_vill]->secs_passed + $this->timediff)) / 3600;
  1027. for ($currency = 1; $currency < 5; ++$currency)
  1028. {
  1029. if ($currency != 4)
  1030. $loot[$currency] = min ((int)($this->village_obj->outposts[$this->def_vill]->ress_prod[$currency] * $storage), $this->village_obj->ress_val ($currency));
  1031. else
  1032. {
  1033. // Thieves can steal big amounts of gold
  1034. if ($thieves_here)
  1035. $loot[$currency] = (int)(min ((int)($this->village_obj->outposts[$this->def_vill]->ress_prod[$currency] * $storage), $this->village_obj->ress_val ($currency))) / (2 / $best_looting) * $hero_hidden;
  1036. else
  1037. $loot[$currency] = (int)(min ((int)($this->village_obj->outposts[$this->def_vill]->ress_prod[$currency] * $storage), $this->village_obj->ress_val ($currency))) / (10 / $best_looting) * $hero_hidden;
  1038. }
  1039. if ($debug)
  1040. echo "Outpostloot 1: ".$this->village_obj->outposts[$this->def_vill]->ress_prod[$currency]." * ".$storage." ". ($this->village_obj->outposts[$this->def_vill]->secs_passed)." passed, max in village ".$this->village_obj->ress_val ($currency).", loot is ".$loot[$currency]."\n";
  1041. $total_loot += $loot[$currency];
  1042. }
  1043. $query = "update village set stamp=addtime(now(), sec_to_time(".$this->timediff.")) where villageid=".$this->def_vill;
  1044. if ($debug)
  1045. echo "Touchquery: ".$query;
  1046. if (!mysql_query ($query))
  1047. log_err ("Cannot touch outpost after raid. Query: ".$query.", ".mysql_error());
  1048. }
  1049. }
  1050. else
  1051. {
  1052. foreach ($this->village_obj->ress_prod as $currency => $amount)
  1053. $hidden[$currency] = calculate_hidden_storage($amount, $this->village_obj->ress_max);
  1054. log_debug ("Storage level ".$row[0].", hidden ".$hidden[1].", ".$hidden[2].", ".$hidden[3].", ".$hidden[4]);
  1055. // Ok, let's see how many ressources are here
  1056. for ($currency = 1; $currency <= 4; ++$currency)
  1057. {
  1058. $amount = $this->village_obj->ress_val ($currency);
  1059. if ($currency != 4)
  1060. $loot[$currency] = max(0, $amount - $hidden[$currency]);
  1061. else
  1062. {
  1063. // Thieves can steal big amounts of gold
  1064. if ($thieves_here)
  1065. $loot[$currency] = max(0, (int)(($amount - $hidden[$currency]) / 2));
  1066. else
  1067. $loot[$currency] = max(0, (int)(($amount - $hidden[$currency]) / 10));
  1068. }
  1069. $total_loot += $loot[$currency];
  1070. }
  1071. // Do we need the offers from the marketplace?
  1072. if ($this->all_cap > $total_loot)
  1073. {
  1074. // Now we check the market for ressources on sale
  1075. $query = "select * from offers where villageid=".$this->def_vill;
  1076. if ($debug)
  1077. echo "offerquery: ".$query;
  1078. if (!($res = mysql_query ($query)))
  1079. {
  1080. log_err ("Cannot fetch marketplace offers in postbattle. Query: ".$query.", ".mysql_error());
  1081. }
  1082. else
  1083. {
  1084. while ($row = mysql_fetch_array ($res))
  1085. {
  1086. if ($total_loot < $this->all_cap)
  1087. {
  1088. $loot[$row['offerkind']] += $row['offersize'];
  1089. $this->village_obj->spend_type ($row['offerkind'], -$row['offersize']);
  1090. $deloffers[] = $row['offerid'];
  1091. $total_loot += $row['offersize'];
  1092. }
  1093. else
  1094. break;
  1095. }
  1096. if (isset ($deloffers))
  1097. {
  1098. $query = "delete from offers where offerid in (".implode (",", $deloffers).")";
  1099. if ($debug)
  1100. echo "offerdelquery: ".$query;
  1101. if (!mysql_query ($query))
  1102. log_err ("Cannot delete offers in postbattle. Query: ".$query.", ".mysql_error());
  1103. }
  1104. }
  1105. }
  1106. if ($debug)
  1107. echo "Hidden: ".$hidden;
  1108. }
  1109. if ($debug)
  1110. print_r ($loot);
  1111. // echo "Total loot: ".$total_loot." All cap: ".$all_cap;
  1112. if ($total_loot > 0)
  1113. {
  1114. $this->loot_prefix = "";
  1115. foreach ($this->armyinfo as $this_uid => $his_values)
  1116. {
  1117. if ($his_values[2000] == 0) // Only attackers get loot
  1118. {
  1119. // echo "Survivors: ".$survivors[$this_uid].", my cap ".$total_cap[$this_uid];
  1120. if ($this->total_cap[$this_uid] > 0)
  1121. {
  1122. $share = array ();
  1123. $share_fac = ($this->total_cap[$this_uid] / $this->all_cap); // Each and every one his share :)
  1124. $this_loot[1] = (int)($loot[1] * $share_fac);
  1125. $this_loot[2] = (int)($loot[2] * $share_fac);
  1126. $this_loot[3] = (int)($loot[3] * $share_fac);
  1127. $this_loot[4] = (int)($loot[4] * $share_fac);
  1128. $to_divide = min ($this->total_cap[$this_uid], $this_loot[1] + $this_loot[2] + $this_loot[3] + $this_loot[4]);
  1129. $remaining_cap = $this->total_cap[$this_uid];
  1130. // Now we loop until all has been divided
  1131. while ($to_divide > 0)
  1132. {
  1133. $num_currencies = 0;
  1134. $to_divide = 0;
  1135. // Check each ressource for availability
  1136. foreach ($this_loot as $currency => $amount)
  1137. {
  1138. if ($amount > 0)
  1139. {
  1140. $num_currencies++;
  1141. $to_divide += $amount;
  1142. }
  1143. }
  1144. $to_divide = min ($remaining_cap, $to_divide);
  1145. // Now divide the remaining loot share through the number of currencies
  1146. // and try to move the result to the attacker
  1147. $left = ceil ($to_divide / $num_currencies);
  1148. foreach ($this_loot as $currency => $amount)
  1149. {
  1150. if ($amount > 0)
  1151. {
  1152. $subtract = min ($amount, $left);
  1153. $this_loot[$currency] -= $subtract;
  1154. $this->village_obj->spend_type ($currency, $subtract);
  1155. if (!isset ($share[$currency]))
  1156. $share[$currency] = $subtract;
  1157. else
  1158. $share[$currency] += $subtract;
  1159. $to_divide -= $subtract;
  1160. $remaining_cap -= $subtract;
  1161. // echo "And is now ".$this_loot[$currency]."\n";
  1162. }
  1163. }
  1164. }
  1165. if ($debug)
  1166. {
  1167. echo "share:";
  1168. print_r ($share);
  1169. }
  1170. // Now pass the loot on in the rep_loot entries
  1171. foreach ($share as $currency => $amount)
  1172. {
  1173. $this->resloot[$this_uid][$currency] = $amount;
  1174. if ($amount > 0)
  1175. {
  1176. $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($currency-1).", ".$this_uid.", ".$amount.")";
  1177. $this->loot_prefix = ",";
  1178. }
  1179. }
  1180. } // No survivors, no loot
  1181. } // was a defender
  1182. } // foreach
  1183. } // No loot there
  1184. } // nobody returns home :(
  1185. }
  1186. function doLootSpecial ()
  1187. {
  1188. global $debug;
  1189. // If we need to set specials in the loot
  1190. // This is actually ugly since it doesn't only contain uids as the primary
  1191. // index, but also aid's :o
  1192. if (is_array ($this->loot_specials))
  1193. {
  1194. foreach ($this->loot_specials as $this_uid => $this_loot_sp)
  1195. {
  1196. foreach ($this_loot_sp as $coin => $param)
  1197. {
  1198. $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".$coin.", ".$this_uid.", ".$param.")";
  1199. $this->loot_prefix = ",";
  1200. }
  1201. if ($debug)
  1202. {
  1203. echo "<pre>Loot specials:";
  1204. print_r ($this->loot_specials);
  1205. echo "</pre>";
  1206. echo $this->loot_query;
  1207. }
  1208. }
  1209. }
  1210. foreach ($this->armyinfo as $this_uid => $his_values)
  1211. {
  1212. if (isset ($this->rescosts[$this_uid][1]))
  1213. {
  1214. foreach ($this->rescosts[$this_uid] as $coin => $param)
  1215. {
  1216. $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($coin+7).", ".$this_uid.", ".$param.")";
  1217. $this->loot_prefix = ",";
  1218. }
  1219. if ($debug)
  1220. {
  1221. echo "<pre>Loot specials:";
  1222. print_r ($this->rescosts);
  1223. echo "</pre>";
  1224. echo $this->loot_query;
  1225. }
  1226. }
  1227. if (isset ($this->reslosses[$this_uid][1]))
  1228. {
  1229. foreach ($this->reslosses[$this_uid] as $coin => $param)
  1230. {
  1231. $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($coin+3).", ".$this_uid.", ".$param.")";
  1232. $this->loot_prefix = ",";
  1233. }
  1234. if ($debug)
  1235. {
  1236. echo "<pre>Loot specials:";
  1237. print

Large files files are truncated, but you can click here to view the full file