Jump to content

Recommended Posts

I want make abillity for my character what can be activated with low HP

Current Code:

--For Rage Function
local function healthcontrol(inst, data)

    if inst.components.health.current <= 100 then
    inst.components.talker:Say("Test")
    inst.AddTag("rage")
    
end end

Anyone can help?

Edited by Aurorus
Link to comment
https://forums.kleientertainment.com/forums/topic/105227-low-health-abillty/
Share on other sites

inst:ListenForEvent("healthdelta", function(inst, data)
	-- You can now access both the old percentage (before the change) and the new percentage (after the change),
	-- using the data in the data-parameter, respectively data.oldpercent and data.newpercent
	if data.oldpercent > data.newpercent then
		-- The entity was hurt, not healed, since oldpercent was higher than newpercent...
		if data.newpercent < 0.9 then
			inst.components.talker:Say("I have less than 90% health. Only "..inst.components.health.currenthealth.." health left!")
		end
	end
end)

EDIT: Fixed code.

Edited by Ultroman
45 minutes ago, Ultroman said:

inst:ListenForEvent("healthdelta", function(inst, data)
	-- You can now access both the old percentage (before the change) and the new percentage (after the change),
	-- using the data in the data-parameter, respectively data.oldpercent and data.newpercent
	if data.oldpercent > data.newpercent then
		-- The entity was hurt, not healed, since oldpercent was higher than newpercent...
		if inst.components.health.newpercent < 0.9 then
			inst.components.talker:Say("I have less than 90% health. Only "..inst.components.health.currenthealth.." health left!")
		end
	end
end)

Thanks for help ^^

 

On 22.04.2019 at 7:30 PM, Ultroman said:

inst:ListenForEvent("healthdelta", function(inst, data)
	-- You can now access both the old percentage (before the change) and the new percentage (after the change),
	-- using the data in the data-parameter, respectively data.oldpercent and data.newpercent
	if data.oldpercent > data.newpercent then
		-- The entity was hurt, not healed, since oldpercent was higher than newpercent...
		if inst.components.health.newpercent < 0.9 then
			inst.components.talker:Say("I have less than 90% health. Only "..inst.components.health.currenthealth.." health left!")
		end
	end
end)

 

i have problem with this cuz if my character life is lower than 90% (i using this for test) i got error

9773ae79d32617e0e897738e844d3ceb.png

Yeah, there was a dumb mistake in the code.

inst:ListenForEvent("healthdelta", function(inst, data)
	-- You can now access both the old percentage (before the change) and the new percentage (after the change),
	-- using the data in the data-parameter, respectively data.oldpercent and data.newpercent
	if data.oldpercent > data.newpercent then
		-- The entity was hurt, not healed, since oldpercent was higher than newpercent...
		if data.newpercent < 0.9 then
			inst.components.talker:Say("I have less than 90% health. Only "..inst.components.health.currenthealth.." health left!")
		end
	end
end)

 

On 7.05.2019 at 6:30 PM, Ultroman said:

Yeah, there was a dumb mistake in the code.


inst:ListenForEvent("healthdelta", function(inst, data)
	-- You can now access both the old percentage (before the change) and the new percentage (after the change),
	-- using the data in the data-parameter, respectively data.oldpercent and data.newpercent
	if data.oldpercent > data.newpercent then
		-- The entity was hurt, not healed, since oldpercent was higher than newpercent...
		if data.newpercent < 0.9 then
			inst.components.talker:Say("I have less than 90% health. Only "..inst.components.health.currenthealth.." health left!")
		end
	end
end)

 

thanks it working but im still have problem with else

my code looks like

local function onload(inst, data)
    inst:ListenForEvent("healthdelta", function(inst, data)
    if data.oldpercent > data.newpercent then
    if data.newpercent < 0.5 then
    inst.Transform:SetScale(1.4, 1.4, 1.4)
    inst.components.combat.damagemultiplier = 1.5
    inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
    else
    inst.Transform:SetScale(0.8, 0.8, 0.8)
    inst.components.combat.damagemultiplier = 1
    inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
        end 
    end
end) end

 

 

But character dont change instantly

Edited by Aurorus

Of course not. You only set up a ListenForEvent, so nothing happens instantly. Something only happens when the event is called. You'd need to call a similar function immediately on load, if you want the character to start out in the correct size.

