Adding Oangband magic realms/spellbooks. What changes do I need to make?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Elfin Jedi
    Adept
    • Mar 2013
    • 102

    #31
    Ok, edited gamedata files are now in gamedata folder rather than user folder.

    Chose INVISIBLE as name. Edited list-mon-timed.h and list-mon-message.h.

    Still working out where to add extra checks.

    Haven't put invisibility spell changes on github yet.

    Oh bother, the line endings are a problem again (with files in gamedata).

    Looks like pit.txt, terrain.txt, and store.txt (at the very bottom) are fine. The others are older and will need to be redone.
    Last edited by Elfin Jedi; July 12, 2016, 00:47.

    Comment

    • Elfin Jedi
      Adept
      • Mar 2013
      • 102

      #32
      Fixed bug where bookstore wasn't showing up and magic shop had bookstores symbol. Terrain.txt had for the bookstore info:6:0. Changed to info:9:0.

      Also, got history.txt, pit.txt, store.txt, and terrain.txt in separate uploads with fixed line endings. (So now it won't say that I changed every line in history.txt, makes it a LOT easier to find changes.)

      Comment

      • Elfin Jedi
        Adept
        • Mar 2013
        • 102

        #33
        Now I just need to get the nature and necromany books to display in the store and inventory lists.

        So far I have made changes to list-magic-realms.h:

        "REALM(NONE, STAT_STR, "", "", "", "")
        REALM(ARCANE, STAT_INT, "cast", "spell", "magic book", "arcane")
        REALM(PIOUS, STAT_WIS, "recite", "prayer", "prayer book", "divine")
        REALM(NATURE, STAT_WIS, "use", "druidic lore", "nature book", "nature")
        REALM(NECROMANCY, STAT_INT, "perform", "ritual", "necromancy book", "necromancy")
        "
        list-tvals.h:

        "TV(MAGIC_BOOK, "magic book")
        TV(PRAYER_BOOK, "prayer book")
        TV(NATURE_BOOK, "nature book")
        TV(NECROMANCY_BOOK, "necromancy book") "

        and obj-desc.c:

        " case TV_MAGIC_BOOK:
        if (terse)
        return "& Book~ #";
        else
        return "& Book~ of Magic Spells #";

        case TV_PRAYER_BOOK:
        if (terse)
        return "& Book~ #";
        else
        return "& Holy Book~ of Prayers #";

        case TV_NATURE_BOOK:
        if (terse)
        return "& Book~ #";
        else
        return "& Book~ of Nature Lore #";

        case TV_NECROMANCY_BOOK:
        if (terse)
        return "& Book~ #";
        else
        return "& Book~ of Necromancy #";"

        Comment

        • Pete Mack
          Prophet
          • Apr 2007
          • 6883

          #34
          The easiest way to do this would be to use priest books for druids and mage books for necromancers. That way you wouldn't need any code at all, and there wouldn't be so much junk--as it is, there's only a 50% chance of a caster being unable to use a particular book. With your change, that goes to 25%.

          That said, I have no idea how many changes are necessary, but I know how to find out: use grep (or select-string in powershell, which I have set as an alias):
          Code:
          > grep TV_MAGIC *.c
          obj-desc.c:155:        case TV_MAGIC_BOOK:
          obj-randart.c:429:           tval == TV_FOOD || tval == TV_MUSHROOM || tval == TV_MAGIC_BOOK ||
          obj-tval.c:331:        case TV_MAGIC_BOOK:
          store.c:671:        case TV_MAGIC_BOOK:
          ui-knowledge.c:1347:    {TV_MAGIC_BOOK,        "Magic Book"    },
          ui-knowledge.c:1860:        case TV_MAGIC_BOOK:
          ui-options.c:1438:    { TV_MAGIC_BOOK,    "Magic books" },
          ui-options.c:1588:        case TV_MAGIC_BOOK:
          wiz-spoil.c:122:    { TV_MAGIC_BOOK,    "Books (Mage)" },
          wiz-stats.c:934:        case TV_MAGIC_BOOK:{

          Comment

          • Nick
            Vanilla maintainer
            • Apr 2007
            • 9637

            #35
            Thanks for all the updates. Ideally a whole new school of magic should be addable by the edit files, and once you get this working I should have a good idea what code changes need to happen for that to be possible.

            It is precisely this sort of behaviour that has made Angband what it is today
            One for the Dark Lord on his dark throne
            In the Land of Mordor where the Shadows lie.

            Comment

            • Elfin Jedi
              Adept
              • Mar 2013
              • 102

              #36
              Ok, I made changes to all of these (the others (obj-desc.c:155, obj-tval.c:331, ui-knowledge.c:1347, and wiz-stats.c:934) I had already edited, with the exception of wiz-stats.c:934 which said it didn't bother using priest books because they had the same probability as magic books.)

              obj-randart.c:429: tval == TV_FOOD || tval == TV_MUSHROOM || tval == TV_MAGIC_BOOK ||
              store.c:671: case TV_MAGIC_BOOK:
              ui-knowledge.c:1860: case TV_MAGIC_BOOK:
              ui-options.c:1438: { TV_MAGIC_BOOK, "Magic books" },
              ui-options.c:1588: case TV_MAGIC_BOOK:
              wiz-spoil.c:122: { TV_MAGIC_BOOK, "Books (Mage)" },

              Unfortunately, the book names still aren't displaying. Maybe I need to look at ui-display.c or somewhere else dealing with displaying stuff?

              And it is having trouble restocking store 9, approximately 50% of the 10 or so characters I started to test this (after the 1st one crashed) closed with an error that read: "unable to (re-)stock store 9, please report this bug."

              Comment

              • Elfin Jedi
                Adept
                • Mar 2013
                • 102

                #37
                Thanks Nick

                Comment

                • Elfin Jedi
                  Adept
                  • Mar 2013
                  • 102

                  #38
                  And detecting monsters that aren't invisible, but not ones that are (permanently or temporarily):

                  effects.c

                  1368: /* Detect all non-invisible, obvious monsters */
                  1369: if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) &&
                  1370: !mflag_has(mon->mflag, MFLAG_UNAWARE)
                  1371: {
                  1372: /* Hack -- Detect the monster */
                  1373: mflag_on(mon->mflag, MFLAG_MARK);
                  1374: mflag_on(mon->mflag, MFLAG_SHOW);
                  1375:
                  1376: /* Update monster recall window */
                  1377: if (player->upkeep->monster_race == mon->race)
                  1378: /* Redraw stuff */
                  1379: player->upkeep->redraw |= (PR_MONSTER);
                  1380:
                  1381: /* Update the monster */
                  1382: update_mon(mon, cave, FALSE);
                  1383:
                  1384: /* Detect */
                  1385: monsters = TRUE;
                  1386: context->ident = TRUE;
                  1387: }
                  1388: }

                  is running into a few errors (involving these curvy brackets "{" "}" (I don't know what they are called, just that they begin and end sections of code)) & a warning:

                  effects.c:1369:84: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
                  if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) &&

                  effects.c:1371:3: error: expected ')' before '{' token
                  {
                  ^
                  effects.c:1388:2: error: expected expression before '}' token
                  }
                  ^

                  Comment

                  • Pete Mack
                    Prophet
                    • Apr 2007
                    • 6883

                    #39
                    @EJ:
                    This is when I would start up the debugger. Have you tried making some of those books always rather than normal in the text file? (At the least, the beginners books need to be, to allow the start-with-gold-no start option.)

                    Comment

                    • Pete Mack
                      Prophet
                      • Apr 2007
                      • 6883

                      #40
                      When you don't have matching openers and closers, the compiler gets horribly confused. In this case:
                      1369: if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) &&
                      1370: !mflag_has(mon->mflag, MFLAG_UNAWARE)
                      1371: {

                      is missing a closing ")"

                      The warning about && is because the precedence is sometimes non-intuitive (as in, it can get evaluated before you think it should.) And in this case, you want the || (OR) evaluated before the AND, so you absolutely need it. (In effect && has precedence like *, and || has precedence like +, so && is applied first.)

                      Here's the complete list:

                      Comment

                      • Elfin Jedi
                        Adept
                        • Mar 2013
                        • 102

                        #41
                        Originally posted by Pete Mack
                        @EJ:
                        This is when I would start up the debugger. Have you tried making some of those books always rather than normal in the text file? (At the least, the beginners books need to be, to allow the start-with-gold-no start option.)
                        Oh, good point. I never use that start option, so it didn't occur to me.

                        Comment

                        • Elfin Jedi
                          Adept
                          • Mar 2013
                          • 102

                          #42
                          Thanks for the link, it looks useful, I bookmarked the site.

                          I added a closing ")" (which it likes) right here:

                          if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) &&
                          !mflag_has(mon->mflag, MFLAG_UNAWARE))

                          But when I try to add parentheses to the && it gives me an error for each one, for the first:

                          effects.c:1369:84: error: called object is not a function or function pointer
                          if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) (&&)

                          and for the second:

                          effects.c:1369:87: error: expected identifier before ')' token
                          if (!rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE]) (&&)

                          Comment

                          • Pete Mack
                            Prophet
                            • Apr 2007
                            • 6883

                            #43
                            Here is what you probably need: Otherwise the && will execute before || (unless this is what you had in mind.)
                            if (!(rf_has(mon->race->flags, RF_INVISIBLE) || (mon->m_timed[MON_TMD_INVISIBLE])) &&
                            !mflag_has(mon->mflag, MFLAG_UNAWARE))

                            However, this is seriously confusing. You might look at De Morgan's laws and simplify.



                            Or better yet, write a little function that returns whether the monster is invisible.

                            Comment

                            • Elfin Jedi
                              Adept
                              • Mar 2013
                              • 102

                              #44
                              Originally posted by Pete Mack
                              The warning about && is because the precedence is sometimes non-intuitive (as in, it can get evaluated before you think it should.) And in this case, you want the || (OR) evaluated before the AND, so you absolutely need it. (In effect && has precedence like *, and || has precedence like +, so && is applied first.)
                              \
                              I thought that you meant that I needed to put the parentheses around the &&.

                              It was happy with the first change (the closing ")") before I added the parentheses around the &&, so if I don't need the AND parentheses it seems to make sense to just keep the first change and go on to the next invisibility check.

                              Comment

                              • Pete Mack
                                Prophet
                                • Apr 2007
                                • 6883

                                #45
                                Yikes. You have 3 conditionals in your statement, call them a, b, c. Depending on paranthesization, they will do very different things. Do you want:

                                !a || (b && !c) -- this is what you will get without parentheses.
                                Or do you want (which looks right without context)
                                !(a || b) && !c
                                which is equivalent to the more readable forms (by Demorgan's laws):
                                !a && !b && !c
                                or:
                                !(a || b || c)
                                Or possibly another alternative:
                                (!a || b) && !c

                                Comment

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