Script: Remove EffectVar, update effect documentation

Günther Brammer 2010-12-21 21:57:40 +01:00
parent 2d1f697dee
commit b562acb32c
23 changed files with 630 additions and 739 deletions

1104
docs/de.po

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,9 @@
<title>Effects</title>
<h>Effects</h>
<part>
<text>Any number of effects can be attached to an object. Effects can perform various tasks, thus eliminating the need for helper objects. This is especially of interest for magic spells that act with a given duration. Effects are available from CE on.</text>
<text>Any number of effects can be attached to an object. Effects can perform various tasks, thus eliminating the need for helper objects. This is especially of interest for magic spells that act with a given duration.</text>
<h id="Intro">Introduction</h>
<text>Effects are, roughly put, dynamic timers that can be attached to objects. Effects themselves have no visible or acoustic representation - for this you would use objects or particles instead - effects are pure scripting helpers. They also offer a general interface that can be used to resolve conflicts of temporary status changes made to objects by other objects at the same time.</text>
<text>Effects are, roughly put, dynamic timers with properties that can be attached to objects. Effects themselves have no visible or acoustic representation - for this you would use objects or particles instead - effects are pure scripting helpers. They also offer a general interface that can be used to resolve conflicts of temporary status changes made to objects by other objects at the same time.</text>
<text>Here an example of implementing an invisibility spell without effects:</text>
<code>/* Unsichtbarkeitszauber ohne Effektsystem */
@ -56,12 +56,9 @@ protected func Destruction()
<h id="Usage">Application</h>
<text>Effects are created using <funclink>AddEffect</funclink> and removed with <funclink>RemoveEffect</funclink>. If an effect was successfully created, the callback Fx*Start is made (* is replaced with the effect name). Depending on the parameters, there can also be an Fx*Timer call for continuous activity such as casting sparks, adjusting energy etc. Finally, when the effect is deleted, the callback Fx*Stop is made. Now, the invisibility spell implemented using effects:</text>
<code>/* Unsichtbarkeitszauber mit Effektsystem */
// EffectVars:
// 0 - Vorheriger Sichtbarkeitsstatus
// 1 - Vorherige Farbmodulation
// visibility - Vorheriger Sichtbarkeitsstatus
// old_mod - Vorherige Farbmodulation
public func Activate(caster, caster2)
{
@ -75,24 +72,24 @@ public func Activate(caster, caster2)
return(RemoveObject());
}
protected func FxInvisPSpellStart(target, num)
protected func FxInvisPSpellStart(target, effect)
{
// Vorherige Sichtbarkeit des Zauberers speichern
EffectVar(0, target, num) = GetVisibility(target);
var old_mod = EffectVar(1, target, num) = GetClrModulation(target);
effect.visibility = GetVisibility(target);
effect.old_mod = GetClrModulation(target);
// Zauberer unsichtbar machen
SetVisibility(VIS_Owner() | VIS_Allies() | VIS_God(), target);
// Halbdurchsichtig bläulich für den Besitzer und Verbündete
SetClrModulation(ModulateColor(old_mod, RGBa(127,127,255,127)), target);
SetClrModulation(ModulateColor(effect.old_mod, RGBa(127,127,255,127)), target);
// Fertig
return true;
}
protected func FxInvisPSpellStop(target, num)
protected func FxInvisPSpellStop(target, effect)
{
// Status wiederherstellen
SetClrModulation(EffectVar(1, target, num), target);
SetVisibility(EffectVar(0, target, num), target);
SetClrModulation(effect.old_mod, target);
SetVisibility(effect.visibility, target);
// Fertig
return true;
}</code>
@ -103,7 +100,7 @@ protected func FxInvisPSpellStop(target, num)
// Rückgabewert -1 bedeutet, dass der Effekt gelöscht wird
return -1;
}</code>
<text>To store the previous status of the target object, special storage space in <funclink>EffectVar</funclink>() is used. This is necessary because in this case the effect callbacks to not have any object script context. So you cannot access any object local variables in the effect callbacks - remember that the magic spell object which has created the effect is already deleted. If you require an object context in the effect callbacks you can specify one in <funclink>AddEffect</funclink>(). In that case, effect callbacks would be in object local context and the effect would automatically be deleted if the target object is destroyed.</text>
<text>To store the previous status of the target object, properties of the effect are used. This is necessary because in this case the effect callbacks do not have any object script context. So you cannot access any object local variables in the effect callbacks - remember that the magic spell object which has created the effect is already deleted. If you require an object context in the effect callbacks you can specify one in <funclink>AddEffect</funclink>(). In that case, effect callbacks would be in object local context and the effect would automatically be deleted if the target object is destroyed.</text>
<h id="Priorities">Priorities</h>
<text>When creating an effect you always specify a priority value which determines the effect order. The engine ensures that effects with lower priority are added before effects with a higher priority - even if this means deleting an existing effect of higher priority. So if one effect colors the clonk green and another colors the clonk red, the result will be that of the effect with higher priority. If two effects have the same priority, the order is undefined. However, it is guaranteed that effects added later always notify the Fx*Effect callback of the same priority.</text>
<text>In the case of the red and green color, one effect could also determine the previous coloring and then mix a result using ModulateColor. But priorities also have another function: an effect of higher priority can prevent the addition of other effects of lower priority. This is done through the Fx*Effect callback. If any existing effect reacts to this callback with the return value -1, the new effect is not added (the same applies to the Start callback of the effect itself). Here an example:</text>
@ -215,10 +212,6 @@ protected func FxBanBurnPSpellEffect(new_name, target, num, new_num, var1, var2,
<text>Effects are also removed when the target object is deleted or dies - the cause for the removal is passed in the reason parameter to the Remove function of the effect. This can be used e.g. to reanimate a clonk immediately upon his death:</text>
<code>/* Wiederbelebungszauber */
// EffectVars: 0 - Anzahl der zusätzlichen Wiederbelebungen
public func Activate(caster, caster2)
{
// Zauberer ermitteln
@ -262,8 +255,8 @@ protected func FxReincarnationPSpellStop(target, num, reason, temporary)
// EffectVars: 0 - Vorherige Gravitation
// 1 - Änderung durch den Zauber
// grav - Vorherige Gravitation
// change - Änderung durch den Zauber
public func Activate(caster, caster2)
{
@ -276,59 +269,58 @@ public func Activate(caster, caster2)
return true;
}
protected func FxGravChangeUSpellStart(target, num, temporary, change)
protected func FxGravChangeUSpellStart(target, effect, temporary, change)
{
// Anderen Gravitationseffekt suchen
if (!temporary)
{
var iOtherEffect = GetEffect(&quot;GravChangeUSpell&quot;, target);
if (iOtherEffect == num) iOtherEffect = GetEffect(&quot;GravChangeUSpell&quot;, target, 1);
if (iOtherEffect)
var otherEffect = GetEffect(&quot;GravChangeUSpell&quot;, target);
if (otherEffect == num) iOtherEffect = GetEffect(&quot;GravChangeUSpell&quot;, target, 1);
if (otherEffect)
{
// Gravitationsänderung auf diesen Effekt aufrechnen
EffectVar(1, target, iOtherEffect) += change;
otherEffect.change += change;
SetGravity(GetGravity() + change);
// Selbst entfernen
return -1;
}
}
// Vorherige Gravitation sichern
var iOldGrav = EffectVar(0, target, num) = GetGravity();
effect.grav = GetGravity();
// Für nichttemporäre Aufrufe wird change übergeben, und auf den Änderungswert aufgerechnet
if (change) EffectVar(1, target, num) += change;
if (change) effect.change += change;
// Gravitationsänderung setzen
// Die Änderung kann in temporären Aufrufen auch ungleich change sein
SetGravity(iOldGrav + EffectVar(1, target, num));
SetGravity(effect.grav + effect.change);
// Fertig
return true;
}
protected func FxGravChangeUSpellTimer(target, num)
protected func FxGravChangeUSpellTimer(target, effect)
{
// Gravitation in Richtung Normalwert schrauben
var gravity_change = EffectVar(1, target, num);
// Fertig?
if (Inside(gravity_change, -1, 1)) return -1;
if (Inside(effect.change, -1, 1)) return -1;
// Anpassen
var iDir = -gravity_change/Abs(gravity_change);
EffectVar(1, target, num) += iDir;
var iDir = -effect.change/Abs(effect.change);
effect.change += iDir;
SetGravity(GetGravity() + iDir);
return true;
}
protected func FxGravChangeUSpellStop(target, num)
protected func FxGravChangeUSpellStop(target, effect)
{
// Gravitation Wiederherstellen
SetGravity(EffectVar(0, target, num));
SetGravity(effect.grav);
// Effekt entfernen
return true;
}</code>
<text>target will be 0 in all these effect calls. You should still pass this parameter to calls such as <funclink>EffectVar</funclink>() for then it is also possible to attach effects to the magician or perhaps a magic tower. In this case, gravity would automatically be reset as soon as the magician dies or the magic tower is destroyed.</text>
<text><code>target</code> will be 0 in all these effect calls. You should still pass this parameter to calls such as <funclink>ChangeEffect</funclink>() for then it is also possible to attach effects to the magician or perhaps a magic tower. In this case, gravity would automatically be reset as soon as the magician dies or the magic tower is destroyed.</text>
<h id="AddEffects">Adding Effects</h>
<text>In the previous example, several gravitational effects were combined so that the gravity change lasts longer if the spell is casted multiple times. Adding these effects cannot be done in the Effect callback because the gravitation effect might always be prevented by another effect with higher priority (e.g. a no-spells-whatsoever-effect). Through the special Fx*Add callback you can achieve the desired result more easily, or at least in a more structured fashion.</text>
<code>[...]
protected func FxGravChangeUSpellEffect(new_name, target, num)
protected func FxGravChangeUSpellEffect(new_name, target, effect)
{
// Falls der neu hinzugefügte Effekt auch eine Gravitationsänderung ist, Interesse am Übernehmen anmelden
if (new_name eq &quot;GravChangeUSpell&quot;) return (-3);
@ -336,16 +328,16 @@ protected func FxGravChangeUSpellEffect(new_name, target, num)
return();
}
protected func FxGravChangeUSpellAdd(target, num, new_name, target, new_timer, change)
protected func FxGravChangeUSpellAdd(target, effect, new_name, target, new_timer, change)
{
// Aufruf erfolgt, wenn der Effekt übernommen werden konnte
// Gravitationsänderung auf diesen Effekt aufrechnen
EffectVar(1, target, num) += change;
effect.change += change;
SetGravity(GetGravity() + change);
// Fertig
return true;
}</code>
<text>Returning -3 in the Fx*Effect callback will cause the Fx*Add callback to be invoked for the new effect. In this case the new effect is not actually created and the function AddEffect will return the effect number of the effect which has taken on the consequences of the new effect instead. As opposed to the method above this has the advantage that the return value can now be used to determine whether the effect has been created at all.</text>
<text>Returning -3 in the Fx*Effect callback will cause the Fx*Add callback to be invoked for the new effect. In this case the new effect is not actually created and the function AddEffect will return the effect which has taken on the consequences of the new effect instead. As opposed to the method above this has the advantage that the return value can now be used to determine whether the effect has been created at all.</text>
<h id="UserCallbacks">User Defined Properties</h>
<text>Effects can be easily classified by name. In this way, e.g. all magic spell effects can easily be found through the respective wildcard string. If, however, you want to create user-defined properties which also apply to existing effects you can do this by defining additional effect functions:</text>
<code>global func FxFireIsHot() { return true; } // Feuer is heiß
@ -472,14 +464,14 @@ global func FxExplodeOnDeathCurseStop(target, num, reason)
<part>
<text>The following callbacks are made by the engine and should be implemented in your script according to necessity. * is to be replaced by your effect name.</text>
<h>Fx*Start</h>
<text><code>int Fx*Start (object target, int num, int temporary, any var1, any var2, any var3, any var4);</code></text>
<text>Called at the start of the effect. target is the target object of the effect. num is the effect index. These two parameters can be used to identify the effect, e.g. to manipulate corresponding variables in <funclink>EffectVar</funclink>().</text>
<text><code>int Fx*Start (object target, effect, int temporary, any var1, any var2, any var3, any var4);</code></text>
<text>Called at the start of the effect. target is the target object of the effect. <code>effect</code> is the effect itself. These two parameters can be used to identify the effect, e.g. to manipulate effect details with <funclink>ChangeEffect</funclink>().</text>
<text>In normal operation the parameter temporary is 0. It is 1 if the effect is re-added after having been temporarily removed and 2 if the effect was temporarily removed and is now to be deleted (in this case a Remove call will follow).</text>
<text>Values var1 to var4 are the additional parameters passed to <placeholder-1/>() and can be custom used.</text>
<text>If temporary is 0 and this callback returns -1 the effect is not created and the corrsponding <funclink>AddEffect</funclink>() call returns 0.</text>
<h>Fx*Stop</h>
<text><code>int Fx*Stop (object target, int num, int reason, bool temporary);</code></text>
<text>When the effect is temporarily or permanently removed. target again is the target object and num the index into the effects list of that object.</text>
<text><code>int Fx*Stop (object target, effect, int reason, bool temporary);</code></text>
<text>When the effect is temporarily or permanently removed. target again is the target object and <code>effect</code> the effect itself.</text>
<text>reason contains the cause of the removal and can be one of the following values:</text>
<text>
<table>
@ -511,24 +503,24 @@ global func FxExplodeOnDeathCurseStop(target, num, reason)
</text>
<text>The effect can prevent removal by returning -1. This will not help, however, in temporary removals or if the target object has been deleted.</text>
<h>Fx*Timer</h>
<text><code>int Fx*Timer (object target, int num, int time);</code></text>
<text>Periodic timer call, if a timer interval has been specified at effect creation. target and num as usual.</text>
<text><code>int Fx*Timer (object target, effect, int time);</code></text>
<text>Periodic timer call, if a timer interval has been specified at effect creation. target and <code>effect</code> as usual.</text>
<text>time specifies how long the effect has now been active. This might alternatively be determined using <funclink>GetEffect</funclink>().</text>
<text>If this function is not implemented or returns -1, the effect will be deleted after this call.</text>
<h>Fx*Effect</h>
<text><code>int Fx*Effect (string new_name, object target, int num, int new_num, any var1, any var2, any var3, any var4);</code></text>
<text>A call to all effects of higher priority if a new effect is to be added to the same target object. new_name is the name of the new effect; num is the index of the effect being called; and ew_num is the index of the new effect.</text>
<text><code>int Fx*Effect (string new_name, object target, effect, reserved, any var1, any var2, any var3, any var4);</code></text>
<text>A call to all effects of higher priority if a new effect is to be added to the same target object. new_name is the name of the new effect; <code>effect</code> is the effect being called.</text>
<text>Warning: the new effect is not yet properly initialized and should not be manipulated in any way. Especially the priority field might not yet have been set. The new_num can however be used to request information via <funclink>EffectCall</funclink>(). In calls made by <funclink>CheckEffect</funclink>() new_num is always 0.</text>
<text>This function can return -1 to reject the new effect. As the new effect might also be rejected by other effects, this callback should not try to add effects or similar (see gravitation spell). Generally you should not try to manipulate any effects during this callback.</text>
<text>Return -2 or -3 to accept the new effect. As long as the new effect is not rejected by any other effect, the Fx*Add call is then made to the accepting effect, the new effect is not actually created, and the calling AddEffect function returns the effect index of the accepting effect. The return value -3 will also temporarily remove all higher prioriy effects just before the Fx*Add callback and re-add them later.</text>
<text>var1 bis var4 are the parameters passed to <funclink>AddEffect</funclink>()</text>
<h>Fx*Add</h>
<text><code>int Fx*Add (object target, int num, string new_name, int new_timer, any var1, any var2, any var3, any var4);</code></text>
<text>Callback to the accepting effect if that has returned -2 or -3 to a prior Fx*Effect call. num identifies the accepting effect to which the consequences of the new effect will be added; target is the target object (0 for global effects).</text>
<text><code>int Fx*Add (object target, effect, string new_name, int new_timer, any var1, any var2, any var3, any var4);</code></text>
<text>Callback to the accepting effect if that has returned -2 or -3 to a prior Fx*Effect call. <code>effect</code> identifies the accepting effect to which the consequences of the new effect will be added; target is the target object (0 for global effects).</text>
<text>new_timer is the timer interval of the new effect; var1 to var4 are the parameters from AddEffect. Notice: in temporary calls, these parameters are not available - here they will be 0.</text>
<text>If -1 is returned, the accepting effect is deleted also. Logically, the calling AddEffect function will then return -2.</text>
<h>Fx*Damage</h>
<text><code>int Fx*Damage (object target, int num, int damage, int cause);</code></text>
<text><code>int Fx*Damage (object target, effect, int damage, int cause);</code></text>
<text>Every effect receives this callback whenever the energy or damage value of the target object is to change. If the function is defined, it should then return whether to allow the change.</text>
<text>This callback is made upon life energy changes in living beings and damage value changes in non-livings - but not vice versa. cause contains the value change and reason:</text>
<text>
@ -605,7 +597,7 @@ global func FxExplodeOnDeathCurseStop(target, num, reason)
</row>
</table>
</text>
<text>Generally, the expression "cause &amp; 32" can be used to determine whether the energy or damage values were changed. Energy values are exact, meaning 100,000 is the full energy value of a normal clonk of rank 10 (C4MaxPhysical).</text>
<text>Generally, the expression "cause &amp; 32" can be used to determine whether the energy or damage values were changed.</text>
<text>Using this callback, damage to an object can be prevented, lessened, or increased. You could deduct magic energy instead, transfer damage to other objects, or something similar.</text>
</part>
<h id="FnRef">Function Reference</h>
@ -617,7 +609,6 @@ global func FxExplodeOnDeathCurseStop(target, num, reason)
<li><funclink>GetEffect</funclink>() - to request effect parameters</li>
<li><funclink>GetEffectCount</funclink>() - for effect counting</li>
<li><funclink>EffectCall</funclink>() - for user defined calls in effects</li>
<li><funclink>EffectVar</funclink>() - to request effect variables</li>
<li><funclink>ChangeEffect</funclink>() - to modify effect names and timers (e.g. for multi-stage effects)</li>
<li><funclink>CheckEffect</funclink>() - to cause effects callbacks without actually creating an effect</li>
</ul>

View File

@ -78,7 +78,6 @@
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>

View File

@ -62,7 +62,6 @@
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>

View File

@ -67,7 +67,6 @@
<funclink>ChangeEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>

View File

@ -21,14 +21,14 @@
<desc>If a mesh was previously attached to another one via <funclink>AttachMesh</funclink> then it can be detached again using this function.</desc>
<examples>
<example>
<code>func FxIntCarryBowStart(object target, int number)
<code>func FxIntCarryBowStart(object target, effect)
{
<funclink>EffectVar</funclink>(0, target, number) = target-&gt;<funclink>AttachMesh</funclink>(Bow, &quot;pos_hand1&quot;, &quot;main&quot;);
effect.mesh = target-&gt;<funclink>AttachMesh</funclink>(Bow, &quot;pos_hand1&quot;, &quot;main&quot;);
}
func FxIntCarryBowStop(object target, int number)
func FxIntCarryBowStop(object target, effect)
{
target-&gt;<funclink>DetachMesh</funclink>(<funclink>EffectVar</funclink>(0, target, number));
target-&gt;<funclink>DetachMesh</funclink>(effect.mesh);
}</code>
<text>Script for an <emlink href="script/Effects.html">effect</emlink>: The effect target carries a bow as long as the effect remains active.</text>
</example>

View File

@ -41,7 +41,6 @@
<funclink>ChangeEffect</funclink>
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>EffectVar</title>
<category>Effects</category>
<version>4.9.5.0 CE</version>
<syntax>
<rtype>&amp;</rtype>
<params>
<param>
<type>int</type>
<name>index</name>
<desc>Index of the variable. Theoretically, any number of variables can be used. As, however, any newly accessed variable has to internally allocated first, you should only use as many variables as really necessary.</desc>
</param>
<param>
<type>object</type>
<name>target</name>
<desc>Target object of the effect the of which you want to access variables. 0 for global effects.</desc>
<optional />
</param>
<param>
<type>int</type>
<name>number</name>
<desc>Effect number. Effect numbers are passed to effect callback functions, they are the return values of <funclink>AddEffect</funclink> and can be determined from an effect name via <funclink>GetEffect</funclink>.</desc>
</param>
</params>
</syntax>
<desc>Returns a reference to an effect local variable. This reference can be used to read or write values.</desc>
<remark>For examples and more information see the <emlink href="script/Effects.html">effects documentation</emlink>.</remark>
<related>
<emlink href="script/Effects.html">Effects Documentation</emlink>
<funclink>AddEffect</funclink>
<funclink>ChangeEffect</funclink>
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>
</func>
<author>Sven2</author><date>2004-03</date>
</funcs>

View File

@ -108,7 +108,6 @@ i = <funclink>GetEffectCount</funclink>();
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>RemoveEffect</funclink>
</related>
</func>

View File

@ -38,7 +38,6 @@
<funclink>ChangeEffect</funclink>
<funclink>CheckEffect</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
<funclink>RemoveEffect</funclink>
</related>

View File

@ -51,7 +51,6 @@
<funclink>CheckEffect</funclink>
<funclink>GetEffectCount</funclink>
<funclink>EffectCall</funclink>
<funclink>EffectVar</funclink>
<funclink>GetEffect</funclink>
</related>
</func>

View File

@ -33,19 +33,19 @@
<desc>If a mesh was previously attached to another mesh then this function can be used to change one or both of the bones at which they are attached. To only change a single bone the other parameter can be set to <code>nil</code>.</desc>
<examples>
<example>
<code>func FxIntCarryBowStart(object target, int number)
<code>func FxIntCarryBowStart(object target, effect)
{
<funclink>EffectVar</funclink>(0, target, number) = target-&gt;<funclink>AttachMesh</funclink>(Bow, &quot;pos_hand1&quot;, &quot;main&quot;);
<funclink>EffectVar</funclink>(1, target, number) = true;
effect.mesh = target-&gt;<funclink>AttachMesh</funclink>(Bow, &quot;pos_hand1&quot;, &quot;main&quot;);
effect.inhand1 = true;
}
func FxIntCarryBowTimer(object target, int number)
func FxIntCarryBowTimer(object target, effect)
{
<funclink>if</funclink>(<funclink>EffectVar</funclink>(1, target, number))
target-&gt;<funclink>SetAttachBones</funclink>(<funclink>EffectVar</funclink>(0, target, number), &quot;pos_hand2&quot;, nil);
<funclink>if</funclink>(effect.inhand1)
target-&gt;<funclink>SetAttachBones</funclink>(effect.mesh, &quot;pos_hand2&quot;, nil);
else
target-&gt;<funclink>SetAttachBones</funclink>(<funclink>EffectVar</funclink>(0, target, number), &quot;pos_hand1&quot;, nil);
<funclink>EffectVar</funclink>(1, target, number) = !<funclink>EffectVar</funclink>(1, target, number);
target-&gt;<funclink>SetAttachBones</funclink>(effect.mesh, &quot;pos_hand1&quot;, nil);
effect.inhand1 = !effect.inhand1;
}</code>
<text>Script for an <emlink href="script/Effects.html">effect</emlink>: Initially the clonk carries a bow and for each timer call the bow is switched from its left hand to its right hand or vice versa.</text>
</example>

View File

@ -1262,7 +1262,7 @@ func StartJump()
AddEffect("Fall",this,1,1,this);
}
func FxFallEffect(string new_name, object target, int num)
func FxFallEffect(string new_name, object target)
{
// reject more than one fall effects.
if(new_name == "Fall") return -1;

View File

@ -178,7 +178,7 @@ public func OnCrewSelection(object clonk, bool deselect)
}
}
public func FxIntSearchInteractionObjectsEffect(string newname, object target, int num, int new_num)
public func FxIntSearchInteractionObjectsEffect(string newname, object target)
{
if(newname == "IntSearchInteractionObjects")
return -1;

View File

@ -215,7 +215,7 @@ func FxIntIsBeingStruckTimer(pTarget, iEffectNumber, iEffectTime)
return true;
}
func FxIntIsBeingStruckEffect(string szNewEffectName, object pTarget, int iEffectNumber, int iNewEffectNumber)
func FxIntIsBeingStruckEffect(string szNewEffectName, object pTarget)
{
if(szNewEffectName == "IntIsBeingStruck") return -2;
return 0;

View File

@ -103,7 +103,7 @@ private func FxEnergyNeedStop(object target, int fxnum, int iReason, bool temp)
return 1;
}
private func FxEnergyNeedEffect(string name, object target, int fxnum, int fxnum_new)
private func FxEnergyNeedEffect(string name, object target)
{
// Only one energy need effect per consumer.
if (name == "EnergyNeed")

View File

@ -5271,7 +5271,7 @@ int32_t C4Object::GetFireCausePlr()
C4Effect *pFire = pEffects->Get(C4Fx_Fire);
if (!pFire) return NO_OWNER;
// get causing player
int32_t iFireCausePlr = FxFireVarCausedBy(pFire).getInt();
int32_t iFireCausePlr = pFire->GetPropertyInt(P_CausedBy);
// return if valid
if (ValidPlr(iFireCausePlr)) return iFireCausePlr; else return NO_OWNER;
}

