Jump to content

[HELP]Non-replacement solution for health_replica


Recommended Posts

Hi, I am new to LUA language. I am currently developing a health arrow widget, similar to the insanity badge widget, it show when health is regenerating. I'm attempting to get this widget working for multiplayer. Unfortunately my working solution requires replacing the health_replica component and I'm looking for tips for a solution that does not require replacing health_replica to reduce mod conflict. The goal is to obtain the client current health within 2 decimal values from the host.

 

Here are the new lines I inserted into health_replica.lua

local Health = Class(function(self, inst)    --original code    self._decimalhealth = net_ushortint(inst.GUID, "health._decimalhealth")    --original codeend)function Health:SetCurrent(current)    if self.classified ~= nil then		--Store 100 times the value, make sure its not out of bound as only short integer supported.		assert(current >= 0 and current <= 65535, "Player ".."_decimalhealth".." out of range: "..tostring(current))		self._decimalhealth:set(math.floor(current * 100))		self.classified:SetValue("currenthealth", current)		    endend--New method to return health value at 2 decimal place.function Health:GetDecimalCurrent()    if self.inst.components.health ~= nil then        return self.inst.components.health.currenthealth    elseif self.classified ~= nil then        return self._decimalhealth:value()/100    else        return 0    endend

With this I am able to call GetDecimalCurrent from health arrow widget

--Most of the code is absent for simplicity sake.local HealthArrow = Class(Widget, function(self,owner) -- owner parameter is not used here	--Get the  player	self.owner = ThePlayer        self.currentHealth = 0.0end)function HealthArrow:OnUpdate(dt)        --Without this it will crash, replica.health is not instanced before this is called.         if self.owner.replica.health then                -- This access the new data created from health_replica component                self.currentHealth = self.owner.replica.health:GetDecimalCurrent()        endend

The reason for this solution is so I can access the client current health that is accurate within 2 decimal places.

 

This line can get health of the client from the host but it only gives current health in whole numbers which I can't work off.

self.owner.replica.health.classified.currenthealth:value()
Link to comment
Share on other sites

@BrokenValkyrie, I don't think anyone but simplex really has the networking down yet, but you might want to look more at player_classified. When defining a netvar like that, there are things you need to set server-side and things that need to be set separately client-side.

 

Also, instead of attaching it to health_replica, I'd use something like this:

AddClassPostConstruct("components/health_replica", function(self)    self.GetCurrentDecimal = function(self)        if self.inst.components.health ~= nil then            return self.inst.components.health.currenthealth        elseif self.classified ~= nil then            return self.classified.currenthealth:value() + self.classified.currenthealthdecimal:value()/100        else            return 0        end    endend)AddPrefabPostInit("player_classified", function(inst)    inst.currenthealthdecimal = net_ushortint(inst.GUID, "health.currenthealthdecimal", "regendirty")    if GLOBAL.TheWorld.ismastersim then        inst:ListenForEvent("healthdelta", function(parent, data)            local health = parent.components.health.currenthealth            parent.components.health.currenthealthdecimal = 100*(health - math.floor(health))        end, inst._parent)    else        inst:ListenForEvent("regendirty", function(inst) --[[ something associated with updating the visuals for regen ]] end)    endend)

Sorry if it doesn't work, this was actually the first time I tried writing networking for a mod. o_o

Edited by rezecib
Link to comment
Share on other sites

Thank you rezecib for taking your time to answer my problem, your code helped me to develop the final solution.

 

I couldn't get the solution you have given me to work, but it helped me developed a solution that does not require replacing health_replica or any of its component. I like your solution to storing decimal places, I modified the solution to allow storage of more than 2 decimal places which I needed.

 

Here is the final solution, while it doesn't properly define server or client side function it works.

 

Mod Main:

AddClassPostConstruct("components/health_replica", function(self)    self.GetCurrentDecimal = function(self)        if self.inst.components.health ~= nil then            return self.inst.components.health.currenthealth        elseif self.classified ~= nil then            return self.classified.currenthealth:value() + (self.classified.currenthealthdecimal:value()/10000)        else            return 0        end    end    self.SetCurrentDecimal = function(self, health)	if self.classified ~= nil then		self.classified:SetValue("currenthealthdecimal", 10000 * (health - math.floor(health)) )	end    endend)AddPrefabPostInit("player_classified", function(inst)    inst.currenthealthdecimal = GLOBAL.net_ushortint(inst.GUID, "health.currenthealthdecimal")end)

To make this work I needed to update currenthealthdecimal with every game update. So  I used my regeneration component on update to do it.

local Regeneration = Class(function(self, inst)    self.inst = inst    self.health = self.inst.components.healthend)function Regeneration:OnUpdate(dt)	self.inst.replica.health:SetCurrentDecimal(self.health.currenthealth)end

While this is not the best solution it is able to retrieve cient health accurate to 4 decimal places from the host and not replace any function of the vanilla scripts. So I call this one a success.

Link to comment
Share on other sites

Sorry for the double post, I can not find a way to edit post.

 

I'm here to report some problem using this method, it really messes up the user hud if they don't have replica and classified component enabled. It will work fine as long as the client and host have these component in sync.

 

If you're wandering about the UI, the game giving lots of false positive, player on fire, starving, freezing, dead and ghost is present, when none of these condition are present. I can't locate the cause but it appears it is setting off all the is flag in player_classified define health variables.

 

If you change the network variable from

inst.decimalhealth = GLOBAL.net_ushortint(inst.GUID,"health.decimalhealth")

to this

inst.decimalhealth = GLOBAL.net_ushortint(inst.GUID,"decimalhealth")

The entire screen goes purple and UI freaks out, all avaliable recipe is avaliable and not avaliable .

 

Overall don't use this method, unless you want to see the game freak out.

 

Anyway Peter A hunt mod avaliable and it has proper handling of the network code. That mod will be a much better reference.

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