i just wonder if the AI Hero Support Source where ever released. I thought of an new version that does not add an map to the list that isn't needed and works for EVERY map even those who did not use it in their luas. Therefore I want to use an custom userscript, but i'm not sure if the source were released it would make my work much easier.
Re: AI Hero support
Posted: Thu Oct 22, 2015 2:28 am
by [RDH]Zerted
I don't know if this was the last version or not. The file is dated 2006-09-27 which is likely when I downloaded it.
AIHeroSupportScriptv1_2.zip
AIHeroSupport.lua
Hidden/Spoiler:
[code]-----------------------------------------------------------------
-----------------------------------------------------------------
-- AIHeroSupport Script by T. Simpson
-- Version 1.2
-- Screen Names: Archer01, Theodranis
-- E-mail: [email protected]
-- Sept 24, 2006
-- Copyright (c) 2006 T. Simpson.
-- About this script: This was my attempt to correct something
-- that I thought was fundementaly "broken" with StarWars BattleFront 2,
-- and that would be the AI never using the heroes.
-- Please note: Several times along the way I found out I couldn't do
-- something I needed to, or a function didn't return anything when it "should"
-- have (all the other functions similar to it do) so I had to find a work-around
-- solution, the result is a somewhat messy script.
-- Usage:
-- During ScriptPostLoad():
-- Create Object (and override variables)
-- Set Hero Classes using the special function (be sure to remove the original SetHeroClass() commands from your script)
-- Set spawn CPs
-- Call Start()
-- NOTE: For ADVANCED scripters only:
-- This script assumes that the ATT team is always 1 and DEF is always 2
-- This can be changed however by overriding the teamATT and teamDEF variables when :New() is called
-- But because the game's scripts also assume ATT == 1 and DEF == 2 it is suggested that this feature be left alone
-- Legal Stuff:
-- You are welcome to use this script in your custom made mods and maps so long as they are not being rented or sold.
-- If you use this script, please credit me in the readme of the project you used it in.
-- Do not claim this script as your own. It may not be much, but I did spend some time writing it after all.
-- Do not edit this script.
-- If you need to override any of the variables, please do so from your own script. Do not edit this one.
-- I am not responsible for any damages that might be incurred through the use of this script.
-- THIS SCRIPT IS NOT MADE, DISTRIBUTED, OR SUPPORTED BY LUCASARTS, A DIVISION OF LUCASFILM ENTERTAINMENT COMPANY LTD.
-----------------------------------------------------------------
-----------------------------------------------------------------
AIHeroSupport = nil --Force garbage collection (just in case)
--- Error message for user debug ---
function AIHeroSupport:PrintError(msg)
print(" ")
print("_______!!!AIHeroSupport ->", msg)
end
--- ADD SPAWN FUNCTION ---
function AIHeroSupport:AddSpawnCP(cpName,pathName)
local tempCPPtr = GetObjectPtr(cpName)
local tempPathPtr = GetPathPoint(pathName, 0)
--print("!!!!!!!!!!!Hero: CPVal returned >", tempCPPtr," PathPointReturned >",tempPathPtr)
if not tempCPPtr then
self:PrintError("Warning!: Invalid CP > " .. cpName)
elseif not tempPathPtr then
self:PrintError("Warning!: Invalid path > " .. pathName)
else
self.cpList[cpName] = pathName
self.cpAdded = true
end
end
-- Allows enabling and disabling of AI hero spawn --
function AIHeroSupport:EnableHeroes(inVal)
self.spawnHero = inVal
end
function AIHeroSupport:EnableHeroTeam(teamPtr,inVal)
if teamPtr then
self.shouldHeroSpawnTeam[teamPtr] = inVal
end
end
--- Sets the bot count ---
function AIHeroSupport:SetBotCount(amount)
local sizeATT = GetUnitCount(self.teamATT)
local sizeDEF = GetUnitCount(self.teamDEF)
if sizeATT < amount then
self:PrintError("Warning!: Bot count larger than ATT unit count")
end
if sizeDEF < amount then
self:PrintError("Warning!: Bot count larger than DEF unit count")
end
if amount then
if amount >= 1 then
ScriptCB_SetNumBots(amount - 1)
self.botCount = amount
elseif amount == 0 then
ScriptCB_SetNumBots(0)
self.botCount = 0
else
self:PrintError("Error!: Invalid bot count setting")
end
end
end
---- MAIN START FUNCTION ----
function AIHeroSupport:Start()
--Doesn't run a second time
if self.hasStarted then return end
if ScriptCB_InNetGame() then
if self.disableInNetGame then return end
self.cycleTime = self.netCycleTime
end
--Init special vars here
self.shouldHeroSpawnTeam[self.teamATT] = true
self.shouldHeroSpawnTeam[self.teamDEF] = true
------ Local functions (just following the convention of the game developers ------
local getValidSpawnPath = function(teamPtr)
local pathList = {}
local cpCount = 0
--local pathPtr = nil
for cp,path in pairs(self.cpList) do
--print("!!!!!!!!!!!Hero: Spawn test CP", cp," Path", path)
if IsObjectAlive(cp) then
--print("!!!!!!!!!!!Hero: Spawn test CP", cp," Path", path, " CPTEAM", GetObjectTeam(cp))
if GetObjectTeam(cp) == teamPtr then
--print("!!!!!!!!!!!Hero: Path gotten >>", path)
cpCount = cpCount + 1
pathList[cpCount] = path
end
end
end
--print("!!!!!!!!!!!Hero: Number of valid paths >", cpCount,"TEAM >", teamPtr)
if cpCount == 1 then
--Just get the first entry, skips randomizer
local path = pathList[1]
--print("!!!!!!!!!!!Hero: Single path gotten >>", path, "TEAM >", teamPtr)
return path
elseif cpCount >= 2 then
local cpIndex = math.random(1,cpCount)
local path = pathList[cpIndex]
--print("!!!!!!!!!!!Hero: Random path gotten >>", path, "TEAM >", teamPtr)
return path
end
--print("!!!!!!!!!!!Hero: No valid path found TEAM >", teamPtr)
return false
end
local removeAllBotHeroes = function(teamPtr)
local heroIndex = self.heroClassIndexList[teamPtr]
if heroIndex then
local teamSize = GetTeamSize(teamPtr)
for i = 0, (teamSize-1) do
local characterIndex = GetTeamMember(teamPtr, i)
if characterIndex then
local charClass = GetCharacterClass(characterIndex)
if charClass then
if charClass == heroIndex then
if not IsCharacterHuman(characterIndex) then
local characterUnit = GetCharacterUnit(characterIndex)
if characterUnit then
KillObject(characterUnit)
end
end
end
end
end
end
end
end
local spawnChar = function(teamPtr, characterIndex, charClass)
if not characterIndex then return false end
local spawnPathName = getValidSpawnPath(teamPtr)
if not spawnPathName then return false end --Error check
local spawnNode = GetPathPoint(spawnPathName, 0)
--if not spawnNode then return end
--if spawnPathName then
if spawnNode then
--print("!!!!!!!!!!!Hero: TEST 2")
local charUnit = GetCharacterUnit(characterIndex)
--print("!!!!!!!!!!!Hero: Activate unit >>", characterIndex)
if not charUnit then
if charClass then
SelectCharacterClass(characterIndex, charClass)
end
SpawnCharacter(characterIndex, spawnNode)
local charUnit = GetCharacterUnit(characterIndex)
if charUnit then
if teamPtr == self.teamATT then
if self.AIATTHeroHealth then
SetProperty(charUnit,"MaxHealth", self.AIATTHeroHealth)
SetProperty(charUnit,"CurHealth", self.AIATTHeroHealth)
--print("!!!!!!!!!!!Hero: Attack hero health set")
end
elseif teamPtr == self.teamDEF then
if self.AIDEFHeroHealth then
SetProperty(charUnit,"MaxHealth", self.AIDEFHeroHealth)
SetProperty(charUnit,"CurHealth", self.AIDEFHeroHealth)
--print("!!!!!!!!!!!Hero: Defend hero health set")
end
end
if self.botImmuneHeroes and self.botDamageThreshold then
SetAIDamageThreshold(charUnit, self.botDamageThreshold)
end
--print("!!!!!!!!!!!Hero: Special spawned ", characterIndex, " at node", spawnNode, "Class", GetCharacterClass(characterIndex), " VERIFY >", charUnit)
return true
end
end
end
return false
end
local getUnspawnedBot = function(teamPtr)
local teamSize = GetTeamSize(teamPtr)
if self.botCount then
if self.botCount <= 0 then
return false
end
end
for i = 0, (teamSize-1) do
local characterIndex = GetTeamMember(teamPtr, i)
--print("!!!!!!!!!!!Hero: Checking index >>", characterIndex)
if characterIndex then
if not IsCharacterHuman(characterIndex) then
local characterUnit = GetCharacterUnit(characterIndex)
if not characterUnit then
return characterIndex
end
end
end
end
return false
end
local activateHeroSameTeam = function(teamPtr)
if not self.spawnHero then return end
local characterIndex = self.heroEntityList[teamPtr]
local heroIndex = self.heroClassIndexList[teamPtr]
--if not heroIndex then return end
if characterIndex then
if GetCharacterClass(characterIndex) == heroIndex then
local characterUnit = GetCharacterUnit(characterIndex)
if characterUnit then
--print("!!!!!!!!!!!Hero: Hero actiavtion skipped >>", characterIndex)
return
end
end
end
--Spawn code here
local newHeroIndex = getUnspawnedBot(teamPtr)
if newHeroIndex then
local spawned = spawnChar(teamPtr,newHeroIndex,heroIndex)
if spawned then
self.heroEntityList[teamPtr] = newHeroIndex
self.recentAIHero[newHeroIndex] = true
--print("!!!!!!!!!!!Hero: Hero actiavtion complete >>", newHeroIndex)
end
end
end
local deactivateHeroSameTeam = function(teamPtr)
local characterIndex = self.heroEntityList[teamPtr]
local heroIndex = self.heroClassIndexList[teamPtr]
--if not heroIndex then return end
if not characterIndex then return end --Skip if no hero is active
if GetCharacterClass(characterIndex) == heroIndex then
local characterUnit = GetCharacterUnit(characterIndex)
self.heroEntityList[teamPtr] = nil
if characterUnit then
--This check on isConquest is not really needed, but there for safety
if self.isConquest then
--This check is to handle the 'infinite' reinforcement count
--Avoids overflow and automatic defeat
if GetReinforcementCount(teamPtr) < self.infiniteReforceBound then
AddReinforcements(teamPtr, 1)
--print("!!!!!!!!!!!Hero: REFORCE POINT ADDED!")
end
end
KillObject(characterUnit)
--print("!!!!!!!!!!!Hero: Hero killed due to deactivation >>", characterIndex)
end
end
end
local humanHeroActive = function(teamPtr)
local teamSize = GetTeamSize(teamPtr)
for i = 0, (teamSize-1) do
local characterIndex = GetTeamMember(teamPtr, i)
if IsCharacterHuman(characterIndex) then
local charClass = GetCharacterClass(characterIndex)
if charClass then
if self.heroClassIndexList[teamPtr] == charClass then
--print("!!!!!!!!!!!Hero: Human Hero Unit", characterIndex," found as class", charClass, " Team >", teamPtr)
return true
end
end
end
end
--print("!!!!!!!!!!!Hero: No Human Hero Unit Team >", teamPtr)
return false
end
local verifySingleHero = function(teamPtr)
if humanHeroActive(teamPtr) then
removeAllBotHeroes(teamPtr)
else
local heroEntity = self.heroEntityList[teamPtr]
if heroEntity then
local heroIndex = self.heroClassIndexList[teamPtr]
local teamSize = GetTeamSize(teamPtr)
for i = 0, (teamSize-1) do
local characterIndex = GetTeamMember(teamPtr, i)
if characterIndex then
if not IsCharacterHuman(characterIndex) then
if characterIndex ~= heroEntity then
local charClass = GetCharacterClass(characterIndex)
if charClass then
if charClass == heroIndex then
local characterUnit = GetCharacterUnit(characterIndex)
if characterUnit then
KillObject(characterUnit)
--print("!!!!!!!!!!!Hero: Extra hero found and removed Team >", teamPtr)
end
end
end
end
end
end
end
else
removeAllBotHeroes(teamPtr)
end
end
end
local cycleTimerTest = function(teamPtr)
local heroIndex = self.heroClassIndexList[teamPtr]
if heroIndex then
--print("!!!!!!!!!!!Hero: Timer test1")
if humanHeroActive(teamPtr) then
deactivateHeroSameTeam(teamPtr)
--print("!!!!!!!!!!!Hero: Hero cycle-deactivated")
else
if self.shouldHeroSpawnTeam[teamPtr] then
local characterIndex = self.heroEntityList[teamPtr]
if characterIndex then
if GetCharacterClass(characterIndex) == heroIndex then
local charUnit = GetCharacterUnit(characterIndex)
if not charUnit then
StartTimer(self.HeroSpawnTimer[teamPtr])
--print("!!!!!!!!!!!Hero: Spawn Timer Cycle-Started")
end
else
StartTimer(self.HeroSpawnTimer[teamPtr])
--print("!!!!!!!!!!!Hero: Spawn Timer Cycle-Started")
end
else
StartTimer(self.HeroSpawnTimer[teamPtr])
--print("!!!!!!!!!!!Hero: Spawn Timer Cycle-Started")
end
end
end
if self.enforceSingleHero then
verifySingleHero(teamPtr)
--print("!!!!!!!!!!!Hero: Enforce called >>", teamPtr)
end
end
end
local initHeroCycleTimer = function()
self.AIHeroCycleTimer = CreateTimer("AIHeroCycleTimer")
SetTimerValue(self.AIHeroCycleTimer, self.cycleTime)
if not humanHeroActive(teamPtr) then
if self.shouldHeroSpawnTeam[teamPtr] then
--print("!!!!!!!!!!!Hero: Hero activated >>", teamPtr)
activateHeroSameTeam(teamPtr)
end
end
end,
self.HeroSpawnTimer[teamPtr]
)
OnCharacterDeathTeam(
function(character,killer)
local charClass = GetCharacterClass(character)
--if charClass then
if charClass == self.heroClassIndexList[teamPtr] then
StopTimer(self.HeroSpawnTimer[teamPtr])
--print("!!!!!!!!!!!Hero: Hero died >>", character,"Team >>",teamPtr)
if IsCharacterHuman(character) then
SetTimerValue(self.HeroSpawnTimer[teamPtr], self.minAfterHuman)
--print("!!!!!!!!!!!Hero: Hero timer set for humanTime >>", teamPtr)
else
SetTimerValue(self.HeroSpawnTimer[teamPtr], self.minSpawnTime)
--print("!!!!!!!!!!!Hero: Hero timer set for minSpawn >>", teamPtr)
end
StartTimer(self.HeroSpawnTimer[teamPtr])
end
--end
end,
teamPtr
)
end
local initBotCountProtect = function(teamPtr)
OnCharacterSpawnTeam(
function(character)
if self.recentAIHero[character] then
local charClass = GetCharacterClass(character)
if charClass ~= self.heroClassIndexList[teamPtr] then
--This check on isConquest is not really needed, but there for safety
if self.isConquest then
--This check is to handle the 'infinite' reinforcement count
--Avoids overflow and automatic defeat
if GetReinforcementCount(teamPtr) < self.infiniteReforceBound then
AddReinforcements(teamPtr, 1)
--print("!!!!!!!!!!!Hero: REFORCE POINT ADDED!")
end
end
local charUnit = GetCharacterUnit(character)
KillObject(charUnit)
self.recentAIHero[character] = nil
--print("!!!!!!!!!!!Hero: Recent hero spawn killed >>", character)
end
end
end,
teamPtr
)
end
------ Actual function ------
--print("!!!!!!!!!!!Hero: STARTED!")
--Class check should take 0,1, or 2 heroes into account
OnCharacterChangeClass(
function(character)
--print("!!!!!!!!!!!Hero: CLASSCHANGE CALLBACK!")
--Ignore AI since they can't be heroes normally
if not IsCharacterHuman(character) then return end
--print("!!!!!!!!!!!Hero: Human class change!")
--Check class and do what is needed
local charTeam = GetCharacterTeam(character)
local charClass = GetCharacterClass(character)
if charTeam == self.teamATT then
if charClass == self.heroClassIndexList[self.teamATT] then
deactivateHeroSameTeam(self.teamATT)
--print("!!!!!!!!!!!Hero: Attack hero deactivated")
end
elseif charTeam == self.teamDEF then
if charClass == self.heroClassIndexList[self.teamDEF] then
deactivateHeroSameTeam(self.teamDEF)
--print("!!!!!!!!!!!Hero: Defense hero deactivated")
end
end
end
)
--Hero cycle timer (callback in function)
initHeroCycleTimer()
--Checks gameMode and stops hero spawn if AI count is zero
if self.gameMode then
local numBots = nil
local modeString = string.lower(self.gameMode)
if modeString == "conquest" then
self.isConquest = true
numBots = ScriptCB_GetCONNumBots()
elseif modeString == "ctf" then
numBots = ScriptCB_GetCTFNumBots()
elseif modeString == "assault" then
numBots = ScriptCB_GetASSNumBots()
elseif modeString == "hunt" then
numBots = ScriptCB_GetASSNumBots()
elseif modeString == "xl" then
self.gameMode = nil
numBots = nil
elseif modeString == "conqueststyle" then
self.isConquest = true
self.gameMode = nil
numBots = nil
elseif modeString == "uberconquest" then
self.isConquest = true
self.gameMode = nil
numBots = nil
elseif modeString == "nonconquest" then
self.gameMode = nil
numBots = nil
else
self.gameMode = nil
numBots = nil
self:PrintError("Warning!: Gamemode not recoginized")
end
self.botCount = numBots
--print("!!!!!!!!!!!Hero: Number of bots set >>", self.botCount)
if numBots then
self:SetBotCount(numBots)
end
end
-- Check for CPs
if not self.cpAdded then
self:PrintError("Warning!: No spawn CP added")
end
if self.minSpawnTime then
if self.minSpawnTime < 1 then
self.minSpawnTime = 15
self:PrintError("Warning!: minSpawnTime was set to an invalid value, resetting to 15 seconds")
end
---------- Hero Support Script for StarWars: BattleFront 2 ----------
Version 1.2
Script by T. Simpson
Screen names: Archer01 or Theodranis
Email: [email protected]
Date: Sept 26, 2006
This script adds AI hero support to a custom or modded map.
Sample scripts have been included to show how it works. The Conquest sample has a bunch of comments explaining everything. The CTF version does not include the comments, so it is a better example of how your script should "look".
Good luck!
Sample scripts:
Example_con.lua -- Commented sample
Example_ctf.lua -- Uncommented sample
Display_Fix.lua -- Display fix sample (see below for details)
Note: Do NOT edit the AIHeroSupport script. Override variables from your own script if needed. If you find a bug, please inform me so that I may fix it.
These are the steps you need to follow to add the script to your map...
*Setting up the script so your map lua can use it:
1- Go into the "\Common" folder for your map
2- Find the "mission.req" file and open it in a text/script editor
3- You should see a few lists of items each contained in quotaion marks
4- Find the list that begins with "script"
5- Add "AIHeroSupport" to the end of the script list
6- Save and close the file
7- Copy the "AIHeroSupport.lua" file into your map's "\Common\scripts" folder
8- The script can now be used in your map's lua
*Setting up your map's lua:
1- Open your map's lua file in text/script editor
2- You will see a bunch of "ScriptCB_DoFile(something here)" commands at the top
3- Add this just after them:
ScriptCB_DoFile("AIHeroSupport")
4- Now further down in the script find the line that says something like "conquest:Start()" or "ctf:Start()". Right after this line is where the hero support code should be added...
5- First add this line:
- Note: The stuff in the curly braces are the different settings the script uses. It is a list of variables seperated by commas. All the variables you can set here have default settings, so if you don't set a variable yourself the default setting is used. See below for a list of the variable names and what they do. Variable names ARE case sensitive.
6- After adding that line, you then set your hero classes using:
herosupport:SetHeroClass(team, "heroClassName")
-Note: If you have more than 7 unit types (including the hero type) on a side, the info boxes for them will not be sized properly during gameplay (the list will go off the end of the screen). There is an easy fix for this. Finish the tutorial, then read the section below relating to this problem.
7- After setting the hero classes, you then need to tell the script the names of the CPs and spawn paths it should use for the heroes. Do that by adding a line like the following for every CP that you want the heroes to be able to spawn at:
8- After all the CPs have been added, add this line:
herosupport:Start()
9- Now this is a VERY important part, the "SetHeroClass" function can only be used once for each team. If it is used a second time, nasty stuff will likely happen. Go through the script and remove all uses of the "SetHeroClass" function, except for the two you added earlier of course, so there won't be any problems. Your final script should have at most only two (2) mentions of "SetHeroClass". Don't forget about your text editor's search function when making sure this is so.
When more than 7 unit types are available for selection (ie more than the standard 6 normal and 1 hero), the display boxes in the spawn screen will not be sized correctly if the code block described above is left that way. There are a variety of ways to fix this, but the simplest (and most practical) is as follows:
1- Start with the first three (3) lines of the hero code block -> the "AIHeroSupport:New{}" and the two "herosupport:SetHeroClass()" lines.
2- Now simply CUT those three lines, and paste them at the very end of the "ScriptInit()" function. If you don't know where that spot is... It is just after the "AddCameraShot()" function calls, but just before the "end" statement at the bottom of the file (that "end" statement marks the end of the function). That will fix the display problem.
Note: Make sure you move ONLY those three lines. The "AddSpawnCP" and "Start" functions may not (and likely won't) work correctly if you move them too. Leave those lines where they are.
See the packaged sample script if you need an example.
Variable name: gameMode
- Possible values: (possible values below)
- Default = "NonConquest"
This should be set to the gameMode the map is using. It can be set to any of the following:
"Conquest" -- Uses the bot count from the Conquest map select settings
"ConquestStyle" -- Like Conquest, but ignores bot count settings
"UberConquest" -- Use this if it is a conquest map that uses UberMode
"CTF" -- Uses the bot count from the CTF map select settings
"Assault" -- Uses the bot count from the Assault map select settings
"Hunt" -- Uses the bot count from the Hunt map select settings
"xl" -- Uses this if it is an XL map that uses points
"NonConquest" -- Like any non-conquest, but ignores bot count settings
NOTE: For saftey sake, only use the conquest-related gamemodes if the map tracks/uses the reinforcement count. For maps that use team "points" use the other modes.
Variable name: AIATTHeroHealth
- Possible values: (a number)
- Default = the hero unit's normal health
The health the attacking team's bot hero should have (does not affect human hero's health). If this variable is not set, the hero's normal health is used.
Variable name: AIDEFHeroHealth
- Possible values: (a number)
- Default = the hero unit's normal health
Same, but for the defender's hero.
Variable name: minSpawnTime
- Possible values: (a number in seconds)
- Default = 25 seconds
The minmal delay between a bot Hero death and it's respawn. This is only the "minimum" amount of time. Usually the bot will spawn in just fine, but not every spawn attempt will end successfully. In the unsuccessful case (team full, unit memory not fully cleared, etc), it may take a little longer for the actual spawn to occur.
Variable name: initSpawnTime
- Possible values: (a number in seconds)
- Default = 10 seconds
This is like minSpawnTime but is only used once at the start of the match. This is how long from match-start before the first bot hero spawn attempt.
Variable name: minAfterHuman
- Possible values: (a number in seconds)
- Default = 25 seconds
This is like minSpawnTime but is used after a human controlled hero dies.
Variable name: botImmuneHeroes
- Possible values: (true or false)
- Default = false
Make it so the bot heroes can only be killed by a human player.
Variable name: botDamageThreshold
- Possible values: (a number between 0 and 1)
- Default = 0.3
If botImmuneHeroes is set to true, this is how much health the hero unit will have remaining before it stops taking damage from other bots. It is represented as a percentage (example: 0.3 == 30% health remaining).
Variable name: disableInNetGame
- Possible values: (true or false)
- Default = false
Disables the AI Hero Support aspect if it is a multiplayer match. When disabled this way, the AIHeroSupport script never starts.
Function name -> AIHeroSupport:New{}
Returns the hero support script object reference.
***Object Functions (functions that can be used anytime AFTER New{} is called):
Function name -> objectName:AddSpawnCP(cpName,pathName)
Adds the CP and associated spawn path data to the script's list.
Function name -> objectName:Start()
Starts the hero script. Only use this once.
Function name -> objectName:EnableHeroes(boolean)
Use true or false. Enables or disables the AI hero spawn for both teams.
Function name -> objectName:EnableHeroTeam(teamPtr,inVal)
Enables or disables the AI hero spawn for the specified team. Use true or false for inVal.
***Special case Object Functions (functions that can be used AFTER New{} is called):
Function name -> objectName:SetHeroClass(teamPtr,className)
Sets the hero class className for teamPtr and records necessary information needed to run the script.
NOTE: This has to be used BEFORE the "Start()" function call. It will not work correctly if used afterwards.
Known glitches:
- The AI heroes will still spawn even when heroes are disabled in the game options. The human players will not be able to play as the heroes, but the hero unit will still be on the map as a bot. I'm not sure if this can be fixed... (I'm also not sure if I want this "fixed")
Known bugs (things like crashing, stuff that can cause problems with gameplay, etc):
- None that I know of.
***Legal Stuff:
You are welcome to use this script in your custom made mods and maps so long as they are not being rented or sold. If you use this script, please credit me in the readme of the project you used it in. Do not claim this script as your own (it may not be much, but I did spend some time writing it after all). Do not edit this script. If you need to override any of the variables, please do so from your own script. I am not responsible for any damages that might be incurred through the use of this script.
THIS SCRIPT IS NOT MADE, DISTRIBUTED, OR SUPPORTED BY LUCASARTS, A DIVISION OF LUCASFILM ENTERTAINMENT COMPANY LTD.
*** VARIBALE LIST ***
***NOTE: It is very unlikely that you will need to change the following variables (so don't unless you know what you're doing)...
Variable name: cycleTime
- Possible values: (a number in seconds)
- Default = 10
How often the script looks for heroes on the map. When the cycleTime has passed, the script checks the units for hero status. If the script happened to not catch a human changing to a hero class (thus resulting in the AI hero never being removed), the AI hero will also be removed at this time. This check does a lot of "loop" work (may slow down a map if done too often). NOTE: This is just here as an extra option for flexability, I would suggest you leave this variable alone.
Variable name: netCycleTime
- Possible values: (a number in seconds)
- Default = 20
Same as the cycleTime but is used in multiplayer games. NOTE: Also just like cycleTime, this is just here as an extra option for flexability, I would suggest you leave this variable alone.
Variable name: enforceSingleHero
- Possible values: (true of false)
- Default = false
Considering the way I setup the script, this option is not really needed, but I decided to have it available "just in case". When enabled, this option makes the cycle test more comprehensive when looking for heroes on the map. Usually it will remove all bot controlled hero units except for one. If a hero is human controlled, it will remove all bot controlled heroes from the map. This check is executed as part of the "cycle test". The ONLY time this should be enabled is if you see more than one of the AI units using the hero at once, and on more than one occasion. This test does a lot of "loop" work so it might be a problem on slower computers.
*** FUNCTION LIST ***
Function name -> objectName:SetBotCount(number)
Overrides and sets the bot count to be used. This setting is applied to all teams (that's the way it works in the game).
!!! Note: The Start() function sets the bot count itself, so using this function before the script is started won't do anything. Also remember that the conquest, ctf, tdm, etc game scripts set the bot count themselves, so they too will override this function if it is used before them.
[code]--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--
-- Script modified by Archer01
-----------------
-- NOTE TO THE NOVICE SCRIPTER:
-- The double dash ("--") identifies a line as a 'comment', these lines are NOT script code
-- Comments just help people read this stuff more easily
--
-- To understand the use of the AIHeroSupport script, look for the comments that start with
-- "AIHEROSUPPORT NOTE:"
--
-- This example script shows how to configure your map's script if your sides have
-- more than 6 normal units (more than 7 if you include the hero)
-----------------
-- load the gametype script
ScriptCB_DoFile("setup_teams")
ScriptCB_DoFile("ObjectiveConquest")
---------------------------------
-- AIHEROSUPPORT NOTE:
-- The following line preps the hero script for use
--------
ScriptCB_DoFile("AIHeroSupport")
---------------------------------
-- Empire Attacking (attacker is always #1)
REP = 1
CIS = 2
-- These variables do not change
ATT = 1
DEF = 2
WookieTeam= 3
---------------------------------------------------------------------------
-- FUNCTION: ScriptInit
-- PURPOSE: This function is only run once
-- INPUT:
-- OUTPUT:
-- NOTES: The name, 'ScriptInit' is a chosen convention, and each
-- mission script must contain a version of this function, as
-- it is called from C to start the mission.
---------------------------------------------------------------------------
function ScriptPostLoad()
---------------------------------
-- AIHEROSUPPORT NOTE:
-- The following lines were added!
-----
-- The object creation and hero setting are done below in the init function
herosupport:AddSpawnCP("CP1CON","CP1CONPATH")
herosupport:AddSpawnCP("CP3CON","CP3CONPATH")
herosupport:AddSpawnCP("CP4CON","CP4CONPATH")
herosupport:AddSpawnCP("CP5CON","CP5CONPATH")
herosupport:Start()
-- This is the disclaimer message to tell people to read the readme
onfirstspawn = OnCharacterSpawn(
function(character)
if IsCharacterHuman(character) then
ReleaseCharacterSpawn(onfirstspawn)
onfirstspawn = nil
ShowObjectiveTextPopup("level.ZZZ.readme")
end
end
)
end
function PlayAnimDown()
PauseAnimation("thegateup");
RewindAnimation("thegatedown");
PlayAnimation("thegatedown");
ShowMessageText("level.kas2.objectives.gateopen",1)
ScriptCB_SndPlaySound("KAS_obj_13")
SetProperty("gatepanel", "MaxHealth", 2200)
-- Allowing AI to run under gate
UnblockPlanningGraphArcs("seawall1");
DisableBarriers("seawalldoor1");
DisableBarriers("vehicleblocker");
end
function PlayAnimUp()
PauseAnimation("thegatedown");
RewindAnimation("thegateup");
PlayAnimation("thegateup");
-- Allowing AI to run under gate
BlockPlanningGraphArcs("seawall1");
EnableBarriers("seawalldoor1");
EnableBarriers("vehicleblocker");
SetProperty("gatepanel", "MaxHealth", 1000)
SetProperty("gatepanel", "CurHealth", 1000)
end
function woodl()
UnblockPlanningGraphArcs("woodl");
DisableBarriers("woodl");
SetProperty("woodl", "MaxHealth", 1800)
-- SetProperty("woodl", "CurHealth", 15)
end
function woodc()
UnblockPlanningGraphArcs("woodc");
DisableBarriers("woodc");
SetProperty("woodc", "MaxHealth", 1800)
-- SetProperty("woodc", "CurHealth", 15)
end
function woodr()
UnblockPlanningGraphArcs("woodr");
DisableBarriers("woodr");
SetProperty("woodr", "MaxHealth", 1800)
-- SetProperty("woodr", "CurHealth", 15)
end
function woodlr()
BlockPlanningGraphArcs("woodl")
EnableBarriers("woodl")
SetProperty("woodl", "MaxHealth", 15000)
SetProperty("woodl", "CurHealth", 15000)
end
function woodcr()
BlockPlanningGraphArcs("woodc")
EnableBarriers("woodc")
SetProperty("woodc", "MaxHealth", 15000)
SetProperty("woodc", "CurHealth", 15000)
end
function woodrr()
BlockPlanningGraphArcs("woodr")
EnableBarriers("woodr")
SetProperty("woodr", "MaxHealth", 15000)
SetProperty("woodr", "CurHealth", 15000)
end
function ScriptInit()
-- Designers, these two lines *MUST* be first!
StealArtistHeap(800 * 1024)
SetPS2ModelMemory(3535000)
ReadDataFile("ingame.lvl")
---------------------------------
-- AIHEROSUPPORT NOTE:
-- Note how ONLY these three lines were moved here instead of being left above
-- This will correct the unit list display sizing problem in the game (for when a side has more than 7 unit types)
----------
[code]--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--
-- Script modified by Archer01
-----------------
-- NOTE TO THE NOVICE SCRIPTER:
-- The double dash ("--") identifies a line as a 'comment', these lines are NOT script code
-- Comments just help people read this stuff more easily
--
-- To understand the use of the AIHeroSupport script, look for the comments that start with
-- "AIHEROSUPPORT NOTE:"
--
-- Also review the CTF script to see what the HeroSupport code looks like without the comments
-----------------
-- load the gametype script
ScriptCB_DoFile("setup_teams")
ScriptCB_DoFile("ObjectiveConquest")
---------------------------------
-- AIHEROSUPPORT NOTE:
-- The following line preps the hero script for use
--------
ScriptCB_DoFile("AIHeroSupport")
---------------------------------
-- Empire Attacking (attacker is always #1)
REP = 1
CIS = 2
-- These variables do not change
ATT = 1
DEF = 2
WookieTeam= 3
---------------------------------------------------------------------------
-- FUNCTION: ScriptInit
-- PURPOSE: This function is only run once
-- INPUT:
-- OUTPUT:
-- NOTES: The name, 'ScriptInit' is a chosen convention, and each
-- mission script must contain a version of this function, as
-- it is called from C to start the mission.
---------------------------------------------------------------------------
function ScriptPostLoad()
-- Allowing AI to run under gate
UnblockPlanningGraphArcs("seawall1");
DisableBarriers("seawalldoor1");
DisableBarriers("vehicleblocker");
end
function PlayAnimUp()
PauseAnimation("thegatedown");
RewindAnimation("thegateup");
PlayAnimation("thegateup");
-- Allowing AI to run under gate
BlockPlanningGraphArcs("seawall1");
EnableBarriers("seawalldoor1");
EnableBarriers("vehicleblocker");
SetProperty("gatepanel", "MaxHealth", 1000)
SetProperty("gatepanel", "CurHealth", 1000)
end
function woodl()
UnblockPlanningGraphArcs("woodl");
DisableBarriers("woodl");
SetProperty("woodl", "MaxHealth", 1800)
-- SetProperty("woodl", "CurHealth", 15)
end
function woodc()
UnblockPlanningGraphArcs("woodc");
DisableBarriers("woodc");
SetProperty("woodc", "MaxHealth", 1800)
-- SetProperty("woodc", "CurHealth", 15)
end
function woodr()
UnblockPlanningGraphArcs("woodr");
DisableBarriers("woodr");
SetProperty("woodr", "MaxHealth", 1800)
-- SetProperty("woodr", "CurHealth", 15)
end
function woodlr()
BlockPlanningGraphArcs("woodl")
EnableBarriers("woodl")
SetProperty("woodl", "MaxHealth", 15000)
SetProperty("woodl", "CurHealth", 15000)
end
function woodcr()
BlockPlanningGraphArcs("woodc")
EnableBarriers("woodc")
SetProperty("woodc", "MaxHealth", 15000)
SetProperty("woodc", "CurHealth", 15000)
end
function woodrr()
BlockPlanningGraphArcs("woodr")
EnableBarriers("woodr")
SetProperty("woodr", "MaxHealth", 15000)
SetProperty("woodr", "CurHealth", 15000)
end
function ScriptInit()
-- Designers, these two lines *MUST* be first!
StealArtistHeap(800 * 1024)
SetPS2ModelMemory(3535000)
ReadDataFile("ingame.lvl")
---------------------------------
-- AIHEROSUPPORT NOTE:
-- The following lines were REMOVED
-- I just commented them out here, but you could/should delete them in your map's script
----------
[code]--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--
-- Modified by Archer01
-- load the gametype script
CTF = ScriptCB_DoFile("ObjectiveCTF")
ScriptCB_DoFile("setup_teams")
ScriptCB_DoFile("AIHeroSupport")
---------------------------------------------------------------------------
-- FUNCTION: ScriptInit
-- PURPOSE: This function is only run once
-- INPUT:
-- OUTPUT:
-- NOTES: The name, 'ScriptInit' is a chosen convention, and each
-- mission script must contain a version of this function, as
-- it is called from C to start the mission.
---------------------------------------------------------------------------
--PostLoad, this is all done after all loading, etc.
function ScriptPostLoad()
--Capture the Flag for stand-alone multiplayer
-- These set the flags geometry names.
--GeometryName sets the geometry when hte flag is on the ground
--CarriedGeometryName sets the geometry that appears over a player's head that is carrying the flag
SetProperty("flag1", "GeometryName", "com_icon_alliance_flag")
SetProperty("flag1", "CarriedGeometryName", "com_icon_alliance_flag_carried")
SetProperty("flag2", "GeometryName", "com_icon_imperial_flag")
SetProperty("flag2", "CarriedGeometryName", "com_icon_imperial_flag_carried")
--This makes sure the flag is colorized when it has been dropped on the ground
SetClassProperty("com_item_flag_carried", "DroppedColorize", 1)
There is nothing compiled here, the scripts themselves are open source.
Re: AI Hero support
Posted: Sat Oct 24, 2015 2:04 pm
by Rayman1103
Hello Anakin. If you're able to get a version working for every map, please let me know. I always wanted Heroes on all maps including customs that didn't use it.
I wish you luck!
Re: AI Hero support
Posted: Sat Oct 24, 2015 4:01 pm
by Anakin
Thank you all I'll have a look at all this scripts and hope i get this working