Jump to content

Recommended Posts

I've got a peculiar trading issue with my mod.

It has a new follower (chester2) basically a duplicate of Chester with the "trader" component added and a new item (ches2fuel) with the "tradable" component added and its also edible.

Chester2 will not acknowledge and display "Give" when I hover the ches2fuel item over it but it does acknowledge any in game tradable item such as food, light bulbs...and accepts them, they disappear and not get stored which is what I expect at this stage.

The same applies to the ches2fuel item, it cannot be traded with chester2 but can be traded with any other in game trader such as pigmen and wormholes which display "Give" and accept the new item.

So there must be something odd about my setup that a new tradable item and a new trader within the same mod cannot interact!?

Note, chester2 and ches2fuel are new and not overrides of in game modules.

 

modmain.lua

local STRINGS = GLOBAL.STRINGS

PrefabFiles = {
"chester2_eyebone",
"chester2",
"ches2fuel",
}

ches2fuel.lua

local assets=
{
Asset("ANIM", "anim/annafuel.zip"),
Asset("IMAGE", "images/annafuel.tex"),
Asset("ATLAS", "images/annafuel.xml"),
}

local function fn(Sim)
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()

MakeInventoryPhysics(inst)

inst.AnimState:SetBank("annafuel")
inst.AnimState:SetBuild("annafuel")
inst.AnimState:PlayAnimation("idle")

inst:AddComponent("stackable")
inst.components.stackable.maxsize = TUNING.STACK_SIZE_MEDITEM

inst:AddComponent("inventoryitem")
inst.components.inventoryitem.atlasname = "images/annafuel.xml"
inst.components.inventoryitem:ChangeImageName("annafuel")

inst:AddComponent("tradable")
inst:AddComponent("inspectable")

inst:AddComponent("edible")
inst.components.edible.healthvalue = TUNING.HEALING_TINY
inst.components.edible.hungervalue = 0
inst.components.edible.foodtype = "VEGGIE"

return inst
end

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

chester2.lua

require "prefabutil"
local brain = require "brains/chester2brain"

local WAKE_TO_FOLLOW_DISTANCE = 14
local SLEEP_NEAR_LEADER_DISTANCE = 7

local assets =
{
Asset("ANIM", "anim/chester2.zip"),
Asset("ANIM", "anim/ui_chest_3x2.zip"),
Asset("SOUND", "sound/chester.fsb"),
}

local prefabs =
{
"chester2_eyebone",
"die_fx",
"ches2fuel",
}

local function ShouldWakeUp(inst)
return DefaultWakeTest(inst) or not inst.components.follower:IsNearLeader(WAKE_TO_FOLLOW_DISTANCE)
end

local function ShouldSleep(inst)
--print(inst, "ShouldSleep", DefaultSleepTest(inst), not inst.sg:HasStateTag("open"), inst.components.follower:IsNearLeader(SLEEP_NEAR_LEADER_DISTANCE))
return DefaultSleepTest(inst) and not inst.sg:HasStateTag("open") and inst.components.follower:IsNearLeader(SLEEP_NEAR_LEADER_DISTANCE)
end

local function ShouldKeepTarget(inst, target)
return false -- chester2 can't attack, and won't sleep if he has a target
end


local function OnOpen(inst)
if not inst.components.health:IsDead() then
inst.sg:GoToState("open")
end
end

local function OnClose(inst)
if not inst.components.health:IsDead() then
inst.sg:GoToState("close")
end
end

-- eye bone was killed/destroyed
local function OnStopFollowing(inst)
--print("chester2 - OnStopFollowing")
inst:RemoveTag("companion")
end

local function OnStartFollowing(inst)
--print("chester2 - OnStartFollowing")
inst:AddTag("companion")
end

local slotpos = {}

for y = 2, 0, -1 do
for x = 0, 2 do
table.insert(slotpos, Vector3(80*x-80*2+80, 80*y-80*2+80,0))
end
end

local function create_chester2()
--print("chester2 - create_chester2")

local inst = CreateEntity()

inst:AddTag("companion")
inst:AddTag("character")
inst:AddTag("scarytoprey")
inst:AddTag("chester2")
inst:AddTag("notraptrigger")

inst.entity:AddTransform()

local minimap = inst.entity:AddMiniMapEntity()
minimap:SetIcon( "chester.png" )

--print(" AnimState")
inst.entity:AddAnimState()
inst.AnimState:SetBank("chester")
inst.AnimState:SetBuild("chester2")

--print(" sound")
inst.entity:AddSoundEmitter()

--print(" shadow")
inst.entity:AddDynamicShadow()
inst.DynamicShadow:SetSize( 2, 1.5 )

--print(" Physics")
MakeCharacterPhysics(inst, 75, .5)

