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