blob: bd2ad4d259d7a9883bcaf035226abe2e27b4c37b [file] [log] [blame]
Zesstra18626972017-01-31 10:38:27 +01001P_NO_ATTACK
2===========
3
4NAME
5----
6::
7
8 P_NO_ATTACK "no_attack"
9
10DEFINIERT IN
11------------
12::
13
14 <living/combat.h>
15
16BESCHREIBUNG
17------------
18::
19
20 Wenn ein NPC nicht angreifbar sein soll (weil er zum Beispiel in einer
21 Gilde oder einer Quest Informationen vermittelt oder aehnlichen), sollte
22 man diese Property auf einen Wert ungleich Null setzen. Sie wird immer
23 abgefragt, wenn ermittelt wird, ob ein Lebewesen prinzipiell angreifbar
24 ist. D.h. auch, dass nach Abfragen von P_NO_ATTACK _nicht_ immer ein
25 Kampf gestartet wird und dass man dabei _nicht_ im Kampf sein muss!
26
27 Gibt man hier einen String an (mit einem Satzzeichen und "\n" abge-
28 schlossen), wird dieser bei direkten Angriffen ausgegeben. Bei anderen
29 Datentypen wird eine Defaultmeldung ausgegeben. Die Defaultmeldung
30 lautet: "<Name> laesst sich nicht angreifen!\n"
31
32 Mit direkten Angriffen sind 'toete <name>' und Angriffszauber gemeint
33 (bzw. alles, was living/life::Kill(), spellbook::TryAttackSpell(),
34 spellbook::TryDefaultAttackSpell() und spellbook::FindEnemyVictim()
35 aufruft).
36
37ACHTUNG
38-------
39::
40
41 1) Zum Thema QueryMethoden auf P_NO_ATTACK
42 Grundsaetzlich legt man entweder eine Query-Methode auf P_NO_ATTACK:
43 Set(P_NO_ATTACK, #'my_no_attack, F_QUERY_METHOD);
44 oder definiert eine Funktion _query_no_attack() im NPC.
45
46 Wie muss nun eine solche Funktion aussehen? Z.B.:
47
48
49
50 int|string my_no_attack() {
51 if (!objectp(this_player())) return 0;
52 if (opfer==getuid(this_player()) || this_player()==this_object())
53 return(0);
54 return(1); //nicht angreifbar
55 }
56
57 Diese Funktion macht den NPC nun nur fuer den Spieler 'opfer' angreifbar.
58 Stattdessen kann natuerlich auch jede andere Bedingung genutzt werden.
59
60 Aber warum die zweite Bedingung, this_player()==this_object()?
61 Warum sollte der NPC sich selber angreifen duerfen?
62
63 Das liegt an folgenden 2 Dingen:
64
65 1. Kaempfer kriegen bei eingeschaltetem Fokus Probleme, wenn man das
66 nicht macht. Das liegt an folgendem: Wenn der NPC angreift, ruft er
67 natuerlich Defend() im Spieler auf. Dieses schaut nach, ob der Spieler
68 den Skill SK_MAGICAL_DEFENSE hat. Dieser ist bei Kaempfern das Parieren.
69 Dieses schaut nach, ob der Fokus aktiv ist, wenn ja, wird dem
70 ge'fokus'te Gegner besonders gut ausgewichen. Zu diesem Zweck wird die
71 Liste der Feind im Raum erstellt mit PresentEnemies() abgerufen. Dieses
72 fragt aber in allen (potentiellen) Gegnern P_NO_ATTACK ab und beendet
73 den Kampf mit allen Gegnern, die nicht angreifbar sind. Bei dieser
74 Abfrage ist jedoch TP==NPC, weil der ja angreift. Wenn er nun 1
75 zurueckgibt, wird der Kampf an der Stelle beendet.
76
77 2. Wenn der NPC den Spieler angreift, wird im Spieler InsertEnemy(NPC)
78 aufgerufen. Auch diesem Fall findet die Abfrage von P_NO_ATTACK statt,
79 da InsertEnemy() ja erstmal rausfinden muss, ob der Gegner angreifbar
80 ist, bevor er in die Feindliste eingetragen wird. Da der NPC den
81 Angriff beginnt, ist TP der NPC. Wenn die Query-Methode auf P_NO_ATTACK
82 hier abbricht, wird der NPC nicht in die Feindliste des Spielers
83 eingetragen. Dann bekaempft der NPC den Spieler, aber der Spieler nicht
84 den NPC.
85
86
87 2) P_NO_ATTACK des NPC wird z.B. beim Kampf eines Kaempfers mit dem NPC
88 pro Kampfrunde um die 10mal abgerufen. Wenn der Kaempfer nur eine
89 Attacke macht. Wenn er noch Sonderattacken machen, Spells ausfuehrt,
90 etc. wird das noch mehr. D.h. was auch immer ihr in der Query-Methode
91 im NPC macht:
92 Es sollte schnell sein, jeder Tick an Rechenzeit zaehlt hier xfach!
93
94LETZTE AENDERUNG
95----------------
96::
97
9809.11.2015, Arathorn
99