unify change_race trigger use.

make all transformations use a single function.
This commit is contained in:
Enno Rehling 2021-06-19 12:11:57 +02:00
parent 4c64affdfc
commit 6cac6439bf
8 changed files with 84 additions and 49 deletions

View File

@ -292,15 +292,8 @@ struct order *ord)
rcfailure = rc_find("toad"); rcfailure = rc_find("toad");
} }
if (rcfailure) { if (rcfailure) {
trigger *trestore = trigger_changerace(u, u_race(u), u->irace);
if (trestore) {
int duration = 2 + rng_int() % 8; int duration = 2 + rng_int() % 8;
change_race(u, duration, rcfailure, NULL);
add_trigger(&u->attribs, "timer", trigger_timeout(duration,
trestore));
u->irace = NULL;
u_setrace(u, rcfailure);
}
} }
} }
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,

View File

@ -1273,10 +1273,12 @@ static void do_fumble(castorder * co)
unit *caster = co_get_caster(co); unit *caster = co_get_caster(co);
const spell *sp = co->sp; const spell *sp = co->sp;
int level = co->level; int level = co->level;
int duration;
double effect; double effect;
static int rc_cache; static int rc_cache;
static const race *rc_toad = NULL;
fumble_f fun; fumble_f fun;
trigger *trestore;
int duration;
ADDMSG(&caster->faction->msgs, ADDMSG(&caster->faction->msgs,
msg_message("patzer", "unit region spell", caster, r, sp)); msg_message("patzer", "unit region spell", caster, r, sp));
@ -1293,32 +1295,26 @@ static void do_fumble(castorder * co)
break; break;
case 1: /* toad */ case 1: /* toad */
{ /* one or two things will happen: the toad changes its race back,
/* one or two things will happen: the toad changes her race back,
* and may or may not get toadslime. * and may or may not get toadslime.
* The list of things to happen are attached to a timeout * The list of things to happen are attached to a timeout
* trigger and that's added to the triggerlit of the mage gone toad. * trigger and that's added to the triggerlist of the mage gone toad.
*/ */
static const race *rc_toad; if (rc_changed(&rc_cache)) {
trigger *trestore = trigger_changerace(mage, u_race(mage), mage->irace); rc_toad = get_race(RC_TOAD);
}
duration = rng_int() % level / 2;
trestore = change_race(mage, duration, rc_toad, NULL);
if (trestore) {
if (chance(0.7)) { if (chance(0.7)) {
const resource_type *rtype = rt_find("toadslime"); const resource_type *rtype = rt_find("toadslime");
if (rtype) { if (rtype) {
t_add(&trestore, trigger_giveitem(mage, rtype->itype, 1)); t_add(&trestore, trigger_giveitem(mage, rtype->itype, 1));
} }
} }
duration = rng_int() % level / 2;
if (duration < 2) duration = 2;
add_trigger(&mage->attribs, "timer", trigger_timeout(duration, trestore));
if (rc_changed(&rc_cache)) {
rc_toad = get_race(RC_TOAD);
}
u_setrace(mage, rc_toad);
mage->irace = NULL;
ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", mage, r, sp)); ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", mage, r, sp));
break;
} }
/* fall-through is intentional! */ break;
case 2: case 2:
/* temporary skill loss */ /* temporary skill loss */
@ -1330,6 +1326,7 @@ static void do_fumble(castorder * co)
c->data.i = SK_MAGIC; c->data.i = SK_MAGIC;
ADDMSG(&caster->faction->msgs, msg_message("patzer2", "unit region", caster, r)); ADDMSG(&caster->faction->msgs, msg_message("patzer2", "unit region", caster, r));
break; break;
case 3: case 3:
case 4: case 4:
/* Spruch schlaegt fehl, alle Magiepunkte weg */ /* Spruch schlaegt fehl, alle Magiepunkte weg */

View File

@ -4551,13 +4551,13 @@ int sp_illusionary_shapeshift(castorder * co)
return 0; return 0;
} }
add_trigger(&u->attribs, "timer", trigger_timeout((int)power + 3, if (NULL == change_race(u, 3 + (int)power, NULL, irace)) {
trigger_changerace(u, NULL, irace))); ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
u->irace = rc; "sp_shapeshift_fail", "target race", u, rc));
return 0;
}
ADDMSG(&mage->faction->msgs, msg_message("shapeshift_effect", ADDMSG(&mage->faction->msgs, msg_message("shapeshift_effect",
"mage target race", mage, u, rc)); "mage target race", mage, u, rc));
return cast_level; return cast_level;
} }

View File

