/** * Trigger an action pulled from the global battle queue * @param rpg_player this_player * @param rpg_robot this_robot * @param rpg_player target_player * @param rpg_robot target_robot * @param string $action_type * @param string $action_token */ public function trigger_action($this_player, $this_robot, $target_player, $target_robot, $action_type = '', $action_token = '') { // Default the return variable to false $this_return = false; // Collect references to global objects $db = cms_database::get_database(); $this_battle = self::get_battle(); $this_field = rpg_field::get_field(); // If the target player does not have any robots left if ($target_player->get_counter('robots_active') == 0) { // Trigger the battle complete action to update status and result $this_battle->trigger_complete($this_player, $this_robot, $target_player, $target_robot); } // Start the battle loop to allow breaking $battle_loop = true; while ($battle_loop == true && $this_battle->battle_status != 'complete') { // If the battle is just starting if ($action_type == 'start') { // If the target player is hidden if ($this_player->player_token == 'player') { // Create the enter event for this robot $event_header = $this_robot->robot_name; $event_body = "{$this_robot->print_name()} wants to fight!<br />"; $this_robot->set_frame('defend'); $this_robot->set_frame_styles(''); $this_robot->set_detail_styles(''); $this_robot->set_position('active'); if (isset($this_robot->robot_quotes['battle_start'])) { $this_find = array('{target_player}', '{target_robot}', '{this_player}', '{this_robot}'); $this_replace = array($target_player->player_name, $target_robot->robot_name, $this_player->player_name, $this_robot->robot_name); $event_body .= $this_robot->print_quote('battle_start', $this_find, $this_replace); } $this_battle->events_create($this_robot, false, $event_header, $event_body, array('canvas_show_target' => false, 'console_show_target' => false)); // Create an event for this robot teleporting in if ($this_player->counters['robots_active'] == 1) { $this_robot->set_frame('taunt'); $this_battle->events_create(false, false, '', ''); } $this_robot->set_frame('base'); $this_robot->set_frame_styles(''); $this_robot->set_detail_styles(''); } // Show the player's other robots one by one $temp_robots_active = $this_player->get_robots_active(); foreach ($temp_robots_active as $key => $temp_robot) { $frame_styles = $temp_robot->get_frame_styles(); if (!preg_match('/display:\\s?none;/i', $frame_styles)) { continue; } $temp_robot->set_frame('taunt'); $temp_robot->set_frame_styles(''); $temp_robot->set_detail_styles(''); $this_battle->events_create(false, false, '', ''); $temp_robot->set_frame('base'); } // Ensure this robot has abilities to loop through if (!$this_robot->has_flag('ability_startup') && $this_robot->has_abilities()) { // Loop through each of this robot's abilities and trigger the start event $temp_abilities_index = $db->get_array_list("SELECT * FROM mmrpg_index_abilities WHERE ability_flag_complete = 1;", 'ability_token'); $temp_robot_abilities = $this_robot->get_abilities(); foreach ($temp_robot_abilities as $temp_key => $temp_token) { // Define the current ability object using the loaded ability data $temp_info = array('ability_id' => $temp_key, 'ability_token' => $temp_token); $temp_ability = new rpg_ability($this_player, $this_robot, $temp_info); } // And now update the robot with the flag $this_robot->set_flag('ability_startup', true); } // Set this token to the ID and token of the starting robot $action_token = $this_robot->robot_id . '_' . $this_robot->robot_token; // Return from the battle function with the start results $this_return = true; break; } elseif ($action_type == 'ability') { // Combine into the actions index $temp_abilities_index = $db->get_array_list("SELECT * FROM mmrpg_index_abilities WHERE ability_flag_complete = 1;", 'ability_token'); // DEFINE ABILITY TOKEN // If an ability token was not collected if (empty($action_token)) { // Collect the ability choice from the robot $temp_token = $this_robot->robot_choices_abilities($target_player, $target_robot); $temp_id = array_search($temp_token, $this_robot->robot_abilities); if (empty($temp_id)) { $temp_id = $this_battle->index['abilities'][$temp_token]['ability_id']; } $this_info = rpg_ability::parse_index_info($temp_abilities_index[$temp_token]); $this_info['ability_id'] = $temp_id; } else { // Define the ability choice data for this robot list($temp_id, $temp_token) = explode('_', $action_token); $this_info = rpg_ability::parse_index_info($temp_abilities_index[$temp_token]); $this_info['ability_id'] = $temp_id; } // If the current robot has been already disabled if ($this_robot->robot_status == 'disabled') { // Break from this queued action as the robot cannot fight break; } // Define the current ability object using the loaded ability data $this_ability = new rpg_ability($this_player, $this_robot, $this_info); // Trigger this robot's ability $ability_results = $this_robot->trigger_ability($target_player, $target_robot, $this_ability); $this_ability->set_results($ability_results); // Ensure the battle has not completed before triggering the taunt event if ($this_battle->battle_status != 'complete') { // Check to ensure this robot hasn't taunted already if (!isset($this_robot->flags['robot_quotes']['battle_taunt']) && isset($this_robot->robot_quotes['battle_taunt']) && $this_robot->robot_quotes['battle_taunt'] != '...' && $this_ability->ability_results['this_amount'] > 0 && $target_robot->robot_status != 'disabled' && $this_battle->critical_chance(3)) { // Generate this robot's taunt event after dealing damage, which only happens once per battle $event_header = ($this_player->player_token != 'player' ? $this_player->player_name . ''s ' : '') . $this_robot->robot_name; $this_find = array('{target_player}', '{target_robot}', '{this_player}', '{this_robot}'); $this_replace = array($target_player->player_name, $target_robot->robot_name, $this_player->player_name, $this_robot->robot_name); //$this_quote_text = str_replace($this_find, $this_replace, $this_robot->robot_quotes['battle_taunt']); $event_body = ($this_player->player_token != 'player' ? $this_player->print_name() . ''s ' : '') . $this_robot->print_name() . ' taunts the opponent!<br />'; $event_body .= $this_robot->print_quote('battle_taunt', $this_find, $this_replace); //$event_body .= '"<em>'.$this_quote_text.'</em>"'; $this_robot->set_frame('taunt'); $target_robot->set_frame('base'); $this_battle->events_create($this_robot, $target_robot, $event_header, $event_body, array('console_show_target' => false)); $this_robot->set_frame('base'); // Create the quote flag to ensure robots don't repeat themselves $this_robot->set_flag('robot_quotes', 'battle_taunt', true); } } // Set this token to the ID and token of the triggered ability $action_token = $action_token['ability_id'] . '_' . $action_token['ability_token']; // Return from the battle function with the used ability $this_return =& $this_ability; break; } elseif ($action_type == 'switch') { // Collect this player's last action if it exists if (!empty($this_player->history['actions'])) { $this_recent_switches = array_slice($this_player->history['actions'], -5, 5, false); foreach ($this_recent_switches as $key => $info) { if ($info['this_action'] == 'switch' || $info['this_action'] == 'start') { $this_recent_switches[$key] = $info['this_action_token']; } else { unset($this_recent_switches[$key]); } } $this_recent_switches = array_values($this_recent_switches); $this_recent_switches_count = count($this_recent_switches); } else { $this_recent_switches = array(); $this_recent_switches_count = 0; } // If the robot token was not collected and this player is NOT on autopilot if (empty($action_token) && $this_player->player_side == 'left') { // Clear any pending actions $this_battle->actions_empty(); // Return from the battle function $this_return = true; break; } elseif (empty($action_token) && $this_player->player_side == 'right') { // Decide which robot the target should use (random) $active_robot_count = count($this_player->values['robots_active']); if ($active_robot_count == 1) { $this_robotinfo = $this_player->values['robots_active'][0]; } elseif ($active_robot_count > 1) { $this_current_token = $this_robot->robot_id . '_' . $this_robot->robot_token; do { $this_robotinfo = $this_player->values['robots_active'][mt_rand(0, $active_robot_count - 1)]; if ($this_robotinfo['robot_id'] == $this_robot->robot_id) { continue; } $this_temp_token = $this_robotinfo['robot_id'] . '_' . $this_robotinfo['robot_token']; } while (empty($this_temp_token)); } else { $this_robotinfo = array('robot_id' => 0, 'robot_token' => 'robot'); } //$this_battle->events_create(false, false, 'DEBUG', 'auto switch picked ['.print_r($this_robotinfo['robot_name'], true).'] | recent : ['.preg_replace('#\s+#', ' ', print_r($this_recent_switches, true)).']'); } else { list($temp_id, $temp_token) = explode('_', $action_token); $this_robotinfo = array('robot_id' => $temp_id, 'robot_token' => $temp_token); } //$this_battle->events_create(false, false, 'DEBUG', 'switch picked ['.print_r($this_robotinfo['robot_token'], true).'] | other : []'); // Update this player and robot's session data before switching $this_player->update_session(); $this_robot->update_session(); // Define the switch reason based on if this robot is disabled $this_switch_reason = $this_robot->robot_status != 'disabled' ? 'withdrawn' : 'removed'; /* $this_battle->events_create(false, false, 'DEBUG', '$this_switch_reason = '.$this_switch_reason.'<br />'. '$this_player->values[\'current_robot\'] = '.$this_player->values['current_robot'].'<br />'. '$this_player->values[\'current_robot_enter\'] = '.$this_player->values['current_robot_enter'].'<br />'. ''); */ // If this robot is being withdrawn on the same turn it entered, return false if ($this_player->player_side == 'right' && $this_switch_reason == 'withdrawn' && $this_player->values['current_robot_enter'] == $this_battle->counters['battle_turn']) { // Return false to cancel the switch action $this_return = false; break; } // If the switch reason was removal, make sure this robot stays hidden if ($this_switch_reason == 'removed' && $this_player->player_side == 'right') { $this_robot->flags['hidden'] = true; $this_robot->update_session(); } // Withdraw the player's robot and display an event for it if ($this_robot->robot_position != 'bench') { $this_robot->robot_frame = $this_robot->robot_status != 'disabled' ? 'base' : 'defeat'; $this_robot->robot_position = 'bench'; $this_player->set_frame('base'); $this_player->set_value('current_robot', false); $this_player->set_value('current_robot_enter', false); $this_robot->update_session(); $event_header = ($this_player->player_token != 'player' ? $this_player->player_name . ''s ' : '') . $this_robot->robot_name; $event_body = $this_robot->print_name() . ' is ' . $this_switch_reason . ' from battle!'; if ($this_robot->robot_status != 'disabled' && isset($this_robot->robot_quotes['battle_retreat'])) { $this_find = array('{target_player}', '{target_robot}', '{this_player}', '{this_robot}'); $this_replace = array($target_player->player_name, $target_robot->robot_name, $this_player->player_name, $this_robot->robot_name); $event_body .= $this_robot->print_quote('battle_retreat', $this_find, $this_replace); } // Only show the removed event or the withdraw event if there's more than one robot if ($this_switch_reason == 'removed' || $this_player->counters['robots_active'] > 1) { $this_battle->events_create($this_robot, false, $event_header, $event_body, array('canvas_show_disabled_bench' => $this_robot->robot_id . '_' . $this_robot->robot_token)); } $this_robot->update_session(); } // If the switch reason was removal, hide the robot from view if ($this_switch_reason == 'removed') { $this_robot->flags['hidden'] = true; $this_robot->update_session(); } // Ensure all robots have been withdrawn to the bench at this point if (!empty($this_player->player_robots)) { foreach ($this_player->player_robots as $temp_key => $temp_robotinfo) { $temp_robot = new rpg_robot($this_player, $temp_robotinfo); $temp_robot->robot_position = 'bench'; $temp_robot->update_session(); } } // Switch in the player's new robot and display an event for it $this_robot->robot_load($this_robotinfo); if ($this_robot->robot_position != 'active') { $this_robot->robot_position = 'active'; $this_player->set_frame('command'); $this_player->set_value('current_robot', $this_robot->robot_string); $this_player->set_value('current_robot_enter', $this_battle->counters['battle_turn']); $this_robot->update_session(); $event_header = ($this_player->player_token != 'player' ? $this_player->player_name . ''s ' : '') . $this_robot->robot_name; $event_body = "{$this_robot->print_name()} joins the battle!<br />"; if (isset($this_robot->robot_quotes['battle_start'])) { $this_robot->robot_frame = 'taunt'; $this_find = array('{target_player}', '{target_robot}', '{this_player}', '{this_robot}'); $this_replace = array($target_player->player_name, $target_robot->robot_name, $this_player->player_name, $this_robot->robot_name); $event_body .= $this_robot->print_quote('battle_start', $this_find, $this_replace); } // Only show the enter event if the switch reason was removed or if there is more then one robot if ($this_switch_reason == 'removed' || $this_player->counters['robots_active'] > 1) { $this_battle->events_create($this_robot, false, $event_header, $event_body); } } // Ensure this robot has abilities to loop through if (!isset($this_robot->flags['ability_startup']) && !empty($this_robot->robot_abilities)) { // Loop through each of this robot's abilities and trigger the start event $temp_abilities_index = $db->get_array_list("SELECT * FROM mmrpg_index_abilities WHERE ability_flag_complete = 1;", 'ability_token'); foreach ($this_robot->robot_abilities as $key => $token) { if (!isset($temp_abilities_index[$token])) { continue; } // Define the current ability object using the loaded ability data $temp_info = array('ability_id' => $key, 'ability_token' => $token); $temp_ability = new rpg_ability($this_player, $this_robot, $temp_info); } // And now update the robot with the flag $this_robot->flags['ability_startup'] = true; $this_robot->update_session(); } // Now we can update the current robot's frame regardless of what happened $this_robot->robot_frame = $this_robot->robot_status != 'disabled' ? 'base' : 'defeat'; $this_robot->update_session(); // Set this token to the ID and token of the switched robot $action_token = $this_robotinfo['robot_id'] . '_' . $this_robotinfo['robot_token']; //$this_battle->events_create(false, false, 'DEBUG', 'checkpoint ['.$action_token.'] | other : []'); // Return from the battle function $this_return = true; break; } elseif ($action_type == 'scan') { // Otherwise, parse the token for data if (!empty($action_token)) { list($temp_id, $temp_token) = explode('_', $action_token); $scan_info = array('robot_id' => $temp_id, 'robot_token' => $temp_token); } // If an ability token was not collected if (empty($scan_info)) { // Decide which robot should be scanned foreach ($target_player->player_robots as $this_key => $this_robotinfo) { if ($this_robotinfo['robot_position'] == 'active') { $scan_info = $this_robotinfo; } } } // Create the temporary target player and robot objects $temp_target_player = $this_battle->get_player($temp_target_robot_info['player_id']); $temp_target_robot = $this_battle->get_robot($scan_info['robot_id']); // Change the target robot's frame is set to taunt $temp_target_robot->set_frame('taunt'); // Generate the event header for this scan action $event_header = ($temp_target_player->player_token != 'player' ? $temp_target_player->player_name . ''s ' : '') . $temp_target_robot->robot_name; if (!rpg_game::robot_scanned($temp_target_robot->robot_token)) { $event_header .= ' (New!)'; } // Generate the event body for this scan action //$event_body = rpg_markup::robot_scan_markup($this_battle, $this_field, $temp_target_player, $temp_target_robot); $event_body = $temp_target_robot->print_scan_markup(); // Create an event showing the scanned robot's data $this_battle->events_create($temp_target_robot, false, $event_header, $event_body, array('console_container_height' => 2, 'canvas_show_this' => false)); //, 'event_flag_autoplay' => false // Ensure the target robot's frame is reset to base $temp_target_robot->set_frame('base'); // Add this robot to the global robot database array rpg_game::scan_robot($temp_target_robot->robot_token); // Set this token to the ID and token of the triggered ability $action_token = $action_token['robot_id'] . '_' . $action_token['robot_token']; // Return from the battle function with the scanned robot $this_return =& $this_ability; break; } // Break out of the battle loop by default break; } // Set the hidden flag on this robot if necessary if ($this_robot->robot_position == 'bench' && ($this_robot->robot_status == 'disabled' || $this_robot->robot_energy < 1)) { $this_robot->flags['apply_disabled_state'] = true; $this_robot->flags['hidden'] = true; $this_robot->update_session(); } // Set the hidden flag on the target robot if necessary if ($target_robot->robot_position == 'bench' && ($target_robot->robot_status == 'disabled' || $target_robot->robot_energy < 1)) { $target_robot->flags['apply_disabled_state'] = true; $target_robot->flags['hidden'] = true; $target_robot->update_session(); } // If the target player does not have any robots left if ($target_player->counters['robots_active'] == 0) { // Trigger the battle complete action to update status and result $this_battle->trigger_complete($this_player, $this_robot, $target_player, $target_robot); } // Update this player's history object with this action $this_player->history['actions'][] = array('action_type' => $action_type, 'action_token' => $action_token); // Return the result for this battle function return $this_return; }