AI-Controlled spawned units Help Needed [Solved]

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
LitFam
Sergeant Major
Sergeant Major
Posts: 234
Joined: Sat Feb 04, 2017 5:52 pm
Games I'm Playing :: SWBF II 2005
xbox live or psn: No gamertag set
Location: Milky Way, Solar System, Earth, Antarctica

AI-Controlled spawned units Help Needed [Solved]

Post by LitFam »

I am trying to follow this tutorial, however, I can't get the units to spawn: http://www.gametoast.com/viewtopic.php?p=126047#p126047

Here is my .lua
Hidden/Spoiler:
[code]--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--

-- load the gametype script
ScriptCB_DoFile("ObjectiveConquest")
ScriptCB_DoFile("setup_teams")
---------------------------------------------------------------------------
-- 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()

-- Setup the team that will spawn in ScriptInit(), include the SetTeamAsFriend() stuff
-- Add this code into ScriptPostLoad() once for each team that can spawn stuff (changing a couple of variables each time)
-- Add an AIGoal for the spawned team somewhere in ScriptPostLoad() so the spawned character will actually do something

TroopSpawnerWeapon = "bot_weap_reinforcements_ord"

OnCharacterDispenseControllableTeam(
function(character,controlled)
if GetEntityClass(controlled) == GetEntityClassPtr(TroopSpawnerWeapon) then
local SupportTeam = 3 --Team the new spawned character is in (change this)
local teamSize = GetTeamSize(SupportTeam)
for i = 0, teamSize-1 do
local characterIndex = GetTeamMember(SupportTeam, i)
local charUnit = GetCharacterUnit(characterIndex)
if not charUnit then
local destination = GetEntityMatrix(GetCharacterUnit(character))
SpawnCharacter(characterIndex,destination)
end
end
end
end,
IMP --User team (change this)
)

TrashStuff();
PlayAnimExtend();
PlayAnimTakExtend();

BlockPlanningGraphArcs("compactor")
OnObjectKillName(CompactorConnectionOn, "grate01")

DisableBarriers("start_room_barrier")
DisableBarriers("dr_left")
DisableBarriers("circle_bar1")
DisableBarriers("circle_bar2")

-- handle reinforcment loss and defeat condition
OnCharacterDeathTeam(function(character, killer) AddReinforcements(1, -1) end, 1)
OnTicketCountChange(function(team, count) if count == 0 then MissionDefeat(team) end end)

OnObjectRespawnName(PlayAnimExtend, "Panel-Chasm");
OnObjectKillName(PlayAnimRetract, "Panel-Chasm");

OnObjectRespawnName(PlayAnimTakExtend, "Panel-Tak");
OnObjectKillName(PlayAnimTakRetract, "Panel-Tak");

EnableSPHeroRules()
KillObject("CP6")
cp1 = CommandPost:New{name = "CP1"}
cp2 = CommandPost:New{name = "CP2"}
cp3 = CommandPost:New{name = "CP3"}
cp4 = CommandPost:New{name = "CP4"}
cp5 = CommandPost:New{name = "CP5"}
--cp6 = CommandPost:New{name = "CP6"}
cp7 = CommandPost:New{name = "CP7"}

--This sets up the actual objective. This needs to happen after cp's are defined
conquest = ObjectiveConquest:New{teamATT = ATT, teamDEF = DEF, textATT = "game.modes.con", textDEF = "game.modes.con2", multiplayerRules = true}

--This adds the CPs to the objective. This needs to happen after the objective is set up
conquest:AddCommandPost(cp1)
conquest:AddCommandPost(cp2)
conquest:AddCommandPost(cp3)
conquest:AddCommandPost(cp4)
conquest:AddCommandPost(cp5)
--conquest:AddCommandPost(cp6)
conquest:AddCommandPost(cp7)

conquest:Start()

SetUberMode(1);

AddDeathRegion("DeathRegion01")
AddDeathRegion("DeathRegion02")
AddDeathRegion("DeathRegion03")
AddDeathRegion("DeathRegion04")
AddDeathRegion("DeathRegion05")

end

function CompactorConnectionOn()
UnblockPlanningGraphArcs ("compactor")
end
--START BRIDGEWORK!

-- OPEN
function PlayAnimExtend()
PauseAnimation("bridgeclose");
RewindAnimation("bridgeopen");
PlayAnimation("bridgeopen");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection122");
DisableBarriers("BridgeBarrier");

