#Shared Abilities

1 messages · Page 1 of 1 (latest)

trail apex
#

I have a building that belongs to the team and shares its abilities and items with all of the players on the team. These are all sort of "auto battler" abilities, so you click a point, there's some CastFilterResultLocation(location) stuff that goes on to make sure you're trying to spawn that unit in a lane/valid location, and then after a 2 second delay, that unit spawns.

This works perfectly well with the items.

With the abilities though, I can see from debug output that I'm getting the correct UF_SUCCESS or UF_FAIL_INVALID_LOCATION, however the OnSpellStart() is NEVER hit.

My KVs look something like:

"DOTAAbilities"
{
    "ability_train_champ_creep"
    {
      "BaseClass"        "ability_lua"
      "ScriptFile"          "abilities/mercs/ability_train_champ_creep.lua"
      "AbilityTextureName"  "mercenary/champ_creep"
      "MaxLevel"        "1"
      "FightRecapLevel"     "1"
      "AbilityType"        "DOTA_ABILITY_TYPE_BASIC"
      "AbilityBehavior"     "DOTA_ABILITY_BEHAVIOR_OPTIONAL_POINT | DOTA_ABILITY_BEHAVIOR_CHANNELLED"
      "AbilitySharedWithTeammates"    "1"
      "AbilityCastPoint"        "0.0"
      "AbilityCooldown"            "30"
      "AbilityManaCost"            "0"
      "AbilityCastRange"        "0" //global?
    }
}

As a sanity check, I changed the AbilityBehavior to DOTA_ABILITY_BEHAVIOR_NO_TARGET and validated that OnSpellStaart() gets hit that way. So I'm not sure if there's just some issue of passing a successful target by a shared owner to the team-owned structure's ability so that the spell phase starts? Not really sure what I'm missing here or if there's something dumb I just forgot to check/set?

mighty galleon
#

Does it help if you replace OPTIONAL_POINT behavior to just POINT?

trail apex
#

err whoops, yeah, I had POINT originally and was testing with OPTIONAL to see if it made a difference - which it didn't

mighty galleon
#

If you remove the cast filter result location stuff, does it work?

Also, is it correct that it's a channeled ability?

#

the main thing would be to start removing things until you see the ability start working as intended, then slowly giving it back stuff

trail apex
#

So I know that the print statement in OnSpellStart gets hit if I use DOTA_ABILITY_BEHAVIOR_NO_TARGET

I've tried removing DOTA_ABILITY_BEHAVIOR_CHANNELLED as well, no difference. No errors in the log or anything. It's just like it never starts the spell.

I've tried adding in some other things too like a OnAbilityPhaseStart that prints "Test" and returns true no matter what, but that doesn't get triggered either

#

The thing that's weird to me is I have items that use basically the same logic and work, but when it's an ability, the targeting stuff gets totally messed up

The only major difference (outside ability vs item) is that with items I can do:

merc_item:SetShareability(ITEM_FULLY_SHAREABLE)

when I load up the inventory after I spawn the building

#

well, I guess that isn't a major difference because the ability is shareable, but something is different about it's usage compared to an item it seems. My worry is that abilities don't share the same way items do and it's not setting the caster target location correctly and throwing the cast out somewhere behind the scenes

mighty galleon
#

I never really worked on shared abilities, so you'll have to do some self testing here.

The only thing I can see that maybe has some meaning is AbilityCastRange is 0, can you try making it some huge value like 20000?

trail apex
#

yeah, I put that to 9999999 as well

#

I wish there was something I could do to trigger more debug about why the cast was getting thrown out

mighty galleon
#

Yeah. You'll probably have to try doing some more testing, and if it doesn't work - try a different approach

#

Like a UI button that causes the building to cast the ability for you or something like that

trail apex
#

worst case I'll just make everything items. I'm not super great at front end stuff, so I'm trying to utilize what's there as much as possible so having ability slots + item slots gives me more space to work with, but I also don't really need a huge amount of these units for my MVP

mighty galleon
#

Right. Maybe DankBud or one of the other active devs have a solution for you

upbeat ermine
#

@trail apex did you do SetCursorTarget before OnSpellStart ?

#

for items you don't have to do it because 'shared item mechanic' exists in dota, for abilities you need to do some workarounds.

upbeat ermine
#

There is also a way to make 'fake shared abilities'. Give everyone the same ability, when one is used, you put others on cooldown as well.

#

I think Enfos custom game did that.

upbeat ermine
mighty galleon
upbeat ermine
#

xD

ebon aspen
#

by what means are you sharing the unit

trail apex
trail apex
trail apex
# ebon aspen by what means are you sharing the unit

just creating the unit for the team, this will look ugly as shit, but it's for an MVP and I need to redo half the code base anyway, but:

Spawners.MercCamps[DOTA_TEAM_GOODGUYS][Constants.KEY_RADIANT_TOP] = CreateUnitByName( "mercenary_camp", Vector(-7232, -5888, 256), true, nil, nil, DOTA_TEAM_GOODGUYS )
#

🤦 I think I might have found it in my OrderFilters and had already solved this problem and forgot about it

#

yep, I'm an idiot, here was how I was accomplishing it:

(again, excuse the ugly ass proof of concept hardcoding)

function CGameMode:OrderFilter(keys)
  local ability = EntIndexToHScript(keys.entindex_ability)
  if ability ~= nil then
    if (    ability:GetName() == "item_merc_demo" 
    or     ability:GetName() == "item_merc_skeletons" 
    or     ability:GetName() == "item_merc_pyromancer" 
    or     ability:GetName() == "ability_train_champ_creep" 
        ) then
      local unit = ability:GetOwner() -- should be the merc camp
      unit.PlayerCaster = keys.issuer_player_id_const
      unit.target_x = keys.position_x
      unit.target_y = keys.position_y
      ability:OnSpellStart()
      return true
  end
end
#

just forgot to add the new ones in