#ifndef H_KRNL_MAGIC #define H_KRNL_MAGIC #include #include #include #ifdef __cplusplus extern "C" { #endif #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 */ #define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */ #define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */ struct sc_mage; struct unit; extern const char *magic_school[MAXMAGIETYP]; extern struct attrib_type at_familiar; extern struct attrib_type at_familiarmage; /* ------------------------------------------------------------- */ /* Spruchparameter * Wir suchen beim Parsen des Befehls erstmal nach lokalen Objekten, * erst in verify_targets wird dann global gesucht, da in den meisten * Faellen das Zielobjekt lokal sein duerfte */ /* siehe auch objtype_t in objtypes.h */ 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" */ SPP_INT /* "i" : atoi() -> int */ } 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; #define TARGET_RESISTS (1<<0) #define TARGET_NOTFOUND (1<<1) /* ------------------------------------------------------------- */ /* Magier: * - Magierichtung * - Magiepunkte derzeit * - Malus (neg. Wert)/ Bonus (pos. Wert) auf maximale Magiepunkte * (koennen sich durch Questen absolut veraendern und durch Gegenstaende * temporaer). Auch fuer Artefakt benoetigt man permanente MP * - Anzahl bereits gezauberte Sprueche diese Runde * - Kampfzauber (3) (vor/waehrend/nach) * - Spruchliste */ typedef struct spell_names { struct spell_names *next; const struct locale *lang; void * tokens; } spell_names; /* ------------------------------------------------------------- */ /* Zauberliste */ 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; /* gewuenschte Stufe oder Stufe des Magiers */ double force; /* Staerke des Zaubers */ struct region *_rtarget; /* Zielregion des Spruchs */ int distance; /* Entfernung zur Zielregion */ struct order *order; /* Befehl */ struct spellparameter *par; /* fuer weitere Parameter */ } castorder; struct unit * co_get_caster(const struct castorder * co); struct unit * co_get_magician(const struct castorder * co); struct region * co_get_region(const struct castorder * co); typedef struct spell_component { const struct resource_type *type; int amount; int cost; } spell_component; /* ------------------------------------------------------------- */ /* besondere Spruchtypen */ #define FARCASTING (1<<0) /* ZAUBER [struct region x y] */ #define SPELLLEVEL (1<<1) /* ZAUBER [STUFE x] */ #define OCEANCASTABLE (1<<2) /* Koennen auch nicht-Meermenschen auf hoher See zaubern */ #define ONSHIPCAST (1<<3) /* kann auch auf von Land ablegenden Schiffen stehend gezaubert werden */ #define TESTCANSEE (1<<4) /* alle Zielunits auf cansee pruefen */ /* ID's koennen zu drei unterschiedlichen Entitaeten gehoeren: Einheiten, * Gebaeuden und Schiffen. */ #define UNITSPELL (1<<5) /* ZAUBER .. [ ..] */ #define SHIPSPELL (1<<6) /* ZAUBER .. [ ..] */ #define BUILDINGSPELL (1<<7) /* ZAUBER .. [ ..] */ #define REGIONSPELL (1<<8) /* wirkt auf struct region */ #define GLOBALTARGET (1<<9) /* Ziel kann ausserhalb der region sein */ #define PRECOMBATSPELL (1<<10) /* PRAEKAMPFZAUBER .. */ #define COMBATSPELL (1<<11) /* KAMPFZAUBER .. */ #define POSTCOMBATSPELL (1<<12) /* POSTKAMPFZAUBER .. */ #define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL) #define TESTRESISTANCE (1<<13) /* Zielobjekte auf Magieresistenz pruefen. not used in XML? */ #define NOTFAMILIARCAST (1<<14) /* not used by XML? */ #define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */ /* Flag Spruchkostenberechnung: */ enum { SPC_FIX, /* Fixkosten */ SPC_LEVEL, /* Komponenten pro Level */ SPC_LINEAR /* Komponenten pro Level und muessen vorhanden sein */ }; /* ------------------------------------------------------------- */ /* Prototypen */ void magic(void); void regenerate_aura(void); 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_icastle; void make_icastle(struct building *b, const struct building_type *btype, int timeout); const struct building_type *icastle_type(const struct attrib *a); /* ------------------------------------------------------------- */ /* Kommentare: * * Spruchzauberrei und Gegenstandszauberrei werden getrennt behandelt. * Das macht u.a. bestimmte Fehlermeldungen einfacher, das * identifizieren der Komponennten ueber den Missversuch ist nicht * moeglich * Spruchzauberrei: 'ZAUBER [struct region x y] [STUFE a] "Spruchname" [Ziel]' * Gegenstandszauberrei: 'BENUTZE "Gegenstand" [Ziel]' * * Die Funktionen: */ /* Magier */ struct 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. */ struct sc_mage *get_mage(const struct unit *u); enum magic_t mage_get_type(const struct sc_mage *mage); const struct spell *mage_get_combatspell(const struct sc_mage *mage, int nr, int *level); struct spellbook * mage_get_spellbook(const struct sc_mage * mage); int mage_get_spellpoints(const struct sc_mage *m); void mage_set_spellpoints(struct sc_mage *m, int aura); int mage_change_spellpoints(struct sc_mage *m, int delta); enum magic_t unit_get_magic(const struct unit *u); void unit_set_magic(struct unit *u, enum magic_t mtype); struct spellbook * unit_get_spellbook(const struct unit * u); void unit_add_spell(struct unit * u, struct spell * sp, int level); bool is_mage(const struct unit *u); /* gibt true, wenn u->mage gesetzt. */ bool is_familiar(const struct unit *u); /* gibt true, wenn eine Familiar-Relation besteht. */ /* Sprueche */ int get_combatspelllevel(const struct unit *u, int nr); /* versucht, eine eingestellte maximale Kampfzauberstufe * zurueckzugeben. 0 = Maximum, -1 u ist kein Magier. */ const struct spell *get_combatspell(const struct unit *u, int nr); /* gibt den Kampfzauber nr [pre/kampf/post] oder NULL zurueck */ void set_combatspell(struct unit *u, struct spell * sp, struct order *ord, int level); /* setzt Kampfzauber */ void unset_combatspell(struct unit *u, struct spell * sp); /* loescht Kampfzauber */ /* fuegt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */ int u_hasspell(const struct unit *u, const struct spell *sp); /* prueft, ob der Spruch in der Spruchliste der Einheit steht. */ void pick_random_spells(struct faction *f, int level, struct spellbook * book, int num_spells); bool knowsspell(const struct region *r, const struct unit *u, const struct spell * sp); /* prueft, ob die Einheit diesen Spruch gerade beherrscht, dh * mindestens die erforderliche Stufe hat. Hier koennen auch Abfragen * auf spezielle Antimagiezauber auf Regionen oder Einheiten eingefuegt * werden */ /* Magiepunkte */ int get_spellpoints(const struct unit *u); /* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurueck */ void set_spellpoints(struct unit *u, int sp); /* setzt die Magiepunkte auf sp */ int change_spellpoints(struct unit *u, int mp); /* veraendert die Anzahl der Magiepunkte der Einheit um +mp */ int max_spellpoints(const struct unit *u, const struct region *r); /* gibt die aktuell maximal moeglichen Magiepunkte der Einheit zurueck */ int change_maxspellpoints(struct unit *u, int csp); /* veraendert die maximalen Magiepunkte einer Einheit */ /* Zaubern */ double spellpower(struct region *r, struct unit *u, const struct spell * sp, int cast_level, struct order *ord); /* ermittelt die Staerke eines Spruchs */ bool fumble(struct region *r, struct unit *u, const struct spell * sp, int cast_level); /* true, wenn der Zauber misslingt, bei false gelingt der Zauber */ typedef struct spellrank { struct castorder *begin; struct castorder **handle_end; } spellrank; struct castorder *create_castorder(struct castorder * co, struct unit *caster, struct unit * familiar, const struct spell * sp, struct region * r, int lev, double force, int range, struct order * ord, struct spellparameter * p); void free_castorder(struct castorder *co); /* Zwischenspreicher fuer Zauberbefehle, notwendig fuer Prioritaeten */ void add_castorder(struct spellrank *cll, struct castorder *co); /* Haenge c-order co an die letze c-order von cll an */ void free_castorders(struct castorder *co); /* Speicher wieder freigeben */ int cast_spell(struct castorder *co); /* Pruefroutinen fuer Zaubern */ int countspells(struct unit *u, int step); int spellcount(const struct unit *u); /* erhoeht den Counter fuer Zaubersprueche um 'step' und gibt die neue * Anzahl der gezauberten Sprueche zurueck. */ int auracost(const struct unit *caster, const struct spell *sp); int spellcost(const struct unit *caster, const struct spell_component *spc); /* gibt die fuer diesen Spruch derzeit notwendigen Magiepunkte auf der * geringstmoeglichen Stufe zurueck, schon um den Faktor der bereits * zuvor gezauberten Sprueche erhoeht */ bool cancast(struct unit *u, const struct spell * spruch, int eff_stufe, int distance, struct order *ord); /* true, wenn Einheit alle Komponenten des Zaubers (incl. MP) fuer die * geringstmoegliche Stufe hat und den Spruch beherrscht */ void pay_spell(struct unit *mage, const struct unit *caster, const struct 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 fuer * die korrekte Bestimmung der Magiepunktkosten */ int eff_spelllevel(struct unit *mage, struct unit *caster, const struct spell * sp, int cast_level, int distance); /* ermittelt die effektive Stufe des Zaubers. Dabei ist cast_level * die gewuenschte maximale Stufe (im Normalfall Stufe des Magiers, * bei Farcasting Stufe*2^Entfernung) */ bool is_magic_resistant(struct unit *magician, struct unit *target, int resist_bonus); /* Mapperfunktion fuer target_resists_magic() vom Typ struct unit. */ variant magic_resistance(struct unit *target); /* gibt die Chance an, mit der einem Zauber widerstanden wird. Je * groesser, desto resistenter ist da Opfer */ bool target_resists_magic(struct unit *magician, void *obj, int objtyp, int resist_bonus); /* gibt false zurueck, wenn der Zauber gelingt, true, wenn das Ziel * widersteht */ struct spell * unit_getspell(struct unit *u, const char *s, const struct locale *lang); const char *magic_name(magic_t mtype, const struct locale *lang); /* Sprueche in der struct region */ /* (sind in curse) */ void set_familiar(struct unit * mage, struct unit * familiar); struct unit *get_familiar(const struct unit *u); struct unit *get_familiar_mage(const struct unit *u); struct unit *get_clone(const struct unit *u); void remove_familiar(struct unit *mage); void create_newfamiliar(struct unit *mage, struct unit *familiar); void create_newclone(struct unit *mage, struct unit *familiar); void fix_fam_spells(struct unit *u); void fix_fam_migrant(struct unit *u); const char *mkname_spell(const struct spell *sp); const char *spell_name(const char *spname, const struct locale *lang); const char *spell_info(const struct spell *sp, const struct locale *lang); const char *curse_name(const struct curse_type *ctype, const struct locale *lang); struct message *msg_unitnotfound(const struct unit *mage, struct order *ord, const struct spllprm *spobj); bool FactionSpells(void); struct spellbook * get_spellbook(const char * name); void free_spellbooks(void); void free_spellbook(struct spellbook *sb); #ifdef __cplusplus } #endif #endif