ID:154245
 
I want to let players take over for an AI mob (not when they log in, but when they use the join_game verb), but then return it to AI control if the player leaves the game. Can anyone suggest a good way to design this?
On the mobs turn, just check for mob.client. If mob.client doesn't exist, call your AI routines. If it does, then alert the player that it's her turn. You may also want to start the AI in Logout() and stop processing AI in the Login() proc if it is that mob's turn.

Stopping in the middle of AI would be the hard part. you could just check for a client at diferent parts of the AI routines and abort if a client is found. you wouldn't need to worry about using mob.Login() if you do it this way.

Joining is fairly simple. Just make a list of mobs that don't have a client and allow the player to select from that list, then attach the client to the chosen mob. There are a number of commands that will do it. (somemob.client = someclient, somemob.key = someclient.key, someclient.mob = somemob.)
In response to Shadowdarke
Disabling the AI routines is not a problem, nor is getting a pointer to the right NPC to take over.

However, I was hoping to avoid calling Login() and Logout() again when the player takes over. I tried using (NPC_mob).key = (player).key, but is there another way that won't call Login and Logout?




Shadowdarke wrote:
On the mobs turn, just check for mob.client. If mob.client doesn't exist, call your AI routines. If it does, then alert the player that it's her turn. You may also want to start the AI in Logout() and stop processing AI in the Login() proc if it is that mob's turn.

Stopping in the middle of AI would be the hard part. you could just check for a client at diferent parts of the AI routines and abort if a client is found. you wouldn't need to worry about using mob.Login() if you do it this way.

Joining is fairly simple. Just make a list of mobs that don't have a client and allow the player to select from that list, then attach the client to the chosen mob. There are a number of commands that will do it. (somemob.client = someclient, somemob.key = someclient.key, someclient.mob = somemob.)
In response to Dramstud
dramstud wrote:
Disabling the AI routines is not a problem, nor is getting a pointer to the right NPC to take over.

However, I was hoping to avoid calling Login() and Logout() again when the player takes over. I tried using (NPC_mob).key = (player).key, but is there another way that won't call Login and Logout?

That's the definition of Login and Logout. If you want to perform actions only when a player enters or leaves the server, you're going to have to move those actions to the /client object--specifically, the procs client/New() and client/Del(). If you've got other player startup/leave actions in Login or Logout, you'll have to stick those in another function, too.
In response to Leftley
Leftley wrote:
dramstud wrote:
Disabling the AI routines is not a problem, nor is getting a pointer to the right NPC to take over.

However, I was hoping to avoid calling Login() and Logout() again when the player takes over. I tried using (NPC_mob).key = (player).key, but is there another way that won't call Login and Logout?

That's the definition of Login and Logout. If you want to perform actions only when a player enters or leaves the server, you're going to have to move those actions to the /client object--specifically, the procs client/New() and client/Del(). If you've got other player startup/leave actions in Login or Logout, you'll have to stick those in another function, too.

ah, ok... that makes sense. But when client/New() is run, has the player mob been created yet (ie. can i use it's variables/procs?)? I'm guessing probably not...
I'll have to read up a bit more on the client object.
In response to Dramstud
ah, ok... that makes sense. But when client/New() is run, has the player mob been created yet (ie. can i use it's variables/procs?)? I'm guessing probably not...

Actually, I'm a bit fuzzy on this. I think the default client/New() is actually the procedure which goes about creating the mob, so no, but you can spawn off commands while you're there. Another option would be to leave client/New() alone and create a client variable (it could be done as a mob var too, but client would be much easier) that keeps track of if you've already done your connecting-to-the-server stuff, and use that variable in Login() to determine whether or not to do it.
In response to Leftley
I ended up using a mob/spectator object which players logging in become by default. Everything seems to work ok, except for the Logout proc (if a player leaves in the middle of the game, it should switch his client back to his spectator mob and then call the spectator logout as well, which should say to world "so and so logged out" ... however, I don't get that message)
In response to Dramstud
dramstud wrote:
I ended up using a mob/spectator object which players logging in become by default. Everything seems to work ok, except for the Logout proc (if a player leaves in the middle of the game, it should switch his client back to his spectator mob and then call the spectator logout as well, which should say to world "so and so logged out" ... however, I don't get that message)

As Leftley pointed out earlier, you should stick your logout message in client.Del(), otherwise you'll see "so and so logged out" whenever they switch from a spectator to a playing mob. You should put the login message in client.New() for the same reason.

I'm not sure I follow why you move them back to the specatator before they logout of the game. In Tanks, I simply delete spectators in their logout() proc (to keep empty spectators from accumulating) and create new ones as they are needed. If you want to prevent someone from reclaiming a mob if they log back in, just set the mob's key to null in Logout().
In response to Shadowdarke
Shadowdarke wrote:

As Leftley pointed out earlier, you should stick your logout message in client.Del(), otherwise you'll see "so and so logged out" whenever they switch from a spectator to a playing mob. You should put the login message in client.New() for the same reason.

I had a problem with:
world << "[src.name] logged in"

if i move it to client.New... I guess I could scratch the name part, but then we see "the dramstud" instead of "dramstud"... of course, I might be the only idiot with a lowercase byond key ;)


I'm not sure I follow why you move them back to the specatator before they logout of the game. In Tanks, I simply delete spectators in their logout() proc (to keep empty spectators from accumulating) and create new ones as they are needed. If you want to prevent someone from reclaiming a mob if they log back in, just set the mob's key to null in Logout().

the motivation for this is to preserve the host's special verbs if he/she repeatedly enters/leaves the game. however, i guess that can be handled another way...