Ok, before you even attempt to look at this code, here is a video that I have uploaded to YouTube that visually describes the problem.
http://www.youtube.com/watch?v=JHIz5ihp7Lw
And here's the problem. Even though within my code I have nested if statements, they still get run even though - in my eyes and what I have outputted in my Dark Basic console window - it shouldn't.
In a nutshell, I set a variable called 'failed' to the value '1'. Yet, later in my code, I test to see what the value is, and it comes back as '0', causing code to incorrectly run.
Nothing else within my code besides this function (I searched) modifies this variable, unless its part of a blanket reset of ALL variables - meaning everything would get reset and nothing would happen anyway.
Here's my code, I have it commented the best I can.
Function RenderTagging(pPlayerID)
REM define local arrays that we will shove data into from pointers
REM this holds tag step information
local dim tArray() as S4_TagStepType
link array tArray(), S4_PlayerList(pPlayerID).tagController.tagGroup.tagSteps
local i
REM update each invidivual sprite step
REM go in reverse order to make sure transitioning from one tag step to the next
REM doesn't get fudged up. Going in reverse prevents keystrokes from failing the next tagstep
REM Loop through each tag step
for i = (get array size(tArray()) - 1) to 0 step -1
REM a tagstep belongs into a group of tagsteps
REM make sure that we're only inputting data into the active tagstep
REM only do input if we're actually in tag mode. This allows animations to be played and finished after we're done tagging.
if S4_PlayerList(pPlayerID).tagController.tagGroup.currentIndex = i and S4_PlayerList(pPlayerID).tagging = 1
REM once again, declare local arrays
REM to hold data
local dim tStepArray() as integer
link array tStepArray(), tArray(i).tagSteps
local j
REM update tag status
REM 1=finished, 0=wip, -1= failed
if tArray(i).tagStatus = 0
REM run through 9 keys for input engine
for j = 0 to 8
if PlayerButtonPressed(pPlayerID, j)
REM get current frame from the current tag step... step. A tag step consists of multiple steps itself.
local tCurFrame
tCurFrame = tStepArray(int(tArray(i).currentStep))
REM make sure what the person inputted is valid.
REM input is valid.
if VerifyTagInput(tCurFrame, j) = 1
REM update current frame for the smooth flowing sprite.
tArray(i).curMaxFrame = tArray(i).maxFrame * ((tArray(i).currentStep + 1)/(tArray(i).maxStep + 1))
if tArray(i).curMaxFrame > tArray(i).maxFrame then tArray(i).curMaxFrame = tArray(i).maxFrame
inc tArray(i).currentStep, 1
if tArray(i).currentStep > tArray(i).maxStep
tArray(i).tagStatus = 1
tArray(i).currentStep = tArray(i).maxStep
REM tagstep is finished, update counter for the group.
REM moves onto the next tagstep within the group.
inc S4_PlayerList(pPlayerID).tagController.tagGroup.currentIndex, 1
endif
endif
REM input is invalid, fail this tagstep.
if VerifyTagInput(tCurFrame, j) = -1
tArray(i).tagStatus = -1
endif
endif
next j
endif
REM unlink the tagsteps
REM so we can iterate through some more later.
tArray(i).tagSteps = get arrayptr(tStepArray())
unlink array tStepArray()
endif
REM now we get to do some transitioning.
REM from taggroup to taggroup
REM we use various states to manage what we're doing.
REM failed=1 means the group was failed, 0 means in progress/not failed
REM finished=1 means the group was finished successfully, 0 means in progress/not finished
REM transitioning=n means various states of transition, such as updating sprites to making sure everything is offscreen and disabled for a new set
REM tagContinue>=1 means continue tagging after this tag group, 0 means no more tagging
REM push sprites off the bottom of the screen
REM since we failed miserably.
REM since this is a transition state, we could have this down below. But there is already a loop iterating through all of the sprites,
REM might as well use this one to update positions.
REM this does not require to be in tagging mode, as this is just updating sprites.
if S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 1 and S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 1
REM update sprite image to a big red X
set sprite frame tArray(i).dbSpriteID, 0
set sprite image tArray(i).dbSpriteID, 24
REM position frame closer to the bottom
inc tArray(i).pos.Y, 400 * GetTimeElapsed()
REM since we're still iterating through sprites
REM and 0 is the last one, if sprite 0 has a Y-value greater than 780,
REM we can assume all sprites are off the screen and ready for the next stage of transition
if i = 0 and tArray(i).pos.Y > 780
S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 2
S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 1
S4_PlayerList(pPlayerID).tagController.tagOrder = 0
S4_PlayerList(pPlayerID).tagController.tagGroup.finished = 0
S4_PlayerList(pPlayerID).tagController.tagContinue = 1
endif
endif
REM update sprite frame
if tArray(i).curFrame < tArray(i).curMaxFrame
inc tArray(i).curFrame, GetTimeElapsed() * 50
endif
REM shrink sprite. sprites are shrunk after their associated tagstep are completed
if S4_PlayerList(pPlayerID).tagController.tagGroup.currentIndex > i and S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 0
dec tArray(i).scale, GetTimeElapsed() * 200
if tArray(i).scale < 0
tArray(i).scale = 0
endif
endif
REM render sprites
scale sprite tArray(i).dbSpriteID, tArray(i).scale
set sprite frame tArray(i).dbSpriteID, int(tArray(i).curFrame)
paste sprite tArray(i).dbSpriteID, tArray(i).pos.X, tArray(i).pos.Y
next i
REM once again, we ONLY want this to happen if we're tagging.
if S4_PlayerList(pPlayerID).tagging = 1
REM now were testing/updating the tag group
REM see if we failed any steps
REM we're not transitioning - we're still doing tags.
REM so check to see if the player screwed up tagging.
if S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 0
for i = 0 to get array size(tArray()) - 1
REM if any tagstatus reads -1, fail the entire group
if tArray(i).tagStatus = -1
S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 1
REM exit loop to save some cycles
exit
endif
next i
endif
REM see if we have finished the tag successfully
REM currentIndex is 0-based whereas tagCount is 1-based
REM thus if currentIndex = tagCount, all tag steps in group have been finished successfully
REM also, don't do this if we're transitioning (value above 0) and ONLY IF WE HAVEN'T FAILED THE TAG
if S4_PlayerList(pPlayerID).tagController.tagGroup.currentIndex >= S4_PlayerList(pPlayerID).tagController.tagGroup.tagCount and S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 0 and S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 0
S4_PlayerList(pPlayerID).tagController.tagGroup.finished = 1
endif
REM this transition is to see if all the sprites have shrunk off to 0.
REM good transition means all sprites shrink to 0, bad sprites go off of the screen.
REM only do this if we're transitioning (transition= 1), if we finished good (finished=1), and that we didn't fail (fail=0)
if S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 1 and S4_PlayerList(pPlayerID).tagController.tagGroup.finished = 1 and S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 0
local tSumScale as float
tSumScale = 0.
for i = 0 to get array size(tArray()) - 1
inc tSumScale, tArray(i).scale
next i
REM if the sum of all sprite scales = 0, then all sprites are effectively oof of the screen
REM go to the next stage of transition
if tSumScale = 0
S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 2
endif
endif
REM player failed the tag earlier.
REM start the transitioning process. Play a bad sound effect, set transition to 1.
REM not updating the transition would mean multiple FX being played at once.
if S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 1 and S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 0
REM update transition to 1
REM set finished to 0, just for good measure.
S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 1
S4_PlayerList(pPlayerID).tagController.tagGroup.finished = 0
REM play failure FX
playDBFX(6)
endif
REM player finished the tag successfully (finished = 1), transitioning hasn't started (trans=0) and the player didn't fail the tag (failure = 0)
if S4_PlayerList(pPlayerID).tagController.tagGroup.finished = 1 and S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 0 and (S4_PlayerList(pPlayerID).tagController.tagGroup.failed = 0)
REM update transition so we only play one sound effect
S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 1
REM check to see if we continue tagging after this.
REM value > 0 means yes, value = 0 means do big finale anthem
local tFinish
tFinish = finishedPlayerTagGroup(pPlayerID, S4_PlayerList(pPlayerID).tagController.csmTagGroup)
REM play tag group finish
if tFinish = 0
REM 12 is success FX
playDBFX(12)
else
playRandomTagSpray()
endif
REM the further along the player gets in a tag, the harder the tag is to complete
inc S4_PlayerList(pPlayerID).tagController.tagOrder, 1
S4_PlayerList(pPlayerID).tagController.tagContinue = tFinish
endif
endif
endif
REM since we're doine with the tags
REM link then back up to pointers
S4_PlayerList(pPlayerID).tagController.tagGroup.tagSteps = get arrayptr(tArray())
unlink array tArray()
REM everything from pointers has been updated and are no longer in use
REM reassign new values to these pointers and groups as needed
REM yes we're tagging
if S4_PlayerList(pPlayerID).tagging = 1
REM yes we're transitioning
if S4_PlayerList(pPlayerID).tagController.tagGroup.transitioning = 2
REM yes we can continue tagging
if S4_PlayerList(pPlayerID).tagController.tagContinue > 0
REM update tag steps for the new tag.
GetTagGroupDD(pPlayerID, S4_PlayerList(pPlayerID).tagController.tagOrder)
S4_PlayerList(pPlayerID).tagController.tagContinue = 0
endif
endif
endif
endfunction
This, with watching the video I have posted, should clearly state the problem that I'm having. When I fail a tag, the sprites go off screen. They do go offscreen like they should, but then play the 'success' sound and continue onward, even though they shouldn't.
If I get rid of the 'success' portion of the code - these lines here especially:
tFinish = finishedPlayerTagGroup(pPlayerID, S4_PlayerList(pPlayerID).tagController.csmTagGroup)
S4_PlayerList(pPlayerID).tagController.tagContinue = tFinish
the problem ceases to exist. However, it also means I cannot continue tagging, period, which is a whole new problem.
Anyone else have sharp eyes and might have a suggestion for me?
EDIT: Solution found. Reason? Incorrect input.
I was inputting a value of "0" into "tagOrder" above. However, the indexes in the data system start off at 1. Thus, setting it would create an 'automatic' finish, so if the person screwed up a tag, it would load up a 'automatic' finish, increase the value by one, and then load to the next. So it seemed to me like it was starting off at 1 each time, but really it wasn't.
In essence, because it only took (1) frame for this to occur, I didn't see it anything flicker or whatnot with my own eye. In addition, because this condition existed for one frame, it was neigh impossible to debug until I started ripping out additional chunks of code until I started narrowing down possibilities.
So, lesson learned here: Sanitize your inputs.