View File

@ -63,7 +63,6 @@ C4AulScript *C4Effect::GetCallbackScript()
}
C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber)
: EffectVars(0)
{
C4Effect *pPrev, *pCheck;
// assign values
@ -143,7 +142,7 @@ C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t
riStoredAsNumber = iNumber;
}
C4Effect::C4Effect(StdCompiler *pComp) : EffectVars(0)
C4Effect::C4Effect(StdCompiler *pComp)
{
// defaults
iNumber=iPriority=iTime=iIntervall=0;
@ -186,8 +185,6 @@ void C4Effect::DenumeratePointers()
{
// command target
pEff->CommandTarget.DenumeratePointers();
// variable pointers
pEff->EffectVars.DenumeratePointers();
// assign any callback functions
pEff->AssignCallbackFunctions();
pEff->C4PropList::DenumeratePointers();
@ -526,17 +523,6 @@ void C4Effect::CompileFunc(StdCompiler *pComp)
// proplist
C4PropListNumbered::CompileFuncNonames(pComp);
pComp->Separator(StdCompiler::SEP_END); // ')'
// read variables
if (pComp->isCompiler() || EffectVars.GetSize() > 0)
{
if (pComp->Separator(StdCompiler::SEP_START2)) // '['
{
pComp->Value(EffectVars);
pComp->Separator(StdCompiler::SEP_END2); // ']'
}
else
EffectVars.Reset();
}
// is there a next effect?
bool fNext = !! pNext;
if (pComp->hasNaming())
@ -555,11 +541,6 @@ void C4Effect::CompileFunc(StdCompiler *pComp)
// Internal fire effect
C4Value &FxFireVarMode(C4Effect *pEffect) { return pEffect->EffectVars[0]; }
C4Value &FxFireVarCausedBy(C4Effect *pEffect) { return pEffect->EffectVars[1]; }
C4Value &FxFireVarBlasted(C4Effect *pEffect) { return pEffect->EffectVars[2]; }
C4Value &FxFireVarIncineratingObj(C4Effect *pEffect) { return pEffect->EffectVars[3]; }
int32_t FnFxFireStart(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int32_t iTemp, int32_t iCausedBy, bool fBlasted, C4Object *pIncineratingObject)
{
// safety
@ -624,10 +605,10 @@ int32_t FnFxFireStart(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int3
iFireMode = C4Fx_FireMode_Object;
}
// store causes in effect vars
FxFireVarMode(pEffect).SetInt(iFireMode);
FxFireVarCausedBy(pEffect).SetInt(iCausedBy); // used in C4Object::GetFireCause and timer!
FxFireVarBlasted(pEffect).SetBool(fBlasted);
FxFireVarIncineratingObj(pEffect).SetObject(pIncineratingObject);
pEffect->SetProperty(P_Mode, C4VInt(iFireMode));
pEffect->SetProperty(P_CausedBy, C4VInt(iCausedBy)); // used in C4Object::GetFireCause and timer!
pEffect->SetProperty(P_Blasted, C4VBool(fBlasted));
pEffect->SetProperty(P_IncineratingObj, C4VObj(pIncineratingObject));
// Set values
pObj->FirePhase=Random(MaxFirePhase);
if (pObj->Shape.Wdt*pObj->Shape.Hgt>500) StartSoundEffect("Inflame",false,100,pObj);
@ -646,7 +627,7 @@ int32_t FnFxFireTimer(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int3
int iNumber = pEffect->iNumber;
// get cause
int32_t iCausedByPlr = NO_OWNER;
iCausedByPlr = FxFireVarCausedBy(pEffect).getInt();
iCausedByPlr = pEffect->GetPropertyInt(P_CausedBy);
if (!ValidPlr(iCausedByPlr)) iCausedByPlr = NO_OWNER;
// causes on object
@ -664,7 +645,7 @@ int32_t FnFxFireTimer(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int3
/* Fire execution behaviour transferred from script (FIRE) */
// get fire mode
int32_t iFireMode = FxFireVarMode(pEffect).getInt();
int32_t iFireMode = pEffect->GetPropertyInt(P_Mode);
// special effects only each four frames, except for objects (e.g.: Projectiles)
if (iTime%4 && iFireMode!=C4Fx_FireMode_Object) return C4Fx_OK;

View File

@ -86,7 +86,6 @@ public:
C4ID idCommandTarget; // ID of command target definition
int32_t iPriority; // effect priority for sorting into effect list; -1 indicates a dead effect
C4ValueList EffectVars; // custom effect variables
int32_t iTime, iIntervall; // effect time; effect callback intervall
int32_t iNumber; // effect number for addressing

View File

@ -4596,33 +4596,6 @@ static long FnGetEffectCount(C4AulContext *ctx, C4String *psEffectName, C4Object
return pEffect->GetCount(szEffect, iMaxPriority);
}
static C4Value FnEffectVar(C4AulContext *cthr, int32_t iVarIndex, C4Object *pObj, C4Effect * pEffect2)
{
// safety
if (!pEffect2) return C4Value();
if (iVarIndex<0) return C4Value();
// get effect
C4Effect *pEffect = pObj ? pObj->pEffects : Game.pGlobalEffects;
if (!pEffect) return C4Value();
if (!(pEffect = pEffect->Get(pEffect2->iNumber, true))) return C4Value();
// return var
return pEffect->EffectVars[iVarIndex];
}
static C4Value FnSetEffectVar(C4AulContext *cthr, int32_t iVarIndex, C4Object *pObj, C4Effect * pEffect2, const C4Value &Value)
{
// safety
if (!pEffect2) return C4Value();
if (iVarIndex<0) return C4Value();
// get effect
C4Effect *pEffect = pObj ? pObj->pEffects : Game.pGlobalEffects;
if (!pEffect) return C4Value();
if (!(pEffect = pEffect->Get(pEffect2->iNumber, true))) return C4Value();
// set and return value
pEffect->EffectVars[iVarIndex] = Value;
return Value;
}
static C4Value FnEffectCall_C4V(C4AulContext *ctx, C4Value *pvpTarget, C4Value *pvEffect, C4Value *pvsCallFn, C4Value *pvVal1, C4Value *pvVal2, C4Value *pvVal3, C4Value *pvVal4, C4Value *pvVal5, C4Value *pvVal6, C4Value *pvVal7)
{
// evaluate parameters
@ -6075,8 +6048,6 @@ void InitFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "FatalError", FnFatalError, false);
AddFunc(pEngine, "ExtractMaterialAmount", FnExtractMaterialAmount);
AddFunc(pEngine, "GetEffectCount", FnGetEffectCount);
AddFunc(pEngine, "EffectVar", FnEffectVar);
AddFunc(pEngine, "SetEffectVar", FnSetEffectVar);
AddFunc(pEngine, "PlayVideo", FnPlayVideo);
AddFunc(pEngine, "StartCallTrace", FnStartCallTrace);
AddFunc(pEngine, "StartScriptProfiler", FnStartScriptProfiler);

View File

@ -1211,17 +1211,10 @@ C4AulBCC C4AulParseState::MakeSetter(bool fLeaveValue)
break;
case AB_GLOBALN: Setter.bccType = AB_GLOBALN_SET; break;
case AB_CALL:
case AB_FUNC:
// Huge hacks would required to make this work. EffectVar should get the Var treatment
// and become a BCC of its own anyway.
throw new C4AulParseError(this, "Setting a call result does not work, sorry!");
case AB_FUNC:
// This one at least works somewhat
if(SEqual(Value.Par.f->Name, "EffectVar"))
{
Setter.Par.f = a->GetFuncRecursive("SetEffectVar");
break;
}
// falthru
default:
throw new C4AulParseError(this, "assignment not possible for this value!");
}

View File

@ -135,6 +135,10 @@ C4StringTable::C4StringTable()
P[P_MaxEnergy] = "MaxEnergy";
P[P_MaxBreath] = "MaxBreath";
P[P_ThrowSpeed] = "ThrowSpeed";
P[P_Mode] = "Mode";
P[P_CausedBy] = "CausedBy";
P[P_Blasted] = "Blasted";
P[P_IncineratingObj] = "IncineratingObj";
P[DFA_WALK] = "WALK";
P[DFA_FLIGHT] = "FLIGHT";
P[DFA_KNEEL] = "KNEEL";

View File

@ -223,6 +223,10 @@ enum C4PropertyName
P_MaxEnergy,
P_MaxBreath,
P_ThrowSpeed,
P_Mode,
P_CausedBy,
P_Blasted,
P_IncineratingObj,
// Default Action Procedures
DFA_WALK,
DFA_FLIGHT,