server/src/spells/unitcurse.c

364 lines
8.8 KiB
C
Raw Normal View History

/* vi: set ts=2:
*
* Eressea PB(E)M host Copyright (C) 1998-2003
* 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.de)
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
*
* This program may not be used, modified or distributed without
* prior permission by the authors of Eressea.
*/
#include <platform.h>
#include <kernel/config.h>
#include "unitcurse.h"
/* kernel includes */
#include <kernel/curse.h>
#include <kernel/message.h>
#include <kernel/race.h>
#include <kernel/skill.h>
#include <kernel/unit.h>
#include <kernel/faction.h>
#include <kernel/objtypes.h>
#include <kernel/version.h>
/* util includes */
#include <util/language.h>
#include <util/nrmessage.h>
#include <util/message.h>
#include <util/base36.h>
#include <util/functions.h>
#include <util/storage.h>
/* libc includes */
#include <string.h>
#include <stdlib.h>
#include <assert.h>
/* ------------------------------------------------------------- */
/*
* C_AURA
*/
/* erh<72>ht/senkt regeneration und maxaura um effect% */
static message *
cinfo_auraboost(const void * obj, typ_t typ, const curse *c, int self)
{
struct unit *u = (struct unit *)obj;
unused(typ);
assert(typ == TYP_UNIT);
if (self != 0){
if (curse_geteffect(c) > 100){
return msg_message("curseinfo::auraboost_0", "unit id", u, c->no);
} else {
return msg_message("curseinfo::auraboost_1", "unit id", u, c->no);
}
}
return NULL;
}
static struct curse_type ct_auraboost = {
"auraboost",
CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE),
cinfo_auraboost
};
/* Magic Boost - Gabe des Chaos */
static struct curse_type ct_magicboost = {
"magicboost",
CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_IMMUNE, M_MEN, cinfo_simple
};
/* ------------------------------------------------------------- */
/*
* C_SLAVE
*/
static message *
cinfo_slave(const void * obj, typ_t typ, const curse *c, int self)
{
unit *u;
unused(typ);
assert(typ == TYP_UNIT);
u = (unit *)obj;
if (self != 0){
return msg_message("curseinfo::slave_1", "unit duration id", u, c->duration, c->no);
}
return NULL;
}
static struct curse_type ct_slavery = { "slavery",
CURSETYP_NORM, 0, NO_MERGE,
cinfo_slave
};
/* ------------------------------------------------------------- */
/*
* C_CALM
*/
static message *
cinfo_calm(const void * obj, typ_t typ, const curse *c, int self)
{
unused(typ);
assert(typ == TYP_UNIT);
if (c->magician && c->magician->faction) {
faction *f = c->magician->faction;
unit *u = (unit *)obj;
if (f==NULL || self == 0) {
const struct race * rc = u_irace(c->magician);
return msg_message("curseinfo::calm_0", "unit race id", u, rc, c->no);
}
return msg_message("curseinfo::calm_1", "unit faction id", u, f, c->no);
}
return NULL;
}
static struct curse_type ct_calmmonster = {
"calmmonster",
CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE,
cinfo_calm
};
/* ------------------------------------------------------------- */
/*
* C_SPEED
*/
static message *
cinfo_speed(const void * obj, typ_t typ, const curse *c, int self)
{
unused(typ);
assert(typ == TYP_UNIT);
if (self != 0){
unit *u = (unit *)obj;
return msg_message("curseinfo::speed_1", "unit number duration id", u, c->data.i, c->duration, c->no);
}
return NULL;
}
static struct curse_type ct_speed = {
"speed",
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
cinfo_speed
};
/* ------------------------------------------------------------- */
/*
* C_ORC
*/
message *
cinfo_unit(const void * obj, typ_t typ, const curse *c, int self)
{
unused(typ);
assert(typ == TYP_UNIT);
if (self != 0){
unit * u = (unit *)obj;
return msg_message(mkname("curseinfo", c->type->cname), "unit id", u, c->no);
}
return NULL;
}
static struct curse_type ct_orcish = {
"orcish",
CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_ISNEW, M_MEN,
cinfo_unit
};
/* ------------------------------------------------------------- */
/*
* C_KAELTESCHUTZ
*/
static message *
cinfo_kaelteschutz(const void * obj, typ_t typ, const curse *c, int self)
{
unused(typ);
assert(typ == TYP_UNIT);
if (self != 0) {
unit * u = (unit *)obj;
return msg_message("curseinfo::warmth_1", "unit number id", u, get_cursedmen(u, c), c->no);
}
return NULL;
}
static struct curse_type ct_insectfur = {
"insectfur",
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
cinfo_kaelteschutz
};
/* ------------------------------------------------------------- */
/*
* C_SPARKLE
*/
static message *
cinfo_sparkle(const void * obj, typ_t typ, const curse *c, int self)
{
const char * effects[] = {
NULL, /* end grau*/
"sparkle_1",
"sparkle_2",
NULL, /* end traum */
"sparkle_3",
"sparkle_4",
NULL, /* end tybied */
"sparkle_5",
"sparkle_6",
"sparkle_7",
"sparkle_8",
NULL, /* end cerrdor */
"sparkle_9",
"sparkle_10",
"sparkle_11",
"sparkle_12",
NULL, /* end gwyrrd */
"sparkle_13",
"sparkle_14",
"sparkle_15",
"sparkle_16",
"sparkle_17",
"sparkle_18",
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 NULL;
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 NULL;
else {
int index = begin + curse_geteffect_int(c) % (end-begin);
return msg_message(mkname("curseinfo", effects[index]), "unit id", u, c->no);
}
}
static struct curse_type ct_sparkle = { "sparkle",
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ), cinfo_sparkle
};
/* ------------------------------------------------------------- */
/*
* C_STRENGTH
*/
static struct curse_type ct_strength = { "strength",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple
};
/* ------------------------------------------------------------- */
/*
* C_ALLSKILLS (Alp)
*/
static struct curse_type ct_worse = {
"worse", CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_NOAGE, M_MEN, cinfo_unit
};
/* ------------------------------------------------------------- */
/*
* C_ITEMCLOAK
*/
static struct curse_type ct_itemcloak = {
"itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit
};
/* ------------------------------------------------------------- */
static struct curse_type ct_fumble = {
"fumble", CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE, cinfo_unit
};
/* ------------------------------------------------------------- */
static struct curse_type ct_oldrace = {
"oldrace", CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, NULL
};
static struct curse_type ct_magicresistance = {
"magicresistance", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple
};
/* ------------------------------------------------------------- */
/*
* C_SKILL
*/
static int
read_skill(struct storage * store, curse * c, void * target)
{
int skill;
if (store->version<CURSETYPE_VERSION) {
int men;
skill = store->r_int(store);
men = store->r_int(store);
} else {
skill = store->r_int(store);
}
c->data.i = skill;
return 0;
}
static int
write_skill(struct storage * store, const curse * c, const void * target)
{
store->w_int(store, c->data.i);
return 0;
}
static message *
cinfo_skillmod(const void * obj, typ_t typ, const curse *c, int self)
{
unused(typ);
if (self != 0) {
unit *u = (unit *)obj;
int sk = c->data.i;
if (c->effect>0) {
return msg_message("curseinfo::skill_1", "unit skill id", u, sk, c->no);
} else if (c->effect<0) {
return msg_message("curseinfo::skill_2", "unit skill id", u, sk, c->no);
}
}
return NULL;
}
static struct curse_type ct_skillmod = {
"skillmod", CURSETYP_NORM, CURSE_SPREADMODULO, M_MEN, cinfo_skillmod,
NULL, read_skill, write_skill
};
/* ------------------------------------------------------------- */
void
register_unitcurse(void)
{
ct_register(&ct_auraboost);
ct_register(&ct_magicboost);
ct_register(&ct_slavery);
ct_register(&ct_calmmonster);
ct_register(&ct_speed);
ct_register(&ct_orcish);
ct_register(&ct_insectfur);
ct_register(&ct_sparkle);
ct_register(&ct_strength);
ct_register(&ct_worse);
ct_register(&ct_skillmod);
ct_register(&ct_itemcloak);
ct_register(&ct_fumble);
ct_register(&ct_oldrace);
ct_register(&ct_magicresistance);
}