Solved: GS Automatic Aurorastorm Notifier

Language: JP EN DE FR
users online
Forum » FFXI » Jobs » White Mage » Solved: GS Automatic Aurorastorm Notifier
Solved: GS Automatic Aurorastorm Notifier
Offline
Posts: 148
By RolandJ 2015-12-03 23:23:02
Link | Quote | Reply
 
RolandJ said: »
Hello guys,

I would like to include a feature in my whm.lua that, when a cure spell is cast, checks to see if the spell Aurorastorm is active. Furthermore, if the check comes back false, I would like for it to print onto my screen a notice. Such a notice could be a line of text that reads "Aurorastorm currently inactive.". It would be even nicer if it could give a subtle sound effect to go along with the notice - though perhaps now I am wandering into the realm of unrealistic requests.

I will look into how to accomplish this while waiting for a response. If anyone has the know-how to accomplish this please help.

Thanks guys,
Roland

PROGRESS UPDATE: Solved

Thanks to multiple contributions from Vow, Braden, and Conagh, I have been able to build the code for this feature to include in my WHM.lua. A thanks also goes out to Draylo for pointing out ingame where in my lua to put the code.

Here is the code - you might notice that it needs to be contained within the precast function in your lua. That's where it is in mine, at least.
Code
function job_precast(spell, action, spellMap, eventArgs)

  if map == 'Cure' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
      add_to_chat(123,'Aurorastorm not active.')
      windower.play_sound('C:/Program Files (x86)/Windower4/addons/GearSwap/data/wav/Chime.wav')
  end
 
  if map == 'Curaga' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
      add_to_chat(123,'Aurorastorm not active.')
      windower.play_sound('C:/Program Files (x86)/Windower4/addons/GearSwap/data/wav/Chime.wav')
  end

end

You will also need to either add a folder named "wav" in your '...\Windower4\addons\GearSwap\data\' folder and put a .wav file named Chime within or create your own folder and name your own .wav in a location of your choosing and manipulate the code to point to your folder and your .wav.

Thank you for taking a look, I hope some people find this helpful.

Thank you all who helped!
Kind Regards,
Roland
 
Offline
Posts:
By 2015-12-04 00:56:03
 Undelete | Edit  | Link | Quote | Reply
 
Post deleted by User.
[+]
Offline
Posts: 148
By RolandJ 2015-12-04 02:01:22
Link | Quote | Reply
 
Ok, so far I've come up with...

if spell.english == 'Cure' and buffinactive.aurorastorm then
add_to_chat(123,'Aurorastorm not active.')
end

I borrowed the framework of that code from Mote-Include.lua's job file message. I am expecting that I might need to expand 'Cure' into another phrase that will be able to catch all of the cure variations or rather just include them all separated by commas - for now I'm just leaving it as 'Cure' until I am able to test it further while ingame.

The main problem impeding my testing right now is that when I tried putting that code in a few different places of my whm.lua it has caused the .lua to become unloadable ingame each time.

Also, is buffinactive the correct opposite of buffactive in this code language? I've found buffactive used in some strings of code but I've not come across a string of code that specifically looks for a buff that is not currently up. Maybe I'll find one soon to verify that I'm using the right coding.

Back to the books...
 Leviathan.Vow
Offline
Server: Leviathan
Game: FFXI
user: woVow
Posts: 125
By Leviathan.Vow 2015-12-04 04:06:27
Link | Quote | Reply
 
Code
include('Mote-Mappings.lua') -- this is a file written by Motenten that includes, among other things, a large-ish table named spell_maps. The table maps similar spells to a common name. e.g. ['Cure V'] = 'Cure', ['Curaga III'] = 'Curaga', etc.


function precast(spell)
    local map = spell_maps[spell.en]

    if map == 'Cure' and not buffactive.Aurorastorm then
        add_to_chat(123,'Aurorastorm not active.')
        windower.play_sound(path) -- path is the path to the file, which must be in wav format.
    end
