• 🏆 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!

[General] AI assigned to custom race - naga

Status
Not open for further replies.
Level 3
Joined
Jan 26, 2015
Messages
38
hello all!

i have a custom race - the Naga - as a playable race.
to select it, one must select Night Elf, and set Handicap to 90%

i have finished tunning and balanceing it for melee play

however, for obvious reasons, there is no AI governing how the computer should play the naga

on this site L I N K, Av3n shows us how to insert a custom Ai into a map via trigger


here is how he inserted an AI for an existing race, the Undead:

EVENTS:
Time - Elapsed game time is 0.00 seconds


CONDTIONS:
(Race of Player 2 (Blue)) Equal to Undead

ACTIONS:
AI - Start melee AI script for Player 2 (Blue): war3mapImported\WyrmMonger.ai


my problem is that my race isnt in the lists in Condition - only human, night elf, orc, undead and demon

so how do i go about inserting a little piece of Ai script i wrote in JassCraft, into my custom race?

i allready imported via Import Manager


thanks
 
Level 5
Joined
Jun 23, 2010
Messages
46
You can make it works deleting the condition and make a trigger:

EVENTS:
Time - Elapsed game time is 0.00 seconds


CONDTIONS:
(none)

ACTIONS:
Unit - Create 1 Town Hall Naga for Player 2 (Blue) at (Player 2 (Blue) start location) facing Vista edificio predeterminada degrees
Unit - Create 5 Peon Naga for Player 2 (Blue) at (Player 2 (Blue) start location) facing Vista edificio predeterminada degrees

AI - Start melee AI script for Player 2 (Blue): Naga.ai

And later a trigger for the default races:

EVENTS:
Time - Elapsed game time is 1.00 seconds


CONDTIONS:
(none)
ACTIONS:
Melee - Run melee AI scripts (for computer players)


Remember delete "war3mapImported\" of the imported file in import manager

Sorry for my english
 
Level 3
Joined
Jan 26, 2015
Messages
38
but how do i make it so that if i choose for player 2 (the computer player) a regular race with 100% normal handicap, it plays as normal, and if i choose night elf ( 90% handicap so it turns into naga) it uses different AIs?

basicly - i need a condition, so that the game differentiates between the regular, standard Night Elf race, and the Night Elf race with 90% handicap - which results in the naga


i allready have the transformation from Night Elf to Naga implemented, via a custom script


this is the script with which i implemented the Naga race:
Code:
library NagaSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Naga",RACE_NIGHTELF,0.9)
        call c.setTownHall('nntt')                  // Temple of Tides
        call c.addWorkerType('nmpe',c.NEAR_MINE,5)  // Murgul Slave
        call c.addHeroType('Hvsh')                  // Lady Vasj
        call c.setAIScript("Naga.ai")
    endfunction
    
endlibrary
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
You have a trigger that replaces the regular starting units of the night elf to the naga race.
Place "Start AI trigger" there?

EDIT:
Or you do this:
  • Initial
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Set TempPlayer = (Picked player)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TempPlayer controller) Equal to Computer
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Race of TempPlayer) Equal to Human
                • Then - Actions
                  • AI - Start melee AI script for TempPlayer: map.ai
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Race of TempPlayer) Equal to Orc
                • Then - Actions
                  • AI - Start melee AI script for TempPlayer: map.ai
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Race of TempPlayer) Equal to Undead
                • Then - Actions
                  • AI - Start melee AI script for TempPlayer: map.ai
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Race of TempPlayer) Equal to Night Elf
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (TempPlayer handicap) Equal to 90.00
                    • Then - Actions
                      • AI - Start melee AI script for TempPlayer: map.ai
                    • Else - Actions
                      • AI - Start melee AI script for TempPlayer: map.ai
                • Else - Actions
            • Else - Actions
 
Level 3
Joined
Jan 26, 2015
Messages
38
no

here is how my race is implemented:

first, a total removal of the initial triggers

then, a category, called CUSTOM RACE SYSTEM - this describes every race, the standard ones and my naga:

a trigger for the Human race, called Human Setup:
Code:
library HumanSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Human",RACE_HUMAN,1.0)
        call c.setTownHall('htow')                  // Town Hall
        call c.addWorkerType('hpea',c.NEAR_MINE,5)  // Peasant
        call c.addHeroType('Hpal')                  // Paladin
        call c.addHeroType('Hamg')                  // Archmage
        call c.addHeroType('Hmkg')                  // Mountain King
        call c.addHeroType('Hblm')                  // Blood Mage
        call c.setAIScript("human.ai")
    endfunction
