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

View File

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

View File

@ -5,6 +5,7 @@
#include <kernel/config.h>
#include <kernel/curse.h>
#include <kernel/event.h>
#include <kernel/faction.h>
#include <kernel/order.h>
#include <kernel/plane.h>
@ -19,6 +20,9 @@
#include <attributes/attributes.h>
#include <triggers/changerace.h>
#include <triggers/timeout.h>
#include <CuTest.h>
#include <tests.h>
@ -280,6 +284,38 @@ static void test_watch_region(CuTest *tc) {
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 *suite = CuSuiteNew();
@ -289,5 +325,6 @@ CuSuite *get_spells_suite(void)
SUITE_ADD_TEST(suite, test_good_dreams);
SUITE_ADD_TEST(suite, test_bad_dreams);
SUITE_ADD_TEST(suite, test_dreams);
SUITE_ADD_TEST(suite, test_change_race);
return suite;
}

View File

@ -1,5 +1,6 @@
#include <platform.h>
#include "changerace.h"
#include "timeout.h"
/* kernel includes */
#include <kernel/unit.h>
@ -26,12 +27,6 @@
** 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)
{
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;
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 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 *trigger_changerace(struct unit *u,
const struct race *urace, const struct race *irace);
extern struct trigger *change_race(struct unit *u, int duration, const struct race *urace, const struct race *irace);
#ifdef __cplusplus
}
#endif

View File

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

View File

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