Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementing action processor #40

Merged
merged 6 commits into from
Jan 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotaservice/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.3.3'
__version__ = '0.3.4'
8 changes: 8 additions & 0 deletions dotaservice/dotaservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
logger = logging.getLogger(__name__)

LUA_FILES_GLOB = pkg_resources.resource_filename('dotaservice', 'lua/*.lua')
LUA_FILES_GLOB_ACTIONS = pkg_resources.resource_filename('dotaservice', 'lua/actions/*.lua')


def verify_game_path(game_path):
Expand Down Expand Up @@ -156,6 +157,13 @@ def _create_bot_path(self):
for filename in lua_files:
shutil.copy(filename, bot_path)

# Copy all the bot action files into the actions subdirectory
action_path = os.path.join(bot_path, "actions")
os.mkdir(action_path)
action_files = glob.glob(LUA_FILES_GLOB_ACTIONS)
for filename in action_files:
shutil.copy(filename, action_path)

# shutil.copy('/Users/tzaman/dev/dotaservice/botcpp/botcpp_radiant.so', bot_path)

# Finally, symlink DOTA to this folder.
Expand Down
100 changes: 100 additions & 0 deletions dotaservice/lua/action_processor.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local pprint = require( "bots/pprint" )

-- Atomic Actions
local actionGlyph = require( "bots/actions/atomic_glyph" )
local actionLevelAbility = require( "bots/actions/atomic_level_ability" )

-- Hero Functions
local actionNone = require( "bots/actions/none" )
local actionClearAction = require( "bots/actions/clear" )
local actionBuyback = require( "bots/actions/buyback" )
local actionChat = require( "bots/actions/chat" )

--local actionMoveToLocation = require( "bots/actions/move_to_location" )
local actionMoveDirectly = require( "bots/actions/move_directly" )
local actionAttackUnit = require( "bots/actions/attack_unit" )

local actionUseAbilityOnEntity = require( "bots/actions/use_ability_on_entity" )
local actionUseAbilityOnLocation= require( "bots/actions/use_ability_on_location" )
local actionUseAbilityOnTree = require( "bots/actions/use_ability_on_tree" )
local actionUseAbility = require( "bots/actions/use_ability" )
local actionToggleAbility = require( "bots/actions/toggle_ability" )

-- Global Variables
ABILITY_STANDARD = 0
ABILITY_PUSH = 1
ABILITY_QUEUE = 2

local ActionProcessor = {}

LookUpTable = {
['DOTA_UNIT_ORDER_NONE'] = actionNone,
['DOTA_UNIT_ORDER_MOVE_TO_POSITION'] = actionMoveDirectly,
['DOTA_UNIT_ORDER_ATTACK_TARGET'] = actionAttackUnit,
['DOTA_UNIT_ORDER_GLYPH'] = actionGlyph,
['DOTA_UNIT_ORDER_STOP'] = actionClearAction,
['DOTA_UNIT_ORDER_TRAIN_ABILITY'] = actionLevelAbility,
['DOTA_UNIT_ORDER_BUYBACK'] = actionBuyback,
['ACTION_CHAT'] = actionChat,
['DOTA_UNIT_ORDER_CAST_POSITION'] = actionUseAbilityOnLocation,
['DOTA_UNIT_ORDER_CAST_TARGET'] = actionUseAbilityOnEntity,
['DOTA_UNIT_ORDER_CAST_TARGET_TREE'] = actionUseAbilityOnTree,
['DOTA_UNIT_ORDER_CAST_NO_TARGET'] = actionUseAbility,
['DOTA_UNIT_ORDER_CAST_TOGGLE'] = actionToggleAbility,
}

local function table_length(tbl)
local lenNum = 0
for k,v in pairs(tbl) do
lenNum = lenNum + 1
end
return lenNum
end

function ActionProcessor:Run(hBot, tblActions)
if table_length(tblActions) == 0 then
print("Got EMPTY tblActions")
-- If we have no action, draw a big red circle around the hero.
DebugDrawCircle(hBot:GetLocation(), 200, 255, 0, 0)
do return end
end