endlibrary


a trigger for the Orc race, called Orc Setup:
Code:
library OrcSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Orc",RACE_ORC,1.0)
        call c.setTownHall('ogre')                  // Great Hall
        call c.addWorkerType('opeo',c.NEAR_MINE,5)  // Peon
        call c.addHeroType('Obla')                  // Blademaster
        call c.addHeroType('Ofar')                  // Far Seer
        call c.addHeroType('Otch')                  // Tauren Chieftain
        call c.addHeroType('Oshd')                  // Shadow Hunter
        call c.setAIScript("orc.ai")
    endfunction
endlibrary


then for the standard Undead and Night Elf.

and after these, for the Custom naga Race:
Code:
library NagaSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Naga",RACE_NIGHTELF,0.9)
        call c.setTownHall('nntt')                  // Temple of Tides
        call c.addWorkerType('nmpe',c.NEAR_MINE,5)  // Murgul Slave
        call c.addHeroType('Hvsh')                  // Lady Vasj
        call c.setAIScript("Naga.ai")
    endfunction
    
endlibrary


also, a trigger called Custom Race System ---> this one, defines how to replace the standard races with the custom units: its needed, else the one about the Naga (the one above) wont work without it!

this is abit longer, mind you!
Code:
//==============================================================================
//  Custom Race System by Archmage Owenalacaster
//==============================================================================
//
//  Purpose:
//      - Creates the starting units for custom races and replaces the standard
//        Melee Initialization trigger. Custom races are selected by race and
//        handicap.
//
//  Usage:
//      - Register a new custom race with CustomRace.create(name, RACE, handicap)
//          Handicaps: Valid handicap values are 1.0, 0.9, 0.8, 0.7, 0.6 and 0.5.
//      - Register a new custom race for all handicaps of a single race with
//        CustomRace.createAll(name, RACE)
//      - Extend the registration of a race with c.register(RACE, handicap)
//      - Set the townhall type with c.setTownHall(unitid)
//      - Add a new worker type with c.addWorkerType(unitid, priority, qty)
//          Priorities: c.NEAR_MINE spawns workers near the mine, where workers
//                        typically spawn.
//                      c.NEAR_HALL spawns workers near the town hall, where
//                        Ghouls spawn.
//      - Add a random hero type with c.addHeroType(unitid)
//      - Set the ai script used by computer players with c.setAIScript(stringpath)
//      - Set a callback function with c.setCallback(CustomRaceCall.function)
//          Callbacks: The callback is executed after all the starting units for a
//                     player are created, and its purpose is to provide enhanced
//                     initial behaviour for a race. A good example of this with the
//                     standard races would be the Undead Goldmine Haunting and
//                     Night Elves Goldmine Entangling.
//                     The callback function passes as arguments all the units
//                     generated in addition to the nearest goldmine detected.
//                     Please note that if a random hero is not created, the last
//                     argument will have a null value, so always do a check.
//       - Get a player's custom race name string with GetPlayerCustomRaceName(player)
//
//  Notes:
//      - Supports a maximum of 24 custom races.
//      - Maximum for worker and hero types are configurable.
//
//  Requirements:
//      - JassHelper version 0.9.E.0 or newer (older versions may still work).
//
//  Installation:
//      - Create a new trigger called CustomRaceSystem.
//      - Convert it to custom text and replace all the code with this code.
//
//  Special Thanks:
//      - Alevice:  He practically co-wrote the code.
//      - cosmicat: His formula for circular unit formation.
//                  Co-developing the single-array registry.
//
//==============================================================================

library CustomRaceSystem initializer Init
    
//===========================================================================
//                                CONFIGURATION SECTION
//===========================================================================
    globals
        // Unit Type Constants
        private constant integer MAX_WORKERTYPES = 4
        private constant integer MAX_HEROTYPES = 4
    endglobals
