Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#1427 closed bug (fixed (in master))

Monster saves are too powerful versus sleep

Reported by: d_m Owned by: d_m
Milestone: 3.3.0 Keywords: monster
Cc:

Description

I'm not sure yet if this applies to all status effects, but currently it's pretty impossible to put monsters to sleep with a wand of sleep monster. I just tried about x15 with a mage against a white icky thing (although i was able to put a white mouse to sleep).

It's not clear which monster levels and status effects are impacted. At a minimum I want to restore the old behavior.

Change History (9)

comment:1 Changed 7 years ago by myshkin

For reference, the origin of this change, from my post on oook: The change in behavior appears to have entered the codebase at the end of January, with the merge of Jeff's monster pain messages patch (with some fixes from CunningGabe). Previously, immunity to sleep was governed only by the NO_SLEEP or UNIQUE flags; saving throw was 0 until level 11, and then was (mlvl - 10) in (clvl - 10). Now, immunity to sleep comes from NO_SLEEP, STUPID, EMPTY_MIND, WEIRD_MIND, and UNDEAD. Uniques get three saving throws (I think this is supposed to be two saving throws, but some code is duplicated). The saving throw is (25 + mlvl - clvl/5) in 100. The upshot is that it is easier to sleep high-level monsters than before, but much harder to sleep low-level monsters.

comment:2 Changed 7 years ago by magnate

  • Keywords status removed
  • Status changed from new to confirmed

comment:3 follow-up: Changed 7 years ago by magnate

Ugh. This is all in project_m, which is awful. It needs refactoring to use gf_table *and* the new MON_TMD_ array.

comment:4 in reply to: ↑ 3 Changed 7 years ago by magnate

  • Status changed from confirmed to pending

[rb48c51b] provides a fix for the bug - wands of sleep monster are useful again. But a full fix needs a complete refactor of project_m which understands whether the attack is from a spell or a device.

comment:5 follow-up: Changed 7 years ago by takkaria

I disagree that the the project() should know anything about spell sources – if you have two different effects you should have two different element types. I think for the monster 'charm' spells, the dam paramater should be used for strength, which gets saved against by the monster, and the extent to which the monster didn't save is how long they get confused for.

comment:6 in reply to: ↑ 5 Changed 7 years ago by magnate

Replying to takkaria:

I disagree that the the project() should know anything about spell sources – if you have two different effects you should have two different element types. I think for the monster 'charm' spells, the dam paramater should be used for strength, which gets saved against by the monster, and the extent to which the monster didn't save is how long they get confused for.

Hmmmkay. Seems odd to use a different element type to encode a different attack source - but the real issue here is that project() deals with both damage and side effects, and you might conceivably want them affected by different things.

On the former issue, IIUC the value of "-1" is used for "who" to denote an attack from the player - so we could easily use

#define EFFECT_SOURCE_SPELL -2
#define EFFECT_SOURCE_WAND -3

etc. This would enable greater flexibility within the existing code, and avoid the need to duplicate elements for different sources.

On the second issue, I recommend separating damage from side effects completely, and taking both damage and effect strength from a table (ultimately an edit file, but list-gf-table would do in the meantime, since this is a logical extension of what's been done with project_p). But I guess this is tied up with #1041 also, so I'd best get my thoughts in order on that first.

comment:7 Changed 7 years ago by takkaria

I don't mean to say that we should use GF_ types for encoding attack source – but as I see it, each GF_ type should have a defined effect that doesn't vary based on attack source. The project code shouldn't be touching device skill or player stats in project_m(), all that should have been done before it gets called to calculate the right parameters to send it. I'd appreciate an example of why it would be useful to have that information.

I'm a bit confused by your second point. Do you mean passing (damage, side_effect_strength) to project(), and taking the parameters from a table when calling project()? Or do you mean to look them up in a table inside of project_m()? I don't understand why you'd want either of those.

comment:8 Changed 7 years ago by magnate

Ok, I've been thinking about this, and you've replied before I've had a chance to write up my thoughts. I think we have three difficulties that need untangling - one goes here and the other two on #1041. This one is about the nature of projection: a projection type defines a *set* of effects which take place at every target in its path or area of effect. One of these effects is often damage (but doesn't have to be), and there can be one or more others like stunning, life draining etc.

If you maintain that all adjustments to variable values must be made before project() is called (with the exception of range attenuation, I guess), you have to pass the adjusted values into it. At the moment it takes only one variable value - the "dam" parameter. My suggestion is that game design is limited if every single one of the set of effects caused by any given projection type must use the same variable (or not vary at all).

So, for example, GF_SOUND cases damage and stunning. Do you always want the stunning to have an identical relationship to the damage? I can envisage different calls to project() for different types of sound - one of which has twice the stunning of the other, for example. So I'd want two variables passed into project() - one for damage and one for the strength of the stunning effect.

I'm guessing your response would be simply to create a new GF_ type for the different type of sound. This is one of the things I address in #1041.

comment:9 Changed 7 years ago by magnate

  • Resolution set to fixed
  • Status changed from pending to closed

In master as of [r022d04e]

Note: See TracTickets for help on using tickets.