#ifdef _MSC_VER #include #endif #include "borders.h" #include "vortex.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct wallcurse { curse *buddy; connection *wall; } wallcurse; static int cw_read_depr(variant *var, void *target, gamedata *data) { storage *store = data->store; curse_init(var); curse_read(var, store, target); curse_done(var); READ_INT(store, NULL); return AT_READ_DEPR; } /* ------------------------------------------------------------- */ /* Name: Feuerwand * Stufe: * Gebiet: Draig * Kategorie: Region, negativ * Flag: * Kosten: SPC_LINEAR * Aura: * Komponenten: * * Wirkung: * eine Wand aus Feuer entsteht in der angegebenen Richtung * * Was fuer eine Wirkung hat die? */ static void wall_vigour(curse * c, double delta) { wallcurse *wc = (wallcurse *)c->data.v; assert(wc->buddy->vigour == c->vigour); wc->buddy->vigour += delta; if (wc->buddy->vigour <= 0) { erase_border(wc->wall); wc->wall = NULL; ((wallcurse *)wc->buddy->data.v)->wall = NULL; } } const curse_type ct_firewall = { "Feuerwand", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | NO_MERGE), NULL, /* curseinfo */ wall_vigour /* change_vigour */ }; static void wall_init(connection * b) { wall_data *fd = (wall_data *)calloc(1, sizeof(wall_data)); if (!fd) abort(); fd->countdown = -1; /* infinite */ b->data.v = fd; } static void wall_destroy(connection * b) { free(b->data.v); } static void wall_read(connection * b, gamedata * data) { static wall_data dummy; wall_data *fd = b->data.v ? (wall_data *)b->data.v : &dummy; read_unit_reference(data, &fd->mage, NULL); READ_INT(data->store, &fd->force); READ_INT(data->store, &fd->countdown); fd->active = true; } static void wall_write(const connection * b, storage * store) { wall_data *fd = (wall_data *)b->data.v; write_unit_reference(fd->mage, store); WRITE_INT(store, fd->force); WRITE_INT(store, fd->countdown); } static int wall_age(connection * b) { wall_data *fd = (wall_data *)b->data.v; --fd->countdown; return (fd->countdown > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } static region *wall_move(const connection * b, struct unit *u, struct region *from, struct region *to, bool routing) { wall_data *fd = (wall_data *)b->data.v; if (!routing && fd->active) { int hp = dice(3, fd->force) * u->number; if (u->hp < hp) hp = u->hp; u->hp -= hp; if (u->hp) { ADDMSG(&u->faction->msgs, msg_message("firewall_damage", "region unit", from, u)); } else ADDMSG(&u->faction->msgs, msg_message("firewall_death", "region unit", from, u)); if (u->number > u->hp) { scale_number(u, u->hp); u->hp = u->number; } } return to; } static const char *b_namefirewall(const connection * b, const region * r, const faction * f, int gflags) { const char *bname; UNUSED_ARG(f); UNUSED_ARG(r); UNUSED_ARG(b); if (gflags & GF_ARTICLE) bname = "a_firewall"; else bname = "firewall"; if (gflags & GF_PURE) return bname; return LOC(f->locale, mkname("border", bname)); } border_type bt_firewall = { "firewall", VAR_VOIDPTR, 0, b_transparent, /* transparent */ wall_init, /* init */ wall_destroy, /* destroy */ wall_read, /* read */ wall_write, /* write */ b_blocknone, /* block */ b_namefirewall, /* name */ b_rvisible, /* rvisible */ b_finvisible, /* fvisible */ b_uinvisible, /* uvisible */ NULL, wall_move, wall_age }; void convert_firewall_timeouts(connection * b, attrib * a) { while (a) { if (b->type == &bt_firewall && a->type == &at_countdown) { wall_data *fd = (wall_data *)b->data.v; fd->countdown = a->data.i; } a = a->next; } } border_type bt_wisps = { /* only here for reading old data */ "wisps", VAR_VOIDPTR, 0, b_transparent, /* transparent */ 0, /* init */ wall_destroy, /* destroy */ wall_read, /* read */ 0, /* write */ b_blocknone, /* block */ 0, /* name */ b_rvisible, /* rvisible */ b_fvisible, /* fvisible */ b_uvisible, /* uvisible */ NULL, /* visible */ 0 }; static bool chaosgate_valid(const connection * b) { const attrib *a = a_find(b->from->attribs, &at_direction); if (!a) a = a_find(b->to->attribs, &at_direction); if (!a) return false; return true; } static struct region *chaosgate_move(const connection * b, struct unit *u, struct region *from, struct region *to, bool routing) { UNUSED_ARG(from); UNUSED_ARG(b); if (!routing) { int maxhp = u->hp / 4; if (maxhp < u->number) maxhp = u->number; u->hp = maxhp; } return to; } border_type bt_chaosgate = { "chaosgate", VAR_NONE, 0, b_transparent, /* transparent */ NULL, /* init */ NULL, /* destroy */ NULL, /* read */ NULL, /* write */ b_blocknone, /* block */ NULL, /* name */ b_rinvisible, /* rvisible */ b_finvisible, /* fvisible */ b_uinvisible, /* uvisible */ chaosgate_valid, chaosgate_move }; void register_borders(void) { border_convert_cb = &convert_firewall_timeouts; at_deprecate("cursewall", cw_read_depr); register_bordertype(&bt_firewall); register_bordertype(&bt_wisps); register_bordertype(&bt_chaosgate); }