[Script] for timed effects with stats

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
User avatar
djoldgames
Posts: 107
Joined: Fri Mar 23, 2012 11:28 pm
Contact:

[Script] for timed effects with stats

Post by djoldgames » Mon Oct 01, 2012 9:00 pm

I need to create some items (potions) with temporarily incremented character stats like Strength, Dexterity, Vitality...
This is my working script for strength boost. In onUseItem hook you can create your own timed effect and in the script function stopEffect_ returns values back. Problem is with too much functions for deactivate timers. Deactivating the timers for effects is some sort of "luberjack" script because I don't find the way to call function with PARAMETER from connector.
It would be much simplier by using some sort of this: addConnector("activate","scriptEffects","stopEffect(PARAMETER)")

@AH: is there any way to connect function with parameter from spawned timer?

Script entity with ID=scriptEffects

Code: Select all

-- script for timed effects --
-- 
--  "strBoost": increasing strength 
-- 
ActiveEffect = {}
function activateEffect(effect, champion, amount, duration)
	if self.ActiveEffect[effect.."_"..champion] then
		return false
	end
	fw.debugPrint("Effect "..effect.." is activated: Champion="..champion..", Amount="..amount..", Duration="..duration.."s")
	self.ActiveEffect[effect.."_"..champion] = { amount=amount, duration=duration }
	local timer = findEntity("timer_effect_"..effect.."_"..champion)
	timer:setTimerInterval(duration)
	timer:activate()
	return true
end

function stopEffect_strBoost(id)
	local champion = party:getChampion(id)
	champion:setStatMax("strength", champion:getStatMax("strength") - self.ActiveEffect["strBoost_"..id].amount)
	self.ActiveEffect["strBoost_"..id] = nil
	local timer = findEntity("timer_effect_strBoost_"..id)
	timer:deactivate()
	playSound("generic_spell")
	print("strBoost deactivated for champion="..id)
	print("Actual Stat="..champion:getStat("strength")..", StatMax="..champion:getStatMax("strength"))
	hudPrint(champion:getName().." feels less stronger!")
end
function stopEffect_strBoost_1()
	self.stopEffect_strBoost(1)
end
function stopEffect_strBoost_2()
	self.stopEffect_strBoost(2)
end
function stopEffect_strBoost_3()
	self.stopEffect_strBoost(3)
end
function stopEffect_strBoost_4()
	self.stopEffect_strBoost(4)
end

spawn("timer",1,1,1,0, "timer_effect_strBoost_1")
timer_effect_strBoost_1:addConnector("activate","scriptEffects","stopEffect_strBoost_1")
spawn("timer",1,1,1,0, "timer_effect_strBoost_2")
timer_effect_strBoost_2:addConnector("activate","scriptEffects","stopEffect_strBoost_2")
spawn("timer",1,1,1,0, "timer_effect_strBoost_3")
timer_effect_strBoost_3:addConnector("activate","scriptEffects","stopEffect_strBoost_3")
spawn("timer",1,1,1,0, "timer_effect_strBoost_4")
timer_effect_strBoost_4:addConnector("activate","scriptEffects","stopEffect_strBoost_4")
Clone object in items.lua

Code: Select all

cloneObject{
	name = "potion_giant_strength",
	baseObject = "potion_healing",
	uiName = "Potion of Giant Strength",
	description = "After drink, character obtain the Giant Strenght for 1 minute.",
	gfxIndex = 149,
	onUseItem = function(self, champion)
		playSound("consume_potion")
		local effect = "strBoost"
		local amount = 10
		local duration = 60
		local str_old = champion:getStatMax("strength")
		local isActive = scriptEffects.activateEffect( effect, champion:getOrdinal(), amount, duration)
		if isActive then
			champion:modifyStatCapacity("strength", amount)
			champion:modifyStat("strength", amount)
			print("Actual Str="..str_old..", Max="..champion:getStatMax("strength"))
			hudPrint(champion:getName().." feels much stronger!")
		else
			hudPrint(champion:getName().." can use only one effect of Giant Strength at the same time!")
		end
		return true
	end,
	weight = 0.6,
}
Last edited by djoldgames on Tue Oct 02, 2012 12:56 am, edited 2 times in total.

User avatar
crisman
Posts: 305
Joined: Sat Sep 22, 2012 9:23 pm
Location: Italy

Re: [Script] for timed effects with stats

Post by crisman » Tue Oct 02, 2012 12:38 am

I'm not sure if I can help, but I'll tell you how I created my temporarily potions. It's pretty complicated, but they works fine for me... I created a regeneration potion and a dexterity potion.
Here is how I created the dexterity potion:

in item.lua I cloned a potion
SpoilerShow
cloneObject{
name = "potion_dexterity",
uiName = "Potion of Dexterity",
baseObject = "potion_speed",
description = "This potion will give you great dexterity for some time",
onUseItem = function(self, champion)
potions.dexterity(self, champion)
return true
end,
}
then, in the editor, I have placed 4 timers, 4 counters, and a script.
I've called the timers timerChampion1, timerChampion2 and so on, and the counters the same way: countSec1, sountSec2 and do on. The script had an ID called potions, with the function called dexterity.
SpoilerShow
function dexterity(self, champion)
--time is how much time the potion will last.
local time = 5

for i = champion:getOrdinal(), champion:getOrdinal() do
x = findEntity("countSec"..i):getValue()
findEntity("countSec"..i):setValue(x+time)

