lotos123/
lotos123/datafiles/conffiles/
lotos123/datafiles/counters/
lotos123/datafiles/fonts/
lotos123/datafiles/helpfiles/
lotos123/datafiles/killmsgs/
lotos123/datafiles/mapfiles/
lotos123/datafiles/motds/motd1/
lotos123/datafiles/motds/motd2/
lotos123/datafiles/pictfiles/
lotos123/datafiles/plfiles/
lotos123/datafiles/plfiles/helpfiles/
lotos123/datafiles/screens/
lotos123/datafiles/textfiles/
lotos123/datafiles/trfiles/
lotos123/datafiles/votefiles/
lotos123/datafiles/votefiles/1/
lotos123/datafiles/votefiles/2/
lotos123/src/plugins/
lotos123/userfiles/
lotos123/userfiles/bin/
/* vi: set ts=4 sw=4 ai: */
/*
 * ct_move.c
 *
 *   Lotos v1.2.3  : (c) 1999-2003 Pavol Hluchy (Lopo)
 *   last update   : 30.1.2003
 *   email         : lotos@losys.sk
 *   homepage      : lotos.losys.sk
 */

#ifndef __CT_MOVE_C__
#define __CT_MOVE_C__ 1

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <ctype.h>

#include "define.h"
#include "prototypes.h"
#include "obj_ur.h"
#include "obj_rm.h"
#ifdef NETLINKS
	#include "obj_nl.h"
#endif
#include "obj_sys.h"
#include "obj_syspp.h"
#include "ct_move.h"
#include "comvals.h"


/*** Move to another room ***/
void go(UR_OBJECT user)
{
	RM_OBJECT rm;
#ifdef NETLINKS
	NL_OBJECT nl;
#endif
	int i;

	set_crash();
if (user->lroom==2) {
  write_user(user,"You have been shackled and cannot move.\n");
  return;
  }
if (user->restrict[RESTRICT_GO]==restrict_string[RESTRICT_GO]) {
	write_user(user,">>>You cannot have access to another sky...\n");
	return;
	}
if (word_count<2) {
  if (!(rm=get_room(default_warp))) {
    write_user(user,"You cannot warp to the main room at this time.\n");
    return;
    }
  if (user->room==rm) {
    vwrite_user(user,"You are already in the %s!\n",default_warp);
    return;
    }
  move_user(user,rm,1);
  follow(user);
  return;
  }
#ifdef NETLINKS
  nl=user->room->netlink;
  if (nl!=NULL && !strncmp(nl->service,word[1],strlen(word[1]))) {
    if (user->pot_netlink==nl) {
      write_user(user,"The remote service may be lagged, please be patient...\n");
      return;
      }
    rm=user->room;
    if (nl->stage<2) {
      write_user(user,"The netlink is inactive.\n");
      return;
      }
    if (nl->allow==IN && user->netlink!=nl) {
      /* Link for incoming users only */
      write_user(user,"Sorry, link is for incoming users only.\n");
      return;
      }
    /* If site is users home site then tell home system that we have removed
       him. */
    if (user->netlink==nl) {
      write_user(user,"~FB~OLYou traverse cyberspace...\n");
      sprintf(text,"REMVD %s\n",user->name);
      write_sock(nl->socket,text);
      if (user->vis) {
	sprintf(text,"%s~RS goes to the %s\n",user->recap,nl->service);
	write_room_except(rm,text,user);
        }
      else write_room_except(rm,invisleave,user);
      write_syslog(NETLOG,1,"NETLINK: Remote user %s removed.\n",user->name);
      destroy_user_clones(user);
      syspp->acounter[user->gender]--;
      syspp->acounter[3]--;
      destruct_user(user);
      reset_access(rm);
      no_prompt=1;
      return;
      }
    /* Can't let remote user jump to yet another remote site because this will 
       reset his user->netlink value and so we will lose his original link.
       2 netlink pointers are needed in the user structure to allow this
       but it means way too much rehacking of the code and I don't have the 
       time or inclination to do it */
    if (user->type==REMOTE_TYPE) {
      write_user(user,"Sorry, due to software limitations you can only traverse one netlink.\n");
      return;
      }
    if (nl->ver_major<=3 && nl->ver_minor<=3 && nl->ver_patch<1) {
      if (!word[2][0]) 
	sprintf(text,"TRANS %s %s %s\n",user->name,user->pass,user->desc);
      else sprintf(text,"TRANS %s %s %s\n",user->name,(char *)crypt(word[2],crypt_salt),user->desc);
      }
    else {
      if (!word[2][0]) 
	sprintf(text,"TRANS %s %s %d %s\n",user->name,user->pass,user->level,user->desc);
      else sprintf(text,"TRANS %s %s %d %s\n",user->name,(char *)crypt(word[2],crypt_salt),user->level,user->desc);
      }
    write_sock(nl->socket,text);
    user->remote_com=GO;
    user->pot_netlink=nl;  /* potential netlink */
    no_prompt=1;
    return;
    }
  /* If someone tries to go somewhere else while waiting to go to a talker
     send the other site a release message */
  if (user->remote_com==GO) {
    sprintf(text,"REL %s\n",user->name);
    write_sock(user->pot_netlink->socket,text);
    user->remote_com=-1;
    user->pot_netlink=NULL;
    }
#endif
if ((rm=get_room(word[1]))==NULL) {
  write_user(user,nosuchroom);  return;
  }
if (rm==user->room) {
  vwrite_user(user,"Ved uz si v %s!\n",rm->name);
  return;
  }
/* See if link from current room */
if (rm->transp!=NULL) {
	if ((!rm->transp->go) && rm->link[rm->transp->out]==user->room) {
		move_user(user, rm, 0);
		follow(user);
		return;
		}
	}
else {
	if (user->room->transp) {
		if ((!user->room->transp->go) && user->room->link[user->room->transp->out]==rm) {
			move_user(user, rm, 0);
			follow(user);
			return;
			}
		}
	else for (i=0; i<MAX_LINKS; ++i) {
		if (user->room->link[i]==rm) {
			move_user(user, rm, 0);
			follow(user);
			return;
			}
		}
	}
if (user->level<WIZ) {
  vwrite_user(user,"The %s is not adjoined to here.\n",rm->name);
  return;
  }
if (rm->access==PERSONAL_UNLOCKED || rm->access==PERSONAL_LOCKED) {
  write_user(user,"To go to another user's home you must .visit them.\n");
  return;
  }
move_user(user,rm,1);
follow(user);
}



