/php/postbattle.php
PHP | 1678 lines | 1312 code | 203 blank | 163 comment | 245 complexity | 815a9fb1d713137469bfabe3e6b657cc MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1
- <?php
- /* postbattle.php - Back-end code that handles post-battle stuff: Report generation, troop return
- *
- * Copyright (C) 2006, 2007, 2008 Kevin Read, Simone Schaefer
- *
- * This file is part of Selador, a browser-based fantasy strategy game
- *
- * This program is distributed under the terms of the GNU Affero General Public License.
- *
- *
- * Selador is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * Selador is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Selador. If not, see <http://www.gnu.org/licenses/>.
- **/
- // Fairly nice code
- // See method post_battle at the end of the file for what happens
- // here in what order
- require_once ("event.php");
- require_once ("unitmap.php");
- require_once("war_functions.php");
- define ("OUTPOST_SIEGE_DURATION", 48); // in hours
- define ("CITY_SIEGE_DURATION", 120); // in hours
- class Postbattle
- {
- public $village_obj; // This references the outside village object so ressources are really subtracted
- public $targetvill_obj;
- private $att_uid;
- private $att_vill;
- private $def_uid;
- private $def_vill;
- private $type;
- private $timediff;
- private $in_units;
- private $result;
- private $idmap;
- private $return_duration;
- private $capacity;
- private $report_spying;
- private $armyinfo;
- private $do_local;
- private $extra_results;
- private $att_troopid;
- private $att_class;
- private $survivors;
- private $defender_virtual_survivors = 0;
- private $total_survivors;
- private $total_cap;
- private $total_def;
- private $all_cap;
- // Stuff for housekeeping and data storage
- private $battleid;
- private $baids = array ();
- private $repqueries = array();
- private $score_sub = array ();
- private $receip_uids = array();
- private $receip_aids = array ();
- private $xp_by_uid = array ();
- private $unitvalue = array ();
- private $unitvalueloss = array ();
- private $return_event;
- private $bquery = null;
- private $def_hero_died = false;
- private $grattid = 0;
- private $wallscore = 0;
- private $outpostscore = 0;
- // Stuff for report generation
- private $loot_specials;
- private $reslosses; //<--------------verluste (array; 1.index = uid, 2. index rohstoffart
- private $resloot; // <----------------------resloot[$this_uid][$currency]
- private $rescosts;
- private $report_subject;
- private $loot_query;
- private $loot_prefix;
- private $army_has_hero = array ();
- // Which uids need to recalculate commanders?
- private $recalc_commanders;
- // Siege stuff
- private $notify_besieger;
- private $notify_besieged;
- private $post_state;
- private $attacker_returns;
- private $attuser;
- private $defuser;
- public $siege_successful = false;
- 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)
- {
- global $debug;
- if ($_SESSION['always_debug'])
- $debug = true;
- $this->attuser = $attuser;
- $this->defuser = $defuser;
- $this->att_uid = $att_uid;
- $this->att_vill = $att_vill;
- $this->def_uid = $def_uid;
- $this->def_vill = $def_vill;
- $this->type = $type;
- $this->timediff = $timediff;
- $this->in_units = $in_units;
- $this->result = $result;
- $this->idmap = $idmap;
- $this->return_duration = $return_duration;
- if ($capacity)
- $this->capacity = $capacity;
- else
- $this->fetch_capacity ();
- $this->village_obj = $village_obj;
- $this->targetvill_obj = $tv_obj;
- $this->report_spying = $report_spying;
- $this->armyinfo = $armyinfo;
- $this->do_local = $do_local;
- $this->extra_results = $extra_results;
- $this->att_troopid = $att_troopid;
- $this->grattid = $grattid;
- if ($debug)
- {
- echo "in_units:<br>\n";
- print_r ($this->in_units);
- echo "results:<br>\n";
- print_r ($this->result);
- echo "idmap:<br>\n";
- print_r ($this->idmap);
- echo "armyinfo:<br>\n";
- print_r ($this->armyinfo);
- echo "extra results:<br>\n";
- print_r ($this->extra_results);
- }
- $this->return_event = array();
- // We'll note the surviving units ordered by uid here later
- $this->survivors = array();
- // All survivors, to check if we need to calculate loot
- $this->total_survivors = 0;
- // Total carrying capacity of each side
- $this->total_cap = array ();
- // All carrying capacities summed up, to divide the loot
- $this->all_cap = 0;
- // Sanity checks
- if (!is_array ($this->idmap) || !count ($this->idmap))
- unset ($this->idmap);
- $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;
- if (!($res = mysql_query ($query)))
- {
- log_err ("Error while looking up names for report in user.inc.php. Query: ".$query.". Error: ".mysql_error());
- }
- else
- {
- if ($row = mysql_fetch_array ($res))
- {
- // If there were no defenders in the target village, result and idmap are empty
- // We will need to add the uid of the defender manually to in_units
- if (!isset ($this->armyinfo[$this->def_uid]))
- {
- $this->armyinfo[$this->def_uid][2000] = 1;
- $this->armyinfo[$this->def_uid][2003] = $row['aid'];
- $this->armyinfo[$this->def_uid][3000] = $this->armyinfo[$this->def_uid][3001] = $this->armyinfo[$this->def_uid][3002] = $this->armyinfo[$this->def_uid][3003];
- }
- $this->att_class = $row['attclass'];
- // Is this an attack on an outpost?
- if ($this->targetvill_obj)
- {
- $vname = $this->targetvill_obj->name;
- $vz = $this->targetvill_obj->give_z ();
- }
- else
- {
- $vname = $this->village_obj->name;
- $vz = $this->village_obj->give_z ();
- }
- // So now we have the name of the attacker and the owner of the attacked village
- if ($this->report_spying)
- {
- $this->report_subject = mysql_real_escape_string (profile_link ($this->att_uid, $row['off']).' späht <a href="land.php?z='.$vz.'">'.$vname.'</a> von '.profile_link ($this->def_uid, $row['def']).' aus');
- // If this was a spying attempt, also add a note to the user explaining the battle
- $this->loot_specials[$this->att_uid][70] = 1;
- $this->loot_specials[$this->def_uid][71] = 1;
- }
- else
- {
- switch ($this->type)
- {
- case ATTACK:
- $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");
- break;
- case RAID:
- $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");
- break;
- case SIEGE:
- $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>");
- break;
- case GROUPATTACK:
- $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");
- break;
- }
- }
- // Next we insert a new battle entry
- $query = "insert into battles values (NULL, ".$this->type.")";
- if (!mysql_query ($query))
- {
- log_err ("Cannot insert battle entry. ".$query.", ".mysql_error());
- return (false);
- }
- else
- {
- $this->battleid = mysql_insert_id ();
- // Do stuff here
- }
- }
- else
- {
- log_err ("No names found while looking up names for report in user.inc.php. Query: ".$query);
- return (false);
- }
- }
- }
- private function fetch_capacity ()
- {
- $this->capacity = array ();
- $query = "select unitid, capacity from units";
- if (!($res = mysql_query ($query)))
- {
- log_err ("Cannot fetch capacity for all units. Query ".$query.", ".mysql_error ());
- }
- else
- {
- while ($row = mysql_fetch_row ($res))
- {
- $this->capacity[$row[0]] = $row[1];
- }
- }
- }
- private function insert_battle_army ($this_uid, $his_values)
- {
- if (!isset ($this->baids[$this_uid]))
- {
- $this->score_sub[$this_uid] = 0;
- if ($his_values[2000] == 1) // Is this a defender?
- $query = "insert into bat_armies values (".$this->battleid.", NULL, 1, ".$this_uid.", ".$this->def_vill.")";
- else
- $query = "insert into bat_armies values (".$this->battleid.", NULL, 0, ".$this_uid.", ".$this->att_vill.")";
- if (!mysql_query ($query))
- {
- log_err ("Cannot write bat_army entry. ".$query.", error: ".mysql_error());
- return (false);
- }
- else
- {
- // Now we need the troop entry for this army
- $this->baids[$this_uid] = $reparmyid = mysql_insert_id ();
- return ($reparmyid);
- }
- }
- else
- return ($this->baids[$this_uid]);
- }
- private function calc_armystate ($this_troopid, $this_uid, $his_values)
- {
- global $unitscoremap, $costmap, $debug, $xpmap;
- if (isset ($this->idmap[$this_troopid]))
- {
- foreach ($this->idmap[$this_troopid] as $unitid=>$resultid)
- {
- $returnquery_done = false;
- // The hero needs special treatment again though
- if ($unitid == 1000)
- {
- $this->army_has_hero[$this_uid] = true;
- // Only update hero entry when his health has changed
- if ($this->result[$resultid] < 1)
- {
- log_debug ("Hero health after battle for uid ".$his_values[2001]." defuid ".$this->def_uid.": ".$this->result[$resultid]);
- // Defending heroes don't die so badly :)
- if (($his_values[2001] == $this->def_uid) && ($this->result[$resultid] <= 0))
- {
- $hero_ret_time = rand (3, 6);
- $this->def_hero_died = true;
- }
- else
- $hero_ret_time = rand (12, 24);
- $new_hero_health = round ($this->result[$resultid] * $this->armyinfo[$this_uid][3500], 2);
- if ($his_values[2001] == $this->def_uid)
- $this->defuser->hero->health = $new_hero_health;
- if ($his_values[2001] == $this->att_uid)
- $this->attuser->hero->health = $new_hero_health;
- // If the health is 0 this means the hero is lost. He will take some time to return
- // This time is calculated by setting the health to a negative value. Once he has healed
- // enough, he will return
- if ($new_hero_health <= 0)
- {
- $new_hero_health = -($hero_ret_time * $this->armyinfo[$this_uid][3505]);
- $hero_new_location = $this->in_units[$this_troopid][2002];
- $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;
- log_debug ("Hero went down under. New health is ".$new_hero_health.", now placed in ".$hero_new_location);
- $this->loot_specials[$this_uid][30] = 1;
- // Magick the hero to his home village, since he won't be available at the moment any way
- $hero_query = "replace into troops select troopid,1000,1 from armies where location=".$hero_new_location." and villageid=".$hero_new_location;
- log_debug ("Hero under query: ".$hero_query);
- if (!mysql_query ($hero_query))
- log_err ("Cannot magick hero back to home village. Query: ".$hero_query.", ".mysql_error ());
- }
- else
- $query = "update user set changed=changed,last_healed=now(),hero_health=".$new_hero_health." where uid=".$this_uid;
- if (!mysql_query ($query))
- log_err ("Cannot set new hero health: ".$query.", ".mysql_error ());
- if ($debug)
- {
- if (isset ($atthero))
- {
- echo "<pre>Atthero:\n";
- print_r ($atthero);
- }
- echo "\nSpecials:\n";
- print_r ($this->loot_specials);
- echo "Hero query: ".$query;
- }
- }
- if ($this_uid != $this->def_uid)
- {
- // Survivors and capacity are calculated differently for heroes
- if (!isset ($this->survivors[$this_troopid]))
- {
- $this->survivors[$this_troopid] = $surv = ceil ($this->result[$resultid]);
- $cap = $this->survivors[$this_troopid] * $this->capacity[1000+$this_uid];
- $this->total_cap[$this_uid] += $cap;
- }
- else
- {
- $surv = ceil ($this->result[$resultid]);
- $this->survivors[$this_troopid] += $surv;
- $cap = $surv * $this->capacity[1000 + $this_uid];
- $this->total_cap[$this_uid] += $cap;
- }
- }
- else
- {
- $returnquery_done = true;
- $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", 1)";
- $this->defender_virtual_survivors = 1;
- if (!isset ($this->survivors[$this_troopid]))
- {
- $this->survivors[$this_troopid] = $surv = 1;
- $cap = $this->survivors[$this_troopid] * $this->capacity[1000+$this_uid];
- $this->total_cap[$this_uid] += $cap;
- }
- else
- {
- $surv = 1;
- $this->survivors[$this_troopid] += $surv;
- $cap = $surv * $this->capacity[1000 + $this_uid];
- $this->total_cap[$this_uid] += $cap;
- }
- }
- // FIXME: What scope?
- if (!isset ($this->repqueries[$this_uid][$unitid][0]))
- $this->repqueries[$this_uid][$unitid][0] = $this->repqueries[$this_uid][$unitid][1] = 0;
- $this->repqueries[$this_uid][$unitid][0] += ceil ($this->in_units[$this_troopid][$unitid] * 100);
- $this->repqueries[$this_uid][$unitid][1] += ceil (($this->in_units[$this_troopid][$unitid] - $this->result[$resultid])*100);
- if (!$returnquery_done)
- $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", ".ceil ($this->result[$resultid]).")";
- }
- else
- {
- $losses = round ($this->in_units[$this_troopid][$unitid] - $this->result[$resultid]);
- // Calculate how much to subtract from the users score because of unit losses
- $this->score_sub[$this_uid] += $unitscoremap[$unitid] * $losses;
- // Calculate absolute costs for the units in this group
- if (!isset ($this->reslosses[$this_uid][1]))
- $this->reslosses[$this_uid][1] = $this->reslosses[$this_uid][2] = $this->reslosses[$this_uid][3] = $this->reslosses[$this_uid][4] = 0;
- if (!isset ($this->unitvalue[$this_uid]))
- $this->unitvalue[$this_uid] = $this->unitvalueloss[$this_uid] = 0;
- $this->reslosses[$this_uid][1] += $costmap[$unitid][1] * $losses;
- $this->reslosses[$this_uid][2] += $costmap[$unitid][2] * $losses;
- $this->reslosses[$this_uid][3] += $costmap[$unitid][3] * $losses;
- $this->reslosses[$this_uid][4] += $costmap[$unitid][4] * $losses;
- $this->unitvalue[$this_uid] += $xpmap[$unitid] * $this->in_units[$this_troopid][$unitid];
- $this->unitvalueloss[$this_uid] += $xpmap[$unitid] * $losses;
- if (!isset ($this->rescosts[$this_uid][1]))
- $this->rescosts[$this_uid][1] = $this->rescosts[$this_uid][2] = $this->rescosts[$this_uid][3] = $this->rescosts[$this_uid][4] = 0;
- // Calculate absolute ressource loss through unit loss for this group
- $this->rescosts[$this_uid][1] += $costmap[$unitid][1] * $this->in_units[$this_troopid][$unitid];
- $this->rescosts[$this_uid][2] += $costmap[$unitid][2] * $this->in_units[$this_troopid][$unitid];
- $this->rescosts[$this_uid][3] += $costmap[$unitid][3] * $this->in_units[$this_troopid][$unitid];
- $this->rescosts[$this_uid][4] += $costmap[$unitid][4] * $this->in_units[$this_troopid][$unitid];
- if ($debug)
- {
- echo "Units ".$unitid.": Score-Sub ".$this->score_sub[$this_uid].": ".$losses." * ".$unitscoremap[$unitid]."\n";
- if (!is_array ($xpmap))
- echo "Fail! No xpmap!";
- print_r ($xpmap);
- print_r ($unitscoremap);
- }
- if (!isset ($this->repqueries[$this_uid][$unitid][0]))
- $this->repqueries[$this_uid][$unitid][0] = $this->repqueries[$this_uid][$unitid][1] = 0;
- $this->repqueries[$this_uid][$unitid][0] += $this->in_units[$this_troopid][$unitid];
- $this->repqueries[$this_uid][$unitid][1] += $losses;
- $this->returnquery[$this_troopid][] = "(".$this_troopid.", ".$unitid.", ".round ($this->result[$resultid]).")";
- if ($debug)
- {
- echo "\nAfter troopid ".$this_troopid.", unitid ".$unitid." retq is ";
- print_r ($this->returnquery);
- }
- // If commanders where decimated we recalculate them later on
- if (($unitid == 19) || ($unitid == 4))
- {
- if (round ($this->result[$resultid]) != $this->in_units[$this_troopid][$unitid])
- $this->recalc_commanders[$this_uid] = true;
- }
- // Take note of the number of survivors for each participant, so we don't record troops
- // that were destroyed
- $surv = round ($this->result[$resultid]);
- if (!isset ($this->survivors[$this_troopid]))
- $this->survivors[$this_troopid] = 0;
- $this->survivors[$this_troopid] += $surv;
- $cap = $surv * $this->capacity[$unitid];
- if (!isset ($this->total_cap[$this_uid]))
- $this->total_cap[$this_uid] = 0;
- $this->total_cap[$this_uid] += $cap;
- }
- if ($his_values[2000] == 0)
- { // Only count total survivors for attackers here
- $this->total_survivors += $surv;
- $this->all_cap += $cap;
- }
- else
- $this->total_def += $surv; //And these are the surviving defenders
- }
- }
- }
- private function fake_armystate ($this_troopid, $this_uid, $his_values)
- {
- global $unitscoremap, $costmap, $debug;
- $bquery = NULL;
- $this->total_def = 0;
- // Otherwise, we need to construct the query from the in_units
- foreach ($this->in_units[$this_troopid] as $unitid=>$amount)
- {
- if ($unitid <= 1000)
- {
- // Heroes use troop amount as health
- if ($unitid == 1000)
- $amount *= 100;
- if ($this->bquery)
- $this->bquery .= ",(".$this->baids[$this_uid].", ".$unitid.", ".$amount.", 0)";
- else
- $this->bquery = "(".$this->baids[$this_uid].", ".$unitid.", ".$amount.", 0)";
- if ($debug)
- {
- echo "Costs for unit ".$unitid.", of which we have ".$amount.": ".$this->bquery;
- }
- // Take note of the number of survivors for each participant, so we don't record troops
- // that were destroyed
- $this->survivors[$this_troopid] += $amount;
- $cap = $amount * $this->capacity[$unitid];
- $this->total_cap[$this_uid] += $cap;
- if ($his_values[2000] == 0)
- { // Only count survivors for attackers here
- $this->total_survivors += $amount;
- $this->all_cap += $cap;
- }
- // Calculate absolute ressource costs
- $this->rescosts[$this_uid][1] += $costmap[$unitid][1] * $amount;
- $this->rescosts[$this_uid][2] += $costmap[$unitid][2] * $amount;
- $this->rescosts[$this_uid][3] += $costmap[$unitid][3] * $amount;
- $this->rescosts[$this_uid][4] += $costmap[$unitid][4] * $amount;
- // print_r ($this->rescosts);
- }
- }
- // Costs is definitely empty :)
- $this->reslosses[$this_uid] = array (0,0,0,0,0);
- }
- private function calculate_xp ()
- {
- global $debug;
- $rescosts_by_side = array ();
- $reslosses_by_side = array ();
- $xp_by_side = array ();
- foreach ($this->armyinfo as $this_uid=>$his_info)
- {
- if (isset ($this->unitvalue[$this_uid]))
- $unitvalue_total += $this->unitvalue[$this_uid];
- if (isset ($this->unitvalueloss[$this_uid]))
- $unitvalueloss_total += $this->unitvalueloss[$this_uid];
- }
- foreach ($this->armyinfo as $this_uid=>$his_info)
- {
- if (isset ($this->unitvalue[$this_uid]))
- $this->xp_by_uid[$this_uid] += round ($unitvalueloss_total * ($this->unitvalue[$this_uid] / $unitvalue_total) * 1000);
- }
- if ($debug)
- {
- echo "<pre>:XP by uid:\n";
- print_r ($this->xp_by_uid);
- echo "</pre>";
- echo "<pre>:UV by uid:\n";
- print_r ($this->unitvalue);
- echo "</pre>";
- echo "<pre>:UVL by uid:\n";
- print_r ($this->unitvalueloss);
- echo "</pre>";
- echo "UVLT: ".$unitvalueloss_total.", UVT:".$unitvalue_total."<br>";
- }
- }
- private function fetch_xp_by_uid ($this_uid)
- {
- if (isset ($this->xp_by_uid[$this_uid]) && isset ($this->army_has_hero[$this_uid]))
- return ($this->xp_by_uid[$this_uid]);
- else
- return (0);
- }
- private function set_survivors ()
- {
- global $debug;
- if ($debug)
- {
- echo "<pre>Repqueries:\n";
- print_r ($this->repqueries);
- echo "</pre>";
- }
- // Still can't hurt to check if there WERE troops for this guy
- if (count ($this->repqueries))
- {
- foreach ($this->repqueries as $repuid=>$unitentry)
- {
- foreach ($unitentry as $repunitid=>$entry)
- {
- if (isset ($query))
- $query .= ", (".$this->baids[$repuid].", ".$repunitid.", ".$entry[0].", ".$entry[1].")";
- else
- $query = "(".$this->baids[$repuid].", ".$repunitid.", ".$entry[0].", ".$entry[1].")";
- }
- }
- $query = "insert into bat_troops values ".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot insert troops in postbattle.php. Query: ".$query.", error: ".mysql_error ());
- // return (false);
- }
- log_debug ("Battletroops: ".$query);
- // We just send them homeward
- foreach ($this->in_units as $this_troopid => $his_values)
- {
- $this_uid = $his_values[2001];
- if ($debug)
- {
- echo "Survivors for T ".$this_troopid." (".$this_uid."): ".$this->survivors[$this_troopid]."<br>\n";
- print_r ($this->returnquery[$this_troopid]);
- }
- // Only update the remaining troops infos if some survived, or the party with these losses
- // was the owner of the attacked village (so he can rebuild troops without having
- // to recreate the db structures), but this only holds
- // if ((($this->survivors[$this_troopid] > 0) && is_array ($this->returnquery[$this_troopid])) || ($this_uid == $this->def_uid) && ($this->in_units[1] > 0))
- if (is_array ($this->returnquery[$this_troopid]))
- {
- $returnquery = "replace into troops values ".implode (",", $this->returnquery[$this_troopid]);
- log_debug ("Returnquery for tid ".$this_troopid.", uid ".$this_uid." is ".$returnquery);
- if ($debug)
- echo "\n".$returnquery;
- if (!mysql_query ($returnquery))
- {
- log_err ("Cannot insert remaining troops in postbattle.php. Query: ".$returnquery.", error: ".mysql_error ());
- // return (false);
- }
- }
- else
- log_debug ("We didn't replace troops for ".$this_uid." (TID: ".$this_troopid.") in battle ".$this->battleid.". He didn't have any surviving troops.");
- }
- }
- else
- log_err ("Participant ".$this_uid." in battle ".$this->battleid." didn't have any troops but idmap was set.");
- }
- private function fake_survivors ()
- {
- global $debug;
- // Still can't hurt to check if there WERE troops for this guy
- if ($this->bquery)
- {
- $query = "insert into bat_troops values ".$this->bquery;
- if ($debug)
- echo "\n".$query;
- // log_debug ("Returnquery for fake uid ".$this_uid." is ".$returnquery);
- if (!mysql_query ($query))
- {
- log_err ("Cannot insert troops in user.inc.php. Query: ".$query.", error: ".mysql_error ());
- // return (false);
- }
- }
- else
- log_debug ("Participant in battle ".$this->battleid." didn't have any troops. idmap wasn't set but we scoured in_units.");
- }
- //Funktion zum Berechnen der kriegs-Punkte
- //Funktion zum Berechnen der kriegs-Punkte
- private function calcuteWarTmpStats()
- {
- global $debug;
- $aid1 = $this->armyinfo[$this->att_uid][2003]; //Allianz-Id des Angreifers
- $aid2 = $this->armyinfo[$this->def_uid][2003]; // Allianz-Id des Verteidigers
- //ueberpruefen, ob die beiden allianzen im krieg sind
- $query= "SELECT aid1, aid2 FROM wars WHERE ((aid1=".$aid1." AND aid2=".$aid2.") OR (aid1=".$aid2." AND aid2=".$aid1.")) AND over=0";
- if (!$res=mysql_query($query))
- log_err("postbattle.php: Problem when checking war of two alliances: ".$query);
- else
- {
- if ($row = mysql_fetch_array($res))
- {
- //echo "Krieg gefunden!";
- $war_aid1 = $row['aid1'];
- $war_aid2 = $row['aid2'];
- }
- }
- //wenn die beiden allianzen im krieg sind, werden nun die punkte berechnet
- //beide Seiten bekommen gutgeschrieben, wieviele Einheiten sie (in Ressourcen) vernichtet haben
- //der Angreifer bekommt zusaetzlich die erbeuteten Rohstoffe als Punkte und ggf Punkte fĂźr die zerstĂśrte Mauer
- if (isset($war_aid1) && isset($war_aid2))
- {
- if ($debug)
- print_r($this->resloot);
- $losses_att = 0;
- $loot = 0;
- $losses_def = 0;
- //iterate over all participants to sum all troop losses
- foreach ($this->armyinfo as $this_uid =>$this_info)
- {
- if (($this->armyinfo[$this_uid][2003] == $war_aid1) || ($this->armyinfo[$this_uid][2003] == $war_aid2)) //count war points just for members of the allies
- {
- if ($this->armyinfo[$this_uid][2000] == 0) //this one is an attacker
- {
- $losses_att += array_sum($this->reslosses[$this_uid]);
- $loot += array_sum($this->resloot[$this_uid]);
- }
- else //we have a defender here
- {
- $losses_def += array_sum($this->reslosses[$this_uid]);
- }
- }
- }
- //if ($this->wallscore > 0)
- // $score += $this->wallscore;
- //$losses_att = array_sum($this->reslosses[$this->att_uid]); // verluste des angreifers
- //$losses_def = array_sum($this->reslosses[$this->def_uid]); // verluste des verteidigers
- $score = round(($loot + $losses_def + ($this->wallscore) + ($this->outpostscore)) / 1000); //Punkte des Angreifers insgesamt
- $score2 = round(($losses_att) / 1000); //Punkte des Angreifers insgesamt
- //if ($debug)
- // echo "Punkte des Angreifers: ".$score.", Punkte des Verteidigers: ".$score2;
- if ($aid1 == $war_aid1) //ist der angreifer aid1 aus der kriegstabelle?
- {
- $aid_string = " score1 ";
- $aid_string2 = "score2";
- }
- else
- {
- $aid_string = " score2 ";
- $aid_string2 = "score1";
- }
- $query = "update war_stats_tmp set ".$aid_string."=".$aid_string."+".$score.", ".$aid_string2."=".$aid_string2."+".$score2." where aid1=".$war_aid1." AND aid2=".$war_aid2 ;
- if (!mysql_query($query))
- {
- log_err("Postbattle.php: Could not give score to attacker. ".$query);
- }
- log_debug("Hurra! ".$query);
- }
- }
- private function calculateFlags()
- {
- global $debug;
- //mit spaehern allein soll man keine faehnchen klauen koennen
- if (!($this->report_spying))
- {
- if (($this->total_def < 1) || (($this->total_def == 1) && $this->def_hero_died))
- {
- $aid1 = $this->armyinfo[$this->att_uid][2003];
- $aid2 = $this->armyinfo[$this->def_uid][2003];
- //ueberpruefen, ob die beiden allianzen im krieg sind, und ob in diesem dorf eine flagge steht
- $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";
- if ($debug)
- echo $query;
- log_debug ("Flagquery: ".$query);
- if (!$res=mysql_query ($query))
- log_err ("Cannot check war of these two allies. Query: ".$query.", error:".mysql_error());
- else
- {
- $in_war = false;
- if ($row_war = mysql_fetch_array($res))
- {
- $all_war[] = $row_war;
- $in_war = true;
- }
- if ($in_war == true)
- {
- //jetzt kommt die eigentliche faehnchen-behanldung
- $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 ;
- if(!mysql_query($query))
- {
- log_err ("Cannot steal flag! Query: ".$query.", error: ".mysql_error());
- }
- else
- {
- log_debug("Fähcnhen klauen: ".$query);
- $this->loot_specials[$this->att_uid][50] = $this->def_vill; // fuer berichte->"Flagge gestohlen"
- //FIXME Platz fuer Optimierung
- //nun ueberpruefen, ob das schon das dritte geklaute faehnchen ist, wenn ja, ist der Krieg beendet
- $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";
- if (!$res=mysql_query($query))
- {
- log_err ("postbattle.php: Postbattle: cannot check end of war???.. ".$query);
- }
- else
- {
- while ($row = mysql_fetch_array($res))
- {
- //if ($row['aid'] == $this->armyinfo[$this->def_uid][2003]) // aid der def-allianz?
- if ($row['aid1'] == $row['aid'])
- {
- if ($row['aid'] != $row['current_aid'])
- {
- $stolen_flags1[] = $row['current_villageid'];
- }
- }
- else //faehnchen der angreifer-allianzt ueberpruefen
- {
- if ($row['aid'] != $row['current_aid'])
- {
- $stolen_flags2[] = $row['current_villageid'];
- }
- }
- }
- if ((count ($stolen_flags1) >=3) || (count($stolen_flags2) >=3))
- {
- $this->loot_specials[$aid2][51] = $aid1; // fuer berichte->"Krieg vorbei"
- $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'];
- if (!mysql_query($query))
- log_err ("Could not update war! ".$query);
- $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'];
- if (!mysql_query($query))
- log_err ("POstbattle.php: Could not update warstats! ".$query);
- // Add ally reload diplomacy event
- $query = "update user set changed=changed,flags=flags|4 where aid in (".$aid1.",".$aid2.")";
- if (!mysql_query ($query))
- log_err ("Cannot add ally reload diplomacy flags after diplomacy addition. Query: ".$query.", ".mysql_error ());
- $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)";
- if (!mysql_query($query))
- {
- log_err("postbattle.php: could not insert allynews when cancelling war: ".$query);
- }
- log_debug ("Cancel war: ". $query);
- $query = "update user set allymsgs=allymsgs+1 where aid in (".$aid1.", ".$aid2.")";
- if (!mysql_query ($query))
- log_err ("Cannot update ally msg counter. Query: ".$query.", ".mysql_error ());
- else
- {
- if (!mysql_affected_rows ())
- log_err ("After updating ally msg counter no rows where affected. Query: ".$query);
- //ueberpruefen, wieivele Punkte die allianz bekommt, dadurch dass sie den krieg fruehzeitig beendet hat
- calctimeDiff ($all_war[0]['aid1'], $all_war[0]['aid2'],$this->armyinfo[$this->att_uid][2003] );
- //Endstatistik updaten
- calcStats($all_war[0]['aid1'], $all_war[0]['aid2']);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- if ($debug)
- echo "Survivors, won't do flags: ".$this->def_hero_died;
- }
- }
- }
- private function create_reports ()
- {
- global $debug;
- // Again we iterate through all participants, to create final reports
- foreach ($this->armyinfo as $this_uid => $his_values)
- {
- if (isset ($query))
- $query .= ", ";
- else
- $query = "";
- if (isset ($this->receip_aids[(int)$his_values[2003]]))
- $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, '')";
- else
- {
- $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].", '')";
- log_debug ("Formulating report for ally id ".(int)$his_values[2003]);
- }
- $this->receip_aids[(int)$his_values[2003]] = 1;
- $score_to_add = round ($this->fetch_xp_by_uid ($this_uid));
- // We also want to check if this guy has lost troops so we reduce his score
- if (($this->score_sub[$this_uid] > 0) || ($score_to_add > 0))
- {
- $scorequery = "update user set changed=changed,reports=reports+1";
- if ($this->score_sub[$this_uid] > 0)
- $scorequery .= ",score=score-".$this->score_sub[$this_uid];
- if ($this->fetch_xp_by_uid ($this_uid) > 0)
- $scorequery .= ",xp=xp+".$score_to_add;
- $this->loot_specials[$this_uid][60] = $score_to_add;
- $scorequery .= " where uid=".$this_uid;
- if ($debug)
- echo "<br>Scoresub query: ".$scorequery."<br>\n";
- if (!mysql_query ($scorequery))
- log_err ("Cannot reduce score in postbattle. Query: ".$scorequery.", ".mysql_error ());
- }
- else
- $this->receip_uids[] = $this_uid; // For the new report notification update
- }
- if (isset ($query))
- {
- // Now we create the report entries
- $query = "insert into reports values ".$query;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot write report entry. ".$query.", error: ".mysql_error());
- return (false);
- }
- }
- else
- {
- log_err ("Report query was empty?? Battleid ".$this->battleid);
- return (false);
- }
- if (count ($this->receip_uids))
- {
- // And give them all an update on their unread report count
- $query = "update user set changed=changed,reports=reports+1 where uid in (".implode (",", $this->receip_uids).")";
- if (!mysql_query ($query))
- log_err ("Cannot update unread report cound in postbattle. Query: ".$query.", ".mysql_error());
- }
- }
- private function do_siege ()
- {
- global $debug;
- $this->loot_specials[$this->att_uid][32] = 1;
- // Change owner of villages
- $query = "update village set uid=".$this->att_uid.",original_uid=".$this->att_uid.",outpost_of=".$this->att_vill." where villageid=".$this->def_vill;
- if (!mysql_query ($query))
- log_err ("Cannot set village to new owner after siege. Query: ".$query.", ".mysql_error ());
- // Change owner of ress tiles
- $query = "update tileres set uid=".$this->att_uid.",time_exhaust=time_exhaust where villageid=".$this->def_vill;
- if (!mysql_query ($query))
- log_err ("Cannot set ress tiles to new owner after siege. Query: ".$query.", ".mysql_error ());
- // Change owner of army
- $query = "update armies set uid=".$this->att_uid." where flag=0 and villageid=".$this->def_vill;
- if (!mysql_query ($query))
- log_err ("Cannot set army to new owner after siege. Query: ".$query.", ".mysql_error ());
- // Now even for outposts there might be stray events for them
- $query = "update event set uid2=".$this->att_uid." where village2=".$this->def_vill;
- if (!mysql_query ($query))
- log_err ("Cannot set stray events to new owner after siege. Query: ".$query.", ".mysql_error ());
- //TBD: as this is a successful siege, the atacker gains additional war score for conquering this outpost
- //$costs = pow ($numvillages, 2)*5000; costs4/2
- $numvillages = count ($this->defuser->allvillageids);
- $costs = pow (($numvillages-1), 2)*5000; //costs4/2
- $this->outpostscore = ($costs*4) ;
- log_debug("additional war score for conquering outpost: ".$this->outpostscore);
- }
- private function send_troops_home_nobattle ()
- {
- // We just send them homeward
- foreach ($this->in_units as $this_troopid => $his_values)
- {
- // Is this an attacker? Defenders don't need to be set to RETURNING state
- if ($his_values[2000] == 0)
- {
- $this->post_state = 10;
- $this->add_event ($this_troopid, $his_values[2001], $his_values[2002]);
- }
- }
- }
- private function add_event ($this_troopid, $uid, $homevillage)
- {
- global $debug;
- if (($this->return_duration > abs ($this->timediff)) || !$this->do_local)
- {
- $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)";
- if ($debug) echo "\n".$event_query;
- }
- else
- {
- // If not, then we just concoct a local event
- $this->return_event[] = array ("eid"=>0, "timestamp"=>date ("Y-m-d H:i:s", time() + $this->timediff), "score"=>0,
- "uid1" => $uid, "village1" => $homevillage, "uid2" => 0, "village2" => $this->def_vill,
- "dif" => ($this->return_duration + $this->timediff), "type"=>10, "param"=>$this_troopid,
- "param2"=>$this->battleid, "flag"=>0);
- log_debug ("Adding local return event: ".array_to_str (end($this->return_event)));
- }
- // So units survived. Set them to returning/siege
- $query = "update armies set flag=".$this->post_state." where troopid=".$this_troopid;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot set troops to ".$this->post_state." state in combat battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
- }
- // Insert the event for the trip home only if this won't be handled
- // by this event handler run
- if (($this->return_duration > abs ($this->timediff)) || !$this->do_local)
- {
- log_debug ("Adding return event ".$event_query);
- if (!@mysql_query ($event_query))
- {
- log_err ("Cannot insert ".$this->post_state." event: ".$event_query.", error: ".mysql_error ());
- return (false);
- }
- }
- }
- private function send_troops_home ()
- {
- global $debug;
- // Yes, there was a battle. Test each group to see if they were destroyed.
- foreach ($this->in_units as $this_troopid => $his_values)
- {
- // Differentiate between attackers and defenders. Defenders will retain their
- // army entry even if all members have died, so that the user can recruit easily again
- if ($his_values[2000] == 0)
- {
- if ($debug)
- echo "\nTroopid ".$this_troopid." is attacker and has ".$this->survivors[$this_troopid]." survivors";
- if ($this->survivors[$this_troopid] <= 0)
- {
- // This group has died. Delete the troopid (FIXME: OPTIMIZEME)
- $query = "delete from armies where troopid=".$this_troopid;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot delete perished troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
- // return (false);
- }
- $query = "delete from troops where troopid=".$this_troopid;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot delete perished troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
- // return (false);
- }
- log_debug ("Deleting perished troop ".$this_troopid." in battle ".$this->battleid);
- }
- else
- $this->add_event ($this_troopid, $his_values[2001], $his_values[2002]);
- }
- else
- {
- // For defenders, we only delete armies that where aiding somebody else, not the native army
- // of the city
- if (($this->survivors[$this_troopid] <= 0) && ($his_values[2002] != $this->def_vill))
- {
- if ($debug)
- {
- echo "Deleting this guy with ".$this->survivors[$this_troopid].":";
- print_r ($his_values);
- }
- // This group has died. Delete the troopid (FIXME: OPTIMIZEME)
- $query = "delete from armies where troopid=".$this_troopid;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot delete perished aiding troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
- return (false);
- }
- $query = "delete from troops where troopid=".$this_troopid;
- if ($debug)
- echo "\n".$query;
- if (!mysql_query ($query))
- {
- log_err ("Cannot delete perished aiding troop in battle ".$this->battleid.". Query: ".$query.", ".mysql_error ());
- return (false);
- }
- }
- }
- } // foreach
- }
- private function loot ()
- {
- global $debug;
- $this->loot_query = "";
- // We're also interested in loot, ain't we? :) But only if there where survivors
- if ($this->total_survivors > 0)
- {
- // We need to find out if there are thieves among the attackers
- $thieves_here = false;
- $best_looting = 0;
- foreach ($this->armyinfo as $this_uid => $his_values)
- {
- // Only check this for attackers
- if ($his_values[2000] == 0)
- {
- // Is it a thief, baggins?
- if ($his_values[3520] == 2)
- $thieves_here = true; // Yup
- // Also check which of the attackers has the best hero loot ability
- if ($his_values[3514] > $best_looting)
- $best_looting = $his_values[3514];
- }
- }
- // But max out loot bonus at 100%, we can't loot more than is there...
- $best_looting = 1 + (min (100, $best_looting) / 100);
- // The defending hero can also make sure that gold loot stays low
- if ($this->armyinfo[$this->def_uid][3513] > 0)
- $hero_hidden = max (0, 1 - ($this->armyinfo[$this->def_uid][3513] / 100));
- else
- $hero_hidden = 1;
- $loot = array();
- $total_loot = 0;
- if ($debug)
- echo "Thieves here is ".$thieves_here.", best_loot is ".$best_looting.", hero_hidden is ".$hero_hidden."\n";
- // If this was an outpost that was just attacked, there are no hidden ressources
- if ($this->def_vill != $this->village_obj->villageid)
- {
- if (!isset ($this->village_obj->outposts[$this->def_vill]))
- log_err ("Outpost not there either in postbattle!!!");
- else
- {
- // We should have the time since the last attack in the stamp field for outposts
- $storage = min (3600, ($this->village_obj->outposts[$this->def_vill]->secs_passed + $this->timediff)) / 3600;
- for ($currency = 1; $currency < 5; ++$currency)
- {
- if ($currency != 4)
- $loot[$currency] = min ((int)($this->village_obj->outposts[$this->def_vill]->ress_prod[$currency] * $storage), $this->village_obj->ress_val ($currency));
- else
- {
- // Thieves can steal big amounts of gold
- if ($thieves_here)
- $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;
- else
- $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;
- }
- if ($debug)
- 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";
- $total_loot += $loot[$currency];
- }
- $query = "update village set stamp=addtime(now(), sec_to_time(".$this->timediff.")) where villageid=".$this->def_vill;
- if ($debug)
- echo "Touchquery: ".$query;
- if (!mysql_query ($query))
- log_err ("Cannot touch outpost after raid. Query: ".$query.", ".mysql_error());
- }
- }
- else
- {
- foreach ($this->village_obj->ress_prod as $currency => $amount)
- $hidden[$currency] = calculate_hidden_storage($amount, $this->village_obj->ress_max);
- log_debug ("Storage level ".$row[0].", hidden ".$hidden[1].", ".$hidden[2].", ".$hidden[3].", ".$hidden[4]);
- // Ok, let's see how many ressources are here
- for ($currency = 1; $currency <= 4; ++$currency)
- {
- $amount = $this->village_obj->ress_val ($currency);
- if ($currency != 4)
- $loot[$currency] = max(0, $amount - $hidden[$currency]);
- else
- {
- // Thieves can steal big amounts of gold
- if ($thieves_here)
- $loot[$currency] = max(0, (int)(($amount - $hidden[$currency]) / 2));
- else
- $loot[$currency] = max(0, (int)(($amount - $hidden[$currency]) / 10));
- }
- $total_loot += $loot[$currency];
- }
- // Do we need the offers from the marketplace?
- if ($this->all_cap > $total_loot)
- {
- // Now we check the market for ressources on sale
- $query = "select * from offers where villageid=".$this->def_vill;
- if ($debug)
- echo "offerquery: ".$query;
- if (!($res = mysql_query ($query)))
- {
- log_err ("Cannot fetch marketplace offers in postbattle. Query: ".$query.", ".mysql_error());
- }
- else
- {
- while ($row = mysql_fetch_array ($res))
- {
- if ($total_loot < $this->all_cap)
- {
- $loot[$row['offerkind']] += $row['offersize'];
- $this->village_obj->spend_type ($row['offerkind'], -$row['offersize']);
- $deloffers[] = $row['offerid'];
- $total_loot += $row['offersize'];
- }
- else
- break;
- }
- if (isset ($deloffers))
- {
- $query = "delete from offers where offerid in (".implode (",", $deloffers).")";
- if ($debug)
- echo "offerdelquery: ".$query;
- if (!mysql_query ($query))
- log_err ("Cannot delete offers in postbattle. Query: ".$query.", ".mysql_error());
- }
- }
- }
- if ($debug)
- echo "Hidden: ".$hidden;
- }
- if ($debug)
- print_r ($loot);
- // echo "Total loot: ".$total_loot." All cap: ".$all_cap;
- if ($total_loot > 0)
- {
- $this->loot_prefix = "";
- foreach ($this->armyinfo as $this_uid => $his_values)
- {
- if ($his_values[2000] == 0) // Only attackers get loot
- {
- // echo "Survivors: ".$survivors[$this_uid].", my cap ".$total_cap[$this_uid];
- if ($this->total_cap[$this_uid] > 0)
- {
- $share = array ();
- $share_fac = ($this->total_cap[$this_uid] / $this->all_cap); // Each and every one his share :)
- $this_loot[1] = (int)($loot[1] * $share_fac);
- $this_loot[2] = (int)($loot[2] * $share_fac);
- $this_loot[3] = (int)($loot[3] * $share_fac);
- $this_loot[4] = (int)($loot[4] * $share_fac);
- $to_divide = min ($this->total_cap[$this_uid], $this_loot[1] + $this_loot[2] + $this_loot[3] + $this_loot[4]);
- $remaining_cap = $this->total_cap[$this_uid];
- // Now we loop until all has been divided
- while ($to_divide > 0)
- {
- $num_currencies = 0;
- $to_divide = 0;
- // Check each ressource for availability
- foreach ($this_loot as $currency => $amount)
- {
- if ($amount > 0)
- {
- $num_currencies++;
- $to_divide += $amount;
- }
- }
- $to_divide = min ($remaining_cap, $to_divide);
- // Now divide the remaining loot share through the number of currencies
- // and try to move the result to the attacker
- $left = ceil ($to_divide / $num_currencies);
- foreach ($this_loot as $currency => $amount)
- {
- if ($amount > 0)
- {
- $subtract = min ($amount, $left);
- $this_loot[$currency] -= $subtract;
- $this->village_obj->spend_type ($currency, $subtract);
- if (!isset ($share[$currency]))
- $share[$currency] = $subtract;
- else
- $share[$currency] += $subtract;
- $to_divide -= $subtract;
- $remaining_cap -= $subtract;
- // echo "And is now ".$this_loot[$currency]."\n";
- }
- }
- }
- if ($debug)
- {
- echo "share:";
- print_r ($share);
- }
- // Now pass the loot on in the rep_loot entries
- foreach ($share as $currency => $amount)
- {
- $this->resloot[$this_uid][$currency] = $amount;
- if ($amount > 0)
- {
- $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($currency-1).", ".$this_uid.", ".$amount.")";
- $this->loot_prefix = ",";
- }
- }
- } // No survivors, no loot
- } // was a defender
- } // foreach
- } // No loot there
- } // nobody returns home :(
- }
- function doLootSpecial ()
- {
- global $debug;
- // If we need to set specials in the loot
- // This is actually ugly since it doesn't only contain uids as the primary
- // index, but also aid's :o
- if (is_array ($this->loot_specials))
- {
- foreach ($this->loot_specials as $this_uid => $this_loot_sp)
- {
- foreach ($this_loot_sp as $coin => $param)
- {
- $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".$coin.", ".$this_uid.", ".$param.")";
- $this->loot_prefix = ",";
- }
- if ($debug)
- {
- echo "<pre>Loot specials:";
- print_r ($this->loot_specials);
- echo "</pre>";
- echo $this->loot_query;
- }
- }
- }
- foreach ($this->armyinfo as $this_uid => $his_values)
- {
- if (isset ($this->rescosts[$this_uid][1]))
- {
- foreach ($this->rescosts[$this_uid] as $coin => $param)
- {
- $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($coin+7).", ".$this_uid.", ".$param.")";
- $this->loot_prefix = ",";
- }
- if ($debug)
- {
- echo "<pre>Loot specials:";
- print_r ($this->rescosts);
- echo "</pre>";
- echo $this->loot_query;
- }
- }
- if (isset ($this->reslosses[$this_uid][1]))
- {
- foreach ($this->reslosses[$this_uid] as $coin => $param)
- {
- $this->loot_query .= $this->loot_prefix."(".$this->battleid.", ".($coin+3).", ".$this_uid.", ".$param.")";
- $this->loot_prefix = ",";
- }
- if ($debug)
- {
- echo "<pre>Loot specials:";
- print_r ($this->reslosses);
- echo "</pre>";
- echo $this->loot_query;
- }
- }
- }
- // Check to see if we added something to the loot query
- if ($this->loot_prefix == ",")
- {
- $this->loot_query = "insert into rep_loot values ".$this->loot_query;
- if ($debug)
- echo "\nQuery: ".$this->loot_query;
- if (!mysql_query ($this->loot_query))
- log_err ("Cannot insert report loot. Query: ".$this->loot_query.", ".mysql_error());
- }
- }
- private function handle_dead_commanders ()
- {
- $info_str = "Commanders died ";
- $query = "update user set flags=flags|1 where uid in (".implode (",", array_keys ($this->recalc_commanders)).")";
- if (!@mysql_query ($query))
- {
- log_err ("Cannot insert commandercalc event: ".$query.", error: ".mysql_error ());
- return (false);
- }
- }
- private function report_extra_results ()
- {
- foreach ($this->extra_results as $id=>$value)
- {
- switch ($id)
- {
- case 1: // initial wall level, is only set when wall was bombed
- $this->loot_specials[$this->def_uid][40] = $value;
- break;
- case 2: // actual wall level after last round, is only set when wall was bombed
- $this->loot_specials[$this->def_uid][41] = $value;
- break;
- case 3: // actual wall level after repairs, is only set when wall was bombed
- $this->loot_specials[$this->def_uid][42] = $value;
- // If the end wall level after repairs is different from beginning wall level,
- // we save the result to the DB
- if ($this->loot_specials[$this->def_uid][40] != $this->loot_specials[$this->def_uid][41])
- {
- // Set the new wall level
- $query = "update villbuild set level=".$this->loot_specials[$this->def_uid][42]." where type=11 and villageid=".$this->def_vill;
- if (!mysql_query ($query))
- log_err ("Cannot subtract wall level after it was hit. Query: ".$query.", ".mysql_error ());
- //we iterate over all damaged levels and calculate the costs.
- //attackers gain war score for damaging walls - calculate the score here
- //TBD: this is an additional query that should not be done if the allies are not in war. i placed it here
- //because it makes the code easier to read and with the thought that heroes might gain experience points for damaged walls.
- $query = "select costs1,costs2, costs3, costs4 from buildings where type=11 and race=".$this->defuser->race;
- if ($res = mysql_query($query))
- {
- if (list($costs1, $costs2, $costs3, $costs4) = mysql_fetch_array($res))
- {
- $wallcosts = $costs1 + $costs2 + $costs3 + $costs4;
- }
- else
- {
- log_err("Could not get wall value - no values found");
- }
- }
- else
- {
- log_err("Could not get wall value. query: ".$query);
- }
- //$wallscore = 0;
- for ($counter = $this->loot_specials[$this->def_uid][42] ; $counter <= $this->loot_specials[$this->def_uid][40]; $counter++)
- {
- $this->wallscore += $wallcosts * ($counter * pow (NEXTLEVEL_COSTS, $counter - 1));
- //log_debug ("costs of wall level ".$counter.": ".($wallcosts * ($counter * pow (NEXTLEVEL_COSTS, $counter - 1))));
- }
- log_debug ("additional war_score for attackers: ".$this->wallscore);
- // And now check the build queue for wall enhancements and get the level
- $query = "select eid from event where village1=".$this->def_vill." and type=".BUILDING." and param2=11";
- if (!($res = mysql_query ($query)))
- {
- log_err ("Cannot fetch wall buildqueue items. Query: ".$query.", ".mysql_error ());
- }
- else
- {
- $num_items = mysql_num_rows ($res);
- if ($num_items > 0)
- {
- $row = mysql_fetch_array ($res);
- $query = "update event set param=".($this->loot_specials[$this->def_uid][42] + 1)." where eid=".$row['eid'];
- if (!mysql_query ($query))
- log_err ("Cannot set new level of wall build item after bombing. Query: ".$query.", ".mysql_error ());
- else
- {
- if ($num_items > 1)
- {
- $row = mysql_fetch_array ($res);
- $query = "update event set param=".($this->loot_specials[$this->def_uid][42] + 2)." where eid=".$row['eid'];
- if (!mysql_query ($query))
- log_err ("Cannot set 2nd new level of wall build item after bombing. Query: ".$query.", ".mysql_error ());
- }
- }
- }
- }
- }
- break;
- }
- }
- }
- public function cleanup ()
- {
- if ($this->grattid)
- {
- $query = "delete from groupatts where grattid=".$this->grattid;
- if (!mysql_query ($query))
- log_err ("Cannot delete groupattack in postbattle. Query: ".$query.", ".mysql_error ());
- }
- }
- public function post_battle ()
- {
- global $debug;
- // Now insert an army entry for each battle participant
- foreach ($this->in_units as $this_troopid => $his_values)
- {
- $this_uid = $his_values[2001];
- $reparmyid = $this->insert_battle_army ($this_uid, $his_values);
- // If idmap is set (the defender had troops), we use it
- // In this structure we fill in a bat_troops query to display all participating units
- // in the battle and the number of survivors of each group.
- // At the same time we fill in a REPLACE for the troops structures, so that
- // the returning troops (which might be less than started out) are set to
- // "returning" state
- if (isset ($this->idmap))
- {
- $this->calc_armystate ($this_troopid, $this_uid, $his_values);
- } // isset idmap
- else
- {
- $this->fake_armystate ($this_troopid, $this_uid, $his_values);
- }
- } // foreach troops
- // Now we insert battle troops and return troops
- // This is different again for "real" battles as opposed to no-combat battles
- if (!isset ($this->idmap))
- {
- $this->fake_survivors ();
- }
- $this->calculate_xp ();
- $this->create_reports ();
- // And once again we iterate through all participants, to setup the armies for the march home
- // or to delete them, if they perished. First check if this isn't a siege though. But a siege only
- // happens if no defenders survive
- if ((($this->type == SIEGE) && (($this->total_def - $this->defender_virtual_survivors) == 0)) && (!$this->army_has_hero[$this->def_uid] || $this->def_hero_died))
- {
- $this->do_siege ($this_troopid);
- $this->siege_successful = true;
- $this->post_state = RETURNING;
- }
- else
- {
- // If this is a failed siege, we need to add this to the battle report
- if ($this->type == SIEGE)
- {
- $this->loot_specials[$this->att_uid][32] = 0;
- }
- $this->attacker_returns = true;
- $this->post_state = RETURNING;
- }
- // First we check if there was a battle at all
- if ($this->idmap == null)
- {
- $this->send_troops_home_nobattle ();
- }
- else
- {
- $this->set_survivors ();
- $this->send_troops_home ();
- }
- if ($debug)
- echo "Total survivors: ".$this->total_survivors;
- // If the spies were caught spying, they won't take anything of course
- if (!$this->report_spying)
- {
- $this->loot (); // FIXME auslagern : teile dieser funktion, weil sonst "faehnchen-geklaut" nicht mehr im bericht auftaucht
- }
- else
- {
- require_once ("spy.php");
- $fake_evrow['village1'] = $this->def_vill;
- $fake_evrow['village2'] = $this->att_vill;
- $fake_evrow['uid1'] = $this->def_uid;
- $fake_evrow['uid2'] = $this->att_uid;
- $fake_evrow['dif'] = 0;
- $fake_evrow['param'] = 0;
- do_spying ($fake_evrow, $this->attuser, $this->defuser, $this->att_vill, true);
- }
- $this->calculateFlags();
- $this->report_extra_results ();
- $this->calcuteWarTmpStats();
- $this->doLootSpecial ();
- // Final check: We might have to recalculate commanders
- if (isset ($this->recalc_commanders))
- {
- $this->handle_dead_commanders ();
- }
- // Cleanup leftovers, like group attack entries
- $this->cleanup ();
- return ($this->return_event);
- }
- }