There are still some physicals left: Energy, Breath, Jump, Throw, CorrosionResist and BreatheWater. I'm not sure what to do with them. The last four can probably just be simple properties. Maybe the first two can be properties named MaxEnergy and MaxBreath or something. When that is done, SetPhysical and GetPhysical can be removed.
I probably made some mistakes while modifying the scripts. Comments and test help are welcome. :-)
In general movement seems like it didn't change, so that's a good thing - your conversions seem correct. But from reading your conversion changes I get the feeling that horizontal movement while jumping with a clonk is faster than just walking, seems a little strange to me. Was this already the case before your conversions, or did you make some error there?
P.S. got some crashes with while using the grappler, compiling a debug engine now.
> But from reading your conversion changes I get the feeling that horizontal movement while jumping with a clonk is faster than just walking, seems a little strange to me. Was this already the case before your conversions, or did you make some error there?
The flight movement had a hardcoded maximum of 2px/frame. I'd blame Newton, but the real culprit is the convoluted Physical code that made doing something "better" unnecessary difficult. And noticing the difference between 1.96px/frame and 2 px/frame is probably impossible anyway.
edit:
> So I tried them and it didn't compile at first hand, I think you may have forgotten to remove C4TempPhysicalInfo::Train. I removed that and it compiled.
Partially - I removed it in another commit that removes C4TempPhysicalInfo completely, but moved that commit to the end and didn't push it because some scripts still rely on it. I'll amend the "training" commit, thanks.
>When that is done, SetPhysical and GetPhysical can be removed.
Wait, how would I for example change the walking speed of a Clonk then? Modifying the ActMap-proplist?
- you have a speed of 100
- you are slowed by 50%
- you have a speed of 50
- you are slowed by 10
- you have a speed of 40
- the first slow (-50%) wears of
- you are at 80
- the second slow (-10) wears off
- you are at 90
Problem!
>I'd recommend using the stacking support of the Effects, which was implemented for just this usecase.
Mh, true. Even though I have a solution in mind, it would in the end be not much different from properly using effect priorities/temporary calls
You're at 100
First slow applies. Stores previous value (100) and reduces to 90
Second slow applies. Stores previous value (90) and reduces to 80
First slow wears off. Resets speed to stored 100
Second slow wears off. Resets speed to stored 90
-> Both slows gone, you end up at 90 speed
The only way to prevent this is to use a stack that ensures the first applied slow is removed last. I.e., effects.
Start: PushStack(...)
Stop: PopStack(...)
is much simpler than
Start: x = PushStack(...)
Stop: RemoveFromStack(x)
and the latter would have the advantage of having the correct physicals between the removes. Remember some physical modifiers can work in a very long time frame. For example, think of boots you can equip to make you faster. If you equip those boots while a two-second temporary slow effect had hit you, you will be slowed forever (until you re-equip them).
- 100
- Reduce by 10 (save +10) -> 90
- Reduce by 10% (save +9) -> 81
- Increase by 200% (save -162) -> 243
- Increase by 2 (save -2) -> 245
It's unimportant in what order these effects end, the outcome is always 245 - 2 - 162 + 9 + 10 = 100
100 - double effect, save -100
200 - three quarters effect, save +150
50 - double effect ends
-50 - oops
Really, the way Effects work by temporarily removing and reapplying changes is the only way to ensure totally correct values. Short of doing that, using the previous value will at least result in usable values with no longterm harm.
2) Apply percentage modifiers(+- X%)
This way:
- you have a speed of 100
- you are slowed by 50%
- you have a speed of 50
- you are slowed by 10
- you have a speed of 45 (if it's a problem, the steps could always get reversed...)
- the first slow (-50%) wears of
- you are at 90
- the second slow (-10) wears off
- you are at 100
Voila!
It starts with 100.
Effect A adds an 200% modifier. (Modifiers now: 200%, Calculation: 100*2.0=200)
Effect B adds an 50% modifier. (Modifiers: 200% 50%, Calculation: 100*2.0*0.5=100)
Effect C adds an +50 modifier. (Modifiers: 200% 50% +50, Calculation: 100*2.0*0.5+50=150)
Effect A runs out. Removes the 200% modifier. (M: 50% +50, C: 100*0.5+50=100)
Effect C runs out. Removes the +50 modifier. (M: 50% C: 100*0.5=50)
Effect B runs out. Removes the 50% modifier. (M: Nothing C: 100=100)
However dunno what API could be used for that.
> What I had in mind was some sort of unique identifier for every slow
You mean the effect number? Really, stop describing the Effect API we already have. It was designed for this and can solve the problem. We only have to make it usable. Help with that would be really appreciated!
But yeah, that could work.
func Fx*ValModifierStart([...], string property)
{
EffectVar(0, [...]) = property;
}
func Fx*ValModifierIsForProperty([...], string property)
{
return EffectVar(0, [...]) == property;
}
func Fx*ValModifierCalculate([...], value)
{
return value; // +25 or something, dependant what kind of modifier
}
+ Some code to handle those effects.
>Really, stop describing the Effect API we already have.
Let me quote myself: "Even though I have a solution in mind, it would in the end be not much different from properly using effect priorities/temporary calls".
I am also for improving the effect interface for this task.
>easy-to-use helper function that provide some sort of stack mechanism
That's easy:
DoMovementSpeed(int change);
will suffice I think (assuming that the normal function/act map property is called SetMovementSpeed/movementSpeed).
> - takebreath = 100 * takebreath / C4MaxPhysical;
C4MaxPhysical is significantly larger than 100, so you're making the filling of breath a lot faster here. I don't know whether that's a good idea, so I just want to make sure that this is intended. Also, an object is an it in English ;-)
SetMaxEnergy.patch:
> - swordman.MaxEnergy = 60000;
> - swordman->DoEnergy(10);
> + swordman->SetMaxEnergy(60000);
SetMaxEnergy won't fill up missing energy, only remove excess energy. That either needs to change, or the DoEnergy call here needs to remain. Hm, doing
NewEnergy = NewMaxEnergy * GetEnergy() / OldMaxEnergy; SetEnergy(NewEnergy);
instead of DoEnergy(0)
would take care of both problems with SetMaxEnergy :-)
>C4MaxPhysical is significantly larger than 100, so you're making the filling of breath a lot faster here. I don't know whether that's a good idea, so I just want to make sure that this is intended.
This was already so before, I remove the conversion(DoBreath() and inverse conversion(takebreath), hence it remains the same.
>Also, an object is an it in English ;-)
Also in Dutch, no excuses for my lacking linguistic skills ;(
>SetMaxEnergy won't fill up missing energy, only remove excess energy. That either needs to change, or the DoEnergy call here needs to remain. Hm, doing NewEnergy = NewMaxEnergy * GetEnergy() / OldMaxEnergy; SetEnergy(NewEnergy); instead of DoEnergy(0) would take care of both problems with SetMaxEnergy :-)
Like this idea, and changed the patche accordingly, though SetEnergy is not available, thus had to use DoEnergy, and line 1370 had to be changed anyways, since effects could change it to zero in any case.
Useless trivia of the day: The Clonk throws objects with 2.94 px/frame.
diff --git a/planet/Objects.c4d/Clonk.c4d/Script.c b/planet/Objects.c4d/Clonk.c4d/Script.c
index 3c7865d..b45a022 100644
--- a/planet/Objects.c4d/Clonk.c4d/Script.c
+++ b/planet/Objects.c4d/Clonk.c4d/Script.c
@@ -1239,11 +1239,15 @@ func PushActionSpeed(string action, int n)
if (ActMap == this.Prototype.ActMap)
ActMap = { Prototype = this.Prototype.ActMap };
ActMap[action] = { Prototype = ActMap[action], Speed = n };
+ if (this.Action == ActMap[action].Prototype)
+ this.Action = ActMap[action];
}
/* Resets the named action to the previous one */
func PopActionSpeed(string action, int n) {
// FIXME: This only works if PushActionSpeed and PopActionSpeed are the only functions manipulating the A
+ if (this.Action == ActMap[action])
+ this.Action = ActMap[action].Prototype;
ActMap[action] = ActMap[action].Prototype;
}
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill