server/src/kernel/magic.h

393 lines
15 KiB
C
Raw Normal View History

2010-08-08 10:06:34 +02:00
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#ifndef H_KRNL_MAGIC
#define H_KRNL_MAGIC
#ifdef __cplusplus
extern "C" {
#endif
#include "curse.h"
2011-03-07 08:02:35 +01:00
struct fighter;
struct building;
struct quicklist;
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
2011-03-07 08:02:35 +01:00
#define MAXCOMBATSPELLS 3 /* PRECOMBAT COMBAT POSTCOMBAT */
#define MAX_SPELLRANK 9 /* Standard-Rank 5 */
#define MAXINGREDIENT 5 /* bis zu 5 Komponenten pro Zauber */
#define CHAOSPATZERCHANCE 10 /* +10% Chance zu Patzern */
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
#define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */
#define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */
/* ------------------------------------------------------------- */
/* Spruchparameter
* Wir suchen beim Parsen des Befehls erstmal nach lokalen Objekten,
* erst in verify_targets wird dann global gesucht, da in den meisten
* F<EFBFBD>llen das Zielobjekt lokal sein d<EFBFBD>rfte */
/* siehe auch typ_t in objtypes.h */
2011-03-07 08:02:35 +01:00
typedef enum {
SPP_REGION, /* "r" : findregion(x,y) -> *region */
SPP_UNIT, /* - : atoi36() -> int */
SPP_TEMP, /* - : temp einheit */
SPP_BUILDING, /* - : atoi() -> int */
SPP_SHIP, /* - : atoi() -> int */
SPP_STRING, /* "c" */
2011-03-07 17:26:50 +01:00
SPP_INT /* "i" : atoi() -> int */
2011-03-07 08:02:35 +01:00
} sppobj_t;
typedef struct spllprm {
sppobj_t typ;
int flag;
union {
struct region *r;
struct unit *u;
struct building *b;
struct ship *sh;
char *s;
char *xs;
int i;
} data;
} spllprm;
typedef struct spellparameter {
int length; /* Anzahl der Elemente */
struct spllprm **param;
} spellparameter;
typedef struct strarray {
int length; /* Anzahl der Elemente */
char **strings;
} strarray;
2010-08-08 10:06:34 +02:00
#define TARGET_RESISTS (1<<0)
#define TARGET_NOTFOUND (1<<1)
/* ------------------------------------------------------------- */
/* Magierichtungen */
2011-03-07 08:02:35 +01:00
extern const char *magic_school[MAXMAGIETYP];
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
/* Magier:
* - Magierichtung
* - Magiepunkte derzeit
* - Malus (neg. Wert)/ Bonus (pos. Wert) auf maximale Magiepunkte
* (k<EFBFBD>nnen sich durch Questen absolut ver<EFBFBD>ndern und durch Gegenst<EFBFBD>nde
* tempor<EFBFBD>r). Auch f<EFBFBD>r Artefakt ben<EFBFBD>tigt man permanente MP
* - Anzahl bereits gezauberte Spr<EFBFBD>che diese Runde
* - Kampfzauber (3) (vor/w<EFBFBD>hrend/nach)
* - Spruchliste
*/
typedef struct combatspell {
int level;
const struct spell *sp;
} combatspell;
typedef struct spell_names {
struct spell_names *next;
const struct locale *lang;
struct tnode * tokens;
} spell_names;
typedef struct sc_mage {
magic_t magietyp;
int spellpoints;
int spchange;
int spellcount;
combatspell combatspells[MAXCOMBATSPELLS];
struct quicklist *spells;
struct spell_names * spellnames;
} sc_mage;
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
/* Zauberliste */
2011-03-07 08:02:35 +01:00
typedef struct castorder {
struct castorder *next;
union {
struct unit *u;
struct fighter *fig;
} magician; /* Magier (kann vom Typ struct unit oder fighter sein) */
struct unit *familiar; /* Vertrauter, gesetzt, wenn der Spruch durch
den Vertrauten gezaubert wird */
const struct spell *sp; /* Spruch */
int level; /* gew<65>nschte Stufe oder Stufe des Magiers */
double force; /* St<53>rke des Zaubers */
struct region *rt; /* Zielregion des Spruchs */
int distance; /* Entfernung zur Zielregion */
struct order *order; /* Befehl */
struct spellparameter *par; /* f<>r weitere Parameter */
} castorder;
2010-08-08 10:06:34 +02:00
/* irgendwelche zauber: */
2011-03-07 08:02:35 +01:00
typedef void (*spell_f) (void *);
2010-08-08 10:06:34 +02:00
/* normale zauber: */
2011-03-07 08:02:35 +01:00
typedef int (*nspell_f) (castorder *);
2010-08-08 10:06:34 +02:00
/* kampfzauber: */
2011-03-07 08:02:35 +01:00
typedef int (*cspell_f) (struct fighter *, int, double,
const struct spell * sp);
2010-08-08 10:06:34 +02:00
/* zauber-patzer: */
2011-03-07 08:02:35 +01:00
typedef void (*pspell_f) (castorder *);
typedef struct spell_component {
const struct resource_type *type;
int amount;
int cost;
} spell_component;
typedef struct spell {
unsigned int id;
2011-03-07 08:02:35 +01:00
char *sname;
char *syntax;
char *parameter;
magic_t magietyp;
int sptyp;
int rank; /* Reihenfolge der Zauber */
int level; /* Stufe des Zaubers */
struct spell_component *components;
spell_f sp_function;
void (*patzer) (castorder *);
} spell;
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
/* besondere Spruchtypen */
2011-03-07 08:02:35 +01:00
#define FARCASTING (1<<0) /* ZAUBER [struct region x y] */
#define SPELLLEVEL (1<<1) /* ZAUBER [STUFE x] */
2010-08-08 10:06:34 +02:00
/* ID's k<>nnen zu drei unterschiedlichen Entit<69>ten geh<65>ren: Einheiten,
* Geb<EFBFBD>uden und Schiffen. */
2011-03-07 08:02:35 +01:00
#define UNITSPELL (1<<2) /* ZAUBER .. <Einheit-Nr> [<Einheit-Nr> ..] */
#define SHIPSPELL (1<<3) /* ZAUBER .. <Schiff-Nr> [<Schiff-Nr> ..] */
#define BUILDINGSPELL (1<<4) /* ZAUBER .. <Gebaeude-Nr> [<Gebaeude-Nr> ..] */
2010-08-08 10:06:34 +02:00
#define REGIONSPELL (1<<5) /* wirkt auf struct region */
2011-03-07 08:02:35 +01:00
#define PRECOMBATSPELL (1<<7) /* PR<50>KAMPFZAUBER .. */
#define COMBATSPELL (1<<8) /* KAMPFZAUBER .. */
#define POSTCOMBATSPELL (1<<9) /* POSTKAMPFZAUBER .. */
2010-08-08 10:06:34 +02:00
#define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL)
2011-03-07 08:02:35 +01:00
#define OCEANCASTABLE (1<<10) /* K<>nnen auch nicht-Meermenschen auf
hoher See zaubern */
2010-08-08 10:06:34 +02:00
#define ONSHIPCAST (1<<11) /* kann auch auf von Land ablegenden
2011-03-07 08:02:35 +01:00
Schiffen stehend gezaubert werden */
2010-08-08 10:06:34 +02:00
/* */
#define NOTFAMILIARCAST (1<<12)
#define TESTRESISTANCE (1<<13) /* alle Zielobjekte (u, s, b, r) auf
2011-03-07 08:02:35 +01:00
Magieresistenz pr<EFBFBD>fen */
2010-08-08 10:06:34 +02:00
#define SEARCHLOCAL (1<<14) /* Ziel muss in der target_region sein */
#define TESTCANSEE (1<<15) /* alle Zielunits auf cansee pr<70>fen */
#define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */
/* Flag Spruchkostenberechnung: */
2011-03-07 08:02:35 +01:00
enum {
SPC_FIX, /* Fixkosten */
SPC_LEVEL, /* Komponenten pro Level */
SPC_LINEAR /* Komponenten pro Level und m<>ssen vorhanden sein */
};
enum {
RS_DUMMY,
RS_FARVISION,
MAX_REGIONSPELLS
};
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
/* Prototypen */
2011-03-07 08:02:35 +01:00
void magic(void);
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
void regeneration_magiepunkte(void);
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
extern struct attrib_type at_seenspell;
extern struct attrib_type at_mage;
extern struct attrib_type at_familiarmage;
extern struct attrib_type at_familiar;
extern struct attrib_type at_clonemage;
extern struct attrib_type at_clone;
extern struct attrib_type at_reportspell;
extern struct attrib_type at_icastle;
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
typedef struct icastle_data {
const struct building_type *type;
struct building *building; /* reverse pointer to dissolve the object */
int time;
} icastle_data;
2010-08-08 10:06:34 +02:00
/* ------------------------------------------------------------- */
/* Kommentare:
*
* Spruchzauberrei und Gegenstandszauberrei werden getrennt behandelt.
* Das macht u.a. bestimmte Fehlermeldungen einfacher, das
* identifizieren der Komponennten <EFBFBD>ber den Missversuch ist nicht
* m<EFBFBD>glich
* Spruchzauberrei: 'ZAUBER [struct region x y] [STUFE a] "Spruchname" [Ziel]'
* Gegenstandszauberrei: 'BENUTZE "Gegenstand" [Ziel]'
*
* Die Funktionen:
*/
/* Magier */
2011-03-07 08:02:35 +01:00
sc_mage *create_mage(struct unit *u, magic_t mtyp);
/* macht die struct unit zu einem neuen Magier: legt die struct u->mage an
* und initialisiert den Magiertypus mit mtyp. */
sc_mage *get_mage(const struct unit *u);
/* gibt u->mage zur<75>ck, bei nicht-Magiern *NULL */
boolean is_mage(const struct unit *u);
/* gibt true, wenn u->mage gesetzt. */
boolean is_familiar(const struct unit *u);
/* gibt true, wenn eine Familiar-Relation besteht. */
2010-08-08 10:06:34 +02:00
/* Spr<70>che */
2011-03-07 08:02:35 +01:00
int get_combatspelllevel(const struct unit *u, int nr);
/* versucht, eine eingestellte maximale Kampfzauberstufe
* zur<EFBFBD>ckzugeben. 0 = Maximum, -1 u ist kein Magier. */
const spell *get_combatspell(const struct unit *u, int nr);
/* gibt den Kampfzauber nr [pre/kampf/post] oder NULL zur<75>ck */
void set_combatspell(struct unit *u, spell * sp, struct order *ord,
int level);
/* setzt Kampfzauber */
void unset_combatspell(struct unit *u, spell * sp);
/* l<>scht Kampfzauber */
void add_spell(struct quicklist **slistp, spell * sp);
void add_spellname(sc_mage * mage, const spell * sp);
2011-03-07 08:02:35 +01:00
/* f<>gt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */
boolean u_hasspell(const struct unit *u, const struct spell *sp);
/* pr<70>ft, ob der Spruch in der Spruchliste der Einheit steht. */
void update_spellbook(struct faction *f, int level);
void updatespelllist(struct unit *u);
/* f<>gt alle Zauber des Magiegebietes der Einheit, deren Stufe kleiner
* als das aktuelle Magietalent ist, in die Spruchliste der Einheit
* ein */
boolean knowsspell(const struct region *r, const struct unit *u,
const spell * sp);
/* pr<70>ft, ob die Einheit diesen Spruch gerade beherrscht, dh
* mindestens die erforderliche Stufe hat. Hier k<EFBFBD>nnen auch Abfragen
* auf spezielle Antimagiezauber auf Regionen oder Einheiten eingef<EFBFBD>gt
* werden
*/
2010-08-08 10:06:34 +02:00
/* Magiepunkte */
2011-03-07 08:02:35 +01:00
int get_spellpoints(const struct unit *u);
/* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zur<75>ck */
void set_spellpoints(struct unit *u, int sp);
/* setzt die Magiepunkte auf sp */
int change_spellpoints(struct unit *u, int mp);
/* ver<65>ndert die Anzahl der Magiepunkte der Einheit um +mp */
int max_spellpoints(const struct region *r, const struct unit *u);
/* gibt die aktuell maximal m<>glichen Magiepunkte der Einheit zur<75>ck */
int change_maxspellpoints(struct unit *u, int csp);
/* ver<65>ndert die maximalen Magiepunkte einer Einheit */
2010-08-08 10:06:34 +02:00
/* Zaubern */
2011-03-07 08:02:35 +01:00
extern double spellpower(struct region *r, struct unit *u, const spell * sp,
int cast_level, struct order *ord);
/* ermittelt die St<53>rke eines Spruchs */
boolean fumble(struct region *r, struct unit *u, const spell * sp,
int cast_level);
/* true, wenn der Zauber misslingt, bei false gelingt der Zauber */
typedef struct spellrank {
struct castorder *begin;
struct castorder **end;
} spellrank;
castorder *new_castorder(void *u, struct unit *familiar, const spell * sp,
struct region *r, int lev, double force, int distance, struct order *ord,
spellparameter * p);
/* Zwischenspreicher f<>r Zauberbefehle, notwendig f<>r Priorit<69>ten */
void add_castorder(struct spellrank *cll, struct castorder *co);
/* H<>nge c-order co an die letze c-order von cll an */
void free_castorders(struct castorder *co);
/* Speicher wieder freigeben */
2010-08-08 10:06:34 +02:00
/* Pr<50>froutinen f<>r Zaubern */
2011-03-07 08:02:35 +01:00
int countspells(struct unit *u, int step);
/* erh<72>ht den Counter f<>r Zauberspr<70>che um 'step' und gibt die neue
* Anzahl der gezauberten Spr<EFBFBD>che zur<EFBFBD>ck. */
int spellcost(struct unit *u, const spell * sp);
/* gibt die f<>r diesen Spruch derzeit notwendigen Magiepunkte auf der
* geringstm<EFBFBD>glichen Stufe zur<EFBFBD>ck, schon um den Faktor der bereits
* zuvor gezauberten Spr<EFBFBD>che erh<EFBFBD>ht */
boolean cancast(struct unit *u, const spell * spruch, int eff_stufe,
int distance, struct order *ord);
/* true, wenn Einheit alle Komponenten des Zaubers (incl. MP) f<>r die
* geringstm<EFBFBD>gliche Stufe hat und den Spruch beherrscht */
void pay_spell(struct unit *u, const spell * sp, int eff_stufe, int distance);
/* zieht die Komponenten des Zaubers aus dem Inventory der Einheit
* ab. Die effektive Stufe des gezauberten Spruchs ist wichtig f<EFBFBD>r
* die korrekte Bestimmung der Magiepunktkosten */
int eff_spelllevel(struct unit *u, const spell * sp, int cast_level,
int distance);
/* ermittelt die effektive Stufe des Zaubers. Dabei ist cast_level
* die gew<EFBFBD>nschte maximale Stufe (im Normalfall Stufe des Magiers,
* bei Farcasting Stufe*2^Entfernung) */
boolean is_magic_resistant(struct unit *magician, struct unit *target, int
resist_bonus);
/* Mapperfunktion f<>r target_resists_magic() vom Typ struct unit. */
extern double magic_resistance(struct unit *target);
/* gibt die Chance an, mit der einem Zauber widerstanden wird. Je
* gr<EFBFBD><EFBFBD>er, desto resistenter ist da Opfer */
boolean target_resists_magic(struct unit *magician, void *obj, int objtyp,
int resist_bonus);
/* gibt false zur<75>ck, wenn der Zauber gelingt, true, wenn das Ziel
* widersteht */
2010-08-08 10:06:34 +02:00
/* Spr<70>che in der struct region */
2011-03-07 08:02:35 +01:00
/* (sind in curse) */
extern struct unit *get_familiar(const struct unit *u);
extern struct unit *get_familiar_mage(const struct unit *u);
extern struct unit *get_clone(const struct unit *u);
extern struct unit *get_clone_mage(const struct unit *u);
extern struct attrib_type at_familiar;
extern struct attrib_type at_familiarmage;
extern void remove_familiar(struct unit *mage);
extern boolean create_newfamiliar(struct unit *mage, struct unit *familiar);
extern void create_newclone(struct unit *mage, struct unit *familiar);
extern struct unit *has_clone(struct unit *mage);
extern const char *spell_info(const struct spell *sp,
const struct locale *lang);
extern const char *spell_name(const struct spell *sp,
const struct locale *lang);
extern const char *curse_name(const struct curse_type *ctype,
const struct locale *lang);
extern struct message *msg_unitnotfound(const struct unit *mage,
struct order *ord, const struct spllprm *spobj);
extern int FactionSpells(void);
extern struct quicklist **get_spelllist(struct sc_mage *mage,
struct faction *f);
extern void write_spells(struct quicklist *slist, struct storage *store);
extern void read_spells(struct quicklist **slistp, magic_t mtype,
struct storage *store);
extern double MagicPower(void);
2010-08-08 10:06:34 +02:00
#ifdef __cplusplus
}
#endif
#endif