-- print('Actions: ', pprint.pformat(tblActions))

for key, value in pairs(tblActions) do
local cmd = LookUpTable[key]
if cmd ~= nil then
-- print("Executing Action: ", cmd.Name)
-- NOTE: It is assumed that the first arguement (if args required)
-- will be the handle to the bot, followed by arguments
-- provided by the `agent`.
-- `Agent` args are double nested lists [[]], as some args
-- specify a location.
-- Example: [[-7000,-7000,128], [2]]
-- to do a move_to_location (X,Y,Z) in Queued fashion
if cmd.NumArgs == 2 then
cmd:Call(hBot, value[1])
elseif cmd.NumArgs == 3 then
cmd:Call(hBot, value[1], value[2])
elseif cmd.NumArgs == 0 then
cmd:Call()
elseif cmd.NumArgs == 1 then
cmd:Call(hBot)
elseif cmd.NumArgs == 4 then
cmd:Call(hBot, value[1], value[2], value[3])
else
print("Unimplemented number of Cmd Args for ", cmd.Name, ": ", cmd.NumArgs)
-- DebugPause()
do return end
end
else
print("<ERROR> [", key, "] does not exist in action table!")
end
end
end

return ActionProcessor
18 changes: 18 additions & 0 deletions dotaservice/lua/actions/atomic_glyph.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local ActionGlyph = {}

ActionGlyph.Name = "Glyph Action"
ActionGlyph.NumArgs = 1

-------------------------------------------------

function ActionGlyph:Call(hHero)
hHero:ActionImmediate_Glyph()
end

-------------------------------------------------

return ActionGlyph
31 changes: 31 additions & 0 deletions dotaservice/lua/actions/atomic_level_ability.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local LevelAbility = {}

LevelAbility.Name = "Level Ability"
LevelAbility.NumArgs = 2

-------------------------------------------------

function LevelAbility:Call( hHero, sAbilityName )
print("Leveling: ", sAbilityName[1])
-- Sanity Check
local nAbilityPoints = hHero:GetAbilityPoints()
if nAbilityPoints > 0 then
-- Another sanity check
local hAbility = hHero:GetAbilityByName(sAbilityName[1])
if hAbility and hAbility:CanAbilityBeUpgraded() then
-- actually do the leveling
hHero:ActionImmediate_LevelAbility(sAbilityName[1])
else
print("Trying to level an ability I cannot", sAbilityName[1])
do return end
end
end
end

-------------------------------------------------

return LevelAbility
41 changes: 41 additions & 0 deletions dotaservice/lua/actions/attack_unit.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local AttackUnit = {}

AttackUnit.Name = "Attack Unit"
AttackUnit.NumArgs = 4

-------------------------------------------------
function AttackUnit:Call( hUnit, hTarget, bOnce, iType )
hTarget = hTarget[1]
if hTarget == -1 then -- Invalid target. Do nothing.
do return end
end
hTarget = GetBotByHandle(hTarget)

iType = iType[1]

-- Note: we do not test if target can be attacked due
-- to modifiers (e.g., invulnerable), range, or any
-- debuffs on the hUnit (e.g., disarmed). We assume
-- only valid and legal actions are agent selected
if not hTarget:IsNull() and hTarget:IsAlive() then
vLoc = hTarget:GetLocation()
DebugDrawCircle(vLoc, 25, 255, 0, 0)
DebugDrawLine(hUnit:GetLocation(), vLoc, 255, 0, 0)

bOnce = bOnce[1]
if iType == nil or iType == ABILITY_STANDARD then
hUnit:Action_AttackUnit(hTarget, bOnce)
elseif iType == ABILITY_PUSH then
hUnit:ActionPush_AttackUnit(hTarget, bOnce)
elseif iType == ABILITY_QUEUE then
hUnit:ActionQueue_AttackUnit(hTarget, bOnce)
end
end
end
-------------------------------------------------

