New Temple+ Available

Discussion in 'General Modification' started by _doug_, May 6, 2020.

Remove all ads!
Tags:
  1. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    So you get these crashes just by entering the earth node? Can you send a save? (I just tried the same but had no crashes)
     
  2. Isewein

    Isewein Established Member

    Joined:
    Dec 10, 2020
    Messages:
    108
    Likes Received:
    10
    Here you go. It's not reliably reproducible though, in fact it seems somewhat random. Maybe even dependent on which PC is used to enter...
     

    Attached Files:

    Sitra Achara likes this.
  3. Isewein

    Isewein Established Member

    Joined:
    Dec 10, 2020
    Messages:
    108
    Likes Received:
    10
    After surviving the Balor fight, I ran into another and this time sadly more serious bug - which I unfortunately only recognised as such after having gone back to Hommlet to do some crafting, etc. It seems that something got messed up with the myriad of buffs I applied for that fight. Some of the visual effects do not disappear even after weeks of resting. This seems to be indicative of a serious problem, because now many spells I have my goons cast on each other "fizzle" (healing spells, for instance). Maybe Spell Resistance somehow became permanent, but isn't it only supposed to affect hostile spells anyway? I would hate to have to do that Balor fight again, maybe there is a way to un-corrupt the save? Thank you very much!

    PS: Actually, it only affects lower level spells, so it would seem like the culprit is a Lesser Globe of Invulnerability effect somehow rendered permanent.
     

    Attached Files:

    Last edited: Sep 24, 2021
  4. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    Yeah, it's Minor Globe that somehow became permanent.
    You can fix it by going to Jaroo for spell permanency removal. It's an interesting case though, because it got past the anti-spell permanency measure I added for next version, so I'll have to improve it.
     
    Isewein likes this.
  5. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    That's exactly what I needed!
    I can reliably trigger the crash by entering the node, reloading the save, and then doing it again. Thank you!!!

    Edit: well actually it's random. But around 50% as you said, and always crashes at the same point, so it's more than enough.
     
  6. Isewein

    Isewein Established Member

    Joined:
    Dec 10, 2020
    Messages:
    108
    Likes Received:
    10
    Brilliant, thank you.

    Unrelated question: What does the magic armour property Mobility do? I assume it grants the wearer the benefit of the Mobility feat?
     
  7. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    Alright, more on that: This is actually caused due to having more than 3 NPCs.

    It's happening in a little function that chooses which NPCs comments on the map you just visited for the first time. It has a fixed sized array corresponding to the original limit of 3 NPCs, so if you have more than that it can select junk data out of the array bounds. Also your crash chance assessment was very accurate - with 5 NPCs, the probability of that is exactly 2/5, heh.

    It also appears to be buggy in another subtle way - it's supposed to check whether each NPC has a comment on the specific map, but the check is faulty, which can cause the engine to try to play a missing line, hence skipping it (rather than from an NPC that actually has a valid one).

    So the good news is that this is all easy to fix (and avoid - just roll d5 to avoid crash when first entering a map :)). The bad news is that it's not the object corruption issue I've been trying to chase...
     
    anatoliy likes this.
  8. Isewein

    Isewein Established Member

    Joined:
    Dec 10, 2020
    Messages:
    108
    Likes Received:
    10
    Interesting. I don't think I have ever heard NPC comments upon entering a new area, although I have noticed them while browsing the dialogue files. Maybe having too many of them around is why.
     
  9. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,745
    Likes Received:
    375
    Elmo and Spugnoir would pretty reliably comment when you arrive at Emridy Meadows, and for memory you get something when you first arrive at Nulb. There's a lot that don't fire, which leads to...
    Funny you should bring all that up because I meant to ask you about that (and I mean, "decided to in the last 24 hours"). I have been planning to just manually script a lot of this stuff similar to what I did with the death lines and the enter combat ones.

    Specifically I am thinking of the comments when players approach a certain thing rather than map. So for instance when you first get to any of the Elemental Temples, or the warded doors, or the Throne, or approach Prince Thrommel (I tihnk Elmo and Zaxis have scripted responses but every NPC should say some variant on, "eek a vampire!") Is there any actual code to make that lot happen? Also, what is meant to trigger them - is that what OSCF_TAGGED_SCENERY is for?

    EDIT: Also, could the problem you identifed be fixed by putting in empty but functional lines in the dlg files?
     
  10. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    The OSCF_TAGGED_SCENERY is not actually checked as far as I can tell, only obj_f_name.

    Here are the relevant pieces of code:

    Code:
    void __cdecl GetTaggedSceneryVoiceLine(ObjHndl obj, ObjHndl pc, ObjHndl objSeen, char *textOut, int *soundIdOut)
    {
      int nameOffset; // eax@1
    
      nameOffset = GetInt32(objSeen, obj_f_name) - 1800;
      if ( nameOffset < 0 || nameOffset > 99 )
      {
        *textOut = 0;
        *soundIdOut = -1;
      }
      else
      {
        GetNpcVoiceLine(obj, pc, textOut, soundIdOut, nameOffset + 4100, nameOffset + 4100, nameOffset + 12090);
      }
    }
    
    Code:
    void __cdecl MarkTaggedScenerySeenAndPlayVoice(ObjHndl objSeen)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      v7 = 0;
      ObjListVicinity(objSeen, OLC_CRITTERS, &listResult);
      v1 = listResult.objects;
      if ( listResult.objects )
      {
        while ( 1 )
        {
          pc.handle = GetFellowPc(v1->item.handle).handle;
          v3 = HIDWORD(pc.handle);
          v4 = pc.handle;
          GetTaggedSceneryVoiceLine(v1->item.handle, pc, objSeen, text, &soundId);
          if ( PlayCritterVoiceLine(v1->item.handle, (ObjHndl)__PAIR__(v3, v4), text, soundId) )
            break;
          v1 = v1->item.next;
          if ( !v1 )
            goto LABEL_6;
        }
        v7 = 1;
      }
    LABEL_6:
      ObjListFree(&listResult);
      if ( v7 )
      {
        v5 = GetInt32(objSeen, obj_f_name);
        v6 = 0;
        while ( nameListSeen[v6] )
        {
          if ( ++v6 >= 100 )
            return;
        }
        nameListSeen[v6] = v5;
      }
    }
    

    Time event code for Search time events: (fires every second)
    Code:
    signed int __cdecl SearchTimeEventExpires(TimeEvent *evt)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      v1 = evt->params[0].value0;
      v2 = evt->params[0].value1;
      v3 = evt->params[1].value0;
      v4 = *(_QWORD *)&evt->params[0].value0 == 0i64;
      v13 = evt->params[0].value1;
      v14 = v3;
      if ( !v4 )
      {
        LOBYTE(v5) = IsCombatActive();
        if ( !v5 )
        {
          ObjListVicinity((ObjHndl)__PAIR__(v2, v1), OLC_ALL, &listResult);
          v6 = listResult.objects;
          if ( listResult.objects )
          {
            do
            {
              v7 = GetInt32(v6->item.handle, obj_f_name);
              if ( v7 >= 1800
                && v7 <= 1979
                && !TaggedSceneryWasSeen(v6->item.handle)
                && HasLineOfAttack((ObjHndl)__PAIR__(v2, v1), v6->item.handle, 0) )
              {
                MarkTaggedScenerySeenAndPlayVoice(v6->item.handle);
              }
              if ( v6->item.handle.handle
                && GetInt32(v6->item.handle, obj_f_secretdoor_flags) & 0x10000
                && !secretDoorIsRevealed(v6->item.handle) )
              {
                SearchEventSecretDoorDetect(v6->item.handle, (ObjHndl)__PAIR__(v2, v1));
              }
              v8 = HIDWORD(v6->item.handle.handle);
              v9 = v6->item.handle.handle;
              if ( GetInt32(v6->item.handle, obj_f_type) == 14
                && GetInt32((ObjHndl)__PAIR__(v8, v9), obj_f_npc_flags) & 0x40000000
                && !BossMonsterSeen(v6->item.handle)
                && HasLineOfAttack((ObjHndl)__PAIR__(v13, v1), v6->item.handle, 0) )
              {
                MarkBossMonsterSeenAndPlayVoice(v6->item.handle);
              }
              if ( !zuggtmoyFound && GetInt32(v6->item.handle, obj_f_type) == 14 )
              {
                v10 = GetProto(v6->item.handle);
                if ( v10 == 14265 || v10 == 14264 )
                {
                  if ( HasLineOfAttack((ObjHndl)__PAIR__(v13, v1), v6->item.handle, 0) )
                  {
                    zuggtmoyFound = 1;
                    SetNofog();
                  }
                }
              }
              v6 = v6->item.next;
              v2 = v13;
            }
            while ( v6 );
          }
          ObjListFree(&listResult);
        }
        timeDelta.Days = 0;
        timeDelta.msecs = 1000;
        if ( v14 )
          timeDelta.msecs += RNG(0, 1000);
        nextEvt.system = TimeEventType_Search;
        nextEvt.params[0].value0 = v1;
        nextEvt.params[0].value1 = v2;
        nextEvt.params[1].value0 = 0;
        TimeEventScheduleSimple(&nextEvt, &timeDelta);
      }
      return 1;
    }
    
    Code that actually plays the line: (I think this is the part that's broken, perhaps due to IsPartyPanterTextOn() and IsPartyBanterVoiceOn() not being properly connected to the configs)
    Code:
    signed int __cdecl PlayCritterVoiceLine(ObjHndl obj, ObjHndl objAddressed, char *text, int soundId)
    {
      int v4; // ebx@1
      signed int result; // eax@8
    
      v4 = 0;
      if ( *text )
      {
        if ( GetInt32(obj, obj_f_type) == 13 )
          v4 = 2;
        if ( IsPartyPanterTextOn() )
        {
          FloatText_100A2E60(obj, v4, text, 0);
          TextFloatSetDuration(obj, 3);
        }
        if ( IsPartyBanterVoiceOn() )
          DialogPlayVoiceSound(obj, objAddressed, soundId);
        result = 1;
      }
      else
      {
        result = 0;
      }
      return result;
    }
    BTW note that this suffers the same issue as the secret door bug - if you quit a game to main menu and then start a new game, the namesSeen List isn't cleared.
     
    Last edited: Sep 25, 2021
  11. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    So about ther scenery banter, I think it does work, but many of these comments are just text only and you need to have the "Party Banter Text" option enabled.
    For example:

    this is what happens when you enter Thrommel's room with "Banter text" enabled:

    upload_2021-9-25_8-0-20.png
    Also, it doesn't give priority to NPCs, unlike the map visited banter.
     
    anatoliy and Isewein like this.
  12. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    Alright, this will now float a text bubble as of next version, and also prioritize NPCs with voices, so you'll get to see a lot more of these:
    Templedoor.jpg
    upload_2021-9-25_10-14-18.png
     
    Isewein and anatoliy like this.
  13. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,745
    Likes Received:
    375
    Ha! Well that saved untold hours of my life. God bless you sir, I've been trying to fix that for 17 years.

    Quick follow-up - if its not OSCF_TAGGED_SCENERY that triggers it - just the name - is there a relation between names and the relevant dlg lines? I am thinking in terms of adding new stuff for Verbobonc and beyond.

    EDIT: Tried to find where I first started looking into this it seems to be from THIS thread of all things, dear lord what a trip down the rabbit-hole.
     
    Last edited: Sep 25, 2021
  14. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,627
    Likes Received:
    538
    Yeah, like it says above, it plays line 12090 + (name - 1800). For PCs or NPCs without specific lines there should be some "generic answer dlg", I think that's what the 4100 refers to.
     
  15. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,745
    Likes Received:
    375
    Sorry, I missed that. Name - 1800: got it!

    And re the generic dialogue - turns out I figured that out in 2005 - I just didn't know what to do with it ;)

    PROOF
     
Our Host!