Jump to content

Recommended Posts

Hey, I've recently decided to take my chances with modding for DST. Starting on the simple side, I made some changes to wolfgang, including the infamous flat stats per form, and also allowing him to work (chop/mine/dig/hammer) better when mighty, cause I always found it odd that wasn't the case to begin with. Works like a charm, clients don't require it, all's well.
 
However, the next step was to play around with some (very experimental) changes to wigfrid, and that's slowed me down to a crawl for a couple weeks already. I made so battleborn goes up to 100, does not consume upon activation, and instead only goes down when getting hit or not fighting for too long. It works okay (it incentivizes proper dodging instead of facetanking damage which me and my dst party feel best suits her), but it makes little sense the player can't see his current 'battleborniness'.
 
Long story short, I can't get a badge to show up only to a specific character, and if I can, it only works for the host.

function AddBattleborniness(status)		--if status.owner.prefab == "wathgrithr" then -- didnt work, removed for now			local BattlebornBadge =  _G.require "widgets/beaverbadge"		status.battleborn = status:AddChild( BattlebornBadge( status.owner ) )		status.battleborn:SetPosition(-80,-40,0)		status.battleborn.arrowdir = nil --for decay arrow	--end	endAddClassPostConstruct( "widgets/statusdisplays", AddBattleborniness )

With the above as is, clients can see the badge, but it'll show up to other characters, which is not desired.

 

 

 

I also can't seem to access the battleborn stacks of a client, even though I know they have the info somewhere, otherwise they couldn't 'go battleborn' (I made a cheesy glow around wigfrid when she has max stacks).

function updateBattlebornBadge(inst)	if inst.HUD then				local this = inst.HUD.controls.status					if this.isghostmode then			this.battleborn:Hide()		else			this.battleborn:Show()			this.battleborn:SetPercent(inst.battleborn/BATTLEBORN_TRIGGER_THRESHOLD or 42)--42 for debugging purposes                end        endend

This is called whenever battleborn suffers a delta. It also works for the host and for the host only.

 

 

 

One last bit of code that could be mandatory:

if _G.TheNet and _G.TheNet:GetIsServer() thenlocal function AddBattlebornParaphernalia(inst)	inst:ListenForEvent("killed", bb_onkilled)	inst:ListenForEvent("onattackother", bb_onattack)	inst:ListenForEvent("attacked", bb_onattacked)	inst:DoPeriodicTask(.5, decay_battleborn)	inst:DoTaskInTime(.1, update_battleborn)end		AddPrefabPostInit("wathgrithr", AddBattlebornParaphernalia);end

This is what adds the events wigfrid should listen to. The usual onattack/killed/attacked have been removed, replaced by these custom versions, and I don't think there's any problem within them. They are however the ones responsible of calling the updatebattleborn function.

 

 

Finally: should this require all_clients_require_mod? I do realize it will, once I swap the beaver badge for a custom one, but I'm curious if this should be the case for now as well.

 

Thanks for reading!

I also can't seem to access the battleborn stacks of a client, even though I know they have the info somewhere, otherwise they couldn't 'go battleborn' (I made a cheesy glow around wigfrid when she has max stacks).

 

Clients don't have access to the battleborn or the battleborn_time attribute.

-- modmainlocal require = GLOBAL.requirelocal BeaverBadge = require "widgets/beaverbadge"AddClassPostConstruct("widgets/statusdisplays", function(self)	if self.owner:HasTag("battleborn") then		self.battleborness = self:AddChild(BeaverBadge(self.owner))		self.battleborness:SetPosition(-80, -40, 0)		self.battleborness:SetPercent(0, 100)		self.owner:ListenForEvent("battleborndirty", function(inst)			self.battleborness:SetPercent(self.owner.net_bb:value(), 100)		end)	endend)AddPrefabPostInit("wathgrithr", function(inst)	inst:AddTag("battleborn")	inst.net_bb = GLOBAL.net_byte(inst.GUID, "player.battleborn", "battleborndirty")	inst.net_bb:set_local(0) -- server and client set up their initial valueend)

And where ever you have the update battleborn value thing

function updateBattlebornBadge(inst)	inst.net_bb:set(inst.battleborn) -- server updates bb value and propagates to clientsend

I knew you'd come to the rescue, DarkXero :)

 

I'm not able to thoroughly test it right now and see if I broke your solution somehow, but I'll do it asap. Plus, I think I see where my mistakes were (besides obviously not even using a netvar, another problem was that I had once tried the tag approach, but had it added only on hosts through that GetIsServer() function).

 

If you have a moment:

 

-can you tell me if I should need all_clients_require_mod in this case and why?

 

-I see in many of your posts of similar problems, _G.TheWorld.ismastersim is used instead of _G.TheNet:GetIsServer() when needed. Are they not interchangeable? Does it not work on modmain.lua?

(_G = GLOBAL, tried both with and without it)

 

 

Thanks a lot!

-can you tell me if I should need all_clients_require_mod in this case and why?

 

Technically speaking, I think a client could play without the mod, since that mod not existing client side would result in the client not having the battleborn HUD element. You are removing the server/client interaction as well as the client results, so, like nothing happens.

 

Different stuff like recipes and component actions must be the same in both ends, or you are going to get a nil on the server or on the client, sooner or later. Because a client will make a request to the server like "I want this recipe" or "I want to do this action", and the server may get it wrong if action number 1 is actually action number 2.

 

However, practically speaking, yes, it is a client required mod. The PostConstruct function doesn't propagate through the net. If a client doesn't run the stuff to get the battleborn widget, then he won't get it. And you want the clients to have it.

 

-I see in many of your posts of similar problems, _G.TheWorld.ismastersim is used instead of _G.TheNet:GetIsServer() when needed. Are they not interchangeable? Does it not work on modmain.lua?

 

They are interchangeable after the server is running.

 

TheWorld is nil, on the main menu.

TheWorld is nil, on the generating world screen.

After the server starts, TheWorld will reference the world entity prefab.

 

Using _G.TheWorld.ismastersim outside all functions in modmain.lua:

Client only mods would crash the game on startup.

Server only mods get loaded during after the generate world screen, so it would crash there.

 

 

TheNet is not nil, on the main menu.

TheNet is not nil, on the generating world screen.

After the server starts, TheNet will reference network related userdata.

 

Using _G.TheNet:GetIsServer() outside all functions in modmain.lua:

For client only mods, false would be returned on startup.

Server only mods get loaded during after the generate world screen, here it would return true.

 

 

Why would you use these outside of the server running is beyond me.

Also, in the world prefab:

inst.ismastersim = TheNet:GetIsMasterSimulation()

I don't know the difference between GetIsMasterSimulation and GetIsServer, tho.

But as of now, they should be the same.

Maybe Klei intended to have a master simulation splitting resources among different servers for performance? :-)

 

(_G = GLOBAL, tried both with and without it)

 

Yeah, you need the GLOBAL.

Modmain has the mod environment, with the functions you see in modutil.lua for use (e.g. env.AddRecipe).

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