I Can't Even GetWorldPosition

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
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

I Can't Even GetWorldPosition

Post by jedimoose32 »

Hi everyone.

Really frustrated. Sometimes when I test my map, my code works fine. Other times, even if I don't change the code at all, it doesn't. It always seems to revolve around my use of GetWorldPosition (and sometimes GetCharacterUnit). But I can't figure out any pattern to it. Here's my ScriptPostLoad:
Hidden/Spoiler:
[code]
--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--

-- load the gametype script
ScriptCB_DoFile("ObjectiveConquest")
ScriptCB_DoFile("setup_teams")

-- REP Attacking (attacker is always #1)
REP = 1;
CIS = 2;
TAR = 3;
CIV = 4;
-- These variables do not change
ATT = REP;
DEF = CIS;


function ScriptPostLoad()


--This defines the CPs. These need to happen first
cp1 = CommandPost:New{name = "cp1"}
cp2 = CommandPost:New{name = "cp2"}
cp3 = CommandPost:New{name = "cp3"}
cp4 = CommandPost:New{name = "cp4"}


--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:Start()


--LET'S KILL SOME TARGETS - BEGIN KTT

--going to define almost all of my timers and local variables here

-------------------------------------------------------------------------------------------------------
--Behaviour: Team 3 is the target team. Individual units will spawn and be marked for the player to kill.
-- Team 4 is the civilian team. A large number of these units will spawn all over the map and
-- pretty much just stand/walk around. I may add functionality later which permits them to run
-- around panicking for a minute or so, once shots are fired.
-- Team 2 is the guard team. Currently they stick close to the selected target, but I plan to
-- change this so that they will patrol the map in small groups until shots are fired. They will
-- go aggro on the player if the player opens fire on *anyone*, and chase the player around until
-- the player is able to hide from them for a sufficient length of time. At that point they will
-- return to their guard duties until another fight starts.
-- Team 1 is just the player. The player starts out friendly to all other teams except Team 3,
-- which he is neutral toward.
--Possible Future Teams: - Cameras/Turrets
-- - Backup for Team 1
-- - Rival assassins?
-------------------------------------------------------------------------------------------------------

print("\n\n----BEGIN KILL THE TARGET----")
print("Everything below this point is for debugging\n")

deftimer = CreateTimer("deftimer")
SetTimerValue(deftimer, 1.0)

evadetimer = CreateTimer("evadetimer")
SetTimerValue(evadetimer, 25.0)

noevadetimer = CreateTimer("noevadetimer")
SetTimerValue(noevadetimer, 10.0)

switchtargettimer1 = CreateTimer("switchtargettimer1")
SetTimerValue(switchtargettimer1, 0.5)
switchtargettimer2 = CreateTimer("switchtargettimer2")
SetTimerValue(switchtargettimer2, 0.5)

i = 1
numTargetsDone = 0
numInnocentsKilled = 0
xplayer,yplayer,zplayer = 0
xenemy,yenemy,zenemy = 0
detected = 0
endGame = false

AllowAISpawn(1, false)

ForceHumansOntoTeam1()

AICanCaptureCP("cp1", 2, false)
AICanCaptureCP("cp2", 2, false)
AICanCaptureCP("cp3", 2, false)
AICanCaptureCP("cp4", 2, false)
AICanCaptureCP("cp1", 3, false)
AICanCaptureCP("cp2", 3, false)
AICanCaptureCP("cp3", 3, false)
AICanCaptureCP("cp4", 3, false)
AICanCaptureCP("cp1", 4, false)
AICanCaptureCP("cp2", 4, false)
AICanCaptureCP("cp3", 4, false)
AICanCaptureCP("cp4", 4, false)

playerone = GetTeamMember(1,0) --Name the player

target1 = GetTeamMember(3,0) --Begin Target setup
target2 = GetTeamMember(3,1)
target3 = GetTeamMember(3,2)
SelectCharacterClass(target1, "cis_hero_darthmaul")
SelectCharacterClass(target2, "cis_hero_countdooku")
SelectCharacterClass(target3, "cis_hero_jangofett")
SpawnCharacter(target1, GetPathPoint("cp4_spawn", 0))
SpawnCharacter(target2, GetPathPoint("cp2_spawn", 0))
SpawnCharacter(target3, GetPathPoint("cp3_spawn", 0))
print("Target setup complete")

SetClassProperty("cis_hero_darthmaul", "MaxSpeed", 4.0) --Initial speed settings: Targets and guards walk at a brisk pace, civilians kind of wander
SetClassProperty("cis_hero_countdooku", "MaxSpeed", 4.0)
SetClassProperty("cis_hero_jangofett", "MaxSpeed", 4.0)
SetClassProperty("cis_inf_rifleman", "MaxSpeed", 4.0)
SetClassProperty("cis_inf_engineer", "MaxSpeed", 2.0)

AddAIGoal(3, "deathmatch", 100)
AddAIGoal(4, "deathmatch", 100)

dummy = CreateTimer("dummy")
SetTimerValue(dummy, 0.5)
StartTimer(dummy)
print("Timer dummy elapsed")

OnTimerElapse(
function(timer)
ClearAIGoals(2)
AddAIGoal(2, "follow", 600, GetCharacterUnit(target1))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target2))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target3))
--MapAddEntityMarker(GetCharacterUnit(target1), "hud_objective_icon_circle", 5, 1, "RED", true, true, true) --map marker
DestroyTimer(dummy)
print("Map marker created")
end,
dummy
)

