blob: 602292fa6ae4c143ab2fffb2c199eb27a6bf108f [file] [log] [blame]
Zesstra18626972017-01-31 10:38:27 +01001AddSpell()
2==========
3
4FUNKTION
5--------
6::
7
8 varargs int AddSpell(int rate, int damage, string TextForEnemy,
9 string TextForOthers, string|string* dam_type,
10 string|closure func, int|mapping spellarg)
11
12DEFINIERT IN
13------------
14::
15
16 /std/npc/combat.c
17
18ARGUMENTE
19---------
20::
21
22 rate - Relative Haeufigkeit der Anwendung (*),
23 muss >= 0 sein
24 damage - Der Schadenswert fuer Defend(),
25 muss > 0 sein
26 TextForEnemy - Text, den der Feind erhalten soll
27 TextForOthers - Text, den andere im Raum erhalten sollen
28 dam_type - Schadenstyp(en) fuer Defend(),
29 (Default: ({DT_MAGIC}) )
30 func - Funktionsname oder Closure, die nach Anwendung
31 aufgerufen werden soll
32 (Optional, bekommt als Argumente object enemy,
33 int real_damage, string* dam_type)
34 spellarg - Spell-Argument fuer Defend(), Default ist "1"
35
36BESCHREIBUNG
37------------
38::
39
40 Ermoeglicht einfache Angriffs-Zaubersprueche fuer NPCs. Das Ausfuehren von
41 Spells verursacht bei dem NPC keine KP-Kosten.
42
43 Mit P_SPELLRATE wird die generelle Wahrscheinlichkeit der Ausfuehrung
44 solcher Spells im Heartbeat angegeben, mit 'rate' kann man die relative
45 Wahrscheinlichkeit der Spells untereinander steuern.
46
47 (*) Relative Haeufigkeit heisst, dass sich alle 'rate' der Spells
48 aufaddieren und ein einzelnes 'rate' dann in Relation zur Gesamtsumme
49 steht. D.h. drei Spells mit 80, 10, 10 (Summe 100) haben die selben
50 Aufruf-Wahrscheinlichkeiten wie drei Spells mit 120, 15, 15 oder drei
51 Spells mit 160, 20, 20.
52
53 Ein Spell wird immer in folgender Reihenfolge abgearbeitet:
54 1. Die Texte werden an die Beteiligten ausgegeben.
55 2. Es wird ggf. SpellDefend gerufen (wenn kein SP_PHYSICAL_ATTACK).
56 Abbruch bei Schutz.
57 3. Im Opfer wird Defend() mit den angegebenen Werten aufgerufen.
58 Abbruch bei Tod/Zerstoerung des Opfers.
59 4. Eine Funktion, so definiert, wird ausgefuehrt.
60
61BEMERKUNGEN
62-----------
63::
64
65 TextForOthers wird vor der Ausgabe der Meldung durch replace_personal()
66 geschickt, d.h. es koennen Platzhalter wie @WER1, @WEMQP1 und aehnliche
67 verwendet werden (siehe auch die Manpage von replace_personal()).
68 Da Ersetzungen nur fuer das Gegnerobjekt beruecksichtigt werden, koennen
69 nur Platzhalter mit Endziffer 1 verwendet werden. Die Ersetzungen werden
70 so gesteuert, dass die eingefuegten Namen nach Satzanfaengen automatisch
71 gross geschrieben werden.
72 Frueher wurden statt replace_personal() die Platzhalter @WER, @WESSEN,
73 @WEM, @WEN verwendet. Diese funktionieren weiterhin, sollten aber nicht
74 mehr in neuem Code benutzt werden.
75
76 In der von AddSpell gerufenen Methode "func" koennen speziellere
77 Sachen mit dem aktuellen Feind angestellt werden koennen. Die Methode
78 muss im selben Objekt definiert sein, sofern der Funktionsname und
79 keine Closure uebergeben wird.
80
81 Will man einen physischen Angriff ausloesen, MUSS <spellarg> ein Mapping
82 mit ([SP_PHYSICAL_ATTACK: 1]) sein. Bei Uebergeben einer 0 oder Weglassen
83 des Werts wird an Defend das Default '1' (da es Spells sind) uebergeben.
84
85 Wenn damage<=0 oder rate<0 oder keine Meldungen uebergeben werden, wird
86 der Spell NICHT eingetragen, sondern die Funktion bricht mit Rueckgabe
87 von 0 ab.
88
89BEISPIELE
90---------
91::
92
93 // #1 Einfacher NPC mit drei Spells, Gesamtrate = 100, also sind die
94 // Raten direkt als Prozent Aufrufwahrscheinlichkeit lesbar.
95 AddSpell(80, 400,
96 "Der Hexer greift Dich mit einem kleinen Feuerball an.\n",
97 "Der Hexer greift @WEN mit einem kleinen Feuerball an.\n",
98 ({DT_FIRE, DT_MAGIC}));
99 AddSpell(10, 800,
100 "Der Hexer greift Dich mit einem riesigen Feuerball an.\n",
101 "Der Hexer greift @WEN mit einem riesigen Feuerball an.\n",
102 ({DT_FIRE, DT_MAGIC}));
103 AddSpell(8, 100,
104 "Der Hexer piekst Dir in die Augen!",
105 "Der Hexer piekst @WEM in die Augen!", ({DT_PIERCE}),
106 "augen_stechen");
107 AddSpell(2, 5, (string)0, (string)0, (string*)0, "salto_mortalis");
108
109 (Kleiner Feuerball mit 80% Wahrscheinlichkeit, riesiger mit 10%,
110 "augen_stechen" mit 8%, "salto_mortalis" mit 2%)
111
112 // Die Funktion "augen_stechen" kann dann so aussehen:
113 void augen_stechen(object enemy, int damage, mixed dam_types ) {
114 if (damage>10 && !enemy->QueryProp(P_BLIND)) {
115 enemy->SetProp(P_BLIND, 1);
116 if(enemy->QueryProp(P_BLIND))
117 tell_object(enemy, "Du bist nun blind!\n");
118 }
119 }
120
121 // Zur Funktion "salto_mortalis" gibt es keine Meldungen, dennoch
122 // wird Defend mit: enemy->Defend(5, ({DT_MAGIC}), 1, this_object())
123 // gerufen!
124 void salto_mortalis(object enemy, int damage, mixed dam_types ) {
125 // dem geneigten Leser ueberlassen, den Gegner zu toeten
126 }
127
128 // #2 Physische Angriffe: die Ruestungen sollen beruecksichtigt werden!
129 // SP_PHYSICAL_ATTACK muss in einem Mapping auf 1 gesetzt werden,
130 // damit Ruestungen physisch wirken (ansonsten werden nur ihre
131 // DefendFuncs() ausgewertet). Es muss auch eine physische Schadensart
132 // enthalten sein!
133 // SpellDefend() wird bei diesem Flag nicht mehr am Gegner gerufen.
134 AddSpell(100, 200+random(200),
135 "Die kleine Ratte beisst Dich!\n",
136 "@WER wird von einer kleinen Ratte gebissen!\n",
137 ({DT_PIERCE, DT_POISON}), (string)0,
138 ([SP_PHYSICAL_ATTACK:1]));
139
140 // #3 Selektive physische Angriffe (siehe auch man Defend_bsp):
141 // Will man erreichen, dass einige Ruestungen wirken, andere aber
142 // nicht oder nur teilweise, kann man das ueber die Spellparameter
143 // ausfuehrlich steuern:
144
145 // erstmal fuer alle Ruestungsarten einen Schutz von 0% einstellen:
146 mapping armours = map_indices(VALID_ARMOUR_CLASS, #'!);
147 armours[AT_TROUSERS] = 120; // 120% Schutz durch Hosen
148 armours[AT_BOOT] = 30; // 30% Schutz durch Stiefel
149
150 AddSpell(20,200+random(200),
151 "Die kleine Ratte beisst Dir blitzschnell in die Wade!\n",
152 "@WER wird von einer kleinen Ratte in die Wade gebissen!\n",
153 ({DT_PIERCE, DT_POISON}), (string)0,
154 ([SP_PHYSICAL_ATTACK:1, SP_NO_ACTIVE_DEFENSE:1,
155 SP_REDUCE_ARMOUR: armours]));
156
157 // SP_NO_ACTIVE_DEFENSE = 1 schaltet aktive Abwehr (Karate/Klerus) ab
158 // SP_REDUCE_ARMOUR enthaelt eine Liste von Ruestungstypen mit ihren
159 // neuen Wirkungsgraden in Prozent. Nicht enthaltene Ruestungen haben
160 // weiterhin 100% Schutzwirkung.
161
162SIEHE AUCH
163----------
164::
165
166 Sonstiges: SpellAttack, SpellDefend, Defend, QueryDefend, SelectEnemy
167 replace_personal
168 Properties: P_DISABLE_ATTACK, P_SPELLRATE, P_AGGRESSIVE
169 Abwehr: Defend, Defend_bsp, SpellDefend
170 Methoden: modifiers
171
172Zuletzt geaendert: 20.11.2016, Bugfix
173