//===========================================================================
//                                END CONFIGURATION SECTION
//===========================================================================

    function interface CustomRaceCall takes player play, group workers, unit goldmine, unit townhall, unit randhero returns nothing
    
    private function r2S takes race r returns string
        if r == RACE_HUMAN then
            return "Human"
        elseif r == RACE_ORC then
            return "Orc"
        elseif r == RACE_UNDEAD then
            return "Undead"
        elseif r == RACE_NIGHTELF then
            return "Night Elf"
        endif
        return "Unknown"
    endfunction
    
    private function r2I takes race r returns integer
        if r == RACE_HUMAN then
            return 1
        elseif r == RACE_ORC then
            return 2
        elseif r == RACE_UNDEAD then
            return 3
        elseif r == RACE_NIGHTELF then
            return 4
        endif
        return 5
    endfunction
    
    globals
        // Victory Defeat Variables
        private string array KEY_STRUCTURE
        private integer KEY_STRUCTURE_COUNT = 0
    endglobals
    
//===========================================================================
//                                STRUCT DATA
//===========================================================================
    private keyword createStartingUnits
    
    struct CustomRace
        string name
        
        // Town Hall Variable
        integer townhallType = 0
      //string  townhallName
        // Town Hall name is not currently supported.
        
        // Worker Variables
        integer totalWorkerTypes = 0
        integer array workerType[MAX_WORKERTYPES]
        integer array workerPriority[MAX_WORKERTYPES]
        integer array workerQty[MAX_WORKERTYPES]
        
        // Random Hero Variables
        integer totalHeroTypes = 0
        integer array heroType[MAX_HEROTYPES]
        
        // AI Script Directory String Variable
        string aiscript = ""
        
        // Callback Variable
        private CustomRaceCall c
        
        // Registry Variable
        static integer array REGISTRY
        
        // Spawn Priority Variables
        static integer NEAR_MINE     = 0
        static integer NEAR_HALL     = 1
        
        static method get takes race r, real h returns CustomRace
            return CustomRace(.REGISTRY[((r2I(r)-1)*6)+(10-R2I(h*10.))])
        endmethod
        
        method register takes race r, real h returns boolean
            local CustomRace c = CustomRace.get(r,h)
            if c != 0 then
                debug call BJDebugMsg("|cffff0000Registration of "+.name+" failed due to conflict with "+c.name+" registered for "+r2S(r)+" race Handicap "+R2S(h))
                return false
            endif
            set .REGISTRY[((r2I(r)-1)*6)+(10-R2I(h*10.))] = integer(this)
            return true
        endmethod
        
        static method create takes string name, race r, real h returns CustomRace
            local CustomRace c = CustomRace.allocate()
            set c.name = name
            if not c.register(r,h) then
                call c.destroy()
                return 0
            endif
            return c
        endmethod
        
        static method createAll takes string name, race r returns CustomRace
            local CustomRace c = CustomRace.allocate()
            set c.name = name
            if not c.register(r,1.0) and not c.register(r,0.9) and not c.register(r,0.8) and not c.register(r,0.7) and not c.register(r,0.6) and not c.register(r,0.5) then
                call c.destroy()
                return 0
            endif
            return c
        endmethod
        
        method setTownHall takes integer hallid returns nothing
            set .townhallType = hallid
            set KEY_STRUCTURE[KEY_STRUCTURE_COUNT] = UnitId2String(hallid)
            set KEY_STRUCTURE_COUNT = KEY_STRUCTURE_COUNT+1
        endmethod
        
        method addWorkerType takes integer workerid, integer priority, integer quantity returns nothing
            set .workerType[.totalWorkerTypes] = workerid
            set .workerPriority[.totalWorkerTypes] = priority
            set .workerQty[.totalWorkerTypes] = quantity
            set .totalWorkerTypes = .totalWorkerTypes+1
        endmethod
        
        method addHeroType takes integer heroid returns nothing
            local integer i = 0
            set .heroType[.totalHeroTypes] = heroid
            set .totalHeroTypes = .totalHeroTypes+1
            loop
                call SetPlayerTechMaxAllowed(Player(i),heroid,1)
                set i = i+1
                exitwhen i == bj_MAX_PLAYERS
            endloop
        endmethod
        
        private method getRandomHeroType takes nothing returns integer
            local integer randomindex = GetRandomInt(0,.totalHeroTypes-1)
            return .heroType[randomindex]
        endmethod
        
        method setAIScript takes string s returns nothing
            set .aiscript = s
        endmethod
        
        method setCallback takes CustomRaceCall callb returns nothing
            set .c = callb
        endmethod
        
        private method createRandomHero takes player p, location loc returns unit
            local unit h = CreateUnitAtLoc(p, .getRandomHeroType(), loc, bj_UNIT_FACING)
            if bj_meleeGrantHeroItems then
                call MeleeGrantItemsToHero(h)
            endif
            return h
        endmethod
        
        method createStartingUnits takes player p returns nothing
            local location   startLoc        = GetPlayerStartLocationLoc(p)
            local location   nearMineLoc     = startLoc
            local location   nearTownLoc     = startLoc
            local location   spawnLoc        = startLoc
            local location   heroLoc         = startLoc
            local unit       nearestMine     = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
            local unit       myTownhall      = null
            local unit       myRandHero      = null
            local group      workerGroup     = CreateGroup()
            local integer    workertypeindex = 0
            local integer    workerqty       = 0
            local integer    spawnPriority   = 0
            if nearestMine != null then
                set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine),startLoc,320,0)
                set nearTownLoc = MeleeGetProjectedLoc(startLoc,GetUnitLoc(nearestMine),288,0)
                set heroLoc     = MeleeGetProjectedLoc(GetUnitLoc(nearestMine),startLoc,384,45)
            endif
            set myTownhall = CreateUnitAtLoc(p,.townhallType,startLoc,bj_UNIT_FACING)
            loop
                exitwhen workertypeindex == .totalWorkerTypes
                    set spawnPriority = .workerPriority[workertypeindex]
                    if (spawnPriority==.NEAR_HALL) then
                        set spawnLoc = nearTownLoc
                    elseif(spawnPriority==.NEAR_MINE) then
                        set spawnLoc = nearMineLoc
                    endif
                    loop
                        call GroupAddUnit(workerGroup, CreateUnitAtLoc(p,.workerType[workertypeindex],PolarProjectionBJ(spawnLoc,65,(I2R(workerqty)*(360.00 / I2R(.workerQty[workertypeindex]))) + 90),bj_UNIT_FACING))
                        set workerqty = workerqty + 1
                        exitwhen workerqty >= .workerQty[workertypeindex]
                    endloop
                    call RemoveLocation(spawnLoc)
                    set workerqty = 0
                set workertypeindex = workertypeindex+1
            endloop
            if (IsMapFlagSet(MAP_RANDOM_HERO) and .totalHeroTypes>0 ) then
                set myRandHero = .createRandomHero(p,heroLoc)
            else
                call SetPlayerState(p,PLAYER_STATE_RESOURCE_HERO_TOKENS,bj_MELEE_STARTING_HERO_TOKENS)
            endif
            if(.c!=0) then
                call .c.evaluate(p,workerGroup,nearestMine,myTownhall,myRandHero)
            else
                call DestroyGroup(workerGroup)
            endif
            if nearMineLoc != startLoc then
                call RemoveLocation(nearMineLoc)
                call RemoveLocation(nearTownLoc)
                call RemoveLocation(heroLoc)
            endif
            call RemoveLocation(startLoc)
            set startLoc    = null
            set nearMineLoc = null
            set nearTownLoc = null
            set spawnLoc    = null
            set heroLoc     = null
            set nearestMine = null
            set myTownhall  = null
            set myRandHero  = null
            set workerGroup = null
        endmethod
     endstruct
     
     globals
        private string array PLAYER_RACE
     endglobals
     
     function GetPlayerCustomRaceName takes player p returns string
        return PLAYER_RACE[GetPlayerId(p)]
     endfunction
    
