Skip to content
Snippets Groups Projects
HTNBehaviors.py 8.35 KiB
import mtry.cxxi.model.HierarchicalTaskNetwork.HTNUtilities as HTNUtilities
from java.util import ArrayList
import cxxi.model.objects.holders.CMHolder as CMHolder
import cxxi.model.behavior.OrderUtilities as OrderUtilities

import mtry.cxxi.model.HierarchicalTaskNetwork.GoalContainer as GoalContainer
import cxxi.model.behavior.PythonUtilities as PythonUtilities

#from UtilityFuncsExp import HTNBorg as borg

__HTN_PATH__ = "HTN/Trees/"
__BASIC_MOVE_PATH__ = "HTN/Trees/BasicMove.xml"
__NETWORK_MOVE_PATH__ = "HTN/Trees/NetworkMove.xml"

borg = None

# Reads from a list of allWPs
def GetRandomPoint():
    _InitBorgInternal()

    int_num = PythonUtilities._py_getRandomNumber("UNIFORM", [0.0, 1.0])
    int_num *= borg.allWPs.size()
    int_num = int(round(int_num))

    destName = borg.allWPs.get(int_num).getName()

    return destName

def _InitBorgInternal():
    global borg

    if borg == None:
        borgName = GoalContainer.getBorgName()
        impStr = "from "+borgName+" import HTNBorg"
        exec(impStr)
        borg = HTNBorg()
        print "Borg created"
    else:
        print "Borg already created"

def TestBorg():
    _InitBorgInternal()
    print "Test borg=",borg.allWPs.size()

def ConvertToJavaList(l):
    al = ArrayList()
    for o in l:
        al.add(o)

    return al

def ConvertJavaToList(l):
    al = []
    for i in range(l.size()):
        al.append(l.get(i))

    return al

# sends the behavior message to the specified entity
def SendUnitEventDelay(entityName, msg, data, delay):
	params = ArrayList()
	for d in data:
		params.add(d)
	HTNUtilities._py_scheduleEventForUnit(entityName, msg, delay, params)

# create a basic move tree and assign it
def CreateBasicMove(locList, speed, formation, useOr, orient, entityToMove, toNotify, msgTo, goalStack, delay):
    al = ArrayList()

    for loc in locList:
        al.add(loc)

    if formation == None:
        formation = "NO_FORMATION"

    goalStackName = goalStack
    if goalStack == None:
        goalStackName = "default"

    addSpecificGoal(
        entityToMove,
        delay,
        __BASIC_MOVE_PATH__,
        goalStackName,
        [al, speed, toNotify, msgTo, formation, orient, useOr],
        None)

# create a network move tree and assign it
def CreateNetworkMove(currentLoc, wpNames, speed, formation, entityToMove, toNotify, msgTo, goalStack, delay):
    al = ArrayList()
    if currentLoc != None:
        al.add(currentLoc)

    for wpName in wpNames:
        wp = CMHolder.retrieveControlMeasureByName(wpName)
        al.add(wp.getLocation())

    if formation == None:
        formation = "NO_FORMATION"

    goalStackName = goalStack
    if goalStack == None:
        goalStackName = "default"

    addSpecificGoal(
        entityToMove,
        delay,
        __NETWORK_MOVE_PATH__,
        goalStackName,
        [al, speed, toNotify, msgTo, formation],
        None)

# sends the behavior message to the specified entity
def SendEntityEventDelay(entityName, msg, data, delay):
	params = ArrayList()
	for d in data:
		params.add(d)
	HTNUtilities._py_scheduleEvent(entityName, msg, delay, params)

# sends the behavior message to the specified entity
def SendEntityEvent(entityName, msg, data):
	params = ArrayList()
	for d in data:
		params.add(d)
	HTNUtilities._py_scheduleEvent(entityName, msg, 5.0, params)

# sends the behavior message to the specified entity
def SendBehaviorMsg(entityName, msg, data):
	params = ArrayList()
	for d in data:
		params.add(d)
	HTNUtilities._py_scheduleEvent(entityName, "GoalTracker_HTNBehaviorMsg", 5.0, params)

# creates a 2d array of specified dimensions
# width = columns, height = rows
def CreateArray(width, height):
	gridMap=[]
	for i in range(width):
		gridMap.append([])
		for j in range(height):
			gridMap[i].append(i+j)
	return gridMap

