Jump to content

Help to turn florid postem into a "trader"


Recommended Posts

I want to turn the portal into an entity that keeps asking the players for specific item in exchange for goodies. My code is already like this:

Spoiler

-- list will be expanded later
local offering_list = {
	{name = 'flint', tier = 1}
}

local function confirmOffering(inst)
	local fx = SpawnPrefab("small_puff")
		fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
		fx.Transform:SetScale(1.2, 1.2, 1.2)
end

local function ShouldAcceptItem(inst, item)
	for n, e in ipairs(offering_list) do
		if item and item.prefab == e.name then
			confirmOffering(inst)
			return true
		end
	end 
end

local function getRewardTier(inst, item)
	for n, e in ipairs(offering_list) do
		if item and item.prefab == e.name then
			return e.tier
		end
	end
end

local function OnGetItemFromPlayer(inst, giver, item)
	if getRewardTier(item) == 1 then
		inst.components.talker:Say("Thank you")
		-- give reward
	end
end

local function OnRefuseItem(inst, item)
	inst.components.talker:Say("I don't want this")
end


function portalpostinit(inst)
	inst:AddComponent("talker")
	inst.components.talker.fontsize = 35
	inst.components.talker.font = TALKINGFONT

	inst:AddComponent("trader")
	inst.components.trader:SetAcceptTest(ShouldAcceptItem)
	inst.components.trader.onaccept = OnGetItemFromPlayer
	inst.components.trader.onrefuse = OnRefuseItem
	inst.components.trader.deleteitemonaccept = true 
	inst.components.trader:Enable()
end

AddPrefabPostInit("multiplayer_portal", portalpostinit)

 

But it's giving me an error "attempt to call global SpawnPrefab (a nil value)". 

 

Link to comment
Share on other sites

Thanks! That worked wonders! Another thing, I'm not familiar with variables and data saving here so how can I save (and retrieve) some stats of the postem? Like how many flints I've given since start and modify the amount of flint needed acording to how many days passed, etc

Link to comment
Share on other sites

The best way to store information like this, is in a component I think.

See this post how it looks like:

 

For saving and loading, all you need from the component code is this:

local TransformerMode = Class(function(self, inst)
    self.inst = inst
    self.modename = nil
    self.builder_tags = {} -- the builder_tags your char should get this way, which will be check with the modded CanLearn function from modmain
end)

function TransformerMode:OnSave()
    return {
    modename = self.modename,
    builder_tags = self.builder_tags,
    }
end

function TransformerMode:OnLoad(data)
    self.modename = data and data.modename or nil
    self.builder_tags = data and data.builder_tags or {}
end

return TransformerMode

of course replace TranformerMode with your component name.
self.inst = inst should be unchange.
this code does save the variable modename and the array builder_tags.
You can replace them of course with your things to save.

Edited by Serpens
Link to comment
Share on other sites

I don't see any unique components so you should probably save and load on the portal itself(this would go in the portalpostinit function)

inst.OnSave = function(inst, data) 
	data.flintused = inst.flintused 
end

inst.OnLoad = function(inst, data)
	if data and data.flintused then
		inst.flintused = data.flintused
	end
end

 

If the portal already has existing OnSave and OnLoad functions, something like this would work:

local inst._OnSave = inst.OnSave
local inst._OnLoad = inst.OnLoad

inst.OnSave = function(inst, data) 
	data.flintused = inst.flintused 
	if inst._OnSave then
		inst._OnSave(data)
	end
end

inst.OnLoad = function(inst, data)
	if data and data.flintused then
		inst.flintused = data.flintused
	end
	if inst._OnLoad then
		inst._OnLoad(data)
	end

 

Link to comment
Share on other sites

but the portal is a game object. so you can't simply change the lua script from portal (at least you should not)
so how would your code look like , when putting it into modmain?
Okay, I guess you can simply use "AddPrefabPostInit" for this...

But I wonder what is the point of components then... if you can save/load and do all the other stuff also in the thing itself...
I think the point of components is, that you can easily transfer it to every other thing you would like to have the same abilties.
So I guess it depends if the author wants it for portal only, or if he maybe want also other things to act like this (this was mostly ment as an explanation to myself :D)
 

