BLsquared Posted January 16, 2015 Share Posted January 16, 2015 Hello, all! I am BLsquared, the creator of the Shovel Knight character mod.In said, mod, I wish to disable his armor slot, as I will add in a new combat component for him to use that will essentially give him built-in armor. Seeing no previous example of either of these on neither this forum or in the game itself, I come to you for assistance. So, this boils down to two questions:1) How may I disable/remove the armor slot?2) How may I redirect him to use an alternate combat component of my choosing?Also, if it is any help, I have included version 0.12.4 of the mod.Thank you very much for your help,BLsquared.Shovel_Knight.zip Link to comment Share on other sites More sharing options...
Ubiquitous Posted January 16, 2015 Share Posted January 16, 2015 Hello, all! I am BLsquared, the creator of the Shovel Knight character mod.In said, mod, I wish to disable his armor slot, as I will add in a new combat component for him to use that will essentially give him built-in armor. Seeing no previous example of either of these on neither this forum or in the game itself, I come to you for assistance. So, this boils down to two questions:1) How may I disable/remove the armor slot?2) How may I redirect him to use an alternate combat component of my choosing?Also, if it is any help, I have included version 0.12.4 of the mod.Thank you very much for your help,BLsquared. Well gave it a try but still new to coding in the game. Got some code working but it isn't 100% as the image will remain in the equipped slot and but the item will not be there and it will be destroyed.local function OnArmorEquip(inst) -- The line will check to make sure worn item is an armor piece if EQUIPSLOTS.BODY ~= nil and inst.components.inventory:IsWearingArmor() then -- This line will remove the item from the armor slot inst.components.inventory:Unequip(EQUIPSLOTS.BODY) endend-- Place the following line in the master_postinit inst:ListenForEvent("equip", OnArmorEquip) Link to comment Share on other sites More sharing options...
BLsquared Posted January 16, 2015 Author Share Posted January 16, 2015 Well gave it a try but still new to coding in the game. Got some code working but it isn't 100% as the image will remain in the equipped slot and but the item will not be there and it will be destroyed.local function OnArmorEquip(inst) -- The line will check to make sure worn item is an armor piece if EQUIPSLOTS.BODY ~= nil and inst.components.inventory:IsWearingArmor() then -- This line will remove the item from the armor slot inst.components.inventory:Unequip(EQUIPSLOTS.BODY) endend-- Place the following line in the master_postinit inst:ListenForEvent("equip", OnArmorEquip)Thanks! I tried the above, and while it disables the armor, it prevents the user from taking out of the slot. I'll try to find a fix; thanks for getting the ball rolling! If anyone knows how to redirect him to use a different combat component, I'd love to know how. Link to comment Share on other sites More sharing options...
Ryuushu Posted January 16, 2015 Share Posted January 16, 2015 (edited) @BLsquaredFor the armor:Changed approach. Keep scrolling down.About the combat component, you could remove it and add your own custom combat component.. which will break everything horribly.Instead, modify the GetAttacked function (to reduce damage based on your own armor) and maybe the DoAttack function (in case you want to do something crazy with the shovel), like so: -- For flat reduction inst.armorlevel = 30 local old_GetAttacked = inst.components.combat.GetAttacked inst.components.combat.GetAttacked = function(self,attacker, damage, weapon) damage = damage - self.inst.armorlevel return old_GetAttacked(self,attacker, damage, weapon) end -- For % reduction (modify this value on something like a LevelUp function) inst.components.health.absorb = .1 Edited February 2, 2015 by Ryuushu Link to comment Share on other sites More sharing options...
BLsquared Posted January 16, 2015 Author Share Posted January 16, 2015 @BLsquaredFor the armor:local function IsChestArmor(item) if item.components.armor and item.components.equippable.equipslot == GLOBAL.EQUIPSLOTS.BODY then return true else return false endend local old_ACTIONEQUIP = GLOBAL.ACTIONS.EQUIP.fnGLOBAL.ACTIONS.EQUIP.fn = function(act) if act.doer.prefab == "shovelknight" then local item = act.invobject if item and IsChestArmor(item) then act.doer.components.talker:Say("My mighty armor is mightier.") return false -- Or return true? If he says "I can't do that" then return true. else return old_ACTIONEQUIP(act) end else return old_ACTIONEQUIP(act) endendAbout the combat component, you could remove it and add your own custom combat component.. which will break everything horribly.Instead, modify the GetAttacked function (to reduce damage based on your own armor) and maybe the DoAttack function (in case you want to do something crazy with the shovel), like so: -- For flat reduction inst.armorlevel = 30 local old_GetAttacked = inst.components.combat.GetAttacked inst.components.combat.GetAttacked = function(self,attacker, damage, weapon) damage = damage - self.inst.armorlevel return old_GetAttacked(self,attacker, damage, weapon) end -- For % reduction (modify this value on something like a LevelUp function) inst.components.health.absorb = .1Whoa. Thanks! I was really having trouble figuring that out on my own there...glad to see you offer your expertise!Quick question, though: putting the armor code into his prefab results in a "variable GLOBAL not declared" error. I'm assuming I placed it wrong. Where exactly does that code go? Link to comment Share on other sites More sharing options...
Ryuushu Posted January 16, 2015 Share Posted January 16, 2015 (edited) @BLsquared It goes into modmain. The variable GLOBAL doesn't exists in your prefab since it's already inside the global enviroment. From what I understand, modmain doesn't runs inside the global env, so you need to specify it when you want to use global functions like SpawnPrefab or constants like TUNING. Edited January 16, 2015 by Ryuushu Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 @BLsquaredIt goes into modmain. The variable GLOBAL doesn't exists in your prefab since it's already inside the global enviroment.From what I understand, modmain doesn't runs inside the global env, so you need to specify it when you want to use global functions like SpawnPrefab or constants like TUNING.Thanks again. Just two problems:While equipping from right-clicking get's the "Armor is mightier" message, picking it up or dragging it into the slot does not, and it is equipped as normal. Why is this?Also, turns out the OnAttack modifier does not go in either the prefab or the modmain. I am confused about this as well. Link to comment Share on other sites More sharing options...
Ryuushu Posted January 17, 2015 Share Posted January 17, 2015 (edited) @BLsquaredThat.. was actually good.local function IsChestArmor(item) if item.components.armor and item.components.equippable.equipslot == EQUIPSLOTS.BODY then return true else return false end end local old_Equip = inst.components.inventory.Equip inst.components.inventory.Equip = function(self, item, old_to_active) if IsChestArmor(item) then self.inst.components.talker:Say("My mighty armor is mightier") return false end return old_Equip(self, item, old_to_active) endThis new approach looks cleaner. This time it goes inside your character's prefab file. It should resolve the drag-and-drop issue. Delete the old code that modified the action, it's no longer needed.Uh, what do you mean by OnAttack modifier? Edited January 17, 2015 by Ryuushu Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 @BLsquaredThat.. was actually good.local function IsChestArmor(item) if item.components.armor and item.components.equippable.equipslot == EQUIPSLOTS.BODY then return true else return false end end local old_Equip = inst.components.inventory.Equip inst.components.inventory.Equip = function(self, item, old_to_active) if IsChestArmor(item) then self.inst.components.talker:Say("My mighty armor is mightier") return false end return old_Equip(self, item, old_to_active) endThis new approach looks cleaner. This time it goes inside your character's prefab file. It should resolve the drag-and-drop issue. Delete the old code that modified the action, it's no longer needed.Uh, what do you mean by OnAttack modifier? I'll try that...By Attack Modifier, I mean the code for redirecting the Get_Attacked. For defense. Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 Also, new error: Says inst is undefined. I would assume this is due to the new function being initialized outside of a function where it is defined? Link to comment Share on other sites More sharing options...
Ryuushu Posted January 17, 2015 Share Posted January 17, 2015 @BLsquared Are you sure you're putting it inside your master_postint function? Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 @BLsquaredAre you sure you're putting it inside your master_postint function?....Whoops. Thank you. I was not. Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 Thanks so much for the help!The only issue per say is him being unable to pick up armor, but that's fine. Not like he can use them anyways. Link to comment Share on other sites More sharing options...
Ryuushu Posted January 17, 2015 Share Posted January 17, 2015 @BLsquaredAh, that's because when you pickup armor without having anything equipped it'll try to autoequip.. and it'll fail in this case.So, we just need to modify the pickup function like so:local old_ACTIONPICKUP = GLOBAL.ACTIONS.PICKUP.fnGLOBAL.ACTIONS.PICKUP.fn = function(act) if act.doer.prefab == "shovelknight and act.target and act.target.components.equippable and act.target.components.inventoryitem and act.target.components.armor and not act.target:IsInLimbo() then act.doer.components.inventory:GiveItem(act.target, nil, act.target:GetPosition()) return true else return old_ACTIONPICKUP(act) endendWith this we're telling the function "If my character is trying to pickup something and if it's an armor instead being autoequipped it should go to his inventory". Link to comment Share on other sites More sharing options...
BLsquared Posted January 17, 2015 Author Share Posted January 17, 2015 @BLsquaredAh, that's because when you pickup armor without having anything equipped it'll try to autoequip.. and it'll fail in this case.So, we just need to modify the pickup function like so:local old_ACTIONPICKUP = GLOBAL.ACTIONS.PICKUP.fnGLOBAL.ACTIONS.PICKUP.fn = function(act) if act.doer.prefab == "shovelknight and act.target and act.target.components.equippable and act.target.components.inventoryitem and act.target.components.armor and not act.target:IsInLimbo() then act.doer.components.inventory:GiveItem(act.target, nil, act.target:GetPosition()) return true else return old_ACTIONPICKUP(act) endendWith this we're telling the function "If my character is trying to pickup something and if it's an armor instead being autoequipped it should go to his inventory".Right! Thank you so much, I was unable to figure this out myslef. I found the function in the Inventory component, but was unable to get it to, well, "function". Again, thank you. Link to comment Share on other sites More sharing options...
Noggle Posted January 18, 2015 Share Posted January 18, 2015 Hello there! The thing you have requested is eerily close to what I am looking for. I am currently wracking my brain to no avail as I am not good at the coding side of things here yet. If I wanted to try and modify this to instead of not allowing you to equip armor, to instead block items from being equipped to hands, what would I be looking to change? I have a character who I am working on who is not supposed to be able to use any item other than his hands (Which is an actual item itself, unless attributes such as chop,dig,mine can be applied to the character directly, which I have had no success with so far) Link to comment Share on other sites More sharing options...
rezecib Posted January 18, 2015 Share Posted January 18, 2015 (edited) @Noggle, You can use the code here, but instead of IsChestArmor(item), use something like this:item.components.equippable.equipslot == EQUIPSLOTS.HANDSEdit: As for being able to punch things, you probably want to add a new action that applies "work" to things with a "workable" component. Edited January 18, 2015 by rezecib 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