ID:162392
 
Here's my idea:

For my spawn points I would want them to be activated before they spawn any creatures. By this I mean I would want there to be a player in the area to activate the spawn points which will then create monsters. I've thought of a way that might work but I'm not sure.

My idea would be to have an /area for the spawn points, and when a player enters the area it sends a message to the spawn points to be activated, therefore it will spawn monsters. But I'd also like it if the player leaves the area the spawn points are deactivated, and that a timer is set on the monsters that are spawned and when it runs out, they are deleted. The twist to this is that if the player enters the area again, the timer is turned off and the monster resumes its normal killing spree.

Any ideas on how to go about this?
Variables make the world go round.

Check it. Do it.
In response to Kaiochao2536
I know I would need variables, I was just wondering if my idea was a working one so I don't have to do all that work just to find out it was a total failure.
In response to Mareth
It's been done before, of course. But don't think that means you can't use it.
In response to Kaiochao2536
Alright, that's all I really wanted to hear. I don't mind if it's been done before. Thanks.
obj/spawnpoint
var/tmp/list/spawned
var/tmp/list/watchers //players in range of this
var/tmp/deltime = 0 //time at which we will delete spawned monsters
var/timetodel = 600 //time it takes to go from stop state to delete monster state
var/spawnrate = 100
var/spawntype = /mob
var/maxspawned = 10
proc
trigger(var/mob/M)
if(M.client)
if(!watchers)
watchers = list(M)
spawn() spawnloop()
else
watchers += M
spawnloop()
//make sure the spawned list is initialized
if(!spawned) spawned = list()
//loop until the spawner is fully deactivated
while(watchers)
//if somebody is around
if(watchers.len)
//and if we haven't maxed out on mobs
if(spawned.len < maxspawned)
//spawn a new mob
spawned += new spawntype(src.loc)
sleep(spawnrate)
untrigger(var/mob/M)
//remove M from watchers
watchers -= M
//if the list is empty, prepare to delete mobs
if(!watchers.len)
deltime = world.time + timetodel
spawn(timetodel)
//if we've been triggered again, then abort deletion
if(world.time < deltime)
return
else
watchers = null
for(var/mob/M in spawned)
del(M)
spawned = null


Now, to clarify some things. The variables spawnrate, spawntype, and timetodel define the rate at which mobs spawn, the type of the mobs spawned, and the time it takes for the spawned mobs (stored in the list spawned) to be deleted once everybody leaves. maxspawned, of course, determines the maximum number of mobs to spawn. trigger() is called whenever somebody triggers the conditions to start spawning mobs (which could be simply stepping within some range, or could be stepping within the area), and untrigger() is called when they leave the conditions (stepping out of range or out of the area). To go along with your idea of using areas, it would go like this:

area
Entered(var/mob/M)
if(istype(M) && M.client)
for(var/obj/spawnpoint/S in src.contents)
S.trigger(M)
..()
Exited(var/mob/M)
if(istype(M) && M.client)
for(var/obj/spawnpoint/S in src.contents)
S.untrigger(M)
..()


(on another note: you don't need to create a new type for each area you want on your map: you can generate a new instance of the same type using the map editor and have two separate areas of type /area side-by-side that aren't the same area)

The state of the spawner is indicated by the list watchers, which serves the dual purpose of also keeping track of who has triggered it.
If watchers is null, then the state of the spawner is that it's totally deactivated: spawnloop() is not running, and any mobs that may have been created have been deleted (if any were created at all, ever).
If watchers is a non-empty list containing mobs, then the spawner is in an activated state. spawnloop() will be active and spawning mobs (unless if the cap is reached, of course)
If watchers is an empty list, then the spawner is in the "standby" state: spawnloop() is running but not spawning anything (waiting to go into either the activated or deactivated states). untrigger() has spawn()ed off a possible transition to the deactivated state, which will carry through unless if it's interrupted by the spawner being activated (indicated by the list no longer being empty).

The use of the variable deltime is to ensure proper operation of mob deletion, so that two separate instances of untrigger() don't get confused with one another. As an example: there is one player and one spawner, with default settings. The player quickly ducks in and out of the spawner's range, calling trigger() and then untrigger(), which is going to wait 60 seconds then deactivate the spawner (and delete the one mob created by spawnloop(). Now, the player waits fifty-nine seconds, then steps in and out again. The desired behavior here is that the spawner then waits another sixty seconds before deactivating. However, the actual behavior (without the deltime check) is that after one more second, the first untrigger() call now deactivates the spawner, because the other conditions still match (watchers is an empty list). After another 59 seconds, the second untrigger() call (the only one we want to actually deactivate the spawner) then tries to deactivate the spawner again, but ends up doing nothing.