SetTeamAsFriend(1,2)
SetTeamAsNeutral(1,3)
SetTeamAsFriend(1,4)
SetTeamAsFriend(2,1)
SetTeamAsFriend(2,3)
SetTeamAsFriend(2,4)
SetTeamAsFriend(3,1)
SetTeamAsFriend(3,2)
SetTeamAsFriend(3,4)
SetTeamAsFriend(4,1)
SetTeamAsFriend(4,2)
SetTeamAsFriend(4,3)

print("Team diplomacy set")
print("State: Anonymous")

onfirstspawn = OnCharacterSpawn(
function(character)
if IsCharacterHuman(character) then
ReleaseCharacterSpawn(onfirstspawn)
onfirstspawn = nil
AllowAISpawn(3, false)
ShowMessageText("level.jer.kill1")
end
end
)

-----------------------------------------------------------------------------------------------------
-- This section will handle all character deaths, checking for civilian losses and target elimination
-----------------------------------------------------------------------------------------------------

personKill = OnCharacterDeath(
function(character, killer)
if GetCharacterTeam(character) == 4 and GetCharacterTeam(killer) == 1 then --CIVILIANS KILLED
ShowMessageText("level.jer.innocentkill")
StartTimer(evadetimer)
numInnocentsKilled = numInnocentsKilled + 1
if numInnocentsKilled < 5 and numInnocentsKilled > 0 then --CIVILIAN MURDER MESSAGE
ShowMessageText("level.jer.innocentcount-" .. numInnocentsKilled)
print(numInnocentsKilled .. " innocents killed, " .. (5 - numInnocentsKilled) .. " more allowed.")
end
elseif character == target1 and numTargetsDone == 0 then --FIRST TARGET KILLED
numTargetsDone = 1
ShowMessageText("level.jer.evade")
elseif character == target2 and numTargetsDone == 1 then --SECOND TARGET KILLED
numTargetsDone = 2
ShowMessageText("level.jer.evade")
elseif character == target3 and numTargetsDone == 2 then --THIRD TARGET KILLED
numTargetsDone = 3
ShowMessageText("level.jer.evade")
end

if numInnocentsKilled >= 5 then --TOO MANY CIVILIANS DEAD
StartTimer(deftimer)
print("Too many civs killed. Starting defeat timer...")
end

if GetNumTeamMembersAlive(1) == 0 then --PLAYER KILLED
StartTimer(deftimer)
print("Starting defeat timer...")
elseif numTargetsDone == 3 and endGame == false then --ALL TARGETS DEAD
endGame = true
ClearAIGoals(2)
AddAIGoal(2, "destroy", 1000, GetCharacterUnit(killer))
ActivateRegion("choppa")
SetTeamAsEnemy(1,2)
SetTeamAsEnemy(2,1)
MapAddRegionMarker("choppa", "hud_objective_icon_circle", 5, 1, "BLUE", true, true, true)
print("Target eliminated")
print("Safe zone activated")
ShowMessageText("level.jer.escape")
end

end
)

