static void test_dragon_attacks_the_rich(CuTest * tc) { faction *f, *f2; unit *u, *m; const item_type *i_silver; create_monsters(&f, &f2, &u, &m); init_resources(); setguard(m, true); set_level(m, SK_WEAPONLESS, 10); rsetmoney(findregion(0, 0), 1); rsetmoney(findregion(1, 0), 0); i_silver = it_find("money"); assert(i_silver); i_change(&u->items, i_silver, 5000); config_set("rules.monsters.attack_chance", "0.00001"); plan_monsters(f2); CuAssertPtrNotNull(tc, find_order("attack 1", m)); CuAssertPtrNotNull(tc, find_order("loot", m)); test_cleanup(); }
void move_unit(unit * u, region * r, unit ** ulist) { assert(u && r); assert(u->faction || !"this unit is dead"); if (u->region == r) return; if (!ulist) ulist = (&r->units); if (u->region) { setguard(u, GUARD_NONE); fset(u, UFL_MOVED); if (u->ship || u->building) { /* can_leave must be checked in travel_i */ #ifndef NDEBUG bool result = leave(u, false); assert(result); #else leave(u, false); #endif } translist(&u->region->units, ulist, u); } else { addlist(ulist, u); } #ifdef SMART_INTERVALS update_interval(u->faction, r); #endif u->region = r; }
/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in * eine Nachbarregion, wobei ein NACH beruecksichtigt wird. Ansonsten * bleibt er stehen und nimmt nicht weiter am Kampf teil. */ int sp_appeasement(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; const spell * sp = co->sp; battle *b = fi->side->battle; unit *mage = fi->unit; region *r = b->region; message *m; /* Fliehende Einheiten verlassen auf jeden Fall Gebaeude und Schiffe. */ if (!(r->terrain->flags & SEA_REGION)) { leave(mage, false); } /* und bewachen nicht */ setguard(mage, false); unit_setstatus(mage, ST_FLEE); /* wir tun so, als waere die Person geflohen */ fi->flags |= FIG_NOLOOT; fi->run.hp = mage->hp; fi->run.number = mage->number; /* fighter leeren */ rmfighter(fi, mage->number); m = msg_message("cast_escape_effect", "mage spell", fi->unit, sp); message_all(b, m); msg_release(m); return level; }
/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in * eine Nachbarregion, wobei ein NACH berücksichtigt wird. Ansonsten * bleibt er stehen und nimmt nicht weiter am Kampf teil. */ int sp_denyattack(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; const spell * sp = co->sp; battle *b = fi->side->battle; unit *mage = fi->unit; region *r = b->region; message *m; /* Fliehende Einheiten verlassen auf jeden Fall Gebäude und Schiffe. */ if (!fval(r->terrain, SEA_REGION)) { leave(mage, false); } /* und bewachen nicht */ setguard(mage, GUARD_NONE); /* irgendwie den langen befehl sperren */ /* fset(fi, FIG_ATTACKED); */ /* wir tun so, als wäre die Person geflohen */ fset(fi, FIG_NOLOOT); fi->run.hp = mage->hp; fi->run.number = mage->number; /* fighter leeren */ rmfighter(fi, mage->number); m = msg_message("cast_escape_effect", "mage spell", fi->unit, sp); message_all(b, m); msg_release(m); return level; }
static void test_monsters_attack_not(CuTest * tc) { faction *f, *f2; unit *u, *m; create_monsters(&f, &f2, &u, &m); setguard(m, true); setguard(u, true); config_set("rules.monsters.attack_chance", "0"); plan_monsters(f2); CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); test_cleanup(); }
static void test_monsters_waiting(CuTest * tc) { faction *f, *f2; unit *u, *m; create_monsters(&f, &f2, &u, &m); setguard(m, true); fset(m, UFL_ISNEW); monster_attacks(m, false, false); CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); test_cleanup(); }
void update_guards(void) { const region *r; for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { if (fval(u, UFL_GUARD)) { if (can_start_guarding(u) != E_GUARD_OK) { setguard(u, false); } } } } }
void guard(unit * u) { setguard(u, true); }
int sp_undeadhero(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; double power = co->force; battle *b = fi->side->battle; unit *mage = fi->unit; region *r = b->region; selist *fgs, *ql; int qi, n, undead = 0; message *msg; int force = (int)get_force(power, 0); double c = 0.50 + 0.02 * power; /* Liste aus allen Kaempfern */ fgs = select_fighters(b, fi->side, FS_ENEMY | FS_HELP, select_hero, NULL); scramble_fighters(fgs); for (qi = 0, ql = fgs; ql && force>0; selist_advance(&ql, &qi, 1)) { fighter *df = (fighter *)selist_get(ql, qi); unit *du = df->unit; int j = 0; /* Wieviele Untote koennen wir aus dieser Einheit wecken? */ for (n = df->alive + df->run.number; force>0 && n != du->number; n++) { if (chance(c)) { ++j; --force; } } if (j > 0) { item **ilist; unit *u = create_unit(r, mage->faction, 0, get_race(RC_UNDEAD), 0, unit_getname(du), du); /* new units gets some stats from old unit */ unit_setinfo(u, unit_getinfo(du)); unit_setstatus(u, du->status); setguard(u, false); for (ilist = &du->items; *ilist;) { item *itm = *ilist; int loot = itm->number * j / du->number; if (loot != itm->number) { int split = itm->number * j % du->number; if (split > 0 && (rng_int() % du->number) < split) { ++loot; } } i_change(&u->items, itm->type, loot); i_change(ilist, itm->type, -loot); if (*ilist == itm) { ilist = &itm->next; } } /* inherit stealth from magician */ if (mage->flags & UFL_ANON_FACTION) { u->flags |= UFL_ANON_FACTION; } /* transfer dead people to new unit, set hitpoints to those of old unit */ transfermen(du, u, j); u->hp = u->number * unit_max_hp(du); assert(j <= df->side->casualties); df->side->casualties -= j; df->side->dead -= j; /* counting total number of undead */ undead += j; } } selist_free(fgs); if (level > undead) { level = undead; } if (undead == 0) { msg = msg_message("summonundead_effect_0", "mage region", mage, mage->region); } else { msg = msg_message("summonundead_effect_1", "mage region amount", mage, mage->region, undead); } message_all(b, msg); msg_release(msg); return level; }
int sp_undeadhero(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; double power = co->force; battle *b = fi->side->battle; unit *mage = fi->unit; region *r = b->region; quicklist *fgs, *ql; int qi, n, undead = 0; message *msg; int force = (int)get_force(power, 0); double c = 0.50 + 0.02 * power; /* Liste aus allen Kämpfern */ fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP); scramble_fighters(fgs); for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) { fighter *df = (fighter *) ql_get(ql, qi); unit *du = df->unit; if (force <= 0) break; /* keine Monster */ if (!playerrace(u_race(du))) continue; if (df->alive + df->run.number < du->number) { int j = 0; /* Wieviele Untote können wir aus dieser Einheit wecken? */ for (n = df->alive + df->run.number; n != du->number; n++) { if (chance(c)) { ++j; if (--force <= 0) break; } } if (j > 0) { unit *u = create_unit(r, mage->faction, 0, new_race[RC_UNDEAD], 0, du->name, du); /* new units gets some stats from old unit */ if (du->display) { unit_setinfo(u, du->display); } else { unit_setinfo(u, NULL); } setstatus(u, du->status); setguard(u, GUARD_NONE); /* inherit stealth from magician */ if (fval(mage, UFL_ANON_FACTION)) { fset(u, UFL_ANON_FACTION); } /* transfer dead people to new unit, set hitpoints to those of old unit */ transfermen(du, u, j); u->hp = u->number * unit_max_hp(du); assert(j <= df->side->casualties); df->side->casualties -= j; df->side->dead -= j; /* counting total number of undead */ undead += j; } } } ql_free(fgs); level = _min(level, undead); if (undead == 0) { msg = msg_message("summonundead_effect_0", "mage region", mage, mage->region); } else { msg = msg_message("summonundead_effect_1", "mage region amount", mage, mage->region, undead); } message_all(b, msg); msg_release(msg); return level; }