Blackcloud 1 Posted December 1, 2020 Hello, I am using a certain enemy type in my game which is "hardened". There I want to make sure if an enemy has the state "hardened" that it only gets 1 dmg per attack or skill (unless we use a special skill for hardened enemy which can do normal dmg). My first Idea was a common event with a condition "Enemy state "hardened" -> second condition "Which skill is used" -> if normal attack or skill -> force action for a 1 HP hit, else -> normal dmg skill is used. Therefore I need the information on which skill is being used, is there a script command or any other idea how I can implement that? I am fiddling around with that for a while now and can't come to a proper solution. If you need any further explanation let me know, I might don't have the perfect way to describe it yet. Share this post Link to post Share on other sites
PhoenixSoul 1,304 Posted December 1, 2020 Let me see...I think this can all be done in the damage formula. I don't know if the syntax is one hundred percent correct, but... b.state_id[x] ? [1, 1].min : (skill damage formula goes here) Explanation: The first bit is checking if b.state_id[x] is true, and if so, returns the result [1, 1].min; if false, returns whatever the formula for the skill would normally return. [1, 1].min is a trick to making sure that the damage dealt is equal to 1, no more and no less because it returns the minimum of the two values (.min). It's a good way to emulate flash RPG weapons like those from Adventure Quest and the like that have that silly, 8 - 8 weapon damage range. Now, for the part that involves the skill for hardened enemies, if you want it so that the skill does damage only to those enemies, the formula would look like this: b.state_id[x] ? (skill damage formula goes here) : [1, 1].min I might have the first part of the syntax incorrect; either @roninator2, @Rikifive, @Seriel, @Kayzee, @Coolie or someone else who is better at RGSS than I am can be of further aid in case I don't have this correct. I'm mainly going by what I recall without using any guides here. Hope it helps, hope it works! Bonne chance. 1 Coolie reacted to this Share this post Link to post Share on other sites
roninator2 205 Posted December 2, 2020 Partly good. You still need to specify the damage for 1 at the end. and you can just say 1 in the formula. b.state?(X) ? dam = 1 : dam = full damage formula; dam or you could do and if statement if b.state?(X) then 1 else formula end It depends on how elaborate you have your formula. I also have used a kernel call I got from the forums. Kernel.eval($data_skills[ID of the skill that this is put in].note.scan(/<\s*formula\s*:\s*((\s|\S)+)>/)[0][0]) then in your note box you would put <formula: if b.state?(X) ; 1 ; else ; formula ; end> This lets you write out long damage formulas if they were to have multiple checks or cause states to be added, etc. Forcing a minimum, I have a script that does that, but the 1 should give 1 damage when evaluated true. 1 PhoenixSoul reacted to this Share this post Link to post Share on other sites
Rikifive 3,330 Posted December 2, 2020 6 hours ago, PhoenixSoul said: b.state_id[x] ? [1, 1].min : (skill damage formula goes here) Hmm... as far as the damage formula suggested above goes, I think, that b.state(ID) ? 1 : dmg_formula would be enough. That [1, 1].min part is interesting - intriguing is what you said, although .min returns the lowest value, so putting two the same values doesn't have any real usage and the actual output from there will be 1 as if it was typed like I suggested. I think I get your idea, but throwing [1, 1].min will not bypass damage variance, nor further modifications (crit, damage resistances etc.), so it still can return a value other than 1 in specific circumstances, if multipliers in total will exceed 100% (because I believe the dmg is rounded down, judging by the fact it uses .to_i at the end of calculations). Putting, for example, b.hp -= 1; 0 in the damage formula will always deal one point of damage, but it is rather a direct subtract than dealing actual damage. It will skip the further multipliers, but the battle system will most likely not register the "damage" and the hp will be subtracted silently without popups --- or the popups will say 0 / NULL, while actually subtracting that 1 HP (eventually killing). Aaaaaanyway, modifying damage formulas all over the place to support just one status effect is rather inconvenient I'd say. What I'd do is to adjust how the damage is calculated in the scripts themselves. For example, pasting the following right below materials; class Game_Battler < Game_BattlerBase #-------------------------------------------------------------------------- # * Calculate Damage #-------------------------------------------------------------------------- def make_damage_value(user, item) value = item.damage.eval(user, self, $game_variables) value *= item_element_rate(user, item) value *= pdr if item.physical? value *= mdr if item.magical? value *= rec if item.damage.recover? value = apply_critical(value) if @result.critical value = apply_variance(value, item.damage.variance) value = apply_guard(value) #------------------------------------------------ if item.damage.to_hp? && state?(29) && !item.note.include?("<penetrate>") value = [value, 1].min # min in case the initial damage would be 0 or sth end #------------------------------------------------ @result.make_damage(value.to_i, item) end end would add a check, that if the item/skill has damage type set as HP damage AND target has a state with ID:29 AND the used skill doesn't have <penetrate> in its note, the damage will be lowered to 1 (after all multipliers, so it should always be a solid 1 or lower, if initially the damage would be nulled/blocked or sth). So basically, if enemy would have a state with ID:29, ALL the damage he'd receive would be lowered to 1, UNLESS it would be hit with a skill, that would contain the <penetrate> tag in the notes, in which case it would normally deal damage from the formula. This of course could be modified further to support more circumstances and whatsoever. PS I did want to alias the method, but looks like aliasing methods doesn't pass local variables, so it wasn't possible to work with "value" anymore. Couldn't figure out how to get that to work from the top of my head. I might be missing something, it's been a rather long while now since I worked with Ruby/Ace. 2 PhoenixSoul and Blackcloud reacted to this Share this post Link to post Share on other sites
Blackcloud 1 Posted December 3, 2020 22 hours ago, Rikifive said: Hmm... as far as the damage formula suggested above goes, I think, that b.state(ID) ? 1 : dmg_formula would be enough. That [1, 1].min part is interesting - intriguing is what you said, although .min returns the lowest value, so putting two the same values doesn't have any real usage and the actual output from there will be 1 as if it was typed like I suggested. I think I get your idea, but throwing [1, 1].min will not bypass damage variance, nor further modifications (crit, damage resistances etc.), so it still can return a value other than 1 in specific circumstances, if multipliers in total will exceed 100% (because I believe the dmg is rounded down, judging by the fact it uses .to_i at the end of calculations). Putting, for example, b.hp -= 1; 0 in the damage formula will always deal one point of damage, but it is rather a direct subtract than dealing actual damage. It will skip the further multipliers, but the battle system will most likely not register the "damage" and the hp will be subtracted silently without popups --- or the popups will say 0 / NULL, while actually subtracting that 1 HP (eventually killing). Aaaaaanyway, modifying damage formulas all over the place to support just one status effect is rather inconvenient I'd say. What I'd do is to adjust how the damage is calculated in the scripts themselves. For example, pasting the following right below materials; class Game_Battler < Game_BattlerBase #-------------------------------------------------------------------------- # * Calculate Damage #-------------------------------------------------------------------------- def make_damage_value(user, item) value = item.damage.eval(user, self, $game_variables) value *= item_element_rate(user, item) value *= pdr if item.physical? value *= mdr if item.magical? value *= rec if item.damage.recover? value = apply_critical(value) if @result.critical value = apply_variance(value, item.damage.variance) value = apply_guard(value) #------------------------------------------------ if item.damage.to_hp? && state?(29) && !item.note.include?("<penetrate>") value = [value, 1].min # min in case the initial damage would be 0 or sth end #------------------------------------------------ @result.make_damage(value.to_i, item) end end would add a check, that if the item/skill has damage type set as HP damage AND target has a state with ID:29 AND the used skill doesn't have <penetrate> in its note, the damage will be lowered to 1 (after all multipliers, so it should always be a solid 1 or lower, if initially the damage would be nulled/blocked or sth). So basically, if enemy would have a state with ID:29, ALL the damage he'd receive would be lowered to 1, UNLESS it would be hit with a skill, that would contain the <penetrate> tag in the notes, in which case it would normally deal damage from the formula. This of course could be modified further to support more circumstances and whatsoever. PS I did want to alias the method, but looks like aliasing methods doesn't pass local variables, so it wasn't possible to work with "value" anymore. Couldn't figure out how to get that to work from the top of my head. I might be missing something, it's been a rather long while now since I worked with Ruby/Ace. That is exactly what I was trying to figure out, maybe was thinking way to complex for it, but I will give this a shot and will let you know if it works for me, thank you all for your opinions already, didn't expect it to be that fast :). Just one more thing, does this also count for normal attacks since they are never allowed to deal more than 1 dmg on an enemy with that state, not even with a critical? 1 Rikifive reacted to this Share this post Link to post Share on other sites
Rikifive 3,330 Posted December 3, 2020 30 minutes ago, Blackcloud said: That is exactly what I was trying to figure out, maybe was thinking way to complex for it, but I will give this a shot and will let you know if it works for me, thank you all for your opinions already, didn't expect it to be that fast :). Just one more thing, does this also count for normal attacks since they are never allowed to deal more than 1 dmg on an enemy with that state, not even with a critical? I did quick tests and it seemed to work, but yeah, check it out yourself as I tend to overlook things. You're welcome. c: If by normal attacks you mean the default attack, then yes, the default attack is actually just a skill from the database (the first one by default) and therefore it works like any other skill. If the default attack in database won't have the <penetrate> tag (you can rename the tag if you wish ofc) in notes, it will deal 1 damage to enemies with that state. And yes, the damage modification I've added is at the end of calculations, so even if the result is a critical and will have the damage multiplied, it will be set to solid 1 (or less) at the end if the conditions regarding the hardened state will be met. I'd also like to remind, to put that piece of code above any other 3rd party scripts that have anything to do with battles (putting right below materials would be okay), as I overwrote the default damage calculation method, which may result in incompatibilities with other scripts if put below them. 1 PhoenixSoul reacted to this Share this post Link to post Share on other sites
PhoenixSoul 1,304 Posted December 3, 2020 2 hours ago, Rikifive said: I'd also like to remind, to put that piece of code above any other 3rd party scripts that have anything to do with battles (putting right below materials would be okay), as I overwrote the default damage calculation method, which may result in incompatibilities with other scripts if put below them. Like Hime's Damage Processing Core Script, which is meant to be used before any other modifier scripts, as one large example. Share this post Link to post Share on other sites
Rikifive 3,330 Posted December 3, 2020 10 hours ago, PhoenixSoul said: Like Hime's Damage Processing Core Script, which is meant to be used before any other modifier scripts, as one large example. Hmm yeah; Then in this case my lil code won't be compatible with Hime's damage processing core script, regardless of their placement. These overwrite the same thing, so only one can be in-effect. (If anyone would be unaware / that wasn't obvious) 1 PhoenixSoul reacted to this Share this post Link to post Share on other sites
PhoenixSoul 1,304 Posted December 3, 2020 (edited) Attempting to make a compatibility scriptlet... I managed to figure out a compatibility scriptlet, but did not manage to bypass modifiers. Spoiler class Game_Battler < Game_BattlerBase def apply_element_modifiers(user, item, value) if item.note.include?("<onek>") value *= (item_element_rate(user, item) / item_element_rate(user, item)) else value *= item_element_rate(user, item) end return value end def apply_item_modifiers(user, item, value) value *= pdr if item.physical? value *= mdr if item.magical? value *= rec if item.damage.recover? return value if item.note.include?("<onek>") # value = [value, 1000].min value = [[1000, 1000].max].min # min in case the initial damage would be 0 or something end end end Edited December 9, 2020 by PhoenixSoul Share this post Link to post Share on other sites