forked from github/server
start removing dependencies on potion_type.
use item_type where we can. does not compile, is WIP.
This commit is contained in:
parent
9dbe1d65b2
commit
915a924fcb
137
src/alchemy.c
137
src/alchemy.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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", ""));
|
||||
|
|
|
@ -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);
|
||||
|
|
10
src/items.c
10
src/items.c
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*********************/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
47
src/laws.c
47
src/laws.c
|
@ -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);
|
||||
|
|
15
src/report.c
15
src/report.c
|
@ -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);
|
||||
|
|
13
src/study.c
13
src/study.c
|
@ -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) {
|
||||
|
|
14
src/upkeep.c
14
src/upkeep.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue