Help with game logic - How to handle competing conditions???

Hey all, it’s the noob of the month here again trying to fix my logic and asking for help :slight_smile:

Let me explain my conundrum first…

So the game I’m trying to put together has a few features pertinent to this scenario:

  • The player gets a specific # of ammo on each level (this changes from lvl to lvl) info is stored in a data table and is updated in the GM every time a new level loads.
  • The level contains exactly the same amount of targets as the player’s ammo for that specific lvl (data from table)

Bound to LeftClick in the PlayerController BP I have the following logic:

Let me explain my logic here and please by all means correct me since it’s not working properly: :rofl:

On left click, first I check to see if the user still has bullets.
HasAmmo(1) → If Yes, → Spawn new bullet → Update Ammo (in GM), check again if user HasAmmo(2) after the spawn. If Yes → check targets left in the level (function in GM). If targets == 0 → EndLevel

HasAmmo(2) after the spawn. If No (means that was the last bullet → Delay (1sec, in case that last bullet hits the last target) → EndLevel

HasAmmo(1) → If No, → EndLevel

To make matters a bit crazier… in GM I have a tick that also checks to see if there are targets left:

Event Tick (GM):

CheckTargets func:

EndLevel Funct:

Now… if that wasn’t enough, I also have a custom event timer that when 1 min runs out calls → EndLevel yet again.

LevelTimer:

CountdownTimer func:

My issue is that when the last bullet is shot, if it hits the last target, CheckTargets calls → EndLevel…
However, immediately after that (1sec Delay) HasAmmo(2) No branch gets executed and EndLevel gets called again.
And 1.5 sec later HasAmo(1) No branch, calls EndLevel again :rofl:
I thought by Pausing the game in EndLevel, the other execution nodes would not fire, but I guess the Delay still fires after Set Game Paused “True”???

Any tips on handling this scenario is greatly appreciated.
I know it might be an easy fix, but can’t figure it out fml.

Hey @cnapsys!

Try using another branch. Put that before the delay, after the false branch on your “ShootBullets” code. Add a “GameOver” Bool, placed in the character controller BP, and make it default to FALSE, then have your delay/EndGame run from the TRUE path.

Next, in the “Check Targets” func on the GM: you can use “GetPlayerController”, cast to “YOURplayerController”, and Set GameOver = True.

That… SHOULD… Work. :slight_smile:

@Mind-Brain

Not sure if this is what you meant…???

The problem still remains with the 2 conditions I circled.
Because somehow, as soon as CheckTargets is true and that was the last bullet shot, the execution continues and HasAmmo(2) == 0 and then the False branch gets executed too :crazy_face:
I know they both load the same EndLevel widget, but for different reasons.
The True branch → CheckTargets, loads it because the level has truly ended. All targets have been cleared.
The False branch → loads it because the user has no more bullets.
At that exact point both conditions are true :crazy_face:
But I only want the False branch to be executed if there are still targets left in the level

Also, shouldn’t the branch be after the delay?

Pfeww… I think I finally got it working.

Still have to test everything thoroughly, but it seems to be working fine as of right now.

@Mind-Brain thx for the tip. Greatly appreciated!

Of course!

How are you using those bools that way? Are they reversed? Set to False once the game ends?

@Mind-Brain
No, it’s actually set to True when game ends in GM CheckTargets:

Okay, yeah! I see what you did there!

Glad to see you got it worked out! Sorry, I wasn’t on for a while. Go ahead and mark that solution, and if you have any more issues don’t be afraid to make another post! :slight_smile:

Will do! :+1:
Thanks again!

@Mind-Brain
Ooooops, spoke too soon. Sometimes it works, sometimes it doesn’t.
And I’m confusing myself in the process even more.
Sigh, back to square 1

Try adding another delay node before the branch you added, off the “HasAmmo=F”. .2 seconds should be good! That way the Gamemode can compute first! :slight_smile:

Working on it :slight_smile:
The problem now is that EndLevel gets triggered twice.
Need to figure out why…

@Mind-Brain

Ok, so I disconnected the EndLevel node from inside CheckTargets as that was causing the double trigger:

However in PC now the 2nd branch with hasAmmo never gets executed, as it never reaches → EndLevel.
It waits for me to click the mouse again to execute it off the 1st branch…

I know it’s such a simple thing but I’m being such a dum-dum :frowning:
Can’t figure it out for the life of me.

Ok, I have found a simpler solution :smiley:
Being the idiot that I am I always over complicate things.
Technically this game should always/only end if the player runs out of bullets. No need for checking the targets at the same time. (As there should be no way all the targets are destroyed and the player is left with bullets, unless of course I over complicate things later down the road and introduce ricochets and other crazy ideas :rofl:)
Since #bullets always == #targets, I can check just for bullets. In the EndLevel widget I can just count the targets left and determine if the level was cleared or not.
This works ok for now…

@Mind-Brain
if you see any issues with this code please let me know…

As always, any tips are greatly appreciated!

You could ditch the delay and bind a function on the bullet actor destroy event. Think that might work for you?

I can see that working… Thank you for the suggestion. I will actually add it in my BP in case I wanna use it later on.
For now it works.
My initial issue was that I was trying to cover all possible scenarios and on each instance I was ending the level.
Well, all those started butting heads and would get triggered in the situation where the last bullet was hitting the last target. I just needed to take a step back and reassess the entire logic.
I actually like your idea where the bullet is the part that is ending the level.
Last bullet → hits last target → ends level. But I’ll have to think of a way for it to work in the future. Knowing me I’ll over complicate things again and mess it up. :rofl:

Nonetheless, I really appreciate your guys’ help.
Thank you!

1 Like