Hey guys, thanks for taking the time to look at this.
I'm working on implementing a turn based combat system.
I've finished most of it but am getting stuck on the last part.
I'm trying to do it exclusively in twine because I've found mixing JS to be not as simple as mixing css.
Anyway, before I post the code here's the current turn algorithm I'm working with so were on the same page:
It's similar to FFX's turn system.
It's basically a hourglass system.
*Every participant in a battle has a hourglass with sand inside. The Sand is tickValue.
*The sand drains at the same rate for every participant
*When a participant runs out of sand, they get a turn
*If a participant is not present, or is KO'd midbattle, they are treated as "Dead" and skipped
Those are the basic principles. There are only small changes otherwise.
I tried to comment and space the code a little to make it easy to understand, any help is appreciated.
I have a lot of variables, but for the most part my format is
ObjectName_Object'sSomething
This is 7 passages by the way, the one with "Elijah" is copypasted 5 other times with only the name changing. The first one is the main passage that calls the rest.
I got through a bunch of problems but can't find out this one please assist!
The part that is failing is pointed out(it never goes to a turn).
This is the main passage"TurnCheck".
As long as the battle is not finished it should loop.
<<if $Battle_Finished is "true">>
<<BattleResolution>>
<<else>>
/%
There can be 1-6 participants
It goes through every participant one by one and decrement's there amount of sand (tickValue)
%/
<<if ($Elijah_Checked is "false") >>
<<ElijahTurnCheck>>
<<endif>>
<<if ($Chrea_Checked is "false") >>
<<ChreaTurnCheck>>
<<endif>>
<<if ($Jonathan_Checked is "false") >>
<<JonathanTurnCheck>>
<<endif>>
<<if ($EnemyOne_Checked is "false") >>
<<EnemyOneTurnCheck>>
<<endif>>
<<if ($EnemyTwo_Checked is "false") >>
<<EnemyTwoTurnCheck>>
<<endif>>
<<if ($EnemyThree_Checked is "false") >>
<<EnemyThreeTurnCheck>>
<<endif>>
/%Once every participant has been checked, reset to false%/
<<set $Elijah_Checked to "false">>
<<set $Chrea_Checked to "false">>
<<set $Jonathan_Checked to "false">>
<<set $EnemyOne_Checked to "false">>
<<set $EnemyTwo_Checked to "false">>
<<set $EnemyThree_Checked to "false">>
/%Call itself again. It should repeat until the battle is resolved%/
<<TurnCheck>>
<<endif>>
A sample Passage "ElijahTurnCheck"(There are 5 more of these).
This code is supposed to decrement sand and trigger a turn if the sand runs out.
<<set $Elijah_Checked to "true">> /%Update Check %/
<<if $Elijah_Dead is "true">>
<<TurnCheck>> /%If this character has been defeated, return to main check page%/
<<else>>
/%If tick is not set, initialize it%/
<<if $Elijah_tickIsSet is "false">>
<<if $Elijah_firstTurn is "true">>
<<set $Elijah_tickValue to $Elijah_Agility>>
<<set $Elijah_firstTurn to "false">>
<<set $Elijah_tickIsSet to "true">>
<<else>>
<<set $Elijah_tickValue = $Elijah_Agility * $Elijah_abilityDelay >>
<<set $Elijah_tickIsSet to "true">>
<<endif>>
<<endif>>
/%Status Effect Modifiers%/
<<if $Elijah_slowed is "true">>
<<set $Elijah_tickValue = $Elijah_tickValue - .5>>
<<else if $Elijah_hasted is "true">>
<<set $Elijah_tickValue = $Elijah_tickValue - 2>>
<<else>>
<<set $Elijah_tickValue = $Elijah_tickValue - 1>>
<<endif>>
/%At 0, you get a turn%/
<<if $Elijah_tickValue <= 0>> <--THIS PART FAILS, I never go to a turn for any participant.
<<ElijahTurn>>
<<else>>/%If it's not 0 yet, the decrement has happened so move on%/
<<TurnCheck>>
<<endif>>
<<endif>>
Comments
Initial sand
playerA:4
playerB:6
playerC:8
Decrement everyone
playerA:3
playerB:5
playerC:7
Decrement everyone
playerA:2
playerB:4
playerC:6
Decrement everyone
playerA:1
playerB:3
playerC:5
Decrement everyone
playerA:0 <--Turn happens. Choose ability/ Calculate damage/status effects.
playerB:2
playerC:4
Decrement everyone
playerA:7 (calculate ability delay/agility. Set new sand amount/tickValue. Decrement)
playerB:1(unchanged, only decremented)
playerC:3(unchanged, only decremented)
Decrement everyone
playerA:6
playerB:0 <--Process repeats
playerC:2
This is how i imagined it would be on paper but it's not working.
Second problem is that if Elijah isn't going to get a go, you're starting another turn.
This routine just needs to decement Elijah's count and, if it hits zero give him a turn. No need for it to be starting any other turns.
Once you've got those fixed and are back to something closer to a linear flow, you might want to try adding a print for the tick value so you can see what's going on.
The following should get rid of a lot of the unnecessarily recursive calls:
1 question though, the first change here: I was able to make sense of this easy as it's doing the same thing but just more efficiently/in less lines of code.
But at the bottom here: You removed the link that points the passage back to the master turncheck.
Will it just go to the master turncheck once it reaches the end of the passage automatically?
Am just trying to wrap my head around it ^^;.
Thanks again Kael! Will drop a status update sometime early this morning.
It keeps repeating infinitely, going to take another crack at it.
I located and solved severals errors and it's going to the object's actual <<turn>> now.
Another problem has arisen though.. instead of it stopping on the turn once it's gotten there and allowing an option to be selected, it goes/reads through the passage and exits immediately without ever prompting the player.
like <<ElijahTurn>>
<--Beginning of turn passage-->
Fight
Run
Etc
<--End of passage-->
^ player never is prompted to choose one, just runs through it then goes to the previous passage that called it. I know it's entering the turn atleast because I put an alert there whenever it does.
Going to keep looking into it.
For other passages you have to click one of the choices to continue.
Does <<display>> only show the text of a passage? I'm wondering if links that are put inside a <<displayed>> passage actually stop progress like regular ones do?
Instead of using "true" and "false" string values to represent a boolean state you should use the actual boolean values of true and false.
ex. using actual boolean values. So mykael's example would look something like the following:
Yeah, display just displays the content - it doesn't stop for input.
So. Download SugarCube 2 for 1.4.2, install it and switch over to using it as your story format. The main reason for this is that it'll give you a working <<goto passage>> macro. Use that instead of <<display passage>> when you want the game to stop for input.
Why SugarCube 2 - I spent several hours trying to get a working goto for 1.4.2 and nothing seemed to work. It ended up being simpler and quicker to switch to SugarCube than to continue messing around trying to get something to work.