Link to comment
Share on other sites

7 minutes ago, Serpens said:

but the portal is a game object. so you can't simply change the lua script from portal (at least you should not)
so how would your code look like , when putting it into modmain?
Okay, I guess you can simply use "AddPrefabPostInit" for this...

But I wonder what is the point of components then... if you can save/load and do all the other stuff also in the thing itself...
I think the point of components is, that you can easily transfer it to every other thing you would like to have the same abilties.
So I guess it depends if the author wants it for portal only, or if he maybe want also other things to act like this (this was mostly ment as an explanation to myself :D)
 

he didn't add any components that are unique to the mod, and modifying the trader/talker component would effect every prefab that uses those components.

 

A lot of things in programming technically aren't needed, but are used for more accessibility and readability.

Edited by Aquaterion
Link to comment
Share on other sites

I might have other uses for the component part later :) But for now, I'll stick with the simplest solution. Ok, so one last thing, How do I make the:

inst:ListenForEvent("killed", onkilled)

work for all characters? Specifically, the portal gives you a target and once you kill it, a chest wiil spawn where it died. (I mean, I could edit the loot tables but since I'm going to make a big list, I'm wondering if there is an easier way)

Link to comment
Share on other sites

2 hours ago, Welpx said:

I might have other uses for the component part later :) But for now, I'll stick with the simplest solution. Ok, so one last thing, How do I make the:


inst:ListenForEvent("killed", onkilled)

work for all characters? Specifically, the portal gives you a target and once you kill it, a chest wiil spawn where it died. (I mean, I could edit the loot tables but since I'm going to make a big list, I'm wondering if there is an easier way)

well depends on how you make it, i would personally do something like this

local function onkill(inst, data)
	if data.victim == inst.target then--if what you killed is your target
		local pos = Point(data.victim.Transform:GetWorldPosition())
		inst:RemoveEventCallback("killed", onkill)--remove the listening for kills
		inst.target = nil--remove target
		local chest = SpawnPrefab("treasurechest")
		chest.Transform:SetPosition(pos:Get())
	end
end

--i'm not sure how you implemented target system so i'm making up some code here
--(in this case i would be running this part of code in OnGetItemFromPlayer)
if #AllPlayers > 1 and not giver.target then--if more than 1 players are on and player doesn't have a target already
	local otherplayers = {}
	for k,v in pairs(AllPlayers) do  
		if v ~= giver then--everyone except yourself
			table.insert(otherplayers, v)
		end
	end
	local targetgiven = otherplayers[math.random(#otherplayers)]--pick random player
	
	if targetgiven then
		giver.target = targetgiven
		giver:ListenForEvent("killed", onkill)
	end
end

 

Link to comment
Share on other sites

Marvelous! Thanks for all the help guys! I just had to make a little change from data.victim to data.victim.prefab. Which rises another question, where/how can I actually find all these properties? I'm always lost when I need to find something searching in all the prefabs (I'm even using sublime search tool to help). 

This time I tried to figure why the code wasn't working so noticed that printing data.victim for a "bee" gives me "###### bee". So I figure the numbers are unique ids for each mob? Where do I need to look if I want to know all properties in victim (and other objetcs)?

Link to comment
Share on other sites

14 hours ago, Welpx said:

Marvelous! Thanks for all the help guys! I just had to make a little change from data.victim to data.victim.prefab. Which rises another question, where/how can I actually find all these properties? I'm always lost when I need to find something searching in all the prefabs (I'm even using sublime search tool to help). 

This time I tried to figure why the code wasn't working so noticed that printing data.victim for a "bee" gives me "###### bee". So I figure the numbers are unique ids for each mob? Where do I need to look if I want to know all properties in victim (and other objetcs)?

The way I learned this stuff is by printing it in game

basically using

for k,v in pairs(ThePlayer) do print(k,v) end

--k = key/property
--v = value stored in k

--for example:
local exampletable = {name = "guy", id="123"}
--the k would be name or id
--and the v for that k would be "guy" or "123"

 

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