Jump to content

Equipable with combat component... failed attempt


Recommended Posts

I made a hat with combat element, along with its own stategraph and brain (scrapped down copy of eyeturret).

The hat is wearable.

The hat attacks when it's on ground.

Unfortunately the hat doesn't attack when it's worn on the head.

Sigh.

 

No way around this one, is there?

 

 

Link to comment
Share on other sites

@SenL, Hmm... That's a really interesting problem. I think the way I'd do this is have the onequip and onunequip functions spawn/despawn an entity that's parented to the player (player:AddChild(SpawnPrefab("turret_eyeball")) or something). You can then set the offset from the main player AnimState with Transform:SetPosition. That way it'd have animations and be able to do anything that a normal entity could do.

Link to comment
Share on other sites

Wow what an idea. Thank you!

How do you despawn?

 

local function onequip(inst, owner) 
  owner.AnimState:OverrideSymbol("swap_hat", "swap_myhat", "swap_myhat")
  owner.AnimState:Show("HAT")
  owner.AnimState:Show("HAT_HAIR")
  owner.AnimState:Hide("HAIR_NOHAT")
  owner.AnimState:Hide("HAIR")
 
  local x, y, z = owner.Transform:GetWorldPosition()
  local myhat_child = owner:AddChild(SpawnPrefab("myhat_child"))
 
  if myhat_child ~= nil then
    myhat_child.Transform:SetPosition(x, y, z)
  end
end
 
local function onunequip(inst, owner) 
  owner.AnimState:Hide("HAT")
  owner.AnimState:Hide("HAT_HAIR")
  owner.AnimState:Show("HAIR_NOHAT")
  owner.AnimState:Show("HAIR")
 
--[[
  if myhat_child ~= nil then --how to despawn any/all children?
    myhat_child.Remove()
  end
--]]
end
Link to comment
Share on other sites

But myhat_child is a local variable inside function onequip ... is that still accessible to other functions (in this case onunequip)?

 

Edit:

Yes, it crashed. Error is "myhat_child" is not declared in onunequip function

 

I also had to change the onequip to

local x, y, z = owner.Transform:GetWorldPosition()
local myhat_child_prefab = SpawnPrefab("myhat_child")
if myhat_child_prefab ~= nil then
  local myhat_child = owner:AddChild(myhat_child_prefab) --crashes when I put SpawnPrefab() right here
 
  if myhat_child ~= nil then
    myhat_child.Transform:SetPosition(x, y, z)
  end
end
 
Is that OK?
Edited by SenL
Link to comment
Share on other sites

Omg it works! Haha!

...but with bugs

 

on myhat_child.lua

If I say

inst.AnimState:SetBank("myhat")

inst.AnimState:SetBuild("myhat")

 

Bug #1: There appears "myhat" at bottom of character and stays.

Bug #2: With combat, it shoots twice. Weird.

 

If I comment those two above,

 

Bug #1: fixed

Bug #2: Only shoots once and never again. Have to unequip and requip. Weird.

 

Code:

local function onequip(inst, owner) 
  owner.AnimState:OverrideSymbol("swap_hat", "swap_myhat", "swap_myhat")
  owner.AnimState:Show("HAT")
  owner.AnimState:Show("HAT_HAIR")
  owner.AnimState:Hide("HAIR_NOHAT")
  owner.AnimState:Hide("HAIR")
 
  local x, y, z = owner.Transform:GetWorldPosition()
  inst.myhat_child_prefab = SpawnPrefab("myhat_child")
  if inst.myhat_child_prefab ~= nil then
    print("myhat->spawn child")
    inst.myhat_child = owner:AddChild(inst.myhat_child_prefab)
 
    if inst.myhat_child ~= nil then
      inst.myhat_child.Transform:SetPosition(x, y, z)
      print("myhat->add and teleport child")
    end
  end
end
 
local function onunequip(inst, owner) 
  owner.AnimState:Hide("HAT")
  owner.AnimState:Hide("HAT_HAIR")
  owner.AnimState:Show("HAIR_NOHAT")
  owner.AnimState:Show("HAIR")
 
  if inst.myhat_child ~= nil then
    inst.myhat_child:Remove()
    inst.myhat_child = nil
    print("myhat->remove child")
  end
 
  if inst.myhat_child_prefab ~= nil then
    inst.myhat_child_prefab = nil
    print("myhat->remove child prefab")
 end
end
Edited by SenL
Link to comment
Share on other sites

@SenL, Not sure about those bugs, but when you make the entity a child of the player, it by default has the same location (and follows the player as they move around). So when you use Transform:SetPosition(x,y,z), the x,y,z needs to be relative to the player. So maybe (0,2,0).

Link to comment
Share on other sites

Ok changed it to (0,2,0).

 

Strange that the "myhat->remove child" and "myhat->add and teleport child" never get printed/called.

 

Log:

[00:10:25]: Could not find anim build OUTOFSPACE
[00:10:25]: Could not find anim bank [OUTOFSPACE]
[00:10:25]: myhat->spawn child
[00:10:32]: myhat->remove child prefab
[00:10:34]: Could not find anim build OUTOFSPACE
[00:10:34]: Could not find anim bank [OUTOFSPACE]
[00:10:34]: myhat->spawn child
[00:10:38]: myhat->remove child prefab
[00:10:43]: DoRestart: true
 
 
Link to comment
Share on other sites

Ok if I change the myhat_child lua to

 