//===========================================================================
//                         UNIT CREATION SECTION
//===========================================================================
    private function CreateStartingUnitsForAllPlayers takes nothing returns nothing
        local integer    index = 0
        local player     indexPlayer
        local race       playerRace
        local CustomRace c
        loop
            set indexPlayer = Player(index)
            if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
                set playerRace = GetPlayerRace(indexPlayer)
                set c = CustomRace.get(playerRace,GetPlayerHandicap(indexPlayer)+0.01)
                if (GetPlayerController(indexPlayer) == MAP_CONTROL_USER or (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER and c.aiscript != "" )) and c != 0 then
                    set PLAYER_RACE[index] = c.name
                    call c.createStartingUnits(indexPlayer)
                elseif playerRace == RACE_HUMAN then
                    call MeleeStartingUnitsHuman(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
                elseif playerRace == RACE_ORC then
                    call MeleeStartingUnitsOrc(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
                elseif playerRace == RACE_NIGHTELF then
                    call MeleeStartingUnitsNightElf(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
                elseif playerRace == RACE_UNDEAD then
                    call MeleeStartingUnitsUndead(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
                else
                    call MeleeStartingUnitsUnknownRace(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
                endif
            endif
            set index = index + 1
            exitwhen index == bj_MAX_PLAYERS
        endloop
    endfunction
    
//===========================================================================
//                         CUSTOM MELEE AI SECTION
//===========================================================================
    private function CustomMeleeStartingAI takes nothing returns nothing
        local integer index = 0
        local player  indexPlayer
        local race    indexRace
        local CustomRace c
        loop
            set indexPlayer = Player(index)
            if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
                set indexRace = GetPlayerRace(indexPlayer)
                set c = CustomRace.get(indexRace,GetPlayerHandicap(indexPlayer)+0.01)
                call SetPlayerHandicap(indexPlayer,1.0)
                if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
                    // Run a race-specific melee AI script.
                    if c != 0 and c.aiscript != "" then
                        call StartMeleeAI(indexPlayer, c.aiscript)
                    elseif (indexRace == RACE_HUMAN) then
                        call PickMeleeAI(indexPlayer, "human.ai", null, null)
                    elseif (indexRace == RACE_ORC) then
                        call PickMeleeAI(indexPlayer, "orc.ai", null, null)
                    elseif (indexRace == RACE_UNDEAD) then
                        call PickMeleeAI(indexPlayer, "undead.ai", null, null)
                        call RecycleGuardPosition(bj_ghoul[index])
                    elseif (indexRace == RACE_NIGHTELF) then
                        call PickMeleeAI(indexPlayer, "elf.ai", null, null)
                    else
                        // Unrecognized race.
                    endif
                    call ShareEverythingWithTeamAI(indexPlayer)
                endif
            endif

            set index = index + 1
            exitwhen index == bj_MAX_PLAYERS
        endloop
    endfunction    

//===========================================================================
//                         VICTORY DEFEAT SECTION
//===========================================================================
    private function CustomGetAllyKeyStructureCount takes player whichPlayer returns integer
        local integer    i           = 0
        local integer    keyStructs  = 0
        local integer    playerIndex = 0
        local player     indexPlayer
        loop
            set indexPlayer = Player(playerIndex)
            if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
                set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "townhall", true, true)
                set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "greathall", true, true)
                set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
                set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "treeoflife", true, true)
                loop
                    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, KEY_STRUCTURE[i], true, true)
                    set i = i+1
                    exitwhen i == KEY_STRUCTURE_COUNT
                endloop
            endif
            set playerIndex = playerIndex + 1
            exitwhen playerIndex == bj_MAX_PLAYERS
        endloop
        return keyStructs
    endfunction

    private function CustomPlayerIsCrippled takes player whichPlayer returns boolean
        local integer allyStructures    = MeleeGetAllyStructureCount(whichPlayer)
        local integer allyKeyStructures = CustomGetAllyKeyStructureCount(whichPlayer)
        return (allyStructures > 0) and (allyKeyStructures <= 0)
    endfunction

    private function CustomCheckForCrippledPlayers takes nothing returns nothing
        local integer    playerIndex
        local player     indexPlayer
        local boolean    isNowCrippled
        call MeleeCheckForLosersAndVictors()
        if bj_finishSoonAllExposed then
            return
        endif
        set playerIndex = 0
        loop
            set indexPlayer = Player(playerIndex)
            set isNowCrippled = CustomPlayerIsCrippled(indexPlayer)
            if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then
                set bj_playerIsCrippled[playerIndex] = true
                call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)
                if (GetLocalPlayer() == indexPlayer) then
                    call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)
                    call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_WARNING_HUMAN"))
                endif
            elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then
                set bj_playerIsCrippled[playerIndex] = false
                call PauseTimer(bj_crippledTimer[playerIndex])
                if (GetLocalPlayer() == indexPlayer) then
                    call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
                    if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
                        if (bj_playerIsExposed[playerIndex]) then
                            call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
                        else
                            call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
                        endif
                    endif
                endif
                call MeleeExposePlayer(indexPlayer, false)
            endif
            set playerIndex = playerIndex + 1
            exitwhen playerIndex == bj_MAX_PLAYERS
        endloop
    endfunction

    private function CustomInitVictoryDefeat takes nothing returns nothing
        local trigger    checker = CreateTrigger()
        local trigger    trig
        local integer    index
        local player     indexPlayer
        set bj_finishSoonTimerDialog = CreateTimerDialog(null)
        call TriggerAddAction(checker, function CustomCheckForCrippledPlayers)
        set trig = CreateTrigger()
        call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
        call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)
        set trig = CreateTrigger()
        call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
        call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)
        set index = 0
        loop
            set indexPlayer = Player(index)
            if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
                set bj_meleeDefeated[index] = false
                set bj_meleeVictoried[index] = false
                set bj_playerIsCrippled[index] = false
                set bj_playerIsExposed[index] = false
                set bj_crippledTimer[index] = CreateTimer()
                set bj_crippledTimerWindows[index] = CreateTimerDialog(bj_crippledTimer[index])
                call TimerDialogSetTitle(bj_crippledTimerWindows[index], MeleeGetCrippledTimerMessage(indexPlayer))
                call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, null)
                call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_DEATH, null)
                call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
                call TriggerRegisterPlayerAllianceChange(checker, indexPlayer, ALLIANCE_PASSIVE)
                call TriggerRegisterPlayerStateEvent(checker, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
                set trig = CreateTrigger()
                call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
                call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)
                set trig = CreateTrigger()
                call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
                call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
             else
                set bj_meleeDefeated[index] = true
                set bj_meleeVictoried[index] = false
                if (IsPlayerObserver(indexPlayer)) then
                    set trig = CreateTrigger()
                    call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
                    call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
                endif
            endif
            set index = index + 1
            exitwhen index == bj_MAX_PLAYERS
        endloop
        call TimerStart(CreateTimer(), 2.0, false, function CustomCheckForCrippledPlayers)
    endfunction
    
    private function TimerAction takes nothing returns nothing
        call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
        call MeleeStartingHeroLimit()
        call MeleeGrantHeroItems()
        call MeleeStartingResources()
        call MeleeClearExcessUnits()
        call CreateStartingUnitsForAllPlayers()
        call CustomMeleeStartingAI()
        call CustomInitVictoryDefeat()
        call DestroyTimer(GetExpiredTimer())
    endfunction
    
    private function Init takes nothing returns nothing
        call TimerStart(CreateTimer(),0,false,function TimerAction)
    endfunction
    
