blob: c0e6da7fe8efbdbb1de2ea033bb0e8115b25e9d0 [file] [log] [blame]
Zesstra953f9972017-02-18 15:37:36 +01001
MG Mud User88f12472016-06-24 23:31:02 +02002AddSpell()
Zesstra953f9972017-02-18 15:37:36 +01003**********
MG Mud User88f12472016-06-24 23:31:02 +02004
MG Mud User88f12472016-06-24 23:31:02 +02005
Zesstra953f9972017-02-18 15:37:36 +01006FUNKTION
7========
MG Mud User88f12472016-06-24 23:31:02 +02008
Zesstrabfab6ac2018-08-29 22:36:57 +02009 varargs int AddSpell(int rate, int damage,
10 string|<int|spell>* TextForEnemy, string|<int|string>*
11 TextForOthers, string|string* dam_type, string|closure func,
12 int|mapping spellarg)
MG Mud User88f12472016-06-24 23:31:02 +020013
MG Mud User88f12472016-06-24 23:31:02 +020014
Zesstra953f9972017-02-18 15:37:36 +010015DEFINIERT IN
16============
MG Mud User88f12472016-06-24 23:31:02 +020017
Zesstra953f9972017-02-18 15:37:36 +010018 /std/npc/combat.c
MG Mud User88f12472016-06-24 23:31:02 +020019
MG Mud User88f12472016-06-24 23:31:02 +020020
Zesstra953f9972017-02-18 15:37:36 +010021ARGUMENTE
22=========
MG Mud User88f12472016-06-24 23:31:02 +020023
Zesstra953f9972017-02-18 15:37:36 +010024 rate - Relative Haeufigkeit der Anwendung (*),
Zesstrabfab6ac2018-08-29 22:36:57 +020025 muss >= 0 sein
26
Zesstra953f9972017-02-18 15:37:36 +010027 damage - Der Schadenswert fuer Defend(),
Zesstrabfab6ac2018-08-29 22:36:57 +020028 muss > 0 sein
29
Zesstra953f9972017-02-18 15:37:36 +010030 TextForEnemy - Text, den der Feind erhalten soll
Zesstrabfab6ac2018-08-29 22:36:57 +020031 String <text> oder Array der Form ({<text>,<messagetype>})
32 (Siehe ReceiveMsg())
33
Zesstra953f9972017-02-18 15:37:36 +010034 TextForOthers - Text, den andere im Raum erhalten sollen
Zesstrabfab6ac2018-08-29 22:36:57 +020035 String <text> oder Array der Form ({<text>,<messagetype>})
36 (Siehe ReceiveMsg())
37
Zesstra953f9972017-02-18 15:37:36 +010038 dam_type - Schadenstyp(en) fuer Defend(),
Zesstrabfab6ac2018-08-29 22:36:57 +020039 (Default: ({DT_MAGIC}) fuer Magische und ({DT_BLUDGEON}) fuer
40 physikalische Angriffe)
41
Zesstra953f9972017-02-18 15:37:36 +010042 func - Funktionsname oder Closure, die nach Anwendung
Zesstrabfab6ac2018-08-29 22:36:57 +020043 aufgerufen werden soll (Optional, bekommt als Argumente object
44 enemy, int real_damage, string* dam_type)
45
Zesstra953f9972017-02-18 15:37:36 +010046 spellarg - Spell-Argument fuer Defend(), Default ist "1"
MG Mud User88f12472016-06-24 23:31:02 +020047
MG Mud User88f12472016-06-24 23:31:02 +020048
Zesstra953f9972017-02-18 15:37:36 +010049BESCHREIBUNG
50============
MG Mud User88f12472016-06-24 23:31:02 +020051
Zesstrabfab6ac2018-08-29 22:36:57 +020052 Ermoeglicht einfache Angriffs-Zaubersprueche fuer NPCs. Das
53 Ausfuehren von Spells verursacht bei dem NPC keine KP-Kosten.
MG Mud User88f12472016-06-24 23:31:02 +020054
Zesstrabfab6ac2018-08-29 22:36:57 +020055 Mit P_SPELLRATE wird die generelle Wahrscheinlichkeit der
56 Ausfuehrung solcher Spells im Heartbeat angegeben, mit 'rate' kann
57 man die relative Wahrscheinlichkeit der Spells untereinander
58 steuern.
MG Mud User88f12472016-06-24 23:31:02 +020059
Zesstra953f9972017-02-18 15:37:36 +010060 (*) Relative Haeufigkeit heisst, dass sich alle 'rate' der Spells
Zesstrabfab6ac2018-08-29 22:36:57 +020061 aufaddieren und ein einzelnes 'rate' dann in Relation zur
62 Gesamtsumme steht. D.h. drei Spells mit 80, 10, 10 (Summe 100)
63 haben die selben Aufruf-Wahrscheinlichkeiten wie drei Spells mit
64 120, 15, 15 oder drei Spells mit 160, 20, 20.
MG Mud User88f12472016-06-24 23:31:02 +020065
Zesstra953f9972017-02-18 15:37:36 +010066 Ein Spell wird immer in folgender Reihenfolge abgearbeitet:
Zesstrabfab6ac2018-08-29 22:36:57 +020067
68 1. Die Texte werden an die Beteiligten ausgegeben.
69
70 2. Es wird ggf. SpellDefend gerufen (wenn kein
71 SP_PHYSICAL_ATTACK). Abbruch bei Schutz.
72
73 3. Im Opfer wird Defend() mit den angegebenen Werten aufgerufen.
74 Abbruch bei Tod/Zerstoerung des Opfers.
75
76 4. Eine Funktion, so definiert, wird ausgefuehrt.
MG Mud User88f12472016-06-24 23:31:02 +020077
MG Mud User88f12472016-06-24 23:31:02 +020078
Zesstra953f9972017-02-18 15:37:36 +010079BEMERKUNGEN
80===========
MG Mud User88f12472016-06-24 23:31:02 +020081
Zesstrabfab6ac2018-08-29 22:36:57 +020082 TextForOthers wird vor der Ausgabe der Meldung durch
83 replace_personal() geschickt, d.h. es koennen Platzhalter wie
84 @WER1, @WEMQP1 und aehnliche verwendet werden (siehe auch die
85 Manpage von replace_personal()). Da Ersetzungen nur fuer das
86 Gegnerobjekt beruecksichtigt werden, koennen nur Platzhalter mit
87 Endziffer 1 verwendet werden. Die Ersetzungen werden so gesteuert,
88 dass die eingefuegten Namen nach Satzanfaengen automatisch gross
89 geschrieben werden. Frueher wurden statt replace_personal() die
90 Platzhalter @WER, @WESSEN, @WEM, @WEN verwendet. Diese
91 funktionieren weiterhin, sollten aber nicht mehr in neuem Code
92 benutzt werden.
MG Mud User88f12472016-06-24 23:31:02 +020093
Zesstra953f9972017-02-18 15:37:36 +010094 In der von AddSpell gerufenen Methode "func" koennen speziellere
Zesstrabfab6ac2018-08-29 22:36:57 +020095 Sachen mit dem aktuellen Feind angestellt werden. Die Methode muss
96 im selben Objekt definiert sein, sofern der Funktionsname und keine
97 Closure uebergeben wird.
MG Mud User88f12472016-06-24 23:31:02 +020098
Zesstrabfab6ac2018-08-29 22:36:57 +020099 Will man einen physischen Angriff ausloesen, MUSS <spellarg> ein
100 Mapping mit ([SP_PHYSICAL_ATTACK: 1]) sein. Bei Uebergeben einer 0
101 oder Weglassen des Werts wird an Defend das Default '1' (da es
102 Spells sind) uebergeben.
MG Mud User88f12472016-06-24 23:31:02 +0200103
Zesstrabfab6ac2018-08-29 22:36:57 +0200104 Wenn damage<=0 oder rate<0 oder keine Meldungen uebergeben werden,
105 wird der Spell NICHT eingetragen, sondern die Funktion bricht mit
106 Rueckgabe von 0 ab.
Zesstra953f9972017-02-18 15:37:36 +0100107
108
109BEISPIELE
110=========
111
Zesstrabfab6ac2018-08-29 22:36:57 +0200112code-block:
113
Zesstra953f9972017-02-18 15:37:36 +0100114 // #1 Einfacher NPC mit drei Spells, Gesamtrate = 100, also sind die
115 // Raten direkt als Prozent Aufrufwahrscheinlichkeit lesbar.
116 AddSpell(80, 400,
117 "Der Hexer greift Dich mit einem kleinen Feuerball an.\n",
118 "Der Hexer greift @WEN mit einem kleinen Feuerball an.\n",
Zesstrabfab6ac2018-08-29 22:36:57 +0200119 ({DT_FIRE, DT_MAGIC}));
Zesstra953f9972017-02-18 15:37:36 +0100120 AddSpell(10, 800,
121 "Der Hexer greift Dich mit einem riesigen Feuerball an.\n",
Zesstrabfab6ac2018-08-29 22:36:57 +0200122 "Der Hexer greift @WEN mit einem riesigen Feuerball an.\n",
Zesstra953f9972017-02-18 15:37:36 +0100123 ({DT_FIRE, DT_MAGIC}));
124 AddSpell(8, 100,
125 "Der Hexer piekst Dir in die Augen!",
126 "Der Hexer piekst @WEM in die Augen!", ({DT_PIERCE}),
127 "augen_stechen");
128 AddSpell(2, 5, (string)0, (string)0, (string*)0, "salto_mortalis");
129
130 (Kleiner Feuerball mit 80% Wahrscheinlichkeit, riesiger mit 10%,
Zesstrabfab6ac2018-08-29 22:36:57 +0200131 "augen_stechen" mit 8%, "salto_mortalis" mit 2%)
132
133code-block:
Zesstra953f9972017-02-18 15:37:36 +0100134
135 // Die Funktion "augen_stechen" kann dann so aussehen:
Zesstrabfab6ac2018-08-29 22:36:57 +0200136 void augen_stechen(object enemy, int damage, mixed dam_types )
137 {
138 if (damage>10 && !enemy->QueryProp(P_BLIND))
139 {
Zesstra953f9972017-02-18 15:37:36 +0100140 enemy->SetProp(P_BLIND, 1);
141 if(enemy->QueryProp(P_BLIND))
142 tell_object(enemy, "Du bist nun blind!\n");
143 }
144 }
145
Zesstrabfab6ac2018-08-29 22:36:57 +0200146code-block:
147
Zesstra953f9972017-02-18 15:37:36 +0100148 // Zur Funktion "salto_mortalis" gibt es keine Meldungen, dennoch
149 // wird Defend mit: enemy->Defend(5, ({DT_MAGIC}), 1, this_object())
150 // gerufen!
Zesstrabfab6ac2018-08-29 22:36:57 +0200151 void salto_mortalis(object enemy, int damage, mixed dam_types )
152 {
Zesstra953f9972017-02-18 15:37:36 +0100153 // dem geneigten Leser ueberlassen, den Gegner zu toeten
154 }
155
156 // #2 Physische Angriffe: die Ruestungen sollen beruecksichtigt werden!
157 // SP_PHYSICAL_ATTACK muss in einem Mapping auf 1 gesetzt werden,
158 // damit Ruestungen physisch wirken (ansonsten werden nur ihre
159 // DefendFuncs() ausgewertet). Es muss auch eine physische Schadensart
160 // enthalten sein!
161 // SpellDefend() wird bei diesem Flag nicht mehr am Gegner gerufen.
Zesstrabfab6ac2018-08-29 22:36:57 +0200162
Zesstra953f9972017-02-18 15:37:36 +0100163 AddSpell(100, 200+random(200),
164 "Die kleine Ratte beisst Dich!\n",
165 "@WER wird von einer kleinen Ratte gebissen!\n",
166 ({DT_PIERCE, DT_POISON}), (string)0,
167 ([SP_PHYSICAL_ATTACK:1]));
168
169 // #3 Selektive physische Angriffe (siehe auch man Defend_bsp):
170 // Will man erreichen, dass einige Ruestungen wirken, andere aber
171 // nicht oder nur teilweise, kann man das ueber die Spellparameter
172 // ausfuehrlich steuern:
173
174 // erstmal fuer alle Ruestungsarten einen Schutz von 0% einstellen:
175 mapping armours = map_indices(VALID_ARMOUR_CLASS, #'!);
176 armours[AT_TROUSERS] = 120; // 120% Schutz durch Hosen
177 armours[AT_BOOT] = 30; // 30% Schutz durch Stiefel
178
179 AddSpell(20,200+random(200),
180 "Die kleine Ratte beisst Dir blitzschnell in die Wade!\n",
181 "@WER wird von einer kleinen Ratte in die Wade gebissen!\n",
182 ({DT_PIERCE, DT_POISON}), (string)0,
183 ([SP_PHYSICAL_ATTACK:1, SP_NO_ACTIVE_DEFENSE:1,
Zesstrabfab6ac2018-08-29 22:36:57 +0200184 SP_REDUCE_ARMOUR: armours]));
Zesstra953f9972017-02-18 15:37:36 +0100185
186 // SP_NO_ACTIVE_DEFENSE = 1 schaltet aktive Abwehr (Karate/Klerus) ab
187 // SP_REDUCE_ARMOUR enthaelt eine Liste von Ruestungstypen mit ihren
188 // neuen Wirkungsgraden in Prozent. Nicht enthaltene Ruestungen haben
189 // weiterhin 100% Schutzwirkung.
190
191
192SIEHE AUCH
193==========
194
Zesstra6cadc1b2018-11-15 22:27:32 +0100195 Sonstiges: SpellAttack(), SpellDefend(), Defend(), QueryDefend(),
196 SelectEnemy(), ReceiveMsg(), replace_personal()
MG Mud User88f12472016-06-24 23:31:02 +0200197
Zesstra6cadc1b2018-11-15 22:27:32 +0100198 Properties: P_DISABLE_ATTACK, P_SPELLRATE, P_AGGRESSIVE
Zesstrabfab6ac2018-08-29 22:36:57 +0200199
200Letzte Aenderung: 15.02.2018, Bugfix