$spell("Spell Name",duration) is broken.

A forum for the general posts relating to MacroQuest. *DEPRECATED: This forum is no longer in public use, but remains here for your reading pleasure. Enjoy

Moderator: MacroQuest Developers

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

$spell("Spell Name",duration) is broken.

Post by merkzu » Thu Jun 12, 2003 10:00 pm

It returns 0 for instant spells and -1 for spells that dont exist, but it ALWAYS returns "PERMANENT" for any other spell.

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Thu Jun 12, 2003 10:45 pm

Ok....got it.

Here is the fixed SPELLLIST struct for this problem:
(You'll notice the addition of DurationValue1 back to the struct..yay)

Code: Select all

#define   SPELLLIST_STARTOFFSET      0x24
#define   TOTAL_SPELL_COUNT         0x0FA0      // # of spells in game
typedef struct _SPELLLIST {
/*0x000*/	DWORD	ID;
/*0x004*/	FLOAT	Range;				
/*0x008*/	BYTE	Unknown0x008[12];
/*0x014*/	DWORD	CastTime;			
/*0x018*/	DWORD	FizzleTime;
/*0x01c*/	DWORD	RecastTime;
/*0x020*/	DWORD	DurationType;	//DurationFormula on Lucy
/*0x024*/	DWORD	DurationValue1;
/*0x028*/	DWORD	Unknown0x024;
/*0x02c*/	DWORD	Mana;
/*0x030*/	DWORD	Base[12];		//Base1-Base12
/*0x060*/	DWORD	Max[12];		//Max1-Max12
/*0x090*/	DWORD	BookIcon;
/*0x094*/	DWORD	GemIcon;
/*0x098*/	DWORD	ReagentId[4];	  //ReagentId1-ReagentId4
/*0x0a8*/	DWORD	ReagentCount[4];  //ReagentCount1-ReagentCount4	
/*0x0b8*/	DWORD	Unknown0x0b8[4];	
/*0x0c8*/	BYTE	Calc[12];			//Calc1-Calc12
/*0x0d4*/	BYTE	Unknown0x0d4;
/*0x0d5*/	BYTE	Deletable;			// untested
/*0x0d6*/	BYTE	Unknown0x0d6[2];
/*0x0d8*/	BYTE	Attrib[12];			//Attrib1-Attrib12
/*0x0e4*/	BYTE	Unknown0x0e4;
/*0x0e5*/	BYTE	FizzLeadj;
/*0x0e6*/	BYTE	Unknown0x0e6;
/*0x0e7*/	BYTE	Unknown0x0e7;
/*0x0e8*/	BYTE	Unknown0x0e8[3];
/*0x0eb*/	BYTE	Level[15];			
/*0x0fa*/	BYTE	Unknown0x0fa[16];
/*0x10a*/	BYTE	CastingAnim;
/*0x10b*/	BYTE	Unknown0x10b[5];		
/*0x110*/	DWORD	UnknownFlags0x110;	// Lucy lists this as 'descnum', but I think it's flags.	
/*0x114*/	DWORD	UnknownFlags0x114;		
/*0x118*/	BYTE	Unknown0x118[12];
/*0x124*/	DWORD	UnknownFlags0x124;
/*0x128*/	DWORD	UnknownFlags0x128;
/*0x12c*/	DWORD	Unknown0x12c[2];
/*0x134*/	CHAR	*Name;
/*0x138*/	CHAR	*Target;
/*0x13c*/	CHAR	*Unknown0x13c;
/*0x140*/	CHAR	*Unknown0x140;		
/*0x144*/	CHAR	*Unknown0x144;		// new struct that indicates casting sound possibly?
/*0x148*/	CHAR	*CastOnYou;
/*0x14c*/	CHAR	*CastOnAnother;
/*0x150*/	CHAR	*WearOff;
/*0x154*/	CHAR	*Unknown0x154;		// new sprites animation struct?
/*0x158*/	DWORD	spaindex;
/*0x15c*/	DWORD	Unknown0x15c;		
/*0x160*/	DWORD	SpellAnim;
/*0x164*/	DWORD	Unknown0x164;
/*0x168*/	DWORD	Unknown130;			// This is Unknown130 from Lucy
/*0x16c*/	DWORD	Unknown0x16c;
/*0x170*/	DWORD	SpellIcon;
/*0x174*/	BYTE	Unknown0x174[12];
} SPELLLIST, *PSPELLLIST;

Then...go to EQLib_Utilities and remove the // comment markings in GetSpellDuration() so that it looks like this again:

Code: Select all

DWORD GetSpellDuration(PSPELLLIST pSpell, PSPAWNINFO pSpawn)
{
	switch (pSpell->DurationType) {
		case 0:
			return 0;
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 8:
		case 9:
		case 10:
		case 11:
		case 12:
			if (pSpell->DurationValue1) {
				return (pSpell->DurationValue1);
			} else {
				return (pSpell->DurationType*10);
			}
		case 7:
			if (pSpell->DurationValue1) {
				return (pSpell->DurationValue1);
			} else {
				return (pSpawn->Level*10);
			}

		case 50:
			return 0xFFFFFFFF;
		case 3600:
			return 6000;
		default:
			return 0xFFFFFFFE;
	}
}

That should do it ...I havn't tested it extensively for any of the newer spells since this function was first coded with these duration types..however, this should work for most spells :)


Devs...let me know if you add this in CVS ..otherwise, I'll include it with a patch at some point.

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

Post by merkzu » Thu Jun 12, 2003 11:14 pm

wow that was fast, thanks a ton

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

Post by merkzu » Thu Jun 12, 2003 11:28 pm

woops, looks like it always gives a duration of 0 now. If the spell doesnt exist it still gives -1. I tested it on Quickness, Venom of the Snake, Chloroplast and Furious Strength

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

Post by merkzu » Thu Jun 12, 2003 11:33 pm

btw i made those changes on brand new cvs

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Fri Jun 13, 2003 2:00 am

That's really strange....can you confirm that the rest of the $spell(name, xxx) work correctly? (ie, range, mana, etc....)

Also....post a simple macro that tests this so I can test it online. Looking at the code, this ought to work beautifully. Chloroplast, for example, should return 1230 seconds ...at level 65, of course. (which means I need to adjust the code so that it works based on level ..hehe)

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Fri Jun 13, 2003 2:01 am

heck... I might as well spend some time on it anyway to see if I can find the new "Game Description" string.

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

Post by merkzu » Fri Jun 13, 2003 9:28 am

This is what I'm using. There's other bugs in this im working out, but the main one is that $spell(spell,duration) is 0 every time. You can check it by just doing /echo $spell("Quickness",duration) in game. All the other $spell features seem to work (recoverytime,casttime,id,level,mana)

Code: Select all

#turbo 100
#event haste "You begin casting Quickness"
#define counter v1
#define curtime v3

Sub Main
  /zapvars
  :mainloop
    /for v2 0 to 99 
      /doevents
      /varset curtime $calc($time(h)*3600+$time(m)*60+$time(s))
      /if n $a(2,$v2)>0 /if n $a(2,$v2)<$curtime {
        /echo $a(1,$v2) has expired on $a(3,$v2)
        /varset a(1,$v2) 0
        /varset a(2,$v2) 0
        /varset a(3,$v2) 0
      }
    /next v2
  /goto :mainloop
/return

Sub Track
  /echo Added $p0 on $p1 to tracking.
  /if n $counter==99 /varset counter 0
  /varset a(1,$counter) $p0
  /varset a(2,$counter) $calc($time(h)*3600+$time(m)*60+$time(s))
  /varadd a(2,$counter) $spell($p0,duration)
  /varset a(3,$counter) $p1
  /varadd counter 1
/return

Sub Event_haste
  /call Track "Quickness" $target(name)
/return

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Mon Jun 16, 2003 4:57 pm

I finally got a chance to fix this today. Strangely enough, it was a coding error that I have no idea how might have appeared in the source tree...but, anyway, here is the fix.

1. Open EQLib_MacroParser.cpp
2. Search for the line that looks like this:

Code: Select all

								} else if (Tics=0) {
...and replace it with this:

Code: Select all

								} else if (Tics==0) {

...that should do it.

merkzu
a ghoul
a ghoul
Posts: 99
Joined: Wed May 14, 2003 2:08 pm

Post by merkzu » Mon Jun 16, 2003 5:16 pm

Oh man, thanks. This will make things so much easier for me =)

icon
Official loudmouth
Official loudmouth
Posts: 158
Joined: Fri Jun 14, 2002 2:59 pm
Location: ...
Contact:

Post by icon » Mon Jun 16, 2003 11:05 pm

lol I have made that exact mistake sooo many times in the past.

So to avoid that I always try to remember, x=y means "set x equal to y" while x==y means "x is equivelent to y".

Of course we all know that so my post was kind of pointless. But that's ok because I'm special, just ask my mom.

- Icon
In memory of [b][color=darkblue]MasTerKeyZ[/b][/color].