Jump to content

Recommended Posts

Hello modders!

I've been digging around to understand how to add a custom badge to a character. I managed to make it appear on the screen using a code I put in the modmain. I have the widget under scripts/widgets/remorsewidget.lua which I created by copying some of the sanity badge. And put a OnEaten function my character prefab. I come accross many problems tho.

First,  I can't understand how to put number in the badge. (***I want the number to raise by 10 after eating meat***)

Second,  how do we change the animation of the badge according to the number above?

Third, Haven't been able to reach that point but, I wonder how to launch a sanity delta when the number reaches 100%. I tried something, can someone tell me if it will work?

Here what I have so far; there might be some mistakes, still trying to figure things out. Dont know exactly where to put the codes anymore :

Modmain :

Spoiler

Assets = { Asset( "ANIM", "anim/remorsewidget.zip" ),

[...]

local function MakeRemorseWidget( self, custom_widget, owner_tag, bank, build, background_build, show_progress, show_remaining, position_normal, position_modded )

	if self.owner:HasTag(owner_tag) then
		local remorsewidget = require "widgets/remorsewidget"
		self[custom_widget] = self:AddChild(remorsewidget(self.owner, bank, build, background_build, show_progress, show_remaining))
		-- Compatibility with Always On Status mod
		if GLOBAL.KnownModIndex:IsModEnabled("workshop-376333686") then			
			self[custom_widget]:SetPosition(position_modded)
		else	
	    	self[custom_widget]:SetPosition(position_normal)
		    self.brain:SetPosition(-40,-55,0) --move sanity badge
		   	self.moisturemeter:SetPosition(0,-120,0) --move moisturemeter badge
		end
		
		local _SetGhostMode = self.SetGhostMode

		function self:SetGhostMode( ghostmode )
			_SetGhostMode( self, ghostmode )
			if ghostmode then
				self[custom_widget]:Hide()
				OnSetGhostMode( self )
			end
		end

	end
	
	return self

end

local function StatusDisplaysPostInit( self )
	MakeRemorseWidget(self,"remorsewidget", "korrigan", "anim", "remorsewidget", "remorsewidget", true, false, {x=40,y=-55,z=0}, {x=-62,y=-52,z=0})
end

AddClassPostConstruct("widgets/statusdisplays", StatusDisplaysPostInit)

 

Character :

Spoiler

--Headlines
local Badge = require "widgets/badge"
local UIAnim = require "widgets/uianim"
local Text = require "widgets/text"
local Widget = require "widgets/widget"
local remorseMax = 100
local remorseMin = 0
local remorseCurrent = remorseMin

[...]

Asset( "ANIM", "anim/remorsewidget.zip" ),

[...[

local remorsewidget = Class(Badge, function(self, owner)
	Badge._ctor(self, "remorsewidget", owner)
end)

local function oneat(inst, food) --Still Don't Know if I Have To Put Something In The Character Prefab
	if food.components.edible and food.components.edible.foodtype == "MEAT"  and inst:HasTag("korrigan") then
		
		--inst.remorsewidget.setpercent =  +10 --Stupid exemple of what I want
		inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")--Testing out
		inst.HUD.controls.status.remorsewidget:PulseRed()--Testing out

		end
		
		if remorsewidget.percent == remorseMax then
		inst.components.sanity:DoDelta(-100)
		end
	end

 

Widget : (from the sanity badge)

Spoiler

local Badge = require "widgets/badge"
local UIAnim = require "widgets/uianim"
local Text = require "widgets/text"
local Widget = require "widgets/widget"

local function OnGhostDeactivated(inst)
    if inst.AnimState:IsCurrentAnimation("anim") then
        inst.widget:Hide()
    end
end

local remorsewidget = Class(Badge, function(self, owner)
    Badge._ctor(self, "remorsewidget", owner)

    self.topperanim = self.underNumber:AddChild(UIAnim())
    self.topperanim:GetAnimState():SetBank("remorsewidget")
    self.topperanim:GetAnimState():SetBuild("remorsewidget")
    self.topperanim:GetAnimState():PlayAnimation("anim")
    self.topperanim:SetClickable(false)

    self.sanityarrow = self.underNumber:AddChild(UIAnim())
    self.sanityarrow:GetAnimState():SetBank("remorsewidget")
    self.sanityarrow:GetAnimState():SetBuild("remorsewidget")
    self.sanityarrow:GetAnimState():PlayAnimation("anim")
    self.sanityarrow:SetClickable(false)

    --Hide the original frame since it is now overlapped by the topperanim
    self.anim:GetAnimState():Hide("frame")

    self.ghostanim = self.underNumber:AddChild(UIAnim())
    self.ghostanim:GetAnimState():SetBank("remorsewidget")
    self.ghostanim:GetAnimState():SetBuild("remorsewidget")
    self.ghostanim:GetAnimState():PlayAnimation("anim")
    self.ghostanim:Hide()
    self.ghostanim:SetClickable(false)
    self.ghostanim.inst:ListenForEvent("animover", OnGhostDeactivated)

    self.val = 0
    self.max = 100
    self.penaltypercent = 0
    self.ghost = false

    --self:StartUpdating() --GOT A NIL VALUE HERE!!! 
end)

function remorsewidget:SetPercent(val, max, penaltypercent)
    self.val = val
    self.max = max
    Badge.SetPercent(self, self.val, self.max)

    self.penaltypercent = penaltypercent or 0
    self.topperanim:GetAnimState():SetPercent("anim", self.penaltypercent)
end

return remorsewidget

 

I hope my questions are clear enough. The badge itself should be simple but I don't know out to solve that.

Thanx for helping :) !

D4rkh0bb1T

Edited by D4rkh0bb1T
Link to comment
https://forums.kleientertainment.com/forums/topic/66190-how-to-add-custom-badge/
Share on other sites

You're probably getting a nil value at StartUpdating because you dont have the OnUpdate function, which is suppose to call the "SetPercent" function which is probably why the badge is not changing its animation.

as for this:

--inst.remorsewidget.setpercent =  +10

if would probably look more like

--inst.remorsewidget.setpercent = inst.remorsewidget.setpercent + 10

but do note that you're using "setpercent" at 1 spot, and "percent" at another

Edited by Aquaterion

So I have to add a OnUpdate function in the widget script with the +10?

function remorsewidget:OnUpdate(dt)
inst.remorsewidget.setpercent = inst.remorsewidget.setpercent + 10

Edit : What about the oneaten function in the character prefab? Do I need to put it in the widget instead?

Or listen for oneaten function in the OnUpdate function?

Edited by D4rkh0bb1T
---- CHARACTER ----
inst.remorseMax = 100
inst.remorseMin = 0
inst.remorseCurrent = remorseMin
-- THE ABOVE SHOULD PROBABLY BE IN MASTER_POSTINIT

[...]

Asset( "ANIM", "anim/remorsewidget.zip" ),

[...]

local remorsewidget = Class(Badge, function(self, owner)
	Badge._ctor(self, "remorsewidget", owner)
end)

local function oneat(inst, food) --Still Don't Know if I Have To Put Something In The Character Prefab
	if food.components.edible and food.components.edible.foodtype == "MEAT"  and inst:HasTag("korrigan") then
		
		inst.remorseCurrent = inst.remorseCurrent + 10 --Stupid exemple of what I want
		inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")--Testing out
		inst.HUD.controls.status.remorsewidget:PulseRed()--Testing out

		end
		
		if inst.remorseCurrent == inst.remorseMax then
		inst.components.sanity:DoDelta(-100)
		end
		inst:PushEvent("remorsedelta", { newpercent = inst.remorseCurrent / inst.remorseMax, currentremorse = inst.remorseCurrent, maxremorse = inst.remorseMax })
	end
---- MODMAIN ----
local function remorsedelta( data )
			
			self[custom_widget]:SetPercent( data.newpercent, data.currentremorse, data.maxremorse )

		end

		local function OnSetPlayerMode( self )
			if self["onremorsedelta"] == nil then
				self["onremorsedelta"] = function( owner, data ) remorsedelta( data ) end
				self.inst:ListenForEvent( "remorsedelta", self["onremorsedelta"], self.owner )
					remorsedelta( 
					  { newpercent = self.owner.remorseCurrent / self.owner.remorseMax),
						currentremorse = self.owner.remorseCurrent,
						maxremorse = self.owner.remorseMax })
			end
		end
---- WIDGET ----

function remorsewidget:SetPercent(pct, val, max)
    self.val = val or 0
    self.max = max or 100
    self.percent = pct or (self.val / self.max) or 0
    Badge.SetPercent(self, self.percent, self.max)

    self.topperanim:GetAnimState():SetPercent("anim", 1 - self.percent)
end

function remorsewidget:OnUpdate(dt)
	self:SetPercent(
		self.owner.remorseCurrent / self.owner.remorseMax,
		self.owner.remorseCurrent,
		self.owner.remorseMax)
end

I'm not sure if this works as I haven't tried it but hopefully it helps. For the Character 1 you have to replace the code, for modmain and widget you have to add the code.

Edited by Aquaterion

BIG Thanx Aquaterion!

5 hours ago, Aquaterion said:

I'm not sure if this works as I haven't tried it but hopefully it helps. For the Character 1 you have to replace the code, for modmain and widget you have to add the code.

You managed to make the mechanic to work by using your nice codes above. I wouldnt thought putting remorse value in the character master_postinit could work. The pushevent is just too good, I was looking for it but wasn't able to write it properly. I can say the same thing for the SetPercent function.

So the SetPercent part of the code is working. When remorse is at 100, it does sanity delta -100, simple and effective. But the anim does not change according to the percent data and I can't see numbers in the widget. I continue to search in files how to do that. I believe I miss few lines about SetString or something like that.

D4rkh0bb1T

Should probably thank Krizor as well, as I learned those from him, as for the number, try adding this to the main widget part

    self.num = self:AddChild(Text(BODYTEXTFONT, 33))
    self.num:SetHAlign(ANCHOR_MIDDLE)
    self.num:SetPosition(3.5, 1, 0)
    self.num:Hide()

and then add this in SetPercent as the last line:

self.num:SetString(tostring(math.ceil(self.percent * self.max)))

You should probably add some prints to see whats working or not in the setpercent part, such as print(self.val)

Edited by Aquaterion

Yeah, good idea! Anyway thanx to ALL modders on the forum who always help. thank for your time man.

The number is showing if on Show. When Hide, nothing appears in the widget. I found how to get the anim ! That was really tricky to create that widget, been reading and reading all the day and then things became confused.

D4rkh0bb1T

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