/*** Wizard moves a user to another room ***/
void s_move(UR_OBJECT user)
{
	UR_OBJECT u;
	RM_OBJECT rm;
	char *name;
	int i, mur=0;

	set_crash();
	if (word_count<2) {
		write_usage(user,"%s <user> [<room>]", command_table[MOVE].name);  return;
		}
	if (word_count<3) rm=user->room;
	else {
		if ((rm=get_room(word[2]))==NULL) {
			write_user(user,nosuchroom);
			return;
			}
		}

	if ((mur=count_musers(user, word[1]))<2) {
		if (!(u=get_user_name(user,word[1]))) {
			write_user(user,notloggedon);
			return;
			}
		if (user==u) {
			write_user(user,"Trying to move yourself this way is the fourth sign of madness.\n");
			return;
			}
		if (u->level>=user->level) {
			write_user(user,"You cannot move a user of equal or higher level than yourself.\n");
			return;
			}
		if (rm==u->room) {
			vwrite_user(user,"%s~RS is already in the %s.\n",u->recap,rm->name);
			return;
			};
		if (u->restrict[RESTRICT_MOVE]==restrict_string[RESTRICT_MOVE]) {
			write_user(user,">>>This user is unmoveable...\n");
			return;
			}
		if (!has_room_access(user,rm)) {
			vwrite_user(user,"The %s is currently private, %s~RS cannot be moved there.\n",rm->name,u->recap);
			return;
			}
		write_user(user, move_prompt_user);
		if (user->vis) name=user->bw_recap;
		else name=invisname;
		vwrite_room_except(user->room,user, user_room_move_prompt, name);
		move_user(u,rm,2);
		prompt(u);
		}

	for (i=0; i<mur; i++) {
		if (!(u=get_user_name(user, user->murlist[i]))) {
			vwrite_user(user, "~FR~OL%s~RS : %s",
				user->murlist[i], notloggedon);
			continue;
			}
		if (user==u) {
			vwrite_user(user, "~FR~OL%s~RS : seba ? hmm...\n", user->murlist[i]);
			continue;
			}
		if (u->level>=user->level) {
			vwrite_user(user,"~FR~OL%s~RS : You cannot move a user of equal or higher level than yourself.\n", user->murlist[i]);
			continue;
			}
		if (rm==u->room) {
			vwrite_user(user,"~FR~OL%s~RS : already in the %s.\n",
				user->murlist[i], rm->name);
			continue;
			};
		if (u->restrict[RESTRICT_MOVE]==restrict_string[RESTRICT_MOVE]) {
			vwrite_user(user,"~FR~OL%s~RS : >>>This user is unmoveable...\n");
			continue;
			}
		if (!has_room_access(user,rm)) {
			vwrite_user(user,"The %s is currently private, %s~RS cannot be moved there.\n",rm->name,u->recap);
			return;
			}
		vwrite_user(user, "~FR~OL%s~RS : %s",
			user->murlist[i], move_prompt_user);
		if (user->vis) name=user->bw_recap;
		else name=invisname;
		if (!i) vwrite_room_except(user->room,user, user_room_move_prompt, name);
		move_user(u,rm,2);
		prompt(u);
		}
}


