Jump to content

Recommended Posts

Hello,

I don't have any programming experience, but I've had success making minor tweaks and changes for a private custom world.

Recently I've been looking into the groundpounder component, and I would like to get the groundpound function to work either on weapon attack, or as part of the spellcaster component.

I read through the groundpounder component, and the bearger prefab, stategraph and brain, because Bearger seems to be the only entity able to groundpound.   There don't seem to be any particular dependencies, other than the "groundpound_fx" and groundpoundring_fx" prefabs for the spikes.

My first attempt was simply to add the groundpounder component to the main function of a batbat, and assign a couple related variables (destroyer, damage rings, numrings, groundpoundFn = doGroundPound), then adding a doGroundPound function with the line inst.components.groundpounder:GroundPound(), and adding doGroundPound to the onattack function.

That crashed with a bunch of errors when attacking with the batbat.

Perhaps I need to add the groundpounder component to the owner instead? Or am I missing something else.

Any suggestions or hints? Thanks!

Edited by Blargh

Ah yes, of course. Sorry first post, so I had to look up where to find the server log. Lol. Also discovering the logfile really does help beyond the error messages the game gives.

So I modified the batbat prefab and put it in the prefab folder
 

local assets =
{
	Asset("ANIM", "anim/batbat.zip"),
	Asset("ANIM", "anim/swap_batbat.zip"),    
}

local function onequip(inst, owner) 
    owner.AnimState:OverrideSymbol("swap_object", "swap_batbat", "swap_batbat")
    owner.AnimState:Show("ARM_carry") 
    owner.AnimState:Hide("ARM_normal") 
end

local function onunequip(inst, owner) 
    owner.AnimState:Hide("ARM_carry") 
    owner.AnimState:Show("ARM_normal") 
end

local function OnGroundPound(inst)
	inst.components.groundpounder:GroundPound()
	print("groundpound")
end

local function onattack(inst, owner, target)
    if owner.components.health and owner.components.health:GetPercent() < 1 and not target:HasTag("wall") then
        owner.components.health:DoDelta(TUNING.BATBAT_DRAIN,false,"batbat")
        owner.components.sanity:DoDelta(-TUNING.BATBAT_DRAIN * 0.5)
		OnGroundPound(inst)
		print("attack")
    end
end

local function fn(Sim)
	local inst = CreateEntity()

	inst.entity:AddTransform()
	inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    if not TheWorld.ismastersim then
        return inst
    end
    
    inst.AnimState:SetBank("batbat")
    inst.AnimState:SetBuild("batbat")
    inst.AnimState:PlayAnimation("idle")

    inst:AddTag("dull")

    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(TUNING.BATBAT_DAMAGE)
    inst.components.weapon.onattack = onattack

    -------

    inst:AddComponent("finiteuses")
    inst.components.finiteuses:SetMaxUses(TUNING.BATBAT_USES)
    inst.components.finiteuses:SetUses(TUNING.BATBAT_USES)

    inst.components.finiteuses:SetOnFinished(inst.Remove)

    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)

	inst:AddComponent("groundpounder")
    inst.components.groundpounder.destroyer = true
    inst.components.groundpounder.damageRings = 2
    inst.components.groundpounder.destructionRings = 2
    inst.components.groundpounder.numRings = 3
    inst.components.groundpounder.groundpoundFn = OnGroundPound
	
    MakeHauntableLaunch(inst)

    return inst
end

return Prefab("batbat", fn, assets)

Server Log - new world, only mod installed, error occurs upon attack

[00:01:50]: [string "scripts/mainfunctions.lua"]:421: stack overflow
LUA ERROR stack traceback:
	scripts/stacktrace.lua:124 in (method) GetTick (Lua) <122-127>
	scripts/mainfunctions.lua:421 in (global) GetTime (Lua) <420-422>
	scripts/entityscript.lua:221 in (field) _ctor (Lua) <216-241>
	scripts/class.lua:181 in (global) EntityScript (Lua) <171-184>
	scripts/mainfunctions.lua:357 in (global) CreateEntity (Lua) <354-361>
	scripts/prefabs/groundpoundringfx.lua:32 in (field) fn (Lua) <31-56>
	scripts/mainfunctions.lua:258 in () ? (Lua) <247-289>
	=[C]:-1 in (method) SpawnPrefab (C) <-1--1>
	scripts/mainfunctions.lua:306 in (global) SpawnPrefab (Lua) <300-308>
	scripts/components/groundpounder.lua:109 in (method) GroundPound (Lua) <107-120>
	../mods/gpTest/scripts/prefabs/batbat.lua:19 in (field) groundpoundFn (Lua) <18-21>
	scripts/components/groundpounder.lua:118 in (method) GroundPound (Lua) <107-120>
	...
	../mods/gpTest/scripts/prefabs/batbat.lua:27 in (field) onattack (Lua) <23-30>
	scripts/components/weapon.lua:69 in (method) OnAttack (Lua) <67-75>
	scripts/components/combat.lua:850 in (method) DoAttack (Lua) <794-868>
	scripts/actions.lua:629 in (field) fn (Lua) <622-631>
	scripts/bufferedaction.lua:24 in (method) Do (Lua) <20-34>
	scripts/entityscript.lua:1308 in (method) PerformBufferedAction (Lua) <1300-1318>
	scripts/stategraphs/SGwilson.lua:4748 in (field) fn (Lua) <4743-4751>
	scripts/stategraph.lua:568 in (method) UpdateState (Lua) <536-580>
	scripts/stategraph.lua:607 in (method) Update (Lua) <599-627>
	scripts/stategraph.lua:125 in (method) Update (Lua) <109-148>
