2015-01-30 20:37:14 +01:00
|
|
|
|
/*
|
2010-08-08 09:40:42 +02:00
|
|
|
|
*
|
2015-01-30 20:37:14 +01:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2015
|
2010-08-08 09:40:42 +02:00
|
|
|
|
* 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 "alp.h"
|
|
|
|
|
|
2012-06-05 06:45:25 +02:00
|
|
|
|
#include <kernel/curse.h>
|
2010-08-08 09:40:42 +02:00
|
|
|
|
#include <kernel/faction.h>
|
2014-06-09 18:54:48 +02:00
|
|
|
|
#include <kernel/messages.h>
|
2010-08-08 09:40:42 +02:00
|
|
|
|
#include <kernel/race.h>
|
|
|
|
|
#include <kernel/region.h>
|
|
|
|
|
#include <kernel/unit.h>
|
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <util/attrib.h>
|
|
|
|
|
#include <util/event.h>
|
|
|
|
|
#include <util/resolve.h>
|
|
|
|
|
#include <util/umlaut.h>
|
2013-12-31 10:06:28 +01:00
|
|
|
|
|
2014-11-11 16:53:56 +01:00
|
|
|
|
#include "monster.h"
|
|
|
|
|
|
2013-12-31 10:06:28 +01:00
|
|
|
|
#include <storage.h>
|
2010-08-08 09:40:42 +02:00
|
|
|
|
|
|
|
|
|
#include <triggers/createcurse.h>
|
|
|
|
|
#include <triggers/killunit.h>
|
|
|
|
|
#include <triggers/removecurse.h>
|
|
|
|
|
#include <triggers/unitmessage.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
extern const char *directions[];
|
|
|
|
|
|
|
|
|
|
typedef struct alp_data {
|
2015-01-30 20:37:14 +01:00
|
|
|
|
unit *mage;
|
|
|
|
|
unit *target;
|
2010-08-08 09:40:42 +02:00
|
|
|
|
} alp_data;
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
static void alp_init(attrib * a)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
a->data.v = calloc(sizeof(alp_data), 1);
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
static void alp_done(attrib * a)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
free(a->data.v);
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
static int alp_verify(attrib * a)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
alp_data *ad = (alp_data *)a->data.v;
|
|
|
|
|
if (ad->mage && ad->target)
|
|
|
|
|
return 1;
|
|
|
|
|
return 0; /* remove the attribute */
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-03-07 08:03:10 +01:00
|
|
|
|
alp_write(const attrib * a, const void *owner, struct storage *store)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
alp_data *ad = (alp_data *)a->data.v;
|
|
|
|
|
write_unit_reference(ad->mage, store);
|
|
|
|
|
write_unit_reference(ad->target, store);
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
static int alp_read(attrib * a, void *owner, struct storage *store)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
alp_data *ad = (alp_data *)a->data.v;
|
|
|
|
|
int rm = read_reference(&ad->mage, store, read_unit_reference, resolve_unit);
|
|
|
|
|
int rt =
|
|
|
|
|
read_reference(&ad->target, store, read_unit_reference, resolve_unit);
|
|
|
|
|
if (rt == 0 && rm == 0 && (!ad->target || !ad->mage)) {
|
|
|
|
|
/* the target or mage disappeared. */
|
|
|
|
|
return AT_READ_FAIL;
|
|
|
|
|
}
|
|
|
|
|
return AT_READ_OK;
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
static attrib_type at_alp = {
|
2015-01-30 20:37:14 +01:00
|
|
|
|
"alp",
|
|
|
|
|
alp_init,
|
|
|
|
|
alp_done,
|
|
|
|
|
alp_verify,
|
|
|
|
|
alp_write,
|
|
|
|
|
alp_read,
|
|
|
|
|
ATF_UNIQUE
|
2010-08-08 09:40:42 +02:00
|
|
|
|
};
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
int sp_summon_alp(struct castorder *co)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
unit *alp, *opfer;
|
|
|
|
|
region *r = co_get_region(co);
|
|
|
|
|
unit *mage = co->magician.u;
|
|
|
|
|
int cast_level = co->level;
|
|
|
|
|
spellparameter *pa = co->par;
|
|
|
|
|
const struct race *rc = get_race(RC_ALP);
|
|
|
|
|
struct faction *f = get_monsters();
|
|
|
|
|
struct message *msg;
|
|
|
|
|
|
|
|
|
|
opfer = pa->param[0]->data.u;
|
|
|
|
|
|
|
|
|
|
/* Der Alp geh<65>rt den Monstern, darum erh<72>lt der Magier auch keine
|
|
|
|
|
* Regionsberichte von ihm. Er erh<EFBFBD>lt aber sp<EFBFBD>ter eine Mitteilung,
|
|
|
|
|
* sobald der Alp sein Opfer erreicht hat.
|
|
|
|
|
*/
|
|
|
|
|
alp = create_unit(r, f, 1, rc, 0, NULL, NULL);
|
|
|
|
|
set_level(alp, SK_STEALTH, 7);
|
|
|
|
|
setstatus(alp, ST_FLEE); /* flieht */
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
attrib *a = a_add(&alp->attribs, a_new(&at_alp));
|
|
|
|
|
alp_data *ad = (alp_data *)a->data.v;
|
|
|
|
|
ad->mage = mage;
|
|
|
|
|
ad->target = opfer;
|
|
|
|
|
}
|
2010-08-08 09:40:42 +02:00
|
|
|
|
|
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
/* Wenn der Alp stirbt, den Magier nachrichtigen */
|
|
|
|
|
add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage,
|
|
|
|
|
"trigger_alp_destroy", MSG_EVENT, ML_INFO));
|
|
|
|
|
/* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */
|
|
|
|
|
add_trigger(&mage->attribs, "destroy", trigger_killunit(alp));
|
|
|
|
|
add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp));
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
msg = msg_message("summon_alp_effect", "mage alp target", mage, alp, opfer);
|
|
|
|
|
r_addmessage(r, mage->faction, msg);
|
|
|
|
|
msg_release(msg);
|
|
|
|
|
|
|
|
|
|
return cast_level;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
void alp_findet_opfer(unit * alp, region * r)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
curse *c;
|
|
|
|
|
attrib *a = a_find(alp->attribs, &at_alp);
|
|
|
|
|
alp_data *ad = (alp_data *)a->data.v;
|
|
|
|
|
unit *mage = ad->mage;
|
|
|
|
|
unit *opfer = ad->target;
|
|
|
|
|
float effect;
|
|
|
|
|
message *msg;
|
|
|
|
|
|
|
|
|
|
assert(opfer);
|
|
|
|
|
assert(mage);
|
|
|
|
|
|
|
|
|
|
/* Magier und Opfer Bescheid geben */
|
|
|
|
|
msg = msg_message("alp_success", "target", opfer);
|
|
|
|
|
add_message(&mage->faction->msgs, msg);
|
|
|
|
|
r_addmessage(opfer->region, opfer->faction, msg);
|
|
|
|
|
msg_release(msg);
|
|
|
|
|
|
|
|
|
|
/* Relations werden in destroy_unit(alp) automatisch gel<65>scht.
|
|
|
|
|
* Die Aktionen, die beim Tod des Alps ausgel<EFBFBD>st werden sollen,
|
|
|
|
|
* m<EFBFBD>ssen jetzt aber deaktiviert werden, sonst werden sie gleich
|
|
|
|
|
* beim destroy_unit(alp) ausgel<EFBFBD>st.
|
|
|
|
|
*/
|
|
|
|
|
a_removeall(&alp->attribs, &at_eventhandler);
|
|
|
|
|
|
|
|
|
|
/* Alp umwandeln in Curse */
|
|
|
|
|
effect = -2;
|
|
|
|
|
c =
|
|
|
|
|
create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect,
|
|
|
|
|
opfer->number);
|
|
|
|
|
/* solange es noch keine spezielle alp-Antimagie gibt, reagiert der
|
|
|
|
|
* auch auf normale */
|
|
|
|
|
set_number(alp, 0);
|
|
|
|
|
|
|
|
|
|
/* wenn der Magier stirbt, wird der Curse wieder vom Opfer genommen */
|
|
|
|
|
add_trigger(&mage->attribs, "destroy", trigger_removecurse(c, opfer));
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
void register_alp(void)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
at_register(&at_alp);
|
2010-08-08 09:40:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 08:03:10 +01:00
|
|
|
|
unit *alp_target(unit * alp)
|
2010-08-08 09:40:42 +02:00
|
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
|
alp_data *ad;
|
|
|
|
|
unit *target = NULL;
|
2011-03-07 08:03:10 +01:00
|
|
|
|
|
2015-01-30 20:37:14 +01:00
|
|
|
|
attrib *a = a_find(alp->attribs, &at_alp);
|
2011-03-07 08:03:10 +01:00
|
|
|
|
|
2015-01-30 20:37:14 +01:00
|
|
|
|
if (a) {
|
|
|
|
|
ad = (alp_data *)a->data.v;
|
|
|
|
|
target = ad->target;
|
|
|
|
|
}
|
|
|
|
|
return target;
|
2010-08-08 09:40:42 +02:00
|
|
|
|
|
|
|
|
|
}
|