diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index adea451ba..f8e5f92b7 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -940,20 +940,6 @@ dogive(region * r, unit * u, strlist * S, boolean liefere, int mode) } if (findparam(s, u->faction->locale) == P_ANY) { /* Alle Gegenstände übergeben */ char * s = getstrtoken(); - const resource_type * rtype = findresourcetype(s, u->faction->locale); - - /* Dumpfbackenbrot kann ohne kontaktiere übergeben werden */ - if (rtype!=NULL) { - const potion_type * ptype = resource2potion(rtype); - if (ptype!=NULL && ptype == oldpotiontype[P_FOOL]) { - item * i = *i_find(&u->items, ptype->itype); - if (i!=NULL) { - n = i->number - new_get_resvalue(u, i->type->rtype); - give_item(n, i->type, u, u2, S->s); - return; - } - } - } if(u2 && !ucontact(u2, u)) { cmistake(u, S->s, 40, MSG_COMMERCE); diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index a096269a2..b0efdf912 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -3187,24 +3187,35 @@ setdefaults (void) } } - static int -use_item(unit * u, const item_type * itype, const char * cmd) +use_item(unit * u, const item_type * itype, int amount, const char * cmd) { int i; + int target = read_unitid(u->faction, u->region); - if (itype->use==NULL) { - cmistake(u, cmd, 76, MSG_PRODUCE); - return EUNUSABLE; - } i = new_get_pooled(u, itype->rtype, GET_DEFAULT); + if (amount>i) { + amount = i; + } if (i==0) { cmistake(u, cmd, 43, MSG_PRODUCE); return ENOITEM; } - return itype->use(u, itype, cmd); + if (target==-1) { + if (itype->use==NULL) { + cmistake(u, cmd, 76, MSG_PRODUCE); + return EUNUSABLE; + } + return itype->use(u, itype, amount, cmd); + } else { + if (itype->useonother==NULL) { + cmistake(u, cmd, 76, MSG_PRODUCE); + return EUNUSABLE; + } + return itype->useonother(u, target, itype, amount, cmd); + } } @@ -3370,11 +3381,17 @@ use(void) for (u = r->units; u; u = u->next) { for (S = u->orders; S; S = S->next) { if (igetkeyword(S->s, u->faction->locale) == K_USE) { - char * t = getstrtoken(); - const item_type * itype = finditemtype(t, u->faction->locale); + const char * t = getstrtoken(); + int n = atoi(t); + const item_type * itype; + if (n==0) { + n = 1; + t = getstrtoken(); + } + itype = finditemtype(t, u->faction->locale); if (itype!=NULL) { - use_item(u, itype, S->s); + use_item(u, itype, n, S->s); } else { cmistake(u, S->s, 43, MSG_PRODUCE); } diff --git a/src/common/items/birthday_firework.c b/src/common/items/birthday_firework.c index 4d6f114b5..264a35664 100644 --- a/src/common/items/birthday_firework.c +++ b/src/common/items/birthday_firework.c @@ -35,13 +35,15 @@ const int FIREWORK_RANGE=10; static int -use_birthday_firework(struct unit * u, const struct item_type * itype, const char *cm) +use_birthday_firework(struct unit * u, const struct item_type * itype, int amount, const char *cm) { regionlist *rlist = all_in_range(u->region, FIREWORK_RANGE); regionlist *rl; message *m; char *name; + unused(amount); + name = getstrtoken(); /* "Zur Feier der Geburtstags von %name wird in %region ein großes @@ -68,7 +70,7 @@ use_birthday_firework(struct unit * u, const struct item_type * itype, const cha res_changeitem(u, itype->rtype, -1); - return -1; + return 0; } resource_type rt_birthday_firework = { @@ -83,6 +85,7 @@ item_type it_birthday_firework = { 0, 50, 0, /* flags, weight, capacity */ NULL, /* construction */ &use_birthday_firework, /* use */ + NULL, NULL /* give */ }; diff --git a/src/common/items/demonseye.c b/src/common/items/demonseye.c index e3d482986..60c93229c 100644 --- a/src/common/items/demonseye.c +++ b/src/common/items/demonseye.c @@ -26,9 +26,10 @@ #include static int -summon_igjarjuk(struct unit * u, const struct item_type * itype, const char * cmd) +summon_igjarjuk(struct unit * u, const struct item_type * itype, int amount, const char * cmd) { unused(u); + unused(amount); unused(itype); unused(cmd); assert(!"not implemented"); @@ -57,6 +58,7 @@ item_type it_demonseye = { ITF_NOTLOST|ITF_CURSED, 0, 0, /* flags, weight, capacity */ NULL, /* construction */ &summon_igjarjuk, + NULL, &give_igjarjuk }; diff --git a/src/common/items/xerewards.c b/src/common/items/xerewards.c index d5977ea19..3d6c75744 100644 --- a/src/common/items/xerewards.c +++ b/src/common/items/xerewards.c @@ -34,19 +34,22 @@ #include static int -use_skillpotion(struct unit * u, const struct item_type * itype, const char *cm) +use_skillpotion(struct unit * u, const struct item_type * itype, int amount, const char *cm) { - skill * sv = u->skills; - while (sv!=u->skills+u->skill_size) { - int i; - for (i=0;i!=3;++i) learn_skill(u, sv->id, 1.0); - ++sv; + int i; + for (i=0;i!=amount;++i) { + skill * sv = u->skills; + while (sv!=u->skills+u->skill_size) { + int i; + for (i=0;i!=3;++i) learn_skill(u, sv->id, 1.0); + ++sv; + } } add_message(&u->faction->msgs, new_message(u->faction, "skillpotion_use%u:unit", u)); - res_changeitem(u, itype->rtype, -1); - return -1; + res_changeitem(u, itype->rtype, -amount); + return 0; } static resource_type rt_skillpotion = { @@ -61,29 +64,31 @@ item_type it_skillpotion = { 0, 0, 0, /* flags, weight, capacity */ NULL, /* construction */ &use_skillpotion, + NULL, NULL }; static int -use_manacrystal(struct unit * u, const struct item_type * itype, const char *cm) +use_manacrystal(struct unit * u, const struct item_type * itype, int amount, const char *cm) { - int sp; + int i, sp = 0; if(!is_mage(u)) { cmistake(u, u->thisorder, 295, MSG_EVENT); return -1; } - sp = max(25, max_spellpoints(u->region, u)/2); - - change_spellpoints(u, sp); + for (i=0;i!=amount;++i) { + sp += max(25, max_spellpoints(u->region, u)/2); + change_spellpoints(u, sp); + } add_message(&u->faction->msgs, new_message(u->faction, "manacrystal_use%u:unit%i:aura", u, sp)); - res_changeitem(u, itype->rtype, -1); - return -1; + res_changeitem(u, itype->rtype, -amount); + return 0; } static resource_type rt_manacrystal = { @@ -98,6 +103,7 @@ item_type it_manacrystal = { 0, 0, 0, /* flags, weight, capacity */ NULL, /* construction */ &use_manacrystal, + NULL, NULL }; diff --git a/src/common/kernel/alchemy.c b/src/common/kernel/alchemy.c index 31c5e2f98..8800aecd5 100644 --- a/src/common/kernel/alchemy.c +++ b/src/common/kernel/alchemy.c @@ -85,7 +85,7 @@ attrib_type at_bauernblut = { }; int -use_potion(unit * u, const item_type * itype, const char * cmd) +use_potion(unit * u, const item_type * itype, int amount, const char * cmd) { const potion_type * ptype = resource2potion(itype->rtype); const potion_type * use = ugetpotionuse(u); @@ -100,7 +100,7 @@ use_potion(unit * u, const item_type * itype, const char * cmd) } if (ptype->use) { - int nRetval = ptype->use(u, ptype, cmd); + int nRetval = ptype->use(u, ptype, amount, cmd); if (nRetval) return nRetval; } else if (ptype==oldpotiontype[P_LIFE]) { region * r = u->region; diff --git a/src/common/kernel/alchemy.h b/src/common/kernel/alchemy.h index 13e4a3222..588cb2de1 100644 --- a/src/common/kernel/alchemy.h +++ b/src/common/kernel/alchemy.h @@ -77,7 +77,7 @@ enum { herb_t rherb2herb(struct region *r); void herbsearch(struct region * r, struct unit * u, int max); -int use_potion(struct unit * u, const struct item_type * itype, const char * cmd); +int use_potion(struct unit * u, const struct item_type * itype, int amount, const char * cmd); void init_potions(void); extern struct attrib_type at_bauernblut; diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 6b50b1b58..6ce2f2667 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1179,7 +1179,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile) if (df->person[dt.index].hp > 0) { /* Hat überlebt */ battledebug(debugbuf); - if (old_race(au->irace) == RC_DAEMON) { + if (old_race(au->race) == RC_DAEMON) { #ifdef TODO_RUNESWORD if (select_weapon(dt, 0, -1) == WP_RUNESWORD) continue; #endif diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index ec4f2b924..cae70d098 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -724,7 +724,7 @@ get_potion(const unit * u, potion_t p) return it?it->number:0; } -void use_birthdayamulet(region * r, unit * magician, strlist * cmdstrings); +void use_birthdayamulet(region * r, unit * magician, int amount, strlist * cmdstrings); enum { IS_RESOURCE, @@ -801,29 +801,30 @@ destroy_curse_crystal(attrib **alist, int cast_level, int force) /* Kann auch von Nichtmagier benutzt werden, erzeugt eine * Antimagiezone, die zwei Runden bestehen bleibt */ static void -use_antimagiccrystal(region * r, unit * mage, strlist * cmdstrings) +use_antimagiccrystal(region * r, unit * mage, int amount, strlist * cmdstrings) { - int effect; - int power; - int duration = 2; - spell *sp = find_spellbyid(SPL_ANTIMAGICZONE); - unused(cmdstrings); + int i; + for (i=0;i!=amount;++i) { + int effect, power, duration = 2; + spell *sp = find_spellbyid(SPL_ANTIMAGICZONE); + unused(cmdstrings); - /* Reduziert die Stärke jedes Spruchs um effect */ - effect = sp->level*4; /* Stufe 5 =~ 15 */ + /* Reduziert die Stärke jedes Spruchs um effect */ + effect = sp->level*4; /* Stufe 5 =~ 15 */ - /* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus. - * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone - * um seine Stufe */ - power = sp->level * 20; /* Stufe 5 =~ 100 */ + /* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus. + * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone + * um seine Stufe */ + power = sp->level * 20; /* Stufe 5 =~ 100 */ - power = destroy_curse(&r->attribs, effect, power, NULL); + power = destroy_curse(&r->attribs, effect, power, NULL); + + if(power) { + create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, power, duration, effect, 0); + } - if(power) { - create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, power, duration, effect, 0); } - - use_pooled(mage, mage->region, R_ANTIMAGICCRYSTAL, 1); + use_pooled(mage, mage->region, R_ANTIMAGICCRYSTAL, amount); add_message(&mage->faction->msgs, new_message(mage->faction, "use_antimagiccrystal%u:unit%r:region", mage, r)); return; @@ -833,19 +834,21 @@ use_antimagiccrystal(region * r, unit * mage, strlist * cmdstrings) /* Kann auch von Nichtmagier benutzt werden, modifiziert Taktik für diese * Runde um -1 - 4 Punkte. */ static void -use_tacticcrystal(region * r, unit * u, strlist * cmdstrings) +use_tacticcrystal(region * r, unit * u, int amount, strlist * cmdstrings) { - int effect = rand()%6 - 1; - int duration = 1; /* wirkt nur eine Runde */ - int power = 5; /* Widerstand gegen Antimagiesprüche, ist in diesem - Fall egal, da der curse für den Kampf gelten soll, - der vor den Antimagiezaubern passiert */ - unused(cmdstrings); + int i; + for (i=0;i!=amount;++i) { + int effect = rand()%6 - 1; + int duration = 1; /* wirkt nur eine Runde */ + int power = 5; /* Widerstand gegen Antimagiesprüche, ist in diesem + Fall egal, da der curse für den Kampf gelten soll, + der vor den Antimagiezaubern passiert */ + unused(cmdstrings); - create_curse(u, &u->attribs, C_SKILL, SK_TACTICS, power, - duration, effect, u->number); - - change_item(u, I_TACTICCRYSTAL, -1); + create_curse(u, &u->attribs, C_SKILL, SK_TACTICS, power, + duration, effect, u->number); + } + use_pooled(u, u->region, R_TACTICCRYSTAL, amount); add_message(&u->faction->msgs, new_message(u->faction, "use_tacticcrystal%u:unit%r:region", u, r)); return; @@ -1309,16 +1312,17 @@ use_oldresource(region * r, const resource_type * rtype, int norders) } static int -use_olditem(struct unit * user, const struct item_type * itype, const char * cmd) +use_olditem(struct unit * user, const struct item_type * itype, int amount, const char * cmd) { - item_t i; - for (i=0;i!=MAXITEMS;++i) { - if (olditemtype[i]==itype) { + item_t it; + for (it=0;it!=MAXITEMS;++it) { + if (olditemtype[it]==itype) { strlist * s = makestrlist(cmd); - itemdata[i].benutze_funktion(user->region, user, s); + itemdata[it].benutze_funktion(user->region, user, amount, s); + return 0; } } - return 0; + return EUNUSABLE; } typedef const char* translate_t[5]; @@ -1884,7 +1888,7 @@ const char *potiontext[MAXPOTIONS] = }; static int -use_warmthpotion(struct unit *u, const struct potion_type *ptype, const char *cmd) +use_warmthpotion(struct unit *u, const struct potion_type *ptype, int amount, const char *cmd) { assert(ptype==oldpotiontype[P_WARMTH]); if (old_race(u->faction->race) == RC_INSECT) { @@ -1899,26 +1903,46 @@ use_warmthpotion(struct unit *u, const struct potion_type *ptype, const char *cm } static int -use_bloodpotion(struct unit *u, const struct potion_type *ptype, const char *cmd) +use_foolpotion(struct unit *u, int targetno, const struct item_type *itype, int amount, const char *cmd) { + unit * target = findunit(targetno); + if (target==NULL || u->region!=target->region) { + cmistake(u, cmd, 63, MSG_EVENT); + return ECUSTOM; + } + /* TODO: wahrnehmung-check */ + ADDMSG(&u->faction->msgs, msg_message("givedumb", + "unit recipient amount", u, target, amount)); + assert(oldpotiontype[P_FOOL]->itype==itype); + change_effect(target, oldpotiontype[P_FOOL], amount); + return 0; +} + +static int +use_bloodpotion(struct unit *u, const struct potion_type *ptype, int amount, const char *cmd) +{ + int i; assert(ptype==oldpotiontype[P_BAUERNBLUT]); unused(ptype); - if (old_race(u->race) == RC_DAEMON) { - attrib * a = (attrib*)a_find(u->attribs, &at_bauernblut); - if (!a) a = a_add(&u->attribs, a_new(&at_bauernblut)); - a->data.i += 100; - } else { - /* bekommt nicht: */ - cmistake(u, cmd, 165, MSG_EVENT); - u->race = new_race[RC_GHOUL]; - u_setfaction(u, findfaction(MONSTER_FACTION)); + for (i=0;i!=amount;++i) { + if (old_race(u->race) == RC_DAEMON) { + attrib * a = (attrib*)a_find(u->attribs, &at_bauernblut); + if (!a) a = a_add(&u->attribs, a_new(&at_bauernblut)); + a->data.i += 100; + } else { + /* bekommt nicht: */ + cmistake(u, cmd, 165, MSG_EVENT); + u->race = new_race[RC_GHOUL]; + u_setfaction(u, findfaction(MONSTER_FACTION)); + break; + } } return 0; } #include static int -use_mistletoe(struct unit * user, const struct item_type * itype, const char * cmd) +use_mistletoe(struct unit * user, const struct item_type * itype, int amount, const char * cmd) { int mtoes = new_get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK); @@ -2012,9 +2036,10 @@ init_oldpotions(void) oldpotiontype[p] = new_potiontype(itype, (terrain_t)p/3); oldpotiontype[p]->level = potionlevel[p]; oldpotiontype[p]->text = potiontext[p]; + if (p==P_FOOL) itype->useonother = &use_foolpotion; } oldpotiontype[P_WARMTH]->use = &use_warmthpotion; - oldpotiontype[P_BAUERNBLUT]->use = &use_bloodpotion; + oldpotiontype[P_BAUERNBLUT]->use = &use_bloodpotion; } resource_type * r_silver; @@ -2486,7 +2511,7 @@ it_read(FILE * F) if (!strcmp(semi, "give")) it->give = (int (*)(const unit*, const unit*, const struct item_type *, int, const char *))get_function(s); break; case 'u': - if (!strcmp(semi, "use")) it->use = (int (*)(unit *, const struct item_type *, const char *))get_function(s); + if (!strcmp(semi, "use")) it->use = (int (*)(unit *, const struct item_type *, int, const char *))get_function(s); break; case 'w': if (!strcmp(semi, "weight")) it->weight=i; @@ -2540,6 +2565,7 @@ register_resources(void) register_function((pf_generic)use_antimagiccrystal, "useantimagiccrystal"); register_function((pf_generic)use_warmthpotion, "usewarmthpotion"); register_function((pf_generic)use_bloodpotion, "usebloodpotion"); + register_function((pf_generic)use_foolpotion, "usefoolpotion"); register_function((pf_generic)use_mistletoe, "usemistletoe"); register_function((pf_generic)give_horses, "givehorses"); diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index ebed3e7e2..8c75ceb28 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -121,7 +121,8 @@ typedef struct item_type { int capacity; const struct construction * construction; /* --- functions --- */ - int (*use)(struct unit * user, const struct item_type * itype, const char * cmd); + int (*use)(struct unit * user, const struct item_type * itype, int amount, const char * cmd); + int (*useonother)(struct unit * user, int targetno, const struct item_type * itype, int amount, const char * cmd); int (*give)(const struct unit * src, const struct unit * dest, const struct item_type * itm, int number, const char * cmd); struct item_type * next; } item_type; @@ -148,7 +149,7 @@ typedef struct potion_type { const item_type * itype; int level; const char * text; - int (*use)(struct unit *, const struct potion_type *, const char *); + int (*use)(struct unit *, const struct potion_type *, int, const char *); } potion_type; extern potion_type * potiontypes; @@ -272,7 +273,7 @@ typedef struct t_item { int gewicht; int preis; unsigned int flags; - void (*benutze_funktion) (struct region *, struct unit *, strlist *); + void (*benutze_funktion) (struct region *, struct unit *, int amount, strlist *); } t_item; enum { diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index bf8ded194..d5dcf80a2 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -84,10 +84,11 @@ leave_fail(unit * u) { } static int -leave_arena(struct unit * u, const struct item_type * itype, const char * cmd) +leave_arena(struct unit * u, const struct item_type * itype, int amount, const char * cmd) { if (!u->building && leave_fail(u)) return -1; if (u->building!=arena_tower(u->faction->magiegebiet) && leave_fail(u)) return -1; + unused(amount); unused(cmd); unused(itype); assert(!"not implemented"); @@ -106,6 +107,7 @@ static item_type it_gryphonwing = { ITF_NOTLOST|ITF_CURSED, 0, 0, /* flags, weight, capacity */ NULL, /* construction */ &leave_arena, + NULL, &give_igjarjuk }; @@ -117,13 +119,14 @@ enter_fail(unit * u) { } static int -enter_arena(unit * u, const item_type * itype, const char * cmd) +enter_arena(unit * u, const item_type * itype, int amount, const char * cmd) { skill_t sk; region * r = u->region; unit * u2; int fee = u->faction->score / 5; unused(cmd); + unused(amount); unused(itype); if (fee>2000) fee = 2000; if (getplane(r)==arena) return -1; @@ -180,23 +183,22 @@ static item_type it_arenagate = { ***/ static int -use_wand_of_tears(unit * user, const struct item_type * itype, const char * cmd) +use_wand_of_tears(unit * user, const struct item_type * itype, int amount, const char * cmd) { - unit * u; + int i; unused(cmd); - for (u=user->region->units;u;u=u->next) { - if (u->faction != user->faction) { - int i, k=SKILLPOINTS; + for (i=0;i!=amount;++i) { + unit * u; + for (u=user->region->units;u;u=u->next) { + if (u->faction != user->faction) { + int i; - for (i=0;i!=u->skill_size;++i) { -#if SKILLPOINTS - change_skill(u, u->skills[i].id, -10); -#else - if (rand()%3) reduce_skill(u, u->skills+i, 1); -#endif + for (i=0;i!=u->skill_size;++i) { + if (rand()%3) reduce_skill(u, u->skills+i, 1); + } + ADDMSG(&u->faction->msgs, msg_message("wand_of_tears_effect", + "unit", u)); } - if (k) ADDMSG(&u->faction->msgs, msg_message("wand_of_tears_effect", - "unit", u)); } } ADDMSG(&user->region->msgs, msg_message("wand_of_tears_usage", diff --git a/src/common/modules/museum.c b/src/common/modules/museum.c index 69b1866bc..8c1a03a0f 100644 --- a/src/common/modules/museum.c +++ b/src/common/modules/museum.c @@ -316,11 +316,13 @@ create_museum(void) } int -use_museumticket(unit *u, const struct item_type *itype, const char * cmd) +use_museumticket(unit *u, const struct item_type *itype, int amount, const char * cmd) { attrib *a; region *r = u->region; + unused(amount); + /* Prüfen ob in normaler Plane und nur eine Person */ if(r->planep != NULL) { cmistake(u, cmd, 265, MSG_MAGIC); @@ -355,13 +357,15 @@ use_museumticket(unit *u, const struct item_type *itype, const char * cmd) } int -use_museumexitticket(unit *u, const struct item_type *itype, const char * cmd) +use_museumexitticket(unit *u, const struct item_type *itype, int amount, const char * cmd) { attrib *a; region *r; unit *warden = findunit(atoi36("mwar")); int unit_cookie; + unused(amount); + /* Prüfen ob in Eingangshalle */ if(u->region->x != 9525 || u->region->y != 9525) { cmistake(u, cmd, 266, MSG_MAGIC); diff --git a/src/common/modules/museum.h b/src/common/modules/museum.h index 5b1b96ef8..33ff3f61b 100644 --- a/src/common/modules/museum.h +++ b/src/common/modules/museum.h @@ -30,6 +30,6 @@ typedef struct { void warden_add_give(struct unit *src, struct unit *u, const struct item_type *itype, int n); void init_museum(void); void create_museum(void); -int use_museumticket(struct unit *u, const struct item_type *itype, const char *cmd); -int use_museumexitticket(struct unit *u, const struct item_type *itype, const char * cmd); +int use_museumticket(struct unit *u, const struct item_type *itype, int amount, const char *cmd); +int use_museumexitticket(struct unit *u, const struct item_type *itype, int amount, const char * cmd); diff --git a/src/res/de/messages.xml b/src/res/de/messages.xml index dc4c2c174..08caa83db 100644 --- a/src/res/de/messages.xml +++ b/src/res/de/messages.xml @@ -4376,11 +4376,10 @@ - - "$unit($unit) gibt $unit($recipient) $int($amount) Dumpfbackenbrot: ${discover}." + "$unit($unit) gibt $unit($recipient) $int($amount) Dumpfbackenbrot."