blob: e7eeb42182397b71d3eae9ac493e1ea274f00a6e [file] [log] [blame]
Zesstra18626972017-01-31 10:38:27 +01001AddSpell()
2==========
3
4FUNKTION
5--------
Zesstra18626972017-01-31 10:38:27 +01006
Zesstradee2e562018-02-28 23:51:56 +01007 varargs int AddSpell(int rate, int damage,
8 string|<int|spell>* TextForEnemy, string|<int|string>* TextForOthers,
9 string|string* dam_type, string|closure func, int|mapping spellarg)
Zesstra18626972017-01-31 10:38:27 +010010
11DEFINIERT IN
12------------
Zesstra18626972017-01-31 10:38:27 +010013
Zesstracc3ff952018-03-05 22:04:49 +010014 /std/npc/combat.c
Zesstra18626972017-01-31 10:38:27 +010015
16ARGUMENTE
17---------
Zesstra18626972017-01-31 10:38:27 +010018
Zesstracc3ff952018-03-05 22:04:49 +010019 rate - Relative Haeufigkeit der Anwendung (*),
20 muss >= 0 sein
21
22 damage - Der Schadenswert fuer Defend(),
23 muss > 0 sein
24
25 TextForEnemy - Text, den der Feind erhalten soll
26 String <text> oder
27 Array der Form ({<text>,<messagetype>})
28 (Siehe ReceiveMsg())
29
30 TextForOthers - Text, den andere im Raum erhalten sollen
31 String <text> oder
32 Array der Form ({<text>,<messagetype>})
33 (Siehe ReceiveMsg())
34
35 dam_type - Schadenstyp(en) fuer Defend(),
36 (Default: ({DT_MAGIC}) fuer Magische und ({DT_BLUDGEON})
37 fuer physikalische Angriffe)
38
39 func - Funktionsname oder Closure, die nach Anwendung
40 aufgerufen werden soll
41 (Optional, bekommt als Argumente object enemy,
42 int real_damage, string* dam_type)
43
44 spellarg - Spell-Argument fuer Defend(), Default ist "1"
Zesstra18626972017-01-31 10:38:27 +010045
46BESCHREIBUNG
47------------
Zesstra18626972017-01-31 10:38:27 +010048
Zesstracc3ff952018-03-05 22:04:49 +010049 Ermoeglicht einfache Angriffs-Zaubersprueche fuer NPCs. Das Ausfuehren von
50 Spells verursacht bei dem NPC keine KP-Kosten.
Zesstra18626972017-01-31 10:38:27 +010051
Zesstracc3ff952018-03-05 22:04:49 +010052 Mit P_SPELLRATE wird die generelle Wahrscheinlichkeit der Ausfuehrung
53 solcher Spells im Heartbeat angegeben, mit 'rate' kann man die relative
54 Wahrscheinlichkeit der Spells untereinander steuern.
Zesstra18626972017-01-31 10:38:27 +010055
Zesstracc3ff952018-03-05 22:04:49 +010056 (*) Relative Haeufigkeit heisst, dass sich alle 'rate' der Spells
57 aufaddieren und ein einzelnes 'rate' dann in Relation zur Gesamtsumme
58 steht. D.h. drei Spells mit 80, 10, 10 (Summe 100) haben die selben
59 Aufruf-Wahrscheinlichkeiten wie drei Spells mit 120, 15, 15 oder drei
60 Spells mit 160, 20, 20.
Zesstra18626972017-01-31 10:38:27 +010061
Zesstracc3ff952018-03-05 22:04:49 +010062 Ein Spell wird immer in folgender Reihenfolge abgearbeitet:
63
64 1. Die Texte werden an die Beteiligten ausgegeben.
65 2. Es wird ggf. SpellDefend gerufen (wenn kein SP_PHYSICAL_ATTACK).
66 Abbruch bei Schutz.
67 3. Im Opfer wird Defend() mit den angegebenen Werten aufgerufen.
68 Abbruch bei Tod/Zerstoerung des Opfers.
69 4. Eine Funktion, so definiert, wird ausgefuehrt.
Zesstra18626972017-01-31 10:38:27 +010070
71BEMERKUNGEN
72-----------
Zesstra18626972017-01-31 10:38:27 +010073
Zesstracc3ff952018-03-05 22:04:49 +010074 TextForOthers wird vor der Ausgabe der Meldung durch replace_personal()
75 geschickt, d.h. es koennen Platzhalter wie @WER1, @WEMQP1 und aehnliche
76 verwendet werden (siehe auch die Manpage von replace_personal()).
77 Da Ersetzungen nur fuer das Gegnerobjekt beruecksichtigt werden, koennen
78 nur Platzhalter mit Endziffer 1 verwendet werden. Die Ersetzungen werden
79 so gesteuert, dass die eingefuegten Namen nach Satzanfaengen automatisch
80 gross geschrieben werden.
81 Frueher wurden statt replace_personal() die Platzhalter @WER, @WESSEN,
82 @WEM, @WEN verwendet. Diese funktionieren weiterhin, sollten aber nicht
83 mehr in neuem Code benutzt werden.
Zesstra18626972017-01-31 10:38:27 +010084
Zesstracc3ff952018-03-05 22:04:49 +010085 In der von AddSpell gerufenen Methode "func" koennen speziellere
86 Sachen mit dem aktuellen Feind angestellt werden. Die Methode
87 muss im selben Objekt definiert sein, sofern der Funktionsname und
88 keine Closure uebergeben wird.
Zesstra18626972017-01-31 10:38:27 +010089
Zesstracc3ff952018-03-05 22:04:49 +010090 Will man einen physischen Angriff ausloesen, MUSS <spellarg> ein Mapping
91 mit ([SP_PHYSICAL_ATTACK: 1]) sein. Bei Uebergeben einer 0 oder Weglassen
92 des Werts wird an Defend das Default '1' (da es Spells sind) uebergeben.
Zesstra18626972017-01-31 10:38:27 +010093
Zesstracc3ff952018-03-05 22:04:49 +010094 Wenn damage<=0 oder rate<0 oder keine Meldungen uebergeben werden, wird
95 der Spell NICHT eingetragen, sondern die Funktion bricht mit Rueckgabe
96 von 0 ab.
Zesstra18626972017-01-31 10:38:27 +010097
98BEISPIELE
99---------
Zesstracc3ff952018-03-05 22:04:49 +0100100code-block::
Zesstra18626972017-01-31 10:38:27 +0100101
Zesstracc3ff952018-03-05 22:04:49 +0100102 // #1 Einfacher NPC mit drei Spells, Gesamtrate = 100, also sind die
103 // Raten direkt als Prozent Aufrufwahrscheinlichkeit lesbar.
104 AddSpell(80, 400,
105 "Der Hexer greift Dich mit einem kleinen Feuerball an.\n",
106 "Der Hexer greift @WEN mit einem kleinen Feuerball an.\n",
Zesstra18626972017-01-31 10:38:27 +0100107 ({DT_FIRE, DT_MAGIC}));
Zesstracc3ff952018-03-05 22:04:49 +0100108 AddSpell(10, 800,
109 "Der Hexer greift Dich mit einem riesigen Feuerball an.\n",
Zesstra18626972017-01-31 10:38:27 +0100110 "Der Hexer greift @WEN mit einem riesigen Feuerball an.\n",
Zesstracc3ff952018-03-05 22:04:49 +0100111 ({DT_FIRE, DT_MAGIC}));
112 AddSpell(8, 100,
113 "Der Hexer piekst Dir in die Augen!",
114 "Der Hexer piekst @WEM in die Augen!", ({DT_PIERCE}),
115 "augen_stechen");
116 AddSpell(2, 5, (string)0, (string)0, (string*)0, "salto_mortalis");
Zesstra18626972017-01-31 10:38:27 +0100117
Zesstracc3ff952018-03-05 22:04:49 +0100118 (Kleiner Feuerball mit 80% Wahrscheinlichkeit, riesiger mit 10%,
119 "augen_stechen" mit 8%, "salto_mortalis" mit 2%)
Zesstra18626972017-01-31 10:38:27 +0100120
Zesstracc3ff952018-03-05 22:04:49 +0100121code-block::
122
123 // Die Funktion "augen_stechen" kann dann so aussehen:
124 void augen_stechen(object enemy, int damage, mixed dam_types )
125 {
126 if (damage>10 && !enemy->QueryProp(P_BLIND))
127 {
128 enemy->SetProp(P_BLIND, 1);
129 if(enemy->QueryProp(P_BLIND))
130 tell_object(enemy, "Du bist nun blind!\n");
Zesstra18626972017-01-31 10:38:27 +0100131 }
Zesstracc3ff952018-03-05 22:04:49 +0100132 }
Zesstra18626972017-01-31 10:38:27 +0100133
Zesstracc3ff952018-03-05 22:04:49 +0100134code-block::
Zesstra18626972017-01-31 10:38:27 +0100135
Zesstracc3ff952018-03-05 22:04:49 +0100136 // Zur Funktion "salto_mortalis" gibt es keine Meldungen, dennoch
137 // wird Defend mit: enemy->Defend(5, ({DT_MAGIC}), 1, this_object())
138 // gerufen!
139 void salto_mortalis(object enemy, int damage, mixed dam_types )
140 {
141 // dem geneigten Leser ueberlassen, den Gegner zu toeten
142 }
Zesstra18626972017-01-31 10:38:27 +0100143
Zesstracc3ff952018-03-05 22:04:49 +0100144 // #2 Physische Angriffe: die Ruestungen sollen beruecksichtigt werden!
145 // SP_PHYSICAL_ATTACK muss in einem Mapping auf 1 gesetzt werden,
146 // damit Ruestungen physisch wirken (ansonsten werden nur ihre
147 // DefendFuncs() ausgewertet). Es muss auch eine physische Schadensart
148 // enthalten sein!
149 // SpellDefend() wird bei diesem Flag nicht mehr am Gegner gerufen.
Zesstra18626972017-01-31 10:38:27 +0100150
Zesstracc3ff952018-03-05 22:04:49 +0100151 AddSpell(100, 200+random(200),
152 "Die kleine Ratte beisst Dich!\n",
153 "@WER wird von einer kleinen Ratte gebissen!\n",
154 ({DT_PIERCE, DT_POISON}), (string)0,
155 ([SP_PHYSICAL_ATTACK:1]));
Zesstra18626972017-01-31 10:38:27 +0100156
Zesstracc3ff952018-03-05 22:04:49 +0100157 // #3 Selektive physische Angriffe (siehe auch man Defend_bsp):
158 // Will man erreichen, dass einige Ruestungen wirken, andere aber
159 // nicht oder nur teilweise, kann man das ueber die Spellparameter
160 // ausfuehrlich steuern:
Zesstra18626972017-01-31 10:38:27 +0100161
Zesstracc3ff952018-03-05 22:04:49 +0100162 // erstmal fuer alle Ruestungsarten einen Schutz von 0% einstellen:
163 mapping armours = map_indices(VALID_ARMOUR_CLASS, #'!);
164 armours[AT_TROUSERS] = 120; // 120% Schutz durch Hosen
165 armours[AT_BOOT] = 30; // 30% Schutz durch Stiefel
166
167 AddSpell(20,200+random(200),
168 "Die kleine Ratte beisst Dir blitzschnell in die Wade!\n",
169 "@WER wird von einer kleinen Ratte in die Wade gebissen!\n",
170 ({DT_PIERCE, DT_POISON}), (string)0,
171 ([SP_PHYSICAL_ATTACK:1, SP_NO_ACTIVE_DEFENSE:1,
172 SP_REDUCE_ARMOUR: armours]));
173
174 // SP_NO_ACTIVE_DEFENSE = 1 schaltet aktive Abwehr (Karate/Klerus) ab
175 // SP_REDUCE_ARMOUR enthaelt eine Liste von Ruestungstypen mit ihren
176 // neuen Wirkungsgraden in Prozent. Nicht enthaltene Ruestungen haben
177 // weiterhin 100% Schutzwirkung.
Zesstra18626972017-01-31 10:38:27 +0100178
179SIEHE AUCH
180----------
Zesstra18626972017-01-31 10:38:27 +0100181
Zesstracc3ff952018-03-05 22:04:49 +0100182 Sonstiges: :doc:`SpellAttack`, :doc:`SpellDefend`, :doc:`Defend`,
183 :doc:`QueryDefend`, :doc:`SelectEnemy`, :doc:`ReceiveMsg`,
184 :doc:`../sefun/replace_personal`
185
186 Properties: :doc:`../props/P_DISABLE_ATTACK`, :doc:`../props/P_SPELLRATE`, :doc:`../props/P_AGGRESSIVE`
187
Zesstra18626972017-01-31 10:38:27 +0100188
Zesstradee2e562018-02-28 23:51:56 +0100189Letzte Aenderung: 15.02.2018, Bugfix