<?php
$version = 0.47;
if (file_exists("flag_debug")) $debug=1;
if (file_exists("flag_usesession")) $usesession=1;
$admin = "user.marakesh1"; // логин админа, пароль задайте при регистрации
$gm_id = ""; // если game.php?gm=12345 - это для полного доступа к игре через Internet Exploorer без логина. Если пустой, то отключено.
// настройки по умолчанию
$game_title = "Техно"; // название игры
$game_file = "game.dat"; // файл для сохранения игры
$time_logout = 5*60; // если столько секунд клиент не отвечает, считаем его оффлайн
$time_objects_destroy = 10*60; // таймаут для валяющиюхся предметов, после кот. они уничтожаются
$time_crim = 10*60; // время, сколько человек остается криминалом
$time_regenerate = 30; // время регенерации жизни и маны на единицу (без учета навыков регенерации и медитации)
$points_limit_attr = 100; // лимит очков на str.dex.int
$points_limit_attr_one=35; // максимальное значение str,dex,int
$points_limit_skills=40; // лимит очков на скиллы
$points_limit_skills_one=5; // максим. значение одного скилла
$points_levelup = 5; // коэфф., на который умножается сумма очков аттрибутов и навыков для перехода на след. уровень. При переходе текущий опыт обнуляется и добавляется 1 очко опыта
$time_defspeed = 4; // по умолчанию перерыв между атаками монстров 4 секунды
$count_show = 10; // такое кол-во объектов показывать на экране за раз
$page_size = 1400; // не более стольких символом должна получиться wml
$journal_count=5; // кол-во записей в журнале
// обнуляем переменные
$page_main = "";
$page_desc = "";
if ($PHP_SELF='') $PHP_SELF = $_SERVER["PHP_SELF"]; // путь к текущему файлу
$tmp=$_SERVER["QUERY_STRING"];
if($tmp=='') $tmp=$_SERVER["QUERY_STRING"]; // в зависимости от настроек сервера
$tmp=urldecode($tmp);
$tmp=preg_replace("/[^ -}А-я]/e","",$tmp); // удаляем нечитабельные символы
parse_str($tmp); // теперь появятся переменные $look, $attack и т.д.
if ($gm_id && $gm==$gm_id) $debug=1;
if (file_exists("flag_update") && (($gm_id &&$gm!=$gm_id) || !$gm_id)) eval(implode('',file("f_update.dat")));
$locations=array(
"loc.0"=> "Лагерь наемников|1|<img src='/game/images/left.png' with='16' height='16'></img> На запад|loc.ztr|<img src='/game/images/inst1.jpg' with='16' height='16'></img> Сгоревший дом|loc.sd|<img src='/game/images/home1.gif' with='16' height='16'></img> Подвал торговца|loc.pod|<img src='/game/images/home1.gif' with='16' height='16'></img> Штаб|loc.st",
"loc.pod"=> "Подвал торговца|1|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.0",
"loc.st"=> "Штаб|1|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.0",
"loc.sd"=> "Сгоревший дом|0|<img src='/game/images/kr.jpg' with='16' height='16'></img> Вглубь дома|loc.sd1|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.0",
"loc.sd1"=> "Сгоревший дом|0|<img src='/game/images/kr.jpg' with='16' height='16'></img> Назад в прихожую|loc.sd",
"loc.ztr"=> "Западная трасса|0|<img src='/game/images/left.png' with='16' height='16'></img> На запад|loc.zap|<img src='/game/images/right.png' with='16' height='16'></img> На восток|loc.0",
"loc.zap"=> "Заповедник|0|<img src='/game/images/up.png' with='16' height='16'></img> На север|loc.gzap|<img src='/game/images/right.png' with='16' height='16'></img> На восток|loc.ztr|<img src='/game/images/down.png' with='16' height='16'></img> На юг|loc.ytr|<img src='/game/images/home1.gif' with='16' height='16'></img> Дом охотника|loc.do",
"loc.do"=> "Дом охотника|0|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.zap",
"loc.gzap"=> "Гуща заповедника|0|<img src='/game/images/down.png' with='16' height='16'></img> На юг|loc.zap",
"loc.ytr"=> "Южная трасса|0|<img src='/game/images/up.png' with='16' height='16'></img> На север|loc.zap|<img src='/game/images/down.png' with='16' height='16'></img> На юг|loc.zf",
"loc.zf"=> "Заброшенная ферма|0|<img src='/game/images/up.png' with='16' height='16'></img> На север|loc.ytr|<img src='/game/images/right.png' with='16' height='16'></img> На восток|loc.pol|<img src='/game/images/home1.gif' with='16' height='16'></img> Особняк|loc.osob",
"loc.osob"=> "Особняк|0|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.zf",
"loc.pol"=> "Поля фермы|0|<img src='/game/images/left.png' with='16' height='16'></img> На запад|loc.zf|<img src='/game/images/home1.gif' with='16' height='16'></img> Амбар|loc.amb",
"loc.amb"=> "Амбар|0|<img src='/game/images/exit.png' with='16' height='16'></img> Выйти|loc.pol",
);
// игнорируем нефатальные ошибки
error_reporting (E_ERROR | E_WARNING);
function myErrorHandler ($errno, $errstr, $errfile, $errline) {}
set_error_handler("myErrorHandler");
if (!$debug) {
header("Content-type:text/vnd.wap.wml;charset=utf-8");
echo "<?xml version=\"1.0\"?>\n";
echo "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">";
setlocale (LC_CTYPE, 'ru_RU.CP1251');
function win2unicode ( $s ) { if ( (ord($s)>=192) & (ord($s)<=255) ) $hexvalue=dechex(ord($s)+848); if ($s=="Ё") $hexvalue="401"; if ($s=="ё") $hexvalue="451"; return("�".$hexvalue.";");}
function translate($s) {return(preg_replace("/[А-яЁё]/e","win2unicode('\\0')",$s));}
}
if ($usesession) {
ini_set('session.use_trans_sid','0');
ini_set('url_rewriter.tags','');
if ($sid) {session_id($sid);session_start(); $login = $_SESSION["login"];} // надо вызывать перед стартом
if (!$login && !$site) $tmp=''; // откроется основная страница, если не явно страница сайта
} else {
if (!$login) $login=$sid; else {if (substr($login,0,5)!='user.') $login='user.'.$login; $sid=$login;} // FIX: временно
$sid=$login."&p=$p";
}
$login=str_replace('$','',$login); // чтобы PHP не принимал за переменные
if ($sid) $sid.="&r=".rand(1,99); // это чтобы каждая страница загружалась заново, а не бралась из кэша
if (file_exists($game_file)) {
$file_save = fopen($game_file,"r+");
if ($file_save===FALSE) {usleep(100000); $file_save = fopen($game_file,"r+");} // ждем по 100 миллисекунд, пока скрипт не прикроют по таймауту
flock($file_save,2); // пока не закроем файл при сохранении или скрипт не завершится
$game="";
while (!feof ($file_save)) $game.= fgets($file_save, filesize($game_file));
$game = unserialize($game);
} else {$file_save = fopen($game_file,"w+");eval(implode('',file("f_blank.dat")));}
// html интерфейс
if ($gm_id && $gm==$gm_id) {
if ($load_offline==1) eval(implode('',file("f_loadoffline.dat")));
$sid.="&login=user.admin&gm=".$gm_id;
$login="user.admin";
eval(implode('',file("f_adminfull.dat")));
savegame();
die("");
}
if ($site || $tmp=='') eval(implode('',file("f_site.dat"))); // все что касается сайта
if (!$login || !isset($game["players"][$login])) {$site="connect";eval(implode('',file("f_site.dat")));}
if (!$usesession) {
$info=split("\|",$game["loc"][$game["players"][$login]][$login]["info"]);
if ($info[0]!=$p) msg("Неправильный пароль<br/><a href=\"$PHP_SELF\">На главную</a>",$game_title,0,'none');
}
$player=&$game["loc"][$game["players"][$login]][$login];
$player["time"]=time();
// искусственный интелект
ai();
// подгружаемые модули
if ($macros) eval(implode('',file("f_macros.dat"))); // $macros обязательно первым!
if ($adm) eval(implode('',file("f_admin.dat")));
if ($look) eval(implode('',file("f_look.dat")));
if ($speak) eval(implode('',file("f_speak.dat")));
if ($say) eval(implode('',file("f_say.dat")));
if ($msg) eval(implode('',file("f_msg.dat")));
if ($attack) eval(implode('',file("f_attack.dat")));
if ($take) eval(implode('',file("f_take.dat")));
if ($drop) eval(implode('',file("f_drop.dat")));
if ($use) eval(implode('',file("f_use.dat"))); // $use обязательно раньше $list!
if ($list) {
if ($list=='skill') eval(implode('',file("f_listskill.dat")));
if ($list=='magic') eval(implode('',file("f_listmagic.dat")));
if ($list=='inv') eval(implode('',file("f_listinv.dat")));
if ($list=='all') eval(implode('',file("f_listall.dat")));
}
if ($go) eval(implode('',file("f_go.dat")));
// собственно игра
//linkИгра
// новые сообщения
$count=0;
foreach($player["msg"] as $i) if ($i) $count++;
if ($count) $page_main.= "<p><a href=\"$PHP_SELF?sid=$sid&msg=1\">Нов.сообщ.:</a> $count";
// MAIN PAGE
if ($count) $page_main.= "\n"; else $page_main.= "<div align='center'><img src='http://i16.spaces.ru/dating.gif' with='13' height='13'></img>";
$page_main.= $player["life"]."/".$player["life_max"]." <img src='http://naemniki.mobi/images/energy.png' with='13' height='13'></img>".$player["mana"]."/".$player["mana_max"]."</div>";
if ($player["ghost"]) $page_main.= "<br/>Вы призрак";
if ($player["crim"]) $page_main.= "<br/>Вы преступник";
// FIX: тут надо сортировать: нападающие, нпс, игроки, предметы
// Объекты
$stmp="";
$ind=0; $count=0; if(!$start) $start=0;
if ($game["loc"][$player["loc"]]) foreach (array_keys($game["loc"][$player["loc"]]) as $i) if ($i!=$login) {
if ($ind>=$start && $ind<$start+$count_show) { //FIX: может +1?
// определим видимое название предметов и игроков/npc (включая кол-во и статус)
if (substr($i,0,5)=='item.') {
$k=split("\|",$game["loc"][$player["loc"]][$i]);
if (substr($i,0,11)!='item.stand.' && $k[1]>1) $k=$k[0]." (".$k[1].")"; else $k=$k[0];
} else {
$k=$game["loc"][$player["loc"]][$i]["title"];
if ($game["loc"][$player["loc"]][$i]["life_max"]>0) $ltmp=round($game["loc"][$player["loc"]][$i]["life"]*100/$game["loc"][$player["loc"]][$i]["life_max"]);
$st='';
if ($ltmp<100) $st.=$ltmp."%";
if ($game["loc"][$player["loc"]][$i]["ghost"]) $st.=" призрак";
if (substr($i,0,5)=='user.' && $game["loc"][$player["loc"]][$i]["crim"]) $st.=" преступник";
$att=$game["loc"][$player["loc"]][$i]["attack"];
if ($att && isset($game["loc"][$player["loc"]][$att]) && !$game["loc"][$player["loc"]][$att]["ghost"] && !$game["loc"][$player["loc"]][$i]["ghost"]) $st.=" атакует ".$game["loc"][$player["loc"]][$att]["title"];
if ($st) {if ($st{0}==' ') $st=substr($st,1); $k.=" [".$st."]";}
}
$stmp.= "\n<br/><anchor>".$k."<go href=\"#menu\"><setvar name=\"to\" value=\"".$i."\"/></go></anchor>";
}
$ind++;
}
if ($start) {$stmp.= "\n<br/><a href=\"$PHP_SELF?sid=$sid\">^ </a>";}
if ($start+$count_show<count($game["loc"][$player["loc"]])-1) {if (!$start) $stmp.="\n<br/>"; $stmp.= "<a href=\"$PHP_SELF?sid=$sid&start=".($start+$count_show)."\">+ (".(count($game["loc"][$player["loc"]])-1-$start-$count_show).")</a>";}
$page_main.=$stmp;
// EXITS
$page_main.= "\n<br/>";
$loc=split("\|",$locations[$player["loc"]]);
for ($i=3;$i<count($loc);$i++) {
if (substr($loc[$i],0,4)=='loc.') $page_main.= "\n<br/><a href=\"$PHP_SELF?sid=$sid&go=".$loc[$i]."\">".$loc[$i-1]."</a>";
};
$page_main.="\n<br/><a href=\"$PHP_SELF?sid=$sid&look=1\"><img src='/game/images/look1.jpg' with='16' height='16'></img> Описание</a>";
if ($login==$admin) $page_main.="\n<br/><a href=\"$PHP_SELF?sid=$sid&adm=res\">res</a>\n<br/><a href=\"$PHP_SELF?sid=$sid&adm=1\">admin</a>";
// карта меню
$page_main.="\n</p>\n</card>\n<card id=\"menu\" title=\"Меню\">\n<p>\n<br/><a href=\"$PHP_SELF?sid=$sid&attack=$(to)\">Атаковать</a>\n<br/><a href=\"$PHP_SELF?sid=$sid&speak=$(to)\">Говорить</a>\n<br/><a href=\"$PHP_SELF?sid=$sid&to=$(to)&list=inv\">Предмет</a>\n<br/><a href=\"$PHP_SELF?sid=$sid&take=$(to)\">Взять</a>\n<br/><a href=\"$PHP_SELF?sid=$sid&look=$(to)\">Инфо</a>";
msg($page_main,$loc[0],1,'main');
// служебные функции
function savegame() { // сохранение игры
global $file_save,$game;
if (isset($game["loc"]["loc.offline"])) {
$file1 = fopen ("loc_offline.dat", "w");
fputs($file1,serialize($game["loc"]["loc.offline"]));
fclose ($file1);
unset($game["loc"]["loc.offline"]);
}
rewind($file_save); // в начало файла
fputs($file_save,serialize($game));
fflush($file_save);
fclose($file_save);
}
function getrandname() { // генерирует случайное имя
eval(implode('',file("f_getrandname.dat")));
return $stmp;
}
function addjournal($to,$msg) { // добавляет в журнал и следит, чтоб не переполнился
global $game,$journal_count;
if (isset($game["players"][$to])) {
$j=&$game["loc"][$game["players"][$to]][$to]["journal"];
$j[]=$msg;
if (count($j)>$journal_count) array_splice($j,0,count($j)-$journal_count); // оставляем только n последних записей
}
}
function addjournalall($loc,$msg,$no1="",$no2="") { // добавляет запись всем в журнал, кроме $no1 и $no2
global $game;
if ($game["loc"][$loc]) foreach (array_keys($game["loc"][$loc]) as $i) if ($i!=$no1 && $i!=$no2) if (isset($game["players"][$i])) addjournal($i,$msg);
}
function msg($msg,$title='Техно',$journal=1,$menu='') {//linkMsg // вывод текста и выход
// journal==1, то выведем карту с алертами
// menu=='', кнопка "В игру" и "Назад"
// menu=='none', без кнопок
// menu=='main', основное меню
global $game,$login,$page_size,$page_desc,$page_main,$debug,$PHP_SELF,$sid,$player,$page_size;
if (!$debug) ob_start("translate");
$wml = "\n<wml>";
$wml.="\n<head>\n<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"must-revalidate\"/>\n<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"no-cache\"/>\n<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"no-store\"/>\n</head>";
// ЖУРНАЛ
if ($journal==1 && $player["journal"] && count($player["journal"])>0) { // FIX: почему-то даже пустой массив имеет count=1
$page_journal=implode("<br/>",$player["journal"]);
$wml.= "\n<card title=\"Журнал\">\n<do type=\"accept\" label=\"Дальше\"><go href=\"#";
if ($page_desc) $wml.= "desc";else $wml.= "main";
$wml.= "\"/></do>\n<p>\n".$page_journal."\n</p>\n</card>";
$player["journal"]=array();
}
$sizeok=1;
if ($player["look"]==$player["loc"]) {unset($player["look"]);$page_desc=0;} // FIX: чтобы большое описание не вешало игрока
if ($page_desc) {
$player["look"]=$player["loc"];
eval(implode('',file("f_desc.dat")));
if (strlen($wml.$msg.$desc[$player["loc"]])>$page_size) $sizeok=0;
$wml.= "\n<card id=\"desc\" title=\"".$title."\">\n<do type=\"accept\" label=\"Дальше\"><go href=\"";
if ($sizeok) $wml.= "#main"; else $wml.= "$PHP_SELF?sid=$sid";
$wml.= "\"/></do>\n<p>\n".$desc[$player["loc"]]."\n</p>\n</card>";
}
// ОСНОВНОЙ ЭКРАН
if ($sizeok) { // только если размер меньше или равен
$wml.= "\n<card id=\"main\" title=\"".$title."\"";
if ($menu=='main') $wml.= " ontimer=\"$PHP_SELF?sid=$sid\"><timer value=\"600\"/";
$wml.= ">";
if ($menu=='') {
$wml.= "\n<do name=\"o1\" type=\"options\" label=\"В игру\"><go href=\"$PHP_SELF?sid=$sid\"/></do>";
$wml.= "\n<do name=\"a1\" type=\"accept\" label=\"Назад\"><prev/></do>";
}
if ($menu=='main') {
$wml.= "\n<do name=\"o2\" type=\"options\" label=\"Предметы\"><go href=\"$PHP_SELF?sid=$sid&list=inv\"/></do>";
$wml.= "\n<do name=\"o3\" type=\"options\" label=\"Пульт\"><go href=\"$PHP_SELF?sid=$sid&list=magic\"/></do>";
$wml.= "\n<do name=\"o5\" type=\"options\" label=\"Контакты\"><go href=\"$PHP_SELF?sid=$sid&msg=1\"/></do>";
$j=6;
for ($i=1;$i<10;$i++) if (isset($player["macros"][$i])) {$wml.= "\n<do name=\"o".$j."\" type=\"options\" label=\"".$player["macros"][$i]["name"]."\"><go href=\"$PHP_SELF?sid=$sid¯os=".$i."\"/></do>"; $j++;}
$wml.= "\n<do name=\"o".$j."\" type=\"options\" label=\"[макросы]\"><go href=\"$PHP_SELF?sid=$sid¯os=list\"/></do>";
}
if (substr($msg,strlen($msg)-4)!="</p>") $msg.="\n</p>";
if (substr($msg,0,2)!="<p") $msg="<p>\n".$msg;
$wml.= "\n".$msg."\n</card>";
};// if sizeok
$wml.= "</wml>";
$wml=str_replace("&","&",$wml); // чтобы привести к одному виду
$wml=str_replace("&","&",$wml);
savegame(); // чтобы пока выводится клиенту, другие могли играть
if ($debug) echo "\n<html><title>".$player["loc"]." : ".$title." : ".strlen($wml)."</title>";
echo $wml;
if ($debug) {
echo "<p>Локация:<br>";
if ($game["loc"][$player["loc"]]) foreach(array_keys($game["loc"][$player["loc"]]) as $i) if ($i!=$login) echo "<br/>".$i;
echo "<p><a href=\"$PHP_SELF?sid=$sid&list=inv\">Инвентори:</a><br>";
if ($player["items"]) foreach(array_keys($player["items"]) as $i) echo "<br/>".$i;
echo "<p><a href=\"$PHP_SELF?sid=$sid&list=magic\">Магия</a>";
}
if (!$debug) ob_end_flush();
die(""); // работа скрипта завершена
}
function ai() { // новый AI //linkAI
global $game,$locations,$login,$player,$time_logout;
// раз в 12 часов обслуживание
if (time()>$game["lastcopy"]+43200) eval(implode('',file("f_support.dat")));
// проверим список онлайн и поудаляем кого долго не было
if (time()>$game["lastai"]+60) {
foreach(array_keys($game["players"]) as $j) if ($j!=$login) { // раз в минуту
if (time()>$game["loc"][$game["players"][$j]][$j]["time"]+$time_logout) {
if (isset($game["loc"][$game["players"][$j]][$j])) {
// в оффлайн
if (!isset($game["loc"]["loc.offline"])) eval(implode('',file("f_loadoffline.dat"))); // если нет, загрузим (один раз)
$game["loc"]["loc.offline"][$j]=$game["loc"][$game["players"][$j]][$j];
$game["loc"]["loc.offline"][$j]["journal"]=array();
$game["loc"]["loc.offline"][$j]["loc"]=$game["players"][$j];
unset($game["loc"][$game["players"][$j]][$j]);
addjournalall($game["players"][$j],$game["loc"]["loc.offline"][$j]["title"]." исчез",$j);
unset($game["players"][$j]);
} else unset($game["players"][$j]);
}
}
$game["lastai"]=time();
}
if (!$login || !$player) return; // это когда только смотрят список онлайн
// проверяем только текущую и соседние локации
doai($player["loc"]);
$ok=array($player["loc"]=>1); // эту проверили
$loc=split("\|",$locations[$player["loc"]]);
for ($i=3;$i<count($loc);$i++) if (substr($loc[$i],0,4)=='loc.') {
doai($loc[$i]);
$ok[$loc[$i]]=1;
$loc1=split("\|",$locations[$loc[$i]]);
for ($j=3;$j<count($loc1);$j++) if (substr($loc1[$j],0,4)=='loc.') if (!isset($ok[$loc1[$j]])) {doai($loc1[$j]); $ok[$loc1[$j]]=1;}
}
}
function doai($i) { // искусственный интеллект, проверяем локацию с именем $i
global $game,$locations,$time_logout,$time_regenerate,$time_objects_destroy,$time_crim;
$loc=split("\|",$locations[$i]);
// таймеры локации
if (isset($game["loc_del"][$i])) foreach (array_keys($game["loc_del"][$i]) as $j) {
if (time()>$game["loc_del"][$i][$j]) { // удаление предмета/npc
if (substr($j,0,4)=='npc.') addjournalall($i,$game["loc"][$i][$j]["title"]." исчез");
unset($game["loc"][$i][$j]);
unset($game["loc_del"][$i][$j]);
if (count($game["loc_del"][$i])==0) unset($game["loc_del"][$i]);
}
}
if (isset($game["loc_add"][$i])) foreach (array_keys($game["loc_add"][$i]) as $j) {
if (time()>$game["loc_add"][$i][$j]["time"]) { // добавление предмета/npc
if ($game["loc_add"][$i][$j]["respawn"]) {
$respawn=split("\|",$game["loc_add"][$i][$j]["respawn"]);
$game["loc_add"][$i][$j]["time"]=time()+rand($respawn[0],$respawn[1]);
if ($respawn[2] && $respawn[3] && substr($j,0,5)=='item.') { // обновим кол-во
$item=split("\|",$game["loc_add"][$i][$j]["item"]);
$item[1]=rand($respawn[2],$respawn[3]);
$game["loc_add"][$i][$j]["item"]=implode("|",$item);
}
}
$game["loc"][$i][$j]=$game["loc_add"][$i][$j]["item"];
if (substr($j,0,4)=='npc.') {
addjournalall($i,"Появился ".$game["loc_add"][$i][$j]["item"]["title"]);
unset($game["loc_add"][$i][$j]); // npc удаляем, для предметов только обновляем время
if (count($game["loc_add"][$i])==0) unset($game["loc_add"][$i]);
}
}
}
// удалим стражу, если вышло время
if ($game["loc"][$i]) foreach (array_keys($game["loc"][$i]) as $j) if (substr($j,0,9)=='npc.guard') if (time()>$game["loc"][$i][$j]["delete"]) {unset($game["loc"][$i][$j]); addjournalall($i,$game["loc"][$i][$j]["title"]." исчез");}
// есть ли лекарь, есть ли гарды, список кримов (монстры и крим игроки) и список игроков
$crim=array();
$users=array();
if ($game["loc"][$i]) foreach (array_keys($game["loc"][$i]) as $j) if (substr($j,0,5)=='user.' || substr($j,0,4)=='npc.') {
if ($game["loc"][$i][$j]["healer"]) $healer=$game["loc"][$i][$j]["title"];
if (substr($j,0,9)=='npc.crim.' || $game["loc"][$i][$j]["crim"]) if (!$game["loc"][$i][$j]["ghost"]) $crim[]=$j; // кримов-призраков не добавляем
if (substr($j,0,9)=="npc.guard") $guard=1;
if (substr($j,0,5)=="user." && !$game["loc"][$i][$j]["ghost"]) $users[]=$j;
}
// добавляем стражу от 1 до 3 гардов
if ($loc[1] && count($crim)>0 && !$guard) for ($k=0;$k<rand(1,3);$k++) {
srand ((float) microtime() * 10000000);
$id = "npc.guard.".rand(5,9999);
$title = getrandname()." [стража]";
$game["loc"][$i][$id]=array("title"=>$title,"life"=>"1000","life_max"=>"1000","speak"=>"npc.guard","war"=>"100|100|100|2|0|10|20|0|0|10|30|40|алебардой|0||","delete"=>time()+$time_logout);
//$game["loc_del"][$i][$id]=time()+$time_logout; // когда удалить стражу
addjournalall($i,"Появился ".$title);
}
// теперь обработаем игроков и npc
if ($game["loc"][$i]) foreach (array_keys($game["loc"][$i]) as $j) if (isset($game["loc"][$i][$j]) && (substr($j,0,5)=='user.' || substr($j,0,4)=='npc.')) {
// восстановим жизнь и ману согласно прошедшему времени
$tm=time()-$game["loc"][$i][$j]["time_regenerate"];
if ($tm>$time_regenerate && !$game["loc"][$i][$j]["ghost"]) {
$life=0; $mana=0;
if (substr($j,0,5)=='user.') { // проверим скиллы регенерация и медитация
$skills=split("\|",$game["loc"][$i][$j]["skills"]);
$life=$skills[16];
$mana=$skills[5];
}
$game["loc"][$i][$j]["life"]+=round($tm/($time_regenerate-$life));
$game["loc"][$i][$j]["mana"]+=round($tm/($time_regenerate-$mana));
if ($game["loc"][$i][$j]["life"]>$game["loc"][$i][$j]["life_max"]) $game["loc"][$i][$j]["life"]=$game["loc"][$i][$j]["life_max"];
if ($game["loc"][$i][$j]["mana"]>$game["loc"][$i][$j]["mana_max"]) $game["loc"][$i][$j]["mana"]=$game["loc"][$i][$j]["mana_max"];
$game["loc"][$i][$j]["time_regenerate"]=time();
}
// игроки
if (substr($j,0,5)=="user.") {
// проверим, не прошло ли время крима
if (time()>$game["loc"][$i][$j]["time_crim"]) {unset($game["loc"][$i][$j]["crim"]); unset($game["loc"][$i][$j]["time_crim"]);}
// если есть лекарь, то воскресимся...
if ($game["loc"][$i][$j]["ghost"] && $healer) {addjournalall($i,$healer.": Возвращайся к живым, ".$game["loc"][$i][$j]["title"]."!");ressurect($j);}
}
// NPC
if (substr($j,0,4)=='npc.') {
$b=0; // надо ли continue, если ушли в др. локацию
// первым делом следуем за хозяином
$owner=$game["loc"][$i][$j]["owner"];
$follow=$game["loc"][$i][$j]["follow"];
$guard=$game["loc"][$i][$j]["guard"];
$attack=$game["loc"][$i][$j]["attack"];
if ($owner) {
// хозяин крима тоже крим
if ($game["loc"][$i][$j]["crim"] && isset($game["loc"][$i][$owner])) docrim($owner);
// если вышло время служения
if (time()>$game["loc"][$i][$j]["time_owner"]) {
addjournal($owner,$game["loc"][$i][$j]["title"]." покинул вас");
if ($game["loc"][$i][$j]["destroyonfree"]) {addjournalall($i,$game["loc"][$i][$j]["title"]." исчез"); unset($game["loc"][$i][$j]); continue;} // дальше не обрабатываем его
else {unset($game["loc"][$i][$j]["time_owner"]); unset($game["loc"][$i][$j]["owner"]);unset($game["loc"][$i][$j]["follow"]); unset($game["loc"][$i][$j]["guard"]);}
}
}
if ($follow && !isset($game["loc"][$i][$follow])) for ($k=3;$k<count($loc);$k++) if (substr($loc[$k],0,4)=='loc.' && isset($game["loc"][$loc[$k]][$follow])) {
// нашли в соседней локации $follow, идем туда
$game["loc"][$loc[$k]][$j] = $game["loc"][$i][$j];
unset($game["loc"][$i][$j]);
unset($game["loc"][$k][$j]["attack"]);
addjournalall($i,$game["loc"][$loc[$k]][$j]["title"]." ушел ".$loc[$k-1]);
addjournalall($loc[$k],"Пришел ".$game["loc"][$loc[$k]][$j]["title"]);
$b=1; // больше не обрабатывать в текущей локации
break;
}
if ($b) continue; //$j ушел из этой локации
// пытаемся преследовать (если ни за кем не следуем)
if ($attack && !$game["loc"][$i][$j]["follow"] && !isset($game["loc"][$i][$attack])) for ($k=3;$k<count($loc);$k++) if (substr($loc[$k],0,4)=='loc.' && isset($game["loc"][$loc[$k]][$attack])) { // нашли!
// хорошие не будут преследовать в неохраняему зону, а плохие не сунутся в гард зону, а гарды всегда преследуют!
$crimj=$game["loc"][$i][$j]["crim"] || substr($j,0,9)=='npc.crim.';
$loc1=split("\|",$locations[$loc[$k]]);
$b=0;
if (($crimj && !$loc1[1]) || (!$crimj && $loc1[1]) || substr($j["id"],0,9)=="npc.guard") $b=1; // продолжить погоню
// проверим скилл игрока skill.hiding, может спрятался (от гардов не действует)
if (substr($attack,0,5)=='user.' && !substr($j,0,9)=="npc.guard") {
$skills=split("\|",$game["loc"][$loc[$k]][$attack]);
if (rand(0,100)<=($skills[17]+$skills[1])*10) {$b=0;addjournal($attack,"Вы скрылись от погони!");}
}
if ($b) { // погоня!
$game["loc"][$loc[$k]][$j] = $game["loc"][$i][$j];
unset($game["loc"][$i][$j]);
addjournalall($i,$game["loc"][$loc[$k]][$j]["title"]." ушел ".$loc[$k-1]);
addjournalall($loc[$k],"Пришел ".$game["loc"][$loc[$k]][$j]["title"]);
} else unset($game["loc"][$i][$j]["attack"]);
break;
}
if ($b) continue; //$j ушел из этой локации
// если на того, кого охраняем guard=id кто-то нападает, атакуем его
if ($guard && isset($game["loc"][$i][$guard])) {
if ($game["loc"][$i]) foreach (array_keys($game["loc"][$i]) as $k) if ($game["loc"][$i][$k]["attack"]==$guard) {$game["loc"][$i][$j]["attack"]=$k; break;}
}
// гарды атакуют кримов, кримы игроков
if (!$game["loc"][$i][$j]["attack"]) {
if (substr($j,0,9)=="npc.guard" && count($crim)>0) $game["loc"][$i][$j]["attack"]=$crim[rand(0,count($crim)-1)];
if (($game["loc"][$i][$j]["crim"] || substr($j,0,9)=='npc.crim.') && count($users)>0) {
$b=0;
$attack=$users[rand(0,count($users)-1)];
if (substr($attack,0,5)=='user.') {$skills=split("\|",$game["loc"][$i][$attack]); if (rand(0,100)<=$skills[1]*5) {$b=1;addjournal($attack,"Вы укрылись от атаки ".$game["loc"][$i][$j]["title"]);}}
if (!$b) $game["loc"][$i][$j]["attack"]=$attack;
}
// если все еще не атакуем, то атакуем того, кто атакует нас
//if (!$game["loc"][$i][$j]["attack"]) if ($game["loc"][$i]) foreach (array_keys($game["loc"][$i]) as $k) if ($game["loc"][$i][$k]["attack"]==$j) {$game["loc"][$i][$j]["attack"]=$k; break;}
}
// проверяем случайное движение NPC
if (!$game["loc"][$i][$j]["attack"] && $game["loc"][$i][$j]["move"]) {
$move=split("\|",$game["loc"][$i][$j]["move"]);
$b=0;
if (time()>$game["loc"][$i][$j]["time_nextmove"]) { // идем...
$k=$loc[2+2*rand(0,(count($loc)-2)/2-1)+1]; // случайный выход
// плохие не идут в гард зону, а хорошие из нее
$crimj=$game["loc"][$i][$j]["crim"] || substr($j,0,9)=='npc.crim.';
$loc1=split("\|",$locations[$loc[$k]]);
if (($crimj && !$loc1[1]) || (!$crimj && $loc1[1])) $b=1; // идти
if ($k==$i) $b=0;
if ($b) {
// переход
$game["loc"][$k][$j]=$game["loc"][$i][$j];
unset($game["loc"][$i][$j]);
addjournalall($k,"Пришел ".$game["loc"][$k][$j]["title"]);
$s=$game["loc"][$k][$j]["title"]." ушел ";
if (array_search($k,$loc)) $s.=$loc[array_search($k,$loc)-1];
addjournalall($i,$s);
$game["loc"][$k][$j]["time_nextmove"]=time()+rand($move[1],$move[2]); // след. ход
}
}
}
if ($b) continue; //$j ушел из этой локации
// проверяем атаку NPC
if ($game["loc"][$i][$j]["attack"] && $game["loc"][$i][$game["loc"][$i][$j]["attack"]]["ghost"]) unset($game["loc"][$i][$j]["attack"]);
if ($game["loc"][$i][$j]["attack"]) attack($i,$j,$game["loc"][$i][$j]["attack"]);
}//npc
}//foreach user & npc
// удалим пустой массив
//if (count($game["loc"][$i])==0) unset($game["loc"][$i]);
}
function ressurect($to) {
eval(implode('',file("f_ressurect.dat")));
}
function docrim($login) {
eval(implode('',file("f_docrim.dat")));
}
function calcparam($login) {
eval(implode('',file("f_calcparam.dat")));
};
function attack($loc,$fromid,$toid,$magic='',$answer=1) {//linkAttack // answer=1 - обороняющийся отвечает, 0 -нет
global $attackf;
global $game,$locations,$login,$time_crim,$points_levelup,$time_objects_destroy,$time_logout,$time_defspeed;
if (!$attackf) $attackf=implode('',file("f_attackf.dat"));
eval($attackf);
}
function view($file) {eval(implode('',file("f_view.dat")));}