Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 1 | AddSpell() |
| 2 | ========== |
| 3 | |
| 4 | FUNKTION |
| 5 | -------- |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 6 | |
Zesstra | dee2e56 | 2018-02-28 23:51:56 +0100 | [diff] [blame] | 7 | 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) |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 10 | |
| 11 | DEFINIERT IN |
| 12 | ------------ |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 13 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 14 | /std/npc/combat.c |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 15 | |
| 16 | ARGUMENTE |
| 17 | --------- |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 18 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 19 | 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 | |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 44 | sinfo - Skillinfomapping, muss SI_SPELL mit den SP_* fuer |
| 45 | den Aufruf von Defend() enthalten |
| 46 | Default ist ([SI_SPELL: ([SP_PHYSICAL_ATTACK: 0]), |
| 47 | SI_MAGIC_TYPE: ({ MT_ANGRIFF }) ]) |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 48 | |
| 49 | BESCHREIBUNG |
| 50 | ------------ |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 51 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 52 | Ermoeglicht einfache Angriffs-Zaubersprueche fuer NPCs. Das Ausfuehren von |
| 53 | Spells verursacht bei dem NPC keine KP-Kosten. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 54 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 55 | Mit P_SPELLRATE wird die generelle Wahrscheinlichkeit der Ausfuehrung |
| 56 | solcher Spells im Heartbeat angegeben, mit 'rate' kann man die relative |
| 57 | Wahrscheinlichkeit der Spells untereinander steuern. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 58 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 59 | (*) Relative Haeufigkeit heisst, dass sich alle 'rate' der Spells |
| 60 | aufaddieren und ein einzelnes 'rate' dann in Relation zur Gesamtsumme |
| 61 | steht. D.h. drei Spells mit 80, 10, 10 (Summe 100) haben die selben |
| 62 | Aufruf-Wahrscheinlichkeiten wie drei Spells mit 120, 15, 15 oder drei |
| 63 | Spells mit 160, 20, 20. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 64 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 65 | Ein Spell wird immer in folgender Reihenfolge abgearbeitet: |
| 66 | |
| 67 | 1. Die Texte werden an die Beteiligten ausgegeben. |
| 68 | 2. Es wird ggf. SpellDefend gerufen (wenn kein SP_PHYSICAL_ATTACK). |
| 69 | Abbruch bei Schutz. |
| 70 | 3. Im Opfer wird Defend() mit den angegebenen Werten aufgerufen. |
| 71 | Abbruch bei Tod/Zerstoerung des Opfers. |
| 72 | 4. Eine Funktion, so definiert, wird ausgefuehrt. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 73 | |
| 74 | BEMERKUNGEN |
| 75 | ----------- |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 76 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 77 | TextForOthers wird vor der Ausgabe der Meldung durch replace_personal() |
| 78 | geschickt, d.h. es koennen Platzhalter wie @WER1, @WEMQP1 und aehnliche |
| 79 | verwendet werden (siehe auch die Manpage von replace_personal()). |
| 80 | Da Ersetzungen nur fuer das Gegnerobjekt beruecksichtigt werden, koennen |
| 81 | nur Platzhalter mit Endziffer 1 verwendet werden. Die Ersetzungen werden |
| 82 | so gesteuert, dass die eingefuegten Namen nach Satzanfaengen automatisch |
| 83 | gross geschrieben werden. |
| 84 | Frueher wurden statt replace_personal() die Platzhalter @WER, @WESSEN, |
| 85 | @WEM, @WEN verwendet. Diese funktionieren weiterhin, sollten aber nicht |
| 86 | mehr in neuem Code benutzt werden. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 87 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 88 | In der von AddSpell gerufenen Methode "func" koennen speziellere |
| 89 | Sachen mit dem aktuellen Feind angestellt werden. Die Methode |
| 90 | muss im selben Objekt definiert sein, sofern der Funktionsname und |
| 91 | keine Closure uebergeben wird. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 92 | |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 93 | Das Mapping <sinfo> beschreibt den Spell fuer das im Gegner aufgerufene |
| 94 | SpellDefend() und Defend(). Es muss ein SI_SPELL fuer das Defend() im |
| 95 | Gegner enthalten. Etwaige SI_SKILLDAMAGE, SI_SKILLDAMAGE_TYPE, und |
| 96 | SI_CLOSURE werden im Mapping durch die Argumente <damage>, <dam_type> und |
| 97 | <func> ueberschrieben. |
| 98 | Es wird empfohlen, SI_MAGIC_TYPE zu nutzen, denn dann werden etwaige |
| 99 | magische Resistenzen des Ziels beruecksichtigt. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 100 | |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 101 | Frueher war das Argument <sinfo> nur das Mapping, was an Defend() uebergeben |
| 102 | wird unter in Skillinfomapping unter dem Key SI_SPELL liegt. Wenn <sinfo> |
| 103 | kein SI_SPELL enthaelt, wird aus Gruenden der Kompatibilitaet ein |
| 104 | Skillinfomapping konstruiert, welches das hier uebergebene <sinfo> unterhalb |
| 105 | des Schluessels SI_SPELL enthaelt: ([ SI_SPELL: sinfo]) |
| 106 | |
| 107 | Will man einen physischen Angriff ausloesen, MUSS in sinfo ein Mapping sein |
| 108 | und unter SI_SPELL ein Mapping mit dem Key SP_PHYSICAL_ATTACK (Wert != 0) |
| 109 | sein. |
| 110 | Bei Uebergeben einer 0 oder Weglassen von <sinfo> wird an Defend der Default |
| 111 | ([SP_PHYSICAL_ATTACK: 0]) (da es Spells sind) uebergeben. |
| 112 | |
| 113 | Wenn damage < 0 oder rate <= 0, wird der Spell NICHT eingetragen, sondern |
| 114 | die Funktion bricht mit Rueckgabe von 0 ab. Ist damage==0, muss eine <func> |
| 115 | angegeben werden. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 116 | |
| 117 | BEISPIELE |
| 118 | --------- |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 119 | code-block:: |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 120 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 121 | // #1 Einfacher NPC mit drei Spells, Gesamtrate = 100, also sind die |
| 122 | // Raten direkt als Prozent Aufrufwahrscheinlichkeit lesbar. |
| 123 | AddSpell(80, 400, |
| 124 | "Der Hexer greift Dich mit einem kleinen Feuerball an.\n", |
| 125 | "Der Hexer greift @WEN mit einem kleinen Feuerball an.\n", |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 126 | ({DT_FIRE, DT_MAGIC})); |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 127 | AddSpell(10, 800, |
| 128 | "Der Hexer greift Dich mit einem riesigen Feuerball an.\n", |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 129 | "Der Hexer greift @WEN mit einem riesigen Feuerball an.\n", |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 130 | ({DT_FIRE, DT_MAGIC})); |
| 131 | AddSpell(8, 100, |
| 132 | "Der Hexer piekst Dir in die Augen!", |
| 133 | "Der Hexer piekst @WEM in die Augen!", ({DT_PIERCE}), |
| 134 | "augen_stechen"); |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 135 | AddSpell(2, 5, 0, 0, 0, "salto_mortalis"); |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 136 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 137 | (Kleiner Feuerball mit 80% Wahrscheinlichkeit, riesiger mit 10%, |
| 138 | "augen_stechen" mit 8%, "salto_mortalis" mit 2%) |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 139 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 140 | code-block:: |
| 141 | |
| 142 | // Die Funktion "augen_stechen" kann dann so aussehen: |
| 143 | void augen_stechen(object enemy, int damage, mixed dam_types ) |
| 144 | { |
| 145 | if (damage>10 && !enemy->QueryProp(P_BLIND)) |
| 146 | { |
| 147 | enemy->SetProp(P_BLIND, 1); |
| 148 | if(enemy->QueryProp(P_BLIND)) |
| 149 | tell_object(enemy, "Du bist nun blind!\n"); |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 150 | } |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 151 | } |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 152 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 153 | code-block:: |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 154 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 155 | // Zur Funktion "salto_mortalis" gibt es keine Meldungen, dennoch |
| 156 | // wird Defend mit: enemy->Defend(5, ({DT_MAGIC}), 1, this_object()) |
| 157 | // gerufen! |
| 158 | void salto_mortalis(object enemy, int damage, mixed dam_types ) |
| 159 | { |
| 160 | // dem geneigten Leser ueberlassen, den Gegner zu toeten |
| 161 | } |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 162 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 163 | // #2 Physische Angriffe: die Ruestungen sollen beruecksichtigt werden! |
| 164 | // SP_PHYSICAL_ATTACK muss in einem Mapping auf 1 gesetzt werden, |
| 165 | // damit Ruestungen physisch wirken (ansonsten werden nur ihre |
| 166 | // DefendFuncs() ausgewertet). Es muss auch eine physische Schadensart |
| 167 | // enthalten sein! |
| 168 | // SpellDefend() wird bei diesem Flag nicht mehr am Gegner gerufen. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 169 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 170 | AddSpell(100, 200+random(200), |
| 171 | "Die kleine Ratte beisst Dich!\n", |
| 172 | "@WER wird von einer kleinen Ratte gebissen!\n", |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 173 | ({DT_PIERCE, DT_POISON}), 0, |
| 174 | ([ SI_SPELL: ([SP_PHYSICAL_ATTACK:1]) ]) ); |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 175 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 176 | // #3 Selektive physische Angriffe (siehe auch man Defend_bsp): |
| 177 | // Will man erreichen, dass einige Ruestungen wirken, andere aber |
| 178 | // nicht oder nur teilweise, kann man das ueber die Spellparameter |
| 179 | // ausfuehrlich steuern: |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 180 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 181 | // erstmal fuer alle Ruestungsarten einen Schutz von 0% einstellen: |
| 182 | mapping armours = map_indices(VALID_ARMOUR_CLASS, #'!); |
| 183 | armours[AT_TROUSERS] = 120; // 120% Schutz durch Hosen |
| 184 | armours[AT_BOOT] = 30; // 30% Schutz durch Stiefel |
| 185 | |
| 186 | AddSpell(20,200+random(200), |
| 187 | "Die kleine Ratte beisst Dir blitzschnell in die Wade!\n", |
| 188 | "@WER wird von einer kleinen Ratte in die Wade gebissen!\n", |
Zesstra | eb3f95e | 2018-12-14 02:00:50 +0100 | [diff] [blame] | 189 | ({DT_PIERCE, DT_POISON}), 0, |
| 190 | ([ SI_SPELL: ([SP_PHYSICAL_ATTACK:1, SP_NO_ACTIVE_DEFENSE:1, |
| 191 | SP_REDUCE_ARMOUR: armours]) |
| 192 | ]) ); |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 193 | |
| 194 | // SP_NO_ACTIVE_DEFENSE = 1 schaltet aktive Abwehr (Karate/Klerus) ab |
| 195 | // SP_REDUCE_ARMOUR enthaelt eine Liste von Ruestungstypen mit ihren |
| 196 | // neuen Wirkungsgraden in Prozent. Nicht enthaltene Ruestungen haben |
| 197 | // weiterhin 100% Schutzwirkung. |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 198 | |
| 199 | SIEHE AUCH |
| 200 | ---------- |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 201 | |
Zesstra | cc3ff95 | 2018-03-05 22:04:49 +0100 | [diff] [blame] | 202 | Sonstiges: :doc:`SpellAttack`, :doc:`SpellDefend`, :doc:`Defend`, |
| 203 | :doc:`QueryDefend`, :doc:`SelectEnemy`, :doc:`ReceiveMsg`, |
| 204 | :doc:`../sefun/replace_personal` |
| 205 | |
| 206 | Properties: :doc:`../props/P_DISABLE_ATTACK`, :doc:`../props/P_SPELLRATE`, :doc:`../props/P_AGGRESSIVE` |
| 207 | |
Zesstra | 1862697 | 2017-01-31 10:38:27 +0100 | [diff] [blame] | 208 | |
Zesstra | dee2e56 | 2018-02-28 23:51:56 +0100 | [diff] [blame] | 209 | Letzte Aenderung: 15.02.2018, Bugfix |