if findEntity("timerChampion"..i):isActivated() then
return
else
champion:modifyStatCapacity("dexterity", 5)
champion:modifyStat("dexterity", 5)
findEntity("timerChampion"..i):activate()
end
end
end
each timer is linked with two things, one the corresponding counter with a decrement function (timerChampion1 with countSec1, and so on...), and with another function, which I'll discuss later. The timer is set to 1 sec.
What the function is doing is adding to the counter a number which decrease by one every second. My code allows the player to add seconds to the duration of the potion, so if a potion lasts 5 seconds, drinking 2 potions will last a total of 10 seconds.
The function which the timer is linked at will wear off the potion. it is a function reserved for every champions, so there are 4 of them.
I've called them noDex1, noDex2, etc...
SpoilerShow
function noDex1()

if countSec1:getValue() == 0 then
party:getChampion(1):modifyStatCapacity("dexterity",-5)
party:getChampion(1):modifyStat("dexterity", -5)
timerChampion1:deactivate()
end
end
obviously, for the other function the 1 must be changed with 2, 3, 4. I hope someone else did it with a much simplier code than mine...
I hope this can help... somehow.

User avatar
Isaac
Posts: 2995
Joined: Fri Mar 02, 2012 10:02 pm

Re: [Script] for timed effects with stats

Post by Isaac » Sat Oct 06, 2012 1:39 pm

crisman wrote:for i = champion:getOrdinal(), champion:getOrdinal() do
When I use this exact line in a function, I get yet another "attempt to index global ''champion', a nil value" error. (capital C or otherwise)
I get these enough to want to stop scripting permanently.

I came looking for instructions to access/use Champions:getOrdinal(), but even valid examples fail for me. :shock:

User avatar
crisman
Posts: 305
Joined: Sat Sep 22, 2012 9:23 pm
Location: Italy

Re: [Script] for timed effects with stats

Post by crisman » Sat Oct 06, 2012 3:54 pm

Isaac wrote:
crisman wrote:for i = champion:getOrdinal(), champion:getOrdinal() do
When I use this exact line in a function, I get yet another "attempt to index global ''champion', a nil value" error. (capital C or otherwise)
I get these enough to want to stop scripting permanently.

I came looking for instructions to access/use Champions:getOrdinal(), but even valid examples fail for me. :shock:
Don't give up :D
It's so fun for me scripting ^_^
Anyway, I think somehow you forgot to pass the champion value in a function.
If the game tells you a nil value, it means you are trying to do something that doesn't exist. In this case, champion is just a name of a variable that I arbitrarily gave. I could have called it oneOfMyGuy! like this:
in items.lua

potions...
onUseItem = function (self, champion)
--in this case 'champion' is demantory
potions.dexterity(champion)
end

in potions script

function dexterity(oneOfMyGuy)
--in this case I called the previous champion as oneOfMyGuy.
i = oneOfMyGuy:getOrdinal()
-- I realize now we can wrote this instead a for with no loop at all ^__^
-- all the code
end

for example.

May I look to your code? Maybe we can figure out what's going on!

User avatar
Isaac
Posts: 2995
Joined: Fri Mar 02, 2012 10:02 pm

Re: [Script] for timed effects with stats

Post by Isaac » Sun Oct 07, 2012 12:57 am

crisman wrote:May I look to your code? Maybe we can figure out what's going on!
What's going on is that I took the scripting reference literally...
Image

Is ''Champion' the given user assigned character name?!

What I am trying to do is set a condition for all of the PCs via a For Loop that calls each of them. This problem looks to be simper than at first thought... My real scripting problem is that I have an alcove that spawns daggers; I can create it so that pressing a button, causes a dagger appear; but when I use the exact same code in in my intended function [an not a simple test map], it throWS A Stack Overflow with just the edition of the same copy / pasted line from the test map... " dungeon_alcove_1:addItem(spawn("dagger", 1, 10, 10, 2))

Lilltiger
Posts: 95
Joined: Sun Sep 16, 2012 1:12 am

Re: [Script] for timed effects with stats

Post by Lilltiger » Sun Oct 07, 2012 1:07 am

stack overflow implies that you are doing something way to many times, like recursively calling a function forever like:

Code: Select all

function a()
   a()
end

User avatar
crisman
Posts: 305
Joined: Sat Sep 22, 2012 9:23 pm
Location: Italy

Re: [Script] for timed effects with stats

Post by crisman » Sun Oct 07, 2012 1:27 am

if you're trying to do incrment some stats for all the party, regardless who did what, then you should try:

function incrementDexterity()

for i = 1, 4 do
party:getChampion(i):modifyStatCapacity("dexterity", 5)
party:getChampion(i):modifyStat("dexterity", 5)
--do other stuff
end
end

Not sure if it can help you with your case, thought

I had a problem with a stack overflow, and in fact I created an infinite loop by mistake.
Last edited by crisman on Sun Oct 07, 2012 1:29 am, edited 1 time in total.

User avatar
Isaac
Posts: 2995
Joined: Fri Mar 02, 2012 10:02 pm

Re: [Script] for timed effects with stats

Post by Isaac » Sun Oct 07, 2012 1:28 am

Lilltiger wrote:stack overflow implies that you are doing something way to many times, like recursively calling a function forever like:

Code: Select all

function a()
   a()
end
Ah ha... I will look closely for this. Thank you very much for the insight.

Post Reply