[00:01:50]: [string "scripts/mainfunctions.lua"]:421: stack overflow
LUA ERROR stack traceback:
	scripts/stacktrace.lua:124 in (method) GetTick (Lua) <122-127>
	scripts/mainfunctions.lua:421 in (global) GetTime (Lua) <420-422>
	scripts/entityscript.lua:221 in (field) _ctor (Lua) <216-241>
	scripts/class.lua:181 in (global) EntityScript (Lua) <171-184>
	scripts/mainfunctions.lua:357 in (global) CreateEntity (Lua) <354-361>
	scripts/prefabs/groundpoundringfx.lua:32 in (field) fn (Lua) <31-56>
	scripts/mainfunctions.lua:258 in () ? (Lua) <247-289>
	=[C]:-1 in (method) SpawnPrefab (C) <-1--1>
	scripts/mainfunctions.lua:306 in (global) SpawnPrefab (Lua) <300-308>
	scripts/components/groundpounder.lua:109 in (method) GroundPound (Lua) <107-120>
	../mods/gpTest/scripts/prefabs/batbat.lua:19 in (field) groundpoundFn (Lua) <18-21>
	scripts/components/groundpounder.lua:118 in (method) GroundPound (Lua) <107-120>
	...
	../mods/gpTest/scripts/prefabs/batbat.lua:27 in (field) onattack (Lua) <23-30>
	scripts/components/weapon.lua:69 in (method) OnAttack (Lua) <67-75>
	scripts/components/combat.lua:850 in (method) DoAttack (Lua) <794-868>
	scripts/actions.lua:629 in (field) fn (Lua) <622-631>
	scripts/bufferedaction.lua:24 in (method) Do (Lua) <20-34>
	scripts/entityscript.lua:1308 in (method) PerformBufferedAction (Lua) <1300-1318>
	scripts/stategraphs/SGwilson.lua:4748 in (field) fn (Lua) <4743-4751>
	scripts/stategraph.lua:568 in (method) UpdateState (Lua) <536-580>
	scripts/stategraph.lua:607 in (method) Update (Lua) <599-627>
	scripts/stategraph.lua:125 in (method) Update (Lua) <109-148>	
[00:01:53]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:53]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:55]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:55]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:55]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:55]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:55]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:55]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:56]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:56]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:57]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:57]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:02:00]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:02:00]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	

 

Well, first clue is that you got a stackoverflow. That means, that it ran out of memory on the stack, and that usually means you've gotten yourself into an infinite loop.

Looking at your code:

1. You've made it call OnGroundPound in onattack

2. You've made OnGroundPound the function to call when the groundpound component is activated (you set groundpoundFn = OnGroundPound).

3. In your OnGroundPound function, you do this: inst.components.groundpounder:GroundPound()

Every time 1 or 2 happens, 3 happens, and whenever 3 happens, 2 happens. It's a circle jerk of biblical proportions.

How to fix this:

1. To avoid confusion, rename your OnGroundPound function to DoGroundPound, since that's what it's actually doing right now.

2. To avoid the circle jerk, remove this line: 

inst.components.groundpounder.groundpoundFn = OnGroundPound

OR make a new function named OnGroundPound, if you want to do something special whenever the groundpound is activated (like, playing an extra sound, spawning something, or changing some stats or whatever). groundpoundFn is a function that's called whenever inst.components.groundpounder:GroundPound() is called, but that function already does the actual groundpound. Anything you add to it with groundpoundFn is extra.

Edited by Ultroman

Ah that makes sense thanks. I didn't even realize that the inst.components.groundpounder.groundpoundFn line was being called by the :GroundPound() function. Looking back at Bearger, I understand now why the only thing happening OnGroundPound is him shedding. 

I still feel like I'm out of my depth though. Upon making your suggested changes, I'm running into another error on attacking with the batbat.

[00:01:04]: [string "scripts/components/groundpounder.lua"]:52: attempt to index field 'combat' (a nil value)
LUA ERROR stack traceback:
scripts/components/groundpounder.lua:52 in (method) DestroyPoints (Lua) <48-101>
   self =
      groundpoundringfx = groundpoundring_fx
      initialRadius = 1
      groundpoundfx = groundpound_fx
      destroyer = true
      groundpounddamagemult = 1
      destructionRings = 2
      burner = false
      pointDensity = 0.25
      inst = 112196 - batbat(LIMBO) (valid:true)
      noTags = table: 358ABE20
      ringDelay = 0.2
      damageRings = 2
      numRings = 3
      radiusStepDistance = 4
   points = table: 3C18A1F0
   breakobjects = true
   dodamage = true
   getEnts = true
   map = Map (0ADEC110)
