Page 1 of 2

UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Aug 15, 2003 6:28 pm
by EqMule
ok, this might have been in the source somewhere allready and I missed it, but here it is anyway.

With this addition you can now cast spells, that are clickable on your items.

Syntax Example: /cast item "Warden Symbol of Tunare"
or /cast item "Jaundiced Bone Bracer"

eqgame.ini

Code: Select all

[Function Locations] 
CastSpell=00471C0B
EQLib_Main.cpp

Code: Select all

DWORD EQADDR_CASTSPELL=0;
	GetPrivateProfileString("Function Locations","CastSpell","0",szBuffer,MAX_STRING,ClientINI);		EQADDR_CASTSPELL = (DWORD)strtoul(szBuffer,NULL,16);
Eqlib.h

Code: Select all

extern DWORD EQADDR_CASTSPELL;

EQLib_Commands.cpp

Code: Select all

 [color=green]// ***************************************************************************
// Function:    Cast
// Description: Our '/cast' command
// Usage:       /cast [list|#|"name of spell"|item "name of item"]
// ***************************************************************************[/color]
VOID Cast(PSPAWNINFO pChar, PCHAR szLine)
{
	if (!cmdCast) return;

	if (szLine[0]==0 || atoi(szLine) || !EQADDR_SPELLS || !EQADDR_CHAR_INFO || !*EQADDR_CHAR_INFO) {
		cmdCast(pChar,szLine);
		return;
	}
	PCHARINFO pCharInfo = *EQADDR_CHAR_INFO;

	DWORD Index;
	CHAR szBuffer[MAX_STRING] = {0};
	CHAR szArg1[MAX_STRING] = {0};
	CHAR szArg2[MAX_STRING] = {0};
	if (!stricmp(szLine,"list")) {
		WriteChatColor("Spells:",USERCOLOR_DEFAULT);
		for (Index=0;Index<8;Index++) {
			if (pCharInfo->MemorizedSpells[Index]==0xFFFFFFFF) {
				sprintf(szBuffer,"%d. <Empty>",Index+1);
			} else {
				sprintf(szBuffer,"%d. %s",Index+1,GetSpellByID(pCharInfo->MemorizedSpells[Index]));
			}
			WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
		}

		return;
	}
	
	GetArg(szArg1,szLine,1);
	GetArg(szArg2,szLine,2);
	DebugSpew("Cast: szArg1 = %s szArg2 = %s",szArg1,szArg2);
	if (!stricmp(szArg1,"item"))
	{
		BOOL FOUND = FALSE;
		DWORD item = 0;
		DWORD slot = 0;
		DWORD SpawnFooter = NULL;
		SpawnFooter = (DWORD)*EQADDR_SPAWNTAIL;
		for (int i=0;i<30;i++) {
			if (pCharInfo->Inventory[i])
				if (!_stricmp(szArg2,pCharInfo->Inventory[i]->Name)) {
					DebugSpew("cast test slot %d = %s address is %x",i,pCharInfo->Inventory[i]->Name,pCharInfo->Inventory[i]);
					item = (DWORD)&pCharInfo->Inventory[i];
					slot = (DWORD)i;
					FOUND = TRUE;
					break;
				}
		}
		if (FOUND) {
			__asm {
				push eax;
				push ecx;
				push edi;
				mov ecx, dword ptr [pCharInfo];
				mov edi, dword ptr [SpawnFooter];
				push slot;//slot item is in
				push item; //pointer to the item...
				push 0x00000000;//always 0
				push 0x0000000A;//always 10
				call dword ptr [EQADDR_CASTSPELL];
				pop edi;
				pop ecx;
				pop eax;
			}
			return;
		}
	}
	GetArg(szBuffer,szLine,1);
	for (Index=0;Index<8;Index++) {
		if (pCharInfo->MemorizedSpells[Index]!=0xFFFFFFFF) {
			PCHAR SpellName = GetSpellByID(pCharInfo->MemorizedSpells[Index]);
			if (!strnicmp(szBuffer,SpellName,strlen(SpellName))) {
				DebugSpew("SpellName = %s",SpellName);
				cmdCast(pChar,itoa(Index+1,szBuffer,10));
				DebugSpew("pChar = %x SpellName = %s %s",pChar,SpellName,itoa(Index+1,szBuffer,10));
				return;
			}
		}
	}
	WriteChatBuffer("You do not seem to have that spell memorized.",USERCOLOR_DEFAULT);
	return;
}
Now, Valerian has been helping me with the $spell in the macroparser, so we can use it to return castingtime and so on, for items as well, but he has some major thing going on with the whole PMP, so until that is in the cvs, you can use this : (replace where needed)

