forked from github/server
6f50f9282a
- STRINGS strings.txt für deutsch und englisch um einen Haufen fehlender Einträge erweitert.language.c schreibt jetzt auf Wunsch ein logfile aller fehlender strings, was extrem hilfreich beim ergänzen ist. - LOKALISIERUNG Man kann jetzt Befehle komplett in einer anderen Sprache geben. Der NR macht Talente, Zugvorlage und Gegenstände in der eigenen Sprache. - monster.h zu monster.c nach gamecode verschoben - locale_string(key, NULL) NULL-locale liefert jetzt den key selbst zurück. - CR: 1. Anzeige der hashes statt der lokalisierten strings 2. TRANSLATION Block - Messages: make_message heisst jetzt msg_message msg_error() ist eine neue funktion für fehlermeldungen - strings.txt, messages.xml Einen Haufen neuer Einträge gemacht.
1678 lines
36 KiB
C
1678 lines
36 KiB
C
/* vi: set ts=2:
|
|
*
|
|
*
|
|
* Eressea PB(E)M host Copyright (C) 1998-2000
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
*
|
|
* based on:
|
|
*
|
|
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
|
|
* Atlantis v1.7 Copyright 1996 by Alex Schröder
|
|
*
|
|
* This program may not be used, modified or distributed without
|
|
* prior permission by the authors of Eressea.
|
|
* This program may not be sold or used commercially without prior written
|
|
* permission from the authors.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "eressea.h"
|
|
#include "curse.h"
|
|
|
|
/* kernel includes */
|
|
#include "magic.h"
|
|
#include "skill.h"
|
|
#include "unit.h"
|
|
#include "region.h"
|
|
#include "race.h"
|
|
#include "faction.h"
|
|
#include "building.h"
|
|
#include "ship.h"
|
|
#include "objtypes.h"
|
|
|
|
/* util includes */
|
|
#include <resolve.h>
|
|
#include <base36.h>
|
|
|
|
/* libc includes */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
|
|
/* ------------------------------------------------------------- */
|
|
direction_t
|
|
dirmirror(direction_t dir)
|
|
{
|
|
return (direction_t)((dir+MAXDIRECTIONS/2) % MAXDIRECTIONS);
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* at_curse */
|
|
|
|
void
|
|
curse_init(attrib * a) {
|
|
a->data.v = calloc(1, sizeof(curse));
|
|
}
|
|
|
|
int
|
|
curse_age(attrib * a)
|
|
{
|
|
curse * c = (curse*)a->data.v;
|
|
|
|
if (c->flag & CURSE_NOAGE) {
|
|
c->duration = 1;
|
|
} else {
|
|
c->duration = max(0, c->duration-1);
|
|
}
|
|
return (c->duration);
|
|
}
|
|
|
|
void
|
|
curse_done(attrib * a) {
|
|
curse *c = (curse *)a->data.v;
|
|
|
|
if( c->data )
|
|
free(c->data);
|
|
free(c);
|
|
}
|
|
|
|
attrib_type at_curse =
|
|
{
|
|
"curse",
|
|
curse_init,
|
|
curse_done,
|
|
curse_age,
|
|
curse_write,
|
|
curse_read,
|
|
ATF_CURSE
|
|
};
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
#define MAXENTITYHASH 8191
|
|
curse *cursehash[MAXENTITYHASH];
|
|
|
|
void
|
|
chash(curse *c)
|
|
{
|
|
curse *old = cursehash[c->no %MAXENTITYHASH];
|
|
|
|
cursehash[c->no %MAXENTITYHASH] = c;
|
|
c->nexthash = old;
|
|
}
|
|
|
|
void
|
|
cunhash(curse *c)
|
|
{
|
|
curse **show;
|
|
|
|
for (show = &cursehash[c->no % MAXENTITYHASH]; *show; show = &(*show)->nexthash) {
|
|
if ((*show)->no == c->no)
|
|
break;
|
|
}
|
|
if (*show) {
|
|
assert(*show == c);
|
|
*show = (*show)->nexthash;
|
|
c->nexthash = 0;
|
|
}
|
|
}
|
|
|
|
curse *
|
|
cfindhash(int i)
|
|
{
|
|
curse *old;
|
|
|
|
for (old = cursehash[i % MAXENTITYHASH]; old; old = old->nexthash)
|
|
if (old->no == i)
|
|
return old;
|
|
return 0;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* Spruch identifizieren */
|
|
|
|
#include "umlaut.h"
|
|
|
|
typedef struct cursetype_list {
|
|
struct cursetype_list * next;
|
|
const curse_type * type;
|
|
} cursetype_list;
|
|
|
|
cursetype_list * cursetypes;
|
|
|
|
void
|
|
ct_register(const curse_type * ct)
|
|
{
|
|
cursetype_list ** ctlp = &cursetypes;
|
|
while (*ctlp) {
|
|
cursetype_list * ctl = *ctlp;
|
|
if (ctl->type==ct) return;
|
|
ctlp=&ctl->next;
|
|
}
|
|
*ctlp = calloc(1, sizeof(cursetype_list));
|
|
(*ctlp)->type = ct;
|
|
}
|
|
|
|
const curse_type *
|
|
ct_find(const char *c)
|
|
{
|
|
/* TODO: findet nur curse_types, die auch in curse_data sind.
|
|
* da fehlt noch eine registrierung wie für attrib_type
|
|
*/
|
|
cursetype_list * ctl = cursetypes;
|
|
while (ctl) {
|
|
int k = min(strlen(c), strlen(ctl->type->name));
|
|
if (!strncasecmp(c, ctl->type->name, k)) return ctl->type;
|
|
ctl = ctl->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
boolean
|
|
is_normalcurse(curse_t id)
|
|
{
|
|
if (cursedaten[id].typ == CURSETYP_NORM)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean
|
|
is_curseunit(curse_t id)
|
|
{
|
|
if (cursedaten[id].typ == CURSETYP_UNIT)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean
|
|
is_curseskill(curse_t id)
|
|
{
|
|
if (cursedaten[id].typ == CURSETYP_SKILL)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* get_curse identifiziert eine Verzauberung über die ID und gibt
|
|
* einen pointer auf die struct zurück.
|
|
*/
|
|
|
|
typedef struct twoids {
|
|
int id;
|
|
int id2;
|
|
} twoids;
|
|
|
|
boolean
|
|
cmp_curse(const attrib * a, void * data) {
|
|
if (a->type->flags & ATF_CURSE) {
|
|
if (!data || (curse*)data == (curse*)a->data.v) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
boolean
|
|
cmp_oldcurse(const attrib * a, void * data)
|
|
{
|
|
twoids * ti = (twoids*)data;
|
|
curse * c = (curse*)a->data.v;
|
|
if (a->type!=&at_curse || c->cspellid!=ti->id) return false;
|
|
switch(cursedaten[ti->id].typ) {
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse_skill * cc = (curse_skill*)c->data;
|
|
if (cc->skill == (skill_t) ti->id2) return true;
|
|
}
|
|
case CURSETYP_SECONDID:
|
|
{
|
|
curse_secondid * cc = (curse_secondid*)c->data;
|
|
if (cc->secondid == ti->id2) return true;
|
|
}
|
|
case CURSETYP_UNIT:
|
|
case CURSETYP_NORM:
|
|
return true;
|
|
break;
|
|
default:
|
|
assert(!"unbekannter cursetyp entdeckt");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
twoids *
|
|
packids(int id, int id2) {
|
|
static twoids ti;
|
|
ti.id = id;
|
|
ti.id2 = id2;
|
|
return &ti;
|
|
}
|
|
|
|
curse *
|
|
get_curse(attrib *ap, curse_t id, int id2)
|
|
{
|
|
attrib * a = a_select(ap, packids(id, id2), cmp_oldcurse);
|
|
|
|
if (!a) return NULL;
|
|
return (curse*)a->data.v;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* Normalerweise ist alles ausser der Id eines curse und dem
|
|
* verzauberten Objekt nicht bekannt. Um den Zauber eindeutig zu
|
|
* identifizieren benötigt man je nach Typ einen weiteren Identifier.
|
|
*/
|
|
void
|
|
remove_curse(attrib **ap, curse_t id, int id2)
|
|
{
|
|
attrib *a = a_select(*ap, packids(id, id2), cmp_oldcurse);
|
|
if (a) a_remove(ap, a);
|
|
}
|
|
|
|
void
|
|
remove_allcurse(attrib **ap, void * data, boolean(*compare)(const attrib *, void *))
|
|
{
|
|
attrib * a = a_select(*ap, data, compare);
|
|
while (a) {
|
|
attrib * next = a->nexttype;
|
|
a_remove(ap, a);
|
|
a = a_select(next, data, compare);
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/*
|
|
* Staerke einer Verzauberung
|
|
*/
|
|
int
|
|
get_cursevigour(attrib *ap, curse_t id, int id2)
|
|
{
|
|
int vigour = 0;
|
|
curse * c = get_curse(ap, id, id2);
|
|
if (c) vigour = c->vigour;
|
|
return vigour;
|
|
}
|
|
|
|
void
|
|
set_cursevigour(attrib *ap, curse_t id, int id2, int i)
|
|
{
|
|
curse * c = get_curse(ap, id, id2);
|
|
assert(i>0);
|
|
if (c) c->vigour = i;
|
|
}
|
|
|
|
/* verändert die Stärke der Verzauberung um +i und gibt die neue
|
|
* Stärke zurück. Sollte die Zauberstärke unter Null sinken, löst er
|
|
* sich auf.
|
|
*/
|
|
int
|
|
change_cursevigour(attrib **ap, curse_t id, int id2, int i)
|
|
{
|
|
i += get_cursevigour(*ap,id,id2);
|
|
|
|
if (i <= 0) {
|
|
remove_curse(ap, id, id2);
|
|
}else{
|
|
set_cursevigour(*ap,id,id2,i);
|
|
}
|
|
return i;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
int
|
|
get_curseeffect(attrib *ap, curse_t id, int id2)
|
|
{
|
|
int effect = 0;
|
|
|
|
curse * c = get_curse(ap, id, id2);
|
|
if (c) effect = c->effect;
|
|
return effect;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
void
|
|
set_curseingmagician(struct unit *magician, struct attrib *ap_target, curse_t id, int id2)
|
|
{
|
|
curse * c = get_curse(ap_target, id, id2);
|
|
if (c){
|
|
c->magician = magician;
|
|
}
|
|
}
|
|
|
|
unit *
|
|
get_cursingmagician(struct attrib *ap, curse_t id, int id2)
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
if( !c )
|
|
return NULL;
|
|
|
|
return c->magician;
|
|
}
|
|
|
|
/* Wichtig! Alle struct curse<typ>, die den Verweis auf den zaubenden
|
|
* Magier enthalten, müssen sie hier mit abgeprüft werden
|
|
*/
|
|
void
|
|
remove_cursemagepointer(unit *magician, attrib *ap_target)
|
|
{
|
|
const attrib * a;
|
|
|
|
a = a_find(ap_target, &at_curse);
|
|
while (a) {
|
|
curse *c = (curse*)a->data.v;
|
|
if(c->magician == magician)
|
|
c->magician = (unit*)NULL;
|
|
a = a->nexttype;
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
int
|
|
get_cursedmen(attrib *ap, curse_t id, int id2)
|
|
{
|
|
switch (cursedaten[id].typ){
|
|
case CURSETYP_UNIT:
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
if (c){
|
|
curse_unit * cc = (curse_unit*)c->data;
|
|
return cc->cursedmen;
|
|
}
|
|
}
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
if (c){
|
|
curse_skill * cc = (curse_skill*)c->data;
|
|
return cc->cursedmen;
|
|
}
|
|
}
|
|
case CURSETYP_NORM:
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
set_cursedmen(attrib *ap, curse_t id, int id2, int cursedmen)
|
|
{
|
|
switch (cursedaten[id].typ){
|
|
case CURSETYP_UNIT:
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
if (c){
|
|
curse_unit * cc = (curse_unit*)c->data;
|
|
cc->cursedmen = cursedmen;
|
|
}
|
|
break;
|
|
}
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
if (c){
|
|
curse_skill * cc = (curse_skill*)c->data;
|
|
cc->cursedmen = cursedmen;
|
|
}
|
|
break;
|
|
}
|
|
case CURSETYP_NORM:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
int
|
|
change_cursedmen(attrib **ap, curse_t id, int id2, int cursedmen)
|
|
{
|
|
switch (cursedaten[id].typ){
|
|
case CURSETYP_UNIT:
|
|
case CURSETYP_SKILL:
|
|
cursedmen += get_cursedmen(*ap, id, id2);
|
|
if (cursedmen <= 0){
|
|
remove_curse(ap,id,id2);
|
|
} else {
|
|
set_cursedmen(*ap, id, id2, cursedmen);
|
|
}
|
|
break;
|
|
case CURSETYP_NORM:
|
|
default:
|
|
break;
|
|
}
|
|
return cursedmen;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
void
|
|
set_curseflag(attrib *ap, curse_t id, int id2, int flag)
|
|
{
|
|
curse * c = get_curse(ap, id, id2);
|
|
if (c) c->flag = (c->flag | flag);
|
|
}
|
|
|
|
void
|
|
remove_curseflag(attrib *ap, curse_t id, int id2, int flag)
|
|
{
|
|
curse * c = get_curse(ap, id, id2);
|
|
if (c) c->flag = (c->flag & ~(flag));
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* Legt eine neue Verzauberung an. Sollte es schon einen Zauber
|
|
* dieses Typs geben, gibt es den bestehenden zurück.
|
|
*/
|
|
curse *
|
|
set_curse(unit *mage, attrib **ap, curse_t id, int id2, int vigour,
|
|
int duration, int effect, int men)
|
|
{
|
|
curse *c;
|
|
attrib * a;
|
|
|
|
a = a_new(&at_curse);
|
|
a_add(ap, a);
|
|
c = (curse*)a->data.v;
|
|
|
|
c->type = &cursedaten[id];
|
|
c->cspellid = id;
|
|
c->flag = (0);
|
|
c->vigour = vigour;
|
|
c->duration = duration;
|
|
c->effect = effect;
|
|
c->magician = mage;
|
|
|
|
c->no = newunitid();
|
|
chash(c);
|
|
|
|
switch (c->type->typ) {
|
|
case CURSETYP_NORM:
|
|
break;
|
|
|
|
case CURSETYP_UNIT:
|
|
{
|
|
curse_unit *cc = calloc(1, sizeof(curse_unit));
|
|
cc->cursedmen += men;
|
|
c->data = cc;
|
|
break;
|
|
}
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse_skill *cc = calloc(1, sizeof(curse_skill));
|
|
cc->skill = (skill_t) id2;
|
|
cc->cursedmen += men;
|
|
c->data = cc;
|
|
break;
|
|
}
|
|
case CURSETYP_SECONDID:
|
|
{
|
|
curse_secondid *cc = calloc(1, sizeof(curse_secondid));
|
|
cc->secondid = id2;
|
|
c->data = cc;
|
|
break;
|
|
}
|
|
|
|
}
|
|
return c;
|
|
}
|
|
|
|
|
|
/* Mapperfunktion für das Anlegen neuer curse. Automatisch wird zum
|
|
* passenden Typ verzweigt und die relevanten Variablen weitergegeben.
|
|
*/
|
|
curse *
|
|
create_curse(unit *magician, attrib **ap, curse_t id, int id2, int vigour,
|
|
int duration, int effect, int men)
|
|
{
|
|
curse *c;
|
|
c = get_curse(*ap, id, id2);
|
|
|
|
if(c && (c->flag & CURSE_ONLYONE)){
|
|
return NULL;
|
|
}
|
|
/* es gibt schon eins diese Typs */
|
|
if (c && cursedaten[id].mergeflags != NO_MERGE) {
|
|
if(cursedaten[id].mergeflags & M_DURATION){
|
|
c->duration = max(c->duration, duration);
|
|
}
|
|
if(cursedaten[id].mergeflags & M_SUMDURATION){
|
|
c->duration += duration;
|
|
}
|
|
if(cursedaten[id].mergeflags & M_SUMEFFECT){
|
|
c->effect += effect;
|
|
}
|
|
if(cursedaten[id].mergeflags & M_MAXEFFECT){
|
|
c->effect = max(c->effect, effect);
|
|
}
|
|
if(cursedaten[id].mergeflags & M_VIGOUR){
|
|
c->vigour = max(vigour, c->vigour);
|
|
}
|
|
if(cursedaten[id].mergeflags & M_VIGOUR_ADD){
|
|
c->vigour = vigour + c->vigour;
|
|
}
|
|
if(cursedaten[id].mergeflags & M_MEN){
|
|
switch (cursedaten[id].typ) {
|
|
case CURSETYP_UNIT:
|
|
{
|
|
curse_unit * cc = (curse_unit*)c->data;
|
|
cc->cursedmen += men;
|
|
}
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse_skill * cc = (curse_skill*)c->data;
|
|
cc->cursedmen += men;
|
|
}
|
|
}
|
|
}
|
|
set_curseingmagician(magician, *ap, id, id2);
|
|
} else {
|
|
c = set_curse(magician, ap, id, id2, vigour, duration, effect, men);
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* hier müssen alle c-typen, die auf Einheiten gezaubert werden können,
|
|
* berücksichtigt werden */
|
|
|
|
void
|
|
do_transfer_curse(curse *c, unit * u, unit * u2, int n)
|
|
{
|
|
curse_t id = c->cspellid;
|
|
int id2 = 0;
|
|
int flag = c->flag;
|
|
int duration = c->duration;
|
|
int vigour = c->vigour;
|
|
unit *magician = c->magician;
|
|
int effect = c->effect;
|
|
int cursedmen = 0;
|
|
int men = 0;
|
|
boolean dogive = false;
|
|
|
|
switch (cursedaten[id].typ) {
|
|
case CURSETYP_UNIT:
|
|
{
|
|
curse_unit * cc = (curse_unit*)c->data;
|
|
men = cc->cursedmen;
|
|
break;
|
|
}
|
|
case CURSETYP_SKILL:
|
|
{
|
|
curse_skill * cc = (curse_skill*)c->data;
|
|
id2 = (int)cc->skill;
|
|
men = cc->cursedmen;
|
|
break;
|
|
}
|
|
default:
|
|
cursedmen = u->number;
|
|
}
|
|
|
|
switch (cursedaten[id].givemenacting){
|
|
case CURSE_SPREADALWAYS:
|
|
dogive = true;
|
|
men = u2->number + n;
|
|
break;
|
|
|
|
case CURSE_SPREADMODULO:
|
|
{
|
|
int i;
|
|
int u_number = u->number;
|
|
for (i=0;i<n+1 && u_number>0;i++){
|
|
if (rand()%u_number < cursedmen){
|
|
++men;
|
|
--cursedmen;
|
|
dogive = true;
|
|
}
|
|
--u_number;
|
|
}
|
|
break;
|
|
}
|
|
case CURSE_SPREADCHANCE:
|
|
{
|
|
int chance = u2->number * 100 / (u2->number + n);
|
|
if (rand()%100 > chance ){
|
|
men = u2->number + n;
|
|
dogive = true;
|
|
}
|
|
break;
|
|
}
|
|
case CURSE_SPREADNEVER:
|
|
break;
|
|
}
|
|
|
|
if (dogive == true) {
|
|
set_curse(magician, &u2->attribs, id, id2, vigour, duration,
|
|
effect, men);
|
|
set_curseflag(u2->attribs, id, id2, flag);
|
|
|
|
switch (cursedaten[id].typ){
|
|
case CURSETYP_UNIT:
|
|
case CURSETYP_SKILL:
|
|
set_cursedmen(u2->attribs, id, id2, men);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
transfer_curse(unit * u, unit * u2, int n)
|
|
{
|
|
attrib * a;
|
|
|
|
a = a_find(u->attribs, &at_curse);
|
|
while (a) {
|
|
curse *c = (curse*)a->data.v;
|
|
do_transfer_curse(c, u, u2, n);
|
|
a = a->nexttype;
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
boolean
|
|
is_cursed(attrib *ap, curse_t id, int id2)
|
|
{
|
|
curse *c = get_curse(ap, id, id2);
|
|
|
|
if (!c)
|
|
return false;
|
|
|
|
if (c->flag & CURSE_ISNEW)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* Diese Funktionen werden von reports.c:print_curses() während der
|
|
* Generierung des Normalreports aufgerufen und ersetzen
|
|
* cursedisplay
|
|
*/
|
|
static int
|
|
cinfo_fogtrap(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Dichte Nebel bedecken diese Woche die Region. "
|
|
"Keine Einheit schafft es, diese Nebel zu durchdringen und "
|
|
"die Region zu verlassen. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* C_NOCOST */
|
|
static int
|
|
cinfo_nocost(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
|
|
assert(typ == TYP_BUILDING);
|
|
sprintf(buf, "Der Zahn der Zeit kann diesen Mauern nichts anhaben. (%s)",
|
|
curseid(c));
|
|
return 1;
|
|
}
|
|
/* C_HOLYGROUND */
|
|
static int
|
|
cinfo_holyground(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
|
|
assert(typ == TYP_REGION);
|
|
sprintf(buf, "Untote schrecken vor dieser Region zurück. (%s)",
|
|
curseid(c));
|
|
return 1;
|
|
}
|
|
/* C_GBDREAM, */
|
|
static int
|
|
cinfo_dreamcurse(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(self);
|
|
unused(typ);
|
|
unused(obj);
|
|
assert(typ == TYP_REGION);
|
|
|
|
if (c->effect > 0){
|
|
sprintf(buf, "Die Leute haben schöne Träume. (%s)", curseid(c));
|
|
}else{
|
|
sprintf(buf, "Albträume plagen die Leute. (%s)", curseid(c));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* C_AURA */
|
|
/* erhöht/senkt regeneration und maxaura um effect% */
|
|
static int
|
|
cinfo_auraboost(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
unused(typ);
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
|
|
if (self){
|
|
if (c->effect > 100){
|
|
sprintf(buf, "%s fühlt sich von starken magischen Energien "
|
|
"durchströmt. (%s)", u->name, curseid(c));
|
|
}else{
|
|
sprintf(buf, "%s hat Schwierigkeiten seine magischen Energien "
|
|
"zu sammeln. (%s)", u->name, curseid(c));
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_BLESSEDHARVEST, */
|
|
static int
|
|
cinfo_blessedharvest(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "In dieser Gegend steht das Korn besonders gut im Feld. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_DROUGHT, */
|
|
static int
|
|
cinfo_drought(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "In dieser Gegend herrscht eine Dürre. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_BADLEARN */
|
|
static int
|
|
cinfo_badlearn(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Alle Leute in der Region haben Schlafstörungen. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_SHIP_NODRIFT */
|
|
static int
|
|
cinfo_shipnodrift(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
ship * sh;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_SHIP);
|
|
sh = (ship*)obj;
|
|
|
|
if (self){
|
|
sprintf(buf, "%s ist mit guten Wind gesegnet", sh->name);
|
|
if (c->duration <= 2){
|
|
scat(", doch der Zauber beginnt sich bereits aufzulösen");
|
|
}
|
|
scat(".");
|
|
} else {
|
|
sprintf(buf, "Ein silberner Schimmer umgibt das Schiff.");
|
|
}
|
|
scat(" (");
|
|
scat(itoa36(c->no));
|
|
scat(")");
|
|
return 1;
|
|
}
|
|
/* C_DEPRESSION */
|
|
static int
|
|
cinfo_depression(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Die Bauern sind unzufrieden. (%s)", curseid(c));
|
|
return 1;
|
|
}
|
|
/* C_MAGICSTONE*/
|
|
static int
|
|
cinfo_magicstone(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
building * b;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_BUILDING);
|
|
b = (building*)obj;
|
|
|
|
if (self){
|
|
sprintf(buf, "Die Mauern von %s wirken, als wären sie "
|
|
"aus der Erde gewachsen. (%s)", b->name, curseid(c));
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/* C_MAGICSTONE*/
|
|
static int
|
|
cinfo_magicrunes(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
|
|
if (typ == TYP_BUILDING){
|
|
building * b;
|
|
b = (building*)obj;
|
|
if (self){
|
|
sprintf(buf, "Auf den Mauern von %s erkennt man seltsame Runen. (%s)",
|
|
b->name, curseid(c));
|
|
return 1;
|
|
}
|
|
} else if (typ == TYP_SHIP) {
|
|
ship *sh;
|
|
sh = (ship*)obj;
|
|
if (self){
|
|
sprintf(buf, "Auf den Planken von %s erkennt man seltsame Runen. (%s)",
|
|
sh->name, curseid(c));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* C_GENEROUS */
|
|
static int
|
|
cinfo_generous(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Es herrscht eine fröhliche und ausgelassene Stimmung. (%s)",
|
|
curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_ASTRALBLOCK */
|
|
static int
|
|
cinfo_astralblock(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Etwas verhindert den Kontakt zur Realität. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_PEACE */
|
|
static int
|
|
cinfo_peace(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Die ganze Region ist von einer friedlichen Stimmung "
|
|
"erfasst. (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_REGCONF */
|
|
static int
|
|
cinfo_regconf(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Ein Schleier der Verwirrung liegt über der Region. (%s)",
|
|
curseid(c));
|
|
|
|
|
|
return 1;
|
|
}
|
|
/* C_MAGICSTREET */
|
|
static int
|
|
cinfo_magicstreet(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
|
|
assert(typ == TYP_REGION);
|
|
|
|
sprintf(buf, "Die Straßen sind erstaunlich trocken und gut begehbar");
|
|
/* Warnung vor auflösung!*/
|
|
if (c->duration <= 2){
|
|
scat(", doch an manchen Stellen bilden sich wieder die erste Schlammlöcher");
|
|
}
|
|
scat(". (");
|
|
scat(itoa36(c->no));
|
|
scat(")");
|
|
|
|
return 1;
|
|
}
|
|
/* C_SLAVE */
|
|
static int
|
|
cinfo_slave(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
|
|
if (self){
|
|
sprintf(buf, "%s wird noch %d Woche%s unter unserem Bann stehen. (%s)",
|
|
u->name, c->duration, (c->duration == 1)? "":"n", curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_DISORIENTATION */
|
|
static int
|
|
cinfo_disorientation(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(obj);
|
|
unused(self);
|
|
|
|
assert(typ == TYP_SHIP);
|
|
|
|
sprintf(buf, "Der Kompaß kaputt, die Segel zerrissen, der Himmel "
|
|
"wolkenverhangen. Wohin fahren wir? (%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
/* C_CALM */
|
|
static int
|
|
cinfo_calm(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
race_t rc;
|
|
faction *f;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
if (c->magician){
|
|
rc = c->magician->irace;
|
|
f = c->magician->faction;
|
|
if (self){
|
|
sprintf(buf, "%s mag %s", u->name, factionname(f));
|
|
}else{
|
|
sprintf(buf, "%s scheint %s zu mögen", u->name, race[rc].name[1]);
|
|
}
|
|
scat(". (");
|
|
scat(itoa36(c->no));
|
|
scat(")");
|
|
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_SPEED */
|
|
static int
|
|
cinfo_speed(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
curse_unit * cu;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
cu = (curse_unit *)c->data;
|
|
|
|
if (self){
|
|
sprintf(buf, "%d Person%s von %s %s noch %d Woche%s beschleunigt. (%s)",
|
|
cu->cursedmen, (cu->cursedmen == 1)? "":"en", u->name,
|
|
(cu->cursedmen == 1)? "ist":"sind", c->duration,
|
|
(c->duration == 1)? "":"n",
|
|
curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_ORC */
|
|
static int
|
|
cinfo_orc(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
|
|
if (self){
|
|
sprintf(buf, "%s stürzt sich von einem amourösen Abenteuer ins "
|
|
"nächste. (%s)", u->name, curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* C_KAELTESCHUTZ */
|
|
static int
|
|
cinfo_kaelteschutz(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
curse_unit * cu;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
cu = (curse_unit *)c->data;
|
|
|
|
if (self){
|
|
sprintf(buf, "%d Person%s von %s %s sich vor Kälte geschützt. (%s)",
|
|
cu->cursedmen, (cu->cursedmen == 1)? "":"en", u->name,
|
|
(cu->cursedmen == 1)? "fühlt":"fühlen",
|
|
curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* C_SPARKLE */
|
|
static int
|
|
cinfo_sparkle(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
const char * effects[] = {
|
|
NULL, /* end grau*/
|
|
"%s ist im Traum eine Fee erschienen.",
|
|
"%s wird von bösen Alpträumen geplagt.",
|
|
NULL, /* end traum */
|
|
"%s wird von einem glitzernden Funkenregen umgeben.",
|
|
"Ein schimmernder Lichterkranz umgibt %s.",
|
|
NULL, /* end tybied */
|
|
"Eine Melodie erklingt, und %s tanzt bis spät in die Nacht hinein.",
|
|
"%s findet eine kleine Flöte, die eine wundersame Melodie spielt.",
|
|
"Die Frauen des nahegelegenen Dorfes bewundern %s verstohlen.",
|
|
"Eine Gruppe vorbeiziehender Bergarbeiter rufen %s eindeutig Zweideutiges nach.",
|
|
NULL, /* end cerrdor */
|
|
"%s bekommt von einer Schlange einen Apfel angeboten.",
|
|
"Ein Einhorn berührt %s mit seinem Horn und verschwindet kurz darauf im Unterholz.",
|
|
"Vogelzwitschern begleitet %s auf all seinen Wegen.",
|
|
"Leuchtende Blumen erblühen rund um das Lager von %s.",
|
|
NULL, /* end gwyrrd */
|
|
"Über %s zieht eine Gruppe Geier ihre Kreise.",
|
|
"Der Kopf von %s hat sich in einen grinsenden Totenschädel verwandelt.",
|
|
"Ratten folgen %s auf Schritt und Tritt.",
|
|
"Pestbeulen befallen den Körper von %s.",
|
|
"Eine dunkle Fee erscheint %s im Schlaf. Sie ist von schauriger Schönheit.",
|
|
"Fäulnisgeruch dringt %s aus allen Körperöffnungen.",
|
|
NULL, /* end draig */
|
|
};
|
|
int m, begin=0, end=0;
|
|
unit *u;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
|
|
if(!c->magician || !c->magician->faction) return 0;
|
|
|
|
for(m=0;m!=c->magician->faction->magiegebiet;++m) {
|
|
while (effects[end]!=NULL) ++end;
|
|
begin = end+1;
|
|
end = begin;
|
|
}
|
|
|
|
while (effects[end]!=NULL) ++end;
|
|
if (end==begin) return 0;
|
|
else sprintf(buf, effects[begin + c->effect % (end-begin)], u->name);
|
|
scat(" (");
|
|
scat(itoa36(c->no));
|
|
scat(")");
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* C_STRENGTH */
|
|
static int
|
|
cinfo_strength(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(c);
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
unused(obj);
|
|
|
|
if (self){
|
|
sprintf(buf, "Die Leute strotzen nur so vor Kraft. (%s)",
|
|
curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_ALLSKILLS */
|
|
static int
|
|
cinfo_allskills(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(obj);
|
|
unused(typ);
|
|
unused(c);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
|
|
if (self){
|
|
sprintf(buf, "Wird von einem Alp geritten. (%s)", curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_SKILL */
|
|
static int
|
|
cinfo_skill(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
curse_skill *ck;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
ck = (curse_skill*)c->data;
|
|
|
|
if (self){
|
|
sprintf(buf, "%s ist in %s ungewöhnlich ungeschickt. (%s)", u->name,
|
|
skillname(ck->skill, u->faction->locale), curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_ITEMCLOAK */
|
|
static int
|
|
cinfo_itemcloak(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit *u;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
u = (unit *)obj;
|
|
|
|
if (self) {
|
|
sprintf(buf, "Die Ausrüstung von %s scheint unsichtbar. (%s)",
|
|
u->name, curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
cinfo_fumble(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unit * u = (unit*)obj;
|
|
unused(typ);
|
|
|
|
assert(typ == TYP_UNIT);
|
|
|
|
if (self){
|
|
sprintf(buf, "%s kann sich kaum konzentrieren.i (%s)",
|
|
u->name, curseid(c));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* C_RIOT */
|
|
static int
|
|
cinfo_riot(void * obj, typ_t typ, curse *c, int self)
|
|
{
|
|
unused(typ);
|
|
unused(self);
|
|
unused(obj);
|
|
|
|
assert(typ == TYP_REGION);
|
|
sprintf(buf, "Die Region befindet sich in Aufruhr.(%s)", curseid(c));
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* cursedata */
|
|
/* ------------------------------------------------------------- */
|
|
/* typedef struct cursedata {
|
|
* int typ;
|
|
* int givemenacting;
|
|
* int mergeflags;
|
|
* char *name;
|
|
* char *info;
|
|
* void (*display)(void*,typ_t, curse*);
|
|
*} cursedata;
|
|
*/
|
|
/* die Beschreibung wird bei einer gelungenen Zauberanalyse ausgegeben
|
|
* und hat die Form:
|
|
* Magier (xx) gelang es folgendes herauszufinden:
|
|
* Unit (xyz) steht unter dem Einfluss des Zaubers %name,/ Auf
|
|
* Region/Schiff/Burg (xy) liegt der Zauber %name,
|
|
* der wohl noch etwa %s Wochen andauert.
|
|
* %info, "Dieser Zauber blafalsel blub"
|
|
*/
|
|
curse_type cursedaten[MAXCURSE] =
|
|
{
|
|
/* struct's vom typ curse: */
|
|
{ /* C_FOGTRAP, */
|
|
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_fogtrap
|
|
},
|
|
{ /* C_ANTIMAGICZONE, */
|
|
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
|
"Magieschwächezone",
|
|
"Dieser Zauber scheint magische Energien irgendwie abzuleiten und "
|
|
"so alle in der Region gezauberten Sprüche in ihrer Wirkung zu "
|
|
"schwächen oder ganz zu verhindern.",
|
|
NULL
|
|
},
|
|
{ /* C_FARVISION, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_GBDREAM, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_dreamcurse
|
|
},
|
|
|
|
{ /* C_AURA, Verändert die max Aura und Regeneration um effect% */
|
|
CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE),
|
|
"Aurafokus",
|
|
"Dieser Zauber greift irgendwie in die Verbindung zwischen Magier "
|
|
"und Magischer Essenz ein. Mit positiver Ausrichtung kann er wohl "
|
|
"wie ein Fokus für Aura wirken, jedoch genauso für das Gegenteil "
|
|
"benutzt werden.",
|
|
(cdesc_fun)cinfo_auraboost
|
|
},
|
|
{ /* C_MAELSTROM, */
|
|
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
|
"Mahlstrom",
|
|
"Dieser Zauber verursacht einen gigantischen magischen Strudel. Der "
|
|
"Mahlstrom wird alle Schiffe, die in seinen Sog geraten, schwer "
|
|
"beschädigen.",
|
|
NULL
|
|
},
|
|
{ /* C_BLESSEDHARVEST, */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
|
|
"Segen der Felder",
|
|
"Dieser Fruchtbarkeitszauber erhöht die Erträge der Felder.",
|
|
(cdesc_fun)cinfo_blessedharvest
|
|
},
|
|
{ /* C_DROUGHT, */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
|
|
"Dürre",
|
|
"Dieser Zauber strahlt starke negative Energien aus. Warscheinlich "
|
|
"ist er die Ursache der Dürre." ,
|
|
(cdesc_fun)cinfo_drought
|
|
},
|
|
{ /* C_BADLEARN, */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
|
|
"",
|
|
"Dieser Zauber scheint die Ursache für die Schlaflosigkeit und "
|
|
"Mattigkeit zu sein, unter der die meisten Leute hier leiden und "
|
|
"die dazu führt, das Lernen weniger Erfolg bringt. ",
|
|
(cdesc_fun)cinfo_badlearn
|
|
},
|
|
{ /* C_SHIP_SPEEDUP, Sturmwind-Zauber, wirkt nur 1 Runde */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Sturmwind",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_SHIP_FLYING, Luftschiff-Zauber, wirkt nur 1 Runde */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Luftschiff",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_SHIP_NODRIFT, GünstigeWinde-Zauber */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
|
|
"Günstige Winde",
|
|
"Der Zauber auf diesem Schiff ist aus den elementaren Magien der Luft "
|
|
"und des Wassers gebunden. Der dem Wasser verbundene Teil des Zaubers "
|
|
"läßt es leichter durch die Wellen gleiten und der der Luft verbundene "
|
|
"Teil scheint es vor widrigen Winden zu schützen.",
|
|
(cdesc_fun)cinfo_shipnodrift
|
|
},
|
|
{ /* C_DEPRESSION, Trübsal-Zauber */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
|
|
"Schwermut",
|
|
"Wie schon zu vermuten war, sind der ewig graue Himmel und die "
|
|
"depressive Stimmung in der Region nicht natürlich. Dieser Fluch "
|
|
"hat sich wie ein bleiernes Tuch auf die Gemüter der Bevölkerung "
|
|
"gelegt und eh er nicht gebrochen oder verklungen ist, wird keiner "
|
|
"sich an Gaukelleien erfreuen können.",
|
|
(cdesc_fun)cinfo_depression
|
|
},
|
|
{ /* C_MAGICSTONE, Heimstein-Zauber */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Felsenmauern",
|
|
"Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern "
|
|
"gebunden. Starke elementarmagische Kräfte sind zu spüren. "
|
|
"Vieleicht wurde gar ein Erdelementar in diese Mauern gebannt. "
|
|
"Ausser ebenso starkter Antimagie wird nichts je diese Mauern "
|
|
"gefährden können.",
|
|
(cdesc_fun)cinfo_magicstone
|
|
},
|
|
{ /* C_STRONGWALL, Feste Mauer - Präkampfzauber, wirkt nur 1 Runde */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Burgschutzzauber",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_ASTRALBLOCK, Astralblock, auf Astralregion */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_astralblock
|
|
},
|
|
{ /* C_GENEROUS, Unterhaltungsanteil vermehren */
|
|
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR | M_MAXEFFECT ),
|
|
"Feierlaune",
|
|
"Dieser Zauber beeinflusst die allgemeine Stimmung in der Region positiv. "
|
|
"Die gute Laune macht die Leute freigiebiger.",
|
|
(cdesc_fun)cinfo_generous
|
|
},
|
|
{ /* C_PEACE, verhindert Attackiere regional */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Friedensbann",
|
|
"Dieser machtvoller Beeinflussungszauber erstickt jeden Streit schon im "
|
|
"Keim.",
|
|
(cdesc_fun)cinfo_peace
|
|
},
|
|
{ /* C_REGCONF, erschwert geordnete Bewegungen */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_regconf
|
|
},
|
|
{ /* C_MAGICSTREET, erzeugt Straßennetz */
|
|
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
|
"magische Pfade",
|
|
"Es scheint sich um einen elementarmagischen Zauber zu handeln, der alle "
|
|
"Pfade und Wege so gut festigt, als wären sie gepflastert. Wie auf einer "
|
|
"Straße kommt man so viel besser und schneller vorwärts.",
|
|
(cdesc_fun)cinfo_magicstreet
|
|
},
|
|
{ /* C_RESIST_MAGIC, */
|
|
CURSETYP_NORM, 0, M_SUMEFFECT,
|
|
"Magieschutz",
|
|
"Dieses Zauber verstärkt die natürliche Widerstandskraft gegen eine "
|
|
"Verzauberung.",
|
|
(cdesc_fun)cinfo_magicrunes
|
|
},
|
|
{ /* C_SONG_BADMR,
|
|
erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur
|
|
1x pro Einheit */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Gesang des schwachen Geistes",
|
|
"Dieses Lied, das irgendwie in die magische Essenz der Region gewoben "
|
|
"ist, schwächt die natürliche Widerstandskraft gegen eine "
|
|
"Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.",
|
|
NULL
|
|
},
|
|
{ /* C_SONG_GOODMR,
|
|
erhöht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro
|
|
Einheit */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Gesang des wachen Geistes",
|
|
"Dieser Lied, das irgendwie in die magische Essenz der Region gewoben "
|
|
"ist, verstärkt die natürliche Widerstandskraft gegen eine "
|
|
"Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.",
|
|
NULL
|
|
},
|
|
{ /* C_SLAVE,
|
|
dient fremder Partei. Zählt nicht zu Migranten, attackiert nicht */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Sklavenketten",
|
|
"Dieser mächtige Bann scheint die Einheit ihres freien Willens "
|
|
"zu berauben. Solange der Zauber wirkt, wird sie nur den Befehlen "
|
|
"ihres neuen Herrn gehorchen.",
|
|
(cdesc_fun)cinfo_slave
|
|
},
|
|
{ /* C_DISORIENTATION, */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Irrfahrt",
|
|
"Dieses Schiff hat sich verfahren.",
|
|
(cdesc_fun)cinfo_disorientation
|
|
},
|
|
{ /* C_CALM, */
|
|
CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE,
|
|
"Besänftigen",
|
|
"Dieser Beeinflussungszauber scheint die Einheit einem ganz "
|
|
"bestimmten Volk wohlgesonnen zu machen.",
|
|
(cdesc_fun)cinfo_calm
|
|
},
|
|
{ /* C_OLDRACE,
|
|
Merkt sich die alte 'richtige' Rasse einer gestalltwandelnden
|
|
Einheit */
|
|
CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE,
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FUMBLE, */
|
|
CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE,
|
|
"Tollpatschfluch",
|
|
"Eine Wolke negativer Energie umgibt die Einheit.",
|
|
(cdesc_fun)cinfo_fumble
|
|
},
|
|
{ /* C_RIOT, */
|
|
CURSETYP_NORM, 0, (M_DURATION),
|
|
"Aufruhr",
|
|
"Eine Wolke negativer Energie liegt über der Region.",
|
|
(cdesc_fun)cinfo_riot
|
|
},
|
|
{ /* C_NOCOST, Ewige Mauern-Zauber */
|
|
CURSETYP_NORM, 0, NO_MERGE,
|
|
"Ewige Mauern",
|
|
"Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern "
|
|
"gebunden. Unbeeindruck vom Zahn der Zeit wird dieses Gebäude wohl "
|
|
"auf Ewig stehen.",
|
|
(cdesc_fun)cinfo_nocost
|
|
},
|
|
{ /* C_HOLYGROUND, */
|
|
CURSETYP_NORM, 0, (M_VIGOUR_ADD),
|
|
"Heiliger Boden",
|
|
"Verschiedene Naturgeistern sind im Boden der Region gebunden und "
|
|
"beschützen diese vor dem der dunklen Magie des lebenden Todes.",
|
|
(cdesc_fun)cinfo_holyground
|
|
},
|
|
{ /* C_FREE_13, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_14, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_15, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_16, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_17, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_18, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_19, */
|
|
CURSETYP_NORM, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
|
|
/* struct's vom typ curse_unit: */
|
|
{ /* C_SPEED, */
|
|
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
|
|
"Beschleunigen II",
|
|
"Diese Einheit bewegt sich doppelt so schnell.",
|
|
(cdesc_fun)cinfo_speed
|
|
},
|
|
{ /* C_ORC, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
|
"Orkfieber",
|
|
"Dieser Zauber scheint die Einheit zu \"orkisieren\". Wie bei Orks "
|
|
"ist eine deutliche Neigung zur Fortpflanzung zu beobachten.",
|
|
(cdesc_fun)cinfo_orc
|
|
},
|
|
{ /* C_MBOOST, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_KAELTESCHUTZ, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
|
|
"Winterfell",
|
|
"Dieser Zauber schützt vor den Auswirkungen der Kälte.",
|
|
(cdesc_fun)cinfo_kaelteschutz
|
|
},
|
|
{ /* C_STRENGTH, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
|
"Trollstärke",
|
|
"Dieser Zauber vermehrt die Stärke der verzauberten Personen um ein "
|
|
"vielfaches.",
|
|
(cdesc_fun)cinfo_strength
|
|
},
|
|
{ /* C_ALLSKILLS, Alp */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_allskills
|
|
},
|
|
{ /* C_MAGICRESISTANCE, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
|
"Magieschutz",
|
|
"Dieser Zauber verstärkt die natürliche Widerstandskraft gegen eine "
|
|
"Verzauberung.",
|
|
NULL
|
|
},
|
|
{ /* C_ITEMCLOAK, */
|
|
CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION,
|
|
"Schleieraura",
|
|
"Dieser Zauber macht die Ausrüstung unsichtbar.",
|
|
(cdesc_fun)cinfo_itemcloak
|
|
},
|
|
{ /* C_SPARKLE, */
|
|
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
|
|
"Leichte Verzauberung",
|
|
"Dieser Zauber ist einer der ersten, den junge Magier in der Schule lernen.",
|
|
(cdesc_fun)cinfo_sparkle
|
|
},
|
|
{ /* C_FREE_22, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_23, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_24, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
|
|
/* struct's vom typ curse_skill: */
|
|
{ /* C_SKILL, */
|
|
CURSETYP_SKILL, CURSE_SPREADMODULO, M_MEN,
|
|
"",
|
|
"",
|
|
(cdesc_fun)cinfo_skill
|
|
},
|
|
{ /* C_FREE_30, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_31, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
{ /* C_FREE_32, */
|
|
CURSETYP_UNIT, 0, (NO_MERGE),
|
|
"",
|
|
"",
|
|
NULL
|
|
},
|
|
/* struct's vom typ curse_secondid: */
|
|
};
|
|
|
|
void *
|
|
resolve_curse(void * id)
|
|
{
|
|
return cfindhash((int)id);
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
/* Überbleibsel des alten source:
|
|
* Nur Regionszauber
|
|
*/
|
|
boolean
|
|
is_spell_active(const region * r, curse_t id)
|
|
{
|
|
curse *c;
|
|
c = get_curse(r->attribs, id, 0);
|
|
|
|
if (!c)
|
|
return false;
|
|
|
|
if (c->flag & CURSE_ISNEW)
|
|
return false;
|
|
|
|
return true;
|
|
}
|