Problem with initializing in LUA after installing NewBonus

Level 4
Joined
Jun 6, 2015
Messages
82
I heard that there is no such thing as a stupid question..

Ok so I am gonna try to do some LUA here again. I'm sure there is a simple explanation for this but I cant figure it out.
I have created a simple spell and it works great. I don't quite get how to use custom made initialization yet so I am doing it the standard way.
(I have bribes Damage Engine installed, although I have changed the Damage to DamageE in an attempt to make it compatible with NewBonus's Damage interface)

So there is no problem in doing this, it works great. BUT when I install the Chopinski's newbonus system into the map, my triggers don't work anymore. They work only once.
I tried to delete newbonus and it worked again.

Any tips on how to implment both bribes Damage Engine and Chopinskis NewBonus?

Initializing the spell:
  • RegisterKvartsmester
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: RegisterQuartzHammerCastTrigger()
      • Custom script: RegisterQuartzHammerTrigger()

The spell:
Lua:
local unitSpellCastFlags = {}

function OnQuartzHammerCast()
    local castingUnit = GetTriggerUnit()
    local spellId = GetSpellAbilityId()
    if spellId == FourCC('KV01') then
        unitSpellCastFlags[GetHandleId(castingUnit)] = true
    end
end

function RegisterQuartzHammerCastTrigger()
    local castTrigger = CreateTrigger()
    TriggerRegisterAnyUnitEventBJ(castTrigger, EVENT_PLAYER_UNIT_SPELL_CAST)
    TriggerAddAction(castTrigger, OnQuartzHammerCast)
end


function QuartzHammerEffect()
    local source = udg_DamageEventSource
    local target = udg_DamageEventTarget
    
    if unitSpellCastFlags[GetHandleId(source)] then
        -- Clear the flag to ensure it's only triggered once per cast
        unitSpellCastFlags[GetHandleId(source)] = nil

        -- Get x, y coordinates of the target
        local x = GetUnitX(target)
        local y = GetUnitY(target)

        -- Set attribute stats
        local strength = GetHeroStr(source, true)
        local intelligence = GetHeroInt(source, true)

        -- Set stun duration (max 5 seconds by bonuses)
        local stunDur = 2 + (strength * 0.01)
        if stunDur > 5 then
            stunDur = 5
        end

        -- Set damage
        local targetDamage = strength * 3
        local aoeDamage = intelligence * 1

        -- Deal damage to the target unit
        DamageE.apply(source, target, targetDamage, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)

        -- Create the dummy unit at the target location
        local dummy = CreateUnit(GetOwningPlayer(source), FourCC('DUMM'), x, y, 0)

        -- Give the dummy unit the Stomp ability and set its stun duration and damage
        UnitAddAbility(dummy, FourCC('S000'))
        BlzSetAbilityRealLevelField(BlzGetUnitAbility(dummy, FourCC('S000')), ABILITY_RLF_DURATION_NORMAL, 0, stunDur)
        BlzSetAbilityRealLevelField(BlzGetUnitAbility(dummy, FourCC('S000')), ABILITY_RLF_DAMAGE_WRS1, 0, aoeDamage)
        IssueImmediateOrder(dummy, "stomp")

        -- Remove the dummy unit after a short time
        TimerStart(CreateTimer(), 2.5, false, function()
            RemoveUnit(dummy)
            DestroyTimer(GetExpiredTimer())
        end)
    end
end

function RegisterQuartzHammerTrigger()
    local quartzHammerTrigger = CreateTrigger()
    TriggerRegisterVariableEvent(quartzHammerTrigger, "udg_DamageEvent", NOT_EQUAL, 0.00)
    TriggerAddAction(quartzHammerTrigger, QuartzHammerEffect)
end


NewBonus: New Bonus [vJASS][LUA]
Damage Engine: Damage Engine 5.A.0.0
 
It might be worth attaching a separate test map with your spell and the two systems integrated (or attaching your map itself) for folks to take a look. Unfortunately, the Lua compiler isn't particularly helpful in these areas--especially when it comes to naming collisions (which are really easy to run into). I know they both use "Damage" for a lot of their naming, and while you did rename Bribe's to DamageE, it's possible there were still some spots missed. :p

I would also add some print statements in OnQuartzHammerCast() and QuartzHammerEffect() to see if the functions are still running as expected (or where exactly it is failing--i.e. perhaps it is running correctly but simply the damage part isn't working). It is possible that it is hitting some exception in Lua down the line too--in that case, I recommend integrating something like DebugUtils (see below).

As a side note, I recommend reading up on this as it definitely helped me get up to speed with Lua:

As part of it, it mentions installing two libraries that have definitely been enormously helpful for me:
  • DebugUtils - this one will provide helpful messages in-game for common lua programming errors, e.g. referencing a nil value and such. It is really easy in Lua to do one typo and then suddenly your whole script or even map stops working correctly. This library is a life saver. In terms of usage, I just recommend wrapping all your individual Lua files in a Debug.beginFile("Name of module")/Debug.endFile(), e.g. in your case Debug.beginFile("QuartzHammer") at the top of your file and Debug.endFile() at the bottom of your file.
  • TotalInitialization - this lets you handle initialization really easily. Just copy this system into your map, and then you can just write this in your files: OnInit.trig(RegisterQuartzHammerTrigger) and OnInit.trig(RegisterQuartzHammerCastTrigger)
I'd start by slapping those into your map and then running the game and seeing if you see anything insightful. If not, attach a map here and maybe we can take a deeper dive. 🧐
 
Level 4
Joined
Jun 6, 2015
Messages
82
Thanks, TotalInitialization worked great :)
Gonna look into DebUtils as well.

I am pretty sure I didn't miss anything in the Damage Engine. When I disable all triggers in newBonus and its libraries, all my triggers work fine. But when I eneable the "utilities" trigger and also along with the triggers it requires: Indexer, Timed handles and RegisterPlayerUnitEvent, my triggers no longer seem to initialize as they from this point only trigger once. I'll attach my map with the NewBonus disabled. And if you enable it you'll see what I mean.
 

Attachments

  • FlaatGruverNewBonus.w3x.zip
    907.3 KB · Views: 4
Thanks, TotalInitialization worked great :)
Gonna look into DebUtils as well.

