start removing dependencies on potion_type.

use item_type where we can. does not compile, is WIP.
This commit is contained in:
Enno Rehling 2018-01-12 09:17:01 +01:00
parent 9dbe1d65b2
commit 915a924fcb
19 changed files with 191 additions and 194 deletions

View File

@ -48,7 +48,41 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
#include <assert.h>
/* ------------------------------------------------------------- */
typedef struct potion_type {
struct potion_type *next;
const struct item_type *itype;
int level;
} potion_type;
static potion_type *potiontypes;
static void pt_register(potion_type * ptype)
{
ptype->next = potiontypes;
potiontypes = ptype;
}
void new_potiontype(item_type * itype, int level)
{
potion_type *ptype;
ptype = (potion_type *)calloc(sizeof(potion_type), 1);
itype->flags |= ITF_POTION;
ptype->itype = itype;
ptype->level = level;
pt_register(ptype);
}
int potion_level(const item_type *itype)
{
potion_type *ptype;
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (ptype->itype == itype) {
return ptype->level;
}
}
return 0;
}
void herbsearch(unit * u, int max_take)
{
@ -95,33 +129,37 @@ void herbsearch(unit * u, int max_take)
}
}
static int begin_potion(unit * u, const potion_type * ptype, struct order *ord)
static int begin_potion(unit * u, const item_type * itype, struct order *ord)
{
bool rule_multipotion;
assert(ptype != NULL);
static int config;
static bool rule_multipotion;
assert(itype);
if (config_changed(&config)) {
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
}
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
if (!rule_multipotion) {
const potion_type *use = ugetpotionuse(u);
if (use != NULL && use != ptype) {
const item_type *use = ugetpotionuse(u);
if (use != NULL && use != itype) {
ADDMSG(&u->faction->msgs,
msg_message("errusingpotion", "unit using command",
u, use->itype->rtype, ord));
u, use->rtype, ord));
return ECUSTOM;
}
}
return 0;
}
static void end_potion(unit * u, const potion_type * ptype, int amount)
static void end_potion(unit * u, const item_type * itype, int amount)
{
use_pooled(u, ptype->itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
amount);
usetpotionuse(u, ptype);
usetpotionuse(u, itype);
ADDMSG(&u->faction->msgs, msg_message("usepotion",
"unit potion", u, ptype->itype->rtype));
"unit potion", u, itype->rtype));
}
static int potion_water_of_life(unit * u, region *r, int amount) {
@ -157,6 +195,22 @@ static int potion_water_of_life(unit * u, region *r, int amount) {
return amount;
}
void show_potions(faction *f, int sklevel)
{
const potion_type *ptype;
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (ptype->level > 0 && sklevel == ptype->level * 2) {
attrib *a = a_find(f->attribs, &at_showitem);
while (a && a->type == &at_showitem && a->data.v != ptype)
a = a->next;
if (a == NULL || a->type != &at_showitem) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
}
}
}
}
static int potion_healing(unit * u, int amount) {
int maxhp = unit_max_hp(u) * u->number;
u->hp = u->hp + 400 * amount;
@ -185,42 +239,40 @@ static int potion_power(unit *u, int amount) {
return amount;
}
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount)
static int do_potion(unit * u, region *r, const item_type * itype, int amount)
{
if (ptype == oldpotiontype[P_LIFE]) {
if (itype == oldpotiontype[P_LIFE]) {
return potion_water_of_life(u, r, amount);
}
else if (ptype == oldpotiontype[P_HEILWASSER]) {
else if (itype == oldpotiontype[P_HEILWASSER]) {
return potion_healing(u, amount);
}
else if (ptype == oldpotiontype[P_PEOPLE]) {
else if (itype == oldpotiontype[P_PEOPLE]) {
return potion_luck(u, r, &at_peasantluck, amount);
}
else if (ptype == oldpotiontype[P_HORSE]) {
else if (itype == oldpotiontype[P_HORSE]) {
return potion_luck(u, r, &at_horseluck, amount);
}
else if (ptype == oldpotiontype[P_MACHT]) {
else if (itype == oldpotiontype[P_MACHT]) {
return potion_power(u, amount);
}
else {
change_effect(u, ptype, 10 * amount);
change_effect(u, itype, 10 * amount);
}
return amount;
}
int use_potion(unit * u, const item_type * itype, int amount, struct order *ord)
{
const potion_type *ptype = resource2potion(itype->rtype);
if (oldpotiontype[P_HEAL] && ptype == oldpotiontype[P_HEAL]) {
if (oldpotiontype[P_HEAL] && itype == oldpotiontype[P_HEAL]) {
return EUNUSABLE;
}
else {
int result = begin_potion(u, ptype, ord);
int result = begin_potion(u, itype, ord);
if (result)
return result;
amount = do_potion(u, u->region, ptype, amount);
end_potion(u, ptype, amount);
amount = do_potion(u, u->region, itype, amount);
end_potion(u, itype, amount);
}
return 0;
}
@ -228,7 +280,7 @@ int use_potion(unit * u, const item_type * itype, int amount, struct order *ord)
typedef struct potiondelay {
unit *u;
region *r;
const potion_type *ptype;
const item_type *itype;
int amount;
} potiondelay;
@ -245,7 +297,7 @@ static int age_potiondelay(attrib * a, void *owner)
{
potiondelay *pd = (potiondelay *)a->data.v;
UNUSED_ARG(owner);
pd->amount = do_potion(pd->u, pd->r, pd->ptype, pd->amount);
pd->amount = do_potion(pd->u, pd->r, pd->itype, pd->amount);
return AT_AGE_REMOVE;
}
@ -256,13 +308,13 @@ attrib_type at_potiondelay = {
age_potiondelay, 0, 0
};
static attrib *make_potiondelay(unit * u, const potion_type * ptype, int amount)
static attrib *make_potiondelay(unit * u, const item_type * itype, int amount)
{
attrib *a = a_new(&at_potiondelay);
potiondelay *pd = (potiondelay *)a->data.v;
pd->u = u;
pd->r = u->region;
pd->ptype = ptype;
pd->itype = itype;
pd->amount = amount;
return a;
}
@ -271,14 +323,13 @@ int
use_potion_delayed(unit * u, const item_type * itype, int amount,
struct order *ord)
{
const potion_type *ptype = resource2potion(itype->rtype);
int result = begin_potion(u, ptype, ord);
int result = begin_potion(u, itype, ord);
if (result)
return result;
a_add(&u->attribs, make_potiondelay(u, ptype, amount));
a_add(&u->attribs, make_potiondelay(u, itype, amount));
end_potion(u, ptype, amount);
end_potion(u, itype, amount);
return 0;
}
@ -301,7 +352,7 @@ a_writeeffect(const attrib * a, const void *owner, struct storage *store)
{
effect_data *edata = (effect_data *)a->data.v;
UNUSED_ARG(owner);
WRITE_TOK(store, resourcename(edata->type->itype->rtype, 0));
WRITE_TOK(store, resourcename(edata->type->rtype, 0));
WRITE_INT(store, edata->value);
}
@ -318,14 +369,16 @@ static int a_readeffect(attrib * a, void *owner, struct gamedata *data)
rtype = rt_find(zText);
READ_INT(store, &power);
if (rtype == NULL || rtype->ptype == NULL || power <= 0) {
if (rtype == NULL || rtype->itype == NULL || power <= 0) {
return AT_READ_FAIL;
}
if (rtype->ptype==oldpotiontype[P_HEAL]) {
/* healing potions used to have long-term effects */
return AT_READ_FAIL;
if (data->version < NOLANDITEM_VERSION) {
if (rtype->itype == oldpotiontype[P_HEAL]) {
/* healing potions used to have long-term effects */
return AT_READ_FAIL;
}
}
edata->type = rtype->ptype;
edata->type = rtype->itype;
edata->value = power;
return AT_READ_OK;
}
@ -339,7 +392,7 @@ attrib_type at_effect = {
a_readeffect,
};
int get_effect(const unit * u, const potion_type * effect)
int get_effect(const unit * u, const item_type * effect)
{
const attrib *a;
for (a = a_find(u->attribs, &at_effect); a != NULL && a->type == &at_effect;
@ -351,7 +404,7 @@ int get_effect(const unit * u, const potion_type * effect)
return 0;
}
int change_effect(unit * u, const potion_type * effect, int delta)
int change_effect(unit * u, const item_type * effect, int delta)
{
if (delta != 0) {
attrib *a = a_find(u->attribs, &at_effect);

View File

@ -26,9 +26,12 @@ extern "C" {
struct potion_type;
struct unit;
struct region;
struct faction;
struct item_type;
struct order;
extern struct attrib_type at_effect;
enum {
/* Stufe 1 */
P_FAST,
@ -52,22 +55,23 @@ extern "C" {
MAX_POTIONS
};
void new_potiontype(struct item_type * itype, int level);
int potion_level(const struct item_type *itype);
void show_potions(struct faction *f, int sklevel);
void herbsearch(struct unit *u, int max);
extern int use_potion(struct unit *u, const struct item_type *itype,
int use_potion(struct unit *u, const struct item_type *itype,
int amount, struct order *);
extern int use_potion_delayed(struct unit *u, const struct item_type *itype,
int use_potion_delayed(struct unit *u, const struct item_type *itype,
int amount, struct order *);
extern void init_potions(void);
extern int get_effect(const struct unit *u, const struct potion_type *effect);
extern int change_effect(struct unit *u, const struct potion_type *effect,
int get_effect(const struct unit *u, const struct item_type *effect);
int change_effect(struct unit *u, const struct item_type *effect,
int value);
extern struct attrib_type at_effect;
/* rausnehmen, sobald man attribute splitten kann: */
typedef struct effect_data {
const struct potion_type *type;
const struct item_type *type;
int value;
} effect_data;

View File

@ -1298,11 +1298,11 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
}
if (oldpotiontype[P_HEAL] && !fval(&df->person[dt.index], FL_HEALING_USED)) {
if (i_get(du->items, oldpotiontype[P_HEAL]->itype) > 0) {
if (i_get(du->items, oldpotiontype[P_HEAL]) > 0) {
message *m = msg_message("potionsave", "unit", du);
battle_message_faction(b, du->faction, m);
msg_release(m);
i_change(&du->items, oldpotiontype[P_HEAL]->itype, -1);
i_change(&du->items, oldpotiontype[P_HEAL], -1);
fset(&df->person[dt.index], FL_HEALING_USED);
df->person[dt.index].hp = u_race(du)->hitpoints * 5; /* give the person a buffer */
return false;

View File

@ -366,13 +366,10 @@ static int tolua_unit_get_effect(lua_State * L)
const unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *potion_name = tolua_tostring(L, 2, 0);
int result = -1;
const potion_type *pt_potion;
const item_type *it_potion = it_find(potion_name);
if (it_potion != NULL) {
pt_potion = it_potion->rtype->ptype;
if (pt_potion != NULL)
result = get_effect(self, pt_potion);
result = get_effect(self, it_potion);
}
lua_pushinteger(L, result);

View File

@ -276,7 +276,7 @@ cr_output_curses(struct stream *out, const faction * viewer, const void *obj, ob
else if (a->type == &at_effect && self) {
effect_data *data = (effect_data *)a->data.v;
if (data->value > 0) {
const char *key = resourcename(data->type->itype->rtype, 0);
const char *key = resourcename(data->type->rtype, 0);
if (!header) {
header = 1;
stream_printf(out, "EFFECTS\n");
@ -1652,27 +1652,26 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
}
for (a = a_find(f->attribs, &at_showitem); a && a->type == &at_showitem;
a = a->next) {
const potion_type *ptype =
resource2potion(((const item_type *)a->data.v)->rtype);
const item_type *itype = (const item_type *)a->data.v;
const char *ch;
const char *description = NULL;
if (ptype == NULL)
if (itype == NULL)
continue;
ch = resourcename(ptype->itype->rtype, 0);
ch = resourcename(itype->rtype, 0);
fprintf(F, "TRANK %d\n", str_hash(ch));
fprintf(F, "\"%s\";Name\n", translate(ch, LOC(f->locale, ch)));
fprintf(F, "%d;Stufe\n", ptype->level);
fprintf(F, "%d;Stufe\n", potion_level(itype));
if (description == NULL) {
const char *pname = resourcename(ptype->itype->rtype, 0);
const char *pname = resourcename(itype->rtype, 0);
const char *potiontext = mkname("potion", pname);
description = LOC(f->locale, potiontext);
}
fprintf(F, "\"%s\";Beschr\n", description);
if (ptype->itype->construction) {
requirement *m = ptype->itype->construction->materials;
if (itype->construction) {
requirement *m = itype->construction->materials;
fprintf(F, "ZUTATEN\n");

View File

@ -1233,14 +1233,14 @@ void split_allocations(region * r)
allocations = NULL;
}
static void create_potion(unit * u, const potion_type * ptype, int want)
static void create_potion(unit * u, const item_type * itype, int want)
{
int built;
if (want == 0) {
want = maxbuild(u, ptype->itype->construction);
want = maxbuild(u, itype->construction);
}
built = build(u, ptype->itype->construction, 0, want, 0);
built = build(u, itype->construction, 0, want, 0);
switch (built) {
case ELOWSKILL:
case ENEEDSKILL:
@ -1253,16 +1253,16 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
case ENOMATERIALS:
/* something missing from the list of materials */
ADDMSG(&u->faction->msgs, msg_materials_required(u, u->thisorder,
ptype->itype->construction, want));
itype->construction, want));
return;
break;
default:
i_change(&u->items, ptype->itype, built);
i_change(&u->items, itype, built);
if (want == INT_MAX)
want = built;
ADDMSG(&u->faction->msgs, msg_message("produce",
"unit region amount wanted resource", u, u->region, built, want,
ptype->itype->rtype));
itype->rtype));
break;
}
}
@ -1277,11 +1277,12 @@ void make_item(unit * u, const item_type * itype, int want)
allocate_resource(u, itype->rtype, want);
}
else {
const potion_type *ptype = resource2potion(itype->rtype);
if (ptype != NULL)
create_potion(u, ptype, want);
else if (itype->construction && itype->construction->materials)
if (itype->flags & ITF_POTION) {
create_potion(u, itype, want);
}
else if (itype->construction && itype->construction->materials) {
manufacture(u, itype, want);
}
else {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
"error_cannotmake", ""));

View File

@ -281,7 +281,7 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord)
return result;
}
lua_pop(L, 1);
if (itype->rtype->ptype) {
if (itype->flags & ITF_POTION) {
return use_potion(u, itype, amount, ord);
} else {
log_error("no such callout: %s", fname);

View File

@ -268,7 +268,7 @@ static int use_foolpotion(unit *u, const item_type *itype, int amount,
ADDMSG(&u->faction->msgs, msg_message("givedumb",
"unit recipient amount", u, target, amount));
change_effect(target, itype->rtype->ptype, amount);
change_effect(target, itype, amount);
use_pooled(u, itype->rtype, GET_DEFAULT, amount);
return 0;
}
@ -278,7 +278,7 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount,
struct order *ord)
{
if (u->number == 0 || u_race(u) == get_race(RC_DAEMON)) {
change_effect(u, itype->rtype->ptype, 100 * amount);
change_effect(u, itype, 100 * amount);
}
else {
const race *irace = u_irace(u);
@ -302,7 +302,7 @@ struct order *ord)
}
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
amount);
usetpotionuse(u, itype->rtype->ptype);
usetpotionuse(u, itype);
ADDMSG(&u->faction->msgs, msg_message("usepotion",
"unit potion", u, itype->rtype));
@ -335,7 +335,7 @@ struct order *ord)
}
use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
amount);
usetpotionuse(user, itype->rtype->ptype);
usetpotionuse(user, itype);
ADDMSG(&user->faction->msgs, msg_message("usepotion",
"unit potion", user, itype->rtype));
@ -408,7 +408,7 @@ static int use_warmthpotion(unit *u, const item_type *itype,
}
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
amount);
usetpotionuse(u, itype->rtype->ptype);
usetpotionuse(u, itype);
ADDMSG(&u->faction->msgs, msg_message("usepotion",
"unit potion", u, itype->rtype));

View File

@ -160,12 +160,12 @@ static void test_build_with_ring(CuTest *tc) {
static void test_build_with_potion(CuTest *tc) {
build_fixture bf = { 0 };
unit *u;
const potion_type *ptype;
const item_type *ptype;
const struct resource_type *rtype;
u = setup_build(&bf);
rtype = bf.cons.materials[0].rtype;
oldpotiontype[P_DOMORE] = ptype = new_potiontype(it_get_or_create(rt_get_or_create("hodor")), 1);
oldpotiontype[P_DOMORE] = ptype = it_get_or_create(rt_get_or_create("hodor"));
assert(rtype && ptype);
i_change(&u->items, rtype->itype, 20);

View File

@ -60,7 +60,6 @@ static critbit_tree inames[MAXLOCALES];
static critbit_tree rnames[MAXLOCALES];
static critbit_tree cb_resources;
luxury_type *luxurytypes;
potion_type *potiontypes;
#define RTYPENAMELEN 24
typedef struct rt_entry {
@ -315,28 +314,8 @@ armor_type *new_armortype(item_type * itype, double penalty, variant magres,
return atype;
}
static void pt_register(potion_type * ptype)
void it_set_appearance(item_type *itype, const char *appearance)
{
ptype->itype->rtype->ptype = ptype;
ptype->next = potiontypes;
potiontypes = ptype;
}
potion_type *new_potiontype(item_type * itype, int level)
{
potion_type *ptype;
assert(resource2potion(itype->rtype) == NULL);
ptype = (potion_type *)calloc(sizeof(potion_type), 1);
ptype->itype = itype;
ptype->level = level;
pt_register(ptype);
return ptype;
}
void it_set_appearance(item_type *itype, const char *appearance) {
assert(itype);
assert(itype->rtype);
if (appearance) {
@ -377,18 +356,6 @@ const luxury_type *resource2luxury(const resource_type * rtype)
#endif
}
const potion_type *resource2potion(const resource_type * rtype)
{
#ifdef AT_PTYPE
attrib *a = a_find(rtype->attribs, &at_ptype);
if (a)
return (const potion_type *)a->data.v;
return NULL;
#else
return rtype->ptype;
#endif
}
resource_type *rt_find(const char *name)
{
const void *match;
@ -573,7 +540,7 @@ item *i_new(const item_type * itype, int size)
return i;
}
const potion_type *oldpotiontype[MAX_POTIONS + 1];
const item_type *oldpotiontype[MAX_POTIONS + 1];
/*** alte items ***/
@ -677,7 +644,7 @@ static void init_oldpotions(void)
for (p = 0; p != MAX_POTIONS; ++p) {
item_type *itype = it_find(potionnames[p]);
if (itype != NULL) {
oldpotiontype[p] = itype->rtype->ptype;
oldpotiontype[p] = itype;
}
}
}

View File

@ -80,7 +80,6 @@ extern "C" {
struct resource_mod *modifiers;
/* --- pointers --- */
struct item_type *itype;
struct potion_type *ptype;
struct luxury_type *ltype;
struct weapon_type *wtype;
struct armor_type *atype;
@ -99,6 +98,7 @@ extern "C" {
#define ITF_ANIMAL 0x0010 /* an animal */
#define ITF_VEHICLE 0x0020 /* a vehicle, drawn by two animals */
#define ITF_CANUSE 0x0040 /* can be used with use_item_fun callout */
#define ITF_POTION 0x0080 /* is a potion (for use_potion) */
/* error codes for item_type::use */
#define ECUSTOM -1
@ -128,13 +128,6 @@ extern "C" {
} luxury_type;
extern luxury_type *luxurytypes;
typedef struct potion_type {
struct potion_type *next;
const item_type *itype;
int level;
} potion_type;
extern potion_type *potiontypes;
#define WMF_WALKING 0x0001
#define WMF_RIDING 0x0002
#define WMF_ANYONE 0x000F /* convenience */
@ -206,7 +199,6 @@ extern "C" {
const resource_type *item2resource(const item_type * i);
const weapon_type *resource2weapon(const resource_type * i);
const potion_type *resource2potion(const resource_type * i);
const luxury_type *resource2luxury(const resource_type * i);
item **i_find(item ** pi, const item_type * it);
@ -234,8 +226,6 @@ extern "C" {
skill_t sk);
armor_type *new_armortype(item_type * itype, double penalty,
variant magres, int prot, unsigned int flags);
potion_type *new_potiontype(item_type * itype, int level);
/* these constants are used with get_resourcetype.
* The order of the enum is not important for stored data.
@ -285,7 +275,7 @@ extern "C" {
NORESOURCE = -1
} resource_t;
extern const struct potion_type *oldpotiontype[];
extern const struct item_type *oldpotiontype[];
const struct resource_type *get_resourcetype(resource_t rt);
struct item *item_spoil(const struct race *rc, int size);

View File

@ -585,7 +585,7 @@ attrib_type at_potionuser = {
NO_READ
};
void usetpotionuse(unit * u, const potion_type * ptype)
void usetpotionuse(unit * u, const item_type * ptype)
{
attrib *a = a_find(u->attribs, &at_potionuser);
if (!a)
@ -593,12 +593,12 @@ void usetpotionuse(unit * u, const potion_type * ptype)
a->data.v = (void *)ptype;
}
const potion_type *ugetpotionuse(const unit * u)
const item_type *ugetpotionuse(const unit * u)
{
attrib *a = a_find(u->attribs, &at_potionuser);
if (!a)
return NULL;
return (const potion_type *)a->data.v;
return (const item_type *)a->data.v;
}
/*********************/

View File

@ -28,11 +28,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
#define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
struct skill;
struct item;
struct sc_mage;
struct gamedata;
struct item_type;
#define MAXUNITS 1048573 /* should be prime for hashing. 524287 was >90% full */
#define UFL_DEAD (1<<0)
#define UFL_ISNEW (1<<1) /* 2 */
#define UFL_LONGACTION (1<<2) /* 4 */
@ -147,8 +150,8 @@ extern "C" {
const char *uprivate(const struct unit *u);
void usetprivate(struct unit *u, const char *c);
const struct potion_type *ugetpotionuse(const struct unit *u); /* benutzt u einein trank? */
void usetpotionuse(struct unit *u, const struct potion_type *p); /* u benutzt trank p (es darf halt nur einer pro runde) */
const struct item_type *ugetpotionuse(const struct unit *u); /* benutzt u einein trank? */
void usetpotionuse(struct unit *u, const struct item_type *p); /* u benutzt trank p (es darf halt nur einer pro runde) */
bool ucontact(const struct unit *u, const struct unit *u2);
void usetcontact(struct unit *u, const struct unit *c);

View File

@ -101,11 +101,11 @@ static void test_remove_units_with_dead_faction(CuTest *tc) {
static void test_scale_number(CuTest *tc) {
unit *u;
const struct potion_type *ptype;
const struct item_type *ptype;
test_setup();
test_create_world();
ptype = new_potiontype(it_get_or_create(rt_get_or_create("hodor")), 1);
ptype = it_get_or_create(rt_get_or_create("hodor"));
u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
change_effect(u, ptype, 1);
u->hp = 35;

View File

@ -2252,17 +2252,17 @@ static void display_item(unit * u, const item_type * itype)
itype->weight, itype->rtype, info));
}
static void display_potion(unit * u, const potion_type * ptype)
static void display_potion(unit * u, const item_type * itype)
{
faction * f = u->faction;
attrib *a;
a = a_find(f->attribs, &at_showitem);
while (a && a->data.v != ptype)
while (a && a->data.v != itype)
a = a->next;
if (!a) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
a->data.v = (void *)itype;
}
}
@ -2429,21 +2429,16 @@ static void reshow_other(unit * u, struct order *ord, const char *s) {
err = 36; /* we do not have this item? */
if (i <= 0) {
/* we don't have the item, but it may be a potion that we know */
const potion_type *ptype = resource2potion(item2resource(itype));
if (ptype) {
if (2 * ptype->level > effskill(u, SK_ALCHEMY, 0)) {
itype = NULL;
}
} else {
int level = potion_level(itype);
if (2 * level > effskill(u, SK_ALCHEMY, 0)) {
itype = NULL;
}
}
}
if (itype) {
const potion_type *ptype = itype->rtype->ptype;
if (ptype) {
display_potion(u, ptype);
if (itype->flags & ITF_POTION) {
display_potion(u, itype);
}
else {
display_item(u, itype);
@ -2471,26 +2466,30 @@ static void reshow_other(unit * u, struct order *ord, const char *s) {
cmistake(u, ord, err, MSG_EVENT);
}
bool display_potions(unit *u)
{
int skill = effskill(u, SK_ALCHEMY, 0);
int c = 0;
const potion_type *ptype;
for (ptype = potiontypes; ptype != NULL; ptype = ptype->next) {
if (ptype->level * 2 <= skill) {
display_potion(u, ptype);
++c;
}
}
return (c > 0);
}
static void reshow(unit * u, struct order *ord, const char *s, param_t p)
{
int skill, c;
const potion_type *ptype;
switch (p) {
case P_ZAUBER:
a_removeall(&u->faction->attribs, &at_seenspell);
break;
case P_POTIONS:
skill = effskill(u, SK_ALCHEMY, 0);
c = 0;
for (ptype = potiontypes; ptype != NULL; ptype = ptype->next) {
if (ptype->level * 2 <= skill) {
display_potion(u, ptype);
++c;
}
}
if (c == 0)
if (!display_potions(u)) {
cmistake(u, ord, 285, MSG_EVENT);
}
break;
case NOPARAM:
reshow_other(u, ord, s);

View File

@ -578,7 +578,7 @@ nr_curses_i(struct stream *out, int indent, const faction *viewer, objtype_t typ
effect_data *data = (effect_data *)a->data.v;
if (data->value > 0) {
msg = msg_message("nr_potion_effect", "potion left",
data->type->itype->rtype, data->value);
data->type->rtype, data->value);
}
}
if (msg) {
@ -2198,11 +2198,10 @@ report_plaintext(const char *filename, report_context * ctx,
CHECK_ERRNO();
for (a = a_find(f->attribs, &at_showitem); a && a->type == &at_showitem;
a = a->next) {
const potion_type *ptype =
resource2potion(((const item_type *)a->data.v)->rtype);
const item_type *itype = (const item_type *)a->data.v;
const char *description = NULL;
if (ptype != NULL) {
const char *pname = resourcename(ptype->itype->rtype, 0);
if (itype) {
const char *pname = resourcename(itype->rtype, 0);
if (ch == 0) {
newline(out);
@ -2213,7 +2212,7 @@ report_plaintext(const char *filename, report_context * ctx,
newline(out);
centre(out, LOC(f->locale, pname), true);
snprintf(buf, sizeof(buf), "%s %d", LOC(f->locale, "nr_level"),
ptype->level);
potion_level(itype));
centre(out, buf, true);
newline(out);
@ -2223,8 +2222,8 @@ report_plaintext(const char *filename, report_context * ctx,
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
if (ptype->itype->construction) {
requirement *rm = ptype->itype->construction->materials;
if (itype->construction) {
requirement *rm = itype->construction->materials;
while (rm->number) {
bytes =
(int)str_strlcpy(bufp, LOC(f->locale, resourcename(rm->rtype, 0)), size);

View File

@ -779,21 +779,10 @@ int study_cmd(unit * u, order * ord)
/* Spruchlistenaktualiesierung ist in Regeneration */
if (sk == SK_ALCHEMY) {
const potion_type *ptype;
faction *f = u->faction;
int skill = effskill(u, SK_ALCHEMY, 0);
if (skill > maxalchemy) {
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (skill == ptype->level * 2) {
a = a_find(f->attribs, &at_showitem);
while (a && a->type == &at_showitem && a->data.v != ptype)
a = a->next;
if (a == NULL || a->type != &at_showitem) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
}
}
}
show_potions(f, skill);
}
}
else if (sk == SK_MAGIC) {

View File

@ -245,26 +245,22 @@ void get_food(region * r)
int hungry = u->number;
/* use peasantblood before eating the peasants themselves */
const struct potion_type *pt_blood = 0;
const resource_type *rt_blood = rt_find("peasantblood");
if (rt_blood) {
pt_blood = rt_blood->ptype;
}
if (pt_blood) {
const struct item_type *it_blood = it_find("peasantblood");
if (it_blood) {
/* always start with the unit itself, then the first known unit that may have some blood */
unit *donor = u;
while (donor != NULL && hungry > 0) {
int blut = get_effect(donor, pt_blood);
int blut = get_effect(donor, it_blood);
if (hungry < blut) blut = hungry;
if (blut > 0) {
change_effect(donor, pt_blood, -blut);
change_effect(donor, it_blood, -blut);
hungry -= blut;
}
if (donor == u)
donor = r->units;
while (donor != NULL) {
if (u_race(donor) == rc_demon && donor != u) {
if (get_effect(donor, pt_blood)) {
if (get_effect(donor, it_blood)) {
/* if he's in our faction, drain him: */
if (donor->faction == u->faction)
break;

View File

@ -133,8 +133,8 @@ damage_unit(unit * u, const char *dam, bool physical, bool magic)
change_effect(u, oldpotiontype[P_HEAL], -1);
heiltrank = 1;
}
else if (i_get(u->items, oldpotiontype[P_HEAL]->itype) > 0) {
i_change(&u->items, oldpotiontype[P_HEAL]->itype, -1);
else if (i_get(u->items, oldpotiontype[P_HEAL]) > 0) {
i_change(&u->items, oldpotiontype[P_HEAL], -1);
change_effect(u, oldpotiontype[P_HEAL], 3);
heiltrank = 1;
}