/** * User command for betting on the coin toss game in the casino * * @param bet int The amount of money to bet on the coin toss game * @return Array * * @note * If the player bets within ~1% of the maximum bet, they will receive a reward item */ public function bet() { $player = new Player(self_char_id()); $bet = intval(in('bet')); $negative = $bet < 0; set_setting('bet', max(0, $bet)); $pageParts = ['reminder-max-bet']; if ($negative) { $pageParts = ['result-cheat']; $player->vo->health = subtractHealth($player->id(), 99); } else { if ($bet > $player->vo->gold) { $pageParts = ['result-no-gold']; } else { if ($bet > 0 && $bet <= self::MAX_BET) { if (rand(0, 1) === 1) { $pageParts = ['result-win']; $player->vo->gold = add_gold($player->id(), $bet); if ($bet >= round(self::MAX_BET * 0.99)) { // within about 1% of the max bet & you win, you get a reward item. add_item($player->id(), self::REWARD, 1); } } else { $player->vo->gold = subtract_gold($player->id(), $bet); $pageParts = ['result-lose']; } } } } // End of not cheating check. return $this->render(['pageParts' => $pageParts, 'player' => $player, 'bet' => get_setting('bet')]); }
/** * Command for current user to purchase a quantity of a specific item * * @param quantity int The quantity of the item to purchase * @param item string The identity of the item to purchase * @return Array */ public function buy() { $in_quantity = in('quantity'); $in_item = in('item'); $gold = get_gold($this->sessionData['char_id']); $current_item_cost = 0; $no_funny_business = false; // Pull the item info from the database $item_costs = $this->itemForSaleCosts(); $item = getItemByID(item_id_from_display_name($in_item)); $quantity = whichever(positive_int($in_quantity), 1); $item_text = null; if ($item instanceof Item) { $item_text = $quantity > 1 ? $item->getPluralName() : $item->getName(); $purchaseOrder = new PurchaseOrder(); // Determine the quantity from input or as a fallback, default of 1. $purchaseOrder->quantity = $quantity; $purchaseOrder->item = $item; $potential_cost = isset($item_costs[$purchaseOrder->item->identity()]['item_cost']) ? $item_costs[$purchaseOrder->item->identity()]['item_cost'] : null; $current_item_cost = first_value($potential_cost, 0); $current_item_cost = $current_item_cost * $purchaseOrder->quantity; if (!$this->sessionData['char_id'] || !$purchaseOrder->item || $purchaseOrder->quantity < 1) { $no_funny_business = true; } else { if ($gold >= $current_item_cost) { // Has enough gold. try { add_item($this->sessionData['char_id'], $purchaseOrder->item->identity(), $purchaseOrder->quantity); subtract_gold($this->sessionData['char_id'], $current_item_cost); } catch (\Exception $e) { $invalid_item = $e->getMessage(); error_log('Invalid Item attempted :' . $invalid_item); $no_funny_business = true; } } } } else { $no_funny_business = true; } $parts = array('current_item_cost' => $current_item_cost, 'quantity' => $quantity, 'item_text' => $item_text, 'no_funny_business' => $no_funny_business, 'view_part' => 'buy'); return $this->render($parts); }
/** * Operation to modify a player object by increasing health and decreasing gold * * @param p_player Player The player object to operate on * @param p_amount int The amount of health to add to the player object * @return void * @throws InvalidArgumentException Heal amount must be an integer greater than 0 * @throws RuntimeException Player is dead * @throws RuntimeException Player does not need healing * @throws RuntimeException Player does not enough gold for the healing requested * @par Preconditions: * Player must be alive to heal * * @par Side Effects: * The gold attribute of $p_player is modified in memory and database * The health attribute of $p_player is modified in memory and database * * @note * Chi reduces cost per heal point by 50% * * @see calculateHealCost */ private function _heal($p_player, $p_amount) { if ($p_amount < 1) { throw new \InvalidArgumentException('Invalid input for heal amount.'); } else { if ($p_player->health() <= 0) { throw new \RuntimeException('You must resurrect before you can heal.'); } else { if ($p_player->is_hurt_by() <= 0) { throw new \RuntimeException('You are at full health.'); } } } $amount = min($p_amount, $p_player->is_hurt_by()); $totalCost = ceil($amount * $this->calculateHealCost($p_player)); if ($totalCost > $p_player->gold) { throw new \RuntimeException('You do not have enough gold for that much healing'); } $p_player->vo->gold = subtract_gold($p_player->id(), $totalCost); $p_player->heal($amount); }
return $res; } if (!$attack_error) { // Nothing to prevent the attack from happening. // Initial attack conditions are alright. $result = ''; if ($command == 'Sight') { $covert = true; $sight_data = pull_sight_data($target); $display_sight_table = true; } elseif ($command == 'Steal') { $covert = true; $gold_decrease = min($target->gold(), rand(5, 50)); add_gold($char_id, $gold_decrease); // *** This one actually adds the value. subtract_gold($target->id(), $gold_decrease); // *** Subtracts whatever positive value is put in. $msg = "{$attacker_id} stole {$gold_decrease} gold from you."; send_event($attacker_char_id, $target->id(), $msg); $generic_skill_result_message = "You have stolen {$gold_decrease} gold from __TARGET__!"; } else { if ($command == 'Unstealth') { $state = 'unstealthed'; if ($target->hasStatus(STEALTH)) { $target->subtractStatus(STEALTH); $generic_state_change = "You are now {$state}."; } else { $turn_cost = 0; $generic_state_change = "__TARGET__ is already {$state}."; } } else {
add_item($char_id, 'phosphor', $quantity = 1); } else { // If the den of theives killed the attacker. $group_gold = 0; } $npc_template = 'npc.thief-group.tpl'; $combat_data = array('attack' => $group_attack, 'gold' => $group_gold, 'victory' => $victory); } else { // Normal attack on a single thief. $thief_attack = rand(0, 35); // *** Thief Damage *** if ($player->vo->health = $victory = subtractHealth($char_id, $thief_attack)) { $thief_gold = rand(0, 40); // *** Thief Gold *** if ($thief_attack > 30) { subtract_gold($char_id, $thief_gold); } else { if ($thief_attack < 30) { add_gold($char_id, $thief_gold); add_item($char_id, 'shuriken', $quantity = 1); } } } else { $thief_gold = 0; } $npc_template = 'npc.thief.tpl'; $combat_data = array('attack' => $thief_attack, 'gold' => $thief_gold, 'victory' => $victory); } } } }
/** * Command for a user to reduce their bounty by paying their own gold * * @param bribe int The amount to spend on reducing bounty * @return Array */ public function bribe() { $bribe = intval(in('bribe')); $error = 0; $quickstat = false; if ($bribe <= get_gold($this->sessionData['char_id']) && $bribe > 0) { subtract_gold($this->sessionData['char_id'], $bribe); subtractBounty($this->sessionData['char_id'], $bribe / 2); $location = 1; $quickstat = 'player'; } else { if ($bribe < 0) { // Was a bug, now the doshin beats you up! Yay! if (get_gold($this->sessionData['char_id']) > 1000) { // *** If they have more than 1000 gold, their bounty will be mostly removed by this event. $bountyReduction = getBounty($this->sessionData['char_id']) * 0.7; subtractBounty($this->sessionData['char_id'], $bountyReduction); } subtractGold($this->sessionData['username'], floor(getGold($this->sessionData['username']) * 0.8)); //Takes away 80% of the players gold. $location = 2; $quickstat = 'player'; } else { $location = 0; $error = 5; } } return $this->render(['error' => $error, 'quickstat' => $quickstat, 'location' => $location, 'command' => 'bribe']); }
} } } if (empty($resultMessage) && !empty($result)) { $resultMessage = $result; } if (!$victim_alive) { // Target was killed by the item. if (!$self_use) { // *** SUCCESSFUL KILL, not self-use of an item *** $attacker_id = $player->hasStatus(STEALTH) ? "A Stealthed Ninja" : $username; if (!$gold_mod) { $gold_mod = 0.15; } $loot = round($gold_mod * get_gold($target_id)); subtract_gold($target_id, $loot); add_gold($char_id, $loot); addKills($char_id, 1); $kill = true; $bountyMessage = runBountyExchange($username, $target); //Rewards or increases bounty. } else { $loot = 0; $suicide = true; } // Send mails if the target was killed. send_kill_mails($username, $target, $attacker_id, $article, $item->getName(), $today = null, $loot); } else { // They weren't killed. $attacker_id = $username; }
} } } } if (!$victim_alive) { // Someone died. if ($target->player_id == $player->player_id) { // Attacker killed themself. $loot = 0; $suicided = true; } else { // Attacker killed someone else. $killed_target = true; $gold_mod = 0.15; $loot = round($gold_mod * get_gold($target->id())); subtract_gold($target->id(), $loot); add_gold($char_id, $loot); addKills($char_id, 1); $added_bounty = floor($level_check / 5); if ($added_bounty > 0) { addBounty($char_id, $added_bounty * 25); } else { // Can only receive bounty if you're not getting it on your own head. if ($bounty = rewardBounty($char_id, $target->vo->player_id)) { $bounty_msg = "You have valiantly slain the wanted criminal, {$target}! For your efforts, you have been awarded {$bounty} gold!"; sendMessage('Village Doshin', $username, $bounty_msg); } } $target_message = "{$attacker_id} has killed you with {$command} and taken {$loot} gold."; send_event($attacker_char_id, $target->id(), $target_message); $attacker_message = "You have killed {$target} with {$command} and taken {$loot} gold.";
$attacking_player->death(); if (!$simultaneousKill) { $loot = floor($gold_mod * $attacking_player->gold()); //Loot for defender if he lives. } $target_msg = "You have killed {$attacker} in combat and taken {$loot} gold."; $attacker_msg = "DEATH: You've been killed by {$target} and lost {$loot} gold!"; sendMessage($attacker, $target, $target_msg); sendMessage($target, $attacker, $attacker_msg); } } // *** END MAIN ATTACK AND DUELING SECTION *** } if ($loot) { add_gold(get_char_id($victor), $loot); subtract_gold(get_char_id($loser), $loot); } /** * HACK(ajv) Because the player obj is modified throughout the above code * we can't really keep track of what happened to safely use the * ActiveRecord pattern. Therefore, we pull another copy of the player * from the data layer, modify it, and save it down here, then transfer * the updated data to the existing object to keep everything in sync */ if ($rounds > 4) { // Evenly matched battle! Reward some ki to the attacker, even if they die $rewarded_ki = 1; $hack_player = Player::find($attacking_player->id()); $hack_player->set_ki($hack_player->ki() + $rewarded_ki); $hack_player->save(); $attacking_player->ki = $hack_player->ki;