• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Modifying Blizzard.j (1.28)

Status
Not open for further replies.
Level 10
Joined
May 31, 2019
Messages
139
In an effort to optimize the core systems of My Zerg Campaign and make them easier to maintain, I'm playing around with the idea of using a modified Blizzard.j, rather than have a huge amount of gui triggers needing to be duplicated for each map.

I started by studying how Project Revolution did their Blizzard.j modification, so as to have an idea of where the modifications should be inserted. They basically create a bunch of triggers in globals, and then in the InitBlizzard function, they call a function that add events and actions to their triggers, which serve as a method of calling the various system functions they made.

Now of course, Project Revolution was made for War3 1.21, and I'm working with 1.28 here. So I'm basing my modifications off of 1.28.5's Scripts\Blizzard.j found in War3x.MPQ (since it doesn't use a War3Patch.mpq. Then I plan to include this file in the ZergCampaign's War3Mod.mpq.

I wanted to start with a very simple modification, so I've followed ProjectRevolution's approach and created a trigger, assigned the 'EVENT_PLAYER_UNIT_SPELL_EFFECT' event to it, and added an action that should display a text message to Player(0) if the GetSpellAbilityId() is Wind Walk.

But when I try to start the game with my modified Blizzard.j, it says 'Could not load the map data'.

I assume there's some issue somewhere, but I cant figure out what it might be. Anyone have an idea?

I've attached my script (pies.blizzard.j) and ProjectRevolution's (PR.Blizzard.j) for comparison.
 

Attachments

  • PR.Blizzard.j
    889.9 KB · Views: 29
  • pies.blizzard.j
    444 KB · Views: 35
Level 10
Joined
May 31, 2019
Messages
139
Played around with this again. This time with an even more simple modification. It seems that the game is okay with adding variables to the globals, and with adding some function calls at the end of InitBlizzard().

It seems the sticking point with the game is if you try to add any functions at the end of blizzard.j.
For example, I was able to call DisplayTextToPlayer() just fine at the end of InitBlizzard(). But take that call DisplayTextToPlayer(), put it into its own new function at the end of blilzzard.j, and call the new function from InitBlizzard()? NOT okay.

I feel like this should be possible. But I can't seem to figure out how.
 

Attachments

  • Blizzard.j
    441.6 KB · Views: 35

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
It seems the sticking point with the game is if you try to add any functions at the end of blizzard.j.
For example, I was able to call DisplayTextToPlayer() just fine at the end of InitBlizzard(). But take that call DisplayTextToPlayer(), put it into its own new function at the end of blilzzard.j, and call the new function from InitBlizzard()? NOT okay.
That is because the function is not declared before InitBlizzard. You are basically trying to call a function that does not exist yet. This limit exists in the normal map script as well, which is why vJASS has language features like libraries and scopes so that it can arrange the script by dependency.

This constraint is not unique to JASS, with both C and C++ also having it. Their work around is to declare function prototypes to reference which can be defined somewhere else. Sadly JASS does not support this feature, although StarCraft II Galaxy script does.
 
Level 10
Joined
May 31, 2019
Messages
139
Cool. Moving the function above InitBlizzard works.

So now I'm trying to implement more complicated function, but I've hit a snag.

JASS:
// What to do for each unit in the Plague area.
function SC_Plague_Loop takes nothing returns nothing
    local unit unitEnum = GetEnumUnit()
    if ( SC_Plague_UnitCheck(unitEnum) ) then
        local location ptAffectedUnit = GetUnitLoc(unitEnum)
        //local location ptAffectedUnit = Location(0,0)
        //Using a Footman as a temporary placeholder
        //call CreateNUnitsAtLocFacingLocBJ(1, 'hfoo', Player(PLAYER_NEUTRAL_PASSIVE), ptAffectedUnit, ptAffectedUnit)
        //call SetUnitVertexColorBJ(bj_lastCreatedUnit, 100, 100, 100, 100.00)
        //call IssueTargetOrderBJ(bj_lastCreatedUnit, "attackonce", unitEnum)
        //call SetUnitExplodedBJ(bj_lastCreatedUnit, true)
        //call UnitApplyTimedLifeBJ(0.30, 'BTLF', bj_lastCreatedUnit)
        //call RemoveLocation(ptAffectedUnit)
    else
    endif
endfunction

If I comment out that
JASS:
local location ptAffectedUnit
declaration, maps can load again. But if I don't, I cannot. Is there a reason local locations cannot be declared in Blizzard.j functions?
The same issue happens with the version on the line below, assigning it to Location(0,0).
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
They can be declared in those functions fine.
The same issue happens with the version on the line below, assigning it to Location(0,0).
That is because of the syntax error. You can only declare local variables after the function declaration and before the first non-local variable declaration statement.

This is a fairly common restriction for old programming languages. Even early revisions of C has this requirement.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
I'm using Sharpcraft World Editor Extended since it's compatible with 1.28. Is there a way to get the JassHelper to acknowledge my modified Blizzard.j?
You probably need to update the copy of Blizzard.j that JassHelper is using to reflect your changes. It is located somewhere in the Shaprcraft install folder tree.
 
Level 10
Joined
May 31, 2019
Messages
139
I've tried a more simple test now: a map that simply displays the value of one of the globals I added in my modified Blizzard.j

I've discovered that SharpCraft appears to always take the Blizzard.j from War3x.mpq. Because when I overwrote the blizzard.j in War3x.mpq, SharpCraft's JassHelper ran successfully, and the value displays correctly in-game.

So the issue is really just convincing SharpCraft to check War3Mod.mpq for Blizzard.j
Not sure if there's anyway to configure that though.
 

Attachments

  • SharpCraft Modified BlizzardJ Test.7z
    676.6 KB · Views: 11
Last edited:
Status
Not open for further replies.
Top