Bumping into unseen peacefuls doesn't anger them#231
Closed
Ardub23 wants to merge 20 commits into
Closed
Conversation
This monster comes from SLASH'EM by way of Hack'EM. I figured that the existing standard scorpions on the Ranger quest don't actually pose much of a threat to the player, and there ought to be an intermediate scorpion-like enemy between them and Scorpius. There are a few changes from Hack'EM scorpions: - They're orange rather than red (small scorpions are red) because when the player is fighting both types on the Ranger quest, an easy visual shorthand for the more threatening type is a good thing to have. This is in line with xNetHack monster color principles anyway. - They're faster, with a speed of 18 rather than 15. - They have only one claw attack; the other claw attack is moved to the third slot, after the sting, and changed to a grapple attack. I did that mainly because a poison resistant Ranger would otherwise still only treat giant scorpions as larger, higher-HP-and-damage enemies; letting them grapple and crush the hero in one of their claws makes them tactically different. - Scorpions can grow up into giant scorpions; that seems like an omission in Hack'EM rather than an intentional choice. The giant scorpion tile is the same as the SLASH'EM/Hack'EM one.
It seemed like it should be possible to ride a tame giant scorpion into battle if one has a saddle for it. Giant spiders becoming saddleable is a side-effect, but one that also makes sense. (Yes, a standard saddle probably isn't equipped to fit around an arachnid's exoskeleton, but that gets handwaved just like with other weird body shape creatures like jabberwocks.)
This is in preparation for a new object which will be made of hard
light. It isn't really intended to take part in the object materials
system where other objects can be made out of it, but some design
thoughts if that ever becomes a thing (and which did inform the numbers
assigned to this material):
Hard light is a magical construct which can be conjured without that
much difficulty by intermediately skilled magic users, but which
does take a lot of effort and skill to form into a useful shape and
hold it. Typically maintaining one of these constructs takes
concentration, and an enchantment placed to hold it in its shape
without concentration will rely on proximity to a living body and
degrade rapidly without it. Consequently, it's unheard of to find an
item made of it just lying around, and shopkeepers won't pay well
for it because they're aware it will disintegrate before they'll be
able to sell it.
It's exceedingly lightweight, and strong but not impervious to
attacks. It's one of the few materials that can hit incorporeal
beings like shades regardless of its beatitude.
This commit also sets the array size of the various material arrays to
NUM_MATERIAL_TYPES; there's no good reason why they should remain
indefinite-length.
In preparation for Ranger quest story changes. This commit merely changes the name. For backwards compatibility, searching the encyclopedia for "Longbow of Diana" will still produce the correct entry.
This is also an key part of the Ranger quest overhaul, being the primary weapon they will get as a reward for completing it. Arrows of light are designed to be very powerful, one-shotting a lot of monsters with their devastatingly high HP damage, but also very limited in order to avoid being exploitable. To that end, they're fragile enough to disintegrate when used or even when dropped (though they can be stolen or put in containers), and there is a hard cap of 5 on how many arrows can exist at once. As of this commit, you can only obtain them by wishing and then only one at a time, but the plan is to have the Longbow create them upon invoke - the hard cap therefore serves to prevent the hero from sitting in a closet, stowing arrows away somewhere the game didn't think to look for them, and building up a huge stockpile. I considered implementations that would avoid using a global variable to track the amount of arrows, but ended up discarding them. The easiest way to do that would be to make the arrow disintegrate upon simply leaving the hero's inventory. The "proper" way to do this would be an obj_no_longer_held or freeinv refactor where those functions become capable of deleting the object, but then this has to be passed up to all direct and indirect callers to make them aware of their obj argument possibly being destroyed, making it quite a big refactor which I didn't want to undertake. If other hard light objects are ever added, this should probably be reconsidered, or else they should trigger a destruction timer in obj_no_longer_held which adds possible timer headaches but at least would allow the code to assume obj_no_longer_held still won't outright destroy any objects. At the same time, I realized that a simple, hacky implementation which inserts arrow disintegration hooks into common places where the arrow leaves the hero's inventory (adding to a container, being stolen, hitting the floor for any reason) would be prone to exploits, because any method that can get an item out of the inventory some other way would be used to circumvent the intended limit on light arrows you can have at one time. Also, it would be odd not to be able to put arrows of light into a carried container. The flavor text for when light arrows interact with monsters is primarily based on how they work in The Legend of Zelda: The Wind Waker. This commit also slightly modifies the defer_breakwep uhitm code (since arrows of light now use it alongside glass weapons), adding an impossible if something sets defer_breakwep but the weapon doesn't appear to be eligible for breakage, and not setting defer_breakwep on ordinary non-glass weapons.
This is the key buff to the Longbow, making it the primary source of arrows of light. The initial idea was to have it top you up with as many new arrows as the game can allow to exist, but I think it is slightly better balanced and more strategical if it provides 3 instead (allowing people to stockpile if they want, but in order to get the most out of a second invoke, you need to use at least one arrow...) The old create-regular-arrows effect is still present, occurring when no arrows of light can be created. I slightly improved these too, since it was considered a pretty underpowered invoke: now the arrows will match your race if you're an elf or gnome (not that this matters if you plan on using the Longbow to fire them) and have their enchantment set to the Longbow's enchantment, providing an incentive to enchant the Longbow. Arrows of light will /not/ get free enchantment, since they do enough damage already. This also adds a message describing the arrows appearing, since it was kind of weird to invoke the Longbow and get no feedback except the addinv message. Unless the inventory was full, but I also changed the hold_another_object message because the arrows "falling out" of the bow is kind of weird too.
This is the first Ranger quest change that's directly about the changed story: Orion's not in the picture because Scorpius slew him. In his place, calling you to the quest, is his lieutenant, servant and guide, Cedalion. He is a lesser known but still well-attested figure in most Orion myths, assigned to guide Orion from atop his shoulder as he wandered after having his eyes put out. I kept most of the statblock unchanged on the basis that it's adjusted for making it tough to kill him to get early entry to the quest, but he is regular human size instead of MZ_HUGE, because he's not a giant like Orion is. I also did not give Cedalion the ability to tear webs that Orion had; the only quest enemies in here seem to be giants, and again Cedalion isn't a giant.
Final Longbow buff: make it much better for multishot and therefore combat in general. Late-game it's very annoying to be facing a crowd of foes and randomly only fire 1 arrow at them; the swinginess of this approach makes it harder to justify using a ranged weapon instead of melee. Note that it doesn't enable you to multishoot better than you could otherwise. This minimum takes into account what you would naturally get as your highest possible multishot, and lowers the floor to that accordingly.
This is not a significant overhaul since this level was already heavily modified from the infamous 1-wide labyrinth in xNetHack 3.0. Mostly I just moved the downstair to the middle of the top/bottom edge, removed Sirius (due to quest story changes and Orion no longer being the leader), and changed up the centaur generation a bit. I also took advantage of the recent feature to block monster spawning in certain areas and made the central grove a no-spawning area. One of the friendly hunters was generating on top of iron bars for some reason; this appeared to be a coordinate error in a previous xNetHack change to the level, so I adjusted that.
Because I can't help but come up with entirely new algorithms when implementing the most basic filler levels, I found myself making a Ranger upper filler level that involved Yet Another Spanning Tree Algorithm. Since I keep coming up with ideas that involve spanning trees, I decided to just bite the bullet and make a general-purpose algorithm and put it in nhlib.lua. This algorithm is basically a generalization of the one that was in the wizard1 level, and this commit replaces the wizard1 code with a call to make_spanning_tree as a proof of concept. There are other places like the Super Honeycomb themed room (but NOT wizard2) that could be refactored to use this function, but aren't done in this commit.
The level I replaced in this commit got points for at least being distinctive for a cavern fill, due to the walls being trees, but once you got past that it was still just a boring cavern. As with most quest fillers, this level had randomized stairs implying a downward traverse (especially out of place in this quest; you're descending from the sky?) so this fixes one stairway at the middle top of the map and the other stairway inside one of two caverns. The idea there is that it's not clear which of the two is the actual Cave of the Wumpus. I threw out the cavern fill and replaced it with an algorithm that makes a spanning tree between various "junction" waypoints on the map, conveying a better sense of following trails through the forest. Hopefully this creates a better "exploration" gameplay sense. A fair bit of code is dedicated to avoiding both inaccessible holes in the forest and diagonal gaps that would require squeezing or cutting a tree down. I added in 1 waiting giant scorpion to the monster loadout on this level to make it a possibility but not a guarantee that the player will see one before the lower filler level.
The Ranger quest story isn't among the most poorly differentiated of them - the ongoing conflict with the centaurs is all right as a reason for the start level being beseiged - but it did suffer from some things that made it bland and some things that didn't make sense. (Scorpius is the mortal enemy of Orion - so why is he sending YOU to kill him while he sits around in the grove? And why would he ally with centaurs? And why is he building a palace with a throne he shouldn't physically be able to occupy anyway?) The most significant change to the story that drives all the other changes is that Scorpius has already killed Orion, and Cedalion is leading the remaining hunters in his stead. Many of these other changes make the story draw on the mythology of Orion, such as Scorpius being sent by Gaia after he intended to kill all the beasts on the earth, and both of them being placed in the sky as constellations afterwards. During writing the story I decided that the bow cannot create arrows of light until you successfully kill Scorpius, because the arrows of light derive directly from Orion's blessing from the stars. (How it still does this for non-Rangers who wish for the bow is another matter I don't have the answer to.) Another experimental change in the story is to make Scorpius entirely mute, because again, scorpion. I always felt like his dialogue was a little odd, even if imagining him as a talking animal. So this is an attempt to see if it'll work with mere descriptive messages instead of dialogue, within the constraints of the existing system for delivering those messages - for instance, you still get a big multiline text window when you first face him, but it's entirely description and threatening behavior. The centaur conflict is kept, because I liked the thematic parallels and gameplay of fighting a lot of enemies who use ranged weapons themselves and try to keep their distance. I also didn't really change anything with the Cave of the Wumpus, other than to make references to how the Wumpus can deliver instant death (it can't yet but will soon). This level is a wholesale reference to Hunt the Wumpus, including in its quest text, and I think it works fine as the Ranger locate level. Due to the nature of quest overhauls, some parts of the changed text reflect things that are not part of the previous commits and don't exist yet.
This is intended to be another incremental experiment in Quest diversity: in all other quests the nemesis hoards the artifact and you have to get it from them. Here, the artifact is not integral to the quest story or accomplishing the mission, so there's no reason why Cedalion can't just give it to you in the hopes it'll help you succeed. To balance this out, and to align it with the quest story changes, the bow cannot make light arrows until Scorpius dies.
In line with how many quest artifacts aren't as effective if you've wished them up as another role, so too is the Longbow. It will summon one arrow of light per invoke (still maxing out at 5) and the arrows don't deal as much damage. But multishooting them will still be pretty devastating. This might be an overnerf, but I'd rather err on that side rather than possibly overbuffing non-Rangers by letting the Longbow create the same amount of light arrows for everybody. Rangers who have the Longbow but have not yet killed Scorpius are treated the same as non-Rangers for all purposes except acquiring arrows of light via invoke, which they cannot do until they kill Scorpius.
With the greater focus on scorpions in the Quest, it didn't make sense to continue to spawn lots of centaurs as time goes on. Scorpions and other creepy-crawlies are mentioned as emerging out of the earth to fight, so them popping up makes more thematic sense too. Centaur presences on levels are better provided by initial generation (primarily on the first three levels; there will be fewer of them on the late levels). Ideally the specific monster to generate most of the time would be a little stronger than the regular scorpion but not as strong as the giant scorpion (which I don't want spawning frequently on the home level, for instance). I suppose I could buff the regular scorpion a bit but I overall like the balance of the two.
This is partly for giant scorpions, since I imagine no one would even know they could tame and saddle one otherwise, but now it's discoverable (especially since a reaction of players to seeing a giant scorpion may be to use monster lookup on it). Otherwise, it's a nice small improvement to monster lookup. I did have to move the logic out of can_saddle into a new saddleable() function; there's nothing in can_saddle that requires anything besides the permonst, so I don't know why it requires a struct monst. Regardless, I felt it was better to leave can_saddle's signature as-is and not change all its callers.
If the hero walked into a creature without attacking, the creature would react as if the hero had attacked violently--but only if the creature was peaceful (not tame), and only if the hero couldn't see them. There is no clear reason for this to occur, given that the hero's action is both innocent and harmless. And it can cause frustration if a strong peaceful creature (such as a quest leader) decides to go invisible or hide. Now, bumping into an unseen peaceful creature will awaken it without being treated as an attack.
c697d13 to
45802ed
Compare
c5f683b to
530a7c3
Compare
Owner
|
This is now in the master branch and part of the 10.0 release. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
If the hero walked into a creature without attacking, the creature would react as if the hero had attacked violently—but only if the creature was peaceful (not tame), and only if the hero couldn't see them. There is no clear reason for this to occur, given that the hero's action is both innocent and harmless. And it can cause frustration if a strong peaceful creature (such as a quest leader) decides to go invisible or hide.
Now, bumping into an unseen peaceful creature will awaken it without being treated as an attack.