function EnemyDistance() --Do anonymity checking... basically try to figure out whether the player is sufficiently far away from all the guards
detected = 0
for unitnum = 0, 9 do --make sure this is updated to reflect the number of people on team 2, or face the consequences
enemynum = GetTeamMember(2,unitnum)
xenemy,yenemy,zenemy = GetWorldPosition(GetCharacterUnit(enemynum))
print("\nGetting enemy X: " .. xenemy)
print("Getting enemy Y: " .. yenemy)
print("Getting enemy Z: " .. zenemy)
if (math.abs(xenemy - xplayer) <= 16) and (math.abs(zenemy - zplayer) <= 16) then
print("Enemy too close")
ShowMessageText("level.jer.noevade")
StartTimer(noevadetimer)
detected = detected + 1
break
else
print("Enemy far enough away, moving on")
end
end
if detected == 0 then
print("State: Anonymous")
SetTeamAsFriend(1,2)
SetTeamAsFriend(2,1)
ClearAIGoals(2)
ShowMessageText("level.jer.evadecomplete")
if numTargetsDone == 1 then
StartTimer(switchtargettimer1)
elseif numTargetsDone == 2 then
StartTimer(switchtargettimer2)
elseif numTargetsDone == 0 then
AddAIGoal(2, "follow", 600, GetCharacterUnit(target1))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target2))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target3))
elseif numTargetsDone >= 3 then
AddAIGoal(2, "deathmatch", 100)
end
end
end

OnTimerElapse(
function(timer)
xplayer,yplayer,zplayer = GetWorldPosition(GetCharacterUnit(playerone))
print("\nGetting player X again: " .. xplayer)
print("Getting player Y again: " .. yplayer)
print("Getting player Z again: " .. zplayer)
StopTimer(noevadetimer)
SetTimerValue(noevadetimer, 15)
EnemyDistance()
end,
noevadetimer)

OnTimerElapse(
function(timer)
xplayer,yplayer,zplayer = GetWorldPosition(GetCharacterUnit(playerone))
print("\nGetting player X: " .. xplayer)
print("Getting player Y: " .. yplayer)
print("Getting player Z: " .. zplayer)
StopTimer(evadetimer)
SetTimerValue(evadetimer, 25)
EnemyDistance()
end,
evadetimer
)

OnTimerElapse(
function(timer)
if numTargetsDone == 1 then
StopTimer(switchtargettimer1)
--SetTimerValue(switchtargettimer1, 0.5)
ClearAIGoals(2)
AddAIGoal(2, "follow", 700, GetCharacterUnit(target2))
AddAIGoal(2, "follow", 300, GetCharacterUnit(target3))
ClearAIGoals(3)
AddAIGoal(3, "deathmatch", 100)
--MapAddEntityMarker(GetCharacterUnit(target2), "hud_objective_icon_circle", 5, 1, "RED", true, true, true) --map marker
print("Second map marker created")
ShowMessageText("level.jer.kill2")
end
end,
switchtargettimer1)

OnTimerElapse(
function(timer)
if numTargetsDone == 2 then
StopTimer(switchtargettimer2)
--SetTimerValue(switchtargettimer2, 0.5)
ClearAIGoals(2)
AddAIGoal(2, "follow", 1000, GetCharacterUnit(target3))
ClearAIGoals(3)
AddAIGoal(3, "deathmatch", 100)
--MapAddEntityMarker(GetCharacterUnit(target3), "hud_objective_icon_circle", 5, 1, "RED", true, true, true) --map marker
print("Third map marker created")
ShowMessageText("level.jer.kill3")
end
end,
switchtargettimer2)

victorycheck = OnEnterRegion(
function(region, character)
if GetCharacterTeam(character) == 1 then
MissionVictory(1)
print("Congration you done it (victory)")
end
end,
"choppa"
)

dmgcheck = OnObjectDamage(function(object, damager)
print("Check damage")
if GetObjectTeam(GetCharacterUnit(damager)) == 1 and detected == 0 then
detected = 1
StartTimer(evadetimer)
ClearAIGoals(3)
AddAIGoal(3, "follow", 500, "cp4") --he'll run away
AddAIGoal(3, "follow", 500, "cp3")
ClearAIGoals(2)
AddAIGoal(2, "destroy", 700, GetCharacterUnit(damager)) --and they'll try to kill you
AddAIGoal(2, "follow", 300, GetCharacterUnit(target1))
SetTeamAsEnemy(1,2)
SetTeamAsEnemy(2,1)
SetClassProperty("cis_inf_rifleman", "MaxSpeed", 5.4)
print("State: Detected")
end
end)