/*** Join a user in another room ***/
void join(UR_OBJECT user)
{
	UR_OBJECT u;
	RM_OBJECT rm;
	char *name;

	set_crash();
if (word_count<2) {
  write_usage(user,"%s <user>", command_table[JOIN].name);
  return;
  }
if (user->lroom==2) {
  write_user(user,"You have been shackled and cannot move.\n");
  return;
  }
if (!(u=get_user_name(user,word[1]))) {
  write_user(user,notloggedon);
  return;
  }
if (user==u) {
  write_user(user,"You really want join yourself?  What would the neighbours think?\n");
  return;
  }
rm=u->room;
#ifdef NETLINKS
  if (rm==NULL) {
    vwrite_user(user,"%s is currently off site so you cannot join them.\n",u->name);
    return;
    }
#endif
if (rm==user->room) {
  vwrite_user(user,"You are already with %s~RS in the %s.\n",u->recap,rm->name);
  return;
  };
if (!has_room_access(user,rm)) {
  vwrite_user(user,"That room is currently private, you cannot join %s~RS there.\n",u->recap);
  return;
  }
if (user->vis) name=user->recap;
else name=invisname;
vwrite_user(user,"~FT~OLYou join %s in the %s.~RS\n",u->bw_recap,u->room->name);
if (user->level<GOD || user->vis) {
  vwrite_room_except(user->room,user,"%s~RS %s\n",name,user->out_phrase);
  vwrite_room_except(rm,user,"%s~RS %s\n",name,user->in_phrase);
  }
user->room=rm;
look(user);
}


/*** bring a user to the same room ***/
void bring(UR_OBJECT user)
{
	UR_OBJECT u;
	RM_OBJECT rm;

	set_crash();
if (word_count<2) {
  write_usage(user,"%s <user>", command_table[BRING].name);
  return;
  }
if (!(u=get_user_name(user,word[1]))) {
  write_user(user,notloggedon);
  return;
  }
rm=user->room;
if (user==u) {
  write_user(user,"You ~OLreally~RS want to bring yourself?!  What would others think?!\n");
  return;
  }
if (rm==u->room) {
  vwrite_user(user,"%s~RS is already here!\n",u->recap);
  return;
  }
if (u->level>=user->level && user->level<GOD) {
  write_user(user,"You cannot move a user of equal or higher level that yourself.\n");
  return;
  }
write_user(user,"You chant a mystic spell...\n");
if (user->vis) vwrite_room_except(user->room,user,"%s~RS chants a mystic spell...\n",user->recap);
else {
  write_monitor(user,user->room,0);
  write_room_except(user->room,"Someone chants a mystic spell...\n",user);
  }
move_user(u,rm,2);
prompt(u);
}