end
-- CLOSE
function PlayAnimRetract()
PauseAnimation("bridgeopen");
RewindAnimation("bridgeclose");
PlayAnimation("bridgeclose");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection122");
EnableBarriers("BridgeBarrier");

end

--START BRIDGEWORK TAK!!!

-- OPEN
function PlayAnimTakExtend()
PauseAnimation("TakBridgeOpen");
RewindAnimation("TakBridgeClose");
PlayAnimation("TakBridgeClose");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection128");
DisableBarriers("Barrier222");

end
-- CLOSE
function PlayAnimTakRetract()
PauseAnimation("TakBridgeClose");
RewindAnimation("TakBridgeOpen");
PlayAnimation("TakBridgeOpen");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection128");
EnableBarriers("Barrier222");

end

function TrashStuff()

trash_open = 1
trash_closed = 0

trash_timer = CreateTimer("trash_timer")
SetTimerValue(trash_timer, 7)
StartTimer(trash_timer)
trash_death = OnTimerElapse(
function(timer)
if trash_open == 1 then
AddDeathRegion("deathregion")
SetTimerValue(trash_timer, 5)
StartTimer(trash_timer)
trash_closed = 1
trash_open = 0
print("death region added")

elseif trash_closed == 1 then
RemoveRegion("deathregion")
SetTimerValue(trash_timer, 15)
StartTimer(trash_timer)
print("death region removed")
trash_closed = 0
trash_open = 1
end
end,
trash_timer
)
end

function ScriptInit()
-- Designers, these two lines *MUST* be first.
SetPS2ModelMemory(4000000)
ReadDataFile("ingame.lvl")

