PHP网页游戏学习之Xnova(ogame)源码解读(十六)
程序员文章站
2023-12-05 14:58:52
十九、攻击任务(missioncaseattack.php)
按照舰队任务的编号,排在第一个的就是攻击任务。这个代码很长,看的时候要有耐心。
好在引用的内容并不是很多,...
十九、攻击任务(missioncaseattack.php)
按照舰队任务的编号,排在第一个的就是攻击任务。这个代码很长,看的时候要有耐心。
好在引用的内容并不是很多,并且给出了详细的注释,读者不会晕头转向。
function missioncaseattack ($fleetrow) { global $user, $phpex, $xnova_root_path, $pricelist, $lang, $resource, $combatcaps; // 在舰队的记录中,fleet_start_time代表的不是出发时间,而是到达目的地时间 // 代表出发时间的是start_time // 此外还有fleet_end_time 这个是回到家的时间 // fleet_end_stay 这个是结束逗留的时间(联合防御和远征任务会用到) // 所以下面这个判断的意思是“舰队到达了目的地”,而不是“舰队起飞了” if ($fleetrow['fleet_start_time'] <= time()) { // fleet_mess是用来记录舰队的状态的,基本可以理解为是在前进途中还是返航途中 // 但感觉利用得并不好,如果只有两个状态,可以用true 和 false来记录 // 所以我把它设为了0,1,2三个状态,对于需要停留的任务,停留时就处于第三个状态 if ($fleetrow['fleet_mess'] == 0) { // ↓↓ 这个判断是试探存放战斗数据的文件是否存在 // 如果文件不存在,就中断操作,提示联系管理员 if (!isset($combatcaps[202]['sd'])) { message("<span style="font-family: ">" . $lang['sys_no_vars'] . "</span>", $lang['sys_error'], "fleet." . $phpex, 2); } // ↓↓ 开始是一系列的数据库查询,取得攻防双方的舰队数量和科技等级 // 根据舰队信息取得防守方星球数据 $qrytargetplanet = "select * from {{table}} "; $qrytargetplanet .= "where "; $qrytargetplanet .= "`galaxy` = '" . $fleetrow['fleet_end_galaxy'] . "' and "; $qrytargetplanet .= "`system` = '" . $fleetrow['fleet_end_system'] . "' and "; $qrytargetplanet .= "`planet` = '" . $fleetrow['fleet_end_planet'] . "' and "; $qrytargetplanet .= "`planet_type` = '" . $fleetrow['fleet_end_type'] . "';"; $targetplanet = doquery($qrytargetplanet, 'planets', true); $targetuserid = $targetplanet['id_owner']; // 根据舰队信息取得攻击方信息 $qrycurrentuser = "select * from {{table}} "; $qrycurrentuser .= "where "; $qrycurrentuser .= "`id` = '" . $fleetrow['fleet_owner'] . "';"; $currentuser = doquery($qrycurrentuser , 'users', true); $currentuserid = $currentuser['id']; // 由星球数据取得目标星球的所有者的信息 $qrytargetuser = "select * from {{table}} "; $qrytargetuser .= "where "; $qrytargetuser .= "`id` = '" . $targetuserid . "';"; $targetuser = doquery($qrytargetuser, 'users', true); // 然后取得双方的科技信息 // 其实下面这两个完全可以与上面两个查询整到一起 $qrytargettech = "select "; $qrytargettech .= "`military_tech`, `defence_tech`, `shield_tech` "; $qrytargettech .= "from {{table}} "; $qrytargettech .= "where "; $qrytargettech .= "`id` = '" . $targetuserid . "';"; $targettechno = doquery($qrytargettech, 'users', true); $qrycurrenttech = "select "; $qrycurrenttech .= "`military_tech`, `defence_tech`, `shield_tech` "; $qrycurrenttech .= "from {{table}} "; $qrycurrenttech .= "where "; $qrycurrenttech .= "`id` = '" . $currentuserid . "';"; $currenttechno = doquery($qrycurrenttech, 'users', true); // ↑↑ 如果有其他的能影响舰队三围的项目(比如指挥官等),也应该在这里一并取出来 // 生成防守方的舰队(防御) // 如果考虑联合防御,在上面还应该把这个星球上联合防御的舰队提取出来 // 然后一起计算数量和科技水平 for ($setitem = 200; $setitem 0) { $targetset[$setitem]['count'] = $targetplanet[$resource[$setitem]]; } } // 生成攻击方的舰队,也是用数组存放。'fleet_array'是不能直接拿来用的 // 这个字段的结构是 编号,数量;编号,数量; …… // 所以使用时需要用两次explode把它打散然后存进数组 $thefleet = explode(";", $fleetrow['fleet_array']); foreach($thefleet as $a => $b) { if ($b != '') { $a = explode(",", $b); $currentset[$a[0]]['count'] = $a[1]; } } // 包含进战斗引擎,ready to fight include_once($xnova_root_path . 'includes/ataki.' . $phpex); // 在输入信息之前采集时间 $mtime = microtime(); $mtime = explode(" ", $mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; // 将双方舰队和科技输入战斗引擎,并用$walka来记录输出结果 $walka = walka($currentset, $targetset, $currenttechno, $targettechno); // 再采集时间,得到战斗过程所用的时间 // 也就是“战斗报告产生于 x.xxxxxxxxxx 秒”的由来 $mtime = microtime(); $mtime = explode(" ", $mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); // 分别用一个单独的数组来记录攻击方的剩余舰队信息、 $currentset = $walka["atakujacy"]; // ……防守方的舰队信息、 $targetset = $walka["wrog"]; // ……战斗的胜负结果、 $fleetresult = $walka["wygrana"]; // ……每一轮的详细情况、 $dane_do_rw = $walka["dane_do_rw"]; // 以及双方的损失和废墟情况 $zlom = $walka["zlom"]; // 计算攻击方剩下的单位,顺便把装载量也一并计算进去了 $fleetarray = ""; $fleetamount = 0; $fleetstorage = 0; foreach ($currentset as $ship => $count) { $fleetstorage += $pricelist[$ship]["capacity"] * $count['count']; // 用$fleetarray记载舰队情况,转换成数据库里字段的格式,准备“入库” $fleetarray .= $ship . "," . $count['count'] . ";"; $fleetamount += $count['count']; } $fleetstorage -= $fleetrow["fleet_resource_metal"]; $fleetstorage -= $fleetrow["fleet_resource_crystal"]; $fleetstorage -= $fleetrow["fleet_resource_deuterium"]; // 计算防守星球战后的情况 $targetplanetupd = ""; if (!is_null($targetset)) { foreach($targetset as $ship => $count) { $targetplanetupd .= "`" . $resource[$ship] . "` = '" . $count['count'] . "', "; } } // 如果战斗结果为攻击方获胜,则开始计算掠夺资源的情况 ↓↓ // 这里可以include进planetresourceupdate.php,在掠夺之前先更新目标星球的资源 $mining['metal'] = 0; $mining['crystal'] = 0; $mining['deuter'] = 0; if ($fleetresult == "a") { if ($fleetstorage > 0) { $metal = $targetplanet['metal'] / 2; $crystal = $targetplanet['crystal'] / 2; $deuter = $targetplanet["deuterium"] / 2; if (($metal) > $fleetstorage / 3) { $mining['metal'] = $fleetstorage / 3; $fleetstorage = $fleetstorage - $mining['metal']; } else { $mining['metal'] = $metal; $fleetstorage = $fleetstorage - $mining['metal']; } if (($crystal) > $fleetstorage / 2) { $mining['crystal'] = $fleetstorage / 2; $fleetstorage = $fleetstorage - $mining['crystal']; } else { $mining['crystal'] = $crystal; $fleetstorage = $fleetstorage - $mining['crystal']; } if (($deuter) > $fleetstorage) { $mining['deuter'] = $fleetstorage; $fleetstorage = $fleetstorage - $mining['deuter']; } else { $mining['deuter'] = $deuter; $fleetstorage = $fleetstorage - $mining['deuter']; } } } // ↑↑ 到这里为止就计算结束了,但如果星球上金属巨多,但晶体和重氢几乎没有 // 那就会出现装了1/3仓的金属,剩下2/3仓全都空着 // 所以可以考虑自己把掠夺方法完善一下,也不是很难 $mining['metal'] = round($mining['metal']); $mining['crystal'] = round($mining['crystal']); $mining['deuter'] = round($mining['deuter']); // ↓↓ 更新数据库 $qryupdatetarget = "update {{table}} set "; $qryupdatetarget .= $targetplanetupd; $qryupdatetarget .= "`metal` = `metal` - '" . $mining['metal'] . "', "; $qryupdatetarget .= "`crystal` = `crystal` - '" . $mining['crystal'] . "', "; $qryupdatetarget .= "`deuterium` = `deuterium` - '" . $mining['deuter'] . "' "; $qryupdatetarget .= "where "; $qryupdatetarget .= "`galaxy` = '" . $fleetrow['fleet_end_galaxy'] . "' and "; $qryupdatetarget .= "`system` = '" . $fleetrow['fleet_end_system'] . "' and "; $qryupdatetarget .= "`planet` = '" . $fleetrow['fleet_end_planet'] . "' and "; $qryupdatetarget .= "`planet_type` = '" . $fleetrow['fleet_end_type'] . "' "; $qryupdatetarget .= "limit 1;"; doquery($qryupdatetarget , 'planets'); $qryupdategalaxy = "update {{table}} set "; $qryupdategalaxy .= "`metal` = `metal` + '" . $zlom['metal'] . "', "; $qryupdategalaxy .= "`crystal` = `crystal` + '" . $zlom['crystal'] . "' "; $qryupdategalaxy .= "where "; $qryupdategalaxy .= "`galaxy` = '" . $fleetrow['fleet_end_galaxy'] . "' and "; $qryupdategalaxy .= "`system` = '" . $fleetrow['fleet_end_system'] . "' and "; $qryupdategalaxy .= "`planet` = '" . $fleetrow['fleet_end_planet'] . "' "; $qryupdategalaxy .= "limit 1;"; doquery($qryupdategalaxy , 'galaxy'); // ↓↓ 计算废墟和损失的情况 $fleetdebris = $zlom['metal'] + $zlom['crystal']; $strattackerunits = sprintf ($lang['sys_attacker_lostunits'], pretty_number ($zlom["atakujacy"])); $strdefenderunits = sprintf ($lang['sys_defender_lostunits'], pretty_number ($zlom["wrog"])); $strruins = sprintf ($lang['sys_gcdrunits'], pretty_number ($zlom["metal"]), $lang['metal'], pretty_number ($zlom['crystal']), $lang['crystal']); $debrisfield = $strattackerunits . "" . $strdefenderunits . "" . $strruins; // ↓↓ 计算产月概率 $moonchance = $fleetdebris / 100000; if ($fleetdebris > 2000000) { $moonchance = 20; } if ($fleetdebris = 100000) { $userchance = mt_rand(1, 100); $chancemoon = sprintf ($lang['sys_moonproba'], $moonchance); } // 如果rp够好,就能产生月亮了。当然前提是这个坐标上没有月亮 if (($userchance > 0) and ($userchance $moonchance) { …… } // ↓↓ 从这里开始生成战斗报告,很长,但并不复杂 $attackdate = date("r", $fleetrow["fleet_start_time"]); $title = sprintf ($lang['sys_attack_title'], $attackdate); $raport = "" . $title . ""; $zniszczony = false; $a_zestrzelona = 0; // ↓↓ 双方攻防信息。如果有其他能影响舰队三围的,也要在这里加进去 // 当然这里的数据只是显示在战报中而已,是不会影响岛实际战斗的 $attacktechon['a'] = $currenttechno["military_tech"] * 10; $attacktechon['b'] = $currenttechno["defence_tech"] * 10; $attacktechon['c'] = $currenttechno["shield_tech"] * 10; $attackerdata = sprintf ($lang['sys_attack_attacker_pos'], $currentuser["username"],$fleetrow['fleet_start_galaxy'], $fleetrow['fleet_start_system'], $fleetrow['fleet_start_planet']); $attackertech = sprintf ($lang['sys_attack_techologies'], $attacktechon['a'],$attacktechon['b'], $attacktechon['c']); $defendtechon['a'] = $targettechno["military_tech"] * 10; $defendtechon['b'] = $targettechno["defence_tech"] * 10; $defendtechon['c'] = $targettechno["shield_tech"] * 10; $defenderdata = sprintf ($lang['sys_attack_defender_pos'], $targetuser["username"], $fleetrow['fleet_end_galaxy'], $fleetrow['fleet_end_system'], $fleetrow['fleet_end_planet']); $defendertech = sprintf ($lang['sys_attack_techologies'], $defendtechon['a'], $defendtechon['b'], $defendtechon['c']); // 根据战斗中每一轮的详细情况生成交火的细节,包括每一轮的数量,攻防值,造成和吸收了多少伤害等 // 有一些键值可能需要看了战斗引擎才会明白它代表的什么,所以看不懂也没关系 ↓↓ foreach ($dane_do_rw as $a => $b) { …… } // ↓↓ 根据胜负结果显示相应的结尾 switch ($fleetresult) { …… } // 战斗报告生成于 x.xxxxxxxxxxxx 秒 $simmessage = sprintf ($lang['sys_rapport_build_time'], $totaltime); $raport .= $simmessage . ""; // ↓↓ 将战斗报告编码,存入数据库 $dpath = (!$user["dpath"]) ? default_skinpath : $user["dpath"]; $rid = md5($raport); $qryinsertrapport = "insert into {{table}} set "; $qryinsertrapport .= "`time` = unix_timestamp(), "; $qryinsertrapport .= "`id_owner1` = '" . $fleetrow['fleet_owner'] . "', "; $qryinsertrapport .= "`id_owner2` = '" . $targetuserid . "', "; $qryinsertrapport .= "`rid` = '" . $rid . "', "; $qryinsertrapport .= "`a_zestrzelona` = '" . $a_zestrzelona . "', "; $qryinsertrapport .= "`raport` = '" . addslashes ($raport) . "';"; doquery($qryinsertrapport , 'rw'); // ↓↓ 这里才是发给玩家的消息,其中有一个onclick的链接到上面的战报 // 下面这个是发给攻击方的,根据战斗结果不同,标题也有不同的颜色 $raport = ""; $raport .= ""; if ($fleetresult == "a") { $raport .= ""; } elseif ($fleetresult == "r") { $raport .= ""; } elseif ($fleetresult == "w") { $raport .= ""; } $raport .= …… // ↓ 这里突然回到计算攻击舰队的资源装载量,其实完全可以挪到上面去 $mining['metal'] = $mining['metal'] + $fleetrow["fleet_resource_metal"]; $mining['crystal'] = $mining['crystal'] + $fleetrow["fleet_resource_crystal"]; $mining['deuter'] = $mining['deuter'] + $fleetrow["fleet_resource_deuterium"]; // 更新舰队信息 $qryupdatefleet = "update {{table}} set "; $qryupdatefleet .= "`fleet_amount` = '" . $fleetamount . "', "; $qryupdatefleet .= "`fleet_array` = '" . $fleetarray . "', "; $qryupdatefleet .= "`fleet_mess` = '1', "; $qryupdatefleet .= "`fleet_resource_metal` = '" . $mining['metal'] . "', "; $qryupdatefleet .= "`fleet_resource_crystal` = '" . $mining['crystal'] . "', "; $qryupdatefleet .= "`fleet_resource_deuterium` = '" . $mining['deuter'] . "' "; $qryupdatefleet .= "where fleet_id = '" . $fleetrow['fleet_id'] . "' "; $qryupdatefleet .= "limit 1 ;"; doquery($qryupdatefleet , 'fleets'); // 发送战斗消息给攻击方 sendsimplemessage ($currentuserid, '', $fleetrow['fleet_start_time'], 3, $lang['sys_mess_tower'], $lang['sys_mess_attack_report'], $raport); // ↓ 又突然插进来开始计算战斗经验和战斗次数 // 严重怀疑coder写这个文件时是不是喝高了 $addpoint = $currentuser['xpraid'] + 1; $qryupdateofficier = "update {{table}} set "; $qryupdateofficier .= "`xpraid` = '" . $addpoint . "' "; $qryupdateofficier .= "where id = '" . $currentuserid . "' "; $qryupdateofficier .= "limit 1 ;"; doquery($qryupdateofficier, 'users'); $raidstotal = $currentuser['raids'] + 1; if ($fleetresult == "a") { $raidswin = $currentuser['raidswin'] + 1; $qryupdateraidscompteur = "update {{table}} set "; $qryupdateraidscompteur .= "`raidswin` ='" . $raidswin . "', "; $qryupdateraidscompteur .= "`raids` ='" . $raidstotal . "' "; $qryupdateraidscompteur .= "where id = '" . $currentuserid . "' "; $qryupdateraidscompteur .= "limit 1 ;"; doquery($qryupdateraidscompteur, 'users'); } elseif ($fleetresult == "r" || $fleetresult == "w") { $raidsloose = $currentuser['raidsloose'] + 1; $qryupdateraidscompteur = "update {{table}} set "; $qryupdateraidscompteur .= "`raidswin` ='" . $raidsloose . "', "; $qryupdateraidscompteur .= "`raids` ='" . $raidstotal . "' "; $qryupdateraidscompteur .= "where id = '" . $currentuserid . "' "; $qryupdateraidscompteur .= "limit 1 ;"; doquery($qryupdateraidscompteur, 'users'); } // ↓↓ 终于又回来了,开始写发给防御方的消息 $raport2 = ""; $raport2 .= ""; if ($fleetresult == "a") { $raport2 .= ""; } elseif ($fleetresult == "r") { $raport2 .= ""; } elseif ($fleetresult == "w") { $raport2 .= ""; } $raport2 .= $lang['sys_mess_attack_report'] . " [" . $fleetrow['fleet_end_galaxy'] . ":" . $fleetrow['fleet_end_system'] . ":" . $fleetrow['fleet_end_planet'] . "]"; sendsimplemessage ($targetuserid, '', $fleetrow['fleet_start_time'], 3, $lang['sys_mess_tower'], $lang['sys_mess_attack_report'], $raport2); } // ↓↓ 如果舰队回到出发地了,就开始卸货,然后飞机入库 $fquery = ""; if ($fleetrow['fleet_end_time'] $count) { $fquery .= "`" . $resource[$ship] . "` = `" . $resource[$ship] . "` + '" . $count['count'] . "', "; } } else { $fleet = explode(";", $fleetrow['fleet_array']); foreach($fleet as $a => $b) { if ($b != '') { $a = explode(",", $b); $fquery .= "{$resource[$a[0]]}={$resource[$a[0]]} + {$a[1]}, \n"; } } } // → 到最后别忘了删除这一条舰队记录,不然会一直占用航道。对其他舰队任务也是一样 doquery ("delete from {{table}} where `fleet_id` = " . $fleetrow["fleet_id"], 'fleets'); if (!($fleetresult == "w")) { $qryupdateplanet = "update {{table}} set "; $qryupdateplanet .= $fquery; $qryupdateplanet .= "`metal` = `metal` + " . $fleetrow['fleet_resource_metal'] . ", "; $qryupdateplanet .= "`crystal` = `crystal` + " . $fleetrow['fleet_resource_crystal'] . ", "; $qryupdateplanet .= "`deuterium` = `deuterium` + " . $fleetrow['fleet_resource_deuterium'] . " "; $qryupdateplanet .= "where "; $qryupdateplanet .= "`galaxy` = " . $fleetrow['fleet_start_galaxy'] . " and "; $qryupdateplanet .= "`system` = " . $fleetrow['fleet_start_system'] . " and "; $qryupdateplanet .= "`planet` = " . $fleetrow['fleet_start_planet'] . " and "; $qryupdateplanet .= "`planet_type` = " . $fleetrow['fleet_start_type'] . " limit 1 ;"; doquery($qryupdateplanet, 'planets'); } } } }
上一篇: 分享五种Android常用布局方式
推荐阅读
-
PHP网页游戏学习之Xnova(ogame)源码解读(十三)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
-
PHP网页游戏学习之Xnova(ogame)源码解读(七)
-
PHP网页游戏学习之Xnova(ogame)源码解读(九)
-
PHP网页游戏学习之Xnova(ogame)源码解读(四)
-
PHP网页游戏学习之Xnova(ogame)源码解读(五)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十)
-
PHP网页游戏学习之Xnova(ogame)源码解读(二)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十一)