Item Search
     
BG-Wiki Search
+ Reply to Thread
Page 3 of 294 FirstFirst 1 2 3 4 5 13 53 ... LastLast
Results 41 to 60 of 5878

Thread: Gearswap Help Thread!     submit to reddit submit to twitter submit to tumblr

  1. #41
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    For whatever reason, "Pet:" is its own augment in the extdata. I will look at this tomorrow. Went and got some Hagondes. Pieces with normal MAB this morning, one of which had the same amount as my avater MAB for that slot I think. Should be able to test it.

  2. #42

    Well, I decided to try an easier job than sch for my first gearswap lua. So I did thief, I actually got to test it last night and it needs a bit of work still, but I am very satisfied with it. I will be looking to do some more with gearswap, it was very easy to do, and it works great for sneak attack and trick attack processing. Here it is:

    THF.lua v 1.1 http://pastebin.com/Eisf7xRQ

    TODOs:

    self_command toggle actions
    build_master_sets() - fix loop to build all master sets.
    get better gear for my thief... :D

  3. #43
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    In precast(), I can do the following:

    Code:
    	if spell.name == 'Cure' and spell.target.raw == '<me>' then
    		change_target('<stpc>')
    		return
    	end
    That is, if the macro target was explicit, I can change it to a selection and have it go back and bring up the selection prompt. The return is necessary to prevent it from equipping precast gear before the target is selected.

    However if I do this:

    Code:
    	if spell.name == 'Cure' and spell.target.raw == '<stpc>' then
    		change_target('<stpt>')
    		return
    	end
    It fails. Turns out that if I use <stpc> or whatever in a macro, at the time that precast() is called it's been updated to <lastst>. I can change <lastst> to an <st*> target and it will attempt to reselect a target, however I can't seem to get it to change which <st*> method is being used before the initial selection.

  4. #44
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    Yeah, this is an old issue on the bugtracker. It's a pain in the ass to deal with <st*> targets because they're at the interface of shortcuts and GearSwap. Basically, <st*> can't be made to work with changetarget without great pain. Here's why:

    SE coded the <st*> targeting system in a super ghetto way. Every subtarget selection you make is pushed through the outgoing text buffer as /prefix "spell name" MobID#. Not kidding. When you hit enter, they set a flag so that MobID# will be accepted as a target, and then they push it through. So when you use /ma "Cure" <stpc>, the client pulls up a subtarget. When you make a selection, it acts like you just typed /ma "Cure" 125230 (or whatever your target's mobID happens to be.) So I actually see every subtarget command twice with both GearSwap and Shortcuts.

    Currently GearSwap doesn't interpret <st*> targets, because <st*> commands aren't actually targets yet. There's no defined target until you hit enter, at which point I can no longer change what type of subtarget cursor you pull up. What I need to do in order to implement this is:
    * On <st*> target, clone the current user environment in such a way that it is sandboxed both from the real user environment and from the global variables that I expose to the user environment.
    * Swap the change_target function out for another one.
    * Pass in the spell information with spell.target.raw but no other spell.target information.
    * Look to see whether or not change_target was used. If it was, alter the target and pass that back.
    * Delete the duplicate user environment.

    Sandboxing in Lua is tricky and frankly I'm not very good at it. This is a pain in the ass, which is why it's one of my oldest issues on the bugtracker.

  5. #45
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Actually, since you mentioned it, this would probably actually be easier to do in Shortcuts than in GearSwap. It's essentially just a rule for rewriting the macro before it's executed.

    What I'm specifically trying to do: set it so that I can optionally change <stal> macro targets to either <stpt> or <stpc>, depending on what's convenient for what I'm doing.

    If there was a reasonable way to define a rule for Shortcuts to use, I could call that via a self_command()/send_command() in GearSwap.

    The other use I have for it is generic mappings for avatar blood pacts, and really all that will be doing will be converting a self_command to a proper macro, which means that there's no target to change anyway.

    So all that's really needed is to allow for user code to interact with Shortcuts, with hooks for self_command() (to change state variables) and a precast() that can change what Shortcuts built.

  6. #46
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Either that, or a pretarget() function in GearSwap that would be the only place it's valid to change the target (ie: define change_target() as a function local to the pretarget() hook so that it will throw an error if used anywhere else).

    Edit: or rather, maybe a change_targetting() function (local to pretarget) that allow changes to <st>/etc, whereas change_target() would only be valid if given an explicit value (either <me>, <t>, or a name).

  7. #47
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    Do you mean converting <stnpc> to <stpc> for commands when the former is invalid? That would be trivial to do in shortcuts but I am not sure I do it. The harder part is when people try to convert <stpc> to stpt or stal when they are in parties or alliances. Ultimately I need a real solution contained inside gearswap.

  8. #48
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Ok, the idea is bouncing around in my head a bit more, trying to figure out if there are other ways that change_target can work that might need to be accounted for, and where my idea wouldn't be sufficient.

    Aside: I can come up with a couple examples that require knowledge of player buffs and such in order to decide how to change the target, so relegating the change target code to Shortcuts doesn't really work. Ignore that idea.


    change_targetting() -- Change the <st*> type used for selecting a target. What if you don't want an <st*> selection? Set it to None? What would that mean? Set it to <t>? How is that different from change_target()?

    Overall, seems to be change_target() plus explicitly allowing selection targets. Only reasonable to use before targetting takes place.


    change_target() -- Example: brd macro that uses <stpt>. If Pianissimo is up, can go through as normal. If not, change the target to <me>. This assumes the user wants to handle Pianissimo manually rather than automatically. There's probly slightly better ways to handle this, but it's the only example that comes to mind to describe where you'd want to change the target after selection takes place, but without changing the selection routine itself.

    Seems reasonable for this to be valid after targetting takes place, and before the spell is actually cast. <st*> values are not valid.


    change_currenttarget() -- Change the target that your gold cursor is on. (Note: I'm not sure this is easily doable, and it's certainly possible to live without it; it just came up as related to the general idea of what change_target() can/might be able to do.) In a lot of fights your current target may regularly change, making finding the target you actually want to select more of a hassle.

    For example, in most fights I keep the mob targetted. That way when I use an <stpt> macro, it defaults directly to me, and I know I can cursor up or down a set number of times to get to specific people. If my current target changes to one of the other players then the selection target starts on them, which can make it confusing (though not necessarily bad, if I want to focus explictly on them).

    I can see this being situatonally useful, including setting the default target before the selection target is activated, as well as setting a default target after the spell is cast. Explicit values are valid, but not selection values.


    So maybe:

    change_targetting()
    -- Valid values of <me>, <t>, <bt>, <ft>, any <st*> selection (ie: any of the abstract target types), but not direct names(?). Function only valid in pretarget().
    -- Would be defined as a local function within gearswap's pretarget() function wrapper, such that it's only in scope for the user in pretarget().
    -- Would replace the first instance of the spell text input.

    change_target()
    -- Can change the spell target to any explicit value (ie: any non-selection abstract target type, or a name). Function only valid in precast().
    -- Would be defined as a local function within gearswap's precast() function wrapper, such that it's only in scope for the user in precast().
    -- Would replace the second instance of the spell text input.

    change_currenttarget()
    -- Change currently main cursor target to a specific individual (including <me>, <bt>, <ft>). Valid at any time (if it's possible to do).
    -- Would be generally accessible.

    The local function scope keeps the functions from being used at inappropriate times (such as changing the target on midcast). I can't think of any reason offhand why you'd need to duplicate the user environment at that point, though I'm not sure there might not be other reasons.

  9. #49
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    I agree that I should probably scope functions so that they cannot be used at inappropriate times. However, I still think the process I explained is the correct solution. Clone the user environment and give it all the normal information except for normal spell.target info (but do give it spell.target.raw) and set some kind of flag indicating it's using a subtarget, and see whether it tries to change targets. If it doesn't, then behave as I currently do and let the <st*> targ pass through. If it does, blank the input, change the target to what it dictates, and send it. This will repeat the process with the new (correct) target. If it passes, wait for the player to select a subtarget as I currently do. When they select a subtarget, send all the relevant spell.target information to the real user environment and proceed as usual.

    This almost invites users to create infinite loops using change_target() in their user files, which they would then blame on gearswap, but I still think it's the right way to go.

  10. #50
    Faster than Walt Flanagan's Dog
    Join Date
    May 2008
    Posts
    206
    BG Level
    4
    FFXI Server
    Asura

    I'm trying to make a gs for my sam but running into some problems given my limited programming abilities. Basically I want different sets based on the weapon I have equipped but I think I have the syntax screwed up and it errors out when I try to load it, here is a sample of what I'm trying:
    Code:
    sets.WS = {}
    	
    	sets.WS.Masamune["Tachi: Fudo"] = {ammo="Thew Bomblet",head="Otomi Helm",neck="Justiciar's Torque",ear1="Moonshade Earring",ear2="Brutal Earring",
    		body="Phorcys Korazin",hands="Miki. Gauntlets",ring1="Rajas Ring",ring2="Pyrosoul Ring",
    		back="Takaha Mantle",waist="Windbuffet Belt",legs="Miki. Cuisses",feet="Mikinaak Greaves"}
    		
    	sets.WS.Tsurumaru["Tachi: Fudo"] = set_combine(sets.WS.Masamune['Tachi: Fudo'],{back="Buquwik Cape"})
    It errors out with attempt to index field 'Masamune' (a nil value). Any ideas how i should be coding this? Also once I get past that when I'm calling it in precast would it be like:
    Code:
    function precast(spell,action)
    	verify_equip()
    	if sets.JA[spell.english] then
    		equip(sets.JA[spell.english])
    	elseif spell.type=="WeaponSkill" then
    		if sets.WS[player.equipment.main[spell.english]] then equip(sets.WS[player.equipment.main[spell.english]]) 
    		else equip(sets.WS.General) end
    	end
    end
    Thanks again for any input

  11. #51
    Cerberus
    Join Date
    Jun 2007
    Posts
    411
    BG Level
    4
    FFXIV Character
    Ninita Nita
    FFXIV Server
    Excalibur
    FFXI Server
    Shiva
    WoW Realm
    Gnomeregan

    Quote Originally Posted by solkanar View Post
    I'm trying to make a gs for my sam but running into some problems given my limited programming abilities. Basically I want different sets based on the weapon I have equipped but I think I have the syntax screwed up and it errors out when I try to load it, here is a sample of what I'm trying:
    Code:
    sets.WS = {}
    	
    	sets.WS.Masamune["Tachi: Fudo"] = {ammo="Thew Bomblet",head="Otomi Helm",neck="Justiciar's Torque",ear1="Moonshade Earring",ear2="Brutal Earring",
    		body="Phorcys Korazin",hands="Miki. Gauntlets",ring1="Rajas Ring",ring2="Pyrosoul Ring",
    		back="Takaha Mantle",waist="Windbuffet Belt",legs="Miki. Cuisses",feet="Mikinaak Greaves"}
    		
    	sets.WS.Tsurumaru["Tachi: Fudo"] = set_combine(sets.WS.Masamune['Tachi: Fudo'],{back="Buquwik Cape"})
    It errors out with attempt to index field 'Masamune' (a nil value). Any ideas how i should be coding this? Also once I get past that when I'm calling it in precast would it be like:
    Code:
    function precast(spell,action)
    	verify_equip()
    	if sets.JA[spell.english] then
    		equip(sets.JA[spell.english])
    	elseif spell.type=="WeaponSkill" then
    		if sets.WS[player.equipment.main[spell.english]] then equip(sets.WS[player.equipment.main[spell.english]]) 
    		else equip(sets.WS.General) end
    	end
    end
    Thanks again for any input
    you need sets.WS.Masamune = {} before you try to sets.WS.Masamune['Tachi:Fudo']

  12. #52
    Faster than Walt Flanagan's Dog
    Join Date
    May 2008
    Posts
    206
    BG Level
    4
    FFXI Server
    Asura

    Thanks again Nitrous! That did it.

  13. #53
    listen!
    Join Date
    Apr 2011
    Posts
    7,236
    BG Level
    8
    FFXI Server
    Sylph

    Sorry if it's obvious, i haven't looked into this much, but is there any way to set gear for precast/midcast/aftercast all in one place? It looks like they need to be separated, which is turning me off from trying this, because it's going to result in massive amounts of duplicated code everywhere, and make changes a huge pain in the ass.

  14. #54
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Quote Originally Posted by hey View Post
    Sorry if it's obvious, i haven't looked into this much, but is there any way to set gear for precast/midcast/aftercast all in one place? It looks like they need to be separated, which is turning me off from trying this, because it's going to result in massive amounts of duplicated code everywhere, and make changes a huge pain in the ass.
    Depends on what you mean by "all in one place".

    If you mean defining the sets and their contents, that's all done in the get_sets() function.

    If you mean applying those changes, that's handled in three separate functions: precast(), midcast() and aftercast(). Since you were doing that all already in Spellcast with the when="xxxcast" attributes, this actually makes things more organized and easier to work with.

    As for code duplication, that's what functions are for. Put every discrete chunk of logic in its own function and you don't have to duplicate it all over the place. Just call it when you need it.

    For a comparison on relative amounts of coding, the brd xml that I'm trying to duplicate is about 1000 lines long. The two include files it draws from (with, admittedly, lots of stuff that's either not relevant to brd, or that I haven't reimplimented) are 2200 and 600 lines long. Meanwhile, the lua version is 400 lines, plus a 200 line include file, and is probably about 90% done. So my total lines of code has gone down by over 80%.

  15. #55
    listen!
    Join Date
    Apr 2011
    Posts
    7,236
    BG Level
    8
    FFXI Server
    Sylph

    If you mean applying those changes, that's handled in three separate functions: precast(), midcast() and aftercast(). Since you were doing that all already in Spellcast with the when="xxxcast" attributes, this actually makes things more organized and easier to work with.
    No, this makes it significantly less organized, because i need a separate if spell = whatever 3 times.

    Code:
    <if spell="Stoneskin">
        <equip when="precast" set="fastcast" />
        <equip when="midcast" set="Stoneskin" />
        <equip when="aftercast" set="idle" />
    </if>
    turns into

    Code:
         if spell.english=="Stoneskin" then
                equip(sets.fastcast)
            end
    Code:
        if spell.english=="Stoneskin" then
            equip(sets.stoneskin)
        end
    Code:
        if spell.english=="Stoneskin" then
            equip(sets.Idle)
        end
    All with hundreds/thousands of lines between them. Code duplication is not avoidable here, or in common cases where conditions are slightly different for many things. And with spellcast i can just ctrl+f stoneskin, and find everything related to stoneskin all in one place. It's not nearly so simple with this.

  16. #56
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Quote Originally Posted by Byrthnoth View Post
    I agree that I should probably scope functions so that they cannot be used at inappropriate times. However, I still think the process I explained is the correct solution. Clone the user environment and give it all the normal information except for normal spell.target info (but do give it spell.target.raw) and set some kind of flag indicating it's using a subtarget, and see whether it tries to change targets. If it doesn't, then behave as I currently do and let the <st*> targ pass through. If it does, blank the input, change the target to what it dictates, and send it. This will repeat the process with the new (correct) target. If it passes, wait for the player to select a subtarget as I currently do. When they select a subtarget, send all the relevant spell.target information to the real user environment and proceed as usual.

    This almost invites users to create infinite loops using change_target() in their user files, which they would then blame on gearswap, but I still think it's the right way to go.
    The logical order of things that you outlined seems fairly sound, but I still don't see why you need to duplicate the user environment, aside from attempting to maintain only the precast() hook instead of adding the pretarget() hook. Is it to prevent the user from explicitly modifying the spell.target value rather than going through the function call? Or is changing the target to an <st*> value going to cause another raised event that looks like you need to call pretarget() again, trapping you in a loop?

    Code:
    user enters command
    Shortcuts modifies as necessary
    GearSwap gets it
    Send to pretarget()
        may call change_targetting().  <st*> values are acceptable.  May want to reject any non-abstract targets (for the sake of this function call only; has no effect on initial player input).
        if change_targetting() called, make adjustments
    if target is an <st*> value, send to game for targetting routine
    game selects a target
    GearSwap gets it
    Send to precast()
        may call change_target().  <st*> values are rejected.
        collect gear information
    Send gear swaps
    Send spell command
    Notification of spell start
    Send to midcast()
        may not call change_target/ing().
    etc..
    Basically, at what point in there can the user screw things up such that you'd need to have an entire backup environment in use? Is the user not being given proxied/readonly global tables? I can't see a single value in the globals that shouldn't be read-only at the user level, so there should never be an issue of needing to back-out the results. At most, you have to dump the user environment since it could have been contaminated by being run through in a situation where you're not using the results.

    The main problem I see with what you described is that it sounds like you're allowing the entire precast() function to run, and then checking to see if check_target() was called, and then running the entire thing a second time regardless of the result (merely changing what gets sent to the game).

  17. #57
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Quote Originally Posted by hey
    No, this makes it signfiicantly less organized, because i need a separate if spell = whatever 3 times.
    Ehh... Maybe sorta, but not really. Here's how lua can handle it:

    Precast: In this case, is it a magic spell? Then equip fastcast gear. Possibly refine it for the magic type. And yes, for Stoneskin in particular possibly refine it further, though that wouldn't be the case for most spells. However you can do this with generic rules and good set constructions:

    Sets:
    Code:
        sets.precast.FC = {general fast cast gear}
        sets.precast.FC.EnhancingMagic = {fast cast gear with Siegal Sash}
        sets.precast.FC.Stoneskin = {fast cast gear with Siegal Sash and Carapacho Cuffs}
    Then in precast():
    Code:
        if action.type == 'Magic' then
            if sets.precast.FC[spell.english] then
                equip(sets.precast.FC[spell.english])
            elseif sets.precast.FC[spell.skill] then
                equip(sets.precast.FC[spell.skill])
            else
                equip(sets.precast.FC)
            end
        end
    And now as long as the set exists, the code will automatically handle applying it during precast. You never need to do [if spell="Stoneskin"] within the precast() function. If you want a set for a specific spell, just name it appropriately. If you just want to catch all spells within a specific skill type, do the same thing. Otherwise it falls back on the generic set. If you get more spell-specific gear, just add an new set for it; you never have to touch the precast logic in order for it to take effect.

    Note that this gets slightly more complicated if you have classes of spells, such as "Mage's Ballad", "Mage's Ballad II" and "Mage's Ballad III", all of which you want to apply a Ballad gear set to. There are a couple different approaches for that, but the code is generally pretty simple, and you can factor it out into a separate function.


    Midcast: This is where you'd actually apply gear for the particular spells, but again you can use exactly the same type of logic as in the precast() function, meaning that the only thing that matters is that you have an appropriately named set for the spell in question. The "one place" that matters is thus still just the sets that you make.


    Aftercast: You're not setting aftercast according to the spell you just cast, but rather according to broader conditions -- idle, engaged, PDT set, etc. So that's not tied specifically to Stoneskin either, and again you don't need to consider it a 'scattering' of where to look for the code for a given spell.


    So in the end, you just need good basic logic in the rules area, and most of the 'work' is just making sure you have the right sets defined.

  18. #58
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    Quote Originally Posted by Motenten View Post
    The logical order of things that you outlined seems fairly sound, but I still don't see why you need to duplicate the user environment, aside from attempting to maintain only the precast() hook instead of adding the pretarget() hook. Is it to prevent the user from explicitly modifying the spell.target value rather than going through the function call? Or is changing the target to an <st*> value going to cause another raised event that looks like you need to call pretarget() again, trapping you in a loop?

    Code:
    user enters command
    Shortcuts modifies as necessary
    GearSwap gets it
    Send to pretarget()
        may call change_targetting().  <st*> values are acceptable.  May want to reject any non-abstract targets (for the sake of this function call only; has no effect on initial player input).
        if change_targetting() called, make adjustments
    if target is an <st*> value, send to game for targetting routine
    game selects a target
    GearSwap gets it
    Send to precast()
        may call change_target().  <st*> values are rejected.
        collect gear information
    Send gear swaps
    Send spell command
    Notification of spell start
    Send to midcast()
        may not call change_target/ing().
    etc..
    Basically, at what point in there can the user screw things up such that you'd need to have an entire backup environment in use? Is the user not being given proxied/readonly global tables? I can't see a single value in the globals that shouldn't be read-only at the user level, so there should never be an issue of needing to back-out the results. At most, you have to dump the user environment since it could have been contaminated by being run through in a situation where you're not using the results.

    The main problem I see with what you described is that it sounds like you're allowing the entire precast() function to run, and then checking to see if check_target() was called, and then running the entire thing a second time regardless of the result (merely changing what gets sent to the game).
    I'm worried because it would make me call precast() twice, rather than because they might mess up the global environment. But as long as I'm sandboxing them from themselves, I might as well sandbox them globally too.

    I'd also like to avoid making an entirely separate event just for <st*> targets.

  19. #59
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Does GearSwap call the file_unload() function when you unload GearSwap (ie: lua unload gearswap)? As far as I can find, it only ever gets called just before loading a new user lua.

  20. #60
    BG Content
    Join Date
    Jul 2007
    Posts
    16,329
    BG Level
    9
    FFXI Server
    Lakshmi
    Blog Entries
    1

    Quote Originally Posted by Motenten View Post
    Does GearSwap call the file_unload() function when you unload GearSwap (ie: lua unload gearswap)? As far as I can find, it only ever gets called just before loading a new user lua.
    True, fixed!

Quick Reply Quick Reply

  • Decrease Size
    Increase Size
  • Remove Text Formatting
  • Insert Link Insert Image Insert Video
  • Wrap [QUOTE] tags around selected text
  • Insert NSFW Tag
  • Insert Spoiler Tag

Similar Threads

  1. Replies: 6547
    Last Post: 2014-07-08, 22:45