Closed Roguedeus closed 9 years ago
An alternative to pluging-into FTB, would be some sort of make_speed
and make_action_orders
change that allowed for the battle order to 'shift' mid-turn, according to each players initiative, chosen actions, and remaining potential actions.
I'm not sure how I could pause and insert multiple actions that way though... I'd have to analyze it.
Essentially I am trying to avoid an Active Battle system, but still allow for a similar dynamic, while maintaining the typical default turn by turn aspect.
I am not familiar with that battle system to provide any useful comments. You'll have to explain how it works.
Each actor has an AP total that is applied to a total party AP cap. An action costs a number of AP (normally 1 AP) and generally each actor is limited to using an equal number of AP they would contribute to the party total, before being capped.
EX: Actor-A with 2 AP and Actor-B with 3 AP, MAY HAVE a party cap of 4 AP. Every turn the party can spend 4 total AP, in any order, via any actor. Thus if Actor-A used both their AP, then Actor-B would be limited to 2 AP, even though they had 3. In reverse, Actor-A would be limited to 1 AP, if Actor-B had used all 3 of theirs first.
The catch for this system, is that initiative is pointless. Speed has no baring on battle at all as every turn is all or nothing for each side. It makes for some very strategic choices and allows for deep skill trees that would be a waste in a timed setting.
Ok, FTB sounds pretty straightforward.
-Turn-based. -You get x amount of AP to work with in one turn -You can use those AP however you wish between actors
Now in your plugin, you want
-AP to recover
That's where I would start. You would determine how you want the AP to recover for the most part. You may be able to implement your new mechanic with that element alone.
Chrono Cross implemented a similar mechanic in the battle system.
Everyone had 7 AP (there was no party cap, each actor just had 7 AP). When your turn comes around (based on speed and whether you had AP available), you have 5 options
I don't remember the AP recovery rates, but I think it was 1 AP per action taken. So for example, if I perform one action, everyone else recovers 1 AP. If I choose to pass, then everyone including myself would recover 1 AP as well.
I could look it up but that's the general idea.
That's similar, but FTB completes the parties turn when all AP have been used, and resets AP at the beginning of every new turn.
I have spent the last few hours deconstructing FTB and finding out how it ticks. I attempted to intercept the way it processes actions as they are made, but I've had an issue with the point in the choice sequence that the action array is touched.
Are the actions executed immediately when you pick them?
Yes.
I am trying to stop that, and instead queue them for NORMAL processing. While keeping the AP mechanic intact.
Once I have that figured out, I am going to shift the actors speed, based on the total queued actions speeds. Thus actors using more AP's will perform theirs after actors using less AP's... Though higher AGI/Speed actors might still act first, even with more AP's used.
I am having a hell of a time trying to work around the damn action_input_index
and next_command
, and I am so brain fried right now I can't see why.
Looking at it, it seems like it shouldn't be much harder than pushing new actions into the array upon selection, and then allowing only actors with qualifying AP to select. Iterating the selecting actors input index, on the resulting next_command
cycle...
But its not working... /boggle
Caveat: It also requires that actors don't initialize their action array with blank actions. Remaining Scene_Battle.next_command
is determined by remaining AP's rather than actor.next_command
being true.
NO I deleted my comment lol
Ok so basically all next_command should be doing is selecting the next person that can move. If no one can move, it will just keep updating until you find it.
I can get the first actor to select skills for AP, but once their lot is done, it won't move over to the next actor.
I am guessing its something simple. But my head hurts and I need sleep. I'll do my best to jump in first thing tomorrow.
Sounds like there's more to be done after you call next_command
I've reached a point where I can't follow the methods clearly enough to figure out why actor selection breaks with my recent changes.
I don't know what I am missing, but whatever it is I have lost my patience and I am beginning to get irritated. So I am going to step away.
If you have time, here is a demo. (uncomment the plugin to see the results) http://www.roguedeus.com/Stuff/New_FTB_Demo.zip
I've commented my plugin as clearly as possible so you know why I did what. (Thats not obvious) If you can figure out what I did wrong, I'd appreciate it. I'll try to look at it again later anyway. After I clear my head for a while. ;)
Note: I had a small realization as I made the demo and this post, so its not as broken as I complained in the first sentence. But I am still stepping away for a while. :)
Alright taking a look.
def next_ftb_member?(last_index)
actor = BattleManager.actor
puts("<FTB Plugin> next_ftb_member? #{actor.name}(#{actor.ftb_actions}/#{actor.max_ftb_actions})")
return true if actor.nil? #OK
return false if actor.max_ftb_actions >= actor.ftb_actions # <------------
return false if BattleManager.actor.index >= last_index
return BattleManager.actor.index != last_index
end
What does this method do?
That may be something I left in on accident.
I changed it from >
to >=
in order to try and stop the extra selection from occurring. Forgot to comment it.
So what is the problem? Eric selects two skills, natalie then selects one skill, and the actions are carried out.
You need to un-comment the plugin...
When active, Eric always selects an extra skill atm.
I haven't touched the code since I posted the demo so I am not sure if its as simple as accurately updating action_input_index
or more complex. Another set of eyes helps.
The problem is that method. There's something wrong with the highlighted condition.
Or at least I think it is...
I don't think BattleManager's next_command
would work here, since it's picking its own actor separate of your logic...
Anyways I used
return false if actor.max_ftb_actions > actor.ftb_actions #OK
And it works fine.
lol no kidding... It seems I tend to pick the moment I am right on the edge of figuring it out to walk away or ask for help.
Thanks BTW. I'll poke at it a bit to see if I can find any holes before adjusting speeds and stuff.
Found something already... In the demo, with your change, act with natalie first, then eric... It completes the turn before both of Erics AP are used. ;)
That's not happening for me. I re-downloaded and applied the one-line change.
Well I'll be damned. Looks like I've got a problem then. :(
For the record, I changed all references of next_command
to the local scope version. It doesn't seem to break anything. (Not sure why Yanfly used the other one)
Looks like I've got more fun to look forward to in the morning...
I hate troubleshooting return
fall-throughs.
Demo issues.
You can't cancel a selection and re-select before the turn ends. This must be caused by the fact that normally an FTB skill is performed the moment its selected, so there is no reason to cancel it. Canceling it would require the last skill pushed into the action array to b deleted, and the AP refunded. I am just not sure where to do it without breaking something.
The demo wont allow you to change actors after Eric selects his first skill... I'm not sure whats causing the inability to switch actors between action selections. It may be why on my full build, acting with the second party member first (natalie in the demo) causes the first action selected by the remaining actor (index 0) to complete selection to early. I am guessing its comparing the AP of first to act index actor rather than the current one.
I can't guess why it doesn't happen in the demo the same way. Some other one of Yanfly's battle plugins may be touching the scenes variables. I am hoping if the demo code works correctly, then whatever is breaking my full build will fix itself.
I am thinking, would it be easier to simply scrap the default FTB code (leaving in the windows and AP variables) and re-purpose it, rather than try to utilize the Scene_Battle
and BattleManager
stuff?
edit: Nope that was a mistake... :p
I don't understand why I am having such a difficult time with this. I am about to start pulling my hair out.
I have written well over a few dozen scripts on my own, ranging from re-arranging the UI to adding effects over time states, and some things I surprised myself I figured out without assistance.
But what seems SHOULD BE a straight forward battle mechanic tweek, has consumed almost three days of my time, in both attempting to do it and untangling my head of the resulting frustration.
For refunding an action, you could simply write additional logic that looks at the currently selected actor's list of actions and removes the last one. This should not break anything.
For the other issue, it is not obvious why that's happening either.
I'd just put it aside until later. A lot of scripts I have were put on hold cause I ran into an issue and wasn't sure how to solve it.
I would, if it wasn't a core battle mechanic. I have nearly all my desired tweaks done, with a few flavor ones still not done yet, but I would rather not get far into battle balance without a reliable core mechanic.
Of course, I could simply cut it. But I am stubborn. ;(
You'll have to go back to the drawing board then and figure out exactly how the "next actor" is determined.
next_command
is a good start.
You might as well just explain to me how it works in detail, with all the steps and the condition checks, since I only glanced at it.
Thats what I spent a good lot of time today doing. I managed to figure out a few new things in the process, but even after tracing the entire logic flow, I get hung up. I am sure if I keep at it long enough I am bound to eventually stumble onto a solution, if nothing else. :p
Its just that my brain doesn't crunch code easily. Its a very deliberate activity for me and after 3+ hours, I get VERY fatigued. Doubly so when I can't follow it easily. Its a curse.
Then write it out. And then translate it into normal language.
Eventually you should be at a point where you have all of the relevant methods down and a brief explanation where you don't have to actually look at it anymore.
That's how debugging usually works.
If the engine doesn't allow you to skip to the next actor, then you'll have to start from the point where you press "skip actor" and then write down all the methods that are being called.
I agree. I have started commenting every single step in the code. A few of my most recent relizations were from that.
I think I am obsessing a bit to much on my battle mechanic though... I have changed pretty much every part of how HP and MP function, HIT, Damage, Variance, Crit, and how Params factor in... Even EVA and MEV... The last untouched part is action speed... Heh.
Very different, but similar enough that its not to shocking.
Anyways so it looks like if I press the "right" key, it skips to the next actor on the right
def create_actor_command_window
scene_battle_create_actor_command_window_abe
@actor_command_window.set_handler(:dir4, method(:prior_command))
@actor_command_window.set_handler(:dir6, method(:next_command)) #<----
end
Easy enough: it calls next_command
in Ace Battle Engine.
Then you go and look for that definition and see that FTB does something
alias scene_battle_next_command_ftb next_command
def next_command
if ftb_action?
perform_ftb_action
else
scene_battle_next_command_ftb
end
end
Checking if it's an FTB action? Not sure how, let's look
def ftb_action?
return false unless BattleManager.btype?(:ftb)
return false if BattleManager.actor.nil?
return false if BattleManager.actor.current_action.nil?
action = BattleManager.actor.current_action.item
return !action.nil?
end
From what I'm seeing, it's an FTB action if there is an action and you're using FTB battle mode. Ok, so if you have an action, then it's FTB. If you don't have an action, then it calls the old next_command
which basically just jumps to the next actor.
OK, so this is the key point: if you skip an actor, it will just go to the next actor. If you skip that actor as well, the action phase will begin and your actors will do nothing.
This also explains something else: if you have selected an action, then it will perform the FTB action. Because you want to queue up all the actions first, you decided to change it
def next_command
if ftb_action?
#perform_ftb_action
queue_ftb_action
else
scene_battle_next_command_ftb
end
end
Again, if your actor has an action, then it will call queue_ftb_action
. If you tried to skip the actor, and it already selected one action, then it will call queue_ftb_action
.
We can now conclude that there's something in your logic that must be forcing the game to always choose Eric if Eric selected an action.
So we look at queue_ftb_action
def queue_ftb_action
puts("<FTB Plugin> queue_ftb_action")
hide_ftb_action_windows
@subject = BattleManager.actor
item = @subject.input.item
if item
puts("\n<FTB Plugin> Queuing #{@subject.name} FTB Action #{item.name}.")
puts("<FTB Plugin> Total Queued: #{@subject.actions.length}\n ")
consume_ftb_action(item)
@subject.action_input_index += 1
end
@subject = nil
show_ftb_action_windows
end_ftb_action #Moved here for visibility. (from: show_ftb_action_windows)
end
There's nothing too interesting here. It's just making sure you update your AP.
end_ftb_action
is where we go.
def end_ftb_action
puts("<FTB Plugin> end_ftb_action")
if $game_party.inputable?
select_next_member
else
status_redraw_target(BattleManager.actor)
BattleManager.next_command
turn_start
end
end
Eric has selected one action. You still have two AP available. Therefore, party is still inputable, and therefore it will select the next member.
def select_next_member
status_redraw_target(BattleManager.actor)
last_index = $game_party.battle_members.size - 1
puts("<FTB Plugin> select_next_member #{BattleManager.actor.name} index(#{BattleManager.actor.index}, last(#{last_index}))")
for member in $game_party.battle_members.reverse
break if member.inputable?
last_index -= 1
end
# next_command if next_ftb_member?(last_index)
BattleManager.next_command if next_ftb_member?(last_index)
return if BattleManager.actor.nil?
if BattleManager.actor.index >= last_index && !BattleManager.actor.inputable?
p 'prior'
prior_command
else
start_actor_command_selection
status_redraw_target(BattleManager.actor)
end
end
You have overwritten the old select_next_member
, so we don't need to worry about anything else.
And this...is not obvious what's going on.
Note that I put in a "prior" output there to test if it occurs. It doesn't happen if I just skip everyone's turn. It doesn't happen if Eric selects one action and tries to skip his turn. It never happens.
If Eric is always being asked to select his action, then that means the BattleManager
has set it to Eric. And it is always set to Eric, even if you try to skip his turn after selecting one action.
You'll have to go to BattleManager.next_command
and see what it's doing. Perhaps it is being overwritten by other scripts as well.
I think select_next_member
and whats happening in the BattleManager
via indexes is whats throwing me off big time. I think I am missing something regarding the windows actor selection and the resulting BattleManage.actor
assignment... But I can't be sure.
In my build I have removed ftb_action?
need for an action, as it will always return true now that actions aren't removed on selection like they would be normally in FTB. I also moved the index iteration outside of queue_ftb_action
because @subject.input.item
was sometimes nil, due to the index not updating BEFORE its checked...
Etc...
Thanks for helping me logic through it. ;)
Battlemanager is straightforward
def self.next_command
begin
if !actor || !actor.next_command
@actor_index += 1
return false if @actor_index >= $game_party.members.size
end
end until actor.inputable?
return true
end
First, @actor_index is the index of the actor that will select a command.
actor
simply returns that actor
def self.actor
@actor_index >= 0 ? $game_party.members[@actor_index] : nil
end
First, if there is no actor, it will check the next member. If the actor cannot move, it will check the next member.
If no one can move anymore, then it will return false and the battle scene should realize that no more actors can input anymore and it's time to move on.
Here is the default method in Scene_Battle
def next_command
if BattleManager.next_command
start_actor_command_selection
else
turn_start
end
end
Taking what I said before: If no more actors can move, then start the turn. Done.
So now the problem. Look carefully
def self.next_command
begin
if !actor || !actor.next_command
@actor_index += 1 #<-------
return false if @actor_index >= $game_party.members.size
end
end until actor.inputable? #<-------
return true
end
Index only changes if your actor can't move. If your actor can still move, then it will return true.
Can Eric move? YES. YES HE CAN.
He still has available AP!!
This is why eric is always selected.
Give me a minute to get my code up and digest through what you've posted. ;)
THANKS!
Here is your problem:
(1) You want to skip Eric's turn. Eric has already selected one action. We know from yanfly's code that skipping an actor's turn involves checking if the actor has any actions. If there are actions, then it will process FTB action. But you've changed it to queue it up and get the next actor. But battle manager will always select Eric because he can still move. Back to (1). We're in a loop.
I think I follow all of that. But I have a few questions... Give me a sec.
I should start charging fees for script consulting lol kind of like corporations that hire people to come in and solve their problems.
First:
BattleManager.actor_index
is only changed when self.clear_actor
, self.next_command
and self.prior_command
are called. So my change to Scene_Battle.next_command
,
def next_command
puts("<FTB Plugin> Scene_Battle.next_command")
if ftb_action?
BattleManager.actor.action_input_index += 1
queue_ftb_action
else
scene_battle_next_command_ftb
end
end
means self.next_command
is only ever called in end_ftb_action
... And since thats only called if the party is out of AP, it helps lock the actor on selection.
Now that I look, the default engine only ever actually calls BattleManager.next_command
in Scene_Battle.next_command
to that's pretty necessary.
However, before I changed it, FTB allowed for actor selection change freely between actions and I can't see how it managed to do that, given the same circumstance.
Being that BattleManager.actor_index
was still decided independent of the player selecting them manually.
I am thinking of writing a plugin for Yanfly's FTB Battle Option that utilizes its AP model but maintains the speed/initiative of the default system, with a twist.
Like FTB, actors will be able to take multiple actions in a turn, dependent on the AP used in the action. But unlike FTB, each potential action point has its own initiative and actions that require multiple action points must WAIT until the total points needed reach their initiative order.
The catch, of course, is that the player will need a visual indicator so they are aware when their potential actions will fall within the order. I figure I could use Yami's - Order Gauge for this somehow.
Thoughts? Critiques? Potential issues?