Localized message repeats itself [Solved]

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Localized message repeats itself [Solved]

Post by jedimoose32 »

Hi everyone.

I'm trying to have a message/notification appear in the top-left of the screen when a certain event happens. The first time the event happens, it works fine and the text appears. All subsequent times after that, the message shows up between three and ten times in a row. I can't figure out what's causing it. Any idea what I've done wrong in my lua? Pictures and code below.

How it looks the first time (no problems here):
Image
How it looks each subsequent time (problem):
Image
Here's the code that runs this:
Hidden/Spoiler:
[code]
function GoForBombing()
if GetObjectTeam("cp6") == DEF or GetObjectTeam("cp7") == DEF then
--BOMB THEM!!

RewindAnimation("flyby"); --Here we want the bomber to go back to the beginning of its run if not there already...
PlayAnimation("flyby"); --...and come for another flyby
--SetProperty("bomber1", "SoundProperty", "vwingflying")
DestroyTimer(bombingreset) --Get rid of the timer that caused us to come back to this point
strafecoord = CreateTimer("strafecoord") --Create a timer that will let us know when the bombing animation is finished
SetTimerValue(strafecoord, (17))
StartTimer(strafecoord)
ShowMessageText("level.dda.objectives.bombwarn1",1) --Let the clones know that the cavalry has arrived
ShowMessageText("level.dda.objectives.bombwarn2",2) --Let the droids know of their impending doom
OnTimerElapse(function(BombingResetTime) --Once the animation timer is done we'll...
DestroyTimer(strafecoord) --...get rid of the timer...
bombingreset = CreateTimer("bombingreset") --...make a new timer that will determine when another bombing run will occur...
SetTimerValue(bombingreset, (math.random(45,105))) --...which will be somewhere between 0:45 and 1:45 later.
StartTimer(bombingreset)
OnTimerElapse(GoForBombing, bombingreset) --Once this random timer has finished I want this whole GoForBombing function to run itself again
end
,strafecoord)
end

end
[/code]
That whole function "GoForBombing" gets called the first time when a particular object is destroyed, using OnObjectKillName, and as you can see by my comments in the code, from then on as long as either CP6 or CP7 belongs to team 2 then the bomber should keep coming back. That part works fine. I'm just trying to make it look a bit nicer by not having the message absolutely spammed on the player's screen. Thanks!
Last edited by jedimoose32 on Sun Nov 16, 2014 5:29 pm, edited 1 time in total.
User avatar
Maveritchell
Jedi Admin
Jedi Admin
Posts: 7366
Joined: Mon Aug 21, 2006 11:03 pm

Re: Localized message repeats itself

Post by Maveritchell »

Your if statement ("GetObjectTeam("cp6") == DEF..etc.) isn't a one-time condition. That should fire multiple times, because the condition is (theoretically) continually met.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: Localized message repeats itself

Post by jedimoose32 »

Right but isn't it just being checked once each time I call the function GoForBombing?
User avatar
Maveritchell
Jedi Admin
Jedi Admin
Posts: 7366
Joined: Mon Aug 21, 2006 11:03 pm

Re: Localized message repeats itself

Post by Maveritchell »

Right, duh, I'm an idiot. I'll take a look back once I've slept.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: Localized message repeats itself

Post by jedimoose32 »

Thanks. I've looked through that code any number of times and can't figure it out.
User avatar
Locutus
1st Lieutenant
1st Lieutenant
Posts: 420
Joined: Fri Jun 04, 2010 10:08 am
Projects :: Stargate Battlefront Pegasus
Location: Germany
Contact:

Re: Localized message repeats itself

Post by Locutus »

I assume you are calling GoForBombing() more than one time during the match, right?
Now, each time you call this function you will register a new OnTimerElapse() event, thus for each time you call the function it will be executed i+1 time.
So just enclose the elapse function with an if-statement and you should be good: (Destroying a timer will not release the OnTimerElapse function)

timer_elapse_initialized = false

function GoForBombing()
[...]
if not timer_elapse_initialized then
OnTimerElapse(...)
timer_elapse_initialized = true
end
[...]
end
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: Localized message repeats itself

Post by jedimoose32 »

It kind of works...

The message now displays 1x the first run, 1x the second run, then 2x the third, 3x the fourth, 4x the fifth, etc. I'll show you how I put it into my code:
Hidden/Spoiler:
[code]
function ScriptPostLoad()
...
timer_elapse_initialized = false --Locutus
end

function GoForBombing()
if GetObjectTeam("cp6") == DEF or GetObjectTeam("cp7") == DEF then
--BOMB THEM!!

RewindAnimation("flyby"); --Here we want the bomber to go back to the beginning of its run if not there already...
PlayAnimation("flyby"); --...and come for another flyby
--SetProperty("bomber1", "SoundProperty", "vwingflying")
DestroyTimer(bombingreset) --Get rid of the timer that caused us to come back to this point
strafecoord = CreateTimer("strafecoord") --Create a timer that will let us know when the bombing animation is finished
SetTimerValue(strafecoord, (17))
StartTimer(strafecoord)
ShowMessageText("level.dda.objectives.bombwarn1",1) --Let the clones know that the cavalry has arrived
ShowMessageText("level.dda.objectives.bombwarn2",2) --Let the droids know of their impending doom
if not timer_elapse_initialized then --Locutus
OnTimerElapse(function(BombingResetTime) --Once the animation timer is done we'll...
DestroyTimer(strafecoord) --...get rid of the timer...
bombingreset = CreateTimer("bombingreset") --...make a new timer that will determine when another bombing run will occur...
SetTimerValue(bombingreset, (math.random(5,15))) --...which will be somewhere between 0:45 and 1:45 later.
StartTimer(bombingreset)
OnTimerElapse(GoForBombing, bombingreset) --Once this random timer has finished I want this whole GoForBombing function to run itself again
end
,strafecoord)
timer_elapse_initialized = true --Locutus
end
end

end
[/code]
I have tried putting that first "timer_elapse_initialized = false" bit above PostLoad, in PostLoad, and in GoForBombing, and they all yield the same result.
I suppose it works the first two times because timer_elapse_initialized is a boolean, and only has two states? What do you think?
User avatar
Maveritchell
Jedi Admin
Jedi Admin
Posts: 7366
Joined: Mon Aug 21, 2006 11:03 pm

Re: Localized message repeats itself

Post by Maveritchell »

So why are you destroying your timers at all? If you're going to reuse them under the same name, just recycle them by resetting their start values (which you're doing already) and don't destroy them. Initialize them first (CreateTimer) outside the function.