--print(" Collision")
inst.Physics:SetCollisionGroup(COLLISION.CHARACTERS)
inst.Physics:ClearCollisionMask()
inst.Physics:CollidesWith(COLLISION.WORLD)
inst.Physics:CollidesWith(COLLISION.OBSTACLES)
inst.Physics:CollidesWith(COLLISION.CHARACTERS)

inst.Transform:SetFourFaced()


--print(" Userfuncs")
inst:AddComponent("trader")
-- inst.components.trader:SetAcceptTest(ShouldAcceptItem)
-- inst.components.trader.onaccept = OnGetItemFromPlayer

------------------------------------------

--print(" combat")
inst:AddComponent("combat")
inst.components.combat.hiteffectsymbol = "chester_body"
inst.components.combat:SetKeepTargetFunction(ShouldKeepTarget)
--inst:ListenForEvent("attacked", OnAttacked)

--print(" health")
inst:AddComponent("health")
inst.components.health:SetMaxHealth(TUNING.CHESTER_HEALTH)
inst.components.health:StartRegen(TUNING.CHESTER_HEALTH_REGEN_AMOUNT, TUNING.CHESTER_HEALTH_REGEN_PERIOD)
inst:AddTag("noauradamage")


--print(" inspectable")
inst:AddComponent("inspectable")
inst.components.inspectable:RecordViews()
--inst.components.inspectable.getstatus = GetStatus

--print(" locomotor")
inst:AddComponent("locomotor")
inst.components.locomotor.walkspeed = 3
inst.components.locomotor.runspeed = 7

--print(" follower")
inst:AddComponent("follower")
inst:ListenForEvent("stopfollowing", OnStopFollowing)
inst:ListenForEvent("startfollowing", OnStartFollowing)

--print(" knownlocations")
inst:AddComponent("knownlocations")

--print(" burnable")
MakeSmallBurnableCharacter(inst, "chester_body")

--(" container")
inst:AddComponent("container")
inst.components.container:SetNumSlots(#slotpos)

inst.components.container.onopenfn = OnOpen
inst.components.container.onclosefn = OnClose

inst.components.container.widgetslotpos = slotpos
inst.components.container.widgetanimbank = "ui_chest_3x3"
inst.components.container.widgetanimbuild = "ui_chest_3x3"
inst.components.container.widgetpos = Vector3(0,-180,0)

--print(" sleeper")
inst:AddComponent("sleeper")
inst.components.sleeper:SetResistance(3)
inst.components.sleeper.testperiod = GetRandomWithVariance(6, 2)
inst.components.sleeper:SetSleepTest(ShouldSleep)
inst.components.sleeper:SetWakeTest(ShouldWakeUp)

--print(" sg")
inst:SetStateGraph("SGchester")
inst.sg:GoToState("idle")

--print(" brain")
inst:SetBrain(brain)

--print("chester2 - create_chester2 END")
return inst
end

return Prefab( "common/chester2", create_chester2, assets, prefabs)

 

I've also attached the test mod if it helps. DebugSpawn("chester2_eyebone") to get chester 2 to appear and DebugSpawn("ches2fuel") to get the new item to trade with chester2.

Any help much appreciated.

chester2.zip

I looked at it and I can't figure out the problem. The ACTION.GIVE gets added to the list of scene actions when I hover the fuel over the chester2 but somehow it never appears in the game when it is chester2 we are hovering over.

 

Even more insane, it suddenly works when I activate my summons mod at the same time as running your mod. My summons mod is obviously not interacting with your stuff in any way.

Edited by Heavenfall

Well, I found out why activating Summons mod makes it tradeable to chester2: I do this in modmain

GLOBAL.ACTIONS.GIVE.priority = 4

 

Okay so it appears that the game collects possible actions using a certain order. Ie, when I hover an item over a target it gathers info - can I attack it? Can I store something in it? Can I trade/give the item to it? Note how you can only really do one thing at a time using this method.

 

For some reason I can't figure out this order is messed up when using ches2fuel on chester2. So instead of the expected Give action, you get Store instead. However, if you make Give a higher priority in your modmain.lua (like the code above) then the Give action gets higher priority and you'll be able to trade your ches2fuel to chester2.

Wow you got it. The priority setting works perfectly, seems most actions have a priority of zero, I tried -1 which did not work, tried 1 and it did work, but I'll stick with 4, since I will be using your Summon mod as well, when I finish this stupid mod so I can actually play the game :nightmare:

As you mentioned with the deciding what action to take logic the only way I could get it to work was to disable the "container" component of chester2 which quite obviously defeats the purpose but got access to the trading action. Was also in the process of looking through your modmain for clues.

 

Thanks again Heavenfall that's the second tight 'modding' spot you got me out of.

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