Jump to content


Photo

DressUp and NPCs?

dressupnpcs

    5 replies to this topic

    #1 Kokonoe

    Kokonoe

      Newbie

    • Members
    • Pip
    • 6 posts

      Posted 11 April 2016 - 06:53 AM

      On the github to DressUp it states:
       

       

      To do:

      Allow for monster models.

      While this is currently possible, others seem to lose their animations if transformed into a monster.


      So is there a way to use DressUp to swap to NPCs?
       



      #2 Iryoku

      Iryoku

        Advanced Member

      • Windower Staff
      • 488 posts

        Posted 11 April 2016 - 10:58 PM

        Most NPCs just use standard player models, so you would change your race and gear to match them. A few NPCs use custom models the same way monsters do, but most do not.



        #3 ibm2431

        ibm2431

          Newbie

        • Members
        • Pip
        • 3 posts

          Posted 12 April 2016 - 09:27 AM

          I've played with this some. I don't know if it's possible to do with DressUp, but it is possible in a general case.

           

          Packet 0x051 is the PC update packet, and typically contains the armor your PC should be wearing. If you capture this packet and inject a modified 'Ranged' value of 0xFFFF, this tells XI that you're supposed to be a monster. You can modify 'Face' and 'Race' to specify which monster model to use, then trigger a PC update packet (changing visible equipment), and bam, you transform into your desired mob or special NPC.

           

          Face represents which model ID to use, while Race is some sort of grouping (perhaps by expansion pack). Face IDs within the same Race set will eventually loop around when they get sufficiently large.For example, if there are X models in the "set", setting Face to be X+1 results in the same model as the first in a set. To reach other sets of models, increase Race.

           

          Example Code:
           

          require 'luau'
          packets = require('packets')
          
          function check_incoming_chunk(id, data, modified, injected, blocked)
            if (id == 0x051) then
              local update_packet = packets.parse('incoming', data)
              update_packet['Ranged'] = 0xFFFF
              update_packet['Face'] = 25
              update_packet['Race'] = 10
              return packets.build(update_packet)
            end
          end
          
          windower.register_event('incoming chunk', check_incoming_chunk)
          

           

          Will transform you into Kumhau on the next PC update packet.

           

          I don't know off the top of my head how to transform into any emote-capable NPCs. But I do know that Trusts are Race 12.

          Face: 38, Race: 12 = Shantotto II

          Face: 39, Race: 12 = Iroha

           

          Animations that the model natively has will work just fine. So you can auto-attack and cast magic as Iroha and she'll have the right animations. But if you try to do a weaponskill for a model which doesn't have it, like Sajj'aka (Face 75, Race 10), the model will get all weird and distorted for the duration of the WS. They also do not do any emotes, they simply stand there while the /em text is sent out.

           

          I don't know how to deduce which Face/Race values need to be used for a given mob (wish I did!). The ones I know came from randomly plugging numbers in. Although I do know that most Adoulin mobs tend to be Race 10, and most trusts tend to be Race 12.


          • Kokonoe likes this

          #4 Kokonoe

          Kokonoe

            Newbie

          • Members
          • Pip
          • 6 posts

            Posted 13 April 2016 - 01:44 AM

            I've played with this some. I don't know if it's possible to do with DressUp, but it is possible in a general case.

             

            Packet 0x051 is the PC update packet, and typically contains the armor your PC should be wearing. If you capture this packet and inject a modified 'Ranged' value of 0xFFFF, this tells XI that you're supposed to be a monster. You can modify 'Face' and 'Race' to specify which monster model to use, then trigger a PC update packet (changing visible equipment), and bam, you transform into your desired mob or special NPC.

             

            Face represents which model ID to use, while Race is some sort of grouping (perhaps by expansion pack). Face IDs within the same Race set will eventually loop around when they get sufficiently large.For example, if there are X models in the "set", setting Face to be X+1 results in the same model as the first in a set. To reach other sets of models, increase Race.

             

            Example Code:
             

            require 'luau'
            packets = require('packets')
            
            function check_incoming_chunk(id, data, modified, injected, blocked)
              if (id == 0x051) then
                local update_packet = packets.parse('incoming', data)
                update_packet['Ranged'] = 0xFFFF
                update_packet['Face'] = 25
                update_packet['Race'] = 10
                return packets.build(update_packet)
              end
            end
            
            windower.register_event('incoming chunk', check_incoming_chunk)
            

             

            Will transform you into Kumhau on the next PC update packet.

             

            I don't know off the top of my head how to transform into any emote-capable NPCs. But I do know that Trusts are Race 12.

            Face: 38, Race: 12 = Shantotto II

            Face: 39, Race: 12 = Iroha

             

            Animations that the model natively has will work just fine. So you can auto-attack and cast magic as Iroha and she'll have the right animations. But if you try to do a weaponskill for a model which doesn't have it, like Sajj'aka (Face 75, Race 10), the model will get all weird and distorted for the duration of the WS. They also do not do any emotes, they simply stand there while the /em text is sent out.

             

            I don't know how to deduce which Face/Race values need to be used for a given mob (wish I did!). The ones I know came from randomly plugging numbers in. Although I do know that most Adoulin mobs tend to be Race 10, and most trusts tend to be Race 12.

            And thanks for the help, much appreciated.



            #5 Iryoku

            Iryoku

              Advanced Member

            • Windower Staff
            • 488 posts

              Posted 13 April 2016 - 08:24 AM

              It's far less complicated than that. Inside the packet structure is a union something like this (note, I'm writing this from memory, so the actual structure is probably not correct, but it should suffice for demonstration purposes):

              union
              {
                  unsigned int monster;
                  struct
                  {
                      unsigned short face;
                      unsigned short race;
                      unsigned short head;
                      unsigned short body;
                      unsigned short hands;
                      unsigned short legs;
                      unsigned short feet;
                      unsigned short main;
                      unsigned short sub;
                      union
                      {
                          unsigned short ranged;
                          unsigned short monster_flag;
                      };
                  };
              };
              

               

              When the server wants to make a character look like a monster it just does:

              character.monster_flag = 0xFFFF;
              character.monster = 2367; // Shinryu
              

               

              If you're not familiar with how a union works in C++, basically the game can either treat the first 4 bytes as two 16-bit integers, or as one 32-bit integer as it pleases and it uses the 16-bit monster_flag value (which shares the same storage space as ranged) to decide which. The reason Iroha has a "Face" of 39 and a "Race" of 12. is because her model ID is 786471, which happens to have 12 in the top 16 bits and 39 in the lower 16 bits.



              #6 ibm2431

              ibm2431

                Newbie

              • Members
              • Pip
              • 3 posts

                Posted 14 April 2016 - 07:01 PM

                And now things make a lot more sense.

                So if one wanted to set a certain model, all they'd need to do is know its ID and do a conversion. Or does Windower have a set_model() function I'm not finding in the API?

                Edit: Heck, not even a "conversion". Literally just grab the bytes from the ID and set race/face.




                1 user(s) are reading this topic

                0 members, 1 guests, 0 anonymous users