Jump to content

[help] How to add configurable cooldown to a spell


Recommended Posts

Hello, i was wondering if you could help me add a configurable (mod cofiguration options) cooldown to a spell that i got in a weapon, this is the code for the spell:

Spoiler

local function freezeSpell(inst, target, owner)
   local owner = inst.components.inventoryitem and inst.components.inventoryitem.owner    
        if owner and owner.components.sanity then
        owner.components.sanity:DoDelta(-2)
    end

    local attacker = inst.components.inventoryitem.owner
    if target.components.sleeper and target.components.sleeper:IsAsleep() then
        target.components.sleeper:WakeUp()
    end
    if target.components.burnable then
        if target.components.burnable:IsBurning() then
            target.components.burnable:Extinguish()
        end
    end
    if target.sg and target.components.combat then
        target.components.combat:SuggestTarget(attacker)
        if not target:HasTag("player") and not target.sg:HasStateTag("frozen") and target.sg.sg.states.hit then
            target.sg:GoToState("hit")
        end
    end
    if target.sg and not target.sg:HasStateTag("frozen") then
        target:PushEvent("attacked", {attacker = attacker, damage = 0})
    end
    if target.components.freezable then
        target.components.freezable:AddColdness(2)
        target.components.freezable:SpawnShatterFX()
    end
end

local function aoeSpell(inst, pos)
    local ents = TheSim:FindEntities(pos.x, pos.y, pos.z, 18, {"freezable"}, {"player"})
    for k, v in pairs(ents) do
        freezeSpell(inst, v)
    end
end

local function multiSpell(inst, target, pos)
    if not target then

        aoeSpell(inst, pos)
    end
end

I also got this for them to work:

Spoiler

    inst:AddComponent("spellcaster")
    inst.components.spellcaster.canuseontargets = true
    inst.components.spellcaster.canuseonpoint = true
    inst.components.spellcaster:SetSpellFn(multiSpell)

I would like that when you cast the spell you would get a message saying how much cooldown left you have, if any, otherwise casting the freeze spell.

Here i'm adding a zip example of this behavior by @DarkXero, he gave me this example a year ago (god bless you bro, you're the best). I tried everything to add this cooldown to my freeze spell but all i got was CTD.

Thanks a lot for your time, i sincerely appreciate your effort by comming here to help me, someday i'll be good in this and i'll help you all back somehow.

spellbooks.zip

Link to comment
Share on other sites

Guys, the zip added in my first message is a working mod with the feature i want to implement, is basically a cooldown that is configurable (you can choose how much time you want for cooldown) and also when you cast the spell if you still got cooldown enabled, the player says how much left until you can re-cast the spell.

Take a look:

local function spellcast(inst)
	if not inst.components.timer:TimerExists("spellbook_freeze") then
		local cooldown = TUNING.SPELLBOOK_FREEZE_COOLDOWN
		local owner = inst.components.inventoryitem.owner
		local pos = owner and owner:GetPosition() or inst:GetPosition()
		local targets = TheSim:FindEntities(pos.x, pos.y, pos.z, 35, {"freezable"}, {"player"})
		for i, v in ipairs(targets) do
			local resistance = v.components.freezable.resistance
			v.components.freezable:AddColdness(resistance)
			v.components.freezable:SpawnShatterFX()
		end
		inst:AddTag("cooldown")
		inst.components.timer:StartTimer("spellbook_freeze", cooldown)
	end
end

local function OnTimerDone(inst, data)
	local name = data and data.name
	if name == "spellbook_freeze" then
		inst:RemoveTag("cooldown")
	end
end

local function OnLoad(inst, data)
	if inst.components.timer:TimerExists("spellbook_freeze") then
		inst:AddTag("cooldown")
	end
end

That goes into prefab.lua, also in the same file, in the main fn () i saw this:

	inst:AddComponent("timer")
	inst:ListenForEvent("timerdone", OnTimerDone)
	inst.OnLoad = OnLoad

 

Now, this is not all, being configurable this expands to both modmain and modinfo. For modmain i found this to be related to the cooldown:

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.CASTSPELLBOOK, function(inst, act)
	local target = act.target or act.invobject
	if target and target:HasTag("cooldown") then
		if target.prefab == "spellbook_freeze" then
			if inst.components.talker then
				local timeleft = math.ceil(target.components.timer:GetTimeLeft("spellbook_freeze"))
				inst.components.talker:Say("Cooldown: "..tostring(timeleft).."s")
			end
		elseif target.prefab == "spellbook_heal" then
			if inst.components.talker then
				local timeleft = math.ceil(target.components.timer:GetTimeLeft("spellbook_heal"))
				inst.components.talker:Say("Cooldown: "..tostring(timeleft).."s")
			end
		end
		return
	end
	return "book"
end))

AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.CASTSPELLBOOK, function(inst, act)
	local target = act.target or act.invobject
	if target and target:HasTag("cooldown") then
		return
	end
	return "book"
end))

And also

TUNING.SPELLBOOK_FREEZE_COOLDOWN = GetModConfigData("spellbook_freeze_cooldown")

 

Finally, the modinfo i saw this related to the cooldown:

configuration_options =
{
	{
		name = "spellbook_freeze_cooldown",
		label = "Freeze Spell Cooldown",
		options = {
			{description = "5", data = 5},
			{description = "10", data = 10},
			{description = "15", data = 15},
		},
		default = 10,
	}
}

So i tryed taking this codes into my mentioned freezespell, and all i got was CTD.

Freeze spell:

Spoiler

local function freezeSpell(inst, target, owner)
   local owner = inst.components.inventoryitem and inst.components.inventoryitem.owner    
        if owner and owner.components.sanity then
        owner.components.sanity:DoDelta(-2)
    end

    local attacker = inst.components.inventoryitem.owner
    if target.components.sleeper and target.components.sleeper:IsAsleep() then
        target.components.sleeper:WakeUp()
    end
    if target.components.burnable then
        if target.components.burnable:IsBurning() then
            target.components.burnable:Extinguish()
        end
    end
    if target.sg and target.components.combat then
        target.components.combat:SuggestTarget(attacker)
        if not target:HasTag("player") and not target.sg:HasStateTag("frozen") and target.sg.sg.states.hit then
            target.sg:GoToState("hit")
        end
    end
    if target.sg and not target.sg:HasStateTag("frozen") then
        target:PushEvent("attacked", {attacker = attacker, damage = 0})
    end
    if target.components.freezable then
        target.components.freezable:AddColdness(2)
        target.components.freezable:SpawnShatterFX()
    end
end

local function aoeSpell(inst, pos)
    local ents = TheSim:FindEntities(pos.x, pos.y, pos.z, 18, {"freezable"}, {"player"})
    for k, v in pairs(ents) do
        freezeSpell(inst, v)
    end
end

local function multiSpell(inst, target, pos)
    if not target then

        aoeSpell(inst, pos)
    end
end

Any clues on how to make this codes work? Again, you can take a closer look by just downloading the zip file, but i think this are the codes that are related to the cooldown, what could i be doing wrong while implement them into my freeze spell? 

Thank you for your time       : )

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...