1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-05-06 15:25:11 +01:00

Merge remote-tracking branch 'notdnethack/master'

This commit is contained in:
Ron Nazarov 2024-11-14 03:18:10 +00:00
commit 7e4548c559
Signed by: noisytoot
GPG key ID: 1D43EF4F4492268B
4 changed files with 107 additions and 21 deletions

View file

@ -1170,6 +1170,7 @@ extern char carrying_readable_weapon(void);
extern char carrying_readable_tool(void);
extern char carrying_readable_armor(void);
extern struct obj *carrying_art(int);
extern char carrying_invokable_object(void);
extern boolean have_lizard(void);
extern struct obj *o_on(unsigned int,struct obj *);
extern boolean obj_here(struct obj *,int,int);

View file

@ -1356,6 +1356,12 @@ struct obj {
|| onum == CONSORT_S_SUIT\
)
#define is_invokable_otyp(onum) (onum == RIN_WISHES\
|| onum == CANDLE_OF_INVOCATION\
|| onum == CRYSTAL_BALL\
)
#define is_readable_armor(obj) ((obj)->oward)
#define is_museable_amulet(otyp) (otyp == AMULET_OF_LIFE_SAVING \

View file

@ -8620,12 +8620,84 @@ scorpion_upgrade_menu(struct obj *obj)
return MOVE_STANDARD;
}
static boolean
invoke_on_cooldown(struct obj *obj, const struct artifact *oart){
if(is_lightsaber(obj) && obj->cobj && obj->oartifact == obj->cobj->oartifact)
obj = obj->cobj;
boolean on = oart->inv_prop <= LAST_PROP && (u.uprops[oart->inv_prop].extrinsic & W_ARTI);
return obj->age > monstermoves && !(
oart->inv_prop == FIRE_SHIKAI ||
oart->inv_prop == SEVENFOLD ||
oart->inv_prop == ANNUL ||
oart->inv_prop == ILLITHID ||
oart->inv_prop == ALTMODE ||
oart->inv_prop == LORDLY ||
oart->inv_prop == DETESTATION ||
oart->inv_prop == THEFT_TYPE ||
oart->inv_prop == GITH_ART
|| oart->inv_prop == ZERTH_ART
|| oart->inv_prop == AMALGUM_ART
|| oart->inv_prop == SCORPION_UPGRADES
|| on
);
}
static struct obj *
do_invoke_menu(void){
struct obj *otmp;
struct artifact *oart;
winid tmpwin;
int n, how;
char buf[BUFSZ];
menu_item *selected;
anything any, anyvoid;
long cooldown;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any.a_void = 0; /* zero out all bits */
anyvoid.a_void = 0; /* zero out all bits */
Sprintf(buf, "Invokable Objects:");
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, buf, MENU_UNSELECTED);
for(otmp = invent; otmp; otmp = otmp->nobj){
oart = (struct artifact *) 0;
if(is_invokable_otyp(otmp->otyp) || (otmp->oartifact && (oart = get_artifact(otmp)) && oart->inv_prop)){
if(oart && invoke_on_cooldown(otmp, oart)){
cooldown = otmp->age - monstermoves;
if(is_lightsaber(otmp) && otmp->cobj && otmp->oartifact == otmp->cobj->oartifact)
cooldown = otmp->cobj->age - monstermoves;
Sprintf(buf, "%3ld %s", cooldown, doname(otmp));
add_menu(tmpwin, NO_GLYPH, &anyvoid,
0, 0, ATR_NONE, buf,
MENU_UNSELECTED);
} else{
Sprintf(buf, "%s", doname(otmp));
any.a_obj = otmp; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
otmp->invlet, 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
}
}
end_menu(tmpwin, "Choose which object to invoke");
how = PICK_ONE;
n = select_menu(tmpwin, how, &selected);
destroy_nhwindow(tmpwin);
return (n > 0) ? selected[0].item.a_obj : (struct obj *) 0;
}
int
doinvoke(void)
{
register struct obj *obj;
obj = getobj(invoke_types, "invoke");
if(!carrying_invokable_object()){
You("have nothing to invoke.");
return 0;
}
obj = do_invoke_menu();
if (!obj) return 0;
if (obj->oartifact && !touch_artifact(obj, &youmonst, FALSE)) return 1;
if(is_lightsaber(obj) && obj->cobj && obj->oartifact == obj->cobj->oartifact)
@ -8679,20 +8751,7 @@ arti_invoke(struct obj *obj)
if(oart->inv_prop > LAST_PROP) {
/* It's a special power, not "just" a property */
if(obj->age > monstermoves && !(
oart->inv_prop == FIRE_SHIKAI ||
oart->inv_prop == SEVENFOLD ||
oart->inv_prop == ANNUL ||
oart->inv_prop == ILLITHID ||
oart->inv_prop == ALTMODE ||
oart->inv_prop == LORDLY ||
oart->inv_prop == DETESTATION ||
oart->inv_prop == THEFT_TYPE ||
oart->inv_prop == GITH_ART
|| oart->inv_prop == ZERTH_ART
|| oart->inv_prop == AMALGUM_ART
|| oart->inv_prop == SCORPION_UPGRADES
)) {
if(invoke_on_cooldown(obj, oart)) {
/* the artifact is tired :-) */
if(obj->oartifact == ART_FIELD_MARSHAL_S_BATON){
You_hear("the sounds of hurried preparation.");

View file

@ -888,6 +888,24 @@ carrying_art(register int artnum)
return((struct obj *) 0);
}
static char
is_invokable_object(struct obj *otmp){
struct artifact *oart;
return is_invokable_otyp(otmp->otyp) || (otmp->oartifact && (oart = get_artifact(otmp)) && oart->inv_prop);
}
char
carrying_invokable_object(void)
{
struct obj *otmp;
for(otmp = invent; otmp; otmp = otmp->nobj){
if(is_invokable_object(otmp))
return TRUE;
}
return FALSE;
}
const char *
currency(long amount)
{
@ -2441,12 +2459,8 @@ itemactions(struct obj *obj)
"Unequip this equipment", MENU_UNSELECTED);
}
/* V: invoke, rub, or break */
any.a_void = (void *)doinvoke;
if ((obj->otyp == FAKE_AMULET_OF_YENDOR && !obj->known) ||
obj->oartifact || objects[obj->otyp].oc_unique ||
(obj->otyp == RIN_WISHES && objects[obj->otyp].oc_name_known && (obj->owornmask & W_RING)) ||
(obj->otyp == CANDLE_OF_INVOCATION && obj->lamplit) ||
obj->otyp == MIRROR) /* wtf NetHack devteam? */
any.a_void = (void *)doparticularinvoke;
if (is_invokable_object(obj))
add_menu(win, NO_GLYPH, &any, 'V', 0, ATR_NONE,
"Try to invoke a unique power of this object", MENU_UNSELECTED);
/* w: hold in hands, works on everything but with different
@ -2557,6 +2571,12 @@ itemactions(struct obj *obj)
destroy_nhwindow(datawin);
return 0;
}
/* The getobj hack won't work for invoking, so we have to call
doparticular invoke with an argument instead.*/
if(feedback_fn == (void *)doparticularinvoke)
return (*(((int (*)(struct obj *)) feedback_fn)))(obj);
/* In most cases, we can just set getobj's result directly.
(This works even for commands that take no arguments, because
they don't call getobj at all. */