server/src/spells/unitcurse.c

374 lines
8.7 KiB
C
Raw Normal View History

2010-08-08 09:40:42 +02:00
/* 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 <storage.h>
2010-08-08 09:40:42 +02:00
/* 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, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
struct unit *u = (struct unit *)obj;
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
if (self != 0) {
if (curse_geteffect(c) > 100) {
2010-08-08 09:40:42 +02:00
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;
}
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
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",
2011-03-07 08:03:10 +01:00
CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_IMMUNE, M_MEN, cinfo_simple
2010-08-08 09:40:42 +02:00
};
/* ------------------------------------------------------------- */
/*
* C_SLAVE
*/
static message *cinfo_slave(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
unit *u;
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
u = (unit *) obj;
2010-08-08 09:40:42 +02:00
2011-03-07 08:03:10 +01:00
if (self != 0) {
return msg_message("curseinfo::slave_1", "unit duration id", u, c->duration,
c->no);
2010-08-08 09:40:42 +02:00
}
return NULL;
}
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
static struct curse_type ct_slavery = { "slavery",
CURSETYP_NORM, 0, NO_MERGE,
cinfo_slave
};
/* ------------------------------------------------------------- */
/*
* C_CALM
*/
static message *cinfo_calm(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
if (c->magician && c->magician->faction) {
faction *f = c->magician->faction;
2011-03-07 08:03:10 +01:00
unit *u = (unit *) obj;
if (f == NULL || self == 0) {
const struct race *rc = u_irace(c->magician);
2010-08-08 09:40:42 +02:00
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",
2011-03-07 08:03:10 +01:00
CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE,
2010-08-08 09:40:42 +02:00
cinfo_calm
};
/* ------------------------------------------------------------- */
/*
* C_SPEED
*/
static message *cinfo_speed(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
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);
2010-08-08 09:40:42 +02:00
}
return NULL;
}
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
static struct curse_type ct_speed = {
"speed",
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
cinfo_speed
};
/* ------------------------------------------------------------- */
/*
* C_ORC
*/
message *cinfo_unit(const void *obj, objtype_t typ, const curse * c, int self)
2010-08-08 09:40:42 +02:00
{
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
if (self != 0) {
unit *u = (unit *) obj;
return msg_message(mkname("curseinfo", c->type->cname), "unit id", u,
c->no);
2010-08-08 09:40:42 +02:00
}
return NULL;
}
static struct curse_type ct_orcish = {
"orcish",
2011-03-07 08:03:10 +01:00
CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_ISNEW, M_MEN,
2010-08-08 09:40:42 +02:00
cinfo_unit
};
/* ------------------------------------------------------------- */
/*
* C_KAELTESCHUTZ
*/
static message *cinfo_kaelteschutz(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
if (self != 0) {
2011-03-07 08:03:10 +01:00
unit *u = (unit *) obj;
return msg_message("curseinfo::warmth_1", "unit number id", u,
get_cursedmen(u, c), c->no);
2010-08-08 09:40:42 +02:00
}
return NULL;
}
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
static struct curse_type ct_insectfur = {
"insectfur",
2011-03-07 08:03:10 +01:00
CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION),
2010-08-08 09:40:42 +02:00
cinfo_kaelteschutz
};
/* ------------------------------------------------------------- */
/*
* C_SPARKLE
*/
static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
2011-03-07 08:03:10 +01:00
const char *effects[] = {
NULL, /* end grau */
2010-08-08 09:40:42 +02:00
"sparkle_1",
"sparkle_2",
2011-03-07 08:03:10 +01:00
NULL, /* end traum */
2010-08-08 09:40:42 +02:00
"sparkle_3",
"sparkle_4",
2011-03-07 08:03:10 +01:00
NULL, /* end tybied */
2010-08-08 09:40:42 +02:00
"sparkle_5",
"sparkle_6",
"sparkle_7",
"sparkle_8",
2011-03-07 08:03:10 +01:00
NULL, /* end cerrdor */
2010-08-08 09:40:42 +02:00
"sparkle_9",
"sparkle_10",
"sparkle_11",
"sparkle_12",
2011-03-07 08:03:10 +01:00
NULL, /* end gwyrrd */
2010-08-08 09:40:42 +02:00
"sparkle_13",
"sparkle_14",
"sparkle_15",
"sparkle_16",
"sparkle_17",
"sparkle_18",
2011-03-07 08:03:10 +01:00
NULL, /* end draig */
2010-08-08 09:40:42 +02:00
};
2011-03-07 08:03:10 +01:00
int m, begin = 0, end = 0;
2010-08-08 09:40:42 +02:00
unit *u;
unused_arg(typ);
2010-08-08 09:40:42 +02:00
assert(typ == TYP_UNIT);
2011-03-07 08:03:10 +01:00
u = (unit *) obj;
2010-08-08 09:40:42 +02:00
2011-03-07 08:03:10 +01:00
if (!c->magician || !c->magician->faction)
return NULL;
2010-08-08 09:40:42 +02:00
2011-03-07 08:03:10 +01:00
for (m = 0; m != c->magician->faction->magiegebiet; ++m) {
while (effects[end] != NULL)
++end;
begin = end + 1;
2010-08-08 09:40:42 +02:00
end = begin;
}
2011-03-07 08:03:10 +01:00
while (effects[end] != NULL)
++end;
if (end == begin)
return NULL;
2010-08-08 09:40:42 +02:00
else {
2011-03-07 08:03:10 +01:00
int index = begin + curse_geteffect_int(c) % (end - begin);
return msg_message(mkname("curseinfo", effects[index]), "unit id", u,
c->no);
2010-08-08 09:40:42 +02:00
}
}
static struct curse_type ct_sparkle = { "sparkle",
2011-03-07 08:03:10 +01:00
CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION), cinfo_sparkle
2010-08-08 09:40:42 +02:00
};
/* ------------------------------------------------------------- */
/*
* 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 = {
2011-03-07 08:03:10 +01:00
"worse", CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_NOAGE, M_MEN, cinfo_unit
2010-08-08 09:40:42 +02:00
};
/* ------------------------------------------------------------- */
/*
* C_ITEMCLOAK
*/
static struct curse_type ct_itemcloak = {
"itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit
};
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
/* ------------------------------------------------------------- */
static struct curse_type ct_fumble = {
2011-03-07 08:03:10 +01:00
"fumble", CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE,
cinfo_unit
2010-08-08 09:40:42 +02:00
};
2011-03-07 08:03:10 +01:00
2010-08-08 09:40:42 +02:00
/* ------------------------------------------------------------- */
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
*/
2011-03-07 08:03:10 +01:00
static int read_skill(struct storage *store, curse * c, void *target)
2010-08-08 09:40:42 +02:00
{
int skill;
if (global.data_version < CURSETYPE_VERSION) {
READ_INT(store, &skill);
READ_INT(store, 0); /* men, ignored */
2010-08-08 09:40:42 +02:00
} else {
READ_INT(store, &skill);
2010-08-08 09:40:42 +02:00
}
c->data.i = skill;
return 0;
}
static int
2011-03-07 08:03:10 +01:00
write_skill(struct storage *store, const curse * c, const void *target)
2010-08-08 09:40:42 +02:00
{
WRITE_INT(store, c->data.i);
2010-08-08 09:40:42 +02:00
return 0;
}
static message *cinfo_skillmod(const void *obj, objtype_t typ, const curse * c,
2011-03-07 08:03:10 +01:00
int self)
2010-08-08 09:40:42 +02:00
{
unused_arg(typ);
2010-08-08 09:40:42 +02:00
if (self != 0) {
2011-03-07 08:03:10 +01:00
unit *u = (unit *) obj;
2010-08-08 09:40:42 +02:00
int sk = c->data.i;
2011-03-07 08:03:10 +01:00
if (c->effect > 0) {
2010-08-08 09:40:42 +02:00
return msg_message("curseinfo::skill_1", "unit skill id", u, sk, c->no);
2011-03-07 08:03:10 +01:00
} else if (c->effect < 0) {
2010-08-08 09:40:42 +02:00
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
};
/* ------------------------------------------------------------- */
2011-03-07 08:03:10 +01:00
void register_unitcurse(void)
2010-08-08 09:40:42 +02:00
{
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);
}