Also, could you describe your desired logic in plaintext? I.e. when your events occur and under what conditions.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: Localized message repeats itself

Post by jedimoose32 »

I must have misinterpreted the tutorial on timers. It seemed to imply that the DestroyTimer bit was an important part of it. I've gone ahead and removed those lines now.

Essentially what I'm trying to accomplish is this:
1. Gate gets destroyed.
2. Message displays advising that V-Wing is about to fly by.
3. V-Wing flies past.
4. V-Wing reaches end of its animation path.
5. Game starts Invisible-Random-Timer to determine when the V-Wing should fly past again.
6. Invisible-Random-Timer elapses.
7. Steps 2 through 6 repeat ad infinitum.

Here's my current code. I tried using Locutus's idea in a few different variations but it ended up stopping everything after the second bombing run.
Hidden/Spoiler:
[code]
function GoForBombing()
if GetObjectTeam("cp6") == DEF or GetObjectTeam("cp7") == DEF then

StopTimer(bombingreset)

--BOMB THEM!!
ShowMessageText("level.dda.objectives.bombwarn1",1) --Let the clones know that the cavalry has arrived
ShowMessageText("level.dda.objectives.bombwarn2",2) --Let the droids know of their impending doom

RewindAnimation("flyby"); --Here we want the bomber to go back to the beginning of its run if not there already...
PlayAnimation("flyby"); --...and come for another flyby

SetTimerValue(strafecoord, (17))

StartTimer(strafecoord) --Start the timer so we know when the anim is done playing
OnTimerElapse(BombingResetTime,strafecoord)
end
end

function BombingResetTime() --Once the animation timer is done we'll...

StopTimer(strafecoord)

--SetTimerValue(bombingreset, (math.random(5,15))) --...which will be somewhere between 0:45 and 1:45 later.
SetTimerValue(bombingreset, (math.random(5,15)))

StartTimer(bombingreset)
OnTimerElapse(GoForBombing, bombingreset) --Once this random timer has finished I want this whole GoForBombing function to run itself again

end
[/code]
User avatar
Locutus
1st Lieutenant
1st Lieutenant
Posts: 420
Joined: Fri Jun 04, 2010 10:08 am
Projects :: Stargate Battlefront Pegasus
Location: Germany
Contact:

Re: Localized message repeats itself

Post by Locutus »

Since you are using two OnTimerElapse functions you should encapsulate both with an if-clause.

if not timer_1_elapse_initialized then
OnTimerElapse(BombingResetTime,strafecoord)
end

if not timer_2_elapse_initialized then
OnTimerElapse(GoForBombing, bombingreset)
end

Set timer_X_elapse_initialized to true at the end of each function.

Another note:
Because math.random can cause trouble in multiplayer I'd recommend to replace it with this: (ScriptCB_random() * 10) + 5
ScriptCB_random() returns a random value between 0 and 1 and works perfectly in MP.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: Localized message repeats itself

Post by jedimoose32 »

This worked. Thanks so much for your help!

For anyone viewing this later on, my code:
Hidden/Spoiler:
[code]
function ScriptPostLoad()
...
--Create a timer that will let us know when the bombing animation is finished
strafecoord = CreateTimer("strafecoord")
bombingreset = CreateTimer("bombingreset") --...make a new timer that will determine when another bombing run will occur...

timer1_elapse_initialized = false
timer2_elapse_initialized = false
...
OnObjectKillName(GoForBombing, "thegate");
end

function GoForBombing()
if GetObjectTeam("cp6") == DEF or GetObjectTeam("cp7") == DEF then

StopTimer(bombingreset)

--BOMB THEM!!
ShowMessageText("level.dda.objectives.bombwarn1",1) --Let the clones know that the cavalry has arrived
ShowMessageText("level.dda.objectives.bombwarn2",2) --Let the droids know of their impending doom

RewindAnimation("flyby");
PlayAnimation("flyby");

SetTimerValue(strafecoord, (17))

StartTimer(strafecoord)
if not timer1_elapse_initialized then
OnTimerElapse(BombingResetTime,strafecoord)
end
end
timer1_elapse_initialized = true
end

function BombingResetTime()

StopTimer(strafecoord)

SetTimerValue(bombingreset, (math.random(5,15)))

StartTimer(bombingreset)
if not timer2_elapse_initialized then
OnTimerElapse(GoForBombing, bombingreset)
end
timer2_elapse_initialized = true
end
[/code]
Post Reply