endlibrary


aside from these categories, a simple trigger to limit the custom heroes (naga sea witch, naga myrmidon and naga royal guard ) to 1.


thats how my custom race was implemented.

it works beautifully, as long as a human plays it!

but the Computer Ai for it, does nothing, except mine gold!
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Wow...
I actually never thought that someone who just joined the hive would come up with proper vJASS... I just have vJASS properly installed since yesterday :D

Code:
library NagaSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Naga",RACE_NIGHTELF,0.9)
        call c.setTownHall('nntt')                  // Temple of Tides
        call c.addWorkerType('nmpe',c.NEAR_MINE,5)  // Murgul Slave
        call c.addHeroType('Hvsh')                  // Lady Vasj
        call c.setAIScript("Naga.ai")
    endfunction
    
endlibrary

So I would say that it is not the trigger but rather the Naga.ai that is wrong.
Try placing the "call c.setAIScript("Naga.ai")" with the regular Night Elf race and watch if those run their ai properly or completely wrong.
 
Level 3
Joined
Jan 26, 2015
Messages
38
if you read the huge trigger -the biggest one - you ll see iti s NOT me that made this :)

but that guy Archmage . He gets the credit

i will investigate this tommorow.


but is there a way to load a custom AI into that custom naga race?
 
Level 3
Joined
Jan 26, 2015
Messages
38
tested it !!!

