static void test_items(CuTest * tc) { const char * data = "{\"items\": { " "\"axe\" : { \"weight\" : 2}," "\"horse\" : { \"flags\" : [ \"animal\", \"big\" ], \"capacity\" : 20 }" "}}"; cJSON *json = cJSON_Parse(data); const item_type * itype; test_cleanup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, it_find("axe")); CuAssertPtrEquals(tc, 0, rt_find("axe")); CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_HORSE)); json_config(json); itype = it_find("axe"); CuAssertPtrNotNull(tc, itype); CuAssertIntEquals(tc, 2, itype->weight); CuAssertIntEquals(tc, 0, itype->flags); itype = it_find("horse"); CuAssertPtrNotNull(tc, itype); CuAssertIntEquals(tc, 20, itype->capacity); CuAssertIntEquals(tc, ITF_ANIMAL|ITF_BIG, itype->flags); CuAssertPtrNotNull(tc, rt_find("axe")); CuAssertPtrNotNull(tc, (void *)get_resourcetype(R_HORSE)); }
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount) { if (ptype == oldpotiontype[P_LIFE]) { int holz = 0; static int tree_type = -1; static int tree_count = -1; if (tree_type < 0) { tree_type = get_param_int(global.parameters, "rules.magic.wol_type", 1); tree_count = get_param_int(global.parameters, "rules.magic.wol_effect", 10); } /* mallorn is required to make mallorn forests, wood for regular ones */ if (fval(r, RF_MALLORN)) { holz = use_pooled(u, rt_find("mallorn"), GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount); } else { holz = use_pooled(u, rt_find("log"), GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount); } if (r->land == 0) holz = 0; if (holz < tree_count * amount) { int x = holz / tree_count; if (holz % tree_count) ++x; if (x < amount) amount = x; } rsettrees(r, tree_type, rtrees(r, tree_type) + holz); ADDMSG(&u->faction->msgs, msg_message("growtree_effect", "mage amount", u, holz)); } else if (ptype == oldpotiontype[P_HEILWASSER]) { u->hp = _min(unit_max_hp(u) * u->number, u->hp + 400 * amount); } else if (ptype == oldpotiontype[P_PEOPLE]) { attrib *a = (attrib *) a_find(r->attribs, &at_peasantluck); if (!a) a = a_add(&r->attribs, a_new(&at_peasantluck)); a->data.i += amount; } else if (ptype == oldpotiontype[P_HORSE]) { attrib *a = (attrib *) a_find(r->attribs, &at_horseluck); if (!a) a = a_add(&r->attribs, a_new(&at_horseluck)); a->data.i += amount; } else if (ptype == oldpotiontype[P_WAHRHEIT]) { fset(u, UFL_DISBELIEVES); amount = 1; } else if (ptype == oldpotiontype[P_MACHT]) { /* Verfünffacht die HP von max. 10 Personen in der Einheit */ u->hp += _min(u->number, 10 * amount) * unit_max_hp(u) * 4; } else { change_effect(u, ptype, 10 * amount); } return amount; }
void test_resource_type(CuTest * tc) { struct item_type *itype; test_cleanup(); CuAssertPtrEquals(tc, 0, rt_find("herpderp")); test_create_itemtype("herpderp"); test_create_itemtype("herpes"); itype = test_create_itemtype("herp"); CuAssertPtrEquals(tc, itype->rtype, rt_find("herp")); }
static int tolua_region_set_resource(lua_State * L) { region *r = (region *)tolua_tousertype(L, 1, 0); const char *type = tolua_tostring(L, 2, 0); int result, value = (int)tolua_tonumber(L, 3, 0); critbit_tree * cb = special_resources(); void * match; if (cb_find_prefix(cb, type, strlen(type) + 1, &match, 1, 0)) { cb_get_kv(match, &result, sizeof(result)); switch (result) { case 0: case 1: case 2: rsettrees(r, result, value); break; case 3: deathcounts(r, value - deathcount(r)); break; case 4: add_chaoscount(r, value - get_chaoscount(r)); break; } } else { const resource_type *rtype = rt_find(type); if (rtype != NULL) { region_setresource(r, rtype, value); } } return 0; }
void test_change_resource(CuTest * tc) { struct unit * u; struct faction * f; struct region * r; const char * names[] = { "money", "aura", "permaura", "horse", "hp", 0 }; int i; test_cleanup(); test_create_world(); skill_enabled[SK_MAGIC] = 1; r = findregion(0, 0); f = test_create_faction(0); u = test_create_unit(f, r); CuAssertPtrNotNull(tc, u); set_level(u, SK_MAGIC, 5); create_mage(u, M_DRAIG); for (i=0;names[i];++i) { const struct resource_type *rtype = rt_find(names[i]); int have = get_resource(u, rtype); CuAssertIntEquals(tc, have+1, change_resource(u, rtype, 1)); CuAssertIntEquals(tc, have+1, get_resource(u, rtype)); } }
static spell * test_magic_create_spell(void) { spell *sp; sp = create_spell("testspell", 0); sp->components = (spell_component *) calloc(4, sizeof(spell_component)); sp->components[0].amount = 1; sp->components[0].type = rt_find("money"); sp->components[0].cost = SPC_FIX; sp->components[1].amount = 1; sp->components[1].type = rt_find("aura"); sp->components[1].cost = SPC_LEVEL; sp->components[2].amount = 1; sp->components[2].type = rt_find("horse"); sp->components[2].cost = SPC_LINEAR; return sp; }
static void equip_newunits(const struct equipment *eq, struct unit *u) { struct region *r = u->region; const struct resource_type *rtype; switch (old_race(u_race(u))) { case RC_ELF: rtype = rt_find("fairyboot"); set_show_item(u->faction, rtype->itype); break; case RC_GOBLIN: rtype = rt_find("roi"); set_show_item(u->faction, rtype->itype); set_number(u, 10); break; case RC_HUMAN: if (u->building == NULL) { const building_type *btype = bt_find("castle"); if (btype != NULL) { building *b = new_building(btype, r, u->faction->locale); b->size = 10; u_set_building(u, b); building_set_owner(u); } } break; case RC_CAT: rtype = rt_find("roi"); set_show_item(u->faction, rtype->itype); break; case RC_AQUARIAN: { ship *sh = new_ship(st_find("boat"), r, u->faction->locale); sh->size = sh->type->construction->maxsize; u_set_ship(u, sh); } break; case RC_CENTAUR: rsethorses(r, 250 + rng_int() % 51 + rng_int() % 51); break; default: break; } }
void test_pay_spell(CuTest * tc) { spell *sp; unit * u; faction * f; region * r; int level; test_cleanup(); test_create_world(); r = findregion(0, 0); f = test_create_faction(0); u = test_create_unit(f, r); CuAssertPtrNotNull(tc, u); sp = test_magic_create_spell(); CuAssertPtrNotNull(tc, sp); set_level(u, SK_MAGIC, 5); unit_add_spell(u, 0, sp, 1); change_resource(u, rt_find("money"), 1); change_resource(u, rt_find("aura"), 3); change_resource(u, rt_find("horse"), 3); level = eff_spelllevel(u, sp, 3, 1); CuAssertIntEquals(tc, 3, level); pay_spell(u, sp, level, 1); CuAssertIntEquals(tc, 0, get_resource(u, rt_find("money"))); CuAssertIntEquals(tc, 0, get_resource(u, rt_find("aura"))); CuAssertIntEquals(tc, 0, get_resource(u, rt_find("horse"))); }
int seed_adamantium(region * r, int base) { const resource_type *rtype = rt_find("adamantium"); rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { if (rm->type->rtype == rtype) break; } if (!rm) { add_resource(r, 1, base, 150, rtype); } return 0; }
static int tolua_region_get_resourcelevel(lua_State * L) { region *r = (region *)tolua_tousertype(L, 1, 0); const char *type = tolua_tostring(L, 2, 0); const resource_type *rtype = rt_find(type); if (rtype != NULL) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { if (rm->type->rtype == rtype) { lua_pushinteger(L, rm->level); return 1; } } } return 0; }
int tolua_faction_add_item(lua_State * L) { faction *self = (faction *)tolua_tousertype(L, 1, 0); const char *iname = tolua_tostring(L, 2, 0); int number = (int)tolua_tonumber(L, 3, 0); int result = -1; if (iname != NULL) { const resource_type *rtype = rt_find(iname); if (rtype && rtype->itype) { item *i = i_change(&self->items, rtype->itype, number); result = i ? i->number : 0; } /* if (itype!=NULL) */ } lua_pushnumber(L, result); return 1; }
static int a_readeffect(attrib * a, void *owner, struct storage *store) { int power; const resource_type *rtype; effect_data *edata = (effect_data *) a->data.v; char zText[32]; READ_TOK(store, zText, sizeof(zText)); rtype = rt_find(zText); READ_INT(store, &power); if (rtype == NULL || rtype->ptype == NULL || power <= 0) { return AT_READ_FAIL; } edata->type = rtype->ptype; edata->value = power; return AT_READ_OK; }
static int tolua_region_get_resource(lua_State * L) { region *r; const char *type; const resource_type *rtype; int result = 0; void * match; critbit_tree * cb = special_resources(); r = (region *)tolua_tousertype(L, 1, 0); LUA_ASSERT(r != NULL, "invalid parameter"); type = tolua_tostring(L, 2, 0); LUA_ASSERT(type != NULL, "invalid parameter"); if (cb_find_prefix(cb, type, strlen(type) + 1, &match, 1, 0)) { cb_get_kv(match, &result, sizeof(result)); switch (result) { case 0: case 1: case 2: result = rtrees(r, result); break; case 3: result = deathcount(r); break; case 4: result = get_chaoscount(r); break; } } else { rtype = rt_find(type); if (rtype) { result = region_getresource(r, rtype); } else { result = -1; } } lua_pushinteger(L, result); return 1; }
int rt_probe(device_t parent, cfdata_t cf, void *aux) { struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; u_int r; int iosize = 1, iobase; if (ISA_DIRECT_CONFIG(ia)) return 0; if (ia->ia_nio < 1) return (0); iobase = ia->ia_io[0].ir_addr; if (!RT_BASE_VALID(iobase)) { printf("rt: configured iobase 0x%x invalid\n", iobase); return 0; } if (bus_space_map(iot, iobase, iosize, 0, &ioh)) return 0; r = rt_find(iot, ioh); bus_space_unmap(iot, ioh, iosize); if (r != 0) { ia->ia_nio = 1; ia->ia_io[0].ir_size = iosize; ia->ia_niomem = 0; ia->ia_nirq = 0; ia->ia_ndrq = 0; return (1); } return (0); }
static void test_core_resources(CuTest *tc) { resource_type * rtype; test_cleanup(); init_resources(); CuAssertPtrNotNull(tc, rtype = rt_find("money")); CuAssertPtrNotNull(tc, rtype->itype); CuAssertPtrNotNull(tc, rtype->uchange); CuAssertPtrNotNull(tc, rtype->itype->give); CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("person")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("permaura")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("hp")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("aura")); CuAssertPtrEquals(tc, 0, rtype->itype); test_cleanup(); }
static void test_recreate_world(CuTest * tc) { test_cleanup(); CuAssertPtrEquals(tc, 0, get_locale("de")); CuAssertPtrEquals(tc, 0, (void *)rt_find("horse")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA)); CuAssertPtrNotNull(tc, (void *)rt_find("money")); test_create_world(); CuAssertPtrEquals(tc, default_locale, get_locale("de")); CuAssertPtrNotNull(tc, default_locale); CuAssertPtrNotNull(tc, findregion(0, 0)); CuAssertPtrNotNull(tc, (void *)rt_find("horse")); CuAssertPtrNotNull(tc, get_resourcetype(R_HORSE)); CuAssertPtrNotNull(tc, (void *)rt_find("money")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_SILVER)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_PEASANT)); CuAssertPtrNotNull(tc, get_resourcetype(R_UNIT)); test_cleanup(); CuAssertPtrEquals(tc, 0, get_locale("de")); CuAssertPtrEquals(tc, 0, (void*)rt_find("horse")); CuAssertPtrEquals(tc, 0, (void*)get_resourcetype(R_HORSE)); CuAssertPtrNotNull(tc, (void *)rt_find("money")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_SILVER)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_PEASANT)); CuAssertPtrNotNull(tc, get_resourcetype(R_UNIT)); CuAssertPtrEquals(tc, 0, findregion(0, 0)); }
void get_food(region * r) { plane *pl = rplane(r); unit *u; int peasantfood = rpeasants(r) * 10; static int food_rules = -1; static int gamecookie = -1; if (food_rules < 0 || gamecookie != global.cookie) { gamecookie = global.cookie; food_rules = get_param_int(global.parameters, "rules.economy.food", 0); } if (food_rules & FOOD_IS_FREE) { return; } /* 1. Versorgung von eigenen Einheiten. Das vorhandene Silber * wird zunächst so auf die Einheiten aufgeteilt, dass idealerweise * jede Einheit genug Silber für ihren Unterhalt hat. */ for (u = r->units; u; u = u->next) { int need = lifestyle(u); /* Erstmal zurücksetzen */ freset(u, UFL_HUNGER); if (u->ship && (u->ship->flags & SF_FISHING)) { unit *v; int c = 2; for (v = u; c > 0 && v; v = v->next) { if (v->ship == u->ship) { int get = 0; if (v->number <= c) { get = lifestyle(v); } else { get = lifestyle(v) * c / v->number; } if (get) { change_money(v, get); } } c -= v->number; } u->ship->flags -= SF_FISHING; } if (food_rules & FOOD_FROM_PEASANTS) { struct faction *owner = region_get_owner(r); /* if the region is owned, and the owner is nice, then we'll get * food from the peasants - should not be used with WORK */ if (owner != NULL && (get_alliance(owner, u->faction) & HELP_MONEY)) { int rm = rmoney(r); int use = _min(rm, need); rsetmoney(r, rm - use); need -= use; } } need -= get_money(u); if (need > 0) { unit *v; for (v = r->units; need && v; v = v->next) { if (v->faction == u->faction && help_money(v)) { int give = get_money(v) - lifestyle(v); give = _min(need, give); if (give > 0) { change_money(v, -give); change_money(u, give); need -= give; } } } } } /* 2. Versorgung durch Fremde. Das Silber alliierter Einheiten wird * entsprechend verteilt. */ for (u = r->units; u; u = u->next) { int need = lifestyle(u); faction *f = u->faction; need -= _max(0, get_money(u)); if (need > 0) { unit *v; if (food_rules & FOOD_FROM_OWNER) { /* the owner of the region is the first faction to help out when you're hungry */ faction *owner = region_get_owner(r); if (owner && owner != u->faction) { for (v = r->units; v; v = v->next) { if (v->faction == owner && alliedunit(v, f, HELP_MONEY) && help_money(v)) { help_feed(v, u, &need); break; } } } } for (v = r->units; need && v; v = v->next) { if (v->faction != f && alliedunit(v, f, HELP_MONEY) && help_money(v)) { help_feed(v, u, &need); } } /* Die Einheit hat nicht genug Geld zusammengekratzt und * nimmt Schaden: */ if (need > 0) { int lspp = lifestyle(u) / u->number; if (lspp > 0) { int number = (need + lspp - 1) / lspp; if (hunger(number, u)) fset(u, UFL_HUNGER); } } } } /* 3. bestimmen, wie viele Bauern gefressen werden. * bei fehlenden Bauern den Dämon hungern lassen */ for (u = r->units; u; u = u->next) { if (u_race(u) == get_race(RC_DAEMON)) { int hungry = u->number; /* use peasantblood before eating the peasants themselves */ const struct potion_type *pt_blood = 0; const resource_type *rt_blood = rt_find("peasantblood"); if (rt_blood) { pt_blood = rt_blood->ptype; } if (pt_blood) { /* always start with the unit itself, then the first known unit that may have some blood */ unit *donor = u; while (donor != NULL && hungry > 0) { int blut = get_effect(donor, pt_blood); blut = _min(blut, hungry); if (blut) { change_effect(donor, pt_blood, -blut); hungry -= blut; } if (donor == u) donor = r->units; while (donor != NULL) { if (u_race(donor) == get_race(RC_DAEMON) && donor != u) { if (get_effect(donor, pt_blood)) { /* if he's in our faction, drain him: */ if (donor->faction == u->faction) break; } } donor = donor->next; } } } /* remaining demons feed on peasants */ if (pl == NULL || !fval(pl, PFL_NOFEED)) { if (peasantfood >= hungry) { peasantfood -= hungry; hungry = 0; } else { hungry -= peasantfood; peasantfood = 0; } if (hungry > 0) { static int demon_hunger = -1; if (demon_hunger < 0) { demon_hunger = get_param_int(global.parameters, "hunger.demons", 0); } if (demon_hunger == 0) { /* demons who don't feed are hungry */ if (hunger(hungry, u)) fset(u, UFL_HUNGER); } else { /* no damage, but set the hungry-flag */ fset(u, UFL_HUNGER); } } } } } rsetpeasants(r, peasantfood / 10); /* 3. Von den überlebenden das Geld abziehen: */ for (u = r->units; u; u = u->next) { int need = _min(get_money(u), lifestyle(u)); change_money(u, -need); } }
/* ARGSUSED */ void rde_dispatch_parent(int fd, short event, void *bula) { struct imsg imsg; struct rt_node *rt; struct kroute kr; struct imsgev *iev = bula; struct imsgbuf *ibuf = &iev->ibuf; ssize_t n; int shut = 0; if (event & EV_READ) { if ((n = imsg_read(ibuf)) == -1) fatal("imsg_read error"); if (n == 0) /* connection closed */ shut = 1; } if (event & EV_WRITE) { if (msgbuf_write(&ibuf->w) == -1 && errno != EAGAIN) fatal("msgbuf_write"); } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal("rde_dispatch_parent: imsg_read error"); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_NETWORK_ADD: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(kr)) { log_warnx("rde_dispatch: wrong imsg len"); break; } memcpy(&kr, imsg.data, sizeof(kr)); rt = rt_new_kr(&kr); rt_insert(rt); break; case IMSG_NETWORK_DEL: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(kr)) { log_warnx("rde_dispatch: wrong imsg len"); break; } memcpy(&kr, imsg.data, sizeof(kr)); if ((rt = rt_find(kr.prefix.s_addr, kr.netmask.s_addr)) != NULL) rt_remove(rt); break; default: log_debug("rde_dispatch_parent: unexpected imsg %d", imsg.hdr.type); break; } imsg_free(&imsg); } if (!shut) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); } }
static void test_resources(CuTest *tc) { resource_type *rtype; test_cleanup(); CuAssertPtrNotNull(tc, rt_find("hp")); CuAssertPtrEquals(tc, rt_find("hp"), (void *)get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, rt_find("peasant")); CuAssertPtrEquals(tc, rt_find("peasant"), (void *)get_resourcetype(R_PEASANT)); CuAssertPtrNotNull(tc, rt_find("aura")); CuAssertPtrEquals(tc, rt_find("aura"), (void *)get_resourcetype(R_AURA)); CuAssertPtrNotNull(tc, rt_find("permaura")); CuAssertPtrEquals(tc, rt_find("permaura"), (void *)get_resourcetype(R_PERMAURA)); CuAssertPtrNotNull(tc, rt_find("unit")); CuAssertPtrEquals(tc, rt_find("unit"), (void *)get_resourcetype(R_UNIT)); CuAssertPtrEquals(tc, 0, rt_find("stone")); rtype = rt_get_or_create("stone"); CuAssertPtrEquals(tc, (void *)rtype, (void *)rt_find("stone")); CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE)); test_cleanup(); CuAssertPtrEquals(tc, 0, rt_find("stone")); rtype = rt_get_or_create("stone"); CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE)); }
int rde_check_route(struct rip_route *e) { struct timeval tv, now; struct rt_node *rn; struct iface *iface; u_int8_t metric; if ((e->nexthop.s_addr & htonl(IN_CLASSA_NET)) == htonl(INADDR_LOOPBACK & IN_CLASSA_NET) || e->nexthop.s_addr == INADDR_ANY) return (-1); if ((iface = if_find_index(e->ifindex)) == NULL) return (-1); metric = MIN(INFINITY, e->metric + iface->cost); if ((rn = rt_find(e->address.s_addr, e->mask.s_addr)) == NULL) { if (metric >= INFINITY) return (0); rn = rt_new_rr(e, metric); rt_insert(rn); rde_send_change_kroute(rn); route_start_timeout(rn); triggered_update(rn); } else { /* * XXX don't we have to track all incoming routes? * what happens if the kernel route is removed later. */ if (rn->flags & F_KERNEL) return (0); if (metric < rn->metric) { rn->metric = metric; rn->nexthop.s_addr = e->nexthop.s_addr; rn->ifindex = e->ifindex; rde_send_change_kroute(rn); triggered_update(rn); } else if (e->nexthop.s_addr == rn->nexthop.s_addr && metric > rn->metric) { rn->metric = metric; rde_send_change_kroute(rn); triggered_update(rn); if (rn->metric == INFINITY) route_start_garbage(rn); } else if (e->nexthop.s_addr != rn->nexthop.s_addr && metric == rn->metric) { /* If the new metric is the same as the old one, * examine the timeout for the existing route. If it * is at least halfway to the expiration point, switch * to the new route. */ timerclear(&tv); gettimeofday(&now, NULL); evtimer_pending(&rn->timeout_timer, &tv); if (tv.tv_sec - now.tv_sec < ROUTE_TIMEOUT / 2) { rn->nexthop.s_addr = e->nexthop.s_addr; rn->ifindex = e->ifindex; rde_send_change_kroute(rn); } } if (e->nexthop.s_addr == rn->nexthop.s_addr && rn->metric < INFINITY) route_reset_timers(rn); } return (0); }