. . . Posted July 14, 2017 Share Posted July 14, 2017 (edited) Hello, I have a question if someone can help me that'd really be awesome ! So, basically I'm trying to make npc players & I noticed that they take huge amount of damage from bosses just like how other entities like pigmen do & I was wondering if there's a way I can prevent that? I went through beequeen.lua which she deals 2x damage to entities that aren't players, but I couldn't really see anything like bonus damage or some special tag to exclude the bonus damage ..so I'm kinda stuck! Any help would be very nice, & thanks for reading my problem! Have a great day/night ! Edited July 17, 2017 by SuperDavid Link to comment Share on other sites More sharing options...
ZupaleX Posted July 14, 2017 Share Posted July 14, 2017 I advice you to look at combat.lua component. Everything is handled there. You could for instance override some of the functions in there to fit your needs Link to comment Share on other sites More sharing options...
. . . Posted July 14, 2017 Author Share Posted July 14, 2017 (edited) It seems it's in this function in combat.lua, the "playermultiplier" for npc attacking player. Though, when I add tag "player" to my npc the game crashes..I think that tag is specifically reserved for players only. That means I have to edit this to include my tag, but I don't know how to edit this function without copy-paste combat.lua for my mod which I think is bad way to do it .. Spoiler function Combat:CalcDamage(target, weapon, multiplier) if target:HasTag("alwaysblock") then return 0 end local basedamage local basemultiplier = self.damagemultiplier local bonus = self.damagebonus --not affected by multipliers local playermultiplier = target ~= nil and target:HasTag("player") local pvpmultiplier = playermultiplier and self.inst:HasTag("player") and self.pvp_damagemod or 1 --NOTE: playermultiplier is for damage towards players -- generally only applies for NPCs attacking players if weapon ~= nil then --No playermultiplier when using weapons basedamage = weapon.components.weapon.damage or 0 playermultiplier = 1 else basedamage = self.defaultdamage playermultiplier = playermultiplier and self.playerdamagepercent or 1 if self.inst.components.rider ~= nil and self.inst.components.rider:IsRiding() then local mount = self.inst.components.rider:GetMount() if mount ~= nil and mount.components.combat ~= nil then basedamage = mount.components.combat.defaultdamage basemultiplier = mount.components.combat.damagemultiplier bonus = mount.components.combat.damagebonus end local saddle = self.inst.components.rider:GetSaddle() if saddle ~= nil and saddle.components.saddler ~= nil then basedamage = basedamage + saddle.components.saddler:GetBonusDamage() end end end return basedamage * (basemultiplier or 1) * (multiplier or 1) * playermultiplier * pvpmultiplier + (bonus or 0) end Edited July 14, 2017 by SuperDavid Link to comment Share on other sites More sharing options...
ZupaleX Posted July 14, 2017 Share Posted July 14, 2017 Maybe you could modify something else instead for your npc? Like the Combat:GetAttacked function. At some point there the damages are calculated, maybe you could check who is the attacker and if it's a boss apply a reduction factor on the damages taken. There are several ways to do what you want to do, this is the first one which came to my mind, not saying it's the best. Link to comment Share on other sites More sharing options...
. . . Posted July 14, 2017 Author Share Posted July 14, 2017 I tried code like this, but my npc still takes the 2x damage before healing back half of it to make it like player damage. inst:ListenForEvent("attacked", function(inst, data) local damage = data.damage if data.attacker:HasTag("epic") then inst.components.health:DoDelta(data.damage * .5) end end) do you maybe know a way the better way to do this ? And sorry for bothering you so much, thanks for all your help man ! Link to comment Share on other sites More sharing options...
ZupaleX Posted July 15, 2017 Share Posted July 15, 2017 You could override the function I am mentioning directly instead of reacting to the event "attacked". Try to read and understand each of the lines in components/combat.lua function Combat:GetAttacked Could you post back which line deals with the damage the entity will receive? Link to comment Share on other sites More sharing options...
code4240 Posted July 15, 2017 Share Posted July 15, 2017 (edited) Give your NPC a unique tag. Then override the CalcDamage function in combat.lua the regular way you override functions ('m assuming you can do this, I haven't tested this) and add a check before calling the regular function that divides the damage by some value that cancels out the player multiplier if the mob has your NPCs unique tag. If you can't replace the function *at all* then I'm not sure what to do off the top of my head. EDIT: I've never edited a component but I'm guessing you'd use the normal trick where you copy the function and embed it into a new function oldCombatcalc = component.whateverfunction component.whateverfunction = function(arguments) --Do the division oldCombatCalc(arguments) end AddComponentPostInit(whatever) I've never used AddComponentPostInit so if this isn't how it would work for components then you'll have to look into that I guess. nvm, check second post Edited July 15, 2017 by code4240 Link to comment Share on other sites More sharing options...
code4240 Posted July 15, 2017 Share Posted July 15, 2017 (edited) Okay, I actually did it in game and this works. I made a really fast custom char with the tag "superspecial" and then did this in modmain: local function OverrideCombat(comp) local OldCombat = comp.CalcDamage comp.CalcDamage = function(self, target, weapon, multiplier) if target:HasTag("superspecial") then multiplier = 0 -- replace this part with the necessary number / calculation end return OldCombat(self, target, weapon, multiplier) end end AddComponentPostInit("combat", OverrideCombat) This made my character immune to damage. You'd replace the 0 with whatever you'd need to in order to cancel out the playermult. EDIT: I'm guessing you'd want to set multiplier to be equal to self.playerdamagepercent, as implied by this line: playermultiplier = playermultiplier and self.playerdamagepercent or 1 -which sets playermult to playerdamagepercent if it's true. However, I don't have a custom NPC to add this code to so I can't actually test this. Edited July 15, 2017 by code4240 Link to comment Share on other sites More sharing options...
. . . Posted July 16, 2017 Author Share Posted July 16, 2017 Thank you @code4240 your code works great, it halves the damage my entity take !! Thanks you because I'm not good at editing components or whatever this is xD.. If maybe you just know one thing is that do you know how I can make this code only work in halving damage from things with "epic" tag? Spoiler local function OverrideCombat(comp) local OldCombat = comp.CalcDamage comp.CalcDamage = function(self, target, weapon, multiplier) if target.prefab == "tieravil" then multiplier = .5 end return OldCombat(self, target, weapon, multiplier) end end AddComponentPostInit("combat", OverrideCombat) since I think only epic entities deal 2x damage to non-players, & thanks a lot your help !! Link to comment Share on other sites More sharing options...
code4240 Posted July 16, 2017 Share Posted July 16, 2017 Actually, my answer was wrong. It just occurred to me that multiplier stacks with playermultiplier so changing it would give inaccurate results if it was supposed to be not 1. So actually what you'll want to do is multiply the result of the old function by the value instead of changing the multiplier. Also, don't use 0.5, use playerdamagepercent. Changing this value is how mobs do different damage to players. I haven't looked but I'm assuming if you look at the files for the bosses such as deerclops you'll see them setting that value to 0.5 (probably using the setter function in combat.lua, though I'm too lazy to go look) which would mean that if the mob would do half damage to players then playerdamagepercent would be 0.5 like you want. Or any other value the mob might do to players. Link to comment Share on other sites More sharing options...
code4240 Posted July 16, 2017 Share Posted July 16, 2017 Quote Thanks you because I'm not good at editing components or whatever this is xD.. You'll wanna study the general technique I used because it's pretty important to modding pretty much anything in the game that isn't brand new content. Luckily it's pretty simple since prefabs and components actually aren't all that different. Basically there are a lot of "AddXPostInit" functions, like AddPrefabPostInit, AddComponentPostInit, AddBrainPostInit, etc. They all pretty much do the same thing, which is modify a prefab/component/etc. that you specify by tacking whatever function you write onto the end of the init function for that thing. Basically, you could pretend that whatever function you gave it (in our case we passed the OverrideCombat function we wrote) just got stuck inside the prefab on the very last line of the init, right before it returns at the end, and you have to figure out how you would modify the rest of the file only using that one function there. As for the part where you actually change the calc, we basically save a copy the function the component was using for calc to a variable, and then replace the calc in the component with a new function we wrote that calls the copy of the old function inside it to ensure the original code still gets called. This is the standard practice for replacing functions in Don't Starve because it allows mods to be compatible; if multiple mods modify the same function this way, it has a sort of nesting doll effect where each one wraps around the other and they all still get called. As opposed to just overriding the function entirely or the whole file, in which case any other modifications that had been made to that function / file before the new one got loaded would be wiped out. Prefabs are changed the same way, and prefabs can actually modify their individual copies of a component. So for example, you could go into the bearger file via AddPrefabPostInit and modify its copy of the combat component by setting the calc function to multiply the damage by 5,000 if it was your NPC. In this case, only the bearger would do 5,000x damage to your NPC and everyone else would be the same because only the copy of the combat component that belongs to the bearger gets modified, while when using AddComponentPostInit you'd be modifying the base file for the combat component and all the prefabs that later used combat would start out with those changes. This also applies to brains but those are a whole other can of worms in terms of how the code you're modifying is actually structured tbh. Link to comment Share on other sites More sharing options...
. . . Posted July 16, 2017 Author Share Posted July 16, 2017 Sorry, but I don't think I understood much of what you said I replace .5 with "playerdamagepercent" at multiplier? It seems to do no damage halving at all now..sorry I couldn't really understand what to do. Though, I don't wanna waste your time since this seems really complicated & stuff so I'm just gonna put a .5 health absorb on my followers, but thanks for your help man ! Link to comment Share on other sites More sharing options...
code4240 Posted July 16, 2017 Share Posted July 16, 2017 (edited) Quote Though, I don't wanna waste your time since this seems really complicated & stuff so I'm just gonna put a .5 health absorb on my followers, but thanks for your help man ! Oh no, this is actually pretty simple to me lol. The reason I wasn't more thorough is because I had to work last night. I realized my error in my first code while I was in the middle of my shift lol. And when I issued my correction was right before I went to bed so I didn't test anything. Anyway, I'm awake and not at work now so allow me to clarify on what I meant: local function OverrideCombat(comp) local OldCombat = comp.CalcDamage comp.CalcDamage = function(self, target, weapon, multiplier) local dmg = OldCombat(self, target, weapon, multiplier) if target:HasTag("superspecial") then print("------") print(dmg) if self.playerdamagepercent ~= nil then dmg = dmg * self.playerdamagepercent print(dmg) print(self.playerdamagepercent) -- print the modifier to see what you're multiplying by else print("1") -- If the value is nil then it's not multiplied end end return dmg end end I tested this and it works. Spoiler (You'll want to remove or comment the prints at some point) Edited July 16, 2017 by code4240 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