indeed, the naga.ai is borked! it doesnt work !
if i use it in the elf ai, the elves just mine wood...if i use it on the nagas, they just mine gold


so HOW do i load a custom AI into the custom race?
a condition would be needed to take into consideration that we're dealing with the custom naga race
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
You already achieved to load the custom AI into the custom race.
The problem is that the custom AI was broken.
You don't need any changes in the triggers.

I don't know much about AI but I think that your object ids have changed...
Try to re-export and re-import the AI again and if that does not work then remake the AI...
 
Level 3
Joined
Jan 26, 2015
Messages
38
You already achieved to load the custom AI into the custom race.
The problem is that the custom AI was broken.
You don't need any changes in the triggers.

I don't know much about AI but I think that your object ids have changed...
Try to re-export and re-import the AI again and if that does not work then remake the AI...

so i just use the Module --> Import Manager to import a custom AI (lets call this one NewNaga) and then simply change the naga.ai in the script, with Newnaga.ai ?
 
Level 3
Joined
Jan 26, 2015
Messages
38
errr...doesnt work :(((

or i am too idiot ....which isnt that impossible :p

Wietlol ... id like to email you the map itself, so you can play it for a little bit

here is my email: [email protected]

what is yours? send me an email

i have a map, (2)Booty Bay, which now accepts the new race

maybe if you have a look at the finished product, you ll get some ideas
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
When posting a reply on a thread click "Go Advanced" just below the textbox.
Then you scroll down to the second block where a button is shown named "Manage Attachments".
Click on it.
A new window has opened.
Click on "Choose File" and select the file you want to upload.
Then at the right of the screen (you might want to increase the window width) click on the button "Upload".
After a while the files are uploaded, the names of the files will show up just below the "Choose Files" box.
Then close the window and post your reply.

I have 0 experience with AI so I cannot guarantee you that I will give the solution.
So uploading for more people will help a lot.

If you don't want to throw your stuff on the internet just like that, go ahead and send a private message with a pastebin or link to whatever-file-hosting-server you prefer.

(I will not throw around with my email address if you don't mind. Just a little quarrel between me and Google.)
 
Level 3
Joined
Jan 26, 2015
Messages
38
here is the map

its a winrar. inside it, a folder with the map booty bay and a folder containing the models for the custom heroes

the naga race uses 2 custom heroes - derived from allready existing units (naga myrmidon and naga royal guard)

naga Myrmidon and royal guard - hybrids, with magic and 1 melee skill
NOT op or cheats !

also, each standard race also has 1 extra hero - check it out!

no, they are NOT cheats or anything like it - just abit of mixing allready existing abilities!

Humans ---> Blood Knight, a paladin of the Blood Elves, with drain mana instead of devotion aura

Undead ---> Eredar Warlock, very interesting mix of abilities

Orc ---> Magnataur chieftain, powerfull melee hero based on Tauren Chieftain, but with Howl of Terror

Elves ---> Moonkin, derived from the Owlbear model, its based on Kepper of the grove, but with starfall instead of
tranquility


To play naga, select Night Elves ---> select handicap 90 %
 

Attachments

  • MyMap.rar
    2.5 MB · Views: 130
Level 24
Joined
Aug 1, 2013
Messages
4,657
1. Go to Import Manager.
2. Click on "Import File (Ctrl + I)".
3. Go to and select your .ai file.
4. Click on "Open".
5. Double click on the row with the .ai file in the Import Manager.
6. Check the checkbox "Use custom path".
7. Remove the "war3mapImported\" part in the string.
8. Save and test the map.

A .w3m/.w3x almost never uses data from files outside the .w3m/.w3x file.
An exception is custom Load/Save functions for example.
All data that you use in your map must be imported via the Import Manager.
All data that is imported via the Import Manager is saved within the .w3m/.w3x file.
So you only have to send the .w2m/.w3x file.

One other thing... you didn't upload the .ai file.
 
Level 3
Joined
Jan 26, 2015
Messages
38
i did as you said precisely, all the way to step 8....still, it mines only gold, but maybe i skipped on something!

now i have to ask ...after step 8, do i go to the script, this section
Code:
library NagaSetup initializer Init requires CustomRaceSystem
    
    private function Init takes nothing returns nothing
        local CustomRace c = CustomRace.create("Naga",RACE_NIGHTELF,0.9)
        call c.setTownHall('nntt')                  // Temple of Tides
        call c.addWorkerType('nmpe',c.NEAR_MINE,5)  // Murgul Slave
        call c.addHeroType('Hvsh')                  // Lady Vasj
        call c.setAIScript("[B][U]AIincepator.ai[/U][/B]")
    endfunction
    
endlibrary

and simply replace the bolded, underlined AI with the name of the imported one?

or, after step 8, i stop and thats it ?
or i must make a separate trigger to make it load the imported AI ? (this also seems to just make it mine gold)


because i imported it, like you said, did all steps...and still it just mines gold :(


many thanks
 
Level 3
Joined
Jan 26, 2015
Messages
38
aha, as i thought.....ok thanks


EDIT: yaaay! it works :p

now i just finish up the AI ! the ai just makes the very basic buildings...an Altar of heroes, 1 supply and the shop for items

many thanks

i will submit the finished maps for you to enjoy
 
Status
Not open for further replies.
Top