scripting with a time delay

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

scripting with a time delay

Post by FeMaiden »

I don't know what to call it...

what I wanted to do is this.
there is a pedestal that a player must place a specific item on in order to *destroy* the item.

I wrote a script that destroyes the item but for the graphical effect, I want it to appear as if lightning stuck the object and destroyed it.

so..I simply placed a spawner that activates a shockburst.


now heres my question.

I want the spawner to activate the shockburst 3 times.

but I want it to wait half a second in between each burst.

putting

Code: Select all

function litStrike()
spawner_1.spawner:activate()
spawner_1.spawner:activate()
spawner_1.spawner:activate()
end
makes it look like it only hit once.I am aware of the order of operations, I realize that the spawner did go off 3 times, but because it happens so fast , it only looks like it went off once.

so i want to do somethhing like

Code: Select all

function litStrike()
spawner_1.spawner:activate()
-- wait half a second
spawner_1.spawner:activate()
--wait half a second
spawner_1.spawner:activate()
end
furthermore, i intend to place some more spawners in the arena to go off and create a kind of "light show" to dazzle and distract the player while I warp in the bosses for the boss fight.
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: scripting with a time delay

Post by Isaac »

Connect a timer to the spawner, set the timer interval to 0.3 seconds.

In your script, call:

Code: Select all

timer_1.timer:start()
delayedCall('timer_1', .95, "stop")
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: scripting with a time delay

Post by FeMaiden »

well, this is awesome...i'm not sure if anyone cares, but somebody seemed interested in my idea of party dialogue.

I just discovered this

Code: Select all

function doHudPrint(text)
  hudPrint(text)
end

function showDialogue()
  delayedCall(self.go.id, 5.0, "doHudPrint", "Hello Lowly Mortal.");
  delayedCall(self.go.id, 10.0, "doHudPrint", "I am going to speak to you using the HudPrint Method.");
  delayedCall(self.go.id, 15.0, "doHudPrint", "And these message will appear on the screen.");
  delayedCall(self.go.id, 20.0, "doHudPrint", "With 5 second gaps between them. All using one callback function.");
end




this will VASTLY improve my dialogue in my mod. I had tons of floor triggers everywhere, and in order to make sure the player stepped on them, i had to create "funnel" shaped hallways to force the player to step on the triggers.

so to take my example from a previous post

Code: Select all


function skinny()
	playSound("power_attack_yell_human_female")
	hudPrint (" "..party.party:getChampionByOrdinal(2):getName()..": Don't you just love skinny dipping in creepy ponds?")
end

function awesome()
	playSound("damage_human_male")
	hudPrint (" "..party.party:getChampionByOrdinal(3):getName()..": Yeah it's Awesome!")
end

function dressed()
	playSound("damage_human_female")
	hudPrint (" "..party.party:getChampionByOrdinal(4):getName()..": I guess we should, like...put our clothes back on or something")
end

function overthere()
	playSound("power_attack_yell_human_male")
	hudPrint (" "..party.party:getChampionByOrdinal(1):getName()..": We left them over there by the trees")
end

function wtf()
	playSound("damage_human_female")
	hudPrint (" "..party.party:getChampionByOrdinal(4):getName()..": like, wtf? it wasn't night when we got here...")
end


	
function showDialogue()
	delayedCall(self.go.id, 1.0, "skinny", "");
	delayedCall(self.go.id, 3.0, "awesome", "");
	delayedCall(self.go.id, 5.0, "dressed", "");
	delayedCall(self.go.id, 7.0, "overthere", "");
	delayedCall(self.go.id, 9.0, "wtf", "");
end
those 5 lines of dialogue required 5 different floor_trigger objects.

but that extra showdialogue() function at the bottom means I only need 1 floor_trigger and i use the connector to call up the showdialogue function and BAM, 5 lines of text from one trigger with a time delay between them.


this means I not only have much less objects on my map, but I can also fit in a LOT more dialogue.
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: scripting with a time delay

Post by Isaac »

One can make a single script object that holds all of the conversations (for the entire mod) in one table. This table can be keyed by floor_trigger_ids, such that all of your conversation triggers can be connected to the same script/function, and their id string itself is what indicates which conversation to display.

(Works best if the floor_triggers are set to self-disable.)
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: scripting with a time delay

Post by FeMaiden »

Isaac wrote:One can make a single script object that holds all of the dialog in one table. This table can be keyed by floor_trigger_ids, such that all of your conversation triggers can be connected to the same script/function, and their id string itself is what indicates which conversation to display.

well, I find it cumbersome to put ALL the dialogue into a single script entity lol.
I have a lot of dialogue i'm writing.
that would be tricky to keep track of it all.

so what i've been doing is making a separate entity for each "conversation" and placing it next to the trigger that triggers the dialogue.

although I guess you were just pointing out that theoretically, I could just write my *entire* script all in a single entity,
I mean couldn't I technically just make a separate map "level" and put all my scripts onto that level and then have every entity in my mod on all the other levels connect to the scripts over there?
but that makes no sense either , it seems easier to keep track of your scripts when you place them near the sections that trigger them.