OnTimerElapse(
function(timer)
MissionDefeat(1)
print("Mission defeat")
DestroyTimer(deftimer)
end,
deftimer
)

DisableAIAutoBalance()

--END KTT

SetUberMode(1);

--EnableSPHeroRules()

end
[/code]
And the relevant section of my error log:
Hidden/Spoiler:
[code]
Message Severity: 3
.\Source\LuaHelper.cpp(312)
CallProc failed: bad argument #1 to `GetWorldPosition' (string expected, got nil)
stack traceback:
[C]: in function `GetWorldPosition'
(none): in function `EnemyDistance'
(none): in function <(none):274>
[/code]
Last edited by jedimoose32 on Thu Mar 12, 2015 2:47 am, edited 2 times in total.
User avatar
Teancum
Jedi Admin
Jedi Admin
Posts: 11080
Joined: Wed Sep 07, 2005 11:42 pm
Projects :: No Mod project currently.
Games I'm Playing :: Destiny
xbox live or psn: No gamertag set
Location: Indiana

Re: I Can't Even GetWorldPosition

Post by Teancum »

Is that even a function? It's not listed in the LUA callback reference

http://secretsociety.com/forum/download ... erence.txt
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: I Can't Even GetWorldPosition

Post by jedimoose32 »

Yep. I know it's not on the list but it does work (usually). It outputs a character or entity's location in xyz form. Others on GT use it as well.

Edit: Could this be caused by the fact that I define xplayer, yplayer, and zplayer, as well as xenemy, yenemy, and zenemy, as 0 right away? Should I leave them undefined until I need them?
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: I Can't Even GetWorldPosition

Post by [RDH]Zerted »

bad argument #1 to `GetWorldPosition' (string expected, got nil)
The error says there's a problem with the first argument being passed to GetWorldPosition(). It requires the argument to be a string, but it's getting a nil instead. So then look to see what you're passing in: the result of a GetCharacterUnit() call. So if GetCharacterUnit() is returning nil, then it means the character doesn't have a unit, meaning that player hasn't spawned yet or is dead.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: I Can't Even GetWorldPosition

Post by jedimoose32 »

[RDH]Zerted wrote:... meaning that player hasn't spawned yet or is dead.
Hidden/Spoiler:
Image
That makes complete sense now that I think of it. The pattern/problem is, I think, that this error gets returned whenever I kill a guard. So when the function EnemyDistance enters the for loop to check how close the guards are, it eventually finds one guard that is dead and returns this error which mucks up the whole game. So what's my best option here, to include something like this?

Code: Select all

if enemynum == nil then
unitnum = unitnum + 1
break
end
In my post-work brain right now I'm thinking that would effectively deal with a nil value by telling the for loop to just move right past the dead unit by breaking, and try the next one. Am I wrong? Is there a better way of doing it?

(Thank you soooo much for your help on this so far.)

Edit: It doesn't seem to work...
ZoomV
Rebel Warrant Officer
Rebel Warrant Officer
Posts: 308
Joined: Thu Aug 15, 2013 11:27 am
Projects :: Old Republic Map pack
Games I'm Playing :: BF2 SWTOR and GW2
xbox live or psn: No gamertag set
Location: Belsavis, Maximum Security Ward

Re: I Can't Even GetWorldPosition

Post by ZoomV »

jedimoose32 wrote: In my post-work brain right now I'm thinking that would effectively deal with a nil value by telling the for loop to just move right past the dead unit by breaking, and try the next one. Am I wrong? Is there a better way of doing it?

(Thank you soooo much for your help on this so far.)

Edit: It doesn't seem to work...
Now I have very little experience with BF2's lua, but generally speaking in every language I know of, using break in a for loop breaks the loop entirely, not just that iteration of the loop. So if it hits a dead unit that isn't the last guard its checking then the loop is getting terminated early.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: I Can't Even GetWorldPosition

Post by jedimoose32 »

You're right, I realized that as I was going to bed last night. So I've got to find another way around this. Some way to tell the for loop to move on past the GetWorldPosition if the GetCharacterUnit returns a nil value. I'm sure this would be no problem for someone with more coding experience.

