ID:145834
 
Code:
Deposit
var/list/Veins

New(Vein)
Veins = new()
..()
Veins += Vein

var/rich = round(rand(1, 3),1)
var/size = round(rand(5,25),1)
var/list/Prev = list(Vein)
var/list/Temp = list()
for(size,size>0,size--)
if(!Prev || !Prev.len) break
for(var/i=1,i<=Prev.len,i++)
if(pick(rich,0,0))
for(rich,rich>0,rich--)
for(var/n=8, n>0, n--)
if(!Prev || !Prev.len)
world.log << "No Prev!"
return
else
world.log << "[Prev.len] Prev!"
if(i > Prev.len)
world.log << "[i] > [Prev.len]!"
return
else
world.log << "[i] < [Prev.len]"
sleep(2)
for(var/p in Prev) world.log << p
var/turf/T = pick(oview(1,Prev[i]))
if(T && !T.contents.len)
var/obj/Vein/V = new(T, src)
Temp += V
break
else
for(var/n=8, n>0, n--)
if(!Prev || !Prev.len)
world.log << "No Prev!"
return
else
world.log << "[Prev.len] Prev!"
if(i > Prev.len)
world.log << "[i] > [Prev.len]!"
return
else
world.log << "[i] < [Prev.len]"
sleep(2)
for(var/p in Prev) world.log << p
var/turf/T = pick(oview(1,Prev[i]))
if(T && !T.contents.len)
var/obj/Vein/V = new(T, src)
Temp += V
break
Prev += Temp
Temp = new()
world.log << "DONE!"



obj
Vein
icon = 'grass.dmi'
icon_state = "vein"

var
Deposit/Load

New(Loc, Depo)
if(istype(Depo,/Deposit)) src.Load = Depo
else InitDeposit()
..()

proc
InitDeposit()
var/Deposit/Depo = new(src)
src.Load = Depo


Problem description: Create an instance of a Vein in the map and run. It goes along fine for a while, then spits out a List Index Out of Bounds error. I don't see how it could be out of bounds with all the checks before it. HELP!

It will help narrow down the problem if you can find the line where this error is happening. Go to the Build menu, select Preferences, and turn on debugging info. Then recompile your game and run it. Once you find the line where the error is, please point it out.

Lummox JR
In response to Lummox JR
Sorry, I thought you would have compiled and run the program. Also the checks should indicate where the problem is, since I wouldn't have them there if there wasn't. Line 61 is the main culprit, but line 42 also triggers it. Both are:

    var/turf/T = pick(oview(1,Prev[i]))


It's refering to i, which is a number less than the length of Prev but greater than 0, which doesn't refer to a null item in the Prev list, and is somehow out of bounds. I'm stumped.
In response to AZ0123
AZ0123 wrote:
    var/turf/T = pick(oview(1,Prev[i]))


Maybe it's not the Prev list that's the problem. Maybe it's pick()ing from the list returned by oview. Perhaps there are no turfs in the oview of whatever atom is returned by Prev[i].
In response to Jon88
It is picking from the list returned by oview(), that's what I want it to do. I don't think oview() would cause this error, and there are turfs all around the position where it spits out the error, so it can't be picking null.
In response to AZ0123
AZ0123 wrote:
It is picking from the list returned by oview(), that's what I want it to do. I don't think oview() would cause this error, and there are turfs all around the position where it spits out the error, so it can't be picking null.

In the BYOND Beta I get this more descriptive error:
runtime error: pick() from empty list
proc name: New (/Deposit/New)
source file: test.dm,50
usr: null
src: /Deposit (/Deposit)
call stack:
/Deposit (/Deposit): New(Vein (/obj/Vein))
Vein (/obj/Vein): InitDeposit()
Vein (/obj/Vein): New(the tile (11,7,1) (/turf/tile), null)


Haven't yet figured out the cause of it, though. Nothing appears to be nearing the edge of the map.

Edit, found out the cause. Adding a check to see the Vein's loc, the loc of the one that crashes is another vein. This is because oview() returns a list of *all* objects, not just turfs. So one vein is being made inside another.

A way to fix this is by first making a temporary list full of the turfs returned by oview(), and then pick() from that. Also something you might want to do is check if there's already a vein in a spot where the creation of another vein is attempted.
In response to Jon88
Oh! Thanks.

edit: I added a check after the pick() which fixes the error completely, but now I see my deposits are a bit larger than I was hoping for. Here's the check, which sees if T really is a turf, if not, it sets T to its loc, which is a turf in this basic setup.

if(!isturf(T)) T = T.loc