-- Empire Attacking (attacker is always #1)
local ALL = 1
local IMP = 2
CIV = 3
-- These variables do not change
local ATT = 1
local DEF = 2

ReadDataFile("dc:sound\\bot.lvl")
OpenAudioStream("dc:sound\\bot.lvl", "BOT_Unit_VO_S")
ReadDataFile("dc:sound\\bot.lvl;BOTcw")
ReadDataFile("sound\\dea.lvl;dea1gcw")

SetMaxFlyHeight(72)
SetMaxPlayerFlyHeight (72)
AISnipeSuitabilityDist(30)

SetMemoryPoolSize ("ClothData",20)
SetMemoryPoolSize ("Combo",50) -- should be ~ 2x number of jedi classes
SetMemoryPoolSize ("Combo::State",650) -- should be ~12x #Combo
SetMemoryPoolSize ("Combo::Transition",650) -- should be a bit bigger than #Combo::State
SetMemoryPoolSize ("Combo::Condition",650) -- should be a bit bigger than #Combo::State
SetMemoryPoolSize ("Combo::Attack",550) -- should be ~8-12x #Combo
SetMemoryPoolSize ("Combo::DamageSample",6000) -- should be ~8-12x #Combo::Attack
SetMemoryPoolSize ("Combo::Deflect",100) -- should be ~1x #combo

ReadDataFile("SIDE\\all.lvl",
"all_inf_rifleman_fleet",
"all_inf_rocketeer_fleet",
"all_inf_engineer_fleet",
"all_inf_sniper_fleet",
"all_inf_officer",
"all_hero_luke_jedi",
"all_inf_wookiee")

ReadDataFile("SIDE\\imp.lvl",
"imp_inf_rifleman",
"imp_inf_rocketeer",
"imp_inf_engineer",
"imp_inf_sniper",
"imp_inf_officer",
"imp_inf_dark_trooper")

ReadDataFile("SIDE\\imp.lvl",
"imp_hero_emperor")

ReadDataFile("dc:SIDE\\bot.lvl",
"bot_inf_stormtrooper",
"bot_inf_evo_trooper",
"bot_inf_death_trooper",
"bot_inf_death_trooper_squad_leader")

SetupTeams{

all={
team = ALL,
units = 50,
reinforcements = 500,
soldier = {"all_inf_rifleman_fleet",7, 25},
assault = {"all_inf_rocketeer_fleet",1, 4},
engineer = {"all_inf_engineer_fleet",1, 4},
sniper = {"all_inf_sniper_fleet",1, 4},
officer = {"all_inf_officer",1, 4},
special = {"all_inf_wookiee",1, 4},
},

imp={
team = IMP,
units = 50,
reinforcements = 500,
soldier = {"bot_inf_stormtrooper",25,25},
assault = {"bot_inf_death_trooper",5,5},
engineer = {"bot_inf_death_trooper_squad_leader",1,1},
},

civ={
team = CIV,
units = 2,
reinforcements = -1,
soldier = {"bot_inf_death_trooper",2,2},
}

}

AddAIGoal(3, "Deathmatch", 100)
SetTeamAsEnemy(ATT,3)
SetTeamAsEnemy(3,ATT)
SetTeamAsFriend(DEF,3)
SetTeamAsFriend(3,DEF)

-- Level Stats
ClearWalkers()
-- AddWalkerType(0, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(1, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(2, 0) -- 2 spider walkers with 2 leg pairs each
-- AddWalkerType(3, 0) -- 2 attes with 3 leg pairs each

local weaponCnt = 203
SetMemoryPoolSize("Aimer", 200)
SetMemoryPoolSize("BaseHint", 200)
SetMemoryPoolSize("EntityFlyer", 200) -- to account for rocket upgrade
SetMemoryPoolSize ("EntitySoundStream", 2)
SetMemoryPoolSize ("EntitySoundStatic", 1)
SetMemoryPoolSize("MountedTurret", 200)
SetMemoryPoolSize("Obstacle", 200)
SetMemoryPoolSize("PathNode", 200)
SetMemoryPoolSize("TentacleSimulator", 0)
SetMemoryPoolSize("TreeGridStack", 200)
SetMemoryPoolSize("SoldierAnimation",656)
SetMemoryPoolSize("EnergyBar",564)
SetMemoryPoolSize("AmmoCounter",564)
SetMemoryPoolSize("Weapon",562)
SetMemoryPoolSize("UnitController",200)
SetMemoryPoolSize("PathFollower",200)
SetMemoryPoolSize("Navigator",200)
SetMemoryPoolSize("UnitAgent",200)
SetMemoryPoolSize("FLEffectObject::OffsetMatrix",2000)
SetMemoryPoolSize("ParticleTransformer::ColorTrans",1648)
SetMemoryPoolSize("ParticleTransformer::PositionTr",2000)
SetMemoryPoolSize("ParticleTransformer::SizeTransf",1165)

SetSpawnDelay(10.0, 0.25)
ReadDataFile("dea\\dea1.lvl", "dea1_Conquest")
SetDenseEnvironment("true")

--SetStayInTurrets(1)

-- Movies
-- SetVictoryMovie(ALL, "all_end_victory")
-- SetDefeatMovie(ALL, "imp_end_victory")
-- SetVictoryMovie(IMP, "imp_end_victory")
-- SetDefeatMovie(IMP, "all_end_victory")

-- Sound

voiceSlow = OpenAudioStream("sound\\global.lvl", "all_unit_vo_slow")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_slow", voiceSlow)
AudioStreamAppendSegments("sound\\global.lvl", "global_vo_slow", voiceSlow)

voiceQuick = OpenAudioStream("sound\\global.lvl", "all_unit_vo_quick")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_quick", voiceQuick)

OpenAudioStream("sound\\global.lvl", "gcw_music")
-- OpenAudioStream("sound\\global.lvl", "global_vo_quick")
-- OpenAudioStream("sound\\global.lvl", "global_vo_slow")
OpenAudioStream("sound\\dea.lvl", "dea1")
OpenAudioStream("sound\\dea.lvl", "dea1")
-- OpenAudioStream("sound\\cor.lvl", "dea1gcw_emt")

SetBleedingVoiceOver(ALL, ALL, "all_off_com_report_us_overwhelmed", 1)
SetBleedingVoiceOver(ALL, IMP, "all_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, ALL, "imp_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, IMP, "imp_off_com_report_us_overwhelmed", 1)

SetLowReinforcementsVoiceOver(ALL, ALL, "all_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(ALL, IMP, "all_off_victory_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, IMP, "imp_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, ALL, "imp_off_victory_im", .1, 1)

SetOutOfBoundsVoiceOver(1, "allleaving")
SetOutOfBoundsVoiceOver(2, "impleaving")

SetAmbientMusic(ALL, 1.0, "all_dea_amb_start", 0,1)
SetAmbientMusic(ALL, 0.8, "all_dea_amb_middle", 1,1)
SetAmbientMusic(ALL, 0.2,"all_dea_amb_end", 2,1)
SetAmbientMusic(IMP, 1.0, "imp_dea_amb_start", 0,1)
SetAmbientMusic(IMP, 0.8, "imp_dea_amb_middle", 1,1)
SetAmbientMusic(IMP, 0.2,"imp_dea_amb_end", 2,1)

SetVictoryMusic(ALL, "all_dea_amb_victory")
SetDefeatMusic (ALL, "all_dea_amb_defeat")
SetVictoryMusic(IMP, "imp_dea_amb_victory")
SetDefeatMusic (IMP, "imp_dea_amb_defeat")

SetSoundEffect("ScopeDisplayZoomIn", "binocularzoomin")
SetSoundEffect("ScopeDisplayZoomOut", "binocularzoomout")
-- SetSoundEffect("BirdScatter", "birdsFlySeq1")
SetSoundEffect("SpawnDisplayUnitChange", "shell_select_unit")
SetSoundEffect("SpawnDisplayUnitAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplaySpawnPointChange", "shell_select_change")
SetSoundEffect("SpawnDisplaySpawnPointAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplayBack", "shell_menu_exit")

SetAttackingTeam(ATT)

AddCameraShot(-0.404895, 0.000992, -0.514360, -0.002240, -121.539894, 62.536297, -257.699493)
--Homestead
AddCameraShot(0.040922, -0.004049, -0.994299, -0.098381, -103.729523, 55.546598, -225.360893)
--Sarlac Pit
AddCameraShot(-1.0, 0.0, -0.514360, 0.0, -55.381485, 50.450953, -96.514324)
end[/code]
Did I make team 3 correctly?

If you need the weapon .odf files look here
Hidden/Spoiler:
[code][WeaponClass]
ClassLabel = "remote"

[Properties]
//IconTexture = "HUD_com_probedroid_health_icon"

MuzzleFlash = "small_muzzle_flash"
Discharge = "small_smoke_effect"

RoundsPerClip = "0"
ReloadTime = "0.0"
LockOnRange = "80.0"
LockTime = "0.4"

HeatPerShot = "1.0"
HeatRecoverRate = "0.05"

ZoomMin = "0.0"
ZoomMax = "0.0"
ZoomRate = "0.0"

//AnimationBank = "grenade"
OffhandWeapon = 1

SwitchImmediately = "0"

FireAnim = "1"
InstantPlayFireAnim = "1"

ShotDelay = "1.4"
MinSpread = "0.0"
MaxSpread = "0.0"
AutoAimSize = "1.0"

SalvoCount = "1"
SalvoDelay = "0.0"
InitialSalvoDelay = "0.3"

FireSound = "com_weap_inf_remotedroid_fire"
FireEmptySound = "com_weap_inf_ammo_empty"

OrdnanceName = "bot_weap_reinforcements_ord"[/code]
Hidden/Spoiler:
[code][GameObjectClass]
ClassLabel = "droid"
GeometryName = "com_weap_probedroid.msh"

[Properties]
ExplosionName = "all_weap_inf_remotedroid_exp1"
GeometryName = "com_weap_probedroid"
ImpactEffectWater = "com_sfx_watersplash_ord"

FLYERSECTION = "BODY"
VehicleType = "light"

PilotType = "remote"

MapTexture = "troop_icon"
HealthTexture = "HUD_com_probedroid_health_icon"
MapScale = 1.0

MapViewMin = 50
MapViewMax = 50
MapSpeedMin = 0
MapSpeedMax = 100

CollisionScale = 10.0

MaxHealth = 100.0
AddHealth = -1.0

EnergyAutoRestore = -99999.9

SetAltitude = 2000.0
GravityScale = 1.0//2
LiftSpring = 10.0 //10Lighter the veh the high the number
LiftDamp = 3.0

ScanningRange = 30.0
TransmitRange = 300.0

Acceleration = 25.0
Deceleration = 3.0
Traction = 22.0
ForwardSpeed = 3.5
ReverseSpeed = 3.5
StrafeSpeed = 0.25

SpinRate = 1.5
TurnRate = 1.5
TurnFilter = 5.0
PitchRate = 2.0
PitchFilter = 5.0
BankAngle = 0.0
BankFilter = 0

MoveTension = "30.0"//how much swim the craft has from the center of the screen


LevelSpring = 5.0
LevelDamp = 3.0

EyePointOffset = "0.0 0.5 0.0"
TrackOffset = "0.0 -0.25 1.8"
TiltValue = "5.0"

DestructTrackOffset = "0.0 0.0 18.0"
DestructTiltValue = "10.0"
DestructChargeEffect = "com_sfx_weap_remotedroidcharge2"

PitchLimits = "-50.0 50.0"
YawLimits = "-0.0 0.0"
AimerPitchLimits = "-90 90"
AimerYawLimits = "-90 90"

WEAPONSECTION = 1
WeaponName = "com_weap_null"
WeaponAmmo = 0
WeaponChannel = 0

AISizeType = "SOLDIER"

AmbientSound = "remotedroid_engine_lp"
Ambient2Sound = "remotedroid_radio"
HurtSound = ""
DeathSound = ""

\\\\\\\\\\\\ Collision \\\\\\\\\\\\\\

BuildingCollision = "p_buildingsphere"
VehicleCollision = "p_buildingsphere"
OrdnanceCollision = "p_sphere"
SoldierCollision = "p_sphere"[/code]
I get this error message in the log
Hidden/Spoiler:
[code]Message Severity: 3
C:\Battlefront2\main\Battlefront2\Source\LuaHelper.cpp(312)
CallProc failed: bad argument #2 to `OnCharacterDispenseControllableTeam' (number expected, got nil)
stack traceback:
[C]: in function `OnCharacterDispenseControllableTeam'
(none): in function `ScriptPostLoad'[/code]
Last edited by LitFam on Mon Nov 20, 2017 7:29 am, edited 1 time in total.
Marth8880
Resistance Leader
Posts: 5042
Joined: Tue Feb 09, 2010 8:43 pm
Projects :: DI2 + Psychosis
Games I'm Playing :: Silent Hill 2
xbox live or psn: Marth8880
Location: Edinburgh, UK
Contact:

Re: AI-Controlled spawned units Help Needed

Post by Marth8880 »

Code: Select all

Message Severity: 3
C:\Battlefront2\main\Battlefront2\Source\LuaHelper.cpp(312)
CallProc failed: bad argument #2 to `OnCharacterDispenseControllableTeam' (number expected, got nil)
stack traceback:
	[C]: in function `OnCharacterDispenseControllableTeam'
	(none): in function `ScriptPostLoad'
This error is saying that there's a problem with the second argument in OnCharacterDispenseControllableTeam - the problem being that the variable appears to be nil (i.e. unassigned). In your case, you're attempting to pass a variable called 'IMP' as the second argument, as shown below:

Code: Select all

   OnCharacterDispenseControllableTeam(
      function(character,controlled)    -- this anonymous function is the first argument
         if GetEntityClass(controlled) == GetEntityClassPtr(TroopSpawnerWeapon) then
            local SupportTeam = 3 --Team the new spawned character is in (change this)
            local teamSize = GetTeamSize(SupportTeam)
            for i = 0, teamSize-1 do
               local characterIndex = GetTeamMember(SupportTeam, i)
               local charUnit = GetCharacterUnit(characterIndex)
               if not charUnit then
                  local destination = GetEntityMatrix(GetCharacterUnit(character))
                  SpawnCharacter(characterIndex,destination)
               end
            end
         end
      end,    -- this closes the function that's passed as the first argument
      IMP -- this is the second argument, a simple reference to a variable 'IMP'
      )
The problem is while 'IMP' is being defined in the script, it's being defined as a local variable in ScriptInit, and as such is outside the scope that OnCharacterDispenseControllableTeam can "see" if that makes sense.

To resolve this problem, look at how 'IMP' is being defined at the top of ScriptInit in your script:

Code: Select all

    --  Empire Attacking (attacker is always #1)
    local ALL = 1
    local IMP = 2
	   CIV = 3
    --  These variables do not change
    local ATT = 1
    local DEF = 2
See the 'local' next to 'IMP'? That means that 'IMP' is being set as a local variable. Read up on the first link I linked below ('Local variables and scope') and go ahead and see if you can resolve this issue yourself. :)

Resources:
Local variables and scope - https://www.lua.org/pil/4.2.html
Variable assignment - https://www.lua.org/pil/4.1.html
LitFam
Sergeant Major
Sergeant Major
Posts: 234
Joined: Sat Feb 04, 2017 5:52 pm
Games I'm Playing :: SWBF II 2005
xbox live or psn: No gamertag set
Location: Milky Way, Solar System, Earth, Antarctica

Re: AI-Controlled spawned units Help Needed [Solved]

Post by LitFam »

Thank you Marth8880
Post Reply