I'm trying to come up with a way during battle to talk with an enemy, and convince them to join you. Right now I'm trying to get two scripts to work: Enemy talk, which lets you choose "talk" as a command and use it to trigger events, and a Traitor script, which applies an effect to a skill that causes the enemy to join your side when the skill hits.
All I want is for the talk command to be able to turn the target you're talking to into a traitor if you're able to convince them to join you. I've tried making it so when you use talk, it forces the actor to use the traitor skill on the enemy, but since the actor already used "talk" as their action that turn, it just freezes the game. Below are the two scripts
#=============================================================================
# * Crystal Engine - Traitor
#------------------------------------------------------------------------------
# Current Version: 1.00
#=============================================================================
$imported = {} if $imported.nil?
$imported["CE-Traitor"] = true
=begin
with this script you can have a skill that invites enemies over to you side and
actors can go to theirs. Use the notetag <traitor> to make a skill a traitor skill
enemies and actors can be notetaged with <traitor rate: x%> were x is the percent
=end
module CRYSTAL
module TRAITOR
TRAITOR_ENEMY = 1 # the enemy used to create a traitor actor
TRAITOR_BASE = 2 # the actor used for the base for capture
DEFAULT_TRAITOR_RATE = 50 # the defualt rate for traitor
end
end
#==============================================================================
# Editing beyond this point may cause stone, zombie, mist frenzy, and/or toad,
# so edit at your own risk.
#==============================================================================
module CRYSTAL
module REGEXP
module BASEITEM
TRAITOR_RATE = /<(?:TRAITOR_RATE|Traitor Rate|traitor rate):[ ](\d+)[%%]>/i
end
module USABLEITEM
TRAITOR = /<(?:TRAITOR|Traitor|traitor)>/i
end
end
end
module CRYSTAL
module CHECK
#--------------------------------------------------------------------------
# * Checks if you have a certain script installed
#--------------------------------------------------------------------------
def self.require(self_name, script, site = "http://crystalnoel42.wordpress.com")
unless $imported["CE-BasicModule"]
msg = "The script '#{self_name}' requires the latest\n"
msg += "version of 'Crystal Engine - Basic Module' to work properly\n"
msg += "Go to http://crystalnoel42.wordpress.com/ to download this script."
raise SyntaxError.new(msg)
end
unless $imported[script]
msg = "The script '#{self_name}' requires the latest\n"
msg += "version of #{scripts_list(script)} to work properly\n"
msg += "Go to #{site} to download this script."
raise SyntaxError.new(msg)
end
end
#--------------------------------------------------------------------------
# * Script Name Guide
#--------------------------------------------------------------------------
class <<self; alias scripts_list_ec scripts_list; end
def self.scripts_list(name)
scripts_list_ec(name)
case name
when "CE-EnemyClasses"
return "Crystal Engine - Enemy Classes and Levels"
end
end
end
end
CRYSTAL::CHECK.require("Crystal Engine - Traitor", "CE-BasicModule")
CRYSTAL::CHECK.require("Crystal Engine - Enemy Capture", "CE-EnemyClasses")
#==============================================================================
# ** DataManager
#------------------------------------------------------------------------------
# This module manages the database and game objects. Almost all of the
# global variables used by the game are initialized by this module.
#==============================================================================
module DataManager
#--------------------------------------------------------------------------
# alias method: load_database
#--------------------------------------------------------------------------
class <<self; alias load_database_traitor load_database; end
def self.load_database
load_database_traitor
load_notetags_traitor
end
#--------------------------------------------------------------------------
# new method: load_notetags_ehpb
#--------------------------------------------------------------------------
def self.load_notetags_traitor
groups = [$data_actors, $data_skills, $data_items, $data_enemies]
for group in groups
for obj in group
next if obj.nil?
obj.load_notetags_traitor
end
end
end
end
#==============================================================================
# ■ RPG::BaseItem
#==============================================================================
class RPG::BaseItem
#--------------------------------------------------------------------------
# public instance variables
#--------------------------------------------------------------------------
attr_accessor :traitor_rate
#--------------------------------------------------------------------------
# common cache: load_notetags_dce
#--------------------------------------------------------------------------
def load_notetags_traitor
@traitor_rate = CRYSTAL::TRAITOR::DEFAULT_TRAITOR_RATE
#---
self.note.split(/[\r\n]+/).each { |line|
case line
#---
when CRYSTAL::REGEXP::BASEITEM::TRAITOR_RATE
@traitor_rate = $1.to_i
#---
end
} # self.note.split
#---
end
end # RPG::BaseItem
#==============================================================================
# ¡ RPG::UsableItem
#==============================================================================
class RPG::UsableItem < RPG::BaseItem
#--------------------------------------------------------------------------
# public instance variables
#--------------------------------------------------------------------------
attr_reader :is_invite
#--------------------------------------------------------------------------
# common cache: load_notetags_abe
#--------------------------------------------------------------------------
def load_notetags_traitor
@is_invite = false
#---
self.note.split(/[\r\n]+/).each { |line|
case line
#---
when CRYSTAL::REGEXP::USABLEITEM::TRAITOR
@is_invite = true
end
} # self.note.split
#---
end
end # RPG::UsableItem
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# A battler class with methods for sprites and actions added. This class
# is used as a super class of the Game_Actor class and Game_Enemy class.
#==============================================================================
class Game_Battler < Game_BattlerBase
#--------------------------------------------------------------------------
# * Traitor Rate
#--------------------------------------------------------------------------
def traitor_rate
if actor?
return actor.traitor_rate
elsif enemy?
return enemy.traitor_rate
else
return 0
end
end
#--------------------------------------------------------------------------
# * Alias method: item_apply
#--------------------------------------------------------------------------
alias item_apply_traitor item_apply
def item_apply(user, item)
item_apply_traitor(user, item)
item_invite(user, item) if @result.hit?
end
#--------------------------------------------------------------------------
# * New method: item_tech_point_effect
#--------------------------------------------------------------------------
def item_invite(user, item)
return unless item.is_invite
invite = rand(100)
if invite < self.traitor_rate
if SceneManager.scene_is?(Scene_Battle)
SceneManager.scene.display_invite_result(self, true)
end
process_invite
else
if SceneManager.scene_is?(Scene_Battle)
SceneManager.scene.display_invite_result(self, false)
end
end
end
#--------------------------------------------------------------------------
# * Process Invite
#--------------------------------------------------------------------------
def process_invite
if enemy?
basic_actor = $data_actors[CRYSTAL::TRAITOR::TRAITOR_BASE].clone
basic_actor.id = $data_actors.size
basic_actor.class_id = enemy.class_id
basic_actor.initial_level = enemy.level
basic_actor.base_equip_slots = enemy.equip_slots if $imported["CE-EnemyEquipment"] && $imported["YEA-AceEquipEngine"]
basic_actor.equips = enemy.equips if $imported["CE-EnemyEquipment"]
basic_actor.name = enemy.name
basic_actor.description = self.class.description if $imported["CE-EnemyClasses"] && $imported["YEA-ClassSystem"]
$data_actors.push(basic_actor)
actor = $game_actors[basic_actor.id]
$game_party.traitors.push(actor)
actor.pokerus_infect if $imported["CE-Pokerus"] && self.infected?
$game_troop.members.delete(self)
@battler_name = ""
SceneManager.scene.create_spriteset
elsif actor?
enemy = Game_Enemy.new($game_troop.members.size, CRYSTAL::TRAITOR::TRAITOR_ENEMY)
enemy.pokerus_infect if $imported["CE-Pokerus"] && self.infected?
enemy.enemy.name = name
$game_troop.members.push(enemy)
$game_party.remove_actor(id)
SceneManager.scene.create_spriteset
end
end
end
#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It used within the Game_Troop class
# ($game_troop).
#==============================================================================
class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :name # Name
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias init_traitor initialize
def initialize(index, enemy_id)
init_traitor(index, enemy_id)
if enemy.take_class_name
data_name = $data_classes[@class_id].name
else
data_name = old_name
end
if CRYSTAL::ENEMY::SHOW_LEVEL
@name = data_name + " Lv. #{level}"
else
@name = data_name
end
end
#--------------------------------------------------------------------------
# * Get Display Name
#--------------------------------------------------------------------------
def name
return @name
end
end
#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
# This class handles parties. Information such as gold and items is included.
# Instances of this class are referenced by $game_party.
#==============================================================================
class Game_Party < Game_Unit
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :traitors # Traitors in the Party
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias traitor_init initialize
def initialize
traitor_init
@traitors = []
end
#--------------------------------------------------------------------------
# * Get Battle Members
#--------------------------------------------------------------------------
alias true_battle_members battle_members
def battle_members
true_battle_members + @traitors
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle < Scene_Base
#--------------------------------------------------------------------------
# * Display a Invite Result
#--------------------------------------------------------------------------
def display_invite_result(subject, result)
@log_window.display_invite_result(subject, result)
end
end
#==============================================================================
# ** BattleManager
#------------------------------------------------------------------------------
# This module manages battle progress.
#==============================================================================
module BattleManager
#--------------------------------------------------------------------------
# * End Battle
# result : Result (0: Win 1: Escape 2: Lose)
#--------------------------------------------------------------------------
class << self; alias traitor_battle_end battle_end; end
def self.battle_end(result)
for actor in $game_party.traitors
$game_party.add_actor(actor.id) unless actor.dead?
end
$game_party.traitors.clear
traitor_battle_end(result)
end
end
#==============================================================================
# ** Window_BattleLog
#------------------------------------------------------------------------------
# This window is for displaying battle progress. No frame is displayed, but it
# is handled as a window for convenience.
#==============================================================================
class Window_BattleLog < Window_Selectable
#--------------------------------------------------------------------------
# * Display an Invite Result
#--------------------------------------------------------------------------
def display_invite_result(subject, result)
if result
add_text("#{subject.name} turned traitor!")
wait
else
add_text("Negotiations failed!")
wait
end
end
end
#==============================================================================
#
# ▼ End of File
#
#==============================================================================
=begin
#===============================================================================
Title: Command - Enemy Talk
Author: Hime
Date: Apr 19, 2013
--------------------------------------------------------------------------------
** Change log
Apr 19, 2013
- added support for accessing currently talking actor
- initial release
--------------------------------------------------------------------------------
** Terms of Use
* Free to use in non-commercial projects
* Contact me for commercial use
* No real support. The script is provided as-is
* Will do bug fixes, but no compatibility patches
* Features may be requested but no guarantees, especially if it is non-trivial
* Credits to Hime Works in your project
* Preserve this header
--------------------------------------------------------------------------------
** Description
This script allows you to set up enemy talk events during battle and use
a talk command to interact with enemies.
--------------------------------------------------------------------------------
** Required
Command Manager
(http://himeworks.wordpress.com/2013/02/19/command-manager/)
--------------------------------------------------------------------------------
** Installation
Place this script below Command Manager and above Main
--------------------------------------------------------------------------------
** Usage
To add the talk command, tag actors with
<cmd: enemy_talk>
Enemy talk events are set up as troop event pages.
To create an enemy talk event page, create a comment of the form
<enemy talk event: x>
Where x is the index of the enemy that this will apply to. The first enemy
has an index of 1.
To trigger this talk event, you must use the "talk" command on the enemy
during battle. The event will run once the action is executed.
#===============================================================================
=end
$imported = {} if $imported.nil?
$imported["Command_EnemyTalk"] = true
#===============================================================================
# ** Configuration
#===============================================================================
module TH
module Command_EnemyTalk
# Command name to display
Name = "Talk"
# Message to display in battle log when talk action executed
Format = "%s talked to %s"
#===============================================================================
# ** Rest of Script
#===============================================================================
Regex = /<enemy talk event: (\d+)>/i
CommandManager.register(:enemy_talk, :actor)
end
end
#-------------------------------------------------------------------------------
# Parse talk events from troop event pages
#-------------------------------------------------------------------------------
module RPG
class Troop
def talk_event_pages
return @talk_event_pages unless @talk_event_pages.nil?
parse_talk_event_pages
return @talk_event_pages
end
def parse_talk_event_pages
@talk_event_pages = {}
@pages.each do |page|
page.list.each do |cmd|
if cmd.code == 108 && cmd.parameters[0] =~ TH::Command_EnemyTalk::Regex
@talk_event_pages[$1.to_i - 1] = page
next
end
end
end
end
end
end
#-------------------------------------------------------------------------------
# Enemy talk command
#-------------------------------------------------------------------------------
class Command_EnemyTalk < Game_BattlerCommand
end
#-------------------------------------------------------------------------------
# Store currently talking actor somewhere
#-------------------------------------------------------------------------------
class Game_Temp
attr_accessor :talking_actor
end
#-------------------------------------------------------------------------------
# Add "talk" action
#-------------------------------------------------------------------------------
class Game_Action
attr_reader :talk_to_enemy
alias :th_cmd_enemy_talk_clear :clear
def clear
th_cmd_enemy_talk_clear
@talk_to_enemy = false
end
def set_enemy_talk
@talk_to_enemy = true
self
end
alias :th_cmd_enemy_talk_valid? :valid?
def valid?
@talk_to_enemy || th_cmd_enemy_talk_valid?
end
end
#-------------------------------------------------------------------------------
# Add "talk" to actor commands
#-------------------------------------------------------------------------------
class Game_Actor < Game_Battler
def add_command_enemy_talk(args)
cmd = Command_EnemyTalk.new(TH::Command_EnemyTalk::Name, :enemy_talk)
add_command(cmd)
end
end
#-------------------------------------------------------------------------------
# Handle talk event pages
#-------------------------------------------------------------------------------
class Game_Troop < Game_Unit
def talk_event_pages
troop.talk_event_pages
end
#-----------------------------------------------------------------------------
#
#-----------------------------------------------------------------------------
def setup_talk_event(index)
page = talk_event_pages[index]
return unless page
@interpreter.setup(page.list)
end
end
#-------------------------------------------------------------------------------
# Display messages related to talk actions
#-------------------------------------------------------------------------------
class Window_BattleLog < Window_Selectable
def display_talk_action(subject, target)
add_text(sprintf(TH::Command_EnemyTalk::Format, subject.name, target.name))
end
end
#-------------------------------------------------------------------------------
# Battle logic for handling talk command
#-------------------------------------------------------------------------------
class Scene_Battle < Scene_Base
def command_enemy_talk
BattleManager.actor.input.set_enemy_talk
select_enemy_selection
end
alias :th_cmd_enemy_talk_on_enemy_cancel :on_enemy_cancel
def on_enemy_cancel
th_cmd_enemy_talk_on_enemy_cancel
case @actor_command_window.current_symbol
when :enemy_talk
@actor_command_window.activate
end
end
alias :th_cmd_enemy_talk_execute_action :execute_action
def execute_action
if @subject.current_action.talk_to_enemy
execute_enemy_talk_action
refresh_status
else
th_cmd_enemy_talk_execute_action
end
end
#-----------------------------------------------------------------------------
# Perform enemy talk execution logic
#-----------------------------------------------------------------------------
def execute_enemy_talk_action
$game_temp.talking_actor = @subject
target_index = @subject.current_action.target_index
target = $game_troop.members[target_index]
@log_window.display_talk_action(@subject, target)
$game_troop.setup_talk_event(@subject.current_action.target_index)
while !scene_changing?
$game_troop.interpreter.update
target.sprite_effect_type = :whiten if target.alive?
break unless $game_troop.interpreter.running?
update_for_wait
end
$game_temp.talking_actor = nil
end
end
I might be missing something really simple, so any help at all is appreciated. Thanks!