Python based RTS tasker system

Left Click unit = select unit

Left Click Terrain = Set target in selected units

Ctrl + Left Click on Selected unit = Remove from selected list

Ctrl + Left Click on unit not currently selected = Add unit to selected list


import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    
    # define sensors
    Mouse = cont.sensors['Left_Click']
    MOA = cont.sensors['MouseOverAny']
    CTRL = cont.sensors['Ctrl']
    
    
    #grab data on frame 0 and initalize properties
    if 'NavMesh' not in own:
        own['NavMesh']=own.scene.objects['Navmesh']
        own['ActorList']=[]
        own['Timer']=0
        own['Selected']=[]
        
        for objects in own.scene.objects:
            if 'Team' in objects:
                if objects['Team']==own['Team']:
                    own['ActorList'].append(objects)
                
        
    
    # Debug readout
    own['Read']=str(own['Selected'])
    
    
    #Timer manager
    if own['Timer']>=1:
        own['Timer']-=1
        
    #Select and Deselect logic        
    if MOA.positive and Mouse.positive and own['Timer']==0:
        if 'Team' in MOA.hitObject:
            own['Timer']=30
            if MOA.hitObject['Team']==own['Team']:
                if MOA.hitObject not in own['Selected']:
                    #Add unit to list
                    if CTRL.positive:
                        own['Selected'].append(MOA.hitObject)
                        
                    #select only unit clicked    
                    else:
                        own['Selected']=[MOA.hitObject]
                                            
                else:
                    own['Timer']=30
                    index=0
                    if CTRL.positive:
                        index=0
                        #unselect actor
                        for actor in own['Selected']:
                            if actor==MOA.hitObject:
                                own['Selected'].pop(index)
                            index+=1    
                    else:
                        own['Selected']=[MOA.hitObject]            
                                
                    
     
    # set targets in selected units
    if MOA.positive and Mouse.positive:
        for unit in own['Selected']:
            if 'Terrain' in MOA.hitObject:
                unit['Target']=MOA.hitPosition
                if 'Path' in unit:
                    del unit['Path']
                
            
    
    for Actor in own['ActorList']:
        #add or remove selected graphics
        if Actor in own['Selected']:
            if 'Picked' not in Actor:
                Actor['Picked']=own.scene.addObject('Selected',Actor,0)
                Actor['Picked'].setParent(Actor,0,1)
        else:
            if 'Picked' in Actor:
                Actor['Picked'].endObject()
                del Actor['Picked']
                
                
        #navigate        
        
        if 'Target' in Actor:
            if 'Path' not in Actor:
                if Actor.getDistanceTo(Actor['Target'])>1.25:
                    P = own['NavMesh'].findPath(Actor.worldPosition,Actor['Target'])
                    
                    Actor['Path']=P
                else:
                    Actor.localLinearVelocity.x*=.95
                    Actor.localLinearVelocity.y*=.95        
                
            else:
                
                # Draw path 
                P =Actor['Path']
                index =0
                for point in Actor['Path']:
                    if index==0:
                        p1 = Actor.worldPosition
                    else:
                        p1 = P[index-1]
                    p2 = P[index]
                    
                    bge.render.drawLine(p2,p1,(1,0,0))
                    index+=1        
                    
               
                if len(P)>=1:
                    #we have a path that is not empty
                    if Actor.getDistanceTo(P[0])<1.25:
                        P.pop(0)
                        print('pop')
                    else:
                        PZ = P[0].copy()
                        PZ.z =Actor.worldPosition.z
                        v2 = Actor.getVectTo(PZ)
                        Actor.alignAxisToVect((0,0,1),2,1)
                        Actor.alignAxisToVect(v2[1],0,.2)
                        # Point head up
                        if Actor.localLinearVelocity.x<3:
                            Actor.applyForce((30,0,0),1)
                        Actor.localLinearVelocity.y*=.25
                else:
                    #path complete
                    if 'Path' in Actor:
                        del Actor['Path']             
                    


main()



Attachments

PythonicRTS_Guts.blend (530 KB)