Cannot Use Gold-Cost Ability on any Unit-Summoned Unit

edited September 6 in General

The title may be confusing, so let me clarify:

Player uses an item to summon a Giant Wolf. The Giant wolf has an ability that costs 200gp, which summons an Alpha Wolf. This works fine. However, when the Alpha Wolf tries to use his 900gp ability to summon a Lycan Shapeshift Wolf, the Player gets the error "Not Enough Gold." Alpha Wolf will otherwise move/attack just fine. I suspect that Dota has decided the Alpha Wolf belongs to the Giant Wolf, and not to the Player.

How do I fix that?

Summons are accomplished via "SpawnUnit" in custom abilities "summon_AlphaWolf" and "summon_AcnientWolf" in the npc_custom_abilities.txt file.

The code that I haphazardly tried was this:

function ResetOwner ( event )
    local player = PlayerResource:GetPlayer(0)
    local unit = CreateUnitByName("base", Vector(0,0,0), false, nil, nil, DOTA_TEAM_GOODGUYS)
    unit:SetOwner(hero)
    unit:SetControllableByPlayer(0,false)
end

But this obviously won't work. I understand that "RunScript" inside of "OnSpellStart" probably doesn't automatically know stuff like "unit = the unit I just summoned." So how do I tell the script what unit to adjust ownership on? And how do I tell the script the correct Player to give the ownership of that unit to, especially if there are multiple people on the Player's team?

I am currently trying to learn Lua, so I'm sorry if it feels like I'm asking you to spoon-feed me. It's just tough to get into stuff like this without a teacher/class, and this particular problem leaves me feeling very lost.

Any Help is Greatly Appreciated,

Abraham Blinkin'

Comments

  • edited September 6 Posts: 151

    in the OnSpawn block you can do RunScript and call some function and in that function you can use PrintTable( keys ) to see all the resources you have available.

    (or the built in function DeepPrintTable, but that one prints so much shit you dont need)

    you can probably just do keys.unit:SetOwner(keys.caster) in the OnSpawn's function

  • edited September 6 Posts: 19

    Hm, the console is returning 'caster' as nil global value. If I apply a RunScript to the first summon that establishes the item caster as the global 'caster' then will this work? Or will it give control of all game units to whomever most recently summoned a unit...?

    I tried this, but no dice:

    function SetOwner ( event )
            local UnitOwner = event.caster
    end
    
    function ResetOwner ( event )
            local UnitOwner = PlayerResource:GetPlayer()
            PrintTable( keys )
            keys.unit:SetOwner(UnitOwner)
    end
    

    I established SetOwner at the beginning of the first summon (in which the player is clearly the caster) and then a used ResetOwner in the second summoning ability.

    Oddly enough, PrintTable( keys ) isn't returning anything to the console. Anything whatsoever.

  • Posts: 151

    all right well first let me make something clear. just putting caster or target or whatever, will never mean anything.

    you need to access caster as a value in the table

    so keys.caster or event.caster, potato.caster... whatever you call the data passed into the function

    -

    it should actually be

    keys.target:SetOwner(keys.caster:GetPlayerOwner())
    
  • I was just informed that it would be easier for me to recreate my items and abilities in Lua, and set the owner at the same time. Some of the guys on the Discord channel said that what I'm asking for here is nearly impossible.

  • Posts: 151

    actually took some time to recreate a similar ability and test it, its has a pretty simple solution. i just stored the original caster in each unit..

    function AbilityN( keys )
        local caster = keys.caster
        local target = keys.target
        local ability = keys.ability
    
        target:AddAbility(ability:GetName()):SetLevel(1)
        FindClearSpaceForUnit(caster, caster:GetAbsOrigin(), false)
    
        target.originalCaster = caster.originalCaster or caster
    
        print("UNIT: "..target:GetOwner():GetName())
        print("CASTER: "..caster:GetName())
        print("HACK: ",target.originalCaster:GetName())
    
        target:SetControllableByPlayer(target.originalCaster:GetPlayerID(), false)
        target:SetOwner(target.originalCaster)
    end
    
  • Posts: 151

    in response to your edited post..

    local variables are only for use in that function, you cant define unitOwner locally and then refer to it in a different function.

    and the reason PrintTable didnt do anything is because "keys" is nil, its not defined anywhere. if you did PrintTable(event) it would work because thats what you called the data being passed into the function

  • edited September 10 Posts: 19

    ((EDITED))

    It looks like it ALMOST worked. The ability the lua added to the unit shows up as a castable spell, but when i try to cast the spell Dota says "item must be in inventory to use."

    Is there a small change I can implement that will make the ability hidden? And make it cast automatically (like an aura or something)?

  • Posts: 151

    are you using baseclass item_datadriven ...?

    to make it hidden use DOTA_ABILITY_BEHAVIOR_HIDDEN or if you want to do it in lua (not sure if hidden abilities are castable)

    ability:SetHidden(true)
    

    and if you want it to cast automatically you will probably have to write a script to handle when and what to cast it on. https://github.com/MNoya/PMP/blob/master/game/dota_addons/pmp/scripts/vscripts/abilities/blood_elf/heal.lua#L19