Jump to content

Recommended Posts

Hi everyone, can someone please tell me how to fix this? I have a violin that flies in a circle around a character(like wormwood), and I want it to shoot projectiles without stopping moving around the character. But I get something strange, and I can't understand what the problem is 
image.gif.a45f158ad301d6d1d69b480a8868764d.gif
I don't really understand how to create mobs from 0, so I may have missed something important that causes this to happen

violin.lua SGviolin.lua musical_instruments.lua

in order to run circles around an entity, it has a directional stategraph so you need:

formationfollower - makes it so things go in circles around an entity. your prefab may be missing this, and it needs to be enabled at all times. if it's a summon you can make it so it despawns or dies when you die or despawn or when it cant find a leader anymore. you may need  to make other formations secondary but possibly not. not sure what the intention of the secondary fn is.

directdrive - makes it so entites run in straight lines and dont pathfind, typically its a good idea to have it on at all times if you are not expecting formationfollower to be broken.

you are running a chaseandattack behavior at the same time as something else, that probably explains the erratic movement. you probably want standandattack instead as it doesnt interfere with the locomotor.

i think you have to assign formation leader at the same time it's spawned so it doesnt get deletted immediately, so either keep that in mind or leave a grace period at summon where it doesnt despawn..

i think it could be nice to set up these things (change fx around to your heart's content ofc)

Spoiler
--SG (from woby)
State{
        name = "despawn",
        tags = {"busy", "nointerrupt"},

        onenter = function(inst, pushanim)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop", true)
        end,

        onexit = function(inst)
			inst:DoTaskInTime(0, inst.Remove)
        end,
    },
--prefab file (from woby)
local function DespawnAndDelete(inst)
	local fx = SpawnPrefab(inst.spawnfx)
	fx.entity:SetParent(inst.entity)

	inst.components.colourtweener:StartTween({ 0, 0, 0, 1 }, 13 * FRAMES, inst.Remove)

	if not inst.sg:HasStateTag("busy") then
		inst.sg:GoToState("despawn")
	end
end
--fn:
inst.DespawnAndDelete = DespawnAndDelete
inst._time_at_summon = GetTime() -- not sure if works
inst.spawnfx = "spawn_fx_small"
inst.persists = false
-- you possibly want these tags
inst:AddTag"stealth"
inst:AddTag"invincible"
inst:AddTag"NOCLICK"

-- your tool that spawns stuff
--  if tool user despawns
if inst.[yourspawnedthigs] then
	inst.[yourspawnedthings]:DespawnAndDelete()
end

 

Then your brain might look something like this (havent tested it though so might need to change some things

Spoiler
-- modmain probably
TUNING.VIOLIN_SUMMONTIME = 20

-- brain
require "behaviours/follow"
require "behaviours/standandattack"

local ViolinBrain = Class(Brain, function(self, inst)
    Brain._ctor(self, inst)
end)

function ViolinBrain:OnStart()
    local root = PriorityNode({
        ParallelNode{
            StandAndAttack(self.inst, nil, TUNING.VIOLIN_SUMMONTIME), -- maybe just do (self.inst) if you want it to target multiple things

            PriorityNode({
				WhileNode(function() return GetTime() - self.inst._time_at_summon > TUNING.VIOLIN_SUMMONTIME end, "Despawn", -- need to assign GetTime() to _time_at_summon
                    ActionNode(function()
						self.inst:DespawnAndDelete()
					end),

                WhileNode(function() return self.inst.components.formationfollower.formationleader == nil end, "No Leader (Despawn)",
					ActionNode(function()
						self.inst:DespawnAndDelete()
					end),

                -- Else no need to do anything from here, movement is handled on update from formationfollower component
                ActionNode(function()
                    self.inst.components.formationfollower.active = true
                    self.inst.components.locomotor.directdrive = true
                end),
            }, .25) -- Not sure what .25 does in brains, you might need to change it if there's still issues
        }
    }, .25)

    self.bt = BT(self.inst, root)
end

return ViolinBrain

 

Edited by oregu
43 minutes ago, oregu said:

in order to run circles around an entity, it has a directional stategraph so you need:

formationfollower - makes it so things go in circles around an entity. your prefab may be missing this, and it needs to be enabled at all times. if it's a summon you can make it so it despawns or dies when you die or despawn or when it cant find a leader anymore. you may need  to make other formations secondary but possibly not. not sure what the intention of the secondary fn is.

directdrive - makes it so entites run in straight lines and dont pathfind, typically its a good idea to have it on at all times if you are not expecting formationfollower to be broken.

you are running a chaseandattack behavior at the same time as something else, that probably explains the erratic movement. you probably want standandattack instead as it doesnt interfere with the locomotor.

  Hide contents
--SG (from woby)
State{
        name = "despawn",
        tags = {"busy", "nointerrupt"},

        onenter = function(inst, pushanim)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop", true)
        end,

        onexit = function(inst)
			inst:DoTaskInTime(0, inst.Remove)
        end,
    },
--prefab file (from woby)
local function DespawnAndDelete(inst)
	local fx = SpawnPrefab(inst.spawnfx)
	fx.entity:SetParent(inst.entity)

	inst.components.colourtweener:StartTween({ 0, 0, 0, 1 }, 13 * FRAMES, inst.Remove)

	if not inst.sg:HasStateTag("busy") then
		inst.sg:GoToState("despawn")
	end
end
--fn:
inst.DespawnAndDelete = DespawnAndDelete
inst._time_at_summon = GetTime() -- not sure if works
inst.spawnfx = "spawn_fx_small"
inst.persists = false

-- your tool that spawns stuff
--  if tool user despawns
if inst.[yourspawnedthigs] then
	inst.[yourspawnedthings]:DespawnAndDelete()
end

 

Then your brain might look something like this (havent tested it though so might need to change some things

  Hide contents
require "behaviours/follow"
require "behaviours/standandattack"

TUNING.VIOLIN_SUMMONTIME = 20

local ViolinBrain = Class(Brain, function(self, inst)
    Brain._ctor(self, inst)
end)

function ViolinBrain:OnStart()
    local root = PriorityNode({
        ParallelNode{
            StandAndAttack(self.inst, nil, TUNING.VIOLIN_SUMMONTIME), -- maybe just do (self.inst) if you want it to target multiple things

            PriorityNode({
				WhileNode(function() return GetTime() - self.inst._time_at_summon > TUNING.VIOLIN_SUMMONTIME end, "Despawn", -- need to assign GetTime() to _time_at_summon
                    ActionNode(function()
						self.inst:DespawnAndDelete()
					end),

                WhileNode(function() return self.inst.components.formationfollower.formationleader == nil end, "No Leader (Despawn)",
					ActionNode(function()
						self.inst:DespawnAndDelete()
					end),

                -- Else no need to do anything from here, movement is handled on update from formationfollower component
                ActionNode(function()
                    self.inst.components.formationfollower.active = true
                    self.inst.components.locomotor.directdrive = true
                end),
            }, .25) -- Not sure what .25 does in brains, you might need to change it if there's still issues
        }
    }, .25)

    self.bt = BT(self.inst, root)
end

return ViolinBrain

 

I don't have a problem with the despawn or the movement in the circle itself, the problem starts when I order them to attack. They have long-range weapons, but for some reason they try to get closer to the target. Using standandattack didn't help either, they now just ignore the character and focus on the target. The idea is that they should constantly keep a circle and attack only if the target is in the attack zone, not try to approach it or something

21 hours ago, GodIess said:

I don't have a problem with the despawn or the movement in the circle itself, the problem starts when I order them to attack. They have long-range weapons, but for some reason they try to get closer to the target. Using standandattack didn't help either, they now just ignore the character and focus on the target. The idea is that they should constantly keep a circle and attack only if the target is in the attack zone, not try to approach it or something

After further inspection of the standandattack behaviour, it looks like it tries to face the target.

Looks like we have to modify the StandAndAttack behaviour to ignore facing the target somehow, gonna nullify the function.

require "behaviours/follow"
require "behaviours/standandattack"
local StandAndAttackNoFace = Class(BehaviourNode, StandAndAttack) -- maybe like this?

local Visit_old = StandAndAttackNoFace.Visit
StandAndAttackNoFace.Visit = function(self, ...)
	local FacePoint_real = self.inst.FacePoint
	self.inst.FacePoint = function() return end
	Visit_old(self, ...)
	self.inst.FacePoint = FacePoint_real
end

If I did that right, can you tell me the changes are after putting that in place of the StandAndAttack node?

If that didnt work, then I think you gotta like, make the Visit the old ver at the end of the brain.

Edited by oregu

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