Jump to content

Deciduoustreeupdater is a pain.


Recommended Posts

So, i'm trying to make sense of Deciduoustreeupdater.lua, and it's....well.....it makes a lot less sense than a lot of things in the coding for this game do.

 

One thing that's strange is that it's using a more direct, pulse-based method of spawning birchdrakes instead of just using Childspawner.

 

I'm trying to make it so that the birchguard's ability to spawn in birchnutters is reduced significantly. Specifically, to make it so that they can't constantly respawn the buggers. One wave, and that's it. Unfortunately, the convoluded if chain that controls that is nothing short of a headache.

if self.monster == true then		-- We want to spawn drakes at some interval    	if self.time_to_passive_drake <= 0 then    		if self.num_passive_drakes == 0 then    			self.num_passive_drakes = 1    			if math.random() < .33 then self.num_passive_drakes = 2 end    			self.passive_drakes_spawned = 0    		elseif self.passive_drakes_spawned < self.num_passive_drakes then        		local passdrake = SpawnPrefab("birchnutdrake")    			local passdrakeangle = math.random(360)    			local passoffset = FindWalkableOffset(self.inst:GetPosition(), passdrakeangle*DEGREES, math.random(2,TUNING.DECID_MONSTER_TARGET_DIST*1.5), 30, false, false)    			local xp,yp,zp = self.inst.Transform:GetWorldPosition()    			passdrake.Transform:SetPosition(xp + passoffset.x, yp + passoffset.y, zp + passoffset.z)    			passdrake.range = TUNING.DECID_MONSTER_TARGET_DIST * 4    			passdrake:DoTaskInTime(0, function(passdrake)    				if passdrake.components.combat then    					local targ = FindEntity(passdrake, TUNING.DECID_MONSTER_TARGET_DIST * 4, function(guy)				            return passdrake.components.combat and passdrake.components.combat:CanTarget(guy) and 				            	not guy:HasTag("flying") and (not guy.sg or (guy.sg and not guy.sg:HasStateTag("flying"))) and				            	not guy:HasTag("birchnutdrake") and not guy:HasTag("wall")				        end)        				passdrake.components.combat:SuggestTarget(targ)    				end    			end)    			self.passive_drakes_spawned = self.passive_drakes_spawned + 1    		else    			self.num_passive_drakes = 0    			self.time_to_passive_drake = GetRandomWithVariance(TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL,TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE)    		end    	else    		self.time_to_passive_drake = self.time_to_passive_drake - dt    	end		-- We only want to do the thinking for roots and proximity-drakes so often		if self.monsterTime > 0 then			self.monsterTime = self.monsterTime - dt		else	        self.monster_target = nil	        local targdist = TUNING.DECID_MONSTER_TARGET_DIST	        -- Look for nearby targets (anything not flying, a wall or a drake)	        self.monster_target = FindEntity(self.inst, targdist * 1.5, function(guy)	            return self.inst.components.combat and self.inst.components.combat:CanTarget(guy) and 	            	not guy:HasTag("flying") and (not guy.sg or (guy.sg and not guy.sg:HasStateTag("flying"))) and	            	not guy:HasTag("birchnutdrake") and not guy:HasTag("wall")	        end)	        if self.monster_target ~= nil and self.last_monster_target ~= nil and (GetTime() - self.last_attack_time) > TUNING.DECID_MONSTER_ATTACK_PERIOD then	        	-- Spawn a root spike and give it a target	            self.last_attack_time = GetTime()            	self.root = SpawnPrefab("deciduous_root")	            local rootpos = self.monster_target:GetPosition()	            local angle = self.inst:GetAngleToPoint(rootpos)*DEGREES	            if distsq(self.inst:GetPosition(), self.monster_target:GetPosition()) > (targdist*targdist) then	                rootpos = self.inst:GetPosition() + Vector3(math.cos(angle) * targdist, 0, -math.sin(angle) * targdist)	            end	            local offset = Vector3(math.cos(angle) * 1.75, 0, -math.sin(angle) * 1.75)	            local x,y,z = self.inst.Transform:GetWorldPosition()	            self.root.Transform:SetPosition(x + offset.x, y + offset.y, z + offset.z)	            self.root:PushEvent("givetarget", {target=self.monster_target, targetpos=rootpos, targetangle=angle, owner=self.inst})	            -- If we haven't spawned drakes yet and the player is close enough, spawn drakes	            if not self.spawneddrakes and distsq(self.inst:GetPosition(), self.monster_target:GetPosition()) <= ((targdist*.5)*(targdist*.5)) then	            	self.spawneddrakes = true	            	self.time_to_passive_drake = GetRandomWithVariance(TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL,TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE)	            	self.numdrakes = math.random(TUNING.MIN_TREE_DRAKES, TUNING.MAX_TREE_DRAKES)	            	self.sectorsize = 360 / self.numdrakes	            	self.drakespawntask = self.inst:DoPeriodicTask(6*FRAMES, function(inst)	            		local dtu = inst.components.deciduoustreeupdater	            		if dtu and dtu.numdrakes <= 0 then	            			dtu.drakespawntask:Cancel()	            			dtu.drakespawntask = nil	            		elseif dtu then	            			local drake = SpawnPrefab("birchnutdrake")	            			local minang = (dtu.sectorsize * (dtu.numdrakes - 1)) >= 0 and (dtu.sectorsize * (dtu.numdrakes - 1)) or 0                			local maxang = (dtu.sectorsize * dtu.numdrakes) <= 360 and (dtu.sectorsize * dtu.numdrakes) or 360			                local drakeangle = math.random(minang, maxang)	            			local offset = FindWalkableOffset(inst:GetPosition(), drakeangle*DEGREES, math.random(2,TUNING.DECID_MONSTER_TARGET_DIST), 30, false, false)	            			local x,y,z = inst.Transform:GetWorldPosition()	            			drake.Transform:SetPosition(x + offset.x, y + offset.y, z + offset.z)	            			drake.target = dtu.monster_target and dtu.monster_target or dtu.last_monster_target	            			drake:DoTaskInTime(0, function(drake)	            				if drake.components.combat then		            				drake.components.combat:SuggestTarget(drake.target and drake.target or GetPlayer())	            				end	            			end)	            			dtu.numdrakes = dtu.numdrakes - 1	            		end	            	end)	            end	        end

