So I'm building and scripting my character sheet, and if I can figure out how to do one simple thing, my life will become a whole lot less complicated. I'm trying to write a script that uses references to fields to make calculations WITHOUT directly writing the Field Name in the script. I want to do one of two things.
Example 1:
There is a field with the name HP1, also STR and MELEE. I want to write a script to be placed in each of those field's Source which will set that Field Name to a variable, let's say "STAT". That way I could use that variable in a single script, but modify any data from other fields with it.
It would look like this: Field to be copied - [Field Name: STR ; Field Source: js.GetFieldName()] to then be used in the script in [Field Name: Stat_STR ; Field Source: js.calcSTAT()]. The GetFieldName() would create a variable, set the variable to whatever the Field Name was, and return it to be used as a variable in the main script. It would serve as a pointer to other Fields, essentially to gather up all other Fields that have STR in them - IE: Stat_STR, Mod_STR, Total_STR - so that the function can call each stat without having to create a script for each stat, ability, skill, etc.
The other method (highly prefered), seems a lot more simple if its possible. Is there some way to get a Field Name, from within a script that the script is being run from? Its basically the same as Example 1, except simplified. I'm trying to find a way to call a Field Name from within a script being run from the source of that field.
Example:
[Field Name: HP1 ; Field Source: js.STATS()]
Inside the STATS() function that basically runs a few calculations. I want to get the Field Name "STAT = FieldName.Name" so that it will be able to be combined with a preset string [var FullName = "Total_" + STAT]. This will allow me to call each stat, skill and ability with the same script. It all hinges on being able to get the Field Name WITHOUT directly referencing a specific field. It would be sort of like a script asking the Field that's running it "What's your Name?".
I don't like the idea of creating 100-200 identical scripts doing exactly the same thing, except with 2-3 letters different for a few Field Name's. Please assist. It's been a long time since I've delved this far into coding/scripting, and my knowledge of javascript is passable at best. I really hope of the two solutions can work, or if there is an alternative, I'd be very appreciative!
Comments
That said, very broadly speaking, what you seem to be forgetting is that functions can and do have parameters and take arguments.
See here: http://www.w3schools.com/js/js_functions.asp .
Also here: http://javascript.info/tutorial/arguments .
(This would be a lot easier if I could copy/paste actual code, by the way. See my wish list thread... or even the example of code posted there.)
Thus, for instance, I could define a function as:
Now, while this particular example is kinda silly, it does illustrate the principle.
Here's how I have the page setup. Currently, it's empty save for 3 boxes. The FieldNames are Karma_Cost_HP1, Karma_Rank_HP1, Karma_Total_HP1. "Karma_Cost_HP1" is variable 1, "Karma_Rank_HP1" is variable 2, and "Karma_Total_HP1" is what calls "js:KARMA_COST(var1, var2)" from its FieldSource. If I type in numbers as the values of var1 and var2, the function works perfectly. If I use the FieldNames in place of var1 and var2, nothing is returned. I have tried using this "js:KARMA_COST(Karma_Cost_HP1, Karma_Rank_HP1)" and referencing the FieldNames directly in the script, which I don't want to do but I was testing. No matter, FieldNames don't appear to work in scripts, which I can't understand why. Perhaps I'm using them wrong? I've tried everything I can think of, FieldName, FieldName.Value, FieldName.Text...nothing returns a value.
A secondary, much much less important issue:
Also, while I have the calculation running correctly, I would really love if I could determine a mathematical equation that could replace the loop I have it running. If for nothing else than improving speed and efficiency. If there is an equation I could use, I would love to hear about it. I swear there is one out there, but my brain is fried right now.
Equation: (Cost*Position) + (Cost*(Position+1) + (Cost*(Position+2) + etc (until Position = Rank)
Example: Cost=5, Rank=5
5+10+15+20+25=75
Or: C=6, R=8
6+12+18+24+30+36+42+48=216
The code I have for the equation:
var Pos_Num = 1;
var Total_Karma = 0;
var Karma_Mod = 1;
function KARMA_COST(Cost, Rank)
{
if(Pos_Num <= Rank)
{
Total_Karma = (Cost * Pos_Num) + Total_Karma;
Pos_Num = Pos_Num +1;
}
if(Pos_Num == Rank+1 && Race.Text == "Bhargastian")
{
Karma_Mod = 0.50;
Total_Karma = Total_Karma * Karma_Mod + Total_Karma;
Pos_Num = Pos_Num +1;
}
return Total_Karma;
}
If anyone has an idea for an equation that doesn't require a recursive function, I'd be all ears. Or, if there is a more efficient way to run the function above, I'd be thankful if one exists. As it stands though, the runtime doesn't feel too bad, although I shudder at what it'll be like when I have 100 more that run.
This should, in theory, return x*y, for all cases where y is a positive integer.
Of course, the sheet I created to test this is giving me what I can politely describe as a nonsensical error, so I rewrote the thing, using a different recursive function. Each time I've tried, for the record, I get similar: an syntax error on the line before the recursive call (so, in this case, I get it on line two -- the line consisting solely of an opening bracket).
Sorry, not sure what else to say there beyond that you may want to mention it in my wish list thread, although I might be able to suggest a workaround or two in the specific case you're trying.
If it's the one you're listing below, there actually is a way to calculate it without recursion, however.
First, you have to realize that C is essentially a multiplier. For all cases of your function, f(C, R) = C * F(1, R). Thus, we can ignore C for now.
Thus, what you have to do is calculate the sum of the sequence 1, 2, 3... R, for a given value of R. This is actually trivially easy when R is even: you can just group opposing ends. For instance, with an R of 8, you get the sequence 1, 2, 3, 4, 5, 6, 7, 8. As it happens, 8+1 = 7+2 = 6+3 = 5+4 = 9.
Each of these pairs is equal to R+1, and since they're pairs, there are always R/2 of them. Thus, the sum is equal to (R+1)*(R/2).
If R is odd, however, it gets a bit more tricky... but the formula still works anyway -- because that odd middle number out is always equal to half of R + 1. So, for instance, 1 + 2 + 3 = 6 = (3 +1)*(3/2) = 4 * 1.5 . Similarly, 1 + 2 + 3 + 4 + 5 = 15 = (5+1)*(5/2) = 6 * 2.5 .
Accordingly, your example function can be represented f(C, R) = C * (R+1) * (R/2).
@RealityBlights :Thank you for finding this, it was driving me crazy! Really something that should be mentioned in the manual about limitations of field naming.