end


buffactive is a table created by gearswap and updated every time your buffs change. Its keys are the written names (with and without capital letters) and buff ids of the buffs you currently have active, and its values are numbers corresponding to how many of each buff you have active (Protect/Shell will always be 1 if you have the buff, while March may be 2 if you have both marches). Gearswap does not create a 'buffinactive' table.
Looking up a buff that you do not have active results in nil.
In Lua,
Code
not nil == true
so if you need to work with the opposite of a value (checking if a buff is not active)
Code
if not value then end
is the appropriate syntax.
The error you probably received was likely something along the lines of attempting to index a nil value: 'buffinactive'. Since buffinactive is undefined, the value is nil. Attempting to lookup a value in nil causes the error. The errors printed in the console will usually be clear enough to figure out what's wrong.
[+]
Offline
Posts: 148
By RolandJ 2015-12-04 13:37:46
Link | Quote | Reply
 
Thank you very much, Vow! That is very helpful and my testing can now continue - that code will load ingame.

I am running into the following errors

If I use
Code
if map == 'Cure' and not buffactive.Aurorastorm then
then the feature works perfectly for non-curaga cures but it leaves out functionality for curagas.

and if I use
Code
if map == 'Cure' or 'Curaga' and not buffactive.Aurorastorm then
then cure spells(non-curaga) trip this message to print onscreen whether aurorastorm is active or not, whereas the curaga-notification function stays intact and working as intended.

I have also tried ('cure','curaga') and {'cure','curaga'} and 'cure','curaga' but those did not work, either. I am considering of making a second string of code for curaga unless I find a way to combine them both into the same line.

I am also having trouble getting the sound to play. I have currently tried
Code
windower.play_sound(C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav)
and that results in the lua become unloadable ingame and an error message reading "WHM.lua:377: '<name>' expected near '\'".

I also tried using
Code
windower.play_sound(Chime.wav)
and moving the file into my char's folder but that results in printing a console message reading "WHM.lua:377: attempt to index global 'Chime' (a nil value)" each time I cast cure.

I am not sure how to get past that. I'm not sure what '<name>' being expected means, either. I'll keep looking, though.

Thanks again for reading.
 Sylph.Braden
Offline
Server: Sylph
Game: FFXI
Posts: 397
By Sylph.Braden 2015-12-04 13:46:43
Link | Quote | Reply
 
Try this:
windower.play_sound('C:/Program Files(x86)/Windower4/addons/GearSwap/data/wav/Chime.wav')
[+]
Offline
Posts: 148
By RolandJ 2015-12-04 14:03:38
Link | Quote | Reply
 
Thanks, Braden! That removed some of the errors.

I tried
Code
windower.play_sound('C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav')
the difference being that the path is now surrounded in ''s. It now becomes loadable ingame and no error message plays on cure casting but the sound file does not play, either.

Using windower.play_sound('Chime.wav') also produces the same effect; no error message nor sound played.

I have the sound files located in the path above and also one within my character's gs folder. Do I need to move it somewhere else or is the location not the current problem?

Inlcuding the following in my whm.lua's precast fuction results in all cure and curaga tiers printing this message onscreen if aurorastorm is not active.
Code
if map == 'Cure' and not buffactive.Aurorastorm then
  add_to_chat(123,'Aurorastorm not active.')
end
	
if map == 'Curaga' and not buffactive.Aurorastorm then
  add_to_chat(123,'Aurorastorm not active.')
end


So now I just need to get the sound to play and I should have this sorted out. I still don't know how to combine cure and curaga into the same line but I've circumvented that for now by creating two different strings of code; one for cure and a separate one for curaga. It is not ideal and hopefully I can combine them into the same line eventually.

Thanks for all the help so far, guys!
 Cerberus.Conagh
Offline
Server: Cerberus
Game: FFXI
user: onagh
Posts: 3189
By Cerberus.Conagh 2015-12-04 15:21:36
Link | Quote | Reply
 