Syntax Example: /echo $clickitem("Warden symbol of Tunare",casttime)
will return 4.00 which indeed is the casttime for the effect on that item (grasping roots)

Code: Select all

 [color=green]					// $clickitem(name,xxx) syntax example: /echo $clickitem("Warden symbol of Tunare",casttime)
					// will return 4.00 which is correct for the grasping roots effect on that item...[/color]
					} else if (!strncmp("clickitem(",szVar,10)) {
						if (!strstr(szVar,",") || !strstr(szVar,")")) {
							DebugSpew("PMP - Bad $spell() '%s'",szVar);
							i--;
							szOutput[j] = '@';
							j++;
						} else {
							i += (strstr(szVar,")")-szVar);
							PCHARINFO pCharInfo = 0;
							pCharInfo = *EQADDR_CHAR_INFO;
							PSPELLLIST pSpell = 0;
							PCHAR szSpell = szVar+10;
							PCHAR szArg = strstr(szVar,",")+1;
							DWORD Length = strstr(szSpell,",")-szSpell;
							CHAR szTemp[MAX_STRING] = {0};
							BOOL IsValid = FALSE;
							if (szSpell[0]=='"') { szSpell++; Length-=2; }
                            DebugSpew("%s -> %s|%d, %s",szVar,szSpell,Length,szArg);
							strncpy(szTemp,szSpell,Length);
							DebugSpew("szTemp = %s szSpell = %s",szTemp, szSpell);
							for (int ItemIndex=0;ItemIndex<30;ItemIndex++) {
								if (pCharInfo->Inventory[ItemIndex])
									if (!_stricmp(szTemp,pCharInfo->Inventory[ItemIndex]->Name)) {
										//DebugSpew("$click(%s,%s) in slot %d = %s address is %x",szTemp,szArg,ItemIndex,pCharInfo->Inventory[ItemIndex]->Name,pCharInfo->Inventory[ItemIndex]);
										PCHAR pcSpellName = GetSpellByID(pCharInfo->Inventory[ItemIndex]->Common.SpellId);
										pSpell = GetSpellByName(pcSpellName);
										IsValid = TRUE;
										break;
									}
							}
							if (!IsValid) {
								strcpy(szTemp,"-1");
							} else if (!strncmp(szArg,"id",2)) {
								itoa(pSpell->ID,szTemp,10);
							} else if (!strncmp(szArg,"level",5)) {
								itoa(pSpell->Level[GetCharInfo()->pSpawn->Class-1],szTemp,10);
							} else if (!strncmp(szArg,"mana",4)) {
								itoa(pSpell->Mana,szTemp,10);
							} else if (!strncmp(szArg,"range",5)) {
								sprintf(szTemp,"%1.2f",pSpell->Range);
							} else if (!strncmp(szArg,"casttime",8)) {
								sprintf(szTemp,"%1.2f",(FLOAT)pCharInfo->Inventory[ItemIndex]->Common.CastTime/1000);
							} else if (!strncmp(szArg,"recoverytime",12)) {
								sprintf(szTemp,"%1.2f",(FLOAT)pSpell->FizzleTime/1000);
							} else if (!strncmp(szArg,"recasttime",10)) {
								sprintf(szTemp,"%1.2f",(FLOAT)pSpell->RecastTime/1000);
							} else if (!strncmp(szArg,"duration",8)) {
								DWORD Tics=GetSpellDuration(pSpell,pChar);
								if (Tics==0xFFFFFFFF) {
									strcpy(szTemp,"PERMANENT");
								} else if (Tics==0xFFFFFFFE) {
									strcpy(szTemp,"UNKNOWN");
								} else if (Tics==0) {
									strcpy(szTemp,"INSTANT");
								} else {
									itoa(Tics*6,szTemp,10);
								}
							} else {
								strcpy(szTemp,"0");
							}
							strcat(szOutput,szTemp);
							j+=strlen(szTemp);
						}
					[color=red]// $return
					} else if (!strncmp("return",szVar,6)) { [/color]

Posted: Fri Aug 15, 2003 6:43 pm
by wassup
Oh heck yes!

I was doing this using /press # with the item in the hotkey, but this is hugely useful.

Thanks EQMule! I'll test it out today!

Posted: Fri Aug 15, 2003 7:31 pm
by EqMule
good, ol' Wassup, always the first to test my code :) thanks man, I appreaciate that alot.

Please let me know if it works as intended

Posted: Fri Aug 15, 2003 9:10 pm
by wassup
Works flawlessly with every item I have that can be right clicked.

/cast item works
/clickitem("item name",casttime) works

Compiled with VS.net

Thanks for the addition!

Posted: Fri Aug 15, 2003 11:49 pm
by Valerian
EqMule00 wrote:Now, Valerian has been helping me with the $spell in the macroparser, so we can use it to return castingtime and so on, for items as well, but he has some major thing going on with the whole PMP
yup. HUGE change to ParseMacroParameter() upcoming, that makes it MUCH easier to add parameters... I should have it finished this weekend, and sent off to DKAA for cvs soon, along with an update to $ini and /ini to default the ini folder to the macro folder (instead of the windows folder)

Posted: Sat Aug 16, 2003 12:43 pm
by Doodman
Does this allow you to use clickable items that need to be equipped without equiping them?

Posted: Sat Aug 16, 2003 1:39 pm
by EqMule
as the function is written, no. but I cant say if it is possible or not...

Posted: Wed Aug 20, 2003 7:04 pm
by GoatFoot
Patched the code into mine, and it appears to be working properly, so I guess I got everything in the right place.

Code: Select all

diff -r1.24 EQLib.h
155a156
> extern DWORD EQADDR_CASTSPELL;


diff -r1.9 EQLib_Commands.cpp
2883c2883
< // Usage:       /cast [list|ability|#]
---
> // Usage:       /cast [list|#|"name of spell"|item "name of item"]
2887c2887
<   if (!cmdCast) return;
---
>    if (!cmdCast) return;
2889,2893c2889,2893
<   if (szLine[0]==0 || atoi(szLine) || !EQADDR_SPELLS || !EQADDR_CHAR_INFO || !*EQADDR_CHAR_INFO) {
<       cmdCast(pChar,szLine);
<       return;
<   }
<   PCHARINFO pCharInfo = *EQADDR_CHAR_INFO;
---
>    if (szLine[0]==0 || atoi(szLine) || !EQADDR_SPELLS || !EQADDR_CHAR_INFO || !*EQADDR_CHAR_INFO) {
>       cmdCast(pChar,szLine);
>       return;
>    }
>    PCHARINFO pCharInfo = *EQADDR_CHAR_INFO;
2895,2896c2895,2908
<   DWORD Index;
<   CHAR szBuffer[MAX_STRING] = {0};
---
>    DWORD Index;
>    CHAR szBuffer[MAX_STRING] = {0};
>    CHAR szArg1[MAX_STRING] = {0};
>    CHAR szArg2[MAX_STRING] = {0};
>    if (!stricmp(szLine,"list")) {
>       WriteChatColor("Spells:",USERCOLOR_DEFAULT);
>       for (Index=0;Index<8;Index++) {
>          if (pCharInfo->MemorizedSpells[Index]==0xFFFFFFFF) {
>             sprintf(szBuffer,"%d. <Empty>",Index+1);
>          } else {
>             sprintf(szBuffer,"%d. %s",Index+1,GetSpellByID(pCharInfo->MemorizedSpells[Index]));
>          }
>          WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
>       }
2898,2923c2910,2965
<   if (!stricmp(szLine,"list")) {
<       WriteChatColor("Spells:",USERCOLOR_DEFAULT);
<       for (Index=0;Index<8;Index++) {
<           if (pCharInfo->MemorizedSpells[Index]==0xFFFFFFFF) {
<               sprintf(szBuffer,"%d. <Empty>",Index+1);
<           } else {
<               sprintf(szBuffer,"%d. %s",Index+1,GetSpellByID(pCharInfo->MemorizedSpells[Index]));
<           }
<           WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
<       }
< 
<       return;
<   }
< 
<   GetArg(szBuffer,szLine,1);
<   for (Index=0;Index<8;Index++) {
<       if (pCharInfo->MemorizedSpells[Index]!=0xFFFFFFFF) {
<           PCHAR SpellName = GetSpellByID(pCharInfo->MemorizedSpells[Index]);
<           if (!strnicmp(szBuffer,SpellName,strlen(SpellName))) {
<               cmdCast(pChar,itoa(Index+1,szBuffer,10));
<               return;
<           }
<       }
<   }
<   WriteChatBuffer("You do not seem to have that spell memorized.",USERCOLOR_DEFAULT);
<   return;
---
>       return;
>    }
>    
>    GetArg(szArg1,szLine,1);
>    GetArg(szArg2,szLine,2);
>    DebugSpew("Cast: szArg1 = %s szArg2 = %s",szArg1,szArg2);
>    if (!stricmp(szArg1,"item"))
>    {
>       BOOL FOUND = FALSE;
>       DWORD item = 0;
>       DWORD slot = 0;
>       DWORD SpawnFooter = NULL;
>       SpawnFooter = (DWORD)*EQADDR_SPAWNTAIL;
>       for (int i=0;i<30;i++) {
>          if (pCharInfo->Inventory[i])
>             if (!_stricmp(szArg2,pCharInfo->Inventory[i]->Name)) {
>                DebugSpew("cast test slot %d = %s address is %x",i,pCharInfo->Inventory[i]->Name,pCharInfo->Inventory[i]);
>                item = (DWORD)&pCharInfo->Inventory[i];
>                slot = (DWORD)i;
>                FOUND = TRUE;
>                break;
>             }
>       }
>       if (FOUND) {
>          __asm {
>             push eax;
>             push ecx;
>             push edi;
>             mov ecx, dword ptr [pCharInfo];
>             mov edi, dword ptr [SpawnFooter];
>             push slot;//slot item is in
>             push item; //pointer to the item...
>             push 0x00000000;//always 0
>             push 0x0000000A;//always 10
>             call dword ptr [EQADDR_CASTSPELL];
>             pop edi;
>             pop ecx;
>             pop eax;
>          }
>          return;
>       }
>    }
>    GetArg(szBuffer,szLine,1);
>    for (Index=0;Index<8;Index++) {
>       if (pCharInfo->MemorizedSpells[Index]!=0xFFFFFFFF) {
>          PCHAR SpellName = GetSpellByID(pCharInfo->MemorizedSpells[Index]);
>          if (!strnicmp(szBuffer,SpellName,strlen(SpellName))) {
>             DebugSpew("SpellName = %s",SpellName);
>             cmdCast(pChar,itoa(Index+1,szBuffer,10));
>             DebugSpew("pChar = %x SpellName = %s %s",pChar,SpellName,itoa(Index+1,szBuffer,10));
>             return;
>          }
>       }
>    }
>    WriteChatBuffer("You do not seem to have that spell memorized.",USERCOLOR_DEFAULT);
>    return;
2924a2967
> 


diff -r1.14 EQLib_MacroParser.cpp
2711a2712,2777
>                   // $clickitem(name,xxx) syntax example: /echo $clickitem("Warden symbol of Tunare",casttime)
>                      // will return 4.00 which is correct for the grasping roots effect on that item...
>                      } else if (!strncmp("clickitem(",szVar,10)) {
>                     if (!strstr(szVar,",") || !strstr(szVar,")")) {
>                        DebugSpew("PMP - Bad $spell() '%s'",szVar);
>                        i--;
>                        szOutput[j] = '@';
>                        j++;
>                     } else {
>                        i += (strstr(szVar,")")-szVar);
>                        PCHARINFO pCharInfo = 0;
>                        pCharInfo = *EQADDR_CHAR_INFO;
>                        PSPELLLIST pSpell = 0;
>                        PCHAR szSpell = szVar+10;
>                        PCHAR szArg = strstr(szVar,",")+1;
>                        DWORD Length = strstr(szSpell,",")-szSpell;
>                        CHAR szTemp[MAX_STRING] = {0};
>                        BOOL IsValid = FALSE;
>                        if (szSpell[0]=='"') { szSpell++; Length-=2; }
>                           DebugSpew("%s -> %s|%d, %s",szVar,szSpell,Length,szArg);
>                        strncpy(szTemp,szSpell,Length);
>                        DebugSpew("szTemp = %s szSpell = %s",szTemp, szSpell);
>                        for (int ItemIndex=0;ItemIndex<30;ItemIndex++) {
>                       if (pCharInfo->Inventory[ItemIndex])
>                          if (!_stricmp(szTemp,pCharInfo->Inventory[ItemIndex]->Name)) {
>                             //DebugSpew("$click(%s,%s) in slot %d = %s address is %x",szTemp,szArg,ItemIndex,pCharInfo->Inventory[ItemIndex]->Name,pCharInfo->Inventory[ItemIndex]);
>                             PCHAR pcSpellName = GetSpellByID(pCharInfo->Inventory[ItemIndex]->Common.SpellId);
>                             pSpell = GetSpellByName(pcSpellName);
>                             IsValid = TRUE;
>                             break;
>                          }
>                        }
>                        if (!IsValid) {
>                       strcpy(szTemp,"-1");
>                        } else if (!strncmp(szArg,"id",2)) {
>                       itoa(pSpell->ID,szTemp,10);
>                        } else if (!strncmp(szArg,"level",5)) {
>                       itoa(pSpell->Level[GetCharInfo()->pSpawn->Class-1],szTemp,10);
>                        } else if (!strncmp(szArg,"mana",4)) {
>                       itoa(pSpell->Mana,szTemp,10);
>                        } else if (!strncmp(szArg,"range",5)) {
>                       sprintf(szTemp,"%1.2f",pSpell->Range);
>                        } else if (!strncmp(szArg,"casttime",8)) {
>                       sprintf(szTemp,"%1.2f",(FLOAT)pCharInfo->Inventory[ItemIndex]->Common.CastTime/1000);
>                        } else if (!strncmp(szArg,"recoverytime",12)) {
>                       sprintf(szTemp,"%1.2f",(FLOAT)pSpell->FizzleTime/1000);
>                        } else if (!strncmp(szArg,"recasttime",10)) {
>                       sprintf(szTemp,"%1.2f",(FLOAT)pSpell->RecastTime/1000);
>                        } else if (!strncmp(szArg,"duration",8)) {
>                       DWORD Tics=GetSpellDuration(pSpell,pChar);
>                       if (Tics==0xFFFFFFFF) {
>                          strcpy(szTemp,"PERMANENT");
>                       } else if (Tics==0xFFFFFFFE) {
>                          strcpy(szTemp,"UNKNOWN");
>                       } else if (Tics==0) {
>                          strcpy(szTemp,"INSTANT");
>                       } else {
>                          itoa(Tics*6,szTemp,10);
>                       }
>                        } else {
>                       strcpy(szTemp,"0");
>                        }
>                        strcat(szOutput,szTemp);
>                        j+=strlen(szTemp);
>                     } 
>                       

diff -r1.11 EQLib_Main.cpp
221a222
> DWORD EQADDR_CASTSPELL=0;
264a266
>   GetPrivateProfileString("Function Locations","CastSpell","0",szBuffer,MAX_STRING,ClientINI);        EQADDR_CASTSPELL = (DWORD)strtoul(szBuffer,NULL,16);

diff -r1.35 eqgame.ini
10a11
> CastSpell=00471C0B

Posted: Tue Sep 02, 2003 2:01 am
by GoatFoot
Crashes EQ with Sept 2 zip file.

Posted: Tue Sep 02, 2003 7:16 am
by EqMule
i know. havent had time to fix it yet.

Re: UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Jan 23, 2026 2:25 pm
by xyilla

Re: UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Jan 23, 2026 2:26 pm
by xyilla

Re: UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Jan 23, 2026 2:27 pm
by xyilla

Re: UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Jan 23, 2026 2:30 pm
by xyilla

Re: UPDATED Function: /cast to cast itemeffects as well

Posted: Fri Jan 23, 2026 2:31 pm
by xyilla