Edit: So what I've done (credit to LRKfm for the idea) is register all of my team 2 units in a table like this:
Hidden/Spoiler:
[code]
enemiesAlive = {}

onenemySpawn = OnCharacterSpawn(
function(character)
if GetCharacterTeam(character) == 2 then
table.insert(enemiesAlive, GetCharacterUnit(character))
print("\t" .. table.getn(enemiesAlive) .. " enemies alive")
end
end
)
[/code]
And then unregister them whenever they die:
Hidden/Spoiler:
[code]
personKill = OnCharacterDeath(
function(character, killer)
...
if GetCharacterTeam(character) == 2 then
table.remove(enemiesAlive, GetCharacterUnit(character))
print("\t" .. table.getn(enemiesAlive) .. " enemies alive")
end

end
)
[/code]
So now the distance check uses "for unitnum = 0, (table.getn(enemiesAlive) - 1) do", which should mean, for example, if there are 8 enemies alive then spots 0 through 7 on Team 2 should be filled, right? Meaning there should be 8 keys in enemiesAlive. So I tell the for loop to start at 0 and work its way up to 8 - 1 (7). This makes sense to me and I honestly thought it would work but I'm still getting the same error! (Here's the actual code for the EnemyDistance function:
Hidden/Spoiler:
[code]
function EnemyDistance() --Do anonymity checking... basically try to figure out whether the player is sufficiently far away from all the guards
detected = 0
for unitnum = 0, (table.getn(enemiesAlive) - 1) do
enemynum = GetTeamMember(2,unitnum)
print("\nThis is enemy # " .. unitnum)
xenemy,yenemy,zenemy = GetWorldPosition(GetCharacterUnit(enemynum))
print("Getting enemy X: " .. xenemy)
print("Getting enemy Y: " .. yenemy)
print("Getting enemy Z: " .. zenemy)
if (math.abs(xenemy - xplayer) <= 16) and (math.abs(zenemy - zplayer) <= 16) then
print("Enemy too close")
ShowMessageText("level.jer.noevade")
StartTimer(noevadetimer)
detected = detected + 1
break
else
print("Enemy far enough away, moving on")
end
end
if detected == 0 then
print("State: Anonymous")
SetTeamAsFriend(1,2)
SetTeamAsFriend(2,1)
ClearAIGoals(2)
ShowMessageText("level.jer.evadecomplete")
if numTargetsDone == 1 then
StartTimer(switchtargettimer1)
elseif numTargetsDone == 2 then
StartTimer(switchtargettimer2)
elseif numTargetsDone == 0 then
AddAIGoal(2, "follow", 600, GetCharacterUnit(target1))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target2))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target3))
elseif numTargetsDone >= 3 then
AddAIGoal(2, "deathmatch", 100)
end
end
end
[/code]
Got it! (edit: Turns out I didn't, see below)

Pairs, man. Pairs are a lifesaver. So I changed the way my tables work a bit, and then instead of having the EnemyDistance function check every unit by getting GetTeamMember(2,x), I just kept a list of which enemies are alive, and then had the GetWorldPosition check each living member of that team. Here's the finished code!
Hidden/Spoiler:
[code]
numTargetsDone = 0
numInnocentsKilled = 0
guardsize = GetTeamSize(2)
detected = 0
xplayer,yplayer,zplayer = 0
endGame = false
EnemiesAliveCounter = 0

ListEnemiesAlive = {}
...
onenemySpawn = OnCharacterSpawn(
function(character)
if GetCharacterTeam(character) == 2 then --if they're a guard
local guard = GetCharacterUnit(character) --then check who we're dealing with
EnemiesAliveCounter = EnemiesAliveCounter + 1 --increase our count of who's alive
for p = EnemiesAliveCounter, guardsize do --loop through until we reach the end of team 2
ListEnemiesAlive[p] = guard --add a table entry with the value of our person
print("Guard spawning, indexed in the List at " .. p) --debug
break
end
end
end
)
...
personKill = OnCharacterDeath(
function(character, killer)
...
if GetCharacterTeam(character) == 2 then
EnemiesAliveCounter = EnemiesAliveCounter - 1
print("That was a guard dying")
print("\t" .. EnemiesAliveCounter .. " enemies alive")
local whoisdead = GetCharacterUnit(character)
table.remove(ListEnemiesAlive, whoisdead)
end
end
)
...
function EnemyDistance() --Do anonymity checking... basically try to figure out whether the player is sufficiently far away from all the guards
detected = 0
for k, v in pairs(ListEnemiesAlive) do --go through the table of who's alive
print("\nThis is enemy # " .. k)
local xenemy,yenemy,zenemy = GetWorldPosition(v)
print("Getting enemy X: " .. xenemy)
print("Getting enemy Y: " .. yenemy)
print("Getting enemy Z: " .. zenemy)
if (math.abs(xenemy - xplayer) <= 16) and (math.abs(zenemy - zplayer) <= 16) then
print("Enemy too close")
ShowMessageText("level.jer.noevade")
StartTimer(noevadetimer)
detected = detected + 1
break
else
print("Enemy far enough away, moving on")
end
end
if detected == 0 then
print("State: Anonymous")
SetTeamAsFriend(1,2)
SetTeamAsFriend(2,1)
ClearAIGoals(2)
ShowMessageText("level.jer.evadecomplete")
if numTargetsDone == 1 then
StartTimer(switchtargettimer1)
elseif numTargetsDone == 2 then
StartTimer(switchtargettimer2)
elseif numTargetsDone == 0 then
AddAIGoal(2, "follow", 600, GetCharacterUnit(target1))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target2))
AddAIGoal(2, "follow", 200, GetCharacterUnit(target3))
elseif numTargetsDone >= 3 then
AddAIGoal(2, "deathmatch", 100)
end
end
end
[/code]
Last edited by jedimoose32 on Thu Mar 12, 2015 2:53 am, edited 1 time in total.
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: I Can't Even GetWorldPosition [Solved]

