FurryEskimo Posted October 28, 2020 Share Posted October 28, 2020 So I've written some code that summons a hound when an object is placed in the ground. I'm trying to assign a loyalty value to the hound, so it indefinitely follows the player who dropped the item. I've seen it done in other mods by making all trained hounds have a default follow value of a million towards the closest player, but that's not really what I'm trying to do. Preferably there's a way for the summoning code to tell who dropped it and assign the loyalty directly to the hound and add a tag the hound. Right now this code mostly works, but "inst.components.follower:AddLoyaltyTime(999999)" breaks, since inst isn't the hound, but the dropped item. Does anyone know how to reference the spawned entity? local function SpawnHound(inst) local x, y, z = inst.Transform:GetWorldPosition() SpawnPrefab("collapse_big").Transform:SetPosition(x, y, z) inst:Remove() SpawnPrefab("Hound").Transform:SetPosition(x, y, z) -- SpawnPrefab("small_puff").Transform:SetPosition(x, y, z) print("Checking for player") local player = FindClosestPlayerToInst(inst, 50, "player") print("Player found?") if player ~= nil then print("Setting Loyalty") player.components.leader:AddFollower(inst) inst.components.follower:AddLoyaltyTime(999999) --Error is here. end end Link to comment Share on other sites More sharing options...
Thomas Die Posted October 28, 2020 Share Posted October 28, 2020 (edited) local function UwU (inst) local owner = FindEntity(inst,20,function(guy) return guy ~= nil and not guy.components.health:IsDead()end ,{"Insert_Tag"}) -->saves the player to add as "leader" local hound = SpawnPrefab("hound") -->saves the follower to be if owner ~= nil then hound.Transform:SetPosition(inst.Transform:GetWorldPosition()) if hound.components.follower.leader ~= leader then owner.components.leader:AddFollower(hound) end hound.components.follower:AddLoyaltyTime(TUNING.HOUNDWHISTLE_EFFECTIVE_TIME + math.random()) --change to whatever if hound.components.combat ~= nil and hound.components.combat:TargetIs(owner) then hound.components.combat:SetTarget(nil) end -->This was from the hound whistle but is still useful just incase the leader becomes target by accident end end inst.components.inventoryitem:SetOnDroppedFn(UwU) ↑ this is the code i wiped up if you're editing an existing prefab you can use an event listener ""ondropped"" is what the event is called I don't think you can identify the original host unless you wanna go through the lucy code inventory items remove their original owner when dropped you can "fix" this by replacing the function for it with your own function:inst._OnDropped = inst.components.inventoryitem.OnDropped inst.components.inventoryitem.OnDropped = function (variable,variable) --code code code code end bt dubs this is from the hound whistle codeExample Local Entity = SpawnPrefab("Prefab_name") --You use this as you would use inst but use the name given --e.g Entity.components.health:DoDelta(-1) -->Effects the one you saved as a variable inst.components.health:DoDelta(-1) -->effects the host Edited October 28, 2020 by thomas4846 Didn't read props Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 28, 2020 Author Share Posted October 28, 2020 @thomas4846 That code looks like it will work, thanks! I’ll test it soon. Your code is very similar to most I’ve seen used, but I have no idea what ‘function(guy)’ does, so I was avoiding it. Where is the function written? It’s referenced in multiple places, but I haven’t actually found it yet. Link to comment Share on other sites More sharing options...
Thomas Die Posted October 28, 2020 Share Posted October 28, 2020 (edited) function FindEntity(inst, radius, fn, musttags, canttags, mustoneoftags) -->one of the variables up here is "fn" that i use --"fn" is the function that we give if inst ~= nil and inst:IsValid() then local x, y, z = inst.Transform:GetWorldPosition() local ents = TheSim:FindEntities(x, y, z, radius, musttags, canttags, mustoneoftags) for i, v in ipairs(ents) do if v ~= inst and v.entity:IsVisible() and (fn == nil or fn(v, inst)) then -->here it gives "v" and "inst", "v" is the mob found return v --guy in the function is simply a renamed v end end end end Find Entity uses: inst --> host mob , radius --> how far it reaches , fn --> function checking validity , musttags --> tags needed , the other two i don't know ( canttags , mustoneoftags )Function or fn Checks if there is a additional task needed example: FindEntity(inst, 20, function(guy) --guy or v return guy ~= nil and not guy.components.health:IsDead() -- if the entity is not dead or is not nil it'll work end , {"Insert_Tag"}) if you don't understand or i could've put it in a better format please tell me Edited October 28, 2020 by thomas4846 Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 28, 2020 Author Share Posted October 28, 2020 @thomas4846 Still having trouble making the hounds permanently loyal. I'm trying to work in a periodic task to these special hounds that will reset their loyalty every few seconds, but so far it hasn't been working. The loyalty variables are local I think, and may be harder to edit than I expected, idk yet. Weird thing though,, For some reason my hound whistle has become super effective.. Two hounds get max loyalty (which I've set to 2.5 days or 1200 units), the next gets about half that, and the remaining two get 4%, which is the correct amount, aka around 60 seconds. Link to comment Share on other sites More sharing options...
Thomas Die Posted October 28, 2020 Share Posted October 28, 2020 i don't think you can have them as permanent followers unless you wanna create your own mob because ya Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 28, 2020 Author Share Posted October 28, 2020 @thomas4846 Oh, I’ve already rewritten the code that controls the hound’s maximum loyalty time once or twice. My hounds have a max loyalty of 2.5 days, but the hound whistle acts kinda funny for some reason now. I could probably rewrite the loyalty countdown too, but I’d prefer not to. I think there’s a way to just add more and more loyalty time every few seconds, just haven’t figured it out, yet. There are so many variables and objects all related to followers it’s a little overwhelming. Mostly this all works fine, but the hound whistle training for the wrong amount of time is super confusing. I have no idea why it does it sometimes. It’s supposed to just add a little time to each hound, with a bit of randomness. Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 28, 2020 Author Share Posted October 28, 2020 (edited) @thomas4846 Edit: There was an update and the hound whistle is working again. Haha, good thing, I was going crazy trying to figure out what I'd mixed up. Edit 2: Nvm, it's back to being weird... I got the infinite loyalty working, but this whistle and normally training these dogs is acting super weird.. Look at this: [00:01:32]: Increased MaxFollowTime assigned. [00:01:32]: Hound Loyalty Per Hunger [00:01:32]: 19.2 [00:01:32]: Total Day Time [00:01:32]: 480 [00:01:32]: Food Item's Hunger Value [00:01:32]: 12.5 [00:01:32]: Assigned Loyalty Time [00:01:32]: 240 [00:01:32]: Hound Loyalty MaxTime [00:01:32]: 1200 [00:01:32]: Loyalty Percent [00:01:32]: 1 [00:01:32]: End For some reason I'm correctly increasing the MaxFollowTime, and the loyalty to food ratios, determining the value of the food offered to the hound, everything,,, but the loyalty percent still returns the wrong value for some reason for the first few hounds trained. This is going to take some time to figure out,,, Edited October 29, 2020 by FurryEskimo Link to comment Share on other sites More sharing options...
Thomas Die Posted October 29, 2020 Share Posted October 29, 2020 can you poste the hound file here for me too look at in the morning Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 29, 2020 Author Share Posted October 29, 2020 (edited) @thomas4846 Sure. Here's the mod's unlisted beta on Steam: https://steamcommunity.com/sharedfiles/filedetails/?id=2238207705 And I've attached the key files. ModMain Has most of the hound code, just scroll all the way to the bottom. The collar code is also here, but it's hard to tell where and why this issue is occurring. Although there's a lot of code, I only edit loyalty values in like,, three places in the entire mod, when I assign food loyalty values/assign the value to a hound, when I edit the MaxFollowTime, and when I spawn in a hound using the collar and make them have unlimited loyalty. modmain.lua kokocollar.lua Edited October 29, 2020 by FurryEskimo Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 29, 2020 Author Share Posted October 29, 2020 @thomas4846 Code seems to be working now. I commented out some stray code I thought wasn't doing anything. It was just some leftover code from the first code I had to train hounds. -- local follower = inst.components.follower --Note: Redundant and outdated? -- follower.maxfollowtime = HOUND_LOYALTY_MAXTIME --Test code. Note: Redundant and outdated? Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 30, 2020 Author Share Posted October 30, 2020 @thomas4846 Figured you might know what's up with this tiny, weird issue. I made it so when the game is saved, these 'Forever Hound Followers' will despawn, and in their place drop their summoning item. It's the only way for me to make them not turn into wild hounds when the game is saved/edited. For some reason the spawn item code is causing an error, but if I post it elsewhere it works just time. local function OnStopFollowing(inst) inst:RemoveTag("companion") --Removes bonuses given to trained hounds. inst:RemoveTag("notraptrigger") inst.components.health:StopRegen() inst.components.follower.keepdeadleader = false if inst:HasTag("ForeverFriend") then --ForeverFriend followers drop summoning item when game is exited, but not if the follower dies. print("Forever Friend Stopped Following.") print("Spawning Collar.") local x, y, z = inst.Transform:GetWorldPosition() -- SpawnPrefab("collapse_big").Transform:SetPosition(x, y, z) SpawnPrefab("kokocollar").Transform:SetPosition(x, y, z) --Note: Error occurs here. print("Killing Forever Friend.") inst.components.health:kill() -- inst.remove end end Seems to me like it doesn't recognize 'SpawnPrefab' for some reason: [00:02:13]: [string "../mods/workshop-2238207705/modmain.lua"]:1845: attempt to call global 'SpawnPrefab' (a nil value) LUA ERROR stack traceback: I'm looking for another way for this to work, but I'm not sure why this would be an issue in the first place. modmain.lua Link to comment Share on other sites More sharing options...
Thomas Die Posted October 30, 2020 Share Posted October 30, 2020 GLOBAL.SpawnPrefab and you should be done, sory i wasn't on yesterday i wanted to game really bad Link to comment Share on other sites More sharing options...
FurryEskimo Posted October 31, 2020 Author Share Posted October 31, 2020 @thomas4846 Huh, I thought I'd already tried that. It's working now. I moved on to spawning a range of hounds, and all work as expected, except the clay hounds. Fixed that issue. I then tried giving these special, super hounds flaming eyes but got the code so wrong somehow, haha. I think I made the hound eyes, also be hounds,, so it just spawned with more hounds on top of it, haha. inst._eyeflames = net_bool(inst.GUID, "clayhound._eyeflames", "eyeflamesdirty") --Test code. inst:ListenForEvent("eyeflamesdirty", OnEyeFlamesDirty) This isn't really necessary, and I don't understand it yet. I thought it was just going to turn on the eyes or something. Link to comment Share on other sites More sharing options...
Thomas Die Posted October 31, 2020 Share Posted October 31, 2020 God sorry i barely have an idea how net_variables work Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 1, 2020 Author Share Posted November 1, 2020 @thomas4846 It's fine, it's new to me too. I was just trying to do something to distinguish these trained hounds from the wild ones. If I knew how I could trying making a new design and making it appear over the original, buuuuut, that's not something I know how to do. I figured glowing eyes would be easy and effective. Technically I could just make all trained hounds convert into clay hounds, since those will almost never be relevant, but they look out of place most of the time. Link to comment Share on other sites More sharing options...
Thomas Die Posted November 1, 2020 Share Posted November 1, 2020 If you want you can create a small child prefab to show it's yours Like an icon above the mob Link to comment Share on other sites More sharing options...
Thomas Die Posted November 1, 2020 Share Posted November 1, 2020 damn just realised that the hound actually uses this if inst.eyefxl == nil then inst.eyefxl = SpawnPrefab("eyeflame") inst.eyefxl.entity:SetParent(inst.entity) --prevent 1st frame sleep on clients inst.eyefxl.entity:AddFollower() inst.eyefxl.Follower:FollowSymbol(inst.GUID, "hound_eye_left", 0, 0, 0) end if inst.eyefxr == nil then inst.eyefxr = SpawnPrefab("eyeflame") inst.eyefxr.entity:SetParent(inst.entity) --prevent 1st frame sleep on clients inst.eyefxr.entity:AddFollower() inst.eyefxr.Follower:FollowSymbol(inst.GUID, "hound_eye_right", 0, 0, 0) end --This is from the hound code (maybe change the names of "eyefxr" and "eyefxl" to something else this should basically do the same thing dw you don't have to add a inst.eyefxr = nil or anything Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 1, 2020 Author Share Posted November 1, 2020 @thomas4846 I noticed that code, and tried adapting it, but botched it. I’ve tried doing these visual edits a few times but have gotten it wrong every time. From what I can tell they’re making an effect appear and follow the eyes’ positions. Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 4, 2020 Author Share Posted November 4, 2020 @thomas4846@thomas4846 Figured I'd ask here first, just incase you knew. This is code I found elsewhere, and I'm just trying to make sense of it, for a small edit I'm making. If the modded character is wearing no pants, their feet should be hidden, and if they are wearing pants, the feet appear. Sounds simple, but I'm still figuring this out. Do I just need to use "self.animstate:OverrideSymbol("foot", "furryeskimo", "foot")" or is it more complicated than that? -- Skins fix: --Test code. local SkinsPuppet = require("widgets/skinspuppet") local CLOTHING = GLOBAL.CLOTHING local _oldSetSkins = SkinsPuppet.SetSkins function SkinsPuppet:SetSkins(prefabname, base_skin, clothing_names, skip_change_emote) if prefabname ~= nil and prefabname ~= "furryeskimo" then self.animstate:ClearOverrideSymbol("foot") self.animstate:ClearOverrideSymbol("swap_body") self.animstate:ClearOverrideSymbol("swap_body_tall") self.animstate:ClearOverrideSymbol("torso") self.enable_idle_emotes = false self.play_non_idle_emotes = false end if prefabname ~= nil and prefabname == "furryeskimo" and (clothing_names == nil or clothing_names["legs"] == nil) then self.animstate:ClearOverrideSymbol("foot") self.animstate:ClearOverrideSymbol("torso") self.enable_idle_emotes = true self.play_non_idle_emotes = true end _oldSetSkins(self, prefabname, base_skin, clothing_names, skip_change_emote) if prefabname ~= nil and prefabname == "furryeskimo" then self.animstate:Hide("swap_body_tall") if clothing_names ~= nil then local overrideslegs = false local overridesfeet = false local overridestorso = false local overridespelvis = false if clothing_names["legs"] ~= nil then for k,v in pairs (CLOTHING[clothing_names.legs].symbol_overrides) do if v == "leg" then overrideslegs = true end if v == "foot" then overridesfeet = true end if v == "torso" then overridestorso = true end if v == "torso_pelvis" then overridespelvis = true end end end if clothing_names["body"] ~= nil then for k,v in pairs (CLOTHING[clothing_names.body].symbol_overrides) do if v == "leg" then overrideslegs = true end if v == "foot" then overridesfeet = true end if v == "torso" then overridestorso = true end if v == "torso_pelvis" then overridespelvis = true end end end if overrideslegs and not overridesfeet and clothing_names["feet"] == nil then self.animstate:OverrideSymbol("foot", "furryeskimo", "foot") end if not overridestorso and overridespelvis then self.animstate:OverrideSymbol("torso", "furryeskimo", "torso_skin") end end end end Link to comment Share on other sites More sharing options...
Thomas Die Posted November 4, 2020 Share Posted November 4, 2020 That should work fine i think Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 4, 2020 Author Share Posted November 4, 2020 (edited) @thomas4846 I thought so too, I just dropped it in to see what would happen, but nothing happened. The temp-feet just appear all the time. Edit: From what I can tell, the code is running, but it's making my torso disappear for some reason, and the print("") code doesn't work, which is weird, and going to make this much harder! Maybe the print code will work if I use a wardrobe instead of the player select screen. Edited November 4, 2020 by FurryEskimo Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 4, 2020 Author Share Posted November 4, 2020 (edited) @thomas4846 Well, I kinda figured it out, but it's,,,,, weird... Weirder than usual.. I've told it to make the feet invisible if I'm not wearing pants, and it's good! The correct feet display, even when wearing skirts. But...... When the character is actually displayed and you're playing, the feet that were previously invisible are now visible.. I have no idea why the game has the correct display when selecting the character and trying on outfits, then displays the wrong thing once you're playing.. -- Skins fix: --Test code. local SkinsPuppet = require("widgets/skinspuppet") local CLOTHING = GLOBAL.CLOTHING local _oldSetSkins = SkinsPuppet.SetSkins function SkinsPuppet:SetSkins(prefabname, base_skin, clothing_names, skip_change_emote) if prefabname ~= nil and prefabname ~= "furryeskimo" then self.animstate:ClearOverrideSymbol("foot") self.animstate:ClearOverrideSymbol("swap_body") self.animstate:ClearOverrideSymbol("swap_body_tall") self.animstate:ClearOverrideSymbol("torso") self.enable_idle_emotes = false self.play_non_idle_emotes = false end if prefabname ~= nil and prefabname == "furryeskimo" and (clothing_names == nil or clothing_names["legs"] == nil) then self.animstate:ClearOverrideSymbol("foot") self.animstate:ClearOverrideSymbol("torso") self.enable_idle_emotes = true self.play_non_idle_emotes = true end _oldSetSkins(self, prefabname, base_skin, clothing_names, skip_change_emote) if prefabname ~= nil and prefabname == "furryeskimo" then self.animstate:Hide("swap_body_tall") if clothing_names ~= nil then local overrideslegs = false local overridesfeet = false local overridestorso = false local overridespelvis = false if clothing_names["legs"] ~= nil then for k,v in pairs (CLOTHING[clothing_names.legs].symbol_overrides) do if v == "leg" then overrideslegs = true end end end if not overrideslegs then -- and not overridesfeet and clothing_names["feet"] == nil then self.animstate:OverrideSymbol("foot", "furryeskimo", "foot_skin") end end end end Edited November 4, 2020 by FurryEskimo 1 Link to comment Share on other sites More sharing options...
Thomas Die Posted November 5, 2020 Share Posted November 5, 2020 I'm legimately confused but yeah as long as it's working Link to comment Share on other sites More sharing options...
FurryEskimo Posted November 5, 2020 Author Share Posted November 5, 2020 (edited) @thomas4846 It’s only half working though. It displays correctly when looking at the character on the select screen, or when using a dresser, but when playing the feet display incorrectly. Edit: I suspect that the character’s skin is being defined and displayed based on some kind of, different code, hence why all my print commands aren’t showing up in the server log. It’s weird though.. Somehow I need to tell the game to update the character’s appearance, I think. I found some code I thought would do that, but instead my whole game went weird and the map reset and crashed. I reset the code and things went back to normal, but the code didn’t work. I think there’s a ‘skinner’ command somewhere, but haven’t found it yet. Edited November 5, 2020 by FurryEskimo 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