Shiggy 630 Posted January 25, 2016 This script modify the way battle order works. Now each batter acts separately from the other and the time before its next action is determined by its speed . It modify heavily the way the battle systems works so it may not be compatible with a lot of battle scripts. I will try to work on compatibility patches in the next days , first with my own scripts and then with yanfly battle engine .(It's almost like there is more people that use this than people using the default engine) I'm still releasing now to gather some feedback first on the UI , should I hide the battle order window and only show it on a button press? How would you put in the interface a preview of how an action will affect the battle order? (I'm really bad at imagining at UI) Second I would also like to know what kind of skills affecting the battle order would you like to see ? I have some ideas but if you have suggestions,I will start with them . Also should the agility stat affect the speed whith which a battle recover its action . If yes,how? =begin #=============================================================================== Title: Advanced Battle Order Author: Shiggy Date: Jan 24, 2015 -------------------------------------------------------------------------------- ** Change log Jan 25, 2015 -Initial release of the script -------------------------------------------------------------------------------- ** Terms of Use * Free to use in non-commercial projects * Commercial uses * Ask permission * I may ask for a small fee * I may ask a free copy of your game * I may ask for other stuff like the right to use some assets * Will do bug fixes * Compatibility patches may be requested but no guarantees * Please report any compatibility issues anyway * Features may be requested but no guarantees, especially if it is non-trivial * Credits to Shiggy in your project * Preserve this header * Be nice to other people ( I don't want mean people to use my scripts) -------------------------------------------------------------------------------- ** Description This script modify the turn order in battle . At the beginning of the fight, agility detemines turn order,then action speed determines when a battler will be able to attack again. A window is showing the battle order. -------------------------------------------------------------------------------- ** Usage There is no real turn (in the way the deafult engine understands it) in this mode so for states and AI purposes ,it is considered that a turn has passed in the time necessary for a battler to recover after a 0 speed attack (default is 100 time units). This may lead to weird situation sometimes so be careful with this. Note that buffs/debuffs as well as states that end at the end of actions should still work normally.But if a state that end at the end of an action prevent the battler to act,he will never act again so be carefult with that. The default guard skill has 2000 speed which means the battler will ba able to attack automaticallly just after,it is advised to put guard speed to 0 or lower if you want it to be relevant. -------------------------------------------------------------------------------- ** Installation Place this script below Materials and above Main This script modifies heavily a lot of the combat system,it will likely be incompatible with other scripts affecting combat #=============================================================================== =end module FFX ActionSpeed = 100 SurpriseBonus = 100 Active_Color = Color.new(255,255,0) Bonus_Color = Color.new(0,255,0) Malus_Color = Color.new(255,0,0) def self.action_time(battler,speed) return [(ActionSpeed-speed),1].max end end module BattleManager attr_reader :action_battlers def self.make_action_list preemptive = [] preemptive = $game_troop.members if @surprise preemptive = $game_party.members if @preemptive preemptive.sort!{|a,b| b.agi - a.agi } return preemptive end def self.turn_start @phase = :turn end def self.actor_index=(index) @actor_index = index end end class Game_Action def speed speed = 0 speed += item.speed if item speed += subject.atk_speed if attack? # speed -= subject.agi/100.0 speed = FFX.action_time(subject,speed) end end class Game_Battler < Game_BattlerBase attr_accessor :speed alias ffx_reset_state_counts reset_state_counts def reset_state_counts(state_id) ffx_reset_state_counts(state_id) if $data_states[state_id].auto_removal_timing == 2 @state_turns[state_id] = (@state_turns[state_id]-1)*FFX::ActionSpeed end end alias ffx_overwrite_buff_turns overwrite_buff_turns def overwrite_buff_turns(param_id, turns) ffx_overwrite_buff_turns(param_id,(turns-1)*FFX::ActionSpeed) end def update_speed @speed-=1 update_buff_states end def update_buff_states update_state_time update_buff_turns end def update_state_time states.each do |state| if @state_turns[state.id] > 0 && state.auto_removal_timing == 2 @state_turns[state.id] -= 1 remove_state(state.id) if @state_turns[state.id] == 0 end end end def update_state_turns states.each do |state| if @state_turns[state.id] > 0 && state.auto_removal_timing == 1 @state_turns[state.id] -= 1 end end end end class Scene_Battle < Scene_Base alias ffx_create_all_window create_all_windows def create_all_windows ffx_create_all_window create_action_list_window end def create_action_list_window @action_list_window = Window_ActionList.new(Graphics.height-@status_window.height) end def increase_turn troop.pages.each {|page| @event_flags = false if page.span == 1 } @turn_count += 1 end def battle_start @timer = FFX::ActionSpeed-1 BattleManager.battle_start @action_battlers = [] preemptive = BattleManager.make_action_list all_battle_members.each { |battler| battler.speed = 0 - battler.agi } preemptive.each{ |battler| battler.speed -= FFX::SurpriseBonus } battler_turn end def speed_order(a, diff = a.speed - b.speed if diff < 0 return -1 elsif diff > 0 return 1 else return a.name <=> b.name end end def update_action_order @active_battlers = [] @alive_members = [] all_battle_members.each { |battler| @active_battlers.push(battler) if battler.alive? && battler.movable? @alive_members.push(battler) if battler.alive? } @active_battlers.sort! {|a,b| speed_order(a, } while @active_battlers[0].speed > 0 @active_battlers.each{|m| m.speed -=1 } @alive_members.each{|m| m.update_buff_states } @timer+=1 $game_troop.increase_turn if @timer%FFX::ActionSpeed == 0 end update_list end def update_list list = [] @active_battlers.each { |battler| for i in 0 .. 3 list.push(Info_Battler.new(battler,i)) end } list.sort! {|a,b| speed_order(a, } @action_list_window.refresh(list) end def battler_turn update_action_order @subject = @active_battlers.shift @subject.make_actions if @subject.actor? BattleManager.actor_index = @subject.index start_actor_command_selection else turn_start end end def command_attack BattleManager.actor.make_actions BattleManager.actor.input.set_attack select_enemy_selection end def command_guard BattleManager.actor.make_actions BattleManager.actor.input.set_guard next_command end alias ffx_on_skill_ok on_skill_ok def on_skill_ok BattleManager.actor.make_actions ffx_on_skill_ok end alias ffx_on_item_ok on_item_ok def on_item_ok BattleManager.actor.make_actions ffx_on_item_ok end def next_command turn_start end def turn_start @party_command_window.close @actor_command_window.close @status_window.unselect BattleManager.turn_start @log_window.wait @log_window.clear end def start_actor_command_selection unless scene_changing? refresh_status @status_window.unselect @status_window.open @status_window.select(BattleManager.actor.index) @party_command_window.close @actor_command_window.setup(BattleManager.actor) end end def process_action return if scene_changing? if !@subject || !@subject.current_action turn_end end return turn_end unless @subject if @subject.current_action @subject.current_action.prepare if @subject.current_action.valid? @status_window.open @subject.speed += @subject.current_action.speed execute_action end @subject.remove_current_action end process_action_end unless @subject.current_action end def turn_end BattleManager.turn_end process_event battler_turn end def process_action_end @subject.on_action_end refresh_status @log_window.display_auto_affected_status(@subject) @log_window.wait_and_clear @log_window.display_current_state(@subject) @log_window.wait_and_clear BattleManager.judge_win_loss end end class Window_ActionList < Window_Selectable def initialize(height) @list=[] super(Graphics.width-100,50,100,height-100) end def refresh(list) @list=list contents.clear draw_all_items end def item_max @list.size end def draw_item(index) rect = item_rect(index) string = @list[index].name change_color(FFX::Active_Color) #if @list[index] == @list[0] draw_text_ex(rect.x,rect.y,string) draw_horz_line(rect.y+rect.height/2) #change_color(normal_color) end def draw_horz_line(y) line_y = y + line_height / 2 - 1 contents.fill_rect(0, line_y, width, 2, line_color) end def line_color color = normal_color color.alpha = 128 color end end class Info_Battler attr_reader :name attr_reader :battler attr_accessor :speed def initialize(battler,turn) @name = battler.name @battler = battler @speed = battler.speed + turn * FFX.action_time(battler,battler.atk_speed) end end 3 Share this post Link to post Share on other sites
Cookie Ninja 374 Posted January 25, 2016 (edited) Great script! CTB systems are very fun to play and add alot of depth to combat tactics. Of course AGI should be considered while determening turn frequenzy. I'm not sure however, what formula is best to use but I'll make a suggestion as food for thought. n * x / y = z n = 1+('previous skill speed'/100) x = AGI of the character y = Total AGI and speed of all participants (enemies + partymembers) * 'their respective skill multipliers' or n z = each characters proportional number of actions (their % share) Other things to consider are how to implement insta cast abilitys. Maybe you could make it so that they get to act imediately after your action. But with the catch being that, you are sloted in behind the next in line if you use consecutive insta casts. Mostly to prevent exploitation from being built in to the engine. As for delay turn, I'll suggest another possible formula. (AGI+Skillspeed)/2 Also with a catch though. No more than 2 reductions can stack, and the debuff will last until the next action. Note: The CTB systems are fun because it lets the player control the flow of battle and anticipate what is to come. So they work best if there is little to no random variance. (I didn't see any of that while glancing over your script, just saying) Some developers like to have MAX and MIN caps on the proportion that any individual may take of the overall action turns. Mainly to prevent some actors/enemys from taking over the show completely (looking at you Rikku ) aswell as preventing some actors to fall behind and get very few action times (looking at you Auron ). JK I for one didn't mind Rikku acting 50 times in a row between every other caracters turn! xD But some do, could be worth considering No matter what type of formulas you finally decide on using, keep in mind what makes CTBs great and nurture those aspects. Finally, GREAT WORK! Your contributions are awsome, thanks alot for your efforts.^^ Hope all this helps to some extent! Edited January 25, 2016 by Cookie Ninja Share this post Link to post Share on other sites
Shiggy 630 Posted January 25, 2016 (edited) Thanks for the feedback,Cookie. I'll see what can I do, the problem is everytime i publish a script thinking to myself I will polish it later. I think of a new script and start working on something else. The thing I'm working on right now is pretty awesome in my opinion and should be released later today Ps: Oh god it's been less than 2 months and I already have more than 500 posts Edited January 25, 2016 by Shiggy Share this post Link to post Share on other sites
Sixth 113 Posted January 25, 2016 I'll see what can I do, the problem is everytime i publish a script thinking to myself I will polish it later. I think of a new script and start working on something else.I know that feeling. Regarding the battle order UI, I think it should be shown all the time. I mean, it is a CTB system, so it is pretty mandatory to show the order. Eventually, you can put in a toggle button for it, in case someone would like to see the scenery without the UI. And here is how you could show where the actor would jump on the order list graphically: http://postimg.org/image/sozbinl3d/ My Paint skills are awesome, right? So, that arrow thingy would be put between the two characters on the order table, indicating that that is the spot the actor will jump after performing the action. Alternatively, you can take a look on the game called "Legend of Heroes - Trails in the Sky". That game uses a CTB system with a pretty solid UI for it. Note that it uses images instead of character names, and when someone is targeted, it's image on the order list will be highlighted. FF10... One and a half hour spent in a single battle just to be able to say that I beat the ultimate boss in it. Good old times! 1 Share this post Link to post Share on other sites
Shiggy 630 Posted January 25, 2016 @Sixth I had FF 10 in mind but showing only the order for each battler once instead of showing several next attacks will be simpler , and if i can't manage to get the arrow,I will try using some kind of color code. Thanks for the idea . I need to look at legend of heroes now. Share this post Link to post Share on other sites
c61dyn 0 Posted September 20, 2017 I was wondering if anyone can help me. It's probably really simple but I know next to nothing about programming. I keep getting this error: https://postimg.org/image/twcvewjwf/442556b4/ It has to do with how the script is split in two and how I don't understand programming syntax. I've tried fiddling around with it, but I'm lost. Help would be appreciated. Share this post Link to post Share on other sites
Shiggy 630 Posted July 7, 2019 Apparently the script was affected by the site migration so you can download it here if you want a clean version https://www.dropbox.com/s/rloftmzysowo5f2/ffx_battle_order.rb?dl=0 Share this post Link to post Share on other sites