Jump to content

Recommended Posts

Okay, so a friend was asking me to do the lua for his character and I can't seem to figure out why this function isn't working to lose 5 health every 12 seconds during day without a hat. Any help?

 

local function VampireEffect(inst)
        if TheWorld.state.phase == "day" and EQUIPSLOTS.HEAD == nil then
            inst:DoTaskInTime(12, inst.components.health:DoDelta(-5))
        else
            inst:DoTaskInTime(12, inst.components.health:DoDelta(0))
    end
end

and these in my master_postinit.

    inst:WatchWorldState("phase", VampireEffect)
    inst:ListenForEvent("equip", VampireEffect)
    inst:ListenForEvent("unequip", VampireEffect)

 

Edited by ELEMENTALCRAFTER009
Link to comment
https://forums.kleientertainment.com/forums/topic/64169-night-degeneration/
Share on other sites

Put this code to your master_postinit

inst.daytime_task = nil

inst:ListenForEvent("daytime", function() VampireEffect(inst) end , TheWorld)
inst:ListenForEvent("dusktime", function() RemoveVampireEffect(inst) end , TheWorld)

 

local function IsWearingHat(inst)
    for k, v in pairs(inst.components.inventory.equipslots) do
        if v:HasTag("hat") then return true end
    end
    return false
end

local function VampireEffect(inst)
    if inst.daytime_task == nil then
        inst.daytime_task = inst:DoPeriodicTask(12, function()
              if not IsWearingHat(inst) then
                  inst.components.health:DoDelta(-5)
              end
        end)
    end
end

local function RemoveVampireEffect(inst)
    if inst.daytime_task ~= nil then
        inst.daytime_task:Cancel()
        inst.daytime_task = nil
    end
end

 

55 minutes ago, zUsername said:

Put this code to your master_postinit


inst.daytime_task = nil

inst:ListenForEvent("daytime", function() VampireEffect(inst) end , TheWorld)
inst:ListenForEvent("dusktime", function() RemoveVampireEffect(inst) end , TheWorld)

 


local function IsWearingHat(inst)
    for k, v in pairs(inst.components.inventory.equipslots) do
        if v:HasTag("hat") then return true end
    end
    return false
end

local function VampireEffect(inst)
    if inst.daytime_task == nil then
        inst.daytime_task = inst:DoPeriodicTask(12, function()
              if not IsWearingHat(inst) then
                  inst.components.health:DoDelta(-5)
              end
        end)
    end
end

local function RemoveVampireEffect(inst)
    if inst.daytime_task ~= nil then
        inst.daytime_task:Cancel()
        inst.daytime_task = nil
    end
end

 

This doens't appear to work either.

Try adding some debug prints, to see which functions are being called.

Then try this:

inst:ListenForEvent("phasechanged", function(world, phase)
    if phase == "day" then
        VampireEffect(inst)
    elseif phase == "dusk" then
        RemoveVampireEffect(inst)
    end
end, TheWorld)

 

5 hours ago, Muche said:

Try adding some debug prints, to see which functions are being called.

Then try this:


inst:ListenForEvent("phasechanged", function(world, phase)
    if phase == "day" then
        VampireEffect(inst)
    elseif phase == "dusk" then
        RemoveVampireEffect(inst)
    end
end, TheWorld)

 

Thank you! This ended up fixing it.

15 hours ago, ELEMENTALCRAFTER009 said:

After the update, once again, this seems to not work.

This should work the way you want it to work. The VampireEffect function will be called when the world changes from Day to Dusk, Dusk to Night, and Night to Day. When it circles back around to Day it will begin it's effect; when it becomes dusk it will end it's effect.

character prefab file:

local function IsWearingTag(inst, tag)
    for k, v in pairs(inst.components.inventory.equipslots) do
        if v:HasTag(tag) then return true end
    end
    return false
end

local function RemoveVampireEffect(inst)
    if inst.vampire_task ~= nil then
        inst.vampire_task:Cancel()
        inst.vampire_task = nil
    end
end

local function VampireEffect(inst, phase)
    if inst.vampire_task == nil and phase == "day" then
        inst.vampie_task = inst:DoPeriodicTask(12, function()
              if not IsWearingTag(inst, "[INSERT TAG ON ITEM HERE]") then
                  inst.components.health:DoDelta(-5)
              end
        end)
	else
		RemoveVampireEffect(inst)
    end
end

master_postinit function:

inst:WatchWorldState("phase", VampireEffect)
VampireEffect( inst )

 

10 hours ago, Kzisor said:

This should work the way you want it to work. The VampireEffect function will be called when the world changes from Day to Dusk, Dusk to Night, and Night to Day. When it circles back around to Day it will begin it's effect; when it becomes dusk it will end it's effect.

character prefab file:


local function IsWearingTag(inst, tag)
    for k, v in pairs(inst.components.inventory.equipslots) do
        if v:HasTag(tag) then return true end
    end
    return false
end

local function RemoveVampireEffect(inst)
    if inst.vampire_task ~= nil then
        inst.vampire_task:Cancel()
        inst.vampire_task = nil
    end
end

local function VampireEffect(inst, phase)
    if inst.vampire_task == nil and phase == "day" then
        inst.vampie_task = inst:DoPeriodicTask(12, function()
              if not IsWearingTag(inst, "[INSERT TAG ON ITEM HERE]") then
                  inst.components.health:DoDelta(-5)
              end
        end)
	else
		RemoveVampireEffect(inst)
    end
end

master_postinit function:


inst:WatchWorldState("phase", VampireEffect)
VampireEffect( inst )

 

How would this look for the tag hat? (It's a bit unclear where specifically)

Edited by ELEMENTALCRAFTER009
55 minutes ago, SenL said:

Would we change IsWearingTag to IsWearingAHat if we don't care what tag does the hat have?

 

local hat = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD)

if hat ~= nil then return true else return false end

If you only care about a specific slot then you can reduce the code down to the following:

local function IsWearingInSlot( inst, slot )
	return inst.components.inventory:GetEquippedItem( slot ) ~= nil
end

When creating functions you want to create them in a fashion which they can be reused time and time again. The reason for functions like this is to reduce the amount of code created in the long term. So if in the future you want to check for BODY or HAND you can easily check the slot versus having to create additional functions to do each task.

30 minutes ago, SenL said:

Does the onphase get called only when changing from day->dusk->night?

What if the player wears hat as night->day then takes it off?

Shouldn't he have vampireeffect check every tick? (how do we do that)

 

The code I posted is to be placed in your master_postinit of the character prefab, not on an item. If you want to create an item which does that then you would need to focus on the 'onunequip' and 'onequip' functions of said item, while also using the code I posted.

Note: The onequip function of said item would simply call the onphase function with the parameter TheWorld.state.phase and the onunequip function would simply disable the vampiric effect.

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
×
  • Create New...