/* lets a user enter their own room.  It creates the room if !exists */
void personal_room(UR_OBJECT user) {
char name[ROOM_NAME_LEN+1],filename[500];
RM_OBJECT rm;
int pcnt=0;

if (!amsys->personal_rooms) {
  write_user(user,"Personal room functions are currently disabled.\n");
  return;
  }
sprintf(name,"(%s)",user->name);
strtolower(name);
/* if the user wants to delete their room */
if (word_count>=2) {
  if (strcmp(word[1],"-d")) {
    write_usage(user,"%s [-d]", command_table[MYROOM].name);
    return;
    }
  /* move to the user out of the room if they are in it */
  if ((rm=get_room_full(name))==NULL) {
    write_user(user,"You do not have a personal room built.\n");
    return;
    }
  pcnt=room_visitor_count(rm);
  if (pcnt) {
    write_user(user,"You cannot destroy your room if any people are in it.\n");
    return;
    }
  write_user(user,"~OL~FRYou whistle a sharp spell and watch your room crumble into dust.~RS\n");
  destruct_room(rm);
  /* delete the files */
  sprintf(filename,"%s/%s.R", USERROOMS,user->name);
  unlink(filename);
  sprintf(filename,"%s/%s.B", USERROOMS,user->name);
  unlink(filename);
  sprintf(filename,"%s/%s.K", USERROOMS,user->name);
  unlink(filename);
  write_syslog(SYSLOG,1,"%s destructed their personal room.\n",user->name);
  return;
  }
/* if the user is moving to their room */
if (user->lroom==2) {
  write_user(user,"You have been shackled and cannot move.\n");
  return;
  }
/* if room doesn't exist then create it */
if ((rm=get_room_full(name))==NULL) {
  if ((rm=create_room())==NULL) {
    write_user(user,"Sorry, but your room could not be created at this time.\n");
    write_syslog(ERRLOG,1,"Could not create room for in personal_room()\n");
    return;
    }
  write_user(user,"\nYour room doesn't exists.  Building it now...\n\n");
  /* set up the new rooms attributes.  We presume that one room has already been parsed
     and that is the room everyone logs onto, and so we link to that */
  strcpy(rm->name,name);
  rm->access=PERSONAL_UNLOCKED;
  rm->link[0]=room_first;
  /* check to see if the room was just unloaded from memory first */
  if (!(personal_room_store(user->name,0,rm))) {
    strcpy(rm->desc,default_personal_room_desc);
    strcpy(rm->topic,"Welcome to my room!");
    write_syslog(SYSLOG,1,"%s creates their own room.\n",user->name);
    if (!personal_room_store(user->name,1,rm)) {
      write_syslog(ERRLOG,1,"Unable to save personal room status in personal_room_decorate()\n");
      }
    }
  }
/* if room just created then shouldn't go in his block */
if (user->room==rm) {
  write_user(user,"You are already in your own room!\n");
  return;
  }
move_user(user,rm,1);
}


/* lets a user go into another user's personal room if it's unlocked */
void personal_room_visit(UR_OBJECT user) {
char name[ROOM_NAME_LEN+1];
RM_OBJECT rm;

if (word_count<2) {
  write_usage(user,"%s <name>", command_table[VISIT].name);
  return;
  }
if (!amsys->personal_rooms) {
  write_user(user,"Personal room functions are currently disabled.\n");
  return;
  }
/* check if not same user */
word[1][0]=toupper(word[1][0]);
if (!strcmp(user->name,word[1])) {
  vwrite_user(user,"To go to your own room use the '%s' command.\n",command_table[MYROOM].name);
  return;
  }
/* see if there is such a user */
if (!find_user_listed(word[1])) {
  write_user(user,nosuchuser);
  return;
  }
/* get room to go to */
sprintf(name,"(%s)",word[1]);
strtolower(name);
if ((rm=get_room_full(name))==NULL) {
  write_user(user,nosuchroom);
  return;
  }
/* can they go there? */
if (!has_room_access(user,rm)) {
  write_user(user,"That room is currently private, you cannot enter.\n");  
  return;
  }
move_user(user,rm,1);
}

#endif /* ct_move.c */