2022-01-25 17:59:18 +00:00
< ? php
namespace Battles ;
use SQLite3 ;
class Arena
{
2022-01-26 22:56:03 +00:00
public static Arena $current ;
2022-01-25 17:59:18 +00:00
private $db ;
2022-01-26 22:56:03 +00:00
private const DB_TEMPLATE = ' create table if not exists fighters (
2022-01-25 17:59:18 +00:00
uid integer not null ,
strength integer not null ,
dexterity integer not null ,
intuition integer not null ,
endurance integer not null ,
intelligence integer not null ,
wisdom integer not null ,
accuracy integer not null ,
evasion integer not null ,
criticals integer not null ,
health integer not null ,
max_health integer not null ,
mana integer not null ,
max_mana integer not null ,
melee_min integer not null ,
melee_max integer not null ,
teamid integer not null ,
rowid integer not null ,
2022-01-26 22:56:03 +00:00
turn_timeout integer ) ' ;
2022-01-25 17:59:18 +00:00
public const MELEE_ATTACK = 1 ;
public const RANGED_ATTACK = 2 ;
public const USE_MAGIC = 3 ;
public const MOVE = 4 ;
2022-01-26 22:56:03 +00:00
public const FLEE = 5 ;
2022-01-25 17:59:18 +00:00
public const PASS = 0 ;
2022-01-26 22:56:03 +00:00
private int $turn_timeout ;
2022-01-25 17:59:18 +00:00
2022-01-26 22:56:03 +00:00
public function __construct ( SQLite3 $battleId )
2022-01-25 17:59:18 +00:00
{
2022-01-26 22:56:03 +00:00
//Придумать человеческий путь, чтобы не создавалось в папке с классами
$dbname = 'battle-' . $battleId . '.db' ;
2022-01-25 17:59:18 +00:00
if ( ! file_exists ( $dbname )) {
2022-01-26 22:56:03 +00:00
$this -> createDb ( $dbname );
2022-01-25 17:59:18 +00:00
}
}
2022-01-26 22:56:03 +00:00
private function createDb ( $dbname )
{
$this -> db = new SQLite3 ( $dbname );
$this -> db -> query ( self :: DB_TEMPLATE );
}
2022-01-25 17:59:18 +00:00
// array type: [[uid1,teamid1], [uid2,teamid2], ..., [uid_N,teamid_N]].
public function Init ( array $fighters )
{
2022-01-26 22:56:03 +00:00
$init_db_query = ' create table if not exists fighters (
uid integer not null ,
strength integer not null ,
dexterity integer not null ,
intuition integer not null ,
endurance integer not null ,
intelligence integer not null ,
wisdom integer not null ,
accuracy integer not null ,
evasion integer not null ,
criticals integer not null ,
health integer not null ,
max_health integer not null ,
mana integer not null ,
max_mana integer not null ,
melee_min integer not null ,
melee_max integer not null ,
teamid integer not null ,
rowid integer not null ,
turn_timeout integer ) ' ;
$init_table_query = ' insert into fighters (
uid ,
strength , dexterity , intuition , endurance , intelligence , wisdom ,
accuracy , evasion , criticals ,
health , max_health , mana , max_mana , melee_min , melee_max ,
teamid , rowid )
values ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) ' ;
$stmt = $this -> db -> prepare ( $init_table_query );
foreach ( $fighters as [ $uid , $team ]) {
2022-01-25 17:59:18 +00:00
$fighter = new UserStats ( $uid );
$stats = $fighter -> getFullStats ();
$stmt -> bindValue ( 1 , $fighter -> getId ());
$stmt -> bindValue ( 2 , $stats -> strength );
$stmt -> bindValue ( 3 , $stats -> dexterity );
$stmt -> bindValue ( 4 , $stats -> intuition );
$stmt -> bindValue ( 5 , $stats -> endurance );
$stmt -> bindValue ( 6 , $stats -> intelligence );
$stmt -> bindValue ( 7 , $stats -> wisdom );
$stmt -> bindValue ( 8 , $stats -> accuracy );
$stmt -> bindValue ( 9 , $stats -> evasion );
$stmt -> bindValue ( 10 , $stats -> criticals );
$stmt -> bindValue ( 11 , $fighter -> getHealth ());
$stmt -> bindValue ( 12 , $fighter -> getMaxHealth ());
$stmt -> bindValue ( 13 , $fighter -> getMana ());
$stmt -> bindValue ( 14 , $fighter -> getMaxMana ());
$stmt -> bindValue ( 15 , $stats -> min_physical_damage );
$stmt -> bindValue ( 16 , $stats -> min_physical_damage );
$stmt -> bindValue ( 17 , $team );
$stmt -> bindValue ( 18 , 1 );
$stmt -> execute ();
}
}
2022-01-26 22:56:03 +00:00
public function playerTurn ( int $action , int $uid ) : void
2022-01-25 17:59:18 +00:00
{
2022-01-26 22:56:03 +00:00
// Перед ходом проверить, а жив ли ты вообще?
if ( empty ( $this -> turn_timeout )) {
$this -> turn_timeout = $this -> db -> querySingle ( 'select turn_timeout from fighters where uid = ' . $uid );
}
$now = date ( 'U' );
2022-01-25 17:59:18 +00:00
/* select from last_turn_time and look at $now_plus_3_minutes - if ok, continue, if no, do nothing */
2022-01-26 22:56:03 +00:00
if ( $now > $this -> turn_timeout && ! in_array ( $action , [ self :: MELEE_ATTACK , self :: RANGED_ATTACK , self :: USE_MAGIC , self :: MOVE , self :: PASS , self :: FLEE ])) {
2022-01-25 17:59:18 +00:00
$action = self :: PASS ;
$stmt_update_timer = $this -> db -> prepare ( 'update fighters set last_turn_time = ? where uid = ?' );
2022-01-26 22:56:03 +00:00
$stmt_update_timer -> bindValue ( 1 , date ( 'U' , strtotime ( '+3 minute' )));
2022-01-25 17:59:18 +00:00
$stmt_update_timer -> bindValue ( 2 , $uid );
}
if ( $action === self :: MELEE_ATTACK ) {
2022-01-26 22:56:03 +00:00
//Выполнимо только с клетки 1, только по вражеской клетке 1.
//Выполнимо по клетке 2, если клетка 1 пуста _у всех с то р о н_;
//Выполнимо по клетке 3, если клетка 2 пуста _у всех с то р о н_;
//Стоя на клетке 2 при пустой клетке 1 - атака невозможна!
2022-01-25 17:59:18 +00:00
echo 'Melee!' ;
}
if ( $action === self :: RANGED_ATTACK ) {
2022-01-26 22:56:03 +00:00
//С клетки 1 атака на вражеские клетки 1 и 2;
//С клетки 2 атака на свою клетку 1 и вражескую клетку 1;
//С клетки 2 атака на вражескую 2, только если пустая клетка 1, либо нет клеток 1 _ни у одной из с то р о н_.
2022-01-25 17:59:18 +00:00
echo 'Ranged!' ;
}
if ( $action === self :: USE_MAGIC ) {
2022-01-26 22:56:03 +00:00
//Достаёт кого угодно откуда угодно в любых обстоятельствах.
//ОЧЕНЬ внимательно проверять цель. Случайный хил трупа вызовёт апокалипсис в логике.
2022-01-25 17:59:18 +00:00
echo '!MAGIC!' ;
}
if ( $action === self :: MOVE ) {
2022-01-26 22:56:03 +00:00
//клетка 1 - ближний ряд, только шаг назад
//клетка 2 - средний ряд, вперёд или назад
//клетка 3 - тыл, только вперёд
//В момент хода при соблюдении условий удара может прилететь неблокируемая атака на расстоянии.
//Перемещение - это ручной гарантированный уворот от всех летящих физических атак.
//Перемещение на пустующую клетку 1 с клетки 2 - это ручной гарантированный уворот всех стоящих на клетке 2 от всех летящих немагических атак по всей клетке.
2022-01-25 17:59:18 +00:00
echo 'I have legs!!' ;
}
2022-01-26 22:56:03 +00:00
if ( $action === self :: FLEE ) {
//побег из боя, только с клетки 3.
echo 'Help me, mommy!' ;
}
2022-01-25 17:59:18 +00:00
if ( $action === self :: PASS ) {
2022-01-26 22:56:03 +00:00
//Пропуск хода.
2022-01-25 17:59:18 +00:00
echo 'I pass this turn.' ;
}
2022-01-26 22:56:03 +00:00
// ПИСАТЬ РЕЗУЛЬТАТ ХОДА ТОЛЬКО ПОСЛЕ ПОВТОРНОЙ ПРОВЕРКИ Н А НАЛИЧИЕ ПРОТИВНИКА - О Н МОГ УСПЕТЬ ОТОЙТИ!
// !!ИЛИ У М Е Р Е Т Ь !!
2022-01-25 17:59:18 +00:00
$stmt_update_timer -> execute ();
}
}