_Q_ Posted February 22, 2013 Share Posted February 22, 2013 (edited) After making some changes to pigking.lua game crash after giving gold to pigking.Here is the code with changes:local assets={ Asset("ANIM", "data/anim/pig_king.zip"), Asset("SOUND", "data/sound/pig.fsb"),}local prefabs = { "goldnugget",}[B] local function Rfun() troll = math.random(1, 10) if troll == 1 then name = "\"goldnugget\"" elseif troll == 2 then name = "\"twigs\"" elseif troll == 3 then name = "\"cutgrass\"" else name = "\"spoiledfood\"" end return nameend[/B]local function OnGetItemFromPlayer(inst, giver, item) if item.components.tradable.goldvalue > 0 then inst.AnimState:PlayAnimation("cointoss") inst.AnimState:PushAnimation("happy") inst.AnimState:PushAnimation("idle", true) inst:DoTaskInTime(20/30, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingThrowGold") for k = 1,item.components.tradable.goldvalue do [B] local nug = SpawnPrefab(Rfun())[/B] local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,4.5,0) nug.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random()*60-30)*DEGREES --local angle = (-TUNING.CAM_ROT-90 + math.random()*60-30)/180*PI local sp = math.random()*6+3 nug.Physics:SetVel(sp*math.cos(angle), math.random()*3+10, sp*math.sin(angle)) end end) inst:DoTaskInTime(1.5, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingHappy") end) endendlocal function OnRefuseItem(inst, giver, item) inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingReject") inst.AnimState:PlayAnimation("unimpressed") inst.AnimState:PushAnimation("idle", true)endlocal function fn(Sim) local inst = CreateEntity() local minimap = inst.entity:AddMiniMapEntity() minimap:SetPriority( 5 ) --inst:AddComponent( "discoverable" ) --inst.components.discoverable:SetIcons( "treasure.png", "pigking.png" ) minimap:SetIcon( "pigking.png" ) minimap:SetPriority( 1 ) inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.DynamicShadow:SetSize( 10, 5 ) MakeObstaclePhysics(inst, 2, .5) --inst.Transform:SetScale(1.5,1.5,1.5) inst.AnimState:SetBank("Pig_King") inst.AnimState:PlayAnimation("idle", true) inst.AnimState:SetBuild("Pig_King") inst:AddComponent("inspectable") inst:AddComponent("trader") inst.components.trader:SetAcceptTest( function(inst, item) return item.components.tradable.goldvalue > 0 end) inst.components.trader.onaccept = OnGetItemFromPlayer inst.components.trader.onrefuse = OnRefuseItem inst:ListenForEvent( "nighttime", function(global, data) inst.components.trader:Disable() inst.AnimState:PlayAnimation("sleep_pre") inst.AnimState:PushAnimation("sleep_loop", true) end, TheGlobalInstance) inst:ListenForEvent( "daytime", function(global, data) inst.components.trader:Enable() inst.AnimState:PlayAnimation("sleep_pst") inst.AnimState:PushAnimation("idle", true) end, TheGlobalInstance) return instendreturn Prefab( "common/objects/pigking", fn, assets, prefabs)The end result of my function is name of the prefab I want to spawn in quotes so I don't know why game crush after giving item to pigking. Any help would be great.Doing this other way also cause crush of game after giving meat to pigking:local function OnGetItemFromPlayer(inst, giver, item) if item.components.tradable.goldvalue > 0 then troll = math.random(1, 10) inst.AnimState:PlayAnimation("cointoss") inst.AnimState:PushAnimation("happy") inst.AnimState:PushAnimation("idle", true) inst:DoTaskInTime(20/30, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingThrowGold") for k = 1,item.components.tradable.goldvalue do if troll == 1 then local nug = SpawnPrefab("goldnugget") else local nug = SpawnPrefab("spoiledfood") end local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,4.5,0) nug.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random()*60-30)*DEGREES --local angle = (-TUNING.CAM_ROT-90 + math.random()*60-30)/180*PI local sp = math.random()*6+3 nug.Physics:SetVel(sp*math.cos(angle), math.random()*3+10, sp*math.sin(angle)) end end) Edited February 22, 2013 by _Q_ Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 (edited) Um....few things...Make sure to check log.txt file in bin folder after crashes to see where and on what line the crash occured. Also you can use print("my text") statements in the code to test values. These show in the log file.The prefab names should not be double quoted, just "name", not "\"name\""Your variables in Rfun should have local in front of them to declare them at that level. Right now you are trying to set undeclared variables. Scope of variables in lua takes a bit of getting used to. For your variable setting to work as you have it means that you would declare them as local outside of the Rfun function (i.e. local to the pigman.lua code chunk)Beyond that is the call to SpawnPrefab....because of how variables in lua works and pointers, etc you are passing the Rfun function itself instead of its return value which SpawnPrefab expects....I think there is a syntax to handle this but forget what it is atm.The basic method is to create a temp variable to receive the return from Rfun and then pass that on to SpawnPrefabsee my changes here:local function Rfun() local troll = math.random(1, 10) local name = "spoiledfood" if troll == 1 then name = "goldnugget" elseif troll == 2 then name = "twigs" elseif troll == 3 then name = "cutgrass" end return nameendlocal function OnGetItemFromPlayer(inst, giver, item)... for k = 1,item.components.tradable.goldvalue do--[[ ORIGlocal nug = SpawnPrefab("goldnugget")-- /ORIG ]]-- MODlocal drop = Rfun()local nug = SpawnPrefab(drop)-- /MOD ]] local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,4.5,0)... Edited February 22, 2013 by WrathOf Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 By the way...the comment format I am using allows me to quickly activate and deactivate mod changes for testing etc.They are not necessary but I would highly recommend putting some sort of comments around your code changes to highlight (and remember later) what was changed. I like keeping the original code nearby too so I don't have to look it up from a backup."--[[" this means start a comment until you reach "]]" but keep in mind that you cannot nest them as in "--[[ outer --[[ inner comment ]] comment ]]" without using a different sytax. Link to comment Share on other sites More sharing options...
_Q_ Posted February 22, 2013 Author Share Posted February 22, 2013 (edited) Then why the second method also cause crash, no function there, just if else.Was doing it your way and it also crashed.After printing this in lua: "\"spoiledfood\"" I got this: "spoiledfood"so it is exact thing like in default script Edited February 22, 2013 by _Q_ Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 For the second method you tried....Again this is because of the troll variable being undeclared, i.e. local troll = math.random(1, 10)Also, I verified that the code I posted worked as you intented. Was amusing to get random drops.EDIT:this is what the log.txt file said about your code when I first tested it......./common/dont_starve/data/scripts/prefabs/pigking.lua:14: assign to undeclared variable 'troll' Link to comment Share on other sites More sharing options...
Developer Bigfoot Posted February 22, 2013 Developer Share Posted February 22, 2013 Hey _Q_,You'll need to add the items into the prefabs list. Also, "spoiledfood" is actually "spoiled_food". Here are the edits that I've tested to work:local prefabs = { "goldnugget", "twigs", "cutgrass", "spoiled_food"}local function Rfun() local troll = math.random(1, 10) local name = "spoiled_food" if troll == 1 then name = "goldnugget" elseif troll == 2 then name = "twigs" elseif troll == 3 then name = "cutgrass" end return nameendlocal function OnGetItemFromPlayer(inst, giver, item) if item.components.tradable.goldvalue > 0 then inst.AnimState:PlayAnimation("cointoss") inst.AnimState:PushAnimation("happy") inst.AnimState:PushAnimation("idle", true) inst:DoTaskInTime(20/30, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingThrowGold") for k = 1,item.components.tradable.goldvalue do local nug = SpawnPrefab(Rfun()) local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,4.5,0) nug.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random()*60-30)*DEGREES --local angle = (-TUNING.CAM_ROT-90 + math.random()*60-30)/180*PI local sp = math.random()*6+3 nug.Physics:SetVel(sp*math.cos(angle), math.random()*3+10, sp*math.sin(angle)) end end) inst:DoTaskInTime(1.5, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingHappy") end) endend Link to comment Share on other sites More sharing options...
Developer Bigfoot Posted February 22, 2013 Developer Share Posted February 22, 2013 So I take back the bit about the prefabs. It doesn't need that part. Mostly your original script was crashing from not declaring the variables with local and the spoiled_food misspelling. Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 [MENTION=5551]_Q_[/MENTION]regarding the quotes text....a return from print ofspoiled_foodis not interpreted the same as a return of"spoiled_food"double quoting the text give this error:.../common/dont_starve/data/scripts/prefabs/pigking.lua:50: attempt to index local 'nug' (a nil value)since the prefab name is used as a lookup against a master list and SpawnPrefab could not find it. [MENTION=2]Bigfoot[/MENTION]I get an error when using SpawnPrefab(Rfun())? Will test again. Must of been the wrong prefab name :DAlso, regarding the prefab assets lists....I know we are *supposed* to add all used prefabs to this but I have come across instances in your code that do *not* do this and everything seems to work fine.I thought that was more about pre-loading the assets versus *required*? Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 Lol @ trying to use forums as a chat app [MENTION=2]Bigfoot[/MENTION]Ok, so it is best practice to add used prefabs to the assets list but not *required*?Is there any issue with memory allocation or anything that we should be concered with if we do *not* add to the assets list? Link to comment Share on other sites More sharing options...
_Q_ Posted February 22, 2013 Author Share Posted February 22, 2013 Hey _Q_,You'll need to add the items into the prefabs list. Also, "spoiledfood" is actually "spoiled_food". Here are the edits that I've tested to work:local prefabs = { "goldnugget", "twigs", "cutgrass", "spoiled_food"}local function Rfun() local troll = math.random(1, 10) local name = "spoiled_food" if troll == 1 then name = "goldnugget" elseif troll == 2 then name = "twigs" elseif troll == 3 then name = "cutgrass" end return nameendlocal function OnGetItemFromPlayer(inst, giver, item) if item.components.tradable.goldvalue > 0 then inst.AnimState:PlayAnimation("cointoss") inst.AnimState:PushAnimation("happy") inst.AnimState:PushAnimation("idle", true) inst:DoTaskInTime(20/30, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingThrowGold") for k = 1,item.components.tradable.goldvalue do local nug = SpawnPrefab(Rfun()) local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,4.5,0) nug.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random()*60-30)*DEGREES --local angle = (-TUNING.CAM_ROT-90 + math.random()*60-30)/180*PI local sp = math.random()*6+3 nug.Physics:SetVel(sp*math.cos(angle), math.random()*3+10, sp*math.sin(angle)) end end) inst:DoTaskInTime(1.5, function() inst.SoundEmitter:PlaySound("dontstarve/pig/PigKingHappy") end) endendThank You [MENTION=2]Bigfoot[/MENTION]Thank You @ WrathOfIt seems I need to find better lua tutorials, and pay more attention to prefab names. Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 No problem, we are all learning here.If your code is not crashing the game then you are not trying hard enough! Link to comment Share on other sites More sharing options...
WrathOf Posted February 22, 2013 Share Posted February 22, 2013 [MENTION=5551]_Q_[/MENTION]I thought of something else....one of my best practices (or hard headed-ness )Verify any possible values returned by a function so in this case the "nil" return is not being evaluated and could cause an unhandled exception if you will.So to me the following is best:local nug = SpawnPrefab(Rfun())if not nug then print("Error: Unexpected 'nil' return from SpawnPrefab") return end Link to comment Share on other sites More sharing options...
Developer Bigfoot Posted February 22, 2013 Developer Share Posted February 22, 2013 [MENTION=10271]WrathOf[/MENTION] I had to speak to [MENTION=8]Kevin[/MENTION] about this.The prefab list is actually used as a build step to generate prefabs.xml. This is generated at compile time, not at run time, so adding prefabs to that list actually doesn't do anything. Basically it creates the dependencies to make sure the right prefabs are loaded prior to the game using them. If your game requires prefabs that have not yet been loaded, then you can explicitly call TheSim:LoadPrefabs() with a table that lists the prefabs you want to load. E.g. TheSim:LoadPrefabs({"twigs","spoiled_food"}). In this case all the items were already preloaded so we're good to go.Also I agree that crashing is a big part of making great mods Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now