Preparing for 4.2 release

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • takkaria
    Veteran
    • Apr 2007
    • 1951

    Code:
    if (check_for_inscrip(gear_obj, "!L")) {
        const char *s = quark_str(gear_obj->note); // gear_obj->note is not 0
        while (s) {
            s = strstr(s, "!L");
            /* The stacking limit tag is !L<digit><digit> */
            if (s && '0'<=s[2] && s[2]<='9' && '0'<=s[3] && s[3]<='9') {
                stack_limit = (int)10*(s[2]-'0') + s[3] - '0';
                /* TODO ignore staking limits > 40? */
                break;
            }
            if (s) s++;
        }
        if (stack_limit>=0)
                num_to_pickup = MIN(num_to_pickup, stack_limit - gear_obj->number);
    }
    This is dangerous code with a potential out of bounds access. I think the following will do what you want just as well:

    Code:
    const char *inscription = quark_str(gear_obj->note);
    const char *s = strstr(inscription, "!L");
    if (s && sscanf(s, "!L%d", &stack_limit) > 0) {
        num_to_pickup = MIN(num_to_pickup, stack_limit - gear_obj->number);
    }
    takkaria whispers something about options. -more-

    Comment

    • Sideways
      Knight
      • Nov 2008
      • 896

      Originally posted by jml34
      What does that code do? For each hidden item, assign the first free letter?
      I think it does that, yes; though there's unrelated but very similar code elsewhere that essentially works by swapping letters between the competing items. (That approach sometimes leads to unintuitive results if an item's letter gets swapped multiple times during the process.)

      The fundamental difference between the Frog/Pos code and V is that in Frog every item only has one corresponding key in a given menu (the inscriptions only change what that key is), while V has (so far) tried to make both the original letter and the inscribed key apply within the same menu. I think the latter approach is ultimately unworkable with @[letter][letter] inscriptions allowed, though it didn't cause any conflicts as long as the inscribed keys were always numbers.

      (I'd also say removing that is a very cheap price to pay for making @[letter][letter] inscriptions work But that might be because I'm already used to it.)
      Last edited by Sideways; July 17, 2019, 15:14.
      The Complainer worries about the lack of activity here these days.

      Comment

      • jml34
        Rookie
        • Jul 2019
        • 11

        @takkaria If you mean the accesses to s[2] and s[3] they can't be out of bounds (null-terminated string so these expressions are in bound when evaluated) -- I copied this from elsewhere in the code.
        Now your code is much cleaner, and faster too. Er, I think you could have a look at some elsewheres in the code
        I just quickly tested it with
        Code:
        if (s && sscanf(s, "!L%d", &stack_limit) > 0 && 0<stack_limit &&
                              stack_limit<=gear_obj->kind->base->max_stack) {
        and it worked (ignoring !L with numbers>40).
        I haven't coded in C for like 20 years so I also tested !L0x20 but it seems %d doesn't accept hexa format

        Another quick note (I realize I wasn't clear): I think the player_pickup_aux code would work the same without the 4th parameter and
        Code:
                        if (!pickup_limit) num = get_quantity(NULL, max);
                        else num = max;
        (don't use auto_max since it's unused). Silly me just got scared of that call to get_quantity that I didn't understand so I left auto_max for no good reason that I know of...

        ------------
        About @<cmd><letter>, my plan would be to have the menu scan the keys, check if they're hidden by an entry in the inscriptions array, in which case the inscriptions array would be scanned for an entry that points to the item: this key would be displayed in the menu if there's one, if not, the first free slot would be assigned first. Degenerate case: the player engraved multiple @ commands to objects so there's no free slot available, we display a space in the menu and the object is not reachable.
        @Sideways So @<cmd><letter> could actually be made to work with multiple ways to select an item. Use a key displayed in the menu -> select the corresponding item, use some other key -> select the first engraved item if any.
        Now I don't know if that's a desirable feature, the code could be messy, perhaps I can't get back to it before the 1st of 08, and above all other people have said there's a more desirable way to have @<cmd><letter> work so I'll leave it at that for now
        Last edited by jml34; July 17, 2019, 16:47.

        Comment

        • khearn
          Rookie
          • Jul 2007
          • 18

          Yeah, I think not being able to use an item because something else has its letter in an engraving does seem like it would be a problem at times. There needs to be some way to tell the system to 'ignore engravings for this command'.

          Maybe <cmd>'<letter>? So "qq" would quaff the potion engraved with @qq, and "q'q" would quaff the potion in inventory slot q. And of course, if there is no @qq engraving, "qq" would just quaff the potion in slot q.
          Last edited by khearn; July 17, 2019, 17:37.

          Comment

          • takkaria
            Veteran
            • Apr 2007
            • 1951

            Originally posted by khearn
            Yeah, I think not being able to use an item because something else has its letter in an engraving does seem like it would be a problem at times. There needs to be some way to tell the system to 'ignore engravings for this command'.

            Maybe <cmd>'<letter>? So "qq" would quaff the potion engraved with @qq, and "q'q" would quaff the potion in inventory slot q. And of course, if there is no @qq engraving, "qq" would just quaff the potion in slot q.
            I think this is over-complicated. If the user has assigned a different key to an item for a particular command, the item that has been overriden should just be assigned another key that isn't in use - I liked the suggestion of uppercase letters.
            takkaria whispers something about options. -more-

            Comment

            • takkaria
              Veteran
              • Apr 2007
              • 1951

              Originally posted by jml34
              @takkaria If you mean the accesses to s[2] and s[3] they can't be out of bounds (null-terminated string so these expressions are in bound when evaluated) -- I copied this from elsewhere in the code.
              Hmm, if an inscription was just "!L" then s[0] == "!", s[1] == "L", s[2] == 0, and then s[3] is out of bounds, no? Where else in the code makes this assumption?

              (I hate C)
              takkaria whispers something about options. -more-

              Comment

              • khearn
                Rookie
                • Jul 2007
                • 18

                Yeah, uppercase sounds good, too.

                Comment

                • jml34
                  Rookie
                  • Jul 2019
                  • 11

                  Originally posted by takkaria
                  Hmm, if an inscription was just "!L" then s[0] == "!", s[1] == "L", s[2] == 0
                  In that case " && '0'<=s[2] " fails so further && conditions are not evaluated, which is how out of bounds accesses are prevented (I also don't like lots of things about C but it still beats assembly code )

                  ----
                  About @<cmd><letter> I just realized my plan would essentially make the inscriptions array a keymap (input letter-or-digit -> equipment slot), since we'd first assign working normal letters to the array (after inscriptions are processed) to guarantee nobody claims that letter. So we could rename this array keymap if we go that route.

                  About the UI, we have several possibilities:
                  1. Don't use uppercase letters inscribed by the user. This guarantees 26 free slots for pathological cases.
                  2. Let the user use uppercase inscriptions and
                  .2a. just do nothing if the user has somehow messed with all letters (an item is unreachable)
                  .2b. provide a few non-letter keys for those cases.
                  It's just that I don't see in what practical situation there'd be a 2a pathological case. "Assign the first free uppercase letter" should always work (going for an uppercase letter first to emphasize in the menu that a lowercase inventory slot was temporarily reassigned), unless the user inscribed all uppercase letters somewhere on purpose right?

                  EDIT in fact @Ee might be safer than @EE in case I'd release the shift key between the Es and end up eating something at slot e. It could be lowercase inscriptions are safer. Or I'd engrave both @EE and @Ee.
                  Last edited by jml34; July 17, 2019, 21:20.

                  Comment

                  • Ingwe Ingweron
                    Veteran
                    • Jan 2009
                    • 2129

                    It seems to me that this entire thread has been sidelined into what should be in the "Development" portion for talk about coding specifics rather than the "Vanilla" portion, but maybe that's just me.
                    “We're more of the love, blood, and rhetoric school. Well, we can do you blood and love without the rhetoric, and we can do you blood and rhetoric without the love, and we can do you all three concurrent or consecutive. But we can't give you love and rhetoric without the blood. Blood is compulsory. They're all blood, you see.”
                    ― Tom Stoppard, Rosencrantz and Guildenstern are Dead

                    Comment

                    • Derakon
                      Prophet
                      • Dec 2009
                      • 9022

                      Originally posted by Nick
                      Also thanks for all the helpful suggestions on a new name for Satisfy Hunger. My current thinking is to go with Derakon's idea of Remove Hunger, and change it to not reset food downward. This means it will not be a cure for fullness, which seems more in keeping with the philosophy of the changes. Also makes ,Purging and !Salt Water more useful
                      You got some positive feedback from the initial change to Satisfy Hunger specifically because it meant that players would no longer have to hoard Purging/Salt Water for the final fights to avoid getting healing-gorged. Reverting that part of the change is therefore likely to provoke complaints.

                      What if it set your percentage to MIN(90, current+50)? Or current+25 or whatever you think a reasonable number is.

                      Comment

                      • Nick
                        Vanilla maintainer
                        • Apr 2007
                        • 9634

                        Originally posted by Derakon
                        You got some positive feedback from the initial change to Satisfy Hunger specifically because it meant that players would no longer have to hoard Purging/Salt Water for the final fights to avoid getting healing-gorged. Reverting that part of the change is therefore likely to provoke complaints.
                        You are very likely correct

                        Here are my reasons for going ahead with this anyway:
                        1. The hunger meter means the player has a chance to plan their food intake before the final fights, which seems reasonable and the sort of integration of the hunger mechanic that I am aiming for
                        2. Slowing through fullness sets in gradually - one healing potion will slow the player by a maximum of 1 - so it is a situation the player can respond to dynamically
                        3. Only two classes of nine get Satisfy Hunger as a spell, so others choosing to rely on "hunger reduction" would need to devote a slot to it in any case
                        4. I plan to introduce some more variety of food, so the player can have more control over their hunger level


                        While I'm aware that there are some people who wish hunger would just go away as a mechanic, I'm in general not in favor of extreme optimisation of aspects of the game to facilitate the equivalent of speedrunning; I think that's the player's job, not the maintainer's. There was a choice between actually removing hunger or making it more integrated within the game, and overall we came down on the side of integration. So I don't want to then do things that run counter to that, in the same way as I'm not going to introduce this
                        Code:
                        #####
                        #123#
                        #4>5#
                        #678#
                        #####
                        as a town layout
                        One for the Dark Lord on his dark throne
                        In the Land of Mordor where the Shadows lie.

                        Comment

                        • Derakon
                          Prophet
                          • Dec 2009
                          • 9022

                          You forgot the little courtyard for the townspeople and Farmer Maggot to spawn in, which is of course separated from the rest of the town by a pile of rubble.

                          But anyway, fair enough. I'm not personally trying to persuade you to go one way or another, just making sure you're making as informed of decisions as possible. Which you are, as best I can tell.

                          Comment

                          • wobbly
                            Prophet
                            • May 2012
                            • 2629

                            Originally posted by Derakon
                            This is a good summation. As for ideas for 3, how about if more powerful races had a lower level cap? Like, you topped out at level 40 for a high-elf and level 50 for a human, and everyone else was somewhere in-between? Newbies will die before the level cap becomes relevant. The biggest problem of course is that this limits spell access for full casters; a lot of the really class-defining spells would be unavailable to high-elves if we used the numbers I suggested. But both the level caps and the spell levels could be tweaked.
                            HPs would probably also be a problem. I think level limits make more sense if you add something like giants & give them insane hps/level. Quickband gives high elves the "Doom of Mandos" from clvl 27 which does bad stuff (not sure what, never played the high elf) but you could adapt Sil's danger mechanic where monsters are spawning at a higher depth or do something different.

                            Comment

                            • Derakon
                              Prophet
                              • Dec 2009
                              • 9022

                              Originally posted by wobbly
                              HPs would probably also be a problem. I think level limits make more sense if you add something like giants & give them insane hps/level. Quickband gives high elves the "Doom of Mandos" from clvl 27 which does bad stuff (not sure what, never played the high elf) but you could adapt Sil's danger mechanic where monsters are spawning at a higher depth or do something different.
                              I'm pretty sure I've seen ladder wins with character levels lower than 40. At level 40 with max CON you get 40*12.5=500 HP from CON, which means you need 2.5 HP per level from your hit dice to be out of instadeath range from Morgoth. The worst hit die in the game is a halfling mage with a d7, which has an average roll of 4. I'm not saying it'd be a fun fight, but it should be doable.

                              But sure, there's plenty of other neat ways to penalize powerful races in the lategame. You could give one race a time limit of 1 million game turns (~= 100k normal-speed turns, plenty to win with), for example. There might also be some way to tweak the experience-received-per-enemy formula such that as a particular race dives deeper they have to get more and more of their experience from "novel" kills (where the monster type hasn't been killed before).

                              Comment

                              • Ingwe Ingweron
                                Veteran
                                • Jan 2009
                                • 2129

                                Originally posted by Derakon
                                I'm pretty sure I've seen ladder wins with character levels lower than 40. At level 40 with max CON you get 40*12.5=500 HP from CON, which means you need 2.5 HP per level from your hit dice to be out of instadeath range from Morgoth. The worst hit die in the game is a halfling mage with a d7, which has an average roll of 4. I'm not saying it'd be a fun fight, but it should be doable.
                                As in PowerWyrm's epic win of the Hobbit comp with The One Ring, Sting, and a Mithril ChainMail to start, with the win condition being the lowest experience. However, I think ladder wins are less comparable across versions, especially as the newest rendition of the end-game is appreciably more difficult to win - in a good way.
                                “We're more of the love, blood, and rhetoric school. Well, we can do you blood and love without the rhetoric, and we can do you blood and rhetoric without the love, and we can do you all three concurrent or consecutive. But we can't give you love and rhetoric without the blood. Blood is compulsory. They're all blood, you see.”
                                ― Tom Stoppard, Rosencrantz and Guildenstern are Dead

                                Comment

                                Working...
                                😀
                                😂
                                🥰
                                😘
                                🤢
                                😎
                                😞
                                😡
                                👍
                                👎