I could use a bit of help on this one.

Link to comment
Share on other sites

So, i'm trying to make sense of Deciduoustreeupdater.lua, and it's....well.....it makes a lot less sense than a lot of things in the coding for this game do.

 

One thing that's strange is that it's using a more direct, pulse-based method of spawning birchdrakes instead of just using Childspawner.

 

I'm trying to make it so that the birchguard's ability to spawn in birchnutters is reduced significantly. Specifically, to make it so that they can't constantly respawn the buggers. One wave, and that's it. Unfortunately, the convoluded if chain that controls that is nothing short of a headache.

if self.monster == true then		-- We want to spawn drakes at some interval    	if self.time_to_passive_drake <= 0 then    		if self.num_passive_drakes == 0 then    			self.num_passive_drakes = 1    			if math.random() < .33 then self.num_passive_drakes = 2 end    			self.passive_drakes_spawned = 0    		elseif self.passive_drakes_spawned < self.num_passive_drakes then        		local passdrake = SpawnPrefab("birchnutdrake")    			local passdrakeangle = math.random(360)    			local passoffset = FindWalkableOffset(self.inst:GetPosition(), passdrakeangle*DEGREES, math.random(2,TUNING.DECID_MONSTER_TARGET_DIST*1.5), 30, false, false)    			local xp,yp,zp = self.inst.Transform:GetWorldPosition()    			passdrake.Transform:SetPosition(xp + passoffset.x, yp + passoffset.y, zp + passoffset.z)    			passdrake.range = TUNING.DECID_MONSTER_TARGET_DIST * 4    			passdrake:DoTaskInTime(0, function(passdrake)    				if passdrake.components.combat then    					local targ = FindEntity(passdrake, TUNING.DECID_MONSTER_TARGET_DIST * 4, function(guy)				            return passdrake.components.combat and passdrake.components.combat:CanTarget(guy) and 				            	not guy:HasTag("flying") and (not guy.sg or (guy.sg and not guy.sg:HasStateTag("flying"))) and				            	not guy:HasTag("birchnutdrake") and not guy:HasTag("wall")				        end)        				passdrake.components.combat:SuggestTarget(targ)    				end    			end)    			self.passive_drakes_spawned = self.passive_drakes_spawned + 1    		else    			self.num_passive_drakes = 0    			self.time_to_passive_drake = GetRandomWithVariance(TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL,TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE)    		end    	else    		self.time_to_passive_drake = self.time_to_passive_drake - dt    	end		-- We only want to do the thinking for roots and proximity-drakes so often		if self.monsterTime > 0 then			self.monsterTime = self.monsterTime - dt		else	        self.monster_target = nil	        local targdist = TUNING.DECID_MONSTER_TARGET_DIST	        -- Look for nearby targets (anything not flying, a wall or a drake)	        self.monster_target = FindEntity(self.inst, targdist * 1.5, function(guy)	            return self.inst.components.combat and self.inst.components.combat:CanTarget(guy) and 	            	not guy:HasTag("flying") and (not guy.sg or (guy.sg and not guy.sg:HasStateTag("flying"))) and	            	not guy:HasTag("birchnutdrake") and not guy:HasTag("wall")	        end)	        if self.monster_target ~= nil and self.last_monster_target ~= nil and (GetTime() - self.last_attack_time) > TUNING.DECID_MONSTER_ATTACK_PERIOD then	        	-- Spawn a root spike and give it a target	            self.last_attack_time = GetTime()            	self.root = SpawnPrefab("deciduous_root")	            local rootpos = self.monster_target:GetPosition()	            local angle = self.inst:GetAngleToPoint(rootpos)*DEGREES	            if distsq(self.inst:GetPosition(), self.monster_target:GetPosition()) > (targdist*targdist) then	                rootpos = self.inst:GetPosition() + Vector3(math.cos(angle) * targdist, 0, -math.sin(angle) * targdist)	            end	            local offset = Vector3(math.cos(angle) * 1.75, 0, -math.sin(angle) * 1.75)	            local x,y,z = self.inst.Transform:GetWorldPosition()	            self.root.Transform:SetPosition(x + offset.x, y + offset.y, z + offset.z)	            self.root:PushEvent("givetarget", {target=self.monster_target, targetpos=rootpos, targetangle=angle, owner=self.inst})	            -- If we haven't spawned drakes yet and the player is close enough, spawn drakes	            if not self.spawneddrakes and distsq(self.inst:GetPosition(), self.monster_target:GetPosition()) <= ((targdist*.5)*(targdist*.5)) then	            	self.spawneddrakes = true	            	self.time_to_passive_drake = GetRandomWithVariance(TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL,TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE)	            	self.numdrakes = math.random(TUNING.MIN_TREE_DRAKES, TUNING.MAX_TREE_DRAKES)	            	self.sectorsize = 360 / self.numdrakes	            	self.drakespawntask = self.inst:DoPeriodicTask(6*FRAMES, function(inst)	            		local dtu = inst.components.deciduoustreeupdater	            		if dtu and dtu.numdrakes <= 0 then	            			dtu.drakespawntask:Cancel()	            			dtu.drakespawntask = nil	            		elseif dtu then	            			local drake = SpawnPrefab("birchnutdrake")	            			local minang = (dtu.sectorsize * (dtu.numdrakes - 1)) >= 0 and (dtu.sectorsize * (dtu.numdrakes - 1)) or 0                			local maxang = (dtu.sectorsize * dtu.numdrakes) <= 360 and (dtu.sectorsize * dtu.numdrakes) or 360			                local drakeangle = math.random(minang, maxang)	            			local offset = FindWalkableOffset(inst:GetPosition(), drakeangle*DEGREES, math.random(2,TUNING.DECID_MONSTER_TARGET_DIST), 30, false, false)	            			local x,y,z = inst.Transform:GetWorldPosition()	            			drake.Transform:SetPosition(x + offset.x, y + offset.y, z + offset.z)	            			drake.target = dtu.monster_target and dtu.monster_target or dtu.last_monster_target	            			drake:DoTaskInTime(0, function(drake)	            				if drake.components.combat then		            				drake.components.combat:SuggestTarget(drake.target and drake.target or GetPlayer())	            				end	            			end)	            			dtu.numdrakes = dtu.numdrakes - 1	            		end	            	end)	            end	        end