RolandJ said: »
Thanks, Braden! That removed some of the errors.

I tried
Code
windower.play_sound('C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav')
the difference being that the path is now surrounded in ''s. It now becomes loadable ingame and no error message plays on cure casting but the sound file does not play, either.

Using windower.play_sound('Chime.wav') also produces the same effect; no error message nor sound played.

I have the sound files located in the path above and also one within my character's gs folder. Do I need to move it somewhere else or is the location not the current problem?

Inlcuding the following in my whm.lua's precast fuction results in all cure and curaga tiers printing this message onscreen if aurorastorm is not active.
Code
if map == 'Cure' and not buffactive.Aurorastorm then
  add_to_chat(123,'Aurorastorm not active.')
end
	
if map == 'Curaga' and not buffactive.Aurorastorm then
  add_to_chat(123,'Aurorastorm not active.')
end


So now I just need to get the sound to play and I should have this sorted out. I still don't know how to combine cure and curaga into the same line but I've circumvented that for now by creating two different strings of code; one for cure and a separate one for curaga. It is not ideal and hopefully I can combine them into the same line eventually.

Thanks for all the help so far, guys!

Code
Cures 									= S{'Cure','Cure II','Cure III','Cure IV','Cure V','Cure VI'}


Just add Curaga's in there.
Code
if Cures:contains(spell.name) and not buffactive.Aurorastorm then
  add_to_chat(123,'Aurorastorm not active.')
