Closed Roguedeus closed 10 years ago
Probably better to modify this script with that functionality http://himeworks.wordpress.com/2013/12/09/parameter-bonuses/
However, note that param formulas accept the "original" value as part of the formula itself. For example
val + 20
Would simply increase the original value by 20. I don't know whether the original value, in this case, is the appropriate value based on its level.
Thats what I was afraid of... I was hoping to be able to do something like this.
Example:
I am allowing the player to have up to 5 battle members, with difficulty scaling pretty heavily for each member above 3. Being able to, for example, multiply an enemies MHP by 150% when the $game_party.battle_members.count > 3
would be sweet. Otherwise I am left guessing what an adequate flat bonus would be.
val * 1.5 if p.battle_members.count > 3
Doesn't work?
I was referring to the Parameter Tables
assigning the value on scene load.
Example:
Enemy Lv-1 : HMP = 100 ... Enemy Lv-10 : HMP = 550
If I have the Lv-10 enemy default stat in tool set set to 100. And the bonus as val * 1.5
then wouldn't the bonus be 150? When I would actually need it to be something closer to 250?
Unless I am mistaking your comment. I have not used Parameter Bonuses
, as that was Actors only.
It looks like enemy param formulas won't be able to accomplish it, since it only uses the enemy's params and doesn't consider the level. It might even crash.
Adapting the parameter bonuses for enemies is a better way.
Parameter bonuses can be applied to enemies now.
Thanks for tackling this so quickly. Though, I am not sure I fully understand how this is supposed to work.
I assume a
is Actor and Enemy?
Also, I don't see a way to access the current param and then multiply it by 150%.
This causes an infinite loop.
<param bonus: mhp>
a.mhp * 1.5 if $game_party.battle_members.count > 3
</param bonus>
Other then that snag, it works great.
I attempted to stare and compare your script, to see if I could hack in a way to accomplish what I need, but you are using syntax thats foreign to my relatively ruby-noobie eyes. :p
I am still digesting the various ways method parameters can be used and default method types.
When I see you do stuff like this:
def value(a, p=$game_party, t=$game_troop, s=$game_switches, v=$game_variables)
eval(@formula)
end
and
def eval_param_formula(formula, val, a, p=$game_party, t=$game_troop, v=$game_variables, s=$game_switches)
eval(formula)
end
I am left with big ?
in my head...
There is still sooo much about Ruby I have no clue of.
Yes, a
now refers to the current battler.
I've updated it to support the base parameter of the current parameter type. For example, if you write
<param bonus: atk>
val * 1.5
</param bonus>
That will give you a 50% bonus to the current atk.
The reason why accessing a.atk
causes an infinite loop is because that includes the bonus. That can be changed though.
Checking it out now! :)
I've updated the script to support "recursive" references. It is not really recursive though
<param bonus: atk>
a.atk * 1.5
</param bonus>
This will now increase the pre-bonus atk by 50%.
The trick is simple: use a temp flag
return 0 if @check_param_bonus
@check_param_bonus = true
val = param_bonus_object.param_bonuses.inject(0) {|r, obj|
obj.param_id == param_id ? r += obj.value(self, param_base(param_id)) : r
}
@check_param_bonus = false
return val
I'm going to remove the val
argument though because...I don't see a point to it.
It may be better to keep the val
argument for consistency. I use multiple of your param scripts and having some of them use val, and others use more natural references may confuse me and others. :p
It is a relatively new concept that I introduced in my formula related scripts, and it is rather inconsistent. For example, enemy gold formula uses gold
for the base value, enemy exp formula uses exp
, and parameters use val
for some reason.
Of course, you can't really compare them because they are separate things. for parameters, I think I introduced val
only for the purpose of accessing "base" value (that is, excluding equips and other bonuses), but there may be a better way to handle that.
I would rather introduce a bunch of aliases like base_atk
, base_def
, and so on rather than use an ugly thing like val
Ah.
Do you plan to add the recursive block to your other param scripts? Like Enemy Param Formulas
?
I think I may have run into an issue... Making sure.
It looks more complicated to add that kind of thing to enemy param formulas.
It may not be an issue, but if for some reason the formula used for the bonus, doesn't return a bonus value, it errors.
This caused a crash error when the party was 3 or less.
<param bonus: mhp>
a.mhp * 0.5 if $game_party.battle_members.count > 3
</param bonus>
This fixed it.
<param bonus: mhp>
if $game_party.battle_members.count > 3
a.mhp * 0.5
else
0.0
end
</param bonus>
Right, that is how I intended it to be done because I don't specify a default value.
This seems to fix it.
Nope
I am trying to wrap my head around the way eval works... And the way you use it so effortlessly.
That's what I mean to return a default value.
eval
takes a string and evaluates it as regular ruby code.
For example, when you say
a.atk * 2
If you think of it as regular ruby, a
is a variable, atk
is a method access, and the rest is just normal math.
When you say eval
, all of the variables in the scope of the call are available, so when I expose a
to the method, I can pass whatever object I want as an argument and let the eval
use it.
I really don't understand why its so difficult for me to grasp logic loops and recursive math sometimes but I am having one of those moments while looking at your method here:
return 0 if @check_param_bonus
@check_param_bonus = true
val = param_bonus_object.param_bonuses.inject(0) {|r, obj|
obj.param_id == param_id ? r += obj.value(self, param_base(param_id)) : r
}
@check_param_bonus = false
return val
Can you explain how this method ever ends with @check_param_bonus
as true?
Unless, it shouldn't unless its calling itself?
/facepalm
Now thats something I haven't seen before!
You know, I have tried using similar to those kinds of things in the past, with Java, and had issue with the variable not updating fast enough to prevent the repeat the first few times... Maybe its in Ruby's slow nature that it evaluates every variable before its use that allows this to work so well???
It's just Ruby's syntactic sugar.
do_something if some_condition
is equivalent to
if some_condition
do_something
end
nil
resolves to boolean false
, so the first line doesn't do anything unless you actually set it to something that doesn't resolve to false
.
It has basically nothing to do with whether the language is fast or not. If the code is executed in sequential order (which it does), then it will work as expected.
If you are working with a multi-threaded application, then you may run into cases where one thread checks it before the value is properly modified.
Its the idea of a class variable (in this case an instance variable) being toggled in time to be caught by the loop that made me remember it. It was so long ago I am likely messing up the circumstance. :)
As for your explanation regarding eval...
How would eval know its referencing itself with a
?
def value(a, p=$game_party, t=$game_troop, s=$game_switches, v=$game_variables)
eval(@formula)
end
I see thats what its doing here:
class Game_Enemy < Game_Battler
def param_bonus_object
self.enemy
end
end
But I am failing to grasp how a
is anything more than a blank parameter?
Nevermind... I got it.
obj.value(self)
I am extremely slow sometimes... But once I get something, I tend to surprise people. :p
I was wondering...
Completely removing the option of using
Enemy Param Formulas
in exchange forParameter Tables
has put me in a rather odd position where changes I had planned for battle member counts, are now impossible that I have decided to useParameter Tables
for the ease of enemy level scaling.I am able to still use
Enemy Param Formulas
for all the sparam and xparam needs, thanks to your addition, as they are not YET table based (though it would be really cool if they where).So I was wondering if it where possible to add the option of assigning the
Enemy Param Formulas
as BONUSES rather than flat assignments when combined with yourParameter Tables
?It will allow a near unlimited range of conditional customization.