I'd suggest splitting up the code a little, and making sure the indentation is neat, so we can see what we're doing properly. Also, I'd suggest keeping a "bookkeeping" variable (inst.is_big) to tell you whether the character is currently big or small, to avoid making all these changes every single time the health is changed.

local function make_big()
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percentage)
	if health_percentage < 0.5 then
		make_big()
	else
		make_normal()
	end
end

local function onload(inst, data)
	-- Instantly do health and size check, and possible size change depending on current health.
	-- Call may need to be wrapped in DoTaskInTime as such, to wait for health component values to be loaded:
	-- DoTaskInTime(0, change_size_by_health(inst.components.health:GetPercent()))
	change_size_by_health(inst.components.health:GetPercent()
	
	-- Set up a call to check for a size change whenever health changes.
	inst:ListenForEvent("healthdelta", function(inst, data)
		change_size_by_health(data.newpercent)
	end)
end

 

Edited by Ultroman
11 hours ago, Ultroman said:

Of course not. You only set up a ListenForEvent, so nothing happens instantly. Something only happens when the event is called. You'd need to call a similar function immediately on load, if you want the character to start out in the correct size.

I'd suggest splitting up the code a little, and making sure the indentation is neat, so we can see what we're doing properly. Also, I'd suggest keeping a "bookkeeping" variable (inst.is_big) to tell you whether the character is currently big or small, to avoid making all these changes every single time the health is changed.


local function make_big()
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percentage)
	if health_percentage < 0.5 then
		make_big()
	else
		make_normal()
	end
end

local function onload(inst, data)
	-- Instantly do health and size check, and possible size change depending on current health.
	-- Call may need to be wrapped in DoTaskInTime as such, to wait for health component values to be loaded:
	-- DoTaskInTime(0, change_size_by_health(inst.components.health.GetPercent()))
	change_size_by_health(inst.components.health.GetPercent()
	
	-- Set up a call to check for a size change whenever health changes.
	inst:ListenForEvent("healthdelta", function(inst, data)
		change_size_by_health(data.newpercent)
	end)
end

 

It can works but when i choose character i get bug splat

16b6748a6a167dd885d5845332823362.png

6 minutes ago, Ultroman said:

Post me your whole LUA file.

local MakePlayerCharacter = require "prefabs/player_common"


local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}
local prefabs = {}

-- Custom starting inventory
local start_inv = {
}

-- When the character is revived from human
local function onbecamehuman(inst)
	-- Set speed when not a ghost (optional)
	inst.components.locomotor:SetExternalSpeedMultiplier(inst, "ryuty_speed_mod", 1.4)
end

local function onbecameghost(inst)
	-- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "ryuty_speed_mod")
end

-- When loading or spawning the character
local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end

--For Rage Function
local function make_big(inst)
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal(inst)
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

local function onload(inst, data)
	-- Instantly do health and size check, and possible size change depending on current health.
	-- Call may need to be wrapped in DoTaskInTime as such, to wait for health component values to be loaded:
	--DoTaskInTime(0, change_size_by_health(inst.components.health:GetPercent()))
	change_size_by_health(inst.components.health:GetPercent()
	
	-- Set up a call to check for a size change whenever health changes.
	)inst:ListenForEvent("healthdelta", function(inst, data)
		change_size_by_health(data.newpercent)
	end)
end

-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst) 
inst.Transform:SetScale(0.8, 0.8, 0.8)
	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "ryuty.tex" )
end

-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
	-- choose which sounds this character will play
	inst.soundsname = "willow"
	
	-- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
	
	-- Stats	
	inst.components.health:SetMaxHealth(125)
	inst.components.hunger:SetMax(175)
	inst.components.sanity:SetMax(175)
	inst.components.temperature.inherentinsulation =(45)
	inst.components.health.fire_damage_scale = 2
	
	-- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 1
	
	-- Hunger rate (optional)
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	
	--Heterochromia System
	    inst:ListenForEvent("locomote", function(inst)     
		if inst:HasTag("playerghost") then 
		return end             
		local dir = inst.Transform:GetRotation()   
		local camera_rot = TheCamera:GetHeadingTarget()        
		if camera_rot < 0 then       
		camera_rot = camera_rot + 360   
		end          
		if camera_rot == 0 or camera_rot == 45 then    
        if dir <= 0 then      
		inst.AnimState:SetBuild("ryuty_right")    
        else        
        inst.AnimState:SetBuild("ryuty_left")      
		end      
		elseif camera_rot == 90 or camera_rot == 135 then      
		if math.abs(dir) >= 90 then        
        inst.AnimState:SetBuild("ryuty_right")   
		else          
		inst.AnimState:SetBuild("ryuty_left")     
		end     
		elseif camera_rot == 180 or camera_rot == 225 then   
		if dir >= 0 then             
		inst.AnimState:SetBuild("ryuty_right")      
		else            
		inst.AnimState:SetBuild("ryuty_left")       
		end     
		else    
		if math.abs(dir) <= 90 then     
		inst.AnimState:SetBuild("ryuty_right")   
		else         
		inst.AnimState:SetBuild("ryuty_left")     
		end        end    end)
		

	
	inst.OnLoad = onload
    inst.OnNewSpawn = onload
	
	
