ID:2124692
 
Code:This i a part of the mission system I tried to create.
var/list/Sessions=list()
Sessions.Add("Session 1: The Test")
if(usr.Mission>0)
Sessions.Add("Session 2: The Sign")
switch(input("Which session would you like to complete?") as null|anything in Sessions)
if("Session 1: The Test")
for(var/obj/MissionSpot/AC in world)
if(!AC.Owner)
if(!AC.MissionLocation)///Whatever the mission var for the turf
usr.loc = AC.loc
AC.MissionLocation=1
var/mob/Danger/A = new()
A.loc = locate(usr.x,usr.y+7,usr.z)
A.name = "{Session}Bot"
A.icon = usr.icon
A.overlays = usr.overlays
A.Health = usr.Health*1.5
A.Energy = usr.Energy*1.5
A.MEnergy = usr.MEnergy*1.5
A.Stamina = usr.Stamina*1.5
A.MStamina = usr.MStamina*1.5
A.Attack = usr.Attack*1.5
A.Focus = usr.Focus*1.5
A.Defense = usr.Defense*1.5
else
usr<<"There are no spots for you!"
else
usr<<"There are no spots for you!"
if("Session 2: The Sign")
usr<<"This session is currently unavailable!"


Problem description: It works for the first person who tries to do the mission, but when another person tries to do the same mission it gives them the "there are no spots for you!" message the amount of times there are rooms and it won't let them join unless the first person finishes first. Side note I use usr<< because this is an object that i allowing them to do the mission.

</<>
add a break at the end of your if so it doesnt loop through all the missionspots. also you should probably just store all the missionspots in a list instead of looping through world
Add a break at which if? And if i used lists would it be easier for future use?
its just a lot more efficient and at if(!AC.MissionLocation)///Whatever the mission var for the tur


looping through every objects in the world or looping through a small list that only has the specific objects your looking for
Even better than looping would be to set the 'tag' variable of the MissionSpot objects and use locate() to grab them.

// If you set the tag of it to, say, "Test1"

var/obj/MissionSpot/AC = locate("Test1") in world
if(AC)
// Do stuff
else
// None found.
How would I make it so that it picks the other rooms if one is full
In response to Dayvon64
If you're referring to Nadrew's suggestion, I suppose you'd have to set the tags of all of the objects, as a string ("Test" in his and this example) ending in a number from 1 to however many there are (e.g. "Test1", "Test2", etc.). Then just loop through those.

The logic would end up being similar to the Universe_Steven's code:
// this is from Nadrew's code
var obj/MissionSpot/AC

// this is the same logic as Universe_Steven's for() loop,
// but AC is found using locate() instead of a search through the world
var n = 0
do AC = locate("Test[++n]")
while(AC && (AC.Owner || AC.MissionLocation))

// this is the rest of Nadrew's code
if(AC)
// Do stuff
else
// None found.


I think I'd rather just manage a list of open spots, though:
// a global var... because why not
var open_mission_spots[]

obj/MissionSpot
New()
if(!open_mission_spots) open_mission_spots = new
open_mission_spots += src

When a MissionSpot is no longer available, remove it from open_mission_spots:
open_mission_spots -= src
if(!open_mission_spots.len) open_mission_spots = null

When a MissionSpot becomes available, add it to open_mission_spots:
if(!open_mission_spots) open_mission_spots = new
open_mission_spots |= src

With that, looking for an open spot becomes this simple:
if(open_mission_spots)
var obj/MissionSpot/AC = open_mission_spots[open_mission_spots.len]
open_mission_spots.len--
// Do stuff
else
// None found.

No loops, no tags, no locate(), no searching the world.