• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Computer AI vjass

Status
Not open for further replies.
Level 11
Joined
Sep 12, 2008
Messages
657
hey.. i finised my gui code of the computer ai, which went terribly wrong...
so i tried remaking it in vjass.. somehow i managed to remember some old stuff :p
anyways, it managed to create heroes, store data, etc.. but it wont work correctly ;/
it uses 2 libraries, 1 i made, and the second is grouputils.
the problem:
it wont go thru the loop i supose.. cant really find it out =]
it creates hero, and wont do anything else, move, attack, etc.

heres the code:

JASS:
library ComputerAI initializer init requires GroupUtils, GetClosestUnit
    
    globals
        //Declared Data
        private timer tim = null
        private integer array index
        private integer array heroList
        
        private integer count
        //Used inloop data
        private unit array botHero
        private player array botOwner
        private string array botState
        private unit array botTarget
        private group array botGroup
        private real array botHealSpotX
        private real array botHealSpotY
        //
    endglobals
    
    //List of indexes:
    //Index[0] = Hero List Count
    //Index[1] = Bots In Total
    //Index[2] = counting units in group
    //
    
    public function AddHeroToList takes integer unitid returns integer
        set index[0] = index[0] + 1
        set heroList[index[0]] = unitid
        return index[0]
    endfunction
    
    public function RemoveHeroFromList takes integer index returns nothing
        set heroList[index] = 0
    endfunction
    
    public function LocateUnitsBoolexpr takes nothing returns boolean
        return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), botOwner[count]) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == false
    endfunction
    
    public function CreateNewBot takes player p, location startLoc, location healLoc returns integer
        local boolean pickedHero = false
        local integer num = 0
        
        set index[1] = index[1] + 1
        
        loop
            set num = GetRandomInt(1, index[0])
            if heroList[num] != 0 then
                set pickedHero = true
            endif
        exitwhen pickedHero == true
        endloop
        
        set botHero[index[1]] = CreateUnit(p, heroList[num], GetLocationX(startLoc), GetLocationY(startLoc), 0)
        set botOwner[index[1]] = p
        set botHealSpotX[index[1]] = GetLocationX(healLoc)
        set botHealSpotY[index[1]] = GetLocationY(healLoc)
        
        set botGroup[index[1]] = NewGroup()
        
        return index[1]
    endfunction
    
    private function HandleActions takes nothing returns nothing
        if botState[count] == "moving to heal" then
            call IssuePointOrder(botHero[count], "move", botHealSpotX[count], botHealSpotY[count])
            if GetUnitStatePercent(botHero[count], UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE) < 98 then
                set botState[count] = "healing"
            endif
        else
            if botState[count] == "attacking enemy" then
                call IssueTargetOrder(botHero[count], "attack", botTarget[count])
            endif
        endif
    endfunction
    
    private function PrepareActions takes nothing returns nothing
        if GetUnitStatePercent(botHero[count], UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE) <= 30 or botState[count] == "healing" then
            set botState[count] = "moving to heal"
            set botTarget[count] = null
            if GetUnitStatePercent(botHero[count], UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE) >= 98 then
                set botState[count] = "no actions"
            endif
        else
            if GetUnitState(botHero[count], UNIT_STATE_LIFE) <= 0 or index[2] <= 0 then
                if index[2] <= 0 then
                    call GroupEnumUnitsInRect(botGroup[count], bj_mapInitialPlayableArea, function LocateUnitsBoolexpr)
                    call GroupRefresh(botGroup[count])
                    
                    set index[2] = CountUnitsInGroup(botGroup[count])
                endif
                
                if GetUnitState(botHero[count], UNIT_STATE_LIFE) <= 0 then
                    set index[2] = index[2] - 1
                    set botTarget[count] = FindClosestUnit(botGroup[count], GetUnitX(botHero[count]), GetUnitY(botHero[count]))
                    set botState[count] = "attacking enemy"
                endif
            endif
        endif
    endfunction
    
    private function ComputerAIActions takes nothing returns nothing
        set count = 0
        if index[1] != 0 then
            loop
            set count = count + 1
                if GetUnitState(botHero[count], UNIT_STATE_LIFE) > 0 then
                    call PrepareActions()
                    call HandleActions()
                endif
            exitwhen count == index[1]
            endloop
        endif
    endfunction
    
    private function init takes nothing returns nothing
        set tim = CreateTimer()
        call TimerStart(tim, 1, true, function ComputerAIActions)
        
    endfunction
endlibrary
 
Level 11
Joined
Sep 12, 2008
Messages
657
hmm.. i tried remaking with Struct after school, i realised you wrote this too late(lightning went offline, so inet had strange difficulties..)
well.. if struct thingy will fail, ill put lots of debug messages, and see where it fails..

btw, last code managed to work,
but i realised it works once, only after around the 2 minutes of waiting.. after creeps show up..
and only 3/4 heroes work.
 
GetUnitState(botHero[count], UNIT_STATE_LIFE) > 0

>

GetWidgetLife(botHero[count]) > 0.405

JASS:
globals
    private timer tim = null
endglobals
private function init takes nothing returns nothing
    set tim = CreateTimer()
    call TimerStart(tim, 1, true, function ComputerAIActions)
endfunction

>

JASS:
private function init takes nothing returns nothing
    call TimerStart(CreateTimer(), 1, true, function ComputerAIActions)
endfunction

GetUnitState(botHero[count], UNIT_STATE_LIFE) <= 0

>

IsUnitType(botHero[count], UNIT_TYPE_DEAD)

public function CreateNewBot takes player p, location startLoc, location healLoc returns integer

>

public function CreateNewBot takes player p, real startX, real startY, real healX, real healY returns integer
 
Level 11
Joined
Sep 12, 2008
Messages
657
yeah i actually had a reason to use locations in here

public function CreateNewBot takes player p, location startLoc, location healLoc returns integer

since this was meant for gui initializing.. too lazy to use it otherwise =]
thx for pointing those stuff out tho :D

btw.. is there a way to make a loop, which goes thru a index from index[0] to index[1],
and arrange the code from biggest to lowest?
for example, i got a list of integers:

1, 5, 7, 2, 3, 9, 4
i want it to give me this at the end:
9, 7, 5, 4, 3, 2, 1

is it possible? i've tried finding it that way.. (trying to arrange the levels in a array,
from lowest to highest, and from highest to lowest.)

thanks =]
 
Level 5
Joined
Dec 4, 2006
Messages
110
You can arrange from high to low. You simply have a loop with two variables.

JASS:
local integer i = begin
local integer j = end
loop
    set array1[i] = array2[j]
    set i = i + 1
    set j = j - 1
    exitwhen ( i == end or j == begin )
endloop

Where array1 is the high-low array and array2 is the low-high array.
 
Status
Not open for further replies.
Top