end

return MakePlayerCharacter("ryuty", prefabs, assets, common_postinit, master_postinit, start_inv)

 

OK, your code says this:

Spoiler

local function make_big(inst)
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal(inst)
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

Since I last looked, you've added an "inst" parameter on your "make_normal" and "make_big" functions, but you never pass a value for that parameter when you call the functions. So naturally, "inst" is nil.

Try this:

Spoiler

local function make_big()
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

And if that doesn't work, then try this:

Spoiler

local function make_big()
	local inst = self.inst
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	local inst = self.inst
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

 

7 minutes ago, Ultroman said:

OK, your code says this:

  Hide contents


local function make_big(inst)
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal(inst)
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

Since I last looked, you've added an "inst" parameter on your "make_normal" and "make_big" functions, but you never pass a value for that parameter when you call the functions. So naturally, "inst" is nil.

Try this:

  Hide contents


local function make_big()
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

And if that doesn't work, then try this:

  Hide contents


local function make_big()
	local inst = self.inst
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal()
	local inst = self.inst
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(health_percent)
	if health_percent < 0.5 then
		make_big()
	else
		make_normal()
	end
end

 

First and second code making bug splat

402d9cb96a2488af0f0863f0f7506d01.png

 

OK, so for some reason the function has no idea what self or inst are, even though the component has them. We're gonna have to pass the instance to the functions.

This should work, then (notice I have also made changes to onload():

Spoiler

local function make_big(inst)
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal(inst)
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(inst)
	if inst.components.health:GetPercent() < 0.5 then
		make_big(inst)
	else
		make_normal(inst)
	end
end

local function onload(inst, data)
	-- Instantly do health and size check, and possible size change depending on current health.
	-- Call may need to be wrapped in DoTaskInTime as such, to wait for health component values to be loaded:
	--DoTaskInTime(0, change_size_by_health(inst.components.health:GetPercent()))
	change_size_by_health(inst)
	
	-- Set up a call to check for a size change whenever health changes.
	inst:ListenForEvent("healthdelta", function(inst, data)
		change_size_by_health(inst, data.newpercent)
	end)
end

 

 

13 hours ago, Ultroman said:

OK, so for some reason the function has no idea what self or inst are, even though the component has them. We're gonna have to pass the instance to the functions.

This should work, then (notice I have also made changes to onload():

  Hide contents


local function make_big(inst)
	if inst.is_big == nil or not inst.is_big then
		inst.Transform:SetScale(1.4, 1.4, 1.4)
		inst.components.combat.damagemultiplier = 1.5
		inst.components.hunger.hungerrate = 2 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = true
	end
end

local function make_normal(inst)
	if inst.is_big == nil or inst.is_big then
		inst.Transform:SetScale(0.8, 0.8, 0.8)
		inst.components.combat.damagemultiplier = 1
		inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
		inst.is_big = false
	end
end

local function change_size_by_health(inst)
	if inst.components.health:GetPercent() < 0.5 then
		make_big(inst)
	else
		make_normal(inst)
	end
end

local function onload(inst, data)
	-- Instantly do health and size check, and possible size change depending on current health.
	-- Call may need to be wrapped in DoTaskInTime as such, to wait for health component values to be loaded:
	--DoTaskInTime(0, change_size_by_health(inst.components.health:GetPercent()))
	change_size_by_health(inst)
	
	-- Set up a call to check for a size change whenever health changes.
	inst:ListenForEvent("healthdelta", function(inst, data)
		change_size_by_health(inst, data.newpercent)
	end)
end

 

It was give me bug splat but now i know what i did bad

I needed to give this code under SetMax health

Now its working. Thanks for help!

 

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...