I could use a bit of help on this one.

 

These are the lines relevant to you:

if math.random() < .33 then self.num_passive_drakes = 2 end

and

self.time_to_passive_drake = GetRandomWithVariance(TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL,TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE)

TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL and TUNING.PASSIVE_DRAKE_SPAWN_INTERVAL_VARIANCE are numbers you may want to change. The first is the interval, and the second one restricts how much the interval can vary by each time.

Link to comment
Share on other sites

  • Developer

@Silentdarkness1 Yeahhh... this is a good lesson in why it's not always better to take an existing file and modify it. A lot of the reason that my code for the deciduous trees and the monster version of the deciduous trees is so horribly, embarrassingly messy is that I took the evergreens file and converted it (and then layered additional functionality onto it as the spec for what the deciduous trees would do grew).  I'm spending a bit of time on mod support now and saw this thread--I've changed the number of passive drakes (i.e. interval spawns) to be a tuning value as well to make it easier to mod. Regardless, thanks for helping him out @debugman18!

Link to comment
Share on other sites

  • Developer

If that's true, then don't forget about The Big List Of Mod-Related Code Suggestions.

 

Of course! I've got a list of threads about mods to come back to (including that one) and am now catching up on the mods forum itself. I may be in touch in the coming days about the stuff in that thread. Thanks for your patience and continued enthusiasm while I finished up with RoG!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...