Not_Wilson Posted March 5, 2017 Share Posted March 5, 2017 I'm making a parasite monster that will latch to the player and it doesn't live long but is there a way to "seal" the equip, or prevent the player from unequipping the parasite until the player dies or the parasite does, whichever comes first? I didn't see any functions like this in the components "armor", "equippable" or "inventory", so I'm assuming that a function will be needed to seal the inventory slot and another function to listen for "equipping" the parasite. Can I get some help? Link to comment Share on other sites More sharing options...
Not_Wilson Posted March 5, 2017 Author Share Posted March 5, 2017 Nevermind. I decided to hide the inventory instead. We'll see how it goes! Link to comment Share on other sites More sharing options...
CarlZalph Posted March 5, 2017 Share Posted March 5, 2017 @DextersComicLaboratory I took a look, and inventory handling is pretty spaghetti'd all over. This is what I came up with that stops slurpers from getting removed: local function HostAndParasiteAreAlive(host, parasite) return host and host.components.health and not host.components.health:IsDead() and parasite.components.health and not host.components.health:IsDead() end AddComponentPostInit( "inventory", function(inst) if not GLOBAL.TheWorld.ismastersim then return end local Unequip_old = inst.Unequip inst.Unequip = function(self, equipslot, slip, ...) if equipslot == GLOBAL.EQUIPSLOTS.HEAD then local current_head = self.equipslots[GLOBAL.EQUIPSLOTS.HEAD] if current_head and current_head.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, current_head) then return nil end end end return Unequip_old(self, equipslot, slip, ...) end local Equip_old = inst.Equip inst.Equip = function(self, item, old_to_active, ...) if item and item.components.equippable and item.components.equippable.equipslot == GLOBAL.EQUIPSLOTS.HEAD then local current_head = self.equipslots[GLOBAL.EQUIPSLOTS.HEAD] if current_head and current_head.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, current_head) then return nil end end end return Equip_old(self, item, old_to_active, ...) end local DropItem_old = inst.DropItem inst.DropItem = function(self, item, wholestack, randomdir, pos, ...) if item and item.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, item) then return nil end end return DropItem_old(self, item, wholestack, randomdir, pos, ...) end end ) Note that this doesn't do anything to the client's end, and so you'll need to stop the client from predicting that they can manually put a hat in the inventory slot. Right now it'll show for a bit that the hat was placed, then 'magically' reappear in the active item slot once the server and client resync. Also note that if the slurper somehow magically loses all of its health, then the world will push that the thing died and won't fire the unequip callback, so the sounds remain. You may need to do some special handling for 'killing' the parasite instead of relying on the health component. Link to comment Share on other sites More sharing options...
Not_Wilson Posted March 5, 2017 Author Share Posted March 5, 2017 Oooh, on second thought, let me try it! Link to comment Share on other sites More sharing options...
Not_Wilson Posted March 5, 2017 Author Share Posted March 5, 2017 21 minutes ago, CarlZalph said: @DextersComicLaboratory I took a look, and inventory handling is pretty spaghetti'd all over. This is what I came up with that stops slurpers from getting removed: local function HostAndParasiteAreAlive(host, parasite) return host and host.components.health and not host.components.health:IsDead() and parasite.components.health and not host.components.health:IsDead() end AddComponentPostInit( "inventory", function(inst) if not GLOBAL.TheWorld.ismastersim then return end local Unequip_old = inst.Unequip inst.Unequip = function(self, equipslot, slip, ...) if equipslot == GLOBAL.EQUIPSLOTS.HEAD then local current_head = self.equipslots[GLOBAL.EQUIPSLOTS.HEAD] if current_head and current_head.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, current_head) then return nil end end end return Unequip_old(self, equipslot, slip, ...) end local Equip_old = inst.Equip inst.Equip = function(self, item, old_to_active, ...) if item and item.components.equippable and item.components.equippable.equipslot == GLOBAL.EQUIPSLOTS.HEAD then local current_head = self.equipslots[GLOBAL.EQUIPSLOTS.HEAD] if current_head and current_head.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, current_head) then return nil end end end return Equip_old(self, item, old_to_active, ...) end local DropItem_old = inst.DropItem inst.DropItem = function(self, item, wholestack, randomdir, pos, ...) if item and item.prefab == "slurper" then if HostAndParasiteAreAlive(inst.inst, item) then return nil end end return DropItem_old(self, item, wholestack, randomdir, pos, ...) end end ) Note that this doesn't do anything to the client's end, and so you'll need to stop the client from predicting that they can manually put a hat in the inventory slot. Right now it'll show for a bit that the hat was placed, then 'magically' reappear in the active item slot once the server and client resync. Also note that if the slurper somehow magically loses all of its health, then the world will push that the thing died and won't fire the unequip callback, so the sounds remain. You may need to do some special handling for 'killing' the parasite instead of relying on the health component. This is definitely an awesome code. Thing is right now if I use an item prefab (The player chooses to let this thing take their character), it'll dupe itself into the inventory and can't be dropped because said prefab is on their head. What should I do then? Link to comment Share on other sites More sharing options...
CarlZalph Posted March 5, 2017 Share Posted March 5, 2017 2 hours ago, DextersComicLaboratory said: This is definitely an awesome code. Thing is right now if I use an item prefab (The player chooses to let this thing take their character), it'll dupe itself into the inventory and can't be dropped because said prefab is on their head. What should I do then? AddComponentPostInit( "inventory", function(inst) if not GLOBAL.TheWorld.ismastersim then return end local function Check_1(slot, current_head) return slot == GLOBAL.EQUIPSLOTS.HEAD end local function Check_2(item, current_head) return item == current_head end local function Check_3(item, current_head) return item and item.components.equippable and item.components.equippable.equipslot == GLOBAL.EQUIPSLOTS.HEAD end local function Hook_This(checkfn, fn) local fn_old = inst[fn] inst[fn] = function(self, slotORitem, ...) local current_head = self.equipslots[GLOBAL.EQUIPSLOTS.HEAD] if current_head and current_head.prefab == "footballhat" and checkfn(slotORitem, current_head) then local host = inst.inst --local parasite = current_head if ( host and host.components.health and not host.components.health:IsDead() -- and parasite.components.health and not parasite.components.health:IsDead() ) then return nil end end return fn_old(self, slotORitem, ...) end end Hook_This(Check_1, "SelectActiveItemFromEquipSlot") Hook_This(Check_1, "CombineActiveStackWithSlot") Hook_This(Check_1, "SelectActiveItemFromSlot") Hook_This(Check_1, "ReturnActiveItem") Hook_This(Check_1, "Unequip") Hook_This(Check_2, "DropItem") Hook_This(Check_2, "GiveActiveItem") Hook_This(Check_2, "GiveItem") Hook_This(Check_2, "RemoveItem") Hook_This(Check_2, "SetActiveItem") Hook_This(Check_3, "Equip") end ) Same issue with that prediction thing with the mouse clickin' as before. Link to comment Share on other sites More sharing options...
Not_Wilson Posted March 5, 2017 Author Share Posted March 5, 2017 It works perfectly! Thanks my dude! 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