scripts/components/groundpounder.lua:104 in (field) fn (Lua) <103-105>
   inst = 112196 - batbat(LIMBO) (valid:true)
   self =
      groundpoundringfx = groundpoundring_fx
      initialRadius = 1
      groundpoundfx = groundpound_fx
      destroyer = true
      groundpounddamagemult = 1
      destructionRings = 2
      burner = false
      pointDensity = 0.25
      inst = 112196 - batbat(LIMBO) (valid:true)
      noTags = table: 358ABE20
      ringDelay = 0.2
      damageRings = 2
      numRings = 3
      radiusStepDistance = 4
   points = table: 3C18A1F0
   breakobjects = true
   dodamage = true
scripts/scheduler.lua:177 in (method) OnTick (Lua) <155-207>
   self =
      running = table: 0BB2AB50
      waitingfortick = table: 0BB2A8F8
      tasks = table: 0BB2A830
      waking = table: 3C1868C0
      attime = table: 0BB2AA88
      hibernating = table: 0BB2ABF0
   tick = 155
   k = PERIODIC 112196: 0.000000
   v = true
   already_dead = false
scripts/scheduler.lua:371 in (global) RunScheduler (Lua) <369-377>
   tick = 155
scripts/update.lua:170 in () ? (Lua) <149-228>
   dt = 0.033333335071802
   tick = 155
   i = 155

[00:01:04]: [string "scripts/components/groundpounder.lua"]:52: attempt to index field 'combat' (a nil value)
LUA ERROR stack traceback:
    scripts/components/groundpounder.lua:52 in (method) DestroyPoints (Lua) <48-101>
    scripts/components/groundpounder.lua:104 in (field) fn (Lua) <103-105>
    scripts/scheduler.lua:177 in (method) OnTick (Lua) <155-207>
    scripts/scheduler.lua:371 in (global) RunScheduler (Lua) <369-377>
    scripts/update.lua:170 in () ? (Lua) <149-228>
	
[00:01:04]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:04]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:10]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:10]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:01:18]: Force aborting...

My guess is something related to the batbat and Area Damage. So looking through the Combat and Area Damage, it looks like I need to add the combat component and area damage to the batbat which strikes me as very wrong. It did work though, with some very strange effects.

So the groundpound only activates on attack for a short period after taking damage. The groundpound rings destroy trees in the area, but don't seem to affect monsters/creatures. Very strange, but most likely due to my poor understanding and implementation.

Ideally, I'm just looking to make a weapon do a small AOE to creatures. I'm starting to wonder if it may be better to give the owner area damage on equip and remove onunequip?

Below are the relevant sections of the batbat prefab changed from my previous post

local function DoGroundPound(inst)
	inst.components.groundpounder:GroundPound()
	print("groundpound")
end

local function onattack(inst, owner, target)
    if owner.components.health and owner.components.health:GetPercent() < 1 and not target:HasTag("wall") then
        owner.components.health:DoDelta(TUNING.BATBAT_DRAIN,false,"batbat")
        owner.components.sanity:DoDelta(-TUNING.BATBAT_DRAIN * 0.5)
		DoGroundPound(inst)
		print("attack")
    end
end

local function fn(Sim)
	local inst = CreateEntity()

	inst.entity:AddTransform()
	inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    if not TheWorld.ismastersim then
        return inst
    end
    
    inst.AnimState:SetBank("batbat")
    inst.AnimState:SetBuild("batbat")
    inst.AnimState:PlayAnimation("idle")

    inst:AddTag("dull")
	
	inst:AddComponent("combat")
	inst.components.combat:SetAreaDamage(6, 0.8)

    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(TUNING.BATBAT_DAMAGE)
    inst.components.weapon.onattack = onattack
	

 

Well, the groundpound component is probably meant for a living entity, since no dead things have a combat component, which is what it's complaining about not having.

For it not affecting monsters and only the trees etc, I don't know. Does Bearger hurt monsters with his groundpound?

If you want the weapon to have this effect, instead of the player, then why not make a custom component, and add that to the weapon? Or just add some more code to the onattack function (probably the least difficult)? Then you can make it do whatever you want. Look around some mods and the game code. There are functions to easily get all monsters within a radius of a point, which could then be given damage (maybe look at how groundpound find all objects within its radius, and change the tag it looks for to "monster"). The rings you can steal from the groundpound component, and leave out the destruction of trees.

If you really want to mod, it's not too hard to get to a mediocre level, and you're already a novice. Here's a great starter tutorial and there are more tutorials to find on that site.

Good luck with it!

Edited by Ultroman
On 9/28/2018 at 12:55 PM, Blargh said:

So the groundpound only activates on attack for a short period after taking damage. The groundpound rings destroy trees in the area, but don't seem to affect monsters/creatures. Very strange, but most likely due to my poor understanding and implementation.

The reason is you've to make the owners combat attack range bigger, if it's too small the GroundPound will only hit things very close too you.

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