void make_zombie(unit * u) { u_setfaction(u, get_monsters()); scale_number(u, 1); u_setrace(u, new_race[RC_ZOMBIE]); u->irace = NULL; }
void make_zombie(unit * u) { u_setfaction(u, get_monsters()); scale_number(u, 1); u->hp = unit_max_hp(u) * u->number; u_setrace(u, get_race(RC_ZOMBIE)); u->irace = NULL; }
void randomevents(void) { region *r; faction *monsters = get_monsters(); icebergs(); godcurse(); orc_growth(); demon_skillchanges(); volcano_update(); /* Monumente zerfallen, Schiffe verfaulen */ for (r = regions; r; r = r->next) { building **blist = &r->buildings; while (*blist) { building *b = *blist; if (fval(b->type, BTF_DECAY) && !building_owner(b)) { b->size -= _max(1, (b->size * 20) / 100); if (b->size == 0) { remove_building(blist, r->buildings); } } if (*blist == b) blist = &b->next; } } /* monster-einheiten desertieren */ if (monsters) { for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { if (u->faction && !is_monsters(u->faction) && (u_race(u)->flags & RCF_DESERT)) { if (fval(u, UFL_ISNEW)) continue; if (rng_int() % 100 < 5) { ADDMSG(&u->faction->msgs, msg_message("desertion", "unit region", u, r)); u_setfaction(u, monsters); } } } } } chaos_update(); #ifdef HERBS_ROT rotting_herbs(); #endif dissolve_units(); }
int remove_unit(unit ** ulist, unit * u) { int result; assert(ufindhash(u->no)); handle_event(u->attribs, "destroy", u); result = gift_items(u, GIFT_SELF | GIFT_FRIENDS | GIFT_PEASANTS); if (result != 0) { make_zombie(u); return -1; } if (u->number) set_number(u, 0); leave(u, true); u->region = NULL; uunhash(u); if (ulist) { while (*ulist != u) { ulist = &(*ulist)->next; } assert(*ulist == u); *ulist = u->next; } u->next = deleted_units; deleted_units = u; dhash(u->no, u->faction); u_setfaction(u, NULL); u->region = NULL; return 0; }
void chaos(region * r) { if (rng_int() % 100 < 8) { switch (rng_int() % 3) { case 0: /* Untote */ if (!fval(r->terrain, SEA_REGION)) { unit *u = random_unit(r); if (u && playerrace(u_race(u))) { ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u)); u_setfaction(u, get_monsters()); u_setrace(u, get_race(RC_GHOUL)); } } break; case 1: /* Drachen */ if (random_unit(r)) { int mfac = 0; unit *u; switch (rng_int() % 3) { case 0: mfac = 100; u = createunit(r, get_monsters(), rng_int() % 8 + 1, get_race(RC_FIREDRAGON)); break; case 1: mfac = 500; u = createunit(r, get_monsters(), rng_int() % 4 + 1, get_race(RC_DRAGON)); break; default: mfac = 1000; u = createunit(r, get_monsters(), rng_int() % 2 + 1, get_race(RC_WYRM)); break; } if (mfac) set_money(u, u->number * (rng_int() % mfac)); fset(u, UFL_ISNEW | UFL_MOVED); } case 2: /* Terrainveränderung */ if (!fval(r->terrain, FORBIDDEN_REGION)) { if (!fval(r->terrain, SEA_REGION)) { direction_t dir; for (dir = 0; dir != MAXDIRECTIONS; ++dir) { region *rn = rconnect(r, dir); if (rn && fval(rn->terrain, SEA_REGION)) break; } if (dir != MAXDIRECTIONS) { ship *sh = r->ships; unit **up; while (sh) { ship *nsh = sh->next; float dmg = get_param_flt(global.parameters, "rules.ship.damage.atlantis", 0.50); damage_ship(sh, dmg); if (sh->damage >= sh->size * DAMAGE_SCALE) { remove_ship(&sh->region->ships, sh); } sh = nsh; } for (up = &r->units; *up;) { unit *u = *up; if (u_race(u) != get_race(RC_SPELL) && u->ship == 0 && !canfly(u)) { ADDMSG(&u->faction->msgs, msg_message("tidalwave_kill", "region unit", r, u)); remove_unit(up, u); } if (*up == u) up = &u->next; } ADDMSG(&r->msgs, msg_message("tidalwave", "region", r)); while (r->buildings) { remove_building(&r->buildings, r->buildings); } terraform_region(r, newterrain(T_OCEAN)); } } else { direction_t dir; for (dir = 0; dir != MAXDIRECTIONS; ++dir) { region *rn = rconnect(r, dir); if (rn && fval(rn->terrain, SEA_REGION)) break; } if (dir != MAXDIRECTIONS) { terraform_region(r, chaosterrain()); } } } } } }
static void get_allies(region * r, unit * u) { unit *newunit = NULL; const char *name; const char *equip; int number; message *msg; assert(u->number); switch (rterrain(r)) { case T_PLAIN: if (!r_isforest(r)) { if (get_money(u) / u->number < 100 + rng_int() % 200) return; name = "random_plain_men"; equip = "random_plain"; number = rng_int() % 8 + 2; break; } else { if (eff_skill(u, SK_LONGBOW, r) < 3 && eff_skill(u, SK_HERBALISM, r) < 2 && eff_skill(u, SK_MAGIC, r) < 2) { return; } name = "random_forest_men"; equip = "random_forest"; number = rng_int() % 6 + 2; } break; case T_SWAMP: if (eff_skill(u, SK_MELEE, r) <= 1) { return; } name = "random_swamp_men"; equip = "random_swamp"; number = rng_int() % 6 + 2; break; case T_DESERT: if (eff_skill(u, SK_RIDING, r) <= 2) { return; } name = "random_desert_men"; equip = "random_desert"; number = rng_int() % 12 + 2; break; case T_HIGHLAND: if (eff_skill(u, SK_MELEE, r) <= 1) { return; } name = "random_highland_men"; equip = "random_highland"; number = rng_int() % 8 + 2; break; case T_MOUNTAIN: if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 2) { return; } name = "random_mountain_men"; equip = "random_mountain"; number = rng_int() % 6 + 2; break; case T_GLACIER: if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 1) { return; } name = "random_glacier_men"; equip = "random_glacier"; number = rng_int() % 4 + 2; break; default: return; } newunit = create_unit(r, u->faction, number, u->faction->race, 0, LOC(u->faction->locale, name), u); equip_unit(newunit, get_equipment(equip)); u_setfaction(newunit, u->faction); set_racename(&newunit->attribs, get_racename(u->attribs)); if (u_race(u)->flags & RCF_SHAPESHIFT) { newunit->irace = u->irace; } if (fval(u, UFL_ANON_FACTION)) fset(newunit, UFL_ANON_FACTION); fset(newunit, UFL_ISNEW); msg = msg_message("encounter_allies", "unit name", u, name); r_addmessage(r, u->faction, msg); msg_release(msg); }
void randomevents(void) { region *r; faction *monsters = get_monsters(); icebergs(); godcurse(); orc_growth(); demon_skillchanges(); /* Orkifizierte Regionen mutieren und mutieren zurück */ for (r = regions; r; r = r->next) { if (fval(r, RF_ORCIFIED)) { direction_t dir; double probability = 0.0; for (dir = 0; dir < MAXDIRECTIONS; dir++) { region *rc = rconnect(r, dir); if (rc && rpeasants(rc) > 0 && !fval(rc, RF_ORCIFIED)) probability += 0.02; } if (chance(probability)) { ADDMSG(&r->msgs, msg_message("deorcified", "region", r)); freset(r, RF_ORCIFIED); } } else { attrib *a = a_find(r->attribs, &at_orcification); if (a != NULL) { double probability = 0.0; if (rpeasants(r) <= 0) continue; probability = a->data.i / (double)rpeasants(r); if (chance(probability)) { fset(r, RF_ORCIFIED); a_remove(&r->attribs, a); ADDMSG(&r->msgs, msg_message("orcified", "region", r)); } else { a->data.i -= _max(10, a->data.i / 10); if (a->data.i <= 0) a_remove(&r->attribs, a); } } } } /* Vulkane qualmen, brechen aus ... */ for (r = regions; r; r = r->next) { if (r->terrain == newterrain(T_VOLCANO_SMOKING)) { if (a_find(r->attribs, &at_reduceproduction)) { ADDMSG(&r->msgs, msg_message("volcanostopsmoke", "region", r)); rsetterrain(r, T_VOLCANO); } else { if (rng_int() % 100 < 12) { ADDMSG(&r->msgs, msg_message("volcanostopsmoke", "region", r)); rsetterrain(r, T_VOLCANO); } else if (r->age > 20 && rng_int() % 100 < 8) { volcano_outbreak(r); } } } else if (r->terrain == newterrain(T_VOLCANO)) { if (rng_int() % 100 < 4) { ADDMSG(&r->msgs, msg_message("volcanostartsmoke", "region", r)); rsetterrain(r, T_VOLCANO_SMOKING); } } } /* Monumente zerfallen, Schiffe verfaulen */ for (r = regions; r; r = r->next) { building **blist = &r->buildings; while (*blist) { building *b = *blist; if (fval(b->type, BTF_DECAY) && !building_owner(b)) { b->size -= _max(1, (b->size * 20) / 100); if (b->size == 0) { remove_building(blist, r->buildings); } } if (*blist == b) blist = &b->next; } } /* monster-einheiten desertieren */ if (monsters) { for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { if (u->faction && !is_monsters(u->faction) && (u_race(u)->flags & RCF_DESERT)) { if (fval(u, UFL_ISNEW)) continue; if (rng_int() % 100 < 5) { ADDMSG(&u->faction->msgs, msg_message("desertion", "unit region", u, r)); u_setfaction(u, monsters); } } } } } /* Chaos */ for (r = regions; r; r = r->next) { int i; if (fval(r, RF_CHAOTIC)) { chaos(r); } i = chaoscount(r); if (i) { chaoscounts(r, -(int)(i * ((double)(rng_int() % 10)) / 100.0)); } } #ifdef HERBS_ROT rotting_herbs(); #endif dissolve_units(); }
/** creates a new unit. * * @param dname: name, set to NULL to get a default. * @param creator: unit to inherit stealth, group, building, ship, etc. from */ unit *create_unit(region * r, faction * f, int number, const struct race *urace, int id, const char *dname, unit * creator) { unit *u = (unit *)calloc(1, sizeof(unit)); assert(urace); if (f) { assert(f->alive); u_setfaction(u, f); if (f->locale) { order *deford = default_order(f->locale); if (deford) { set_order(&u->thisorder, NULL); addlist(&u->orders, deford); } } } u_seteffstealth(u, -1); u_setrace(u, urace); u->irace = NULL; set_number(u, number); /* die nummer der neuen einheit muss vor name_unit generiert werden, * da der default name immer noch 'Nummer u->no' ist */ createunitid(u, id); /* zuerst in die Region setzen, da zb Drachennamen den Regionsnamen * enthalten */ if (r) move_unit(u, r, NULL); /* u->race muss bereits gesetzt sein, wird für default-hp gebraucht */ /* u->region auch */ u->hp = unit_max_hp(u) * number; if (!dname) { name_unit(u); } else { u->name = _strdup(dname); } if (creator) { attrib *a; /* erbt Kampfstatus */ setstatus(u, creator->status); /* erbt Gebäude/Schiff */ if (creator->region == r) { if (creator->building) { u_set_building(u, creator->building); } if (creator->ship && fval(u_race(u), RCF_CANSAIL)) { u_set_ship(u, creator->ship); } } /* Tarnlimit wird vererbt */ if (fval(creator, UFL_STEALTH)) { attrib *a = a_find(creator->attribs, &at_stealth); if (a) { int stealth = a->data.i; a = a_add(&u->attribs, a_new(&at_stealth)); a->data.i = stealth; } } /* Temps von parteigetarnten Einheiten sind wieder parteigetarnt */ if (fval(creator, UFL_ANON_FACTION)) { fset(u, UFL_ANON_FACTION); } /* Daemonentarnung */ set_racename(&u->attribs, get_racename(creator->attribs)); if (fval(u_race(u), RCF_SHAPESHIFT) && fval(u_race(creator), RCF_SHAPESHIFT)) { u->irace = creator->irace; } /* Gruppen */ if (creator->faction == f && fval(creator, UFL_GROUP)) { a = a_find(creator->attribs, &at_group); if (a) { group *g = (group *) a->data.v; set_group(u, g); } } a = a_find(creator->attribs, &at_otherfaction); if (a) { a_add(&u->attribs, make_otherfaction(get_otherfaction(a))); } a = a_add(&u->attribs, a_new(&at_creator)); a->data.v = creator; } return u; }