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