send_command('@input /echo <se.9> Weather Isn't up, sort it out!')
end


You can do it in one line that way, in terms of getting a sound to work it shouldn't be an issue however you can do this instead ~
[+]
 Leviathan.Vow
Offline
Server: Leviathan
Game: FFXI
user: woVow
Posts: 125
By Leviathan.Vow 2015-12-04 16:54:24
Link | Quote | Reply
 
RolandJ said: »
I tried
Code
windower.play_sound('C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav')
Code
'C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav' -- a string

C:\Program Files(x86)\Windower4\addons\GearSwap\data\wav\Chime.wav -- garbled nonsense

The quotes make a big difference! The problem now is that the backslash is an escape character. It tells Lua that the next character(s) in the string should be interpreted differently (e.g. \n creates a newline).
To correct the problem, either escape the escape character (replace \ with \\, which tells Lua that \ should not be interpreted as the escape character), or replace the backslashes with forward slashes (the better solution).

Quote:
I still don't know how to combine cure and curaga into the same line but I've circumvented that for now by creating two different strings of code; one for cure and a separate one for curaga.
Code
if map == 'Cure' or map == 'Curaga' then ...
Your previous attempt (if map == 'Cure' or 'Curaga' ...) failed for the following reason:
Code
map == 'Cure' -- This is a single boolean condition.
map == 'Cure' or 'Curaga' -- This is two separate boolean conditions compared with a logical operator. 

The second condition is simply 'Curaga' (i.e. if 'Curaga' then ...) which always evaluates to true, as anything that is not false or nil evaluates to true in Lua. The statement will always run since
Code
<condition> or true
is true.

One common shortcut for a long string of conditions that compare the same value
Code
if a == 1 or a == 2 or a == 3 or ... 
is to toss all of the possibilities into a table and check if the value is in the table. You may choose not to predefine the table:
Code
if S({1,2,3,4,...}):contains(value) then ... -- S is a function from windower's libraries (/addons/libs/sets.lua)
--Using T instead of S will probably be quicker for small tables, but the difference is trivial either way. 

It's essentially a trivial loss of efficiency for a minor gain in readability.

You can use Conag's solution, or a number of others. The advantage to using Motenten's maps is that you skip out on a lot of typing.

This is a really good site for learning Lua:http://lua-users.org/wiki/TutorialDirectory
Lua has very few built in libraries, so it's very quick to learn.
[+]
Offline
Posts: 148
By RolandJ 2015-12-04 17:28:38
Link | Quote | Reply
 
Thank you for those two great replies! I have been able to progress the code to a state that I am pleased with and happy to implement!

I am now using
Code
    if map == 'Cure' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
        add_to_chat(123,'Aurorastorm not active.')
		windower.play_sound('C:\\Program Files (x86)\\Windower4\\addons\\GearSwap\\data\\wav\\Chime.wav')
    end
	
	if map == 'Curaga' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
        add_to_chat(123,'Aurorastorm not active.')
		windower.play_sound('C:\\Program Files (x86)\\Windower4\\addons\\GearSwap\\data\\wav\\Chime.wav')
    end


Thank you Conagh for the cures:contains code. The only reason I did not use it is because I'm too much of an amateur to figure it out ^^;.

Thank you Vow for explaining the backslash conflict and explaining the tables. Using the tables method seems to be above my understanding at the moment so I am just using the earlier code that managed to work for me.

Thanks guys! I'll update the original post with the code and we can consider this finished with potential updates in the future(code simplifications). ^^
necroskull Necro Bump Detected! [101 days between previous and next post]
Offline
Posts: 95
By cocl 2016-03-14 08:27:16
Link | Quote | Reply
 
I hate to necro a 3 month old thread but I tried including RolandJ's code in my gearswap but it is not working for me. I'm not sure I put it in the right spot or not but if anyone would be so kind as to take a look for me I would greatly appreciate it.
 Bahamut.Ayasha
Offline
Server: Bahamut
Game: FFXI
user: Ayasha
Posts: 89
By Bahamut.Ayasha 2016-03-14 13:28:15
Link | Quote | Reply
 
The variable 'map' in your job_precast function is undefined. Change the code block to read:


Code
function job_precast(spell, action, spellMap, eventArgs)
  local map = spell_maps[spell.en]
  if map == 'Cure' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
      add_to_chat(123,'Aurorastorm not active.')
      windower.play_sound(windower.addon_path..'wav/Chime.wav')
  end
   
  if map == 'Curaga' and player.sub_job == "SCH" and not buffactive.Aurorastorm then
      add_to_chat(123,'Aurorastorm not active.')
      windower.play_sound(windower.addon_path..'wav/Chime.wav')
  end
end


This should fix your problem.
Offline
Posts: 95
By cocl 2016-03-14 15:21:18
Link | Quote | Reply
 
Thank you for the reply. I have tried to include that portion of code and it still does not work. No text is even coming up or anything.
 Bahamut.Ayasha
Offline
Server: Bahamut
Game: FFXI
user: Ayasha
Posts: 89
By Bahamut.Ayasha 2016-03-15 00:03:57
Link | Quote | Reply
 
Ah OK, I figured out the issue that I missed before. You have 3 different job_precast functions defined. I'm not a magician with LUA, but I'm fairly sure that it will just redefine the function every time it reads it in a linear fashion (final function read, final definition of the function).

I modified your .lua to include the code in the proper spot, and commented out the extraneous third function that essentially says "if state.Buff['yadda'] is true, then state.Buff['yadda'] is true". As far as I know, it should not be necessary.


PM me if there's any issues with this. I've tested it on my side, so hopefully it should work for you.
Offline
Posts: 95
By cocl 2016-03-15 00:44:09
Link | Quote | Reply
 
Bahamut.Ayasha said: »
Ah OK, I figured out the issue that I missed before. You have 3 different job_precast functions defined. I'm not a magician with LUA, but I'm fairly sure that it will just redefine the function every time it reads it in a linear fashion (final function read, final definition of the function).

I modified your .lua to include the code in the proper spot, and commented out the extraneous third function that essentially says "if state.Buff['yadda'] is true, then state.Buff['yadda'] is true". As far as I know, it should not be necessary.


PM me if there's any issues with this. I've tested it on my side, so hopefully it should work for you.

Thank you so much, it works perfectly!
Log in to post.