This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - Grymskvll
16
« on: May 25, 2017, 07:59:27 pm »
Make sure the SpellFamilyName aka SpellClassSet matches between Mirage Blast and Mirage CD Test in Spell.dbc, and your class in ChrClasses.dbc
17
« on: January 07, 2017, 04:08:30 pm »
Edit: woops, code parts got mangled a bit. Copy+paste them into notepad and use a fixed-width font (such as Courier) to display correctly It's been a while so take what I say with some caution. If you want a spell to affect another one (for example, Improved Renew affects all Renew spells but not other spells), you need to: - set the SpellFamilyName (aka SpellClassSet) to the same value for both (maybe not?)
- set the SpellFamilyFlags (aka SpellClassMask) in the AFFECTED spell (Renew in this case)
- set the EffectSpellClassMasks in the AFFECTING spell (Improved Renew in this case)
The SpellFamilyName is just the identifier of the class that has the spells. SpellFamilyFlags and EffectSpellClassMasks are a bitmasking system. To better understand, turn the values in both into binary. Renew rank 1 (Id=139) has the following SpellFamilyFlags by default, first in hex and below it the same value represented in binary (the exact name of the field may differ, I'm looking at the fields in Stoneharry's spell editor/accompanying database): Id SpellName0 SpellFamilyFlags SpellFamilyFlags1 SpellFamilyFlags2 139 Renew 0x40 0x0 0x400 0000 0000 0100 0000 0 0000 0100 0000 0000
Improved Renew rank 1 (Id=14908) has the following EffectSpellClassMasks for effect 1 by default, again first in hex and below it in binary. Imp Renew only has one effect (out of a possible 3), so the other two effects' EffectSpellClassMask (B1, B2, B3, C1, C2, C3) fields are left out: Id SpellName0 EffectSpellClassMaskA1 EffectSpellClassMaskA2 EffectSpellClassMaskA3 14908 Improved Renew 0x40 0x0 0x0 0000 0000 0100 0000 0 0
Because Renew has the 7th bit set in SpellFamilyFlags, and Imp Renew has the 7th bit set in EffectSpellClassMaskA1, Imp Renew affects Renew. If the bit was set in the second flags field for Renew instead, it wouldn't work. SpellFamilyFlags is checked by EffectSpellClassMaskA1, EffectSpellClassMaskB1, EffectSpellClassMaskC1 SpellFamilyFlags1 is checked by EffectSpellClassMaskA2, EffectSpellClassMaskB2, EffectSpellClassMaskC2 SpellFamilyFlags2 is checked by EffectSpellClassMaskA3, EffectSpellClassMaskB3, EffectSpellClassMaskC3 It doesn't matter if Renew has a bit set set that Imp Renew doesn't match. So long as a single bit in a corresponding field is set, then the spell is affected. If Imp Renew has a bit set that Renew doesn't have, that just means Imp Renew might affect other spells. If Renew has a bit set that Imp Renew doesn't have, that just means Renew might be affected by other spells. As an experiment, we can make the talent Shadow Reach affect Renew by adding a bit to Renew's flags that Shadow Reach already matches. Doing it this way is likely to have side effects. The "cleaner" way would be to take a bit that's unused among priest spells (in any of the SpellFamilyFlags fields), and set that in both the AFFECTING and AFFECTED spells. We'll look at Shadow Reach rank 2 (Id=17323) because I can't find rank 3 for some reason. Again, it only has 1 effect: Id EffectSpellClassMaskA1 EffectSpellClassMaskA2 EffectSpellClassMaskA3 17323 0x682A004 0x300502 0x2040 0110 1000 0010 1010 0000 0000 0100 0011 0000 0000 0101 0000 0010 0010 0000 0100 0000
If we set any of these bits in Renew's flags (in the appropriate field), Renew should have its range extended by 13%. So I'll just open Stoneharry's spell editor, make a duplicate of Renew, set any of the bits from Shadow Reach's masks in an appropriate flags field of Renew, save and export the modified Spell.DBC, then copy it over to the server's DBC directory, put it in a client-side patch so I can learn the new spell, learn the original Renew and the modified version, then learn Shadow Reach (rank shouldn't matter, come to think of it, since all ranks affect identical spells). As you can see, there were some side effects besides the increased range (the heal is stronger and costs less mana). Presumably because the bit by which I allowed Renew to be targeted by Shadow Reach is also targeted by other spells that have that effect. Tips: use as few bits as possible. Depending on where you look, flags/masks will be in hex, binary or decimal. Use online converters.
18
« on: December 17, 2016, 09:57:56 am »
No idea why this would happen. I thought spell.dbc was responsible for procs.
Try loading an unmodified talent.dbc and see if it still bugs. Then try making a tiny change, then another, etc.
19
« on: December 10, 2016, 01:50:48 am »
It doesn't matter if I modify the files or not, it gives the same error. You might be modifying an outdated version of the interface file. Think you want the one from patch-xxXX-2.MPQ
20
« on: December 08, 2016, 11:39:34 pm »
Oh yeah, that's a lot better lol
21
« on: December 08, 2016, 08:51:34 pm »
I couldn't get GameTooltip:SetSpellByID(ID) to work, so I used a hacky way to populate the gametooltip from a spell hyperlink. The only downside is that if you have a hyperlink popup on screen (the little box that appears when you click a chat link for a spell/talent/item), the popup will disappear.
If anyone knows how to actually get GameTooltip:SetSpellByID to work instead of resorting to ghetto magic, please let us know!
local AIO = AIO or require("AIO") AIO.AddAddon()
if not AIO.IsServer() then -- Hacky way to set up custom talent tooltips. Creates and reads an ItemRefTooltip from a spellID and returns a table of text with color and wrap data. -- The ItemRefTooltip is shown, read and hidden again without ever appearing on the screen (hopefully) local function GetSpellTooltip(spellID) if (not ItemRefTooltip:IsVisible()) then ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE"); end ItemRefTooltip:ClearLines(); local linky = "124cff71d5ff124Hspell:"..spellID.."124h124h124r" ItemRefTooltip:SetHyperlink(linky) local numLines = ItemRefTooltip:NumLines(); local tmp = {}; local i = 1; for currentLine=1, numLines do local line = {}; local left = _G["ItemRefTooltipTextLeft"..currentLine]; local right = _G["ItemRefTooltipTextRight"..currentLine]; if ( left ) then line.w = left:CanWordWrap(); line.leftR, line.leftG, line.leftB = left:GetTextColor(); line.left = left:GetText(); end if ( right ) then line.rightR, line.rightG, line.rightB = right:GetTextColor(); line.right = right:GetText(); end tmp[i] = line; i = i + 1; end HideUIPanel(ItemRefTooltip); return(tmp) end
function GameTooltip:ActuallySetSpellByID(spellID) local tmp = GetSpellTooltip(spellID) GameTooltip:ClearLines() for i=1, #tmp do if ( tmp[i].left and tmp[i].right ) then GameTooltip:AddDoubleLine(tmp[i].left, tmp[i].right, tmp[i].leftR, tmp[i].leftG, tmp[i].leftB, tmp[i].rightR, tmp[i].rightG, tmp[i].rightB); elseif ( tmp[i].left ) then GameTooltip:AddLine(tmp[i].left, tmp[i].leftR, tmp[i].leftG, tmp[i].leftB, tmp[i].w); elseif ( tmp[i].right ) then GameTooltip:AddDoubleLine("", tmp[i].right, 0, 0, 0, tmp[i].rightR, tmp[i].rightG, tmp[i].rightB); end end GameTooltip:Show() end end
To test it, enter the game, mouse over a spell in your spellbook and paste this in chat to set the tooltip to Blizzard rank 1:
/run GameTooltip:ActuallySetSpellByID(10)
22
« on: October 23, 2016, 12:51:27 am »
Sounds really cool. Any plans for texture generating?
23
« on: October 02, 2016, 08:01:44 pm »
I have not succeeded. I have just the base map ... :/ Do you get something vastly different from what's seen in this tutorial: http://modcraft.io/viewtopic.php?f=21&t=1686 ? What you see is what you get. It's a template. Man, that guide should really use layer masks more.
24
« on: October 01, 2016, 06:14:24 pm »
Hi, it's possible to convert PSD to PNG and give me the pictures? I do not use photoshop and I have not found how to convert with layers :/
Thanks !
A litte French :') GIMP can work with PSD files. If you don't like GIMP, you can use it to open the PSD and export the layers as plain images.
25
« on: September 13, 2016, 05:39:35 pm »
How are you going to access SpellFlyout.dbc?
26
« on: August 28, 2016, 04:35:04 pm »
According to the error popup, this part is causing the error:
for i=1, MAX_RACES, 1 do local button = getglobal("CharacterCreateRaceButton"..i); button:Enable(); SetButtonDesaturated(button, false) end You have
MAX_RACES = 22; And your XML file only creates up to and including CharacterCreateRaceButton12.
27
« on: August 24, 2016, 08:47:00 pm »
To add a custom tooltip line for Epic difficulty items, you need to make some changes to Wow.exe (or alternatively do some Lua tooltip modding). This is for WotLK 3.3.5 12340 Backup your Wow.exe. Also, this probably requires that you've already patched Wow.exe to load custom interface files. Open up notepad and copy this over: OFFSET_1 = OFFSET_2 = OFFSET_3 = OFFSET_4 = OFFSET_5 = OFFSET_6 =
Open Wow.exe in OllyDbg. Right click, search for -> All referenced strings In the strings window, hit ctrl+f and find "ITEM_HEROIC". Double click it and it'll take you to something that looks like this (the addresses might be slightly different): 00627BA3 F641 18 08 TEST BYTE PTR DS:[ECX+18],08 00627BA7 74 24 JE SHORT 00627BCD 00627BA9 |> /56 PUSH ESI 00627BAA |. |6A FF PUSH -1 00627BAC |. |68 4866A200 PUSH OFFSET 00A26648 ; ASCII "ITEM_HEROIC" 00627BB1 |> |E8 8A211F00 CALL 00819D40 00627BB6 |. |83C4 0C ADD ESP,0C 00627BB9 |. |56 PUSH ESI 00627BBA |. |68 402DAD00 PUSH OFFSET 00AD2D40 00627BBF |. |68 402DAD00 PUSH OFFSET 00AD2D40 00627BC4 |> |56 PUSH ESI 00627BC5 |. |50 PUSH EAX 00627BC6 |> |8BCF MOV ECX,EDI 00627BC8 |. |E8 F382FFFF CALL 0061FEC0 ; Wow.0061FEC0 00627BCD |> |3975 F0 CMP DWORD PTR SS:[EBP-10],ESI
Right click the first "PUSH ESI" line (2 higher than the line with the ASCII comment), Edit->Copy address Paste the address after OFFSET_1 in Notepad Do the same for "CALL 00819D40" as OFFSET_2 Do the same for "CMP DWORD PTR SS:[EBP-10],ESI" as OFFSET_3 Now scroll to the bottom where you just see a bunch of lines that say "DB 00" (you can press Page Up/Down to advance one page at a time). Pick a nice empty spot with 60 empty bytes. I chose 009DE3C0 Write down the address you choose as OFFSET_4 Calculate OFFSET_4 + 0x13 ( http://www.miniwebtool.com/hex-calculator/), write it down as OFFSET_5. Calculate OFFSET_4 + 0x24, write it down as OFFSET_6 Starting at your OFFSET_4, enter these lines, replacing OFFSET_# with your addresses: TEST BYTE PTR DS:[ECX+18],01 JE SHORT OFFSET_5 PUSH ESI PUSH -1 PUSH OFFSET_6 JMP OFFSET_2 TEST BYTE PTR DS:[ECX+18],08 JE OFFSET_3 JMP OFFSET_1
Press ctrl+G and go to OFFSET_6. Right click the highlighted line, go to Edit -> Binary edit Put your cursor at the leftmost place in the HEX field, right click and paste this (make sure "Keep size" is UNCHECKED): 49 54 45 4D 5F 48 45 52 4F 49 43 5F 45 50 49 43 5F 43 55 53 54 4F 4D 00 00 00 00
This will turn into ASCII "ITEM_HEROIC_EPIC_CUSTOM", which will be the name of our global Lua variable that holds the string we want to show in the tooltip. Select all the red lines, right click -> Edit -> Copy to executable. Don't close the popup, minimize it or drag it to the side so you can still find it. Go back to the main window. Press ctrl+G and go to OFFSET_1. Select the two lines above it that say "TEST..." and "JE SHORT..." Right click, Edit->Fill with NOPs Then, with the red NOP lines still selected press space to edit them to: JMP OFFSET_4 NOP
Select these 2 red lines, right click -> Edit -> Copy to executable. Now go to the popup from before, right click -> Save to file... Choose a name you'll recognize, like Wow_tooltip_test.exe. Close OllyDbg. Next you just need to add a string for ITEM_HEROIC_EPIC_CUSTOM to GlobalStrings.lua Extract the most up-to-date GobalStrings.lua from your game archives (or if you've already modified it, grab your modified one). Open GlobalStrings.lua, search for "ITEM_HEROIC_EPIC". Under it, add this line, replacing the string with whatever you like ITEM_HEROIC_EPIC_CUSTOM = "Epic Dungeon loot";
Save and pack into a custom MPQ or load it straight from WowInterfaceFrameXML Finally, to create an item with this new tooltip line, set the 0x01 flag for the item in world.item_template. If you're changing an existing item, remember to delete your client cache (WowcacheWDB). If you don't know how to change the flag properly, take the old "flags" value from your world.item_template item row, convert to hex, add 0x01, convert back to decimal and enter it back into your database. A warning is due, though. The 0x01 flag isn't used and its purpose is unknown, but it's possible that it will interfere with something. If the mod works but it crashes at a (random?) point, or has some other weird behavior, let me know. If this happens and you want to try to fix it, check documentation for the "flags" field in world.item_template and see which other flags are unused. You'll need to modify the condition we added for the 0x01 flag and update item flags. Here's the result:
28
« on: August 16, 2016, 04:46:56 pm »
This is a system for custom secondary powertypes, like combo points, DK runes or spriests' shadow orbs. Here's a demo video, I previously posted it in the showoff thread: [media:20r7yr4d]https://www.youtube.com/watch?v=qHSFOsNAs_A[/media:20r7yr4d] If I forgot anything or if you have improvements, please let me know. To use this, you need to have patched Wow.exe to load modified interface files. See http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-and-programs/501200-repost-sig-md5-protection-remover.htmlFirst we need to add some Eluna player hooks for various stages of casting. We need 3 new hooks: PLAYER_EVENT_ON_SPELL_CAST_START (validation and cancellation: script can return false to cancel the cast) PLAYER_EVENT_ON_SPELL_CAST_SUCCESS (spell passed normal checks for range, mana, target, etc, so now we do custom validation, but NO CHANGES ARE APPLIED in case a later script that registered this hook wants to cancel the cast) PLAYER_EVENT_ON_SPELL_LAUNCH (spell passed all custom validation from the previous hook, so here we can take custom power or do anything else without bugs) To add these hooks, we need to modify various files. Hopefully it's not too disorienting. Make sure you don't have any uncommited changes before beginning! In gameSpellsSpell.cpp, at the top of Spell::prepare, add the Eluna hook: void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura) {
#ifdef ELUNA if (Player* playerCaster = m_caster->ToPlayer()) { if (!sEluna->OnSpellCastStart(playerCaster, this)) { finish(false); return; } } #endif
In Spell::Cast, below "CallScriptOnCastHandlers();" add the Eluna hook: CallScriptOnCastHandlers();
#ifdef ELUNA if (Player* playerCaster = m_caster->ToPlayer()) { if (!sEluna->OnSpellCastSuccess(playerCaster, this)) { SendInterrupted(0);
if (playerCaster->GetTypeId() == TYPEID_PLAYER) { playerCaster->RestoreSpellMods(this); // cleanup after mod system // triggered spell pointer can be not removed in some cases playerCaster->SetSpellModTakingSpell(this, false); } finish(false); SetExecutedCurrently(false);
return; } } #endif
At the top of Spell::HandleLaunchPhase(), add the Eluna hook: void Spell::HandleLaunchPhase() { if (Player* playerCaster = m_caster->ToPlayer()) { sScriptMgr->OnPlayerSpellLaunch(playerCaster, this); }
In LuaEngineHeader FilesHooks.h, in "enum PlayerEvents" add: PLAYER_EVENT_ON_SPELL_CAST_START = 43, // (event, player, spell) PLAYER_EVENT_ON_SPELL_CAST_SUCCESS = 44, // (event, player, spell, skipCheck) PLAYER_EVENT_ON_SPELL_LAUNCH = 45, // (event, player, spell)
In LuaEngineHeader FilesLuaEngine.h, add this under the "void OnTextEmote" declaration: bool OnSpellCastStart(Player* pPlayer, Spell* pSpell); bool OnSpellCastSuccess(Player* pPlayer, Spell* pSpell); void OnSpellLaunch(Player* pPlayer, Spell* pSpell);
In LuaEngineSource FilesPlayerHooks.cpp, add the following: bool Eluna::OnSpellCastStart(Player* pPlayer, Spell* pSpell) { START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_SPELL_CAST_START, true); bool result = true; Push(pPlayer); Push(pSpell); int n = SetupStack(PlayerEventBindings, key, 2);
while (n > 0) { int r = CallOneFunction(n--, 2, 1);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false;
lua_pop(L, 1); }
CleanUpStack(2); return result; }
bool Eluna::OnSpellCastSuccess(Player* pPlayer, Spell* pSpell) { START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_SPELL_CAST_SUCCESS, true); bool result = true; Push(pPlayer); Push(pSpell); int n = SetupStack(PlayerEventBindings, key, 2);
while (n > 0) { int r = CallOneFunction(n--, 2, 1);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false;
lua_pop(L, 1); }
CleanUpStack(2); return result; }
void Eluna::OnSpellLaunch(Player* pPlayer, Spell* pSpell) { START_HOOK(PLAYER_EVENT_ON_SPELL_LAUNCH); Push(pPlayer); Push(pSpell); CallAllFunctions(PlayerEventBindings, key); }
In gameScriptingScriptMgr.h, add this under the "virtual void OnTextEmote" declaration: // Called in Spell::Prepare. virtual void OnSpellCastStart(Player* /*player*/, Spell* /*spell*/) { }
// Called in Spell::Cast. virtual void OnSpellCastSuccess(Player* /*player*/, Spell* /*spell*/) { }
// Called in Spell::HandleLaunchPhase. virtual void OnSpellLaunch(Player* /*player*/, Spell* /*spell*/) { }
In gameScriptingScriptMgr.cpp, add: void ScriptMgr::OnPlayerSpellCastStart(Player* player, Spell* spell) { #ifdef ELUNA sEluna->OnSpellCastStart(player, spell); #endif FOREACH_SCRIPT(PlayerScript)->OnSpellCastStart(player, spell); }
void ScriptMgr::OnPlayerSpellCastSuccess(Player* player, Spell* spell) { #ifdef ELUNA sEluna->OnSpellCastSuccess(player, spell); #endif FOREACH_SCRIPT(PlayerScript)->OnSpellCastSuccess(player, spell); }
void ScriptMgr::OnPlayerSpellLaunch(Player* player, Spell* spell) { #ifdef ELUNA sEluna->OnSpellLaunch(player, spell); #endif FOREACH_SCRIPT(PlayerScript)->OnSpellLaunch(player, spell); }
Next, we need to add a new Eluna spell method: SendCastResult. This is needed so that our Eluna script can send the player's client a notification to cancel the casting state and GCD, using castresult code 0 (SPELL_FAILED_SUCCESS), which has no error notification so we can jam in our custom "Not enough powertype" message separately. In hindsight, it might've been just as good to put a call to spell->SendCastResult inside Spell::prepare and Spell::Cast... oops. In LuaEngineMethodsSpellMethods.h, within "namespace LuaSpell" add: int SendCastResult(Eluna* /*E*/, lua_State* L, Spell* spell) { SpellCastResult result = (SpellCastResult)Eluna::CHECKVAL<uint32>(L, 2); spell->SendCastResult(result); return 0; }
In LuaEngineSource FilesLuaFunctions.cpp, in ElunaRegister<Spell> SpellMethods[], add this under // Other: { "SendCastResult", &LuaSpell::SendCastResult },
To make spells that require the custom secondary power, create a spell with no power cost (the powertype shouldn't matter). Finally, here's an archive with an MPQ required by each client that defines some custom secure vars and has some art required by the Happy Hearts example, as well as the AIO script with two example secondary powers included ("Happy Hearts" for the shaman, "Displeasure" for the warrior). The spell IDs in the examples are basic custom spells I made for testing. There's nothing special about them besides having 0 cost in Spell.dbc. Spell costs are handled in each power's own script file, in the "consuming" and "generating" tables. The Happy Hearts example has some comments. To make a new custom secondary power, copy one of the examples (Happy Hearts probably), and modify it to your needs (token, values at the top, update function, graphic setup). You don't need to change the main script file. Mirror: https://a.fluntcaps.me/eakwpn.zip
29
« on: August 11, 2016, 05:13:09 am »
There's already spells you can cast while mounted, like paladin auras, warrior stances, dk presences, hunter tracking. https://wowdev.wiki/Spell.dbc/AttributesSPELL_ATTR0_CASTABLE_WHILE_MOUNTED = 0x01000000, // 24 castable while mounted Stoneharry's spell editor recommended for editing ease, you can just click a checkbox for it.
30
« on: August 10, 2016, 12:13:46 am »
Sorry, I misinterpreted your earlier post
|