Brainy Posted July 9, 2014 Share Posted July 9, 2014 I'm working on a modification that adds to the game an instrument that can summon hounds. However, I don't know which scripts should I use to gain control over the amount of dogs. I was able to get the effect of summon, but number of hounds that appears is completely random and uncontrolled. Typically, the instrument summons a dozen or twenty/twenty-five dogs, but it also happens that the number is so large that it even causes disruptions in the game mechanics. I put screenshots and prefab file into this post. I hope that someone will be able to help, because as a beginner I may not be able to solve this problem by myself. PREFAB: local assets={Asset("ANIM", "anim/bone_flute.zip"),Asset("ATLAS", "images/inventoryimages/bone_flute.xml"),Asset("IMAGE", "images/inventoryimages/bone_flute.tex"),}local prefabs ={"hound","icehound","yellowhound","firehound"}local function onfinished(inst)inst:Remove()endlocal function HearBoneFlute(inst, musician, instrument)local pt = Vector3(GetPlayer().Transform:GetWorldPosition())local spawn_pt = GetSpawnPoint(pt)if spawn_pt thenlocal prefab = "hound"local special_hound_chance = GetSpecialHoundChance()if math.random() < special_hound_chance thenif GetSeasonManager():IsWinter() or GetSeasonManager():IsSpring() thenprefab = "icehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsSummer() thenprefab = "firehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsAutumn() thenprefab = "yellowhound"endendlocal hound = SpawnPrefab(prefab)if hound thenhound.Physics:Teleport(spawn_pt:Get())hound:FacePoint(pt)return houndendendendfunction GetSpecialHoundChance()local day = GetClock():GetNumCycles()local chance = 0for k,v in ipairs(TUNING.HOUND_SPECIAL_CHANCE) doif day > v.minday thenchance = v.chanceelseif day <= v.minday thenreturn chanceendendreturn chanceendfunction GetSpawnPoint(pt)local theta = math.random() * 2 * PIlocal radius = (30)local offset = FindWalkableOffset(pt, theta, radius, 5, true)if offset thenlocal pos = pt + offsetreturn pt+offsetendendlocal function fn(Sim)local inst = CreateEntity()inst.entity:AddTransform()inst.entity:AddAnimState()inst:AddTag("flute")inst.AnimState:SetBank("pan_flute")inst.AnimState:SetBuild("bone_flute")inst.AnimState:PlayAnimation("idle")MakeInventoryPhysics(inst)inst:AddComponent("inspectable")inst:AddComponent("instrument")inst.components.instrument:SetOnHeardFn(HearBoneFlute)inst:AddComponent("tool")inst.components.tool:SetAction(ACTIONS.PLAY)inst:AddComponent("finiteuses")inst.components.finiteuses:SetMaxUses(3)inst.components.finiteuses:SetUses(3)inst.components.finiteuses:SetOnFinished( onfinished)inst.components.finiteuses:SetConsumption(ACTIONS.PLAY, 1)inst:AddComponent("inventoryitem")inst.components.inventoryitem.atlasname = "images/inventoryimages/bone_flute.xml"return instendreturn Prefab( "common/inventory/bone_flute", fn, assets) Link to comment Share on other sites More sharing options...
Heavenfall Posted July 9, 2014 Share Posted July 9, 2014 Can I just say "LOL"? Link to comment Share on other sites More sharing options...
Battal Posted July 9, 2014 Share Posted July 9, 2014 o.o Link to comment Share on other sites More sharing options...
Mobbstar Posted July 9, 2014 Share Posted July 9, 2014 you should release the mod just like that! Link to comment Share on other sites More sharing options...
spencer320 Posted July 9, 2014 Share Posted July 9, 2014 Hell yeah!Call it Hardcore Hounds! In the description of the mod write adds a few hounds since you thought they were so easy! Link to comment Share on other sites More sharing options...
Brainy Posted July 9, 2014 Author Share Posted July 9, 2014 All these hounds won't have any chance to beat dragonfly after all. He will smash them with single area attack.Also if you use BushHat after using Bone Flute, Hounds won't attack you and also I added special Hat that make you hound's friend. But the game is super slow when they appear in such quantity. That's too much after all. Link to comment Share on other sites More sharing options...
BoundTheHound Posted July 9, 2014 Share Posted July 9, 2014 HOLY COW! The screenshot with the dragonfly look's epic! Link to comment Share on other sites More sharing options...
Brainy Posted July 9, 2014 Author Share Posted July 9, 2014 But I was able to do it only with GodModeMod. I'm still working on it and there is small progress. Now I'm using this code: local numhounds = 1 but it seems that "1" means "22" for hounds oO Link to comment Share on other sites More sharing options...
Rincevvind Posted July 9, 2014 Share Posted July 9, 2014 but there no "numhounds" variable in your code Link to comment Share on other sites More sharing options...
Brainy Posted July 9, 2014 Author Share Posted July 9, 2014 It's better with this code: local function HearBoneFlute(inst, musician, instrument)local pt = Vector3(musician.Transform:GetWorldPosition())local numhounds = 1musician:StartThread(function()for k = 1, numhounds dolocal theta = math.random() * 2 * PIlocal radius = math.random(3, 8)-- we have to special case this one because birds can't land on creeplocal result_offset = FindValidPositionByFan(theta, radius, 12, function(offset)local x,y,z = (pt + offset):Get()local ents = TheSim:FindEntities(x,y,z , 1)return not next(ents)end)if result_offset thenlocal hound = SpawnPrefab("hound")endendend)return trueend But still twenty and even more hounds appear. Link to comment Share on other sites More sharing options...
JackSlender Posted July 9, 2014 Share Posted July 9, 2014 First off, I believe the instrument code is the wrong code for you. The instrument code will search the range that you set for entities. Not a specific type of entity, just entities. It will then proceed to execute the onheard command for every single entity within the range. In other words, one hound is being spawned per entity in the assigned range, which is a lot especially when you remember that an entity is pretty much any object in the world. The default range is not too big (15), but when you play it multiple times in a row, it will get catastrophic because it will effectively double the amount of hounds it spawns every time. I would suggest making a new component that sends the player to the same state as the horn does, but you can set the function that will be executed whenever you play it. I hope this helps you solve your problem. If it doesn't, feel free to ask and I'd be happy to help some more. Link to comment Share on other sites More sharing options...
Don1 Posted July 10, 2014 Share Posted July 10, 2014 You should release it like that and fix the problem when you get the chance Link to comment Share on other sites More sharing options...
Brainy Posted July 10, 2014 Author Share Posted July 10, 2014 First off, I believe the instrument code is the wrong code for you. The instrument code will search the range that you set for entities. Not a specific type of entity, just entities. It will then proceed to execute the onheard command for every single entity within the range. In other words, one hound is being spawned per entity in the assigned range, which is a lot especially when you remember that an entity is pretty much any object in the world. The default range is not too big (15), but when you play it multiple times in a row, it will get catastrophic because it will effectively double the amount of hounds it spawns every time. I would suggest making a new component that sends the player to the same state as the horn does, but you can set the function that will be executed whenever you play it. I hope this helps you solve your problem. If it doesn't, feel free to ask and I'd be happy to help some more. This is a good clue. Now I'm using this component: inst:AddComponent("useableitem")inst.components.useableitem:SetCanInteractFn( CanSummon )inst.components.useableitem:SetOnUseFn( SummonHounds ) Now I have control over the number of dogs, but the object that summons them is inexhaustible. Although I try to give durability to it, it still doesn't disappear. I'm using this: inst:AddComponent("finiteuses")inst.components.finiteuses:SetMaxUses(1)inst.components.finiteuses:SetUses(1)inst.components.finiteuses:SetOnFinished(OnFinished) and this: local function OnFinished(inst)inst:Remove()end but unsuccessfully. Link to comment Share on other sites More sharing options...
JackSlender Posted July 10, 2014 Share Posted July 10, 2014 In your SummonHounds function, just put this line of code: inst.components.finiteuses:Use(1) That will deduct 1 point from the object's durability. If you want to do it the proper way (I guess we can call it that), add this line of code below where you define finiteuses in the fn function: inst.components.finiteuses:SetConsumption(ACTIONS.USEITEM, 1) That line will make it so it consumes 1 from the durability of the item whenever you use the USEITEM action on it.Hope this helps you! Link to comment Share on other sites More sharing options...
Brainy Posted July 10, 2014 Author Share Posted July 10, 2014 In your SummonHounds function, just put this line of code: inst.components.finiteuses:Use(1) That will deduct 1 point from the object's durability. If you want to do it the proper way (I guess we can call it that), add this line of code below where you define finiteuses in the fn function: inst.components.finiteuses:SetConsumption(ACTIONS.USEITEM, 1) That line will make it so it consumes 1 from the durability of the item whenever you use the USEITEM action on it.Hope this helps you! I've tried that already. I also added to function "SummonHounds" those codes: holder:RemoveItem(inst) or inst:Remove() but this won't work too. I think I'll make something like Maxwell Journal. It will be infinite but will need to use an object from your inventory. Link to comment Share on other sites More sharing options...
JackSlender Posted July 10, 2014 Share Posted July 10, 2014 Have you tried the SetConsumption yet? That's what the horn uses. If that doesn't work, can you try posting your prefab file again? Thanks. Link to comment Share on other sites More sharing options...
Brainy Posted July 10, 2014 Author Share Posted July 10, 2014 Currently it looks like this: local assets ={Asset("ANIM", "anim/hound_salve.zip"),Asset("ATLAS", "images/inventoryimages/hound_salve.xml"),Asset("IMAGE", "images/inventoryimages/hound_salve.tex"),}local function CanSummon(inst)local owner = inst.components.inventoryitem and inst.components.inventoryitem.ownerif owner then return true endendlocal function SummonHounds(inst)local pt = Vector3(GetPlayer().Transform:GetWorldPosition())local spawn_pt = GetSpawnPoint(pt)if spawn_pt thenlocal prefab = "hound"local special_hound_chance = GetSpecialHoundChance()if math.random() < special_hound_chance thenif GetSeasonManager():IsWinter() or GetSeasonManager():IsSpring() thenprefab = "icehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsSummer() thenprefab = "firehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsAutumn() thenprefab = "yellowhound"endendlocal hound = SpawnPrefab(prefab)if hound thenhound.Physics:Teleport(spawn_pt:Get())hound:FacePoint(pt)return houndendendOnFinishedendfunction GetSpecialHoundChance()local day = GetClock():GetNumCycles()local chance = 0for k,v in ipairs(TUNING.HOUND_SPECIAL_CHANCE) doif day > v.minday thenchance = v.chanceelseif day <= v.minday thenreturn chanceendendreturn chanceendfunction GetSpawnPoint(pt)local theta = math.random() * 2 * PIlocal radius = (10)local offset = FindWalkableOffset(pt, theta, radius, 5, true)if offset thenlocal pos = pt + offsetreturn pt+offsetendendlocal function OnFinished(inst)inst:Remove()endlocal function fn(Sim)local inst = CreateEntity()inst.entity:AddTransform()inst.entity:AddAnimState()MakeInventoryPhysics(inst)inst.AnimState:SetBank("spider_gland_salve")inst.AnimState:SetBuild("hound_salve")inst.AnimState:PlayAnimation("idle")inst:AddComponent("inspectable")inst:AddComponent("inventoryitem")inst.components.inventoryitem.atlasname = "images/inventoryimages/hound_salve.xml"inst:AddComponent("finiteuses")inst.components.finiteuses:SetMaxUses(1)inst.components.finiteuses:SetUses(1)inst.components.finiteuses:SetOnFinished(OnFinished)inst:AddComponent("useableitem")inst.components.useableitem:SetCanInteractFn( CanSummon )inst.components.useableitem:SetOnUseFn( SummonHounds )return instendreturn Prefab( "common/inventory/hound_salve", fn, assets) But when I try to do this just like Maxwell Journal it alway crashed when I try to add special hound chance. Now it looks like this: local assets ={Asset("ANIM", "anim/book_maxwell.zip"),Asset("ATLAS", "images/inventoryimages/hound_book.xml"),Asset("IMAGE", "images/inventoryimages/hound_book.tex"),}local function canread(inst)return (inst.components.sanity:GetMaxSanity() >= TUNING.SHADOWWAXWELL_SANITY_PENALTY)endlocal function onread(inst, reader)--Check sanityif not canread(reader) thenif reader.components.talker thenreader.components.talker:Say(GetString(reader.prefab, "ANNOUNCE_NOSANITY"))return trueendend--Check reagentif not reader.components.inventory:Has("nightmarefuel", TUNING.SHADOWWAXWELL_FUEL_COST) thenif reader.components.talker thenreader.components.talker:Say(GetString(reader.prefab, "ANNOUNCE_NOFUEL"))return trueendendreader.components.inventory:ConsumeByName("nightmarefuel", TUNING.SHADOWWAXWELL_FUEL_COST)--Ok you had everything. Make the image.local theta = math.random() * 2 * PIlocal pt = inst:GetPosition()local radius = math.random(3, 6)local offset = FindWalkableOffset(pt, theta, radius, 12, true)local numhounds = 5reader:StartThread(function()for k = 1, numhounds dolocal theta = math.random() * 2 * PIlocal radius = math.random(3, 8)local prefab = "hound"local result_offset = FindValidPositionByFan(theta, radius, 12, function(offset)local x,y,z = (pt + offset):Get()local ents = TheSim:FindEntities(x,y,z , 1)return not next(ents)end)if result_offset thenlocal hound = SpawnPrefab("prefab")hound.Transform:SetPosition((pt + result_offset):Get())endlocal special_hound_chance = GetSpecialHoundChance()if math.random() < special_hound_chance thenif GetSeasonManager():IsWinter() or GetSeasonManager():IsSpring() thenprefab = "icehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsSummer() thenprefab = "firehound"endendif math.random() < special_hound_chance thenif GetSeasonManager():IsAutumn() thenprefab = "yellowhound"endendlocal hound = SpawnPrefab(prefab)if hound thenhound.Physics:Teleport(spawn_pt:Get())hound:FacePoint(pt)return houndendendend)return trueendfunction GetSpecialHoundChance()local day = GetClock():GetNumCycles()local chance = 0for k,v in ipairs(TUNING.HOUND_SPECIAL_CHANCE) doif day > v.minday thenchance = v.chanceelseif day <= v.minday thenreturn chanceendendreturn chanceendlocal function fn()local inst = CreateEntity()local trans = inst.entity:AddTransform()local anim = inst.entity:AddAnimState()local sound = inst.entity:AddSoundEmitter()anim:SetBank("book_maxwell")anim:SetBuild("hound_book")anim:PlayAnimation("idle")MakeInventoryPhysics(inst)inst:AddComponent("inventoryitem")-----------------------------------inst:AddComponent("inspectable")inst:AddComponent("book")inst.components.book.onread = onreadinst:AddComponent("inventoryitem")inst.components.inventoryitem.atlasname = "images/inventoryimages/hound_book.xml"MakeSmallBurnable(inst)MakeSmallPropagator(inst)return instendreturn Prefab("common/hound_book", fn, assets) Link to comment Share on other sites More sharing options...
JackSlender Posted July 10, 2014 Share Posted July 10, 2014 Have you tried using SetConsumption? Link to comment Share on other sites More sharing options...
Brainy Posted July 10, 2014 Author Share Posted July 10, 2014 Yes. Also it's strange that character doesn't perform any animation when using this item. Link to comment Share on other sites More sharing options...
JackSlender Posted July 10, 2014 Share Posted July 10, 2014 It isn't supposed to play the animation. It you want it to, you need to send the player to a different stategraph state. I did manage to get your code working (if you want to do it just using the inst:Remove() in the summonhounds function). The problem was your return statement at the end of that function. It isn't supposed to return anything. Try it after removing the return statement and see if it gives you trouble. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.