Help me make my new variant! (please!)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Nick
    Vanilla maintainer
    • Apr 2007
    • 9647

    #76
    Originally posted by will_asher
    hmmm, I found this in the code for the LOSE_ALL monster attack:
    effect_simple(EF_DRAIN_STAT, source_monster(context->mon->midx), "0", STAT_STR, 0, 0, 0, 0, &context->obvious);
    Could I have one handler call another this way?
    Yes. There are several effects that do just that - do a search for effect_simple in effects.c for examples.
    One for the Dark Lord on his dark throne
    In the Land of Mordor where the Shadows lie.

    Comment

    • will_asher
      DaJAngband Maintainer
      • Apr 2007
      • 1124

      #77
      Originally posted by Nick
      Yes. There are several effects that do just that - do a search for effect_simple in effects.c for examples.
      oh good. thanks
      Will_Asher
      aka LibraryAdventurer

      My old variant DaJAngband:
      http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

      Comment

      • will_asher
        DaJAngband Maintainer
        • Apr 2007
        • 1124

        #78
        Quick question for the potion of Mediocrity:
        Is there a quick way to refer to the base stat rather than the current stat?
        (As in base STR without any bonuses from equipment)
        Will_Asher
        aka LibraryAdventurer

        My old variant DaJAngband:
        http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

        Comment

        • Nick
          Vanilla maintainer
          • Apr 2007
          • 9647

          #79
          Off the top of my head I think it's player->stat_use[i] - player->stat_add[i] (because the first is the actual stat being used and the second is the bonuses), but that would bear some checking.
          One for the Dark Lord on his dark throne
          In the Land of Mordor where the Shadows lie.

          Comment

          • will_asher
            DaJAngband Maintainer
            • Apr 2007
            • 1124

            #80
            Originally posted by Nick
            Off the top of my head I think it's player->stat_use[i] - player->stat_add[i] (because the first is the actual stat being used and the second is the bonuses), but that would bear some checking.
            thanks again
            Will_Asher
            aka LibraryAdventurer

            My old variant DaJAngband:
            http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

            Comment

            • Pete Mack
              Prophet
              • Apr 2007
              • 6883

              #81
              @Will--
              Potions with temporary bad effects are of very limited value. I usually only use !blind, !pois, !conf and the like exactly once per game--when I ID them. Very occasionally, I use them to ID runes. And that's it. Stat swap potions are more interesting.

              Comment

              • will_asher
                DaJAngband Maintainer
                • Apr 2007
                • 1124

                #82
                Originally posted by Pete Mack
                @Will--
                Potions with temporary bad effects are of very limited value. I usually only use !blind, !pois, !conf and the like exactly once per game--when I ID them. Very occasionally, I use them to ID runes. And that's it. Stat swap potions are more interesting.
                If your stats are:
                STR 18, INT 8, WIS 16, DEX 15, CON 16
                !Mediocrity will damage STR and raise INT. So drink it when you have sustain strength. It's kind of like a stat swap potion.
                Will_Asher
                aka LibraryAdventurer

                My old variant DaJAngband:
                http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

                Comment

                • will_asher
                  DaJAngband Maintainer
                  • Apr 2007
                  • 1124

                  #83
                  Working an adding duel-wielding, thinking I'd just add the off-hand attack to the shield bash code.
                  I added a parameter to two functions, changing it everywhere the function is used:

                  bool attempt_shield_bash(struct player *p, struct loc grid, bool *fear, bool offhandhit)
                  bool py_attack_real(struct player *p, struct loc grid, bool *fear, bool offhand)

                  In py_attack_real(), I have this:
                  /* The weapon used */
                  struct object *obj = equipped_item_by_slot_name(p, "weapon");

                  /* off-weapon attack */
                  if (offhand) obj = equipped_item_by_slot_name(p, "shield");

                  In attempt_shield_bash(), after calculating the chance for an off-hand attack (similar to the way a shield bash works), I have this:
                  if (offhandhit) {
                  if (py_attack_real(p, grid, &fear, true)) return true;
                  }
                  Here's it's giving me a "differs in levels of indirection" warning on that line. What does that mean?
                  Can you see what I did wrong from this?

                  If I remove the ampersand next to "fear", the warning goes away, but I want to make sure that is the right way to do it.

                  EDIT: I compiled after just removing the ampersand, and it's crashing when attacking with the off-hand weapon, so something's not right.
                  Last edited by will_asher; April 30, 2021, 10:23.
                  Will_Asher
                  aka LibraryAdventurer

                  My old variant DaJAngband:
                  http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

                  Comment

                  • backwardsEric
                    Knight
                    • Aug 2019
                    • 531

                    #84
                    Originally posted by will_asher
                    In attempt_shield_bash(), after calculating the chance for an off-hand attack (similar to the way a shield bash works), I have this:
                    if (offhandhit) {
                    if (py_attack_real(p, grid, &fear, true)) return true;
                    }
                    Here's it's giving me a "differs in levels of indirection" warning on that line. What does that mean?
                    Can you see what I did wrong from this?

                    If I remove the ampersand next to "fear", the warning goes away, but I want to make sure that is the right way to do it.

                    EDIT: I compiled after just removing the ampersand, and it's crashing when attacking with the off-hand weapon, so something's not right.
                    Removing the ampersand before "fear" in that call to py_attack_real() from attempt_shield_bash() is right. The ampersand is the "take the address of the argument" operator. The type of its result is a pointer to the type of the argument. Before you corrected that call, the ampersand was generating a bool** (a pointer to a pointer to a bool) while py_attack_real() was declared as expecting a bool* (a pointer to bool). The mismatch between the bool** and bool* was the cause of the error message ("levels of indirection" is the common way to refer to the number of asterisks in a pointer type).

                    As for the behavior after fixing the compiler error, you'll need to distinguish between types of crashes. It could be an assertion failure. Those are from checks (via assert() statements in the code itself) that the state of the program is as expected. You may get those as you modify Angband because someone before you may thought something like, "The object the code works with here has to be in the weapon slot. I'll verify that by adding 'assert(object_slot(obj) == EQUIP_WEAPON);'.", and your change means that assumption is no longer valid. For those, you'll have to examine the assertion and the code after it that presumably depends on that assumption. Then either modify that code and the assertion to be compatible with your other change or modify or discard your other change so it will work with the code protected by that assertion.

                    Other types of crashes, segmentation faults and illegal instructions, are due to bad logic in the code, frequently involving the use of pointers and sometimes well before the point at which the crash occurred. Most of those crashes may be your fault, but some could be logic problems in the base Angband code (or stuff in the libraries that Angband calls) that had not been recognized because nothing before set up the necessary conditions for the crash to occur.

                    Comment

                    • Julian
                      Adept
                      • Apr 2021
                      • 122

                      #85
                      Originally posted by will_asher
                      In attempt_shield_bash(), after calculating the chance for an off-hand attack (similar to the way a shield bash works), I have this:
                      if (offhandhit) {
                      if (py_attack_real(p, grid, &fear, true)) return true;
                      }
                      Here's it's giving me a "differs in levels of indirection" warning on that line. What does that mean?
                      Can you see what I did wrong from this?
                      We can’t see what you’re doing wrong in the limited context, because we can’t see where the compiler is seeing a pointer to a thing where it’s expecting the thing. (Or vice versa.)

                      Having actually looked at the code, it was likely fear, since it’s passed into attempt_shield_bash() as a pointer already, and that’s what py_attack_real() wants, not a pointer to a pointer.

                      If I remove the ampersand next to "fear", the warning goes away, but I want to make sure that is the right way to do it.

                      EDIT: I compiled after just removing the ampersand, and it's crashing when attacking with the off-hand weapon, so something's not right.
                      Yes, but that change was (probably) actually correct, so it’s something else.

                      Pointers in C (and strings and arrays — they’re all the same thing) are very easy to get wrong if you don’t know what you’re going, and trying to muddle along, asking questions on the Angband forums whenever something blows up is going to be a very slow and painful process for everyone involved. Find yourself a C tutorial — there are tons of free ones online.

                      Comment

                      • Pete Mack
                        Prophet
                        • Apr 2007
                        • 6883

                        #86
                        Treat compiler warnings about indirection as hard errors, and you most likely won't go wrong. That said, when a program crashes, we need to know the line number of the crash, and the exact error message. In any case, this is the point at which you should be running RubberBand from the debugger, so you can see the value of variables that caused the crash.

                        Comment

                        • will_asher
                          DaJAngband Maintainer
                          • Apr 2007
                          • 1124

                          #87
                          yeah, I'd almost forgotten Visual Studio comes with a debugger. I need to remind myself how to use it...
                          Will_Asher
                          aka LibraryAdventurer

                          My old variant DaJAngband:
                          http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

                          Comment

                          • will_asher
                            DaJAngband Maintainer
                            • Apr 2007
                            • 1124

                            #88
                            The problem seems to be something about this part:
                            Code:
                            	/* The weapon used */
                            	struct object *obj = equipped_item_by_slot_name(p, "weapon");
                            
                            	/* off-weapon attack */
                            	if (offhand) obj = equipped_item_by_slot_name(p, "shield");
                            
                            	/* Information about the attack */
                            	int chance = chance_of_melee_hit(p, obj);
                            The debugger is saying
                            "Exception thrown: read access violation.
                            weapon was 0xDDDDDDDD."
                            But I don't understand why the assignment to "obj" is working for the main weapon but not for the off-hand weapon in the shield slot.
                            The line number it gives me is when it tries to do something with the "obj" (which turns into "weapon") in chance_of_melee_hit() here:
                            Code:
                            int chance_of_melee_hit(const struct player *p, const struct object *weapon)
                            {
                            	int chance, bonus = p->state.to_h;
                            
                            	if (weapon)
                            *>*		bonus += weapon->to_h;
                            	chance = p->state.skills[SKILL_TO_HIT_MELEE] + bonus * 
                            		BTH_PLUS_ADJ;
                            	return chance;
                            }
                            but if it passed the "if (weapon)" part, shouldn't it be able to get the "to_h" from the weapon?

                            EDIT: I think I fixed the problem. Apparently the name of the slot is "arm" not "shield"...
                            Last edited by will_asher; May 1, 2021, 07:02.
                            Will_Asher
                            aka LibraryAdventurer

                            My old variant DaJAngband:
                            http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

                            Comment

                            • fph
                              Veteran
                              • Apr 2009
                              • 1030

                              #89
                              Unfortunately memory accesses are hard to debug because the true error often lies somewhere else than where the debugger reports. In this case, the true error is where you write an invalid value into `obj`, but the debugger only tells you when you try to use that value many lines later. C is brutal in this respect, because most memory management has to be done manually.

                              In this case, I would suggest to add an error check so that the game crashes immediately when you pass equipped_item_by_slot_name a wrong slot name. "Fail fast" is often a good idea.
                              --
                              Dive fast, die young, leave a high-CHA corpse.

                              Comment

                              • Pete Mack
                                Prophet
                                • Apr 2007
                                • 6883

                                #90
                                @fph--
                                This isn't a memory error. It's an ordinary pointer bug that can be discovered by watching values in the debugger. But I don't know the problem by looking at this code fragment. Off the top of my head, it looks like uninitialized memory in debug mode being accessed. I am guessing that 0xDDDDDDDD is MS debugger speak for 0x0BADBEEF in the classical lexicon.
                                Last edited by Pete Mack; May 1, 2021, 13:07.

                                Comment

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