I am pretty sure I didn't miss anything in the Damage Engine. When I disable all triggers in newBonus and its libraries, all my triggers work fine. But when I eneable the "utilities" trigger and also along with the triggers it requires: Indexer, Timed handles and RegisterPlayerUnitEvent, my triggers no longer seem to initialize as they from this point only trigger once. I'll attach my map with the NewBonus disabled. And if you enable it you'll see what I mean.
Got it! Thanks for the clear repro steps.

It seems like the problem lies in TimedHandles conflicting with the "Timed" module that the DamageEngine depends on (they both declare/use Timed as the class name). From what I can tell, NewBonus/Utilities only uses the plain-function interface for TimedHandles (e.g. DestroyLightningTimed rather than Timed:handle(...)), so I think you can fix the problem by going into the TimedHandles file and changing this line:
Lua:
Timed = setmetatable({}, {})
to
Lua:
local Timed = setmetatable({}, {})

That way the "Timed" in TimedHandles will be local to the file, and therefore won't mess with the other Timed module. I made that change and that seemed to fix it!
 
Level 4
Joined
Jun 6, 2015
Messages
82
Got it! Thanks for the clear repro steps.

It seems like the problem lies in TimedHandles conflicting with the "Timed" module that the DamageEngine depends on (they both declare/use Timed as the class name). From what I can tell, NewBonus/Utilities only uses the plain-function interface for TimedHandles (e.g. DestroyLightningTimed rather than Timed:handle(...)), so I think you can fix the problem by going into the TimedHandles file and changing this line:
Lua:
Timed = setmetatable({}, {})
to
Lua:
local Timed = setmetatable({}, {})

That way the "Timed" in TimedHandles will be local to the file, and therefore won't mess with the other Timed module. I made that change and that seemed to fix it!
You're a goddamn legend.

I was reconciling with the idea of using either NewBonus or Damage Engine on my project, thanks!
 
Top