/** * @return StreamedViewResponse */ private function combat(Player $attacker, Player $target, $required_turns = 0, $options) { $error = ''; $stealthed_attack = false; $stealth_damage = false; $stealth_lost = false; $bounty_result = false; $rewarded_ki = false; $wrath = false; $loot = 0; $killpoints = 1; $rounds = 1; $victor = null; $loser = null; $starting_attacker = clone $attacker; $starting_target = clone $target; $turns_counter = $options['duel'] ? -1 : 1; $attacker_label = $attacker->name(); if (!$options['duel'] && $attacker->hasStatus(STEALTH)) { $stealthed_attack = true; $this->stealthStrike($attacker, $target); $gold_mod = self::STEALTH_GOLD_MOD; if ($target->health > 0) { $stealth_damage = true; } else { $attacker_label = 'a stealthed ninja'; $victor = $attacker; $loser = $target; } $attack_label = "attacked %s from the shadows"; } else { $gold_mod = $options['duel'] ? self::DUEL_GOLD_MOD : self::DEFAULT_GOLD_MOD; if ($attacker->hasStatus(STEALTH)) { $stealth_lost = true; } $attacker->subtractStatus(STEALTH); while ($turns_counter != 0 && $attacker->health > 0 && $target->health > 0) { $turns_counter--; $rounds++; $this->strike($attacker, $target, $options['blaze'], $options['deflect']); /** * Evasion effect: * * Break off the duel/attack if less than 10% health or * health is less than average of defender's strength */ if ($options['evade'] && ($attacker->health < $target->getStrength() * 0.5 || $attacker->health < $attacker->health * 0.1)) { break; } } $attacker->turns = $attacker->turns - max(0, $required_turns); $attack_label = $options['duel'] ? 'dueled %s' : 'attacked %s'; } if ($target->health > 0 && $attacker->health > 0) { $combat_msg = "%s {$attack_label} for %s damage, but they got away before you could kill them!"; Event::create($attacker->id(), $target->id(), sprintf($combat_msg, $attacker->name(), 'you', $starting_target->health - $target->health)); if ($attacker->hasStatus(STEALTH)) { $stealth_lost = true; } $attacker->subtractStatus(STEALTH); } else { if ($target->health < 1 && $attacker->health < 1) { $loot = 0; $this->win($attacker, $target, $loot, $killpoints); $this->win($target, $attacker, $loot, 1); $this->lose($attacker, $target, $loot); $this->lose($target, $attacker, $loot); } else { if ($target->health < 1) { $victor = $attacker; $loser = $target; $bounty_result = Combat::runBountyExchange($victor, $loser); $loot = floor($gold_mod * $loser->gold); if ($options['duel']) { $killpoints = Combat::killpointsFromDueling($attacker, $target); $skillListObj = new Skill(); if ($skillListObj->hasSkill('wrath', $attacker)) { // They'll regain some health for the kill, at the end. $attacker->heal(self::BASE_WRATH_REGAIN); $wrath = true; } } $reporting_victor = $victor; if ($victor->hasStatus(STEALTH)) { $reporting_victor = new Player(); $reporting_victor->uname = 'a stealthed ninja'; $reporting_victor->player_id = 0; } $this->lose($loser, $reporting_victor, $loot); $this->win($victor, $loser, $loot, $killpoints); } else { $victor = $target; $loser = $attacker; $loot = floor($gold_mod * $loser->gold); $this->lose($loser, $victor, $loot); $this->win($victor, $loser, $loot, $killpoints); } } } if ($options['duel']) { $this->logDuel($attacker, $target, $victor, $killpoints); } if ($rounds > self::EVEN_MATCH_ROUND_COUNT) { // Evenly matched battle! Reward some ki to the attacker, even if they die $rewarded_ki = self::EVEN_MATCH_KI_REWARD; $attacker->setKi($attacker->ki + $rewarded_ki); } $target->save(); $attacker->save(); return new StreamedViewResponse('Battle Status', 'attack_mod.tpl', get_defined_vars(), ['quickstat' => 'player']); }
/** * * @param Player $p_leader * @param String $p_clan_name * @return Clan */ public static function create(Player $p_leader, $p_clan_name) { DatabaseConnection::getInstance(); $clan_name = trim($p_clan_name); $result = DatabaseConnection::$pdo->query("SELECT nextval('clan_clan_id_seq')"); $clan_id = $result->fetchColumn(); $statement = DatabaseConnection::$pdo->prepare('INSERT INTO clan (clan_id, clan_name, clan_founder) VALUES (:clanID, :clanName, :leader)'); $statement->bindValue(':clanID', $clan_id); $statement->bindValue(':clanName', $clan_name); $statement->bindValue(':leader', $p_leader->name()); $statement->execute(); $statement = DatabaseConnection::$pdo->prepare('INSERT INTO clan_player (_player_id, _clan_id, member_level) VALUES (:leader, :clanID, 2)'); $statement->bindValue(':clanID', $clan_id); $statement->bindValue(':leader', $p_leader->id()); $statement->execute(); return new Clan($clan_id, $clan_name); }
/** * Actual login! Performs the login of a user using pre-vetted info! * * Creates the cookie and session stuff for the login process. * * @param Account $account * @param Player $player * @return void */ private function createGameSession(Account $account, Player $player) { $_COOKIE['username'] = $player->name(); $session = SessionFactory::getSession(); $session->set('username', $player->name()); $session->set('player_id', $player->id()); $session->set('account_id', $account->id()); $session->set('authenticated', true); $request = RequestWrapper::$request; $user_ip = $request->getClientIp(); query('UPDATE players SET active = 1, days = 0 WHERE player_id = :player', [':player' => [$player->id(), PDO::PARAM_INT]]); query('UPDATE accounts SET last_ip = :ip, last_login = now() WHERE account_id = :account', [':ip' => $user_ip, ':account' => [$account->id(), PDO::PARAM_INT]]); }
/** * Send out the killed messages. * * @return void */ private function sendKillMails(Player $attacker, Player $target, $attacker_label, $article, $item, $loot) { $target_email_msg = "You have been killed by {$attacker_label} with {$article} {$item} and lost {$loot} gold."; Event::create($attacker->name() === $attacker_label ? $attacker->id() : 0, $target->id(), $target_email_msg); $user_email_msg = "You have killed " . $target->name() . " with {$article} {$item} and received {$loot} gold."; Event::create($target->id(), $attacker->id(), $user_email_msg); }