Jump to content


Photo

Distance and Gearswap question


    16 replies to this topic

    #1 Kenshi

    Kenshi

      Advanced Member

    • Members
    • PipPipPip
    • 334 posts

      Posted 02 June 2014 - 08:07 PM

      It is possible in Gearswap to cancel spell abilities and weapon skill based on the range provided in the res files and taking into account the model size of the mob?

      something like maybe using windower.ffxi.get_mob_by_target and windower.ffxi.get_spells?

      Never used predefined ranges cause they usually mess with the model size of the mobs.

       

      Thank you.



      #2 Arcon

      Arcon

        Advanced Member

      • Windower Staff
      • 1189 posts
      • LocationMunich, Germany

      Posted 02 June 2014 - 09:40 PM

      Yeah, it's possible, but the values as they are in the resources are incomplete. The (approximate) formula for calculating the actual range is this:

      distance = target.model_size + spell.range * range_mult[spell.range]

       

      Here range_mult is a table that contains multipliers. Each range has a different multiplier it uses. Here's a list of what I have compiled:

      range_mult = {
            [2] =  1.70,
            [3] = 1.490909,
            [4] = 1.44,
            [5] = 1.377778,
            [6] = 1.30,
            [7] = 1.20,
            [8] = 1.30,
            [9] = 1.377778,
           [10] = 1.45,
           [11] = 1.490909,
           [12] = 1.70,
      }


      #3 sdahlka

      sdahlka

        Advanced Member

      • Members
      • PipPipPip
      • 324 posts

        Posted 03 June 2014 - 07:08 PM

        so it would be

         

        function get_sets()

        range_mult ={
              [2]=  1.70,
              [3]=1.490909,
              [4]=1.44,
              [5]=1.377778,
              [6]=1.30,
              [7]=1.20,
              [8]=1.30,
              [9]=1.377778,
             [10]=1.45,
             [11]=1.490909,
             [12]=1.70,
        }

        ....

        end

        function precast(spell)

        if (target.model_size + spell.range * range_mult[spell.range]) < spell.target.distance then
                        cancel_spell()
                        return

        end

        ....

        end



        #4 Kenshi

        Kenshi

          Advanced Member

        • Members
        • PipPipPip
        • 334 posts

          Posted 03 June 2014 - 08:46 PM

          with that code I get the error attempt to index global 'target' (a nil value)

           

          Another question I have, it's possible in gearswap to equip different ws set for magical WS's? or I need to set them individualy?



          #5 Arcon

          Arcon

            Advanced Member

          • Windower Staff
          • 1189 posts
          • LocationMunich, Germany

          Posted 04 June 2014 - 04:11 AM

          You need spell.target.model_size, and yes, that works, although I wouldn't put the range_mult table in get_sets, but outside of it.

           

          We don't distinguish between physical and magical WS, so the latter won't work. You need to hard-code whatever you want it to switch on.



          #6 Kenshi

          Kenshi

            Advanced Member

          • Members
          • PipPipPip
          • 334 posts

            Posted 05 June 2014 - 03:21 PM

            I got it working, but had to add range 0 in the range_mult ([0] = 0) or everytime I use a range 0 spell I'll get an error.

             

            For the magical WS I was thinking on something like:

             

            function precast(spell)
            	if T{'magicalws1','magicalws2',...):contains(spell) then
            		equip(sets.precast.magicalWS)
            	end
            end
            

            I have been thinking too on how to cancel a ws if you are unable to see the mob, using the player.facing and the spell.target.x, spell.target.y and spell.target.z, but not sure how to do it. Any idea?



            #7 Arcon

            Arcon

              Advanced Member

            • Windower Staff
            • 1189 posts
            • LocationMunich, Germany

            Posted 05 June 2014 - 10:12 PM

            First, you should be using S{...} instead of T{...}. Second, you should define that outside of the function somewhere near the top of the file:

            magic_ws = S{'Cyclone', 'Sunburst', ...}

             

            Then later use the code like this:

            if magic_ws:contains(spell.english) then

             

            As for the angle, I added some functions to the vector library that should make this easier to handle (you'll need to update Windower for this to work):

            require('vectors')
             
            function precast(spell)
                if spell.target.type == 'MONSTER' then
                    local dir = V{spell.target.x, spell.target.y} - V{player.x, player.y}
                    local heading = V{}.from_radian(player.facing)
                    local angle = V{}.angle(dir, heading):degree():abs()
                    if angle > 90 then
                        print('Aborting...')
                        cancel_spell()
                        return
                    end
                end
             
               -- Other crap
            end


            #8 Kenshi

            Kenshi

              Advanced Member

            • Members
            • PipPipPip
            • 334 posts

              Posted 07 June 2014 - 01:30 PM

              Working really good, just had to add a rule for it to fire only on weapon skills and reduce the angle to 45, thx Arcon!!



              #9 Kenshi

              Kenshi

                Advanced Member

              • Members
              • PipPipPip
              • 334 posts

                Posted 09 September 2014 - 10:51 AM

                this rule not working after september update

                 

                if (target.model_size + spell.range * range_mult[spell.range]) < spell.target.distance then
                                cancel_spell()
                                return
                
                end
                

                 

                 

                its getting it always as true, its maybe a resource thing?



                #10 Kenshi

                Kenshi

                  Advanced Member

                • Members
                • PipPipPip
                • 334 posts

                  Posted 09 September 2014 - 11:07 AM

                  Updated and seems to be solved now



                  #11 Arcon

                  Arcon

                    Advanced Member

                  • Windower Staff
                  • 1189 posts
                  • LocationMunich, Germany

                  Posted 09 September 2014 - 11:19 AM

                  Yeah, model_size was broken this update, but it was fixed earlier, just needed to re-download LuaCore.



                  #12 sdahlka

                  sdahlka

                    Advanced Member

                  • Members
                  • PipPipPip
                  • 324 posts

                    Posted 10 September 2014 - 04:03 AM

                    arcon do you have a pice of code that will do the calculations for spell ranges??

                    i.e. target.model_size + spell.range * range_mult[spell.range] in reverse to get range_mult
                     
                    i ask because i noticed that some spells and ability's actually have a larger range then what this code actually gives
                     
                     
                    local range_mult = {
                            [0] = 0,
                            [2] = 1.70,
                            [3] = 1.490909,
                            [4] = 1.44,
                            [5] = 1.377778,
                            [6] = 1.30,
                            [7] = 1.20,
                            [8] = 1.30,
                            [9] = 1.377778,
                            [10] = 1.45,
                            [11] = 1.490909,
                            [12] = 1.70,
                            }
                        if (spell.target.model_size + spell.range * range_mult[spell.range]) < spell.target.distance then
                            if player.target.type == "MONSTER" then
                                add_to_chat(7,"Monster out of range of spell")
                            elseif player.target.type == "NPC" then
                                add_to_chat(7,"NPC out of range of spell")
                            else
                                add_to_chat(7,"Player out of range of spell")        
                            end
                            cancel_spell()
                            return
                        end
                     
                    im hopeing this is correct
                    (spell.target.distance / (spell.target.model_size + spell.range))

                    #13 Arcon

                    Arcon

                      Advanced Member

                    • Windower Staff
                    • 1189 posts
                    • LocationMunich, Germany

                    Posted 10 September 2014 - 07:18 AM

                    (spell.target.distance - spell.target.model_size) / spell.range


                    #14 sdahlka

                    sdahlka

                      Advanced Member

                    • Members
                    • PipPipPip
                    • 324 posts

                      Posted 13 September 2014 - 08:51 PM

                      i have been testing this for a couple of days and no mater the spell range or mob size i keep getting the same out put

                      that being
                      1.642276421172564

                      so for my calculations i would use
                      spell.target.model_size + spell.range * 1.642276421172564 == max spell distance

                      using the same size mob for all posible distances
                      spell.target.model_size = 0.30000001192093
                      spell.range = 0 to 12
                       

                       

                      12.30000001192093    max distance = 20.2
                      11.30000001192093    max distance = 18.55772357882744
                      10.30000001192093    max distance = 16.91544715765487
                      9.30000001192093    max distance = 15.27317073648231
                      8.30000001192093    max distance = 13.63089431530974
                      7.30000001192093    max distance = 11.98861789413718
                      6.30000001192093    max distance = 10.34634147296462
                      5.30000001192093    max distance = 8.704065051792051
                      4.30000001192093    max distance = 7.061788630619487
                      3.30000001192093    max distance = 5.419512209446923
                      2.30000001192093    max distance = 3.777235788274359
                      1.30000001192093    max distance = 2.134959367101795
                      0                    max distance = 0
                       
                      


                      #15 Arcon

                      Arcon

                        Advanced Member

                      • Windower Staff
                      • 1189 posts
                      • LocationMunich, Germany

                      Posted 14 September 2014 - 12:36 AM

                      Interesting, maybe they changed the range modifiers. What did you test it with?



                      #16 sdahlka

                      sdahlka

                        Advanced Member

                      • Members
                      • PipPipPip
                      • 324 posts

                        Posted 14 September 2014 - 02:45 AM

                        i tested it with

                        12 - cure

                        11 - Monomi: Ichi

                        10 - Tourbillion

                        9 - Death Ray

                        8 - Voracious Trunk

                        7 - Awful Eye

                        6 -

                        5 -

                        4 - Temporal Shift

                        3 -

                        2 - Hydro Shot

                        1 -

                        0 - (always self only)

                         

                        all the others are just guesses based on what the others said

                         

                        ofcorse i only did spells

                         

                        the way i tested

                        target mob or pc /lockon select the spell backup untill i see the targeting change to yellow the move forward till it just turns blue again cast the spell

                         

                        this is the code i used to get the numbers(in gearswap) and this creates a file with the range_mult table in it

                         

                         

                        range_mult ={}
                        range_mult.ability ={}
                        range_mult.spell ={}
                        range_mult.ws ={}
                        function precast(spell)
                            if spell.range then
                                if windower.wc_match(spell.prefix, '/jobability|/pet') then
                                    range_mult.ability[spell.range] = (spell.target.distance / (spell.target.model_size + spell.range))
                                elseif windower.wc_match(spell.prefix, '/weaponskill') then
                                    range_mult.ws[spell.range] = (spell.target.distance / (spell.target.model_size + spell.range))
                                else
                                    range_mult.spell[spell.range] = (spell.target.distance / (spell.target.model_size + spell.range))
                                end
                            end
                            file_write()
                        end
                        function file_write()
                            local file = io.open('c:/distance.lua',"w")
                            local info = {}
                            save('range_mult', range_mult)
                            file:close()
                        end
                        function basicSerialize (o)
                            if type(o) == "number" or type(o) == "boolean" then
                                return tostring(o)
                            else   -- assume it is a string
                                return string.format("%q", o)
                            end
                        end
                        function save (name, value, saved)
                            saved = saved or {}       -- initial value
                            file:write(name, " = ")
                            if type(value) == "number" or type(value) == "string" or type(value) == "boolean" then
                                file:write(basicSerialize(value), "\n")
                            elseif type(value) == "table" then
                                if saved[value] then    -- value already saved?
                                    file:write(saved[value], "\n")  -- use its previous name
                                else
                                    saved[value] = name   -- save name for next time
                                    file:write("{}\n")     -- create a new table
                                    for k,v in pairs(value) do      -- save its fields
                                        local fieldname = string.format("%s[%s]", name,
                                        basicSerialize(k))
                                        save(fieldname, v, saved)
                                    end
                                end
                            else
                                error("cannot save a " .. type(value))
                            end
                        end
                         


                        #17 sdahlka

                        sdahlka

                          Advanced Member

                        • Members
                        • PipPipPip
                        • 324 posts

                          Posted 14 September 2014 - 02:53 AM

                          i also modified the distance addon to show more them one decimal place

                          i.e. like this

                           

                          _addon.name = 'Distance'
                          _addon.author = 'Windower'
                          _addon.version = '1.0.0.1'
                          _addon.command = 'distance'
                          
                          config = require('config')
                          texts = require('texts')
                          
                          defaults = {}
                          defaults.pos = {}
                          defaults.pos.x = -178
                          defaults.pos.y = 21
                          defaults.text = {}
                          defaults.text.font = 'Arial'
                          defaults.text.size = 14
                          defaults.flags = {}
                          defaults.flags.right = true
                          
                          show_full = false
                          settings = config.load(defaults)
                          distance = texts.new(settings)
                          
                          debug.setmetatable(nil, {__index = {}, __call = functions.empty})
                          
                          windower.register_event('prerender', function()
                              local t = windower.ffxi.get_mob_by_index(windower.ffxi.get_player().target_index or 0)
                              if show_full then
                                  distance:text(t.distance:sqrt() or 0)
                              else
                                  distance:text('%.1f':format(t.distance:sqrt() or 0))
                              end
                              distance:visible(t ~= nil)
                          end)
                          
                          windower.register_event('addon command', function(command)
                              if command == 'save' then
                                  config.save(settings, 'all')
                              end
                              if command == 'show_full' then
                                  show_full = not show_full
                              end
                          end)
                           

                          then i could put in the command

                          distance show_full and have it show all the decimals






                          1 user(s) are reading this topic

                          0 members, 1 guests, 0 anonymous users