Grimtooth and Sunsword invoke can be paid with magic power

If the invoke timeout hasn't run out, the effect will take 25 pw,
the same as a lvl 5 spell.
If hero doesn't have that much, then the invoke fails.
This commit is contained in:
Pasi Kallinen
2025-12-14 12:00:26 +02:00
parent b92cccbbcd
commit 758528f094
2 changed files with 47 additions and 9 deletions

View File

@@ -1510,6 +1510,7 @@ if a tree and a boulder or statue were at the same location, applying an axe
would break the boulder or statue rather than chop the tree
avoid premapping outside Sokoban map to prevent showing stone glyphs
Grimtooth is permanently poisoned, protects from poison, and can fling poison
invoke cost for Grimtooth and Sunsword can be paid with magic power
cursed magic whistle can teleport you to your pet
Fire and Frost Brand can be invoked for expert level fireball or cone of cold
wielding Trollsbane grants hungerless regeneration

View File

@@ -40,6 +40,8 @@ staticfn int invoke_banish(struct obj *) NONNULLARG1;
staticfn int invoke_fling_poison(struct obj *) NONNULLARG1;
staticfn int invoke_storm_spell(struct obj *) NONNULLARG1;
staticfn int invoke_blinding_ray(struct obj *) NONNULLARG1;
staticfn int arti_invoke_cost_pw(struct obj *) NONNULLARG1;
staticfn boolean arti_invoke_cost(struct obj *) NONNULLARG1;
staticfn int arti_invoke(struct obj *);
staticfn boolean Mb_hit(struct monst * magr, struct monst *mdef,
struct obj *, int *, int, boolean, char *);
@@ -2083,6 +2085,48 @@ invoke_blinding_ray(struct obj *obj)
return ECMD_TIME;
}
/* return the amount of Pw invoking an object costs.
return a negative value, if obj invoking cannot be paid with Pw */
staticfn int
arti_invoke_cost_pw(struct obj *obj)
{
const struct artifact *oart = get_artifact(obj);
if (oart->inv_prop == FLING_POISON
|| oart->inv_prop == BLINDING_RAY) {
/* pretend it's a level 5 spell */
return SPELL_LEV_PW(5);
}
return -1;
}
/* return TRUE if artifact object's invoke cost can be paid (and pay it) */
staticfn boolean
arti_invoke_cost(struct obj *obj)
{
if (obj->age > svm.moves) {
int pw_cost = arti_invoke_cost_pw(obj);
if (pw_cost < 0 || u.uen < pw_cost) {
/* the artifact is tired :-) */
You_feel("that %s %s ignoring you.", the(xname(obj)),
otense(obj, "are"));
/* and just got more so; patience is essential... */
obj->age += (long) d(3, 10);
return FALSE;
} else {
/* you pay invoke cost with your own magic */
You_feel("drained...");
u.uen -= pw_cost;
disp.botl = TRUE;
}
} else {
obj->age = svm.moves + rnz(100);
}
return TRUE;
}
staticfn int
arti_invoke(struct obj *obj)
{
@@ -2102,17 +2146,10 @@ arti_invoke(struct obj *obj)
return ECMD_TIME;
}
/* It's a special power, not "just" a property */
if (oart->inv_prop > LAST_PROP) {
/* It's a special power, not "just" a property */
if (obj->age > svm.moves) {
/* the artifact is tired :-) */
You_feel("that %s %s ignoring you.", the(xname(obj)),
otense(obj, "are"));
/* and just got more so; patience is essential... */
obj->age += (long) d(3, 10);
if (!arti_invoke_cost(obj))
return ECMD_TIME;
}
obj->age = svm.moves + rnz(100);
switch (oart->inv_prop) {
case TAMING: res = invoke_taming(obj); break;