# gets the neighbors of an element in a 2d array
# assumes neighbors are in cardinal directions
def GetArrayNeighbors(net, x, y, xlim, ylim):
	neighbors = []
#	directions = [-1, 0, 0, -1, 0, 1, 1, 0]
	directions = [-1, 0, 0, -1, 0, 1, 1, 0, -1, -1, -1, 1, 1, -1, 1, 1]
	for i in range(len(directions)/2):
		nx = x + directions[i*2]
		ny = y + directions[i*2+1]
		if nx >= 0 and nx < xlim and ny >= 0 and ny < ylim:
			neighbors.append(net[nx][ny])

	return neighbors

# convert a python list to a java list
def ConvertToJavaList(larr):
	l = ArrayList()
	for la in larr:
		l.add(la)
	return l

# convert python list of GraphPoint to name
def GraphPointDesc(l):
	desc=[]
	for ll in l:
		desc.append(ll.getWayPoint().getName())
	return desc

###################################################################################################
# generates the full argument list for addGoal methods without the side-effect of modifying the
# passed in args
#
def _buildGoalArgs(goalPath, goalStack, var, args):
    result = [goalPath, goalStack, var]

    for arg in args:
        result.append(arg)

    return result

###################################################################################################
# adds a goal to the specified entity. This is done by publishing the GoalTracker_AddGoal
# event so a behavior needs to be setup to handle this. (There's usually a default behavior setup to
# handle this)
#
# entityName: String, name of the entity to add to
# delay: double, time in seconds from now to send the event
# goalPath: String, path to the xml file that contains the HTN plan
# stackName: String, name of the stack to add the goal to
# args: List, list of arguments to send with the event
# var: HashMap<String, Object>, variable hash map to send with the event
def addSpecificGoal(entityName, delay, goalPath, stackName, args, var):
    arguments = _buildGoalArgs(goalPath, stackName, var, args)

    OrderUtilities.getEntityByName(entityName).getDM().waitDelay("GoalTracker_AddGoal", delay, arguments)

###################################################################################################
# adds a goal to the specified entity. This is done by publishing the GoalTracker_AddGoal
# event so a behavior needs to be setup to handle this. (There's usually a default behavior setup to
# handle this)
#
# entityName: String, name of the entity to add to
# delay: double, time in seconds from now to send the event
# goalPath: String, path to the xml file that contains the HTN plan
# args: List, list of arguments to send with the event
# var: HashMap<String, Object>, variable hash map to send with the event
def addGoal(entityName, delay, goalPath, args, var):
    arguments = _buildGoalArgs(goalPath, None, var, args)

    OrderUtilities.getEntityByName(entityName).getDM().waitDelay("GoalTracker_AddGoal", delay, arguments)

###################################################################################################
# adds a goal to everyone in the specified unit. This is done by publishing the GoalTracker_AddGoal
# event so a behavior needs to be setup to handle this. (There's usually a default behavior setup to
# handle this)
#
# unitName: String, name of the unit to add to
# delay: double, time in seconds from now to send the event
# goalPath: String, path to the xml file that contains the HTN plan
# stackName: String, name of the stack to add the goal to
# args: List, list of arguments to send with the event
# var: HashMap<String, Object>, variable hash map to send with the event
def addSpecificGoalToUnit(unitName, delay, goalPath, stackName, args, var):
    unit = UtilityFuncs.getUnitByName(unitName)
    arguments = _buildGoalArgs(goalPath, stackName, var, args)

    for member in unit.getMembers():
        member.getDM().waitDelay("GoalTracker_AddGoal", delay, arguments)

###################################################################################################
# adds a goal to everyone in the specified unit. This is done by publishing the GoalTracker_AddGoal
# event so a behavior needs to be setup to handle this. (There's usually a default behavior setup to
# handle this)
#
# unitName: String, name of the unit to add to
# delay: double, time in seconds from now to send the event
# goalPath: String, path to the xml file that contains the HTN plan
# args: List, list of arguments to send with the event
# var: HashMap<String, Object>, variable hash map to send with the event
def addGoalToUnit(unitName, delay, goalPath, args, var):
    unit = UtilityFuncs.getUnitByName(unitName)
    arguments = _buildGoalArgs(goalPath, None, var, args)

    for member in unit.getMembers():
        member.getDM().waitDelay("GoalTracker_AddGoal", delay, arguments)