@ -5,6 +5,7 @@
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/curse.h> #include <kernel/curse.h>
#include <kernel/event.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/plane.h> #include <kernel/plane.h>
@ -19,6 +20,9 @@
#include <attributes/attributes.h> #include <attributes/attributes.h>
#include <triggers/changerace.h>
#include <triggers/timeout.h>
#include <CuTest.h> #include <CuTest.h>
#include <tests.h> #include <tests.h>
@ -280,6 +284,38 @@ static void test_watch_region(CuTest *tc) {
test_teardown(); test_teardown();
} }
static void test_change_race(CuTest *tc) {
unit *u;
race *rctoad;
trigger **tp, *tr;
timeout_data *td;
changerace_data *crd;
test_setup();
rctoad = test_create_race("toad");
u = test_create_unit(test_create_faction(), test_create_plain(0, 0));
CuAssertPtrEquals(tc, (void *)u->faction->race, (void *)u->_race);
CuAssertPtrNotNull(tc, change_race(u, 2, rctoad, NULL));
CuAssertPtrEquals(tc, (void *)rctoad, (void *)u->_race);
CuAssertPtrEquals(tc, NULL, (void *)u->irace);
CuAssertPtrNotNull(tc, u->attribs);
tp = get_triggers(u->attribs, "timer");
CuAssertPtrNotNull(tc, tp);
CuAssertPtrNotNull(tc, tr = *tp);
CuAssertPtrEquals(tc, &tt_timeout, tr->type);
td = (timeout_data *)tr->data.v;
CuAssertPtrNotNull(tc, td);
CuAssertIntEquals(tc, 2, td->timer);
CuAssertPtrNotNull(tc, td->triggers);
CuAssertPtrEquals(tc, &tt_changerace, td->triggers->type);
CuAssertPtrEquals(tc, NULL, td->triggers->next);
crd = (changerace_data *)td->triggers->data.v;
CuAssertPtrEquals(tc, (void *)u->faction->race, (void *)crd->race);
CuAssertPtrEquals(tc, NULL, (void *)crd->irace);
test_teardown();
}
CuSuite *get_spells_suite(void) CuSuite *get_spells_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
@ -289,5 +325,6 @@ CuSuite *get_spells_suite(void)
SUITE_ADD_TEST(suite, test_good_dreams); SUITE_ADD_TEST(suite, test_good_dreams);
SUITE_ADD_TEST(suite, test_bad_dreams); SUITE_ADD_TEST(suite, test_bad_dreams);
SUITE_ADD_TEST(suite, test_dreams); SUITE_ADD_TEST(suite, test_dreams);
SUITE_ADD_TEST(suite, test_change_race);
return suite; return suite;
} }

View File

@ -1,5 +1,6 @@
#include <platform.h> #include <platform.h>
#include "changerace.h" #include "changerace.h"
#include "timeout.h"
/* kernel includes */ /* kernel includes */
#include <kernel/unit.h> #include <kernel/unit.h>
@ -26,12 +27,6 @@
** restore a mage that was turned into a toad ** restore a mage that was turned into a toad
**/ **/
typedef struct changerace_data {
struct unit *u;
const struct race *race;
const struct race *irace;
} changerace_data;
static void changerace_init(trigger * t) static void changerace_init(trigger * t)
{ {
t->data.v = calloc(1, sizeof(changerace_data)); t->data.v = calloc(1, sizeof(changerace_data));
@ -97,3 +92,13 @@ trigger *trigger_changerace(unit * u, const race * prace, const race * irace)
td->irace = irace; td->irace = irace;
return t; return t;
} }
extern struct trigger *change_race(struct unit *u, int duration, const struct race *urace, const struct race *irace) {
trigger *trestore = trigger_changerace(u, u_race(u), u->irace);
if (trestore) {
add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore));
u->irace = irace;
u_setrace(u, urace);
}
return trestore;
}

View File

@ -10,11 +10,15 @@ extern "C" {
struct unit; struct unit;
struct race; struct race;
typedef struct changerace_data {
struct unit *u;
const struct race *race;
const struct race *irace;
} changerace_data;
extern struct trigger_type tt_changerace; extern struct trigger_type tt_changerace;
extern struct trigger *trigger_changerace(struct unit *u, extern struct trigger *change_race(struct unit *u, int duration, const struct race *urace, const struct race *irace);
const struct race *urace, const struct race *irace);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -16,12 +16,6 @@
** timeout ** timeout
**/ **/
typedef struct timeout_data {
trigger *triggers;
int timer;
variant trigger_data;
} timeout_data;
static void timeout_init(trigger * t) static void timeout_init(trigger * t)
{ {
t->data.v = calloc(1, sizeof(timeout_data)); t->data.v = calloc(1, sizeof(timeout_data));

View File

@ -7,6 +7,11 @@ extern "C" {
struct trigger_type; struct trigger_type;
struct trigger; struct trigger;
typedef struct timeout_data {
struct trigger *triggers;
int timer;
} timeout_data;
extern struct trigger_type tt_timeout; extern struct trigger_type tt_timeout;
extern struct trigger *trigger_timeout(int time, struct trigger *callbacks); extern struct trigger *trigger_timeout(int time, struct trigger *callbacks);