inst.AnimState:SetBank("myhat")

inst.AnimState:SetBuild("myhat_child")

 

It works fine (hat shoots more than once).

However, it seems that the "remove child" does not get called... so if I unequip->equip again and again, there will be many children and all of them are shooting. It's crazy haha.

 

Code is

local function onunequip(inst, owner) 
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAT_HAIR")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
 
if inst.myhat_child ~= nil then
inst.myhat_child:Remove()
inst.myhat_child = nil
print("myhat->remove child")
end
 
if inst.myhat_child_prefab ~= nil then
inst.myhat_child_prefab = nil
print("myhat->remove child prefab")
end
end
 
It never goes inside "if inst.myhat_child ~= nil then" 
It seems that inst.myhat_child is never not nil.
Should this "inst" be "owner" instead? Doubt it...
What then..
Link to comment
Share on other sites

@SenL, You don't need a separate myhat_child_prefab field, since you're already attaching the child to the table. So if the rest works, you can just do away with that part, and store the SpawnPrefab in a local variable, then add it as a child. You should really be able to add it as one step, though, if there is a prefab of that name.

Link to comment
Share on other sites

I made a typo in the onequip. Now it's this and it crashes.

 

if inst.myhat_child == nil then
  inst.myhat_child = owner:AddChild(SpawnPrefab("myhat_child"))
  inst.myhat_child.Transform:SetPosition(0, 2, 0) --crashes here, saying it's indexing a nil
end
 
Let me trying using a local variable...
Edited by SenL
Link to comment
Share on other sites

Omg I think I fixed it. I copied forcefieldfx from hats.lua and used SetParent() instead of AddChild().

Is that ok?

 

onequip:

if inst.myhat_child == nil then
  local child = SpawnPrefab("myhat_child")
  child.entity:SetParent(owner.entity)
  child.Transform:SetPosition(0, 0.2, 0)
 
  owner:DoTaskInTime(1, function() inst.myhat_child = child end)
end
 
onunequip:
if inst.myhat_child ~= nil then
  inst.myhat_child:Remove()
  inst.myhat_child = nil
end
 
Edited by SenL
Link to comment
Share on other sites

I have a bug.

The "shooting hat" works fine as host.

As client, the hat only shoots the host's target. The client doesn't shoot any enemies the client attacking when host is far.

What seems to cause this...

 

Thanks.

Link to comment
Share on other sites

Hm good idea.

I see that it's using "LinkToPlayer".

Is that built-in?

 

When I tried it, it doesn't work on mine.

 

shootinghat_child.lua:

...

local function linktoplayer(inst, player)

  inst._playerlink = player

  print("player:"..player) --this doesn't seem to print, why?

  player.components.leader:AddFollower(inst, true)

end

...

local function fn(Sim)

  ...

  inst.entity:AddNetwork()

  ...

  inst.LinkToPlayer = linktoplayer

  return inst

end

 

return Prefab("common/inventory/shootinghat_child", fn, assets)

 

Why doesn't it do print() in this lua? How do I debug?

 

Edit:

Oh it seems to be called from abigail_flower.lua...

Edit:

OH YEA! It works (as client)!

 

shootinghat.lua

...

  local function linktoplayer(inst, player)

    if player ~= nil then

      inst._playerlink = player

    end

  end

...

  local function onequip(inst, owner)

    ..

    if inst.shootinghat_child == nil then

      local child = SpawnPrefab("shootinghat_child")

      child.entity:SetParent(owner.entity)

      child.Transform:SetPosition(0, 0.2, 0)

      linktoplayer(inst, owner)

      child:LinkToPlayer(inst._playerlink) --could we just do child:LinkToPlayer(owner)?

    ..

  end

...

 

shootinghat_child.lua

...

local function auratest(inst, target)

  ... --copy from abigail.lua

end

...

local function retargetfn(inst)

  ... --copy from abigail.lua

end

...

local function linktoplayer(inst, player)

  inst._playerlink = player

  print("shootinghat_child->linktoplayer linking to ",player)

  player.components.leader:AddFollower(inst, true) --I don't have a check if player has leader component, but maybe it's default for character prefab?

  end

...

local function fn(Sim)

  ...

  inst:AddComponent("combat")

  ...

  inst.components.combat.SetRetargetFunction(1, retargetfn)

  ...

  inst:AddComponent("aura")

  ...

  inst.components.aura.auratestfn = auratest

  ...

  inst:AddComponent("follower")

  inst._playerlink = nil

  inst.LinkToPlayer = linktoplayer

  return inst

end

...

Tested briefly with a client and it seems to work.

Let me know if anything looks wrong above.

I'll test more tomorrow.

 

Thanks!

Edited by SenL
Link to comment
Share on other sites

This means I need to fix my "stinger turret" (a weaker copy of Houndius Shootius) mod. As it currently only target host's enemies.

However in this mod I don't have any equippable component (where it has SetOnEquip, where it has owner information).

How then do I find the "owner" (or crafter, or builder) of this turret?

 

This turret components are:

health, combat, lighttweener, inventory, sanityaura, inspectable, lootdropper

 

Any hints?

Thanks.

 

Edit:

When it's an item, it has "deployable" component so I can use ondeploy because it has deployer.

Do I want to make the turret only target deployer's enemies (pvp ok) or any player's enemies (I may try using FindEntity) (pvp not ok)...

Edited by SenL
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...