return AttackUnit
20 changes: 20 additions & 0 deletions dotaservice/lua/actions/buyback.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local ActionBuyback = {}

ActionBuyback.Name = "Buyback Action"
ActionBuyback.NumArgs = 1

-------------------------------------------------

function ActionBuyback:Call( hHero )
if not hHero:IsAlive() then
hHero:ActionImmediate_Buyback()
end
end

-------------------------------------------------

return ActionBuyback
18 changes: 18 additions & 0 deletions dotaservice/lua/actions/chat.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local Chat = {}

Chat.Name = "Chat"
Chat.NumArgs = 3

-------------------------------------------------

function Chat:Call( hHero, sMsg, bAllChat )
hHero:ActionImmediate_Chat(sMsg[1], bAllChat[1])
end

-------------------------------------------------

return Chat
23 changes: 23 additions & 0 deletions dotaservice/lua/actions/clear.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local ActionClear = {}

ActionClear.Name = "Clear Action"
ActionClear.NumArgs = 2

local function toboolean(number)
if number >= 1 then return true end
return false
end

-------------------------------------------------

function ActionClear:Call( hHero, bStop )
hHero:Action_ClearActions(toboolean(bStop[1]))
end

-------------------------------------------------

return ActionClear
42 changes: 42 additions & 0 deletions dotaservice/lua/actions/move_directly.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local MoveDirectly = {}

MoveDirectly.Name = "Move Directly to Location"
MoveDirectly.NumArgs = 3

-------------------------------------------------

function MoveDirectly:Call( hUnit, vLoc, iType )
-- Note: we test for valid conditions here on hUnit, but we shouldn't
-- as the agent should only suggest legal and valid actions
if not hUnit:IsAlive() or hUnit:IsRooted() or hUnit:IsStunned() then
print("[ERROR] - MoveDirectly under death/root/stun")
do return end
end

-- print("Moving to: <", vLoc[1],", " vLoc[2], "> from <", hUnit:GetLocation().x, ", ", hUnit:GetLocation().y, ">")

iType = iType[1]

vLoc = Vector(vLoc[1], vLoc[2], vLoc[3])
DebugDrawCircle(vLoc, 25, 255, 255 ,255)
DebugDrawLine(hUnit:GetLocation(), vLoc, 255, 255, 255)

if iType == nil or iType == ABILITY_STANDARD then
hUnit:Action_MoveDirectly(vLoc)
elseif iType == ABILITY_PUSH then
hUnit:ActionPush_MoveDirectly(vLoc)
elseif iType == ABILITY_QUEUE then
hUnit:ActionQueue_MoveDirectly(vLoc)
else
print("[ERROR] - Unknown iType: ", iType)
do return end
end
end

-------------------------------------------------

return MoveDirectly
19 changes: 19 additions & 0 deletions dotaservice/lua/actions/none.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local ActionNone = {}

ActionNone.Name = "No Action"
ActionNone.NumArgs = 0

-------------------------------------------------

function ActionNone:Call()
print("No Action")
DebugDrawCircle(GetBot():GetLocation(), 50, 127, 127, 127)
end

-------------------------------------------------

return ActionNone
21 changes: 21 additions & 0 deletions dotaservice/lua/actions/toggle_ability.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-------------------------------------------------------------------------------
--- AUTHOR: Nostrademous
-------------------------------------------------------------------------------

local ToggleAbility = {}

ToggleAbility.Name = "Toggle Ability"
ToggleAbility.NumArgs = 2

-------------------------------------------------
function ToggleAbility:Call( hUnit, intAbilitySlot )
local hAbility = hUnit:GetAbilityInSlot(intAbilitySlot[1])
if not hAbility then
print('[ERROR]: ', hUnit:GetUnitName(), " failed to find ability in slot ", intAbilitySlot[1])
do return end
end
hAbility:ToggleAutoCast()
end
-------------------------------------------------

return ToggleAbility
Loading