isn't the point of the object oriented language so that it's easier to separate the different parts so you can debug it more efficiently?


which is why it's superior to say...BASIC which just has the code in one long list with the lines separated by numbers?
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: scripting with a time delay

Post by Isaac »

Imagine having one script of conversations, and anytime you need to add a new one, you just add a table entry, and connect a floor_trigger with an id that matches the table. This would save you duplicating [lots of] code in all of the separate script objects.

*Basic supports subroutines.

** Try this out:

Code: Select all

--Name the floor_triggers for the conversations. IE. convo_1, convo_2, convo_3, etc; or change "convo_#" to anything, and name a floor_trigger to match.

function showDialogue(floor_trigger)
 	local dialog = {}	  --Ordinal / text	
		dialog.convo_1 = {
							"2: Don't you just love skinny dipping in creepy ponds?",
							"3: Yeah it's Awesome!",
							"4: I guess we should, like...put our clothes back on or something",
							"1: We left them over there by the trees",
							"4: like, wtf? it wasn't night when we got here...",
						 }
		dialog.convo_2 = {
						
						 }
	local delay = 0
	for v = 1, #dialog[floor_trigger.go.id] do
		delayedCall(self.go.id, delay, "displayText", dialog[floor_trigger.go.id][v])
		delay = delay + (#dialog[floor_trigger.go.id][v])/9.5
	end
end
	
function displayText(text)
	local ordinal = tonumber(string.sub(text, 1,1))
	local champion = party.party:getChampionByOrdinal(ordinal) 
	local race = champion:getRace()
	if race == "ratman" or race == "insectoid" or race == "lizardman" then
		champion:playSound(race.."_happy")
	 else playSound('power_attack_yell_'..race..'_'..champion:getSex())	
	end
	
	hudPrint(tostring(champion:getName()..string.sub(text, 2)))
end	
Last edited by Isaac on Sat Oct 31, 2015 3:03 pm, edited 1 time in total.
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: scripting with a time delay

Post by FeMaiden »

I see...
and this might cover instances for one conversation has 8 lines of dialogue while another one might have only 3 lines?

and it also covers it if I want one conversation to have a time delay of 2 in between each line, but in a different convo, I might want a time delay of 3 in between each line?

and yeah I remember the gosub command from my C64 days, my point there was that a program in BASIC looks like this

10 code
20 code
30 code
40 code
50 code
60 code
..(etc)

and then theres all these goto 50, goto 90, commands anf if you are debugging you have to literally scan up and down all through the text.

but in my mod, i write each separate trap and puzzle in a separate entity, so that way I can test each one without having the others to distract me.


I admit, i have no true formal education in computer programming, I'm mostly self taught and therefore might not have formed the proper habits.
I learned QBASIC and visual basic in college, but they were mostly introductory courses, before I switched my major to accounting because my mother *convinced* me that "there's no money in computer programming, you're gonna earn a degree and end up in data entry"...
Last edited by FeMaiden on Sat Oct 31, 2015 2:50 pm, edited 1 time in total.
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: scripting with a time delay

Post by Isaac »

It should handle long conversations.

As it is ~currently, it sets the delay based on the length of the sentence; a longer sentence gives a longer delay.

If you want to change it, to a flat 4 seconds for every statement... The line to change is:

Code: Select all

delay = delay + (#dialog[floor_trigger.go.id][v])/9.5
Change it to:

Code: Select all

delay = delay + 4 --(#dialog[floor_trigger.go.id][v])/9.5
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: scripting with a time delay

Post by FeMaiden »

Isaac wrote:It should handle long conversations.

As it is ~currently, it sets the delay based on the length of the sentence; a longer sentence gives a longer delay.

If you want to change it, to a flat 4 seconds for every statement... The line to change is:

Code: Select all

delay = delay + (#dialog[floor_trigger.go.id][v])/9.5
Change it to:

Code: Select all

delay = delay + 4 --(#dialog[floor_trigger.go.id][v])/9.5

oh, now THAT is fascinating, the code dynamically adjusts the delay according to the sentence.
I've been trying to figure out what delay I want to put because some people read faster than others. I don't want someone tapping their foot impatiently waiting for the dialogue to finish, but I also don't want them rushing forward thinking it's done and missing something that the dialogue hinted at...
and then I don't want people getting frustrated because it moves too quick for them to read it.
I also realized that not all the players read english very well.
I played some mods, and the authors admitted they are not very good with english, i don't want them getting frustrated by all my english dialogue.
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: scripting with a time delay

Post by FeMaiden »

in the dialogue, i also have the game play a sound before each line of text, characters 2 and 4 are females while 1 and 3 are males, so i currently have been pasting "power_attack_male"/"female" for the front line and "damage_male"/"female" for the ones in back so each character has a different "voice".

I might make custom sounds later, but that could be cumbersome to change it all. I suppose it might be better to get that done first but I dunno.

I do have a custom sound effect that i plan to us throughout my mod connected to floor triggers, and i have 1 scripting entity and i've just been connecting them all to that. it seems pointless to keep copy/pasting the entity when my code will always be the same
Post Reply