Closed HimeWorks closed 10 years ago
I was going to create a plugin for your script later on when I needed weapons to matter. But my current project has skills learned via body parts (equipment) thus I skip most of the common expectations of weapon elements making any difference.
I forgot to mention that I scrapped Element-Ex for your script last week... It was much less of a headache keeping things straight. I plan on expanding it later.
I'm sure its obvious, but I figure I'll mention a few immediate examples.
I'd assume that any skill that uses normal attack elements would simply assume the weapons elements. Otherwise I can see it being simple, or more complex.
Get the damage total divide it by the number of element sources, and apply each sources element split to its fraction of the total.
Create arrays for each source, sum them, and divide by the source count.
Elements: 0=Phys, 1=Fire, 2=Ice, 3=Shock
Skill [50,50,0,0] = 100
Weapon [0,50,50,0] = 100
#---------------------------
Total [50,100,50,0] = 200
[50,100,50,0] * 0.5
Result [25,50,25,0]
Skill [25,50,0,25]
Weapon [0,50,50,0]
#---------------------------
Total [25,100,50,25]
[25,100,50,25] * 0.5
Result [12.5,50,25,12.5]
This assumes that each additional source totals an additional 100%.
The complex version results in the same total value, per element, but it allows for further manipulation of each element with adjustments from equipment. Such as +50% Fire Damage [12.5,50,25,12.5] = [12.5,75,25,12.5], etc...
Its likely that I have missed something though. I am not good at imagining numbers.
Hmm I think I get what you mean. I would implement it as such.
First, I take my note-tag and extend it to all feature objects. That is, I extend "attack element rate" to all objects. As discussed before, the default element rate feature is in fact the elemental resistance rate, so 80% fire element rate means you only take 80% fire damage.
Therefore, to avoid confusion, I will say attack element rate
to specifically mean the percentage of the damage that is of a particular element type.
My skill has a "normal" element atk which means it pulls its atk elements from actor features. My weapon has attack element rates 30% fire and 70% physical. Therefore, atk element rate is simply 30% and 70% as usual.
Let's make things more complicated with different atk element rates. Now suppose I am dual-wielding, and I'm attacking an enemy that is immune to physical damage.
Suppose my first weapon does 30% fire and 70% physical, and inflicts 100 base damage Suppose my second weapon does 80% fire and 20% physical, and inflicts 100 base damage.
Based on elemental immunity, the first weapon should only deal 30 damage, and the second weapon should deal 80 damage, for a total of 110 damage.
So you add the rates together and divide them by 2. Fire: (30% + 80%) / 2 gives you 55% Physical: (70% + 20%) / 2 gives you 45%
Doing the math, your total damage is supposed to be 200: 55% of it is fire, which gives 110, and 45% of it is physical, which gives 90.
The enemy would resist 90 damage as expected, leaving you a total of 110 fire damage. I am kind of curious why adding it up and dividing it by the number of sources actually works but both of our examples show that the math adds up.
I wonder if there's something missing...
Let's say you had a guy that naturally emits fire, and everything he touches is fire elemental. You would note-tag the actor with an atk element rate of 100% fire. This means that EVERY skill he uses that has "normal" element type, will deal 100% fire damage.
The "atk element" feature would basically be replaced with my custom "atk element rate" data.
Sound good to me. I am thinking the only reason that the numbers work out is that we are working with (100% * sources) / sources. If one of the sources came out to more than 100% it would wreck the numbers a bit. (I am guessing)
This would then require any bonuses to be applied after factoring the totals for each element. It may also require them to be a new note-tag.
It definitely works with rates that are equal or less than 100%
If one weapon does 50% fire damage, and another weapon does 50% fire damage, then you expect the total fire rate to be 50% as well, because it's impossible that your final fire damage is greater than 50%.
If two weapons deal 100% fire damage, you expect your damage to be 100% fire damage.
If one weapon does 100% fire damage, and another weapon does 200% fire damage...now there is an issue. Because what does it even mean to deal 200% fire damage? For me it is difficult to reason with a concrete example what that means.
I assumed the only issue would be totals above 100% for a source. :)
Right now the original script assumes that a total of more than 100% is a form of damage bonus. Though its moot considering that the skill itself is giving itself the bonus. Thus any update should consider a solution for desired bonuses granted by items. I gave such an example in my first feedback above.
I'm looking at your updated script and I want to make sure that's your final solution?
No plans to support bonus element damage?
No plans to allow for equip elements to mix with skill/item elements? (Other than the normal
selection)
Not sure how bonus element damage would be specified. If you specify that a skill is "Fire" type, under what circumstances should equip element rates mix with it?
Oh, here's a simple example: Fire Ring that increases all fire-elemental damage by 20%.
element_rate
is the resistance rate, so we can't put it there.
The current logic doesn't provide any room for adding bonuses either. I would need to provide some abstraction for calculating the "atk element rate".
When you note-tag a weapon with <attack element: fire 0.5>
, that means you do 50% fire damage.
This is the "base" attack element rate. I would then provide a method that allows you to operate on this value, so you can create your own scripts that will increase the element rate.
I would just add the skills element assignment to the equipment based mix used for normal attack
element. But add a note tag with the option to override equipment assignments in mass or individually. (In the case of a special exclusive skill)
Example: If a 'Fire Ball' skill has 100% Fire Damage, and the caster is wearing a special Ice Wand that grants <attack element: ice 1.0>
then the skill would have 50% Fire and 50% Ice. However if the 'Fire Ball' skill had normal attack
element, then it would do 100% Ice damage from the wand, and without the wand it would do Physical or any other type... Defeating the idea of a 'Fire Ball'.
If the dev wanted the Fire Ball to be element exclusive, a <element exclusive>
tag (or some such) would keep it only reacting to FIRE damage adjustments (or element splits assigned only to the skill).
Thus an <element adjust: fire +0.5>
would make the 'Fire Ball' equivalent to 150% damage, with only fire element.
If I end up writing a plugin I would separate every element into an array and then recombine after adjustments.
Then the fireball skill should just be Fire element.
Exactly. Without any mixing with gear supplied elements. I thought we where looking for ways to mix skill elements assignments with gear/state assignments.
In the default mechanics the most effective of all available elements is used to apply the damage. In our solution to mix elements we have actually broken the ability for someone to 'add' an element to their attack during battle. (Unless the skill uses normal attack
element.)
In the default mechanics the most effective of all available elements is used to apply the damage.
That only applies to the normal
attack element, which is what the "normal attack element" update does.
If you specify None element then it ignores elemental modifiers. If you specify a particular element, then it uses that.
I don't see a reason to mix skills with equips or other things. My fire ring example shows how bonuses could be applied to a fire-type skill or a normal-type skill that inherits fire elemental attacks, but those are separate bonuses and is not "mixing" skill elements with equip elements.
Damn, I hadn't noticed. I stand corrected. ;)
I suppose you're done then? (With updating your script)
Still have to provide some logic for those bonuses, since the current calculation provides no way to include them.
It will be an internal change for the most part, where I added a method or two to compute the "final" element rates, which is basically taking the base rate (specified by the skill or other stuff) and adds bonuses to it.
I had always worked towards what I described without considering that skill element assignment was the immutable part of the formula.
When you are done I think I'll shift my plugin towards a gear focused exception. So if an item is flagged then it infiltrates, or overrides a skills assignments conditionally.
I think your last update expanding the role of equipment on normal element attacks, broke state element rate application somehow. I didn't have time to test exactly how, but reverting to your previous version fixed the problem...
"State element rate application"?
Any States, element rate application. They don't factor in the results anymore.
Normal: item_element_rate
#--------------------------------------------------------------------------
# * Get Element Modifier for Skill/Item
#--------------------------------------------------------------------------
def item_element_rate(user, item)
if item.damage.element_id < 0
user.atk_elements.empty? ? 1.0 : elements_max_rate(user.atk_elements)
else
element_rate(item.damage.element_id)
end
end
New: item_element_rate
alias :th_attack_atk_element_modifiers_item_element_rate :item_element_rate
def item_element_rate(user, item)
if item.damage.element_id < 0
normal_atk_element_modifiers(user, item)
else
# Check if it uses multiple elements
if item.atk_element_modifiers.empty?
return th_attack_atk_element_modifiers_item_element_rate(user, item)
else
return item_multi_element_rate(user, item)
end
end
end
Where are self
's element rates collected and applied for normal element
skills?
Maybe I am misunderstanding something, but a defenders element rates only seem to be correctly factored in skills (not splitting their elements) that have an explicit element assignment in their item.damage.element_id
I don't know why I have so much trouble visualizing code past the first few steps of abstraction but the way you reference element type names as keys and total a value has thrown me for a loop and I can't seem to figure it out.
Maybe I am just losing my patience...
Every time I think I am done coding another fucking quirk in the mechanics tosses me back into it, and my brain has trouble toggling from code to content in between sleep cycles.
/grumble
I am pretty sure that the issue is the way that normal_atk_element_modifiers
only processes the targets element_rate
for elements it finds in the note tags. Thus no note tags makes normal_atk_element_modifiers
return 1
all the time. Skipping the targets element rates.
If the item has a defined item.damage.element_id
with no note tags then the default item_element_rate
is used without issue.
I have not gotten to item_multi_element_rate
...
Actors, classes, weapons, armors, states, and enemies are called feature objects
, and there is a method defined in Game_BattlerBase
called feature_objects
that returns an array of all these things.
normal_atk_element_modifiers
returns the final elemental multiplier for a "normal" element,
def normal_atk_element_modifiers(user, item)
count = 0
rates = {}
user.feature_objects.each do |obj| # <---------
next if obj.atk_element_modifiers.empty?
count += 1
obj.atk_element_modifiers.each do |id, val|
rates[id] ||= 0
rates[id] += val
end
end
return 1 if rates.empty?
return rates.inject(0) do |r, (id, val)|
r + element_rate(id) / count * val
end
end
I don't begrudge you your assumption that I am the one that's wrong whenever you don't immediately grasp what I am trying to explain, because I have made some pretty stupid mistakes.
Though it would often help a lot more if you where less cryptic in your responses when I make them. And a bit less quick to assume that I have made another.
You can start by trying to keep in mind that this is all really new to me and sometimes I simply don't know how best to explain what I find. And when I do, its ALMOST ALWAYS after I have already spent some time FAILING at figuring out how to fix it myself. Thus I am impatient and often very frustrated while I type it up.
For that I apologize.
...
I tried to point out that the SELF element rates are not being applied to the element rates found on the USERS feature objects, because your loop SKIPS any feature object that doesn't have a note tag, and then returns 1
when the rates are empty as a result.
def normal_atk_element_modifiers(user, item)
count = 0
rates = {}
user.feature_objects.each do |obj|
next if obj.atk_element_modifiers.empty? #<------- THIS
count += 1
obj.atk_element_modifiers.each do |id, val|
rates[id] ||= 0
rates[id] += val
end
end
return 1 if rates.empty? #<------- AND THIS
return rates.inject(0) do |r, (id, val)|
r + element_rate(id) / count * val #<------- ENDS UP SKIPING THIS, when a normal element attack has no (atk_element_modifiers) note tags.
end
end
I really hope I am not wrong because if I am, I am going to feel really stupid.
I don't mean to be a pain, and I know that you don't have to do what you do here. You have always been rather quick with helping when I needed it and I don't want to give you the impression that I am ungrateful. I realize that I can be real thick headed and argumentative when I think I know something and even worse when I just spent the better part of a day (or more) beating my head against the wall on something that seems to be simple, and probably should be, but for some reason I just can't see it.
So when you answer my questions with questions, or give me an answer I didn't ask for (even if its the right one, and I just don't know it) I might bite your head off or get rude without thinking.
I hope you don't hold that against me. Because believe me when I say that you have been the ONLY reason I have managed to get as far as I have and I have nothing but appreciation and heart felt thanks. My personality flaws just sometimes get the best of me.
So you're saying if my enemy has a 50% fire element rate (eg: takes half damage from fire) and I have a skill with normal element, but none of my objects have an atk element rate, then the modifier is not calculated correctly because I don't take into consideration the target's elemental resistance?
I'm not sure why the target's element rates are relevant when the user has no atk element rates. It is just assumed to be a null element attack, which means there is no elemental modifier.
I never said that the user had no element rates. I said the user had no note tags. The user has normally assigned element rates. (in this case the PHYSICAL element is assigned to an enemy and the class of the target) But the skill has normal attack
and because there are no note tags associated with the element assignment (in the enemy object), its never checked against the targets element rates.
And you are up late. :)
What is the atk element rate supposed to be if you just use the atk element feature?
I always assumed that unless you are dividing it up, you are still using the feature assignment because that's how it worked before you updated the normal attack
factoring. I would think that I'm not the only one that would assume that, without it spelled out in big neon letters.
However, if you wanted to support feature element assignments on top of note tags, I wouldn't think it to unreasonable to assume that multiple element features on the same object are split divisions factored into the total with other feature object splits, as the script currently does.
It shouldn't mess anything up, and note tags would always be checked for first. Thus like it functions now, if note tags exist then those are the only thing checked.
Is there any reason why you need the atk element feature instead of just using atk element rate note-tags, which basically does the same thing except
No reason besides legacy support.
You are big on not breaking default function so I made an assumption that default feature assignment still worked. Like it did before the update.
If you would prefer not to support it then I big disclaimer indicating that this breaks normal feature assigned elements for non-skills might help avoid the same confusion from others.
The decision was made based on that some things are simply not worth providing backwards compatibility for, especially if it doesn't do things very well in the first place.
A consistent note-tag is more important than being able to piggyback on something that sort of tried to accomplish something.
I guess a disclaimer would be more clear than not mentioning it at all.
http://www.himeworks.com/2014/01/03/attack-element-modifiers/
This script basically assumes elements are based on the item's elements and doesn't take into consider features.
So if you had a weapon that had a fire attribute, and the skill was a "normal" element (which means it uses the elements defined by features), it isn't applied.
The problem is that while a skill can say it does 50% fire and 50% physical, how do you say that a weapon does 50% fire and 50% physical? What if you generalize it to an arbitrary number of features?