PDA

View Full Version : Need Help With Calculator Formula

Alsark
08-28-2008, 03:27 AM
Alright, so I am making a kind of "calculator" to determine output damage value for a game called PoxNora. There is a complex formula to determine how much damage a unit will receive by subtracting the attacker's attack by the defender's defense and then... well, it's complicated. Anyway, it's nice to have some kind of calculator to do it for you, which is why I was trying to code one. I can get a basic formula working, like ATK+DMG+DEF=outputDMG, but I cannot get the actual formula working.

Ergo, the problem lies somewhere within this code specifically:

// clears field of default value

function clear_field(field) {

if (field.value==field.value) {

field.value=''

}

}

function Damage0(form)

form.result.value = if((parseInt(form.attack.value) - parseInt(form.defense.value))<1)
{
Math.round((parseInt(form.damage.value)) - (0.02 * (Math.abs(parseInt(form.attack.value) - parseInt(form.defense.value))) * (parseInt(form.damage.value)))
}
else
{
Math.round((parseInt(form.damage.value)) + (0.01 * (parseInt(form.attack.value) - parseInt(form.defense.value)) * (parseInt(form.damage.value)))
};

//-->

The entire code shouldn't be necessary, since the rest of the code works fine with basic formulas. It's just when I try that code, I get an error and it doesn't calculate a thing.

I have ZERO Javascript experience (so I am sure that this is a stupid question). Yes, I tried to research the answer myself, but came up blank.

The layout looks something like this: http://www.runescapehall.net/alsark/PoxNora/test.html

That is a sample formula I have (simple addition), but cannot get my more complex formula working.

rangana
08-28-2008, 05:18 AM
On the first look, the problem is that you miss to close Math.round():

Math.round((parseInt(form.damage.value)) - (0.02 * (Math.abs(parseInt(form.attack.value) - parseInt(form.defense.value))) * (parseInt(form.damage.value))))

Math.round((parseInt(form.damage.value)) + (0.01 * (parseInt(form.attack.value) - parseInt(form.defense.value)) * (parseInt(form.damage.value))))

Otherwise, I'm not certain what your problem is since I'm totally unaware about the formula you have and the expected output when a certain value is given.

Alsark
08-30-2008, 01:31 AM
Adding the parenthesis did not seem to help, unfortunately. Well, I originally created the formula using Excel, but it's difficult to explain. This is what it looks like in Excel:

=IF(B2<1,ROUND((\$A3)-(0.02*ABS(B2)*(\$A3)),0),ROUND((\$A3)+(0.01*(B2)*(\$A3)),0))

B2 is ATK-DEF.

So basically, if ATK-DEF is less than one, then take damage subtracted by .02 times the absolute value of ATK-DEF times damage. If ATK-DEF is greater than or equal to one, damage plus .01 times ATK-DEF times damage is the formula.

So if ATK-DEF is 0, then the output result will equal damage. If ATK-DEF is positive, the output result should be greater than the damage value (if at least about 4 points higher), or lower than the damage value (if at least about 4 points lower).

The field should clear as soon as you click in the field, and it should automatically calculate things as you type in numbers. With the above formula, however, the field does not clear and even if you type in numbers and press "calculate damage", not happens.

rangana
08-30-2008, 03:51 AM
Basing in your excel sheet formula and the scenario you've given, try to change your Damage0 function to:

function Damage0(form)
{
var atk=form.elements['attack'], // attack field
def=form.elements['defense'], //defense field
dmge=form.elements['damage'], // damage field
result=form.elements['result'], // result field
b2=Number(atk.value)-Number(def.value); // b2 as based on excel sheet
if(b2<1) // if b2 is less than 1
result.value=Math.round(Number(dmge.value)-(((0.02)*Math.abs(b2))*Number(dmge.value)));
else if(b2>1) // if b2 is greater than 1
result.value=Math.round(Number(dmge.value)+((0.01*b2)*Number(dmge.value)));
else // if b2 is NaN
result.value=0;
}

Comments attached to explain the script's flow.

Hope it helps.

Alsark
08-30-2008, 07:43 PM
That is amazing... works like a charm! That looks nothing like what I had, though, haha. So thanks for going above and beyond just fixing something, and basically doing it for me, lol. That had to have taken a bit of time, so thanks! :) Sorry, I've never coded before, so I had no idea what I was doing.

I included this at the top of the source code (and in the calculator template thing):
<!-- Special thanks to rangana of codingforums.com for helping me code the formula -->

If, for whatever reason, you'd prefer not to have your name mentioned, let me know and I'll take it off.

This is the end result: www.runescapehall.net/alsark/PoxNora/Damage&#37;20Calculator.html

:Edit: There is one small thing I thought of after the fact. This was something I had forgot to put in my Excel sheet, too. "Attack" should only be allowed to increase "damage" up to a maximum of 40% for the result value. "Defense" should only be allowed to decrease "damage" up to a maximum of 80% for the result value. I'm not sure how I'd add this, unfortunately.

This is taken directly from the game, so maybe it can explain things better than I:

Attack
When this Champion attacks another champion, the damage is increased by 1% per point that its ATK is greater than that unit's DEF, to a maximum of 40%.

Defense
When this champion takes damage, the damage is reduced by 2% per point in DEF, to a maximum of 80%. If that damage comes from a Champion, its ATK is subtracted from this unit's DEF first. Damage from spells is not reduced.

Damage
The base damage done on any attack (before ATK or DEF modify it) is equal to the unit's DMG.

rangana
08-31-2008, 07:13 AM
I don't fully understand it, but we can always see the 40&#37; of the damage field and 80% of the damage field for debugging purposes.

Try to change Damage0 function to:

function Damage0(form)
{
var atk=form.elements['attack'], // attack field
def=form.elements['defense'], //defense field
dmge=form.elements['damage'], // damage field
result=form.elements['result'], // result field
b2=Number(atk.value)-Number(def.value); // b2 as based on excel sheet
document.getElementById('test').value=Number(result.value)*(40/100); // 40% of damage
document.getElementById('test2').value=Number(result.value)*(80/100); // 80% of damage
if(b2<1) // if b2 is less than 1
result.value=Math.round(Number(dmge.value)-(((0.02)*Math.abs(b2))*Number(dmge.value)));
else if(b2>1) // if b2 is greater than 1
result.value=Math.round(Number(dmge.value)+((0.01*b2)*Number(dmge.value)));
else // if b2 is NaN or 1
result.value=0;
}

<label for="test">40% of Damage Field: </label><input type="text" id="test">
<label for="test2">80% of Damage Field: </label><input type="text" id="test2">

Hope that gives you a hint to create a formula which I'm totally is uncertain per time being.

Hope that helps.

rangana
08-31-2008, 07:13 AM
I don't fully understand it, but we can always see the 40% of the damage field and 80% of the damage field for debugging purposes.

Try to change Damage0 function to:

function Damage0(form)
{
var atk=form.elements['attack'], // attack field
def=form.elements['defense'], //defense field
dmge=form.elements['damage'], // damage field
result=form.elements['result'], // result field
b2=Number(atk.value)-Number(def.value); // b2 as based on excel sheet
document.getElementById('test').value=Number(result.value)*(40/100); // 40% of damage
document.getElementById('test2').value=Number(result.value)*(80/100); // 80% of damage
if(b2<1) // if b2 is less than 1
result.value=Math.round(Number(dmge.value)-(((0.02)*Math.abs(b2))*Number(dmge.value)));
else if(b2>1) // if b2 is greater than 1
result.value=Math.round(Number(dmge.value)+((0.01*b2)*Number(dmge.value)));
else // if b2 is NaN or 1
result.value=0;
}

<label for="test">40% of Damage Field: </label><input type="text" id="test">
<label for="test2">80% of Damage Field: </label><input type="text" id="test2">

Hope that gives you a hint to create a formula which I'm totally is uncertain per time being.

Hope that helps.

Alsark
08-31-2008, 11:50 AM
Ironically, despite meaning something else than what was coded above, I did happen to need what you coded. However, I would like to put it in the form of radio buttons, and when a button is ticked, the "result" value is automatically adjusted depending on what radio button is ticked. Then there would be another radio field that would also change the result value, but after the other radio field already modified the result field. However, I still need to work out the math on this, so I cannot even attempt to get this coded yet (nor could I tell somebody how the formula works without some testing).

As for the 40% damage and 80% damage thing, I meant that the amount b2 modifies damage can be no greater than +40%, and the amount it decreases damage can be no more than -80%. So for example, if the damage value were 10, the highest possible number in the result field would be 14, regardless of what b2 (ATK-DEF) was. And if the damage were 10, the lowest possible number in the result field could be 2.

Alsark
09-01-2008, 09:04 AM
Alright, so I figured out the calculation.

The 40&#37; damage increase and 80% damage decrease limit would take place prior to the following.

There would be nine radio buttons under the name "atkmod". One would not modify the result value (in other words, leave it as it is), one would make it 110% of what it should be, another 120%, another 125%, another 130%, another 135%, another 140%, another 145%, and another 150%. However, this set needs to take effect before "defmod" (see below) has taken effect. I would need it set so that it goes by the unmodified result value (so the value will always be the same when you click the button instead of, for example, taking 80% of the 65% when you switch buttons; it should always be taking the percentage off the 100%).

There would then be four buttons (called "defmod", which applies to unit resistances/vulnerabilities). One would not modify the result value, one would make it 80% of what it should be, another 65% of what it should be, another 50% of what it should be, and one 140% of what it should be. This effect would be modifying the value after Amplification has taken effect, so for example, the 50% option would be taking, say, 50% of 150% (if the 150% atkmod button is chosen).

These should both, if possible, modify result.value directly (so there would not be another number field for when these buttons are ticked).

I'd also need to add another modifier called "Hunter", which either increases damage or reduces damage by 50%, however, I should be able to figure that out after some help with the above code, since it would be very similar to "defmod" and "atkmod". I'm not sure when "Hunter" really applies in the sequence, anyway.

Sorry for all the questions :(. Surely you're annoyed by now, lol, so if this sounds like a lot of work (it does to me), or if you just don't want to do it, then I'm cool with that and understand completely. I did try to do these things myself (I'm trying not to leech off you), but pretty much failed.