diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index b98a6c850..41d21057f 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -484,11 +484,7 @@ recruit(unit * u, struct order * ord, request ** recruitorders) } if (!(rc->ec_flags & ECF_REC_HORSES) && fval(r, RF_ORCIFIED)) { -#if RACE_ADJUSTMENTS if (rc != new_race[RC_URUK]) -#else - if (rc != new_race[RC_ORC]) -#endif { cmistake(u, ord, 238, MSG_EVENT); return; @@ -1164,6 +1160,20 @@ typedef struct allocation_list { static allocation_list * allocations; +static boolean +can_guard(const unit * guard, const unit * u) +{ + if (fval(guard, UFL_ISNEW)) return false; + if (guard->number<=0 || !cansee(guard->faction, guard->region, u, 0)) return false; + if (besieged(guard) || !armedmen(guard)) return false; + + return !alliedunit(guard, u->faction, HELP_GUARD); +} + +enum { + AFL_DONE = 1<<0, + AFL_LOWSKILL = 1<<1 +}; static void allocate_resource(unit * u, const resource_type * rtype, int want) @@ -1174,22 +1184,25 @@ allocate_resource(unit * u, const resource_type * rtype, int want) int dm = 0; allocation_list * alist; allocation * al; - unit *u2; - int amount, skill; + attrib * a = a_find(rtype->attribs, &at_resourcelimit); + resource_limit * rdata = (resource_limit*)a->data.v; + int amount, skill; /* momentan kann man keine ressourcen abbauen, wenn man daf�r * Materialverbrauch hat: */ assert(itype!=NULL && (itype->construction==NULL || itype->construction->materials==NULL)); + assert(rdata!=NULL); - if (itype == olditemtype[I_WOOD] && fval(r, RF_MALLORN)) { - cmistake(u, u->thisorder, 92, MSG_PRODUCE); - return; - } - if (itype == olditemtype[I_MALLORN] && !fval(r, RF_MALLORN)) { - cmistake(u, u->thisorder, 91, MSG_PRODUCE); - return; - } - if (itype == olditemtype[I_LAEN]) { + if (rdata->limit!=NULL) { + int avail = rdata->limit(r, rtype); + if (avail<=0) { + cmistake(u, u->thisorder, 121, MSG_PRODUCE); + return; + } + + } + + if (itype == olditemtype[I_LAEN]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; if (btype != bt_find("mine")) { @@ -1202,21 +1215,15 @@ allocate_resource(unit * u, const resource_type * rtype, int want) cmistake(u, u->thisorder, 60, MSG_PRODUCE); return; } - /* Elfen k�nnen Holzf�llen durch Bewachen verhindern, wenn sie - die Holzf�ller sehen. */ - if (itype == olditemtype[I_WOOD] || itype == olditemtype[I_MALLORN]) { + + if (rdata->guard!=0) { + unit * u2; for (u2 = r->units; u2; u2 = u2->next) { - if (getguard(u2) & GUARD_TREES - && u2->number - && cansee(u2->faction,r,u,0) - && !besieged(u2) - && !alliedunit(u2, u->faction, HELP_GUARD) - && armedmen(u2) - ) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "region_guarded", "guard", u2)); - return; - } + if ((getguard(u2) & rdata->guard) && can_guard(u2, u)) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "region_guarded", "guard", u2)); + return; + } } } @@ -1224,8 +1231,8 @@ allocate_resource(unit * u, const resource_type * rtype, int want) * Als magische Wesen 'sehen' Bergw�chter alles und werden durch * Belagerung nicht aufgehalten. (Ansonsten wie oben bei Elfen anpassen). */ - if (itype == olditemtype[I_IRON] || itype == olditemtype[I_LAEN]) - { + if (itype == olditemtype[I_IRON] || itype == olditemtype[I_LAEN]) { + unit * u2; for (u2 = r->units; u2; u2 = u2->next ) { if (getguard(u) & GUARD_MINING && !fval(u2, UFL_ISNEW) @@ -1256,18 +1263,24 @@ allocate_resource(unit * u, const resource_type * rtype, int want) } else { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (itype == olditemtype[I_IRON] && btype == bt_find("mine")) { + + if (rdata->modifiers) { + resource_mod * mod = rdata->modifiers; + for (;mod->flags!=0;++mod) { + if (mod->flags & RMF_SKILL) { + if (mod->btype==NULL || mod->btype==btype) { + if (mod->race==NULL || mod->race==u->race) { + skill += mod->value.i; + } + } + } + } + } else if (itype == olditemtype[I_IRON] && btype == bt_find("mine")) { ++skill; } else if (itype == olditemtype[I_STONE] && btype == bt_find("quarry")) { ++skill; } - else if (itype == olditemtype[I_WOOD] && btype == bt_find("sawmill")) { - ++skill; - } - else if (itype == olditemtype[I_MALLORN] && btype == bt_find("sawmill")) { - ++skill; - } } amount = skill * u->number; /* nun ist amount die Gesamtproduktion der Einheit (in punkten) */ @@ -1303,193 +1316,168 @@ allocate_resource(unit * u, const resource_type * rtype, int want) al->next = alist->data; al->unit = u; alist->data = al; - if (itype==olditemtype[I_IRON]) { + + if (rdata->modifiers) { + struct building * b = inside_building(u); + const struct building_type * btype = b?b->type:NULL; + + resource_mod * mod = rdata->modifiers; + for (;mod->flags!=0;++mod) { + if (mod->flags & RMF_SKILL) { + if (mod->btype==NULL || mod->btype==btype) { + if (mod->race==NULL || mod->race==u->race) { + al->save *= mod->value.f; + } + } + } + } + } else if (itype==olditemtype[I_IRON]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; if (btype==bt_find("mine")) al->save *= 0.5; if (u->race == new_race[RC_DWARF]) { -#if RACE_ADJUSTMENTS al->save *= 0.75; -#else - al->save *= 0.5; -#endif } } else if (itype==olditemtype[I_STONE]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; if (btype==bt_find("quarry")) al->save = al->save*0.5; -#if RACE_ADJUSTMENTS if (u->race == new_race[RC_TROLL]) al->save = al->save*0.75; -#endif - } else if (itype==olditemtype[I_MALLORN]) { - struct building * b = inside_building(u); - const struct building_type * btype = b?b->type:NULL; - if (btype==bt_find("sawmill")) - al->save *= 0.5; - } else if (itype==olditemtype[I_WOOD]) { - struct building * b = inside_building(u); - const struct building_type * btype = b?b->type:NULL; - if (btype==bt_find("sawmill")) - al->save *= 0.5; } } -typedef struct allocator { - const struct resource_type * type; - void (*allocate)(const struct allocator *, region *, allocation *); - - struct allocator * next; -} allocator; - -static struct allocator * allocators; - -static const allocator * -get_allocator(const struct resource_type * type) -{ - const struct allocator * alloc = allocators; - while (alloc && alloc->type!=type) alloc = alloc->next; - return alloc; -} - -static allocator * -make_allocator(const struct resource_type * type, void (*allocate)(const struct allocator *, region *, allocation *)) -{ - allocator * alloc = (allocator *)malloc(sizeof(allocator)); - alloc->type = type; - alloc->allocate = allocate; - return alloc; -} - -static void -add_allocator(allocator * alloc) -{ - alloc->next = allocators; - allocators = alloc; -} - -enum { - AFL_DONE = 1<<0, - AFL_LOWSKILL = 1<<1 -}; - static int required(int want, double save) { - int norders = (int)(want * save); - if (norders < want*save) ++norders; - return norders; + int norders = (int)(want * save); + if (norders < want*save) ++norders; + return norders; } static void -leveled_allocation(const allocator * self, region * r, allocation * alist) +leveled_allocation(const resource_type * rtype, region * r, allocation * alist) { - const resource_type * rtype = self->type; - const item_type * itype = resource2item(rtype); - rawmaterial * rm = rm_get(r, rtype); - int need; - boolean first = true; + const item_type * itype = resource2item(rtype); + rawmaterial * rm = rm_get(r, rtype); + int need; + boolean first = true; - if (rm!=NULL) { - do { - int avail = rm->amount; - int norders = 0; - allocation * al; + if (rm!=NULL) { + do { + int avail = rm->amount; + int norders = 0; + allocation * al; - if(avail <= 0) { - for (al=alist;al;al=al->next) { - al->get = 0; - } - break; - } + if(avail <= 0) { + for (al=alist;al;al=al->next) { + al->get = 0; + } + break; + } - assert(avail>0); + assert(avail>0); - for (al=alist;al;al=al->next) if (!fval(al, AFL_DONE)) { - int req = required(al->want-al->get, al->save); - assert(al->get<=al->want && al->get >= 0); - if (eff_skill(al->unit, itype->construction->skill, r) - >= rm->level+itype->construction->minskill-1) { - if (req) { - norders += req; - } else { - fset(al, AFL_DONE); - } - } else { - fset(al, AFL_DONE); - if (first) fset(al, AFL_LOWSKILL); - } - } - need = norders; + for (al=alist;al;al=al->next) if (!fval(al, AFL_DONE)) { + int req = required(al->want-al->get, al->save); + assert(al->get<=al->want && al->get >= 0); + if (eff_skill(al->unit, itype->construction->skill, r) + >= rm->level+itype->construction->minskill-1) { + if (req) { + norders += req; + } else { + fset(al, AFL_DONE); + } + } else { + fset(al, AFL_DONE); + if (first) fset(al, AFL_LOWSKILL); + } + } + need = norders; - avail = min(avail, norders); - if (need>0) { - int use = 0; - for (al=alist;al;al=al->next) if (!fval(al, AFL_DONE)) { - if (avail > 0) { - int want = required(al->want-al->get, al->save); - int x = avail*want/norders; - /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ - if (rand() % norders < (avail*want) % norders) - ++x; - avail -= x; - use += x; - norders -= want; - need -= x; - al->get = min(al->want, al->get+(int)(x/al->save)); - } - } - if (use) { - assert(use<=rm->amount); - rm->type->use(rm, r, use); - } - assert(avail==0 || norders==0); - } - first = false; - } while (need>0); - } + avail = min(avail, norders); + if (need>0) { + int use = 0; + for (al=alist;al;al=al->next) if (!fval(al, AFL_DONE)) { + if (avail > 0) { + int want = required(al->want-al->get, al->save); + int x = avail*want/norders; + /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ + if (rand() % norders < (avail*want) % norders) + ++x; + avail -= x; + use += x; + norders -= want; + need -= x; + al->get = min(al->want, al->get+(int)(x/al->save)); + } + } + if (use) { + assert(use<=rm->amount); + rm->type->use(rm, r, use); + } + assert(avail==0 || norders==0); + } + first = false; + } while (need>0); + } } static void -attrib_allocation(const allocator * self, region * r, allocation * alist) +attrib_allocation(const resource_type * rtype, region * r, allocation * alist) { - allocation * al; - const resource_type * rtype = self->type; - int avail = 0; - int norders = 0; - attrib * a = a_find(rtype->attribs, &at_resourcelimit); - resource_limit * rdata = (resource_limit*)a->data.v; + allocation * al; + int norders = 0; + attrib * a = a_find(rtype->attribs, &at_resourcelimit); + resource_limit * rdata = (resource_limit*)a->data.v; + int avail = rdata->value; - for (al=alist;al;al=al->next) { - norders += required(al->want, al->save); - } + for (al=alist;al;al=al->next) { + norders += required(al->want, al->save); + } - if (rdata->limit) { - avail = rdata->limit(r, rtype); - if (avail < 0) avail = 0; - } - else avail = rdata->value; + if (rdata->limit) { + avail = rdata->limit(r, rtype); + if (avail < 0) avail = 0; + } - avail = min(avail, norders); - for (al=alist;al;al=al->next) { - if (avail > 0) { - int want = required(al->want, al->save); - int x = avail*want/norders; - /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ - if (rand() % norders < (avail*want) % norders) - ++x; - avail -= x; - norders -= want; - al->get = min(al->want, (int)(x/al->save)); - if (rdata->use) { - int use = required(al->get, al->save); - if (use) rdata->use(r, rtype, use); - } - } - } - assert(avail==0 || norders==0); + avail = min(avail, norders); + for (al=alist;al;al=al->next) { + if (avail > 0) { + int want = required(al->want, al->save); + int x = avail*want/norders; + /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ + if (rand() % norders < (avail*want) % norders) + ++x; + avail -= x; + norders -= want; + al->get = min(al->want, (int)(x/al->save)); + if (rdata->produce) { + int use = required(al->get, al->save); + if (use) rdata->produce(r, rtype, use); + } + } + } + assert(avail==0 || norders==0); +} + +typedef void (*allocate_function)(const resource_type *, struct region *, struct allocation *); + +static allocate_function +get_allocator(const struct resource_type * rtype) +{ + attrib * a = a_find(rtype->attribs, &at_resourcelimit); + + if (a!=NULL) { + resource_limit * rdata = (resource_limit*)a->data.v; + if (rdata->value>0 || rdata->limit!=NULL) { + return attrib_allocation; + } + return leveled_allocation; + } + return NULL; } static void @@ -1500,12 +1488,12 @@ split_allocations(region * r) while (*p_alist) { allocation_list * alist = *p_alist; const resource_type * rtype = alist->type; - const allocator * alloc = get_allocator(rtype); + allocate_function alloc = get_allocator(rtype); const item_type * itype = resource2item(rtype); allocation ** p_al = &alist->data; freset(r, RF_DH); - alloc->allocate(alloc, r, alist->data); + alloc(rtype, r, alist->data); while (*p_al) { allocation * al = *p_al; @@ -3201,16 +3189,3 @@ produce(void) } } - -void -init_economy(void) -{ - add_allocator(make_allocator(item2resource(olditemtype[I_HORSE]), attrib_allocation)); - add_allocator(make_allocator(item2resource(olditemtype[I_WOOD]), attrib_allocation)); - add_allocator(make_allocator(item2resource(olditemtype[I_MALLORN]), attrib_allocation)); - add_allocator(make_allocator(item2resource(olditemtype[I_STONE]), leveled_allocation)); - add_allocator(make_allocator(item2resource(olditemtype[I_IRON]), leveled_allocation)); - add_allocator(make_allocator(item2resource(olditemtype[I_LAEN]), leveled_allocation)); - add_allocator(make_allocator(rt_seed, attrib_allocation)); - add_allocator(make_allocator(rt_mallornseed, attrib_allocation)); -} diff --git a/src/common/gamecode/economy.h b/src/common/gamecode/economy.h index c16cb0035..8570b500d 100644 --- a/src/common/gamecode/economy.h +++ b/src/common/gamecode/economy.h @@ -53,7 +53,6 @@ void produce(void); enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC }; void maintain_buildings(boolean crash); extern void add_spende(struct faction * f1, struct faction * f2, int betrag, struct region * r); -extern void init_economy(void); #ifdef __cplusplus } diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index a5e333f57..e2015cb70 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -298,24 +298,10 @@ get_unit(region * r, unit * u) newunit = createunit(r, u->faction, rand() % 20 + 3, u->faction->race); fset(newunit, UFL_ISNEW|UFL_MOVED); set_string(&newunit->name, "Dorfbewohner"); - set_money(newunit, (rand() % 26 + 10) * newunit->number); - if (fval(u, UFL_PARTEITARNUNG)) fset(newunit, UFL_PARTEITARNUNG); - switch (rand() % 4) { - case 0: - set_level(newunit, SK_MINING, 1); - break; - case 1: - set_level(newunit, SK_LUMBERJACK, 1); - break; - case 2: - set_level(newunit, SK_CARTMAKER, 1); - break; - case 3: - set_level(newunit, SK_QUARRYING, 1); - break; - } - set_item(newunit, I_WAGON, rand() % 2); - set_item(newunit, I_HORSE, min(get_item(newunit, I_WAGON) * 2, rand() % 5)); + if (fval(u, UFL_PARTEITARNUNG)) { + fset(newunit, UFL_PARTEITARNUNG); + } + equip_unit(newunit, get_equipment("random_villagers")); } static void @@ -1204,77 +1190,6 @@ randomevents(void) orc_growth(); demon_skillchanges(); -#if RACE_ADJUSTMENTS == 0 - /* Orks vermehren sich */ - - for (r = regions; r; r = r->next) { - - plane * p = rplane(r); - /* there is a flag for planes without orc growth: */ - if (p && (p->flags & PFL_NOORCGROWTH)) continue; - for (u = r->units; u; u = u->next) { - if ( (u->race == new_race[RC_ORC]) - && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) { - int n; - int increase = 0; - int num = u->number; - int prob = 5; - - for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) { - if (rand() % 100 < prob) { - ++increase; - } - } - if (increase) { - if (u->race == new_race[RC_ORC]) { - int i; - struct orcskills { - skill_t skill; - int level; - } skills [] = { - { SK_MELEE, 1 }, { SK_SPEAR, 1 }, { SK_TACTICS, 0 }, - { SK_LONGBOW, 0 }, { SK_CROSSBOW, 0 }, { SK_CATAPULT, 0 }, - { SK_AUSDAUER, 0 }, { NOSKILL, 0 } - }; - for (i=0;skills[i].skill!=NOSKILL;++i) { - int k = get_level(u, skills[i].skill); - change_skill(u, skills[i].skill, increase * max(k, s)); - } - } - - set_number(u, u->number + increase); - - u->hp += unit_max_hp(u) * increase; - ADDMSG(&u->faction->msgs, msg_message("orcgrowth", - "unit amount race", u, increase, u->race)); - } - } - } - } -#endif - - for (r = regions; r; r = r->next) { -#if !RACE_ADJUSTMENTS - /* Elfen generieren Wald */ - if (r->land && !fval(r, RF_MALLORN)) { - int trees = rtrees(r, 2); - int maxgen = (production(r) * MAXPEASANTS_PER_AREA)/8; - for (u = r->units; u && maxgen > 0; u = u->next) { - if (u->race == new_race[RC_ELF]) { - for (n = u->number; n && maxgen > 0; n--) { - if (rand() % 1000 < 15) { /* 1.5% Chance */ - trees++; - } - maxgen--; - } - } - } - rsettrees(r, 2, trees); - } /* !RACE_ADJUSTMENTS */ -#endif - - } - /* Orkifizierte Regionen mutieren und mutieren zur�ck */ for (r = regions; r; r = r->next) { @@ -1373,45 +1288,7 @@ randomevents(void) } } - /* Fr�hling, die B�ume schlagen aus. */ - - for (r = regions; r; r = r->next) { - if (fval(r, RF_CHAOTIC) ||(r->x >= -13 && r->x <= -6 && r->y >= 50 && r->y <= 57)) { - if (woodcount(r) >= 40 && rand()%100 < 33) { - int trees = rtrees(r,2); - int treemen = rand()%(max(50,trees)/3); - struct message * msg; - - treemen = max(25, treemen); - woodcounts(r, -40); - trees = max(0, trees-treemen); - rsettrees(r, 2, trees); - u = createunit(r, findfaction(MONSTER_FACTION),treemen, new_race[RC_TREEMAN]); - fset(u, UFL_ISNEW|UFL_MOVED); - - set_level(u, SK_OBSERVATION, 2); - if (u->number == 1) - set_string(&u->name, "Ein w�tender Ent"); - else - set_string(&u->name, "W�tende Ents"); - - log_printf("%d Ents in %s.\n", u->number, regionname(r, NULL)); - - msg = msg_message("entrise", "region", r); - add_message(&r->msgs, msg); - for (u=r->units;u;u=u->next) freset(u->faction, FL_DH); - for (u=r->units;u;u=u->next) { - if (fval(u->faction, FL_DH)) continue; - fset(u->faction, FL_DH); - add_message(&u->faction->msgs, msg); - } - msg_release(msg); - } - } - } - /* Chaos */ - for (r = regions; r; r = r->next) { int i; if (fval(r, RF_CHAOTIC)) { diff --git a/src/common/items/seed.c b/src/common/items/seed.c index 2e7c38f71..995cdc71e 100644 --- a/src/common/items/seed.c +++ b/src/common/items/seed.c @@ -56,7 +56,7 @@ init_seed(void) a = a_add(&rt_seed->attribs, a_new(&at_resourcelimit)); rdata = (resource_limit*)a->data.v; rdata->limit = limit_seeds; - rdata->use = produce_seeds; + rdata->produce = produce_seeds; } } @@ -94,6 +94,6 @@ init_mallornseed(void) a = a_add(&rt_mallornseed->attribs, a_new(&at_resourcelimit)); rdata = (resource_limit*)a->data.v; rdata->limit = limit_mallornseeds; - rdata->use = produce_mallornseeds; + rdata->produce = produce_mallornseeds; } } diff --git a/src/common/items/weapons.c b/src/common/items/weapons.c index 7b9292bed..7cf6f2251 100644 --- a/src/common/items/weapons.c +++ b/src/common/items/weapons.c @@ -42,9 +42,6 @@ static weapon_mod wm_lance[] = { }; enum { - WP_EOGSWORD, - WP_SPEAR, - WP_LANCE, WP_NONE, WP_MAX }; @@ -77,15 +74,10 @@ static weapondata weapontable[WP_MAX + 1] = /* MagRes, Schaden/Fu�, Schaden/Pferd, Item, Skill, OffMod, DefMod, * missile, is_magic */ { - {0.30, "3d6+10", "3d6+10", I_LAENSWORD, SK_MELEE, 1, 1, false, false, { 0, 0}, CUT }, - /* Speer */ - {0.00, "1d10+0", "1d12+2", I_SPEAR, SK_SPEAR, 0, 0, false, false, { 0, 0}, PIERCE }, - /* Lanze */ - {0.00, "1d5", "2d6+5", I_LANCE, SK_SPEAR, 0, -2, false, false, { 0, 0}, PIERCE }, /* Unbewaffnet */ - {0.00, "1d5+0", "1d6+0", I_WOOD, SK_MELEE, 0, 0, false, false, { 0, 0}, BASH }, + {0.00, "1d5+0", "1d6+0", MAX_ITEMS, SK_MELEE, 0, 0, false, false, { 0, 0}, BASH }, /* Dummy */ - {0.00, "0d0+0", "0d0+0", I_WOOD, SK_MELEE, 0, 0, false, false, { 0, 0}, 0 } + {0.00, "0d0+0", "0d0+0", MAX_ITEMS, SK_MELEE, 0, 0, false, false, { 0, 0}, 0 } }; weapon_type * oldweapontype[WP_MAX]; @@ -210,7 +202,7 @@ static void init_oldweapons(void) { int w; - for (w=0;w!=WP_MAX && weapontable[w].item!=I_WOOD;++w) { + for (w=0;w!=WP_MAX && weapontable[w].item!=MAX_ITEMS;++w) { const char * damage[2]; item_type * itype = olditemtype[weapontable[w].item]; int minskill = 1, wflags = WTF_NONE; @@ -218,15 +210,6 @@ init_oldweapons(void) weapon_mod * modifiers = NULL; boolean (*attack)(const troop *, const struct weapon_type *, int *, int) = NULL; - switch (w) { - case WP_LANCE: - modifiers = wm_lance; - break; - case WP_SPEAR: - modifiers = wm_spear; - break; - } - assert(itype!=NULL || !"item not initialized"); if (weapontable[w].rear) wflags |= WTF_MISSILE; diff --git a/src/common/kernel/alchemy.c b/src/common/kernel/alchemy.c index bd455c3c8..375ddc63d 100644 --- a/src/common/kernel/alchemy.c +++ b/src/common/kernel/alchemy.c @@ -106,10 +106,10 @@ use_potion(unit * u, const item_type * itype, int amount, struct order *ord) /* f�r die Aufforstung von Mallornw�ldern braucht man Mallorn */ if (fval(r, RF_MALLORN)) { - holz = use_pooled(u, oldresourcetype[R_MALLORN], + holz = use_pooled(u, rt_find("mallorn"), GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 10*amount); } else { - holz = use_pooled(u, oldresourcetype[R_WOOD], + holz = use_pooled(u, rt_find("log"), GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 10*amount); } if (r->land==0) holz=0; diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 239f226d0..c7a75d25e 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -103,9 +103,14 @@ attrib_type at_building_action = { lc_write, lc_read }; -building_typelist *buildingtypes; +typedef struct building_typelist { + struct building_typelist * next; + building_type * type; +} building_typelist; -const building_type * +static building_typelist *buildingtypes; + +building_type * bt_find(const char* name) { const struct building_typelist * btl = buildingtypes; @@ -382,20 +387,6 @@ register_buildings(void) #endif } -building_type * -bt_make(const char * name, int flags, int capacity, int maxcapacity, int maxsize) -{ - building_type * btype = calloc(sizeof(building_type), 1); - btype->_name = name; - btype->flags = flags | BTF_DYNAMIC; - btype->capacity = capacity; - btype->maxcapacity = maxcapacity; - btype->maxsize = maxsize; - - bt_register(btype); - return btype; -} - void * resolve_building(variant id) { return findbuilding(id.i); diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 321e125ba..f16853264 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -60,16 +60,10 @@ typedef struct building_type { struct attrib * attribs; } building_type; -extern const building_type * bt_find(const char* name); +extern building_type * bt_find(const char* name); extern void register_buildings(void); extern void bt_register(building_type * type); -typedef struct building_typelist { - struct building_typelist * next; - const building_type * type; -} building_typelist; - -extern struct building_typelist *buildingtypes; /* buildingt => building_type * Name => locale_string(name) * MaxGroesse => levels @@ -129,8 +123,6 @@ void destroy_building(struct building * b); const struct building_type * findbuildingtype(const char * name, const struct locale * lang); -extern struct building_type * bt_make(const char * name, int flags, int capacity, int maxcapacity, int maxsize); - #include "build.h" #define NOBUILDING NULL diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 01009ec1b..04e3b8a72 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -3107,7 +3107,6 @@ attrib_init(void) at_register(&at_moveblock); at_register(&at_deathcount); at_register(&at_chaoscount); - at_register(&at_woodcount); /* neue UNIT-Attribute */ at_register(&at_siege); diff --git a/src/common/kernel/give.c b/src/common/kernel/give.c index 78ac4cbcd..e43f86766 100644 --- a/src/common/kernel/give.c +++ b/src/common/kernel/give.c @@ -155,11 +155,9 @@ give_men(int n, unit * u, unit * u2, struct order * ord) return; } else if (u == u2) { error = 10; -#if RACE_ADJUSTMENTS } else if (!u2 && u->race == new_race[RC_SNOTLING]) { /* Snotlings k�nnen nicht an Bauern �bergeben werden. */ error = 307; -#endif #ifdef HEROES } else if (u2 && u2->number>0 && fval(u, UFL_HERO)!=fval(u2, UFL_HERO)) { error = 75; diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index d5a3ad8d9..4832fe0bd 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -641,149 +641,128 @@ use_tacticcrystal(region * r, unit * u, int amount, struct order * ord) return; } +typedef struct t_item { + const char *name[4]; + /* [0]: Einzahl f�r eigene; [1]: Mehrzahl f�r eigene; + * [2]: Einzahl f�r Fremde; [3]: Mehrzahl f�r Fremde */ + item_t typ; + skill_t skill; + int minskill; + int gewicht; + int preis; + unsigned int flags; + void (*benutze_funktion) (struct region *, struct unit *, int amount, struct order *); +} t_item; + static t_item itemdata[MAXITEMS] = { /* name[4]; typ; sk; minskill; material[6]; gewicht; preis; * benutze_funktion; */ { /* I_IRON */ {"Eisen", "Eisen", "Eisen", "Eisen"}, - IS_RESOURCE, SK_MINING, 1, {0, 0, 0, 0, 0, 0}, 500, 0, FL_ITEM_NOTLOST, NULL - }, - { /* I_WOOD */ - {"Holz", "Holz", "Holz", "Holz"}, - IS_RESOURCE, SK_LUMBERJACK, 1, {0, 0, 0, 0, 0, 0}, 500, 0, FL_ITEM_NOTLOST, NULL + IS_RESOURCE, SK_MINING, 1, 500, 0, FL_ITEM_NOTLOST, NULL }, { /* I_STONE */ {"Stein", "Steine", "Stein", "Steine"}, - IS_RESOURCE, SK_QUARRYING, 1, {0, 0, 0, 0, 0, 0}, 6000, 0, FL_ITEM_NOTLOST, NULL + IS_RESOURCE, SK_QUARRYING, 1, 6000, 0, FL_ITEM_NOTLOST, NULL }, { /* I_HORSE */ {"Pferd", "Pferde", "Pferd", "Pferde"}, - IS_RESOURCE, SK_HORSE_TRAINING, 1, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_MOUNT | FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL - }, - { /* I_WAGON */ - {"Wagen", "Wagen", "Wagen", "Wagen"}, - IS_PRODUCT, SK_CARTMAKER, 1, {0, 5, 0, 0, 0, 0}, 4000, 0, FL_ITEM_NOTINBAG, NULL - }, - { /* I_SPEAR */ - {"Speer", "Speere", "Speer", "Speere"}, - IS_PRODUCT, SK_WEAPONSMITH, 2, {0, 1, 0, 0, 0, 0}, 100, 0, 0, NULL + IS_RESOURCE, SK_HORSE_TRAINING, 1, 5000, 0, FL_ITEM_MOUNT | FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL }, { /* I_AMULET_OF_HEALING */ {"Amulett der Heilung", "Amulette der Heilung", "Amulett", "Amulette"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_AMULET_OF_TRUE_SEEING 22 */ {"Amulett des wahren Sehens", "Amulette des wahren Sehens", "Amulett", "Amulette"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_RING_OF_INVISIBILITY 24 */ {"Ring der Unsichtbarkeit", "Ringe der Unsichtbarkeit", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_RING_OF_POWER 25 */ {"Ring der Macht", "Ringe der Macht", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_DRAGONHEAD 33 */ {"Drachenkopf", "Drachenk�pfe", "Drachenkopf", "Drachenk�pfe"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 500, 0, 0, NULL }, { /* I_CHASTITY_BELT 34 */ {"Amulett der Keuschheit", "Amulette der Keuschheit", "Amulett", "Amulette"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL - }, - { /* I_LAENSWORD 38 */ - {"Laenschwert", "Laenschwerter", "Laenschwert", "Laenschwerter"}, - IS_PRODUCT, SK_WEAPONSMITH, 8, {0, 0, 0, 0, 1, 0}, 100, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_LAEN 41 */ {"Laen", "Laen", "Laen", "Laen"}, - IS_RESOURCE, SK_MINING, 7, {0, 0, 0, 0, 0, 0}, 200, 0, 0, NULL - }, - { /* I_LANCE 44 */ - {"Lanze", "Lanzen", "Lanze", "Lanzen"}, - IS_PRODUCT, SK_WEAPONSMITH, 2, {0, 2, 0, 0, 0, 0}, 200, 0, 0, NULL - }, - { /* I_MALLORN 45 */ - {"Mallorn", "Mallorn", "Mallorn", "Mallorn"}, - IS_RESOURCE, SK_LUMBERJACK, 2, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL + IS_RESOURCE, SK_MINING, 7, 200, 0, 0, NULL }, { /* I_DRACHENBLUT 59 */ {"Drachenblut", "Drachenblut", "Drachenblut", "Drachenblut"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 100, 0, 0, NULL }, { /* I_FEENSTIEFEL 60 */ {"Feenstiefel", "Feenstiefel", "Feenstiefel", "Feenstiefel"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_BIRTHDAYAMULET 69 */ {"Katzenamulett", "Katzenamulette", "Amulett", "Amulette"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, &use_birthdayamulet + IS_MAGIC, NOSKILL, 0, 100, 0, 0, &use_birthdayamulet }, { /* I_PEGASUS 60 */ {"Pegasus", "Pegasi", "Pegasus", "Pegasi" }, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL + IS_MAGIC, NOSKILL, 0, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL }, { /* I_UNICORN 61 */ {"Elfenpferd", "Elfenpferde", "Elfenpferd", "Elfenpferde"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL + IS_MAGIC, NOSKILL, 0, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL }, { /* I_DOLPHIN 62 */ {"Delphin", "Delphine", "Delphin", "Delphine"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL + IS_MAGIC, NOSKILL, 0, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG | FL_ITEM_NOTLOST, NULL }, { /* I_RING_OF_NIMBLEFINGER 64 */ {"Ring der flinken Finger", "Ringe der flinken Finger", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_TROLLBELT 65 */ {"G�rtel der Trollst�rke", "G�rtel der Trollst�rke", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, 0, NULL }, { /* I_PRESSCARD 67 */ {"Akkredition des Xontormia-Expre�", "Akkreditionen des Xontormia-Expre�", "Akkredition des Xontormia-Expre�", "Akkreditionen des Xontormia-Expre�"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, FL_ITEM_CURSED, NULL + IS_MAGIC, NOSKILL, 0, 0, 0, FL_ITEM_CURSED, NULL }, { /* I_AURAKULUM 69 */ {"Aurafocus", "Aurafocuse", "Amulett", "Amulette"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 100, 0, 0, NULL }, { /* I_SEASERPENTHEAD 70 */ {"Seeschlangenkopf", "Seeschlangenk�pfe", "Seeschlangenkopf", "Seeschlangenk�pfe"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 500, 0, 0, NULL }, { /* I_SPHERE_OF_INVISIBILITY */ {"Sph�re der Unsichtbarkeit", "Sph�ren der Unsichtbarkeit", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 100, 0, 0, NULL }, { /* I_BAG_OF_HOLDING */ {"Zauberbeutel", "Zauberbeutel", "Zauberbeutel", "Zauberbeutel"}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, FL_ITEM_NOTINBAG|FL_ITEM_NOTLOST, NULL + IS_MAGIC, NOSKILL, 0, 100, 0, FL_ITEM_NOTINBAG|FL_ITEM_NOTLOST, NULL }, { /* I_SACK_OF_CONSERVATION */ {"Magischer Kr�uterbeutel", "Magische Kr�uterbeutel", "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL + IS_MAGIC, NOSKILL, 0, 100, 0, 0, NULL }, { /* I_TACTICCRYSTAL 71 */ - {"Traumauge", "Traumaugen", - "", ""}, - IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, &use_tacticcrystal + {"Traumauge", "Traumaugen", "", ""}, + IS_MAGIC, NOSKILL, 0, 100, 0, 0, &use_tacticcrystal }, }; -const item_t matresource[] = { - I_IRON, - I_WOOD, - I_STONE, - -1, - I_LAEN, - I_MALLORN -}; - #include "movement.h" static int @@ -794,27 +773,11 @@ mod_elves_only(const unit * u, const region * r, skill_t sk, int value) return -118; } -typedef int material_t; -enum { /* Vorsicht! Reihenfolge der ersten 3 mu� wie I_IRON ... sein! */ - M_EISEN, - M_HOLZ, - M_STEIN, - M_SILBER, - M_EOG, - M_MALLORN, - M_MAX_MAT, - NOMATERIAL = (material_t) - 1 -}; - static int -limit_oldtypes(const region * r, const resource_type * rtype) +limit_oldresource(const region * r, const resource_type * rtype) /* TODO: split into seperate functions. really much nicer. */ { - if (rtype==oldresourcetype[R_WOOD]) { - return rtrees(r,2) + rtrees(r,1); - } else if (rtype==oldresourcetype[R_MALLORN]) { - return rtrees(r,2) + rtrees(r,1); - } else if (rtype==oldresourcetype[R_HORSE]) { + if (rtype==oldresourcetype[R_HORSE]) { return rhorses(r); } else { assert(!"das kann man nicht produzieren!"); @@ -824,35 +787,15 @@ limit_oldtypes(const region * r, const resource_type * rtype) static void -use_oldresource(region * r, const resource_type * rtype, int norders) +produce_oldresource(region * r, const resource_type * rtype, int norders) /* TODO: split into seperate functions. really much nicer. */ { assert(norders>0); - if (rtype==oldresourcetype[R_WOOD] || rtype==oldresourcetype[R_MALLORN]) { - int avail_grownup = rtrees(r,2); - int avail_young = rtrees(r,1); - int wcount; - - assert(norders <= avail_grownup + avail_young); - - if(norders <= avail_grownup) { - rsettrees(r, 2, avail_grownup-norders); - wcount = norders; - } else { - rsettrees(r, 2, 0); - rsettrees(r, 1, avail_young-(norders-avail_grownup)); - wcount = norders * 3; - } - if(rtype==oldresourcetype[R_MALLORN]) { - woodcounts(r, wcount); - } else { - woodcounts(r, wcount*2); - } - } else if (rtype==oldresourcetype[R_HORSE]) { + if (rtype==oldresourcetype[R_HORSE]) { int avail = rhorses(r); assert(norders <= avail); rsethorses(r, avail-norders); - } else if (rtype!=oldresourcetype[R_STONE]) { + } else { assert(!"unknown resource"); } } @@ -961,9 +904,6 @@ init_olditems(void) itype->capacity = HORSECAPACITY; itype->give = give_horses; break; - case I_WAGON: - itype->capacity = WAGONCAPACITY; - break; case I_BAG_OF_HOLDING: itype->capacity = BAGCAPACITY; break; @@ -985,8 +925,11 @@ init_olditems(void) a = a_add(&rtype->attribs, a_new(&at_resourcelimit)); { resource_limit * rdata = (resource_limit*)a->data.v; - rdata->limit = limit_oldtypes; - rdata->use = use_oldresource; + if (i==I_HORSE) { + rdata->limit = limit_oldresource; + rdata->produce = produce_oldresource; + } + if (i==I_LAEN || i==I_IRON) rdata->guard |= GUARD_MINING; } break; } @@ -998,35 +941,21 @@ init_olditems(void) } for (i=0; i!=MAXITEMS; ++i) { - construction * con = calloc(sizeof(construction), 1); - item_type * itype = olditemtype[i]; - int m, n; + if (itemdata[i].skill!=NOSKILL) { + construction * con = calloc(sizeof(construction), 1); + item_type * itype = olditemtype[i]; - con->minskill = itemdata[i].minskill; - if (i==I_LAEN && SkillCap(SK_QUARRYING)) { - /* at least 4 levels on which you can mine laen */ - con->minskill = SkillCap(SK_QUARRYING)-3; - } - con->skill = itemdata[i].skill; - con->maxsize = -1; - con->reqsize = 1; - con->improvement = NULL; - for (m=0, n=0;m!=M_MAX_MAT;++m) - if (itemdata[i].material[m]>0) ++n; - if (n>0) { - con->materials = calloc(sizeof(requirement), n+1); - for (m=0, n=0;m!=M_MAX_MAT;++m) { - if (itemdata[i].material[m]>0) { - assert(oldresourcetype[matresource[m]]); - con->materials[n].rtype = oldresourcetype[matresource[m]]; - con->materials[n].number = itemdata[i].material[m]; - con->materials[n].recycle = 0.0; - ++n; - } + con->minskill = itemdata[i].minskill; + if (i==I_LAEN && SkillCap(SK_QUARRYING)) { + /* at least 4 levels on which you can mine laen */ + con->minskill = SkillCap(SK_QUARRYING)-3; } + con->skill = itemdata[i].skill; + con->maxsize = -1; + con->reqsize = 1; + con->improvement = NULL; + itype->construction = con; } - - itype->construction = con; } } @@ -1303,18 +1232,11 @@ item_score(item_t i) { switch (i) { case I_IRON: - case I_WOOD: case I_STONE: case I_HORSE: return 10; - case I_MALLORN: - return 30; case I_LAEN: return 100; - case I_WAGON: - return 60; - case I_LAENSWORD: - return 400; case I_AMULET_OF_HEALING: case I_AMULET_OF_TRUE_SEEING: case I_RING_OF_INVISIBILITY: @@ -1541,9 +1463,6 @@ register_resources(void) register_function((pf_generic)res_changehp, "changehp"); register_function((pf_generic)res_changeaura, "changeaura"); - register_function((pf_generic)limit_oldtypes, "limit_oldtypes"); - - register_function((pf_generic)use_oldresource, "useoldresource"); register_function((pf_generic)use_olditem, "useolditem"); register_function((pf_generic)use_potion, "usepotion"); register_function((pf_generic)use_tacticcrystal, "usetacticcrystal"); diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index 7a9334d39..b67b792b5 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -76,13 +76,25 @@ extern const char* resourcename(const resource_type * rtype, int flags); extern const resource_type * findresourcetype(const char * name, const struct locale * lang); /* resource-limits for regions */ +#define RMF_SKILL 0x01 /* int, bonus on resource production skill */ +#define RMF_SAVEMATERIAL 0x02 /* float, multiplier on resource usage */ +#define RMF_SAVERESOURCE 0x03 /* int, bonus on resource production skill */ +typedef struct resource_mod { + variant value; + const struct building_type * btype; + const struct race * race; + unsigned int flags; +} resource_mod; + extern struct attrib_type at_resourcelimit; typedef int (*rlimit_limit)(const struct region * r, const struct resource_type * rtype); -typedef void (*rlimit_use)(struct region * r, const struct resource_type * rtype, int n); +typedef void (*rlimit_produce)(struct region * r, const struct resource_type * rtype, int n); typedef struct resource_limit { rlimit_limit limit; - rlimit_use use; + rlimit_produce produce; + unsigned int guard; /* how to guard against theft */ int value; + resource_mod * modifiers; } resource_limit; @@ -93,6 +105,7 @@ typedef struct resource_limit { #define ITF_NOTLOST 0x0020 /* special object (quests), cannot be lost through death etc. */ #define ITF_BIG 0x0040 /* big item, e.g. does not fit in a bag of holding */ #define ITF_ANIMAL 0x0080 /* an animal */ +#define ITF_VEHICLE 0x0100 /* a vehicle, drawn by two animals */ /* error codes for item_type::use */ #define ECUSTOM -1; @@ -240,27 +253,10 @@ extern resource_type * r_permaura; extern resource_type * r_unit; extern resource_type * r_hp; -typedef struct t_item { - const char *name[4]; - /* [0]: Einzahl f�r eigene; [1]: Mehrzahl f�r eigene; - * [2]: Einzahl f�r Fremde; [3]: Mehrzahl f�r Fremde */ - item_t typ; - skill_t skill; - int minskill; - int material[6]; - int gewicht; - int preis; - unsigned int flags; - void (*benutze_funktion) (struct region *, struct unit *, int amount, struct order *); -} t_item; - enum { I_IRON, /* 0 */ - I_WOOD, I_STONE, I_HORSE, - I_WAGON, - I_SPEAR, /* alte Artefakte */ I_AMULET_OF_HEALING, I_AMULET_OF_TRUE_SEEING, @@ -268,10 +264,7 @@ enum { I_RING_OF_POWER, I_DRAGONHEAD, I_CHASTITY_BELT, /* bleibt */ - I_LAENSWORD, I_LAEN, - I_LANCE, - I_MALLORN, I_DRACHENBLUT, I_FEENSTIEFEL, I_BIRTHDAYAMULET, @@ -293,11 +286,8 @@ enum { enum { /* ITEMS: */ R_IRON, - R_WOOD, R_STONE, R_HORSE, - R_WAGON, - R_SPEAR, /**/ R_AMULET_OF_HEALING, R_AMULET_OF_TRUE_SEEING, @@ -305,10 +295,7 @@ enum { R_RING_OF_POWER, R_DRAGONHEAD, R_CHASTITY_BELT, - R_EOGSWORD, R_EOG, - R_LANCE, - R_MALLORN, R_DRACHENBLUT, R_FEENSTIEFEL, R_BIRTHDAYAMULET, diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index bb880ce0d..0d2473e81 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -208,18 +208,7 @@ entrance_allowed(const struct unit * u, const struct region * r) int personcapacity(const unit *u) { -#ifdef RACE_CAPACITY int cap = u->race->weight+u->race->capacity; -#else - int cap = u->race->weight+540; - - if (u->race == new_race[RC_TROLL]) - cap += 540; -#if RACE_ADJUSTMENTS - else if (u->race == new_race[RC_GOBLIN]) - cap -= 100; -#endif -#endif if (fspecial(u->faction, FS_QUICK)) cap -= 200; @@ -237,75 +226,101 @@ eff_weight(const unit *u) return weight(u); } +static void +get_transporters(const item * itm, int * p_animals, int *p_acap, int * p_vehicles, int * p_vcap) +{ + int vehicles = 0, vcap = 0; + int animals = 0, acap = 0; + + for (;itm!=NULL;itm=itm->next) { + const item_type * itype = itm->type; + if (itype->capacity>0) { + if (itype->flags & ITF_ANIMAL) { + ++animals; + if (acap==0) acap = itype->capacity; + assert(acap==itype->capacity || !"animals with different capacity not supported"); + } + if (itype->flags & ITF_VEHICLE) { + ++vehicles; + if (vcap==0) vcap = itype->capacity; + assert(vcap==itype->capacity || !"vehicles with different capacity not supported"); + } + } + } + *p_vehicles = vehicles; + *p_animals = animals; + *p_vcap = vcap; + *p_acap = acap; +} + static int ridingcapacity(unit * u) { - int n; - int wagen, pferde; + int vehicles = 0, vcap = 0; + int animals = 0, acap = 0; - n = 0; + get_transporters(u->items, &animals, &acap, &vehicles, &vcap); - /* Man tr�gt sein eigenes Gewicht plus seine Kapazit�t! Die Menschen - * tragen nichts (siehe walkingcapacity). Ein Wagen z�hlt nur, wenn er - * von zwei Pferden gezogen wird */ + /* Man tr�gt sein eigenes Gewicht plus seine Kapazit�t! Die Menschen + * tragen nichts (siehe walkingcapacity). Ein Wagen z�hlt nur, wenn er + * von zwei Pferden gezogen wird */ - pferde = get_item(u, I_HORSE) + get_item(u, I_UNICORN); - pferde = min(pferde, effskill(u, SK_RIDING) * u->number * 2); - if (fval(u->race, RCF_HORSE)) pferde += u->number; + animals = min(animals, effskill(u, SK_RIDING) * u->number * 2); + if (fval(u->race, RCF_HORSE)) animals += u->number; /* maximal diese Pferde k�nnen zum Ziehen benutzt werden */ - wagen = min(pferde / HORSESNEEDED, get_item(u, I_WAGON)); + vehicles = min(animals / HORSESNEEDED, vehicles); - n = wagen * WAGONCAPACITY + pferde * HORSECAPACITY; - return n; + return vehicles * vcap + animals * acap; } int walkingcapacity(const struct unit * u) { - int n, tmp, personen, pferde_fuer_wagen; - int wagen, wagen_ohne_pferde, wagen_mit_pferden, wagen_mit_trollen; - /* Das Gewicht, welches die Pferde tragen, plus das Gewicht, welches + int n, tmp, people, pferde_fuer_wagen; + int wagen_ohne_pferde, wagen_mit_pferden, wagen_mit_trollen; + int vehicles = 0, vcap = 0; + int animals = 0, acap = 0; + + get_transporters(u->items, &animals, &acap, &vehicles, &vcap); + + /* Das Gewicht, welches die Pferde tragen, plus das Gewicht, welches * die Leute tragen */ - int pferde = get_item(u, I_HORSE) + get_item(u, I_UNICORN); + pferde_fuer_wagen = min(animals, effskill(u, SK_RIDING) * u->number * 4); if (fval(u->race, RCF_HORSE)) { - pferde += u->number; - personen = 0; + animals += u->number; + people = 0; } else { - personen = u->number; + people = u->number; } - wagen = get_item(u, I_WAGON); - - pferde_fuer_wagen = min(pferde, effskill(u, SK_RIDING) * u->number * 4); /* maximal diese Pferde k�nnen zum Ziehen benutzt werden */ + wagen_mit_pferden = min(vehicles, pferde_fuer_wagen / HORSESNEEDED); - wagen_mit_pferden = min(wagen, pferde_fuer_wagen / HORSESNEEDED); - - n = wagen_mit_pferden * WAGONCAPACITY; + n = wagen_mit_pferden * vcap; if (u->race == new_race[RC_TROLL]) { /* 4 Trolle ziehen einen Wagen. */ /* Unbesetzte Wagen feststellen */ - wagen_ohne_pferde = wagen - wagen_mit_pferden; + wagen_ohne_pferde = vehicles - wagen_mit_pferden; /* Genug Trolle, um die Restwagen zu ziehen? */ wagen_mit_trollen = min(u->number / 4, wagen_ohne_pferde); /* Wagenkapazit�t hinzuz�hlen */ - n += wagen_mit_trollen * WAGONCAPACITY; + n += wagen_mit_trollen * vcap; wagen_ohne_pferde -= wagen_mit_trollen; } - n += pferde * HORSECAPACITY; - n += personen * personcapacity(u); + n += animals * acap; + n += people * personcapacity(u); /* Goliathwasser */ tmp = get_effect(u, oldpotiontype[P_STRONG]); - n += min(personen, tmp) * (HORSECAPACITY - personcapacity(u)); + n += min(people, tmp) * (acap - personcapacity(u)); /* change_effect wird in ageing gemacht */ tmp = get_item(u, I_TROLLBELT); - n += min(personen, tmp) * (STRENGTHMULTIPLIER-1) * personcapacity(u); + n += min(people, tmp) * (STRENGTHMULTIPLIER-1) * personcapacity(u); return n; } @@ -320,16 +335,16 @@ enum { static int canwalk(unit * u) { - int wagen, maxwagen; - int pferde, maxpferde; + int maxwagen, maxpferde; + int vehicles = 0, vcap = 0; + int animals = 0, acap = 0; - /* workaround: monsters are too stupid to drop items, therefore they have + /* workaround: monsters are too stupid to drop items, therefore they have * infinite carrying capacity */ - if (u->faction->no == 0) return E_CANWALK_OK; + if (u->faction->no == MONSTER_FACTION) return E_CANWALK_OK; - wagen = get_item(u, I_WAGON); - pferde = get_item(u, I_HORSE) + get_item(u, I_UNICORN); + get_transporters(u->items, &animals, &acap, &vehicles, &vcap); maxwagen = effskill(u, SK_RIDING) * u->number * 2; if (u->race == new_race[RC_TROLL]) { @@ -337,7 +352,7 @@ canwalk(unit * u) } maxpferde = effskill(u, SK_RIDING) * u->number * 4 + u->number; - if (pferde > maxpferde) + if (animals > maxpferde) return E_CANWALK_TOOMANYHORSES; if (walkingcapacity(u) - eff_weight(u) >= 0) @@ -348,7 +363,7 @@ canwalk(unit * u) * die Einheit nicht zum Ziehen benutzt, also nicht mehr Wagen gezogen * als erlaubt. */ - if (wagen > maxwagen) + if (vehicles > maxwagen) return E_CANWALK_TOOMANYCARTS; /* Es mu� nicht zwingend an den Wagen liegen, aber egal... (man * k�nnte z.B. auch 8 Eisen abladen, damit ein weiterer Wagen als diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 68141849b..2f548a137 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -136,13 +136,6 @@ chaoscount(const region * r) { return a->data.i; } -int -woodcount(const region * r) { - attrib * a = a_find(r->attribs, &at_woodcount); - if (!a) return 0; - return a->data.i; -} - void deathcounts (region * r, int fallen) { attrib * a; @@ -170,19 +163,6 @@ chaoscounts(region * r, int fallen) { if (a->data.i<=0) a_remove(&r->attribs, a); } -void -woodcounts(region * r, int fallen) { - attrib * a; - - if (fallen==0) return; - - a = a_find(r->attribs, &at_woodcount); - if (!a) a = a_add(&r->attribs, a_new(&at_woodcount)); - a->data.i += fallen; - - if (a->data.i<=0) a_remove(&r->attribs, a); -} - /********************/ /* at_direction */ /********************/ @@ -508,7 +488,7 @@ attrib_type at_woodcount = { DEFAULT_INIT, DEFAULT_FINALIZE, DEFAULT_AGE, - a_writeint, + NO_WRITE, a_readint, ATF_UNIQUE }; diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index deb2ab03b..c31efd978 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -164,11 +164,9 @@ extern struct attrib *create_special_direction(struct region *r, struct region * int duration, const char *desc, const char *keyword); -int woodcount(const struct region * r); int deathcount(const struct region * r); int chaoscount(const struct region * r); -void woodcounts(struct region * r, int delta); void deathcounts(struct region * r, int delta); void chaoscounts(struct region * r, int delta); diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 1ff240893..0944de0d9 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -243,36 +243,41 @@ parse_buildings(xmlDocPtr doc) for (i=0;i!=nodes->nodeNr;++i) { xmlNodePtr node = nodes->nodeTab[i]; xmlChar * property; - building_type * bt = calloc(sizeof(building_type), 1); + building_type * btype; xmlXPathObjectPtr result; int k; property = xmlGetProp(node, BAD_CAST "name"); assert(property!=NULL); - bt->_name = strdup((const char *)property); + btype = bt_find((const char*)property); + if (btype==NULL) { + btype = calloc(sizeof(building_type), 1); + btype->_name = strdup((const char *)property); + bt_register(btype); + } xmlFree(property); - bt->capacity = xml_ivalue(node, "capacity", -1); - bt->maxcapacity = xml_ivalue(node, "maxcapacity", -1); - bt->maxsize = xml_ivalue(node, "maxsize", -1); + btype->capacity = xml_ivalue(node, "capacity", -1); + btype->maxcapacity = xml_ivalue(node, "maxcapacity", -1); + btype->maxsize = xml_ivalue(node, "maxsize", -1); - bt->magres = xml_ivalue(node, "magres", 0); - bt->magresbonus = xml_ivalue(node, "magresbonus", 0); - bt->fumblebonus = xml_ivalue(node, "fumblebonus", 0); - bt->auraregen = xml_fvalue(node, "auraregen", 1.0); + btype->magres = xml_ivalue(node, "magres", 0); + btype->magresbonus = xml_ivalue(node, "magresbonus", 0); + btype->fumblebonus = xml_ivalue(node, "fumblebonus", 0); + btype->auraregen = xml_fvalue(node, "auraregen", 1.0); - if (xml_bvalue(node, "nodestroy", false)) bt->flags |= BTF_INDESTRUCTIBLE; - if (xml_bvalue(node, "oneperturn", false)) bt->flags |= BTF_ONEPERTURN; - if (xml_bvalue(node, "nobuild", false)) bt->flags |= BTF_NOBUILD; - if (xml_bvalue(node, "unique", false)) bt->flags |= BTF_UNIQUE; - if (xml_bvalue(node, "decay", false)) bt->flags |= BTF_DECAY; - if (xml_bvalue(node, "magic", false)) bt->flags |= BTF_MAGIC; - if (xml_bvalue(node, "protection", false)) bt->flags |= BTF_PROTECTION; + if (xml_bvalue(node, "nodestroy", false)) btype->flags |= BTF_INDESTRUCTIBLE; + if (xml_bvalue(node, "oneperturn", false)) btype->flags |= BTF_ONEPERTURN; + if (xml_bvalue(node, "nobuild", false)) btype->flags |= BTF_NOBUILD; + if (xml_bvalue(node, "unique", false)) btype->flags |= BTF_UNIQUE; + if (xml_bvalue(node, "decay", false)) btype->flags |= BTF_DECAY; + if (xml_bvalue(node, "magic", false)) btype->flags |= BTF_MAGIC; + if (xml_bvalue(node, "protection", false)) btype->flags |= BTF_PROTECTION; /* reading eressea/buildings/building/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstruction(xpath, result->nodesetval->nodeTab, result->nodesetval->nodeNr, &bt->construction); + xml_readconstruction(xpath, result->nodesetval->nodeTab, result->nodesetval->nodeNr, &btype->construction); xmlXPathFreeObject(result); if (gamecode_enabled) { @@ -286,18 +291,18 @@ parse_buildings(xmlDocPtr doc) if (fun==NULL) { log_error(("unknown function name '%s' for building %s\n", - (const char*)property, bt->_name)); + (const char*)property, btype->_name)); xmlFree(property); continue; } assert(property!=NULL); if (strcmp((const char*)property, "name")==0) { - bt->name = (const char * (*)(int size))fun; + btype->name = (const char * (*)(int size))fun; } else if (strcmp((const char*)property, "init")==0) { - bt->init = (void (*)(struct building_type*))fun; + btype->init = (void (*)(struct building_type*))fun; } else { log_error(("unknown function type '%s' for building %s\n", - (const char*)property, bt->_name)); + (const char*)property, btype->_name)); } xmlFree(property); } @@ -310,10 +315,10 @@ parse_buildings(xmlDocPtr doc) xmlNodePtr node = result->nodesetval->nodeTab[k]; maintenance * mt; - if (bt->maintenance==NULL) { - bt->maintenance = calloc(sizeof(struct maintenance), result->nodesetval->nodeNr+1); + if (btype->maintenance==NULL) { + btype->maintenance = calloc(sizeof(struct maintenance), result->nodesetval->nodeNr+1); } - mt = bt->maintenance + k; + mt = btype->maintenance + k; mt->number = xml_ivalue(node, "amount", 0); property = xmlGetProp(node, BAD_CAST "type"); @@ -328,8 +333,8 @@ parse_buildings(xmlDocPtr doc) } xmlXPathFreeObject(result); - /* finally, register the new building type */ - bt_register(bt); + /* finally, initialize the new building type */ + if (btype->init) btype->init(btype); } } xmlXPathFreeObject(buildings); @@ -652,7 +657,7 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); assert(wtype->modifiers==NULL); - wtype->modifiers = calloc(sizeof(weapon_mod), result->nodesetval->nodeNr+1); + wtype->modifiers = calloc(result->nodesetval->nodeNr+1, sizeof(weapon_mod)); for (k=0;k!=result->nodesetval->nodeNr;++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; xmlXPathObjectPtr races; @@ -740,6 +745,7 @@ xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) if (xml_bvalue(node, "herb", false)) flags |= ITF_HERB; if (xml_bvalue(node, "big", false)) flags |= ITF_BIG; if (xml_bvalue(node, "animal", false)) flags |= ITF_ANIMAL; + if (xml_bvalue(node, "vehicle", false)) flags |= ITF_VEHICLE; itype = new_itemtype(rtype, flags, weight, capacity); #ifdef SCORE_MODULE itype->score = xml_ivalue(node, "score", 0); @@ -917,41 +923,120 @@ parse_resources(xmlDocPtr doc) xmlXPathFreeObject(result); } + /* reading eressea/resources/resource/resourcelimit */ + xpath->node = node; + result = xmlXPathEvalExpression(BAD_CAST "resourcelimit", xpath); + assert(result->nodesetval->nodeNr<=1); + if (result->nodesetval->nodeNr!=0) { + resource_limit * rdata; + attrib * a = a_find(rtype->attribs, &at_resourcelimit); + xmlNodePtr limit = result->nodesetval->nodeTab[0]; + + if (a==NULL) a = a_add(&rtype->attribs, a_new(&at_resourcelimit)); + rdata = (resource_limit*)a->data.v; + rtype->flags |= RTF_LIMITED; + xpath->node = limit; + xmlXPathFreeObject(result); + + result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); + if (result->nodesetval!=NULL) { + rdata->modifiers = calloc(result->nodesetval->nodeNr+1, sizeof(resource_mod)); + for (k=0;k!=result->nodesetval->nodeNr;++k) { + xmlNodePtr node = result->nodesetval->nodeTab[k]; + building_type * btype = NULL; + const race * rc = NULL; + + property = xmlGetProp(node, BAD_CAST "race"); + if (property!=NULL) { + rc = rc_find((const char*)property); + if (rc==NULL) rc = rc_add(rc_new((const char*)property)); + xmlFree(property); + } + rdata->modifiers[k].race = rc; + + property = xmlGetProp(node, BAD_CAST "building"); + if (property!=NULL) { + btype = bt_find((const char*)property); + if (btype==NULL) { + btype = calloc(sizeof(building_type), 1); + btype->_name = strdup((const char *)property); + bt_register(btype); + } + xmlFree(property); + } + rdata->modifiers[k].btype = btype; + + property = xmlGetProp(node, BAD_CAST "type"); + assert(property!=NULL); + if (strcmp((const char *)property, "skill")) { + rdata->modifiers[k].value.i = xml_ivalue(node, "value", 0); + rdata->modifiers[k].flags |= RMF_SKILL; + } else if (strcmp((const char *)property, "material")) { + rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0); + rdata->modifiers[k].flags |= RMF_SAVEMATERIAL; + } else if (strcmp((const char *)property, "resource")) { + rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0); + rdata->modifiers[k].flags |= RMF_SAVERESOURCE; + } else { + log_error(("unknown type '%s' for resourcelimit-modifier '%s'\n", + (const char*)property, rtype->_name[0])); + } + xmlFree(property); + } + } + xmlXPathFreeObject(result); + + result = xmlXPathEvalExpression(BAD_CAST "guard", xpath); + if (result->nodesetval!=NULL) for (k=0;k!=result->nodesetval->nodeNr;++k) { + xmlNodePtr node = result->nodesetval->nodeTab[k]; + xmlChar * flag = xmlGetProp(node, BAD_CAST "flag"); + + if (flag!=NULL) { + if (strcmp((char*)flag, "logging")==0) { + rdata->guard |= GUARD_TREES; + } else if (strcmp((char*)flag, "mining")==0) { + rdata->guard |= GUARD_MINING; + } + xmlFree(flag); + } + } + xmlXPathFreeObject(result); + + /* reading eressea/resources/resource/resourcelimit/function */ + result = xmlXPathEvalExpression(BAD_CAST "function", xpath); + if (result->nodesetval!=NULL) for (k=0;k!=result->nodesetval->nodeNr;++k) { + xmlNodePtr node = result->nodesetval->nodeTab[k]; + pf_generic fun; + + property = xmlGetProp(node, BAD_CAST "value"); + assert(property!=NULL); + fun = get_function((const char*)property); + if (fun==NULL) { + log_error(("unknown limit '%s' for resource %s\n", + (const char*)property, rtype->_name[0])); + xmlFree(property); + continue; + } + xmlFree(property); + + property = xmlGetProp(node, BAD_CAST "name"); + assert(property!=NULL); + if (strcmp((const char*)property, "produce")==0) { + rdata->produce = (rlimit_produce)fun; + } else if (strcmp((const char*)property, "limit")==0) { + rdata->limit = (rlimit_limit)fun; + } else { + log_error(("unknown limit '%s' for resource %s\n", + (const char*)property, rtype->_name[0])); + } + xmlFree(property); + } + } + xmlXPathFreeObject(result); + /* reading eressea/resources/resource/resourcelimit/function */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath); - if (result->nodesetval!=NULL) for (k=0;k!=result->nodesetval->nodeNr;++k) { - attrib * a = a_find(rtype->attribs, &at_resourcelimit); - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - - property = xmlGetProp(node, BAD_CAST "value"); - assert(property!=NULL); - fun = get_function((const char*)property); - if (fun==NULL) { - log_error(("unknown limit '%s' for resource %s\n", - (const char*)property, rtype->_name[0])); - xmlFree(property); - continue; - } - xmlFree(property); - - if (a==NULL) a = a_add(&rtype->attribs, a_new(&at_resourcelimit)); - - property = xmlGetProp(node, BAD_CAST "name"); - assert(property!=NULL); - if (strcmp((const char*)property, "use")==0) { - resource_limit * rdata = (resource_limit*)a->data.v; - rdata->use = (rlimit_use)fun; - } else if (strcmp((const char*)property, "limit")==0) { - resource_limit * rdata = (resource_limit*)a->data.v; - rdata->limit = (rlimit_limit)fun; - } else { - log_error(("unknown limit '%s' for resource %s\n", - (const char*)property, rtype->_name[0])); - } - xmlFree(property); - } xmlXPathFreeObject(result); /* reading eressea/resources/resource/item */ @@ -1312,7 +1397,7 @@ parse_races(xmlDocPtr doc) rc->maintenance = xml_ivalue(node, "maintenance", 0); rc->weight = xml_ivalue(node, "weight", 0); #ifdef RACE_CAPACITY - rc->capacity = xml_ivalue(node, "capacity", 0); + rc->capacity = xml_ivalue(node, "capacity", 540); #endif rc->speed = (float)xml_fvalue(node, "speed", 1.0F); rc->hitpoints = xml_ivalue(node, "hp", 0); diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index 8136ac0e4..eca6abc6b 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -235,13 +235,14 @@ make_temple(region * r) { const building_type * btype = bt_find("temple"); building * b; - if (btype==NULL) - btype = bt_make("temple", BTF_UNIQUE | BTF_NOBUILD | BTF_INDESTRUCTIBLE, -1, 2, 50); - else { - b = r->buildings; - while (b!=NULL && b->type!=btype) b = b->next; - if (b!=NULL) return; /* gibt schon einen */ - } + if (btype==NULL) { + log_error(("could not find buildingtype 'temple'\n")); + return; + } + + b = r->buildings; + while (b!=NULL && b->type!=btype) b = b->next; + if (b!=NULL) return; /* gibt schon einen */ b = new_building(btype, r, NULL); b->size = btype->maxsize; diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c index e60d965ea..47d2a32cd 100644 --- a/src/common/modules/autoseed.c +++ b/src/common/modules/autoseed.c @@ -487,7 +487,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island) short x = 0, y = 0; region * r = NULL; region_list * rlist = NULL; - int rsize, tsize = 0; + int rsize = 0, tsize = 0; int isize = REGIONS_PER_FACTION; /* target size for the island */ int psize = 0; /* players on this island */ const terrain_type * volcano_terrain = get_terrain("volcano"); @@ -567,14 +567,15 @@ autoseed(newfaction ** players, int nsize, boolean new_island) assert(virgin_region(rconnect(rmin, dmin))); x = rmin->x + delta_x[dmin]; y = rmin->y + delta_y[dmin]; + r = new_region(x, y); + terraform(r, T_OCEAN); /* we change the terrain later */ } - r = new_region(x, y); - terraform(r, T_OCEAN); /* we change the terrain later */ } - - add_regionlist(&rlist, r); - fset(r, FL_MARK); - rsize = 1; + if (r!=NULL) { + add_regionlist(&rlist, r); + fset(r, FL_MARK); + rsize = 1; + } while (rsize && (nsize || isize>=REGIONS_PER_FACTION)) { int i = rand() % rsize; diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index c97635e9b..41d0759df 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -706,10 +706,10 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver))); - for (i=0;i<=I_WAGON;++i) { + for (i=0;i<=I_HORSE;++i) { a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); } - for (i=I_LAENSWORD;i!=I_DRACHENBLUT;++i) { + for (i=I_LAEN;i!=I_DRACHENBLUT;++i) { a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); } @@ -771,10 +771,10 @@ gm_addfaction(const char * email, plane * p, region * r) a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver))); - for (i=0;i<=I_WAGON;++i) { + for (i=0;i<=I_HORSE;++i) { a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); } - for (i=I_LAENSWORD;i!=I_DRACHENBLUT;++i) { + for (i=I_LAEN;i!=I_DRACHENBLUT;++i) { a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); } diff --git a/src/common/settings-eressea.h b/src/common/settings-eressea.h index be31c8949..fd2b8abed 100644 --- a/src/common/settings-eressea.h +++ b/src/common/settings-eressea.h @@ -17,7 +17,6 @@ #define ENTERTAINFRACTION 20 #define IMMUN_GEGEN_ANGRIFF 8 #define RESOURCE_CONVERSION 1 -#define RACE_ADJUSTMENTS 1 #define TEACHDIFFERENCE 2 #define PEASANT_ADJUSTMENT 1 #define GUARD_DISABLES_RECRUIT 1 diff --git a/src/common/settings-tutorial.h b/src/common/settings-tutorial.h index 099b5cded..d44677c2f 100644 --- a/src/common/settings-tutorial.h +++ b/src/common/settings-tutorial.h @@ -17,7 +17,6 @@ #define ENTERTAINFRACTION 20 #define IMMUN_GEGEN_ANGRIFF 8 #define RESOURCE_CONVERSION 1 -#define RACE_ADJUSTMENTS 1 #define TEACHDIFFERENCE 2 #define PEASANT_ADJUSTMENT 1 #define GUARD_DISABLES_RECRUIT 1 diff --git a/src/common/settings-vinyambar-3.h b/src/common/settings-vinyambar-3.h index 854beabdc..b233488e6 100644 --- a/src/common/settings-vinyambar-3.h +++ b/src/common/settings-vinyambar-3.h @@ -17,7 +17,6 @@ #define ENTERTAINFRACTION 20 #define IMMUN_GEGEN_ANGRIFF 8 #define RESOURCE_CONVERSION 1 -#define RACE_ADJUSTMENTS 1 #define TEACHDIFFERENCE 2 #define PEASANT_ADJUSTMENT 1 #define GUARD_DISABLES_RECRUIT 1 diff --git a/src/common/settings-wdw.h b/src/common/settings-wdw.h index 723273714..8018ede6f 100644 --- a/src/common/settings-wdw.h +++ b/src/common/settings-wdw.h @@ -17,7 +17,6 @@ #define ENTERTAINFRACTION 20 #define IMMUN_GEGEN_ANGRIFF 8 #define RESOURCE_CONVERSION 1 -#define RACE_ADJUSTMENTS 1 #define TEACHDIFFERENCE 2 #define PEASANT_ADJUSTMENT 1 #define GUARD_DISABLES_RECRUIT 1 diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 23931662f..18388328a 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -345,7 +345,7 @@ update_gms(void) for (k=0;keys[k];++k) { add_key((attrib**)&permissions->data.v, atoi36(keys[k])); } - for (i=I_LAENSWORD;i!=I_DRACHENBLUT;++i) { + for (i=I_LAEN;i!=I_DRACHENBLUT;++i) { attrib * a = a_find((attrib*)permissions->data.v, &at_gmcreate); while (a && a->data.v!=(void*)olditemtype[i]) a=a->nexttype; if (!a) a_add((attrib**)&permissions->data.v, make_atgmcreate(olditemtype[i])); diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp index 2eb62cd9d..37b9695a4 100644 --- a/src/eressea/lua/eressea.cpp +++ b/src/eressea/lua/eressea.cpp @@ -182,7 +182,10 @@ lua_autoseed(const char * filename, bool new_island) int n = listlen(players); int k = (n+ISLANDSIZE-1)/ISLANDSIZE; k = n / k; - autoseed(&players, k, new_island || (turn % TURNS_PER_ISLAND)==0); + n = autoseed(&players, k, new_island || (turn % TURNS_PER_ISLAND)==0); + if (n==0) { + break; + } } } diff --git a/src/eressea/lua/item.cpp b/src/eressea/lua/item.cpp index b67be07c3..13ab01648 100644 --- a/src/eressea/lua/item.cpp +++ b/src/eressea/lua/item.cpp @@ -4,9 +4,13 @@ #include "script.h" // kernel includes -#include <kernel/unit.h> #include <kernel/item.h> +#include <kernel/region.h> +#include <kernel/unit.h> + +// util includes #include <util/attrib.h> +#include <util/functions.h> // lua includes #include <lua.hpp> @@ -62,9 +66,58 @@ item_register(const char * name, const char * appearance) init_itemnames(); } +static int +limit_resource(const region * r, const resource_type * rtype) +{ + char fname[64]; + snprintf(fname, sizeof(fname), "%s_limit", rtype->_name[0]); + int retval = -1; + + lua_State * L = (lua_State *)global.vm_state; + if (is_function(L, fname)) { + try { + retval = call_function<int>(L, fname, r); + } + catch (error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while trying to call '%s': %s.\n", + fname, error)); + lua_pop(L, 1); + std::terminate(); + } + } + return retval; +} + +static void +produce_resource(region * r, const resource_type * rtype, int norders) +{ + char fname[64]; + snprintf(fname, sizeof(fname), "%s_produce", rtype->_name[0]); + + lua_State * L = (lua_State *)global.vm_state; + if (is_function(L, fname)) { + try { + call_function<void>(L, fname, r, norders); + } + catch (error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while trying to call '%s': %s.\n", + fname, error)); + lua_pop(L, 1); + std::terminate(); + } + } +} + void bind_item(lua_State * L) { + register_function((pf_generic)produce_resource, "lua_produceresource"); + register_function((pf_generic)limit_resource, "lua_limitresource"); + module(L)[ def("register_item", &item_register) ]; diff --git a/src/eressea/main.c b/src/eressea/main.c index 235809b63..adb7a1c6e 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -177,7 +177,6 @@ game_init(void) init_races(); init_itemtypes(); init_races(); - init_economy(); init_rawmaterials(); init_gmcmd(); diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index 1fd44349d..c974b5d3c 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -245,7 +245,6 @@ game_init(void) init_attributes(); init_races(); init_itemtypes(); - init_economy(); init_rawmaterials(); init_gmcmd(); diff --git a/src/mapper/map_partei.c b/src/mapper/map_partei.c index f7157f73d..e8fffa283 100644 --- a/src/mapper/map_partei.c +++ b/src/mapper/map_partei.c @@ -137,31 +137,6 @@ change_level(unit * u, skill_t sk, int bylevel) sk_set(sv, sv->level+bylevel); } -static void -give_latestart_bonus(region *r, unit *u, int b) -{ - int bsk = days2level(b*30); - change_level(u, SK_OBSERVATION, bsk); - change_money(u, 200*b); - - { - unit *u2 = createunit(r, u->faction, 1, u->race); - change_level(u2, SK_TACTICS, bsk); - u2->irace = u->irace; -/* fset(u2, UFL_PARTEITARNUNG); */ - } - - { - unit *u2 = createunit(r, u->faction, 2*b, u->race); - change_level(u2, SK_SPEAR, 3); - change_level(u2, SK_TAXING, 3); - i_change(&u2->items, olditemtype[I_SPEAR], u2->number); - u2->irace = u->irace; -/* fset(u2, UFL_PARTEITARNUNG); */ - } -} - - newfaction * select_newfaction(const struct race * rc) { @@ -318,8 +293,6 @@ NeuePartei(region * r) u = addplayer(r, addfaction(email, passwd, frace, lang, subscription)); ++numnewbies; - if(late) give_latestart_bonus(r, u, late); - sprintf(buf, "newuser %s", email); system(buf); } diff --git a/src/res/equipment.xml b/src/res/equipment.xml index 654c52af1..ce148018c 100644 --- a/src/res/equipment.xml +++ b/src/res/equipment.xml @@ -242,6 +242,17 @@ <skill name="herbalism" level="d2"/> </set> + <set name="random_villagers"> + <item name="money" amount="d80+19"/> + <skill name="cartmaking" level="d2-1"/> + <skill name="mining" level="d2-1"/> + <skill name="quarrying" level="d2-1"/> + <skill name="forestry" level="d2-1"/> + <item name="horse" amount="2"/> + <item name="wagon" amount="d2-1"/> + <item name="money" amount="d30+10"/> + </set> + <set name="random_plain"> <item name="money" amount="d80+19"/> <subset> diff --git a/src/res/messages.xml b/src/res/messages.xml index 7c2e91d1b..c53f69cb1 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -4635,6 +4635,16 @@ <text locale="fr">"$unit($unit) in $region($region): '$order($command)' - You can breed horses only in a stable."</text> <text locale="en">"$unit($unit) in $region($region): '$order($command)' - You can breed horses only in a stable."</text> </message> + <message name="error121" section="errors"> + <type> + <arg name="unit" type="unit"/> + <arg name="region" type="region"/> + <arg name="command" type="order"/> + </type> + <text locale="de">"$unit($unit) in $region($region): '$order($command)' - So etwas gibt es hier nicht."</text> + <text locale="fr">"$unit($unit) in $region($region): '$order($command)' - That resource does not exist in this region."</text> + <text locale="en">"$unit($unit) in $region($region): '$order($command)' - That resource does not exist in this region."</text> + </message> <message name="error120" section="errors"> <type> <arg name="unit" type="unit"/> diff --git a/src/res/resources.xml b/src/res/resources.xml index 6dccb840c..2551bdeab 100644 --- a/src/res/resources.xml +++ b/src/res/resources.xml @@ -1,6 +1,43 @@ <?xml version="1.0"?> <resources> + <resource name="seed" limited="yes"> + <item weight="10" score="50"> + <construction skill="herbalism" minskill="3" reqsize="1"/> + </item> + </resource> + + <resource name="mallornseed" limited="yes"> + <item weight="10" score="100"> + <construction skill="herbalism" minskill="4" reqsize="1"/> + </item> + </resource> + + <resource name="log"> + <item weight="500" score="10"> + <construction skill="forestry" minskill="1" reqsize="1"/> + </item> + <resourcelimit> + <modifier building="sawmill" type="skill" value="1"/> + <modifier building="sawmill" type="material" value="0.5"/> + <guard flag="logging"/> + <function name="produce" value="lua_produceresource"/> + <function name="limit" value="lua_limitresource"/> + </resourcelimit> + </resource> + + <resource name="mallorn"> + <item weight="500" score="30"> + <construction skill="forestry" minskill="2" reqsize="1"/> + </item> + <resourcelimit> + <bonus building="sawmill" type="skill" value="1"/> + <guard flag="logging"/> + <function name="produce" value="lua_produceresource"/> + <function name="limit" value="lua_limitresource"/> + </resourcelimit> + </resource> + <!-- luxury items --> <resource name="balm"> <item weight="200"><luxury price="4"/></item> @@ -54,15 +91,11 @@ </resource> <!-- items --> - <resource name="seed" limited="yes"> - <item weight="10" score="50"> - <construction skill="herbalism" minskill="3" reqsize="1"/> - </item> - </resource> - - <resource name="mallornseed" limited="yes"> - <item weight="10" score="100"> - <construction skill="herbalism" minskill="4" reqsize="1"/> + <resource name="cart" big="true"> + <item capacity="14000" weight="4000" score="60" vehicle="yes"> + <construction skill="cartmaking" minskill="1" reqsize="1"> + <requirement type="log" quantity="5"/> + </construction> </item> </resource> @@ -94,8 +127,20 @@ </item> </resource> + <resource name="laensword"> + <item weight="100" score="400"> + <construction skill="weaponsmithing" minskill="8" reqsize="1"> + <requirement type="laen" quantity="1"/> + </construction> + <weapon cut="true" skill="melee" offmod="1" defmod="1" magres="0.30"> + <damage type="rider" value="3d6+10"/> + <damage type="footman" value="3d6+10"/> + </weapon> + </item> + </resource> + <resource name="rustygreatsword"> - <item weight="200"> + <item weight="200" score="20"> <construction skill="weaponsmithing" minskill="4" reqsize="1"> <requirement type="iron" quantity="2"/> </construction> @@ -107,7 +152,7 @@ </resource> <resource name="runesword"> - <item weight="100"> + <item weight="100" score="2000"> <weapon minskill="7" cut="true" magical="yes" skill="melee" offmod="2" defmod="2"> <function name="attack" value="attack_firesword"/> <damage type="rider" value="3d10+10"/> @@ -127,7 +172,7 @@ </resource> <resource name="greatsword"> - <item weight="200"> + <item weight="200" score="30"> <construction skill="weaponsmithing" minskill="4" reqsize="1"> <requirement type="iron" quantity="2"/> </construction> @@ -264,6 +309,20 @@ </item> </resource> + <resource name="spear"> + <item weight="100"> + <construction skill="weaponsmithing" minskill="2" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + <weapon pierce="true" skill="polearm" offmod="0" defmod="0"> + <damage type="footman" value="1d10"/> + <damage type="rider" value="1d12+2"/> + <modifier type="skill" value="1" riding="true" against_riding="true" against_walking="true" offensive="true"/> + <modifier type="skill" value="1" walking="true" against_riding="true" against_walking="true" defensive="true"/> + </weapon> + </item> + </resource> + <resource name="mallornspear"> <item weight="100"> <construction skill="weaponsmithing" minskill="5" reqsize="1"> @@ -272,6 +331,20 @@ <weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15"> <damage type="footman" value="1d10+1"/> <damage type="rider" value="1d12+3"/> + <modifier type="skill" value="1" riding="true" against_riding="true" against_walking="true" offensive="true"/> + <modifier type="skill" value="1" walking="true" against_riding="true" against_walking="true" defensive="true"/> + </weapon> + </item> + </resource> + + <resource name="lance"> + <item weight="200"> + <construction skill="weaponsmithing" minskill="2" reqsize="1"> + <requirement type="log" quantity="2"/> + </construction> + <weapon pierce="true" skill="polearm" offmod="0" defmod="-2"> + <damage type="footman" value="1d5"/> + <damage type="rider" value="2d6+5"/> </weapon> </item> </resource> @@ -283,7 +356,7 @@ </construction> <weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15"> <damage type="footman" value="1d5+1"/> - <damage type="rider" value="2d6+2"/> + <damage type="rider" value="2d6+6"/> </weapon> </item> </resource> diff --git a/src/scripts/eressea.lua b/src/scripts/eressea.lua index e8eed57af..a311347c7 100644 --- a/src/scripts/eressea.lua +++ b/src/scripts/eressea.lua @@ -31,7 +31,8 @@ function run_scripts() "eressea/ponnuki.lua", "eressea/xmas2004.lua", "eressea/xmas2005.lua", - "eressea/embassy.lua" + "eressea/embassy.lua", + "eressea/ents.lua" } for index in scripts do loadscript(scripts[index]) @@ -66,6 +67,7 @@ function process(orders) spawn_dragons() spawn_undead() spawn_braineaters(0.25) + spawn_ents() plan_monsters() process_orders() diff --git a/src/scripts/eressea/ents.lua b/src/scripts/eressea/ents.lua new file mode 100644 index 000000000..0133e061f --- /dev/null +++ b/src/scripts/eressea/ents.lua @@ -0,0 +1,33 @@ + +local function create_ents(r, number) + local f = get_faction(0) + if f~=nil and number>0 then + u = add_unit(f, r) + u.number = number + u.name = "W�tende Ents" + u:set_skill("perception", 2) + + msg = message("entrise") + msg:set_region("region", r) + msg:send_region(r) + return u + end + return nil +end + +-- this is old stuff. it's not active at the moment. +function spawn_ents() + local r + for r in regions() do + if r:get_flag(0) then -- RF_CHAOTIC + if r.terrain == "plain" and r:get_resource("tree")==0 then + if math.random(3)==1 then + u = create_ents(r, math.random(30)) + if u ~= nil then + r:set_resource("tree", u.number) + end + end + end + end + end +end diff --git a/src/scripts/extensions.lua b/src/scripts/extensions.lua index e9b9d7ded..325283155 100644 --- a/src/scripts/extensions.lua +++ b/src/scripts/extensions.lua @@ -28,3 +28,49 @@ function hp_changeresource(u, delta) u.hp = hp return hp end + +function log_limit(r) + if r:get_flag(1) then -- RF_MALLORN + return 0 + end + return r:get_resource("tree") + r:get_resource("sapling") +end + +function log_produce(r, n) + local trees = r:get_resource("tree") + if trees>=n then + r:set_resource("tree", trees-n) + else + r:set_resource("tree", 0) + n = n - trees + trees = r:get_resource("sapling") + if trees>=n then + r:set_resource("sapling", trees-n) + else + r:set_resource("sapling", 0) + end + end +end + +function mallorn_limit(r) + if not r:get_flag(1) then -- RF_MALLORN + return 0 + end + return r:get_resource("tree") + r:get_resource("sapling") +end + +function mallorn_produce(r, n) + local trees = r:get_resource("tree") + if trees>=n then + r:set_resource("tree", trees-n) + else + r:set_resource("tree", 0) + n = n - trees + trees = r:get_resource("sapling") + if trees>=n then + r:set_resource("sapling", trees-n) + else + r:set_resource("sapling", 0) + end + end +end