Post by [RDH]Zerted »

In most programming languages "continue" skips to the next iteration of a loop. However for some reason Lua doesn't have "continue". So the standard practice is to use an if statement instead. Quick Example:

Code: Select all

for i=1,4 do
    if i == 3 then
        --do nothing this iteration
    else
        --do whatever the loop normally does
    end
end
or

Code: Select all

for i=1,4 do
    if i ~= 3 then
        --do whatever the loop normally does
    end
end
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: I Can't Even GetWorldPosition [Solved]

Post by jedimoose32 »

Interesting. Are you saying I could implement something similar to have the code skip members of team 2 that are dead? Because I tried something similar and still had the GetWorldPosition trying to read the unit's nil value. Maybe I was going about it the wrong way though.

Edit: To be more specific I had something along the lines of:

Code: Select all

for i = 0, 10 do if GetCharacterUnit(i) == nil then elseif (the rest of my function) end end
(Sorry for the poor formatting, I'm on my phone at work)

Edit 2: I shouldn't have marked the thread [Solved]... I did some more testing and now I'm getting an instant CTD sometimes when the script is checking the enemy distance. Here's the last thing it shows me in the error log each time (not always #6):

Code: Select all

...
Second map marker created
State: Detected
That was a guard dying
	9 enemies alive
That was a guard dying
	8 enemies alive
That was a guard dying
	7 enemies alive

Getting player X: -142.08474731445
Getting player Y: 0.99105077981949
Getting player Z: 221.30699157715

This is enemy # 6
*CTD*
I'm not sure if it was something I changed. It's worth mentioning that a friend recommended I try Eclipse LDT for lua editing, so I made a tiny little change to a completely unrelated part of the script in that environment and saved, and only notice the problem afterward. This could be a false correlation though.
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: I Can't Even GetWorldPosition

Post by [RDH]Zerted »

At the very least GetCharacterUnit(i) should be GetCharacterUnit(GetTeamMember(2,i)).

Your OnCharacterDeath performs a GetCharacterUnit() on a character it knows is dead. Dead characters don't have units. Don't do that. It looks like you're always and only removing nil from ListEnemiesAlive.
jedimoose32
Field Commander
Field Commander
Posts: 938
Joined: Thu Jan 24, 2008 12:41 am
Projects :: Engineering Degree
Location: The Flatlands of Canada

Re: I Can't Even GetWorldPosition

Post by jedimoose32 »

Okay that makes sense. Even so, the crash appears to be coming from the game trying to read my table in function EnemyDistance... You can see it starts the function just fine and prints "this is enemy # ..." but then dies. If I'm only removing nils from my table with OnCharacterDeath then what is the GetWorldPosition finding in there that breaks the game?
Post Reply