/* look.c */
#include "config.h"
/*
* This file is part of TeenyMUD II.
* Copyright(C) 1993, 1994, 1995 by Jason Downs.
* All rights reserved.
*
* TeenyMUD II is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* TeenyMUD II is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file 'COPYING'); if not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
*/
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <sys/types.h>
#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
#else
#include <time.h>
#endif /* TM_IN_SYS_TIME */
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif /* HAVE_STRING_H */
#include "conf.h"
#include "teeny.h"
#include "commands.h"
#include "externs.h"
/* routines dealing with looking at things */
static char noloc[] = "You have no location!";
VOID do_look(player, cause, switches, argone)
int player, cause, switches;
char *argone;
{
int loc, here, obj, isfar;
if ((argone == (char *)NULL) || (argone[0] == '\0')
|| (strcasecmp(argone, "here") == 0))
look_location(player, cause, (switches & CMD_QUIET));
else {
if ((get_int_elt(player, LOC, &here) == -1) || !exists_object(here)) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player, noloc, NOT_QUIET);
return;
}
obj = resolve_object(player, cause, argone,
(!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY
: RSLV_EXITS));
if(obj == -1)
return;
if ((get_int_elt(obj, LOC, &loc) != -1) && exists_object(loc)) {
isfar = ((loc != here) && (loc != player));
if ((isfar || isROOM(obj)) && !controls(player, cause, obj)) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player,
"That's much too far away to see.", NOT_QUIET);
} else {
if(isEXIT(obj)) {
look_exit(player, cause, obj, isfar);
} else {
look_thing(player, cause, obj, isfar);
}
}
} else
notify_bad(player);
}
}
VOID do_examine(player, cause, switches, argone, argtwo)
int player, cause, switches;
char *argone, *argtwo;
{
int obj, num, *dests;
char *msg = (char *)NULL;
char *name;
time_t timestamp;
char buf[MEDBUFFSIZ];
if ((argone == (char *)NULL) || (argone[0] == '\0')) {
if ((get_int_elt(player, LOC, &obj) == -1) || !exists_object(obj)) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player, noloc, NOT_QUIET);
return;
}
} else {
if((argtwo == (char *)NULL) || (argtwo[0] == '\0')) {
/* Fish it out of the first argument, instead. */
argone = parse_slash(argone, &argtwo);
}
obj = resolve_object(player, cause, argone,
(!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY
: RSLV_EXITS));
if(obj == -1)
return;
}
if (!exists_object(obj)) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player, "No such object.", NOT_QUIET);
return;
}
if (!isVISUAL(obj) && !controls(player, cause, obj)
&& !econtrols(player, cause, obj)) {
if(!(switches & EXAMINE_ATTRS)) {
/* Use look_thing(), even for exits, because we don't want TRANSPARENT. */
look_thing(player, cause, obj, 1);
/* Owner */
if ((get_int_elt(obj, OWNER, &num) != -1) &&
(get_str_elt(num, NAME, &name) != -1)) {
snprintf(buf, sizeof(buf), "Owner: %s", name);
notify_player(player, cause, player, buf, 0);
} else
notify_player(player, cause, player, "Owner: ???", 0);
} else
notify_player(player, cause, player, "Permission denied.", 0);
return;
}
/* name */
notify_player(player, cause, player, display_name(player, cause, obj), 0);
if(switches & EXAMINE_ATTRS) {
/* attributes */
if (!(switches & EXAMINE_PARENT)) {
display_attributes(player, cause, obj, argtwo, (switches & EXAMINE_SORT));
} else {
display_attributes_parent(player, cause, obj, argtwo,
(switches & EXAMINE_SORT));
}
return;
}
/* flags */
display_flags(player, cause, obj);
/* Owner */
if ((get_int_elt(obj, OWNER, &num) != -1) &&
(get_str_elt(num, NAME, &name) != -1)) {
snprintf(buf, sizeof(buf), "Owner: %s ", name);
} else {
strcpy(buf, "Owner: ??? ");
}
/* pennies */
if (mudconf.enable_money && has_pennies(obj)) {
register char *str, chr;
if(mudconf.money_pennies[0]) {
chr = to_upper(mudconf.money_pennies[0]);
str = &mudconf.money_pennies[1];
} else {
chr = 'M';
str = "oney";
}
if (get_int_elt(obj, PENNIES, &num) != -1) {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf),
" %c%s: %d", chr, str, num);
} else {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf),
" %c%s: ???", chr, str);
}
}
notify_player(player, cause, player, buf, 0);
/* charges, semaphores, cost, queue */
if(get_int_elt(obj, CHARGES, &num) != -1) {
if(num >= 0) {
snprintf(buf, sizeof(buf), "Charges: %d", num);
} else {
strcpy(buf, "Charges: *NOT CHARGED*");
}
} else {
strcpy(buf, "Charges: ???");
}
if(get_int_elt(obj, SEMAPHORES, &num) != -1) {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf),
" Semaphores: %d", num);
} else {
strcat(buf, " Semaphores: ???");
}
if(mudconf.enable_money) {
if(get_int_elt(obj, COST, &num) != -1) {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), " Cost: %d", num);
} else {
strcat(buf, " Cost: ???");
}
}
if(isWIZARD(player) && isPLAYER(obj)) {
if(get_int_elt(obj, QUEUE, &num) != -1) {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf),
" Queue: %d", num);
} else {
strcat(buf, " Queue: ???");
}
}
notify_player(player, cause, player, buf, 0);
if (get_int_elt(obj, TIMESTAMP, (int *) ×tamp) != -1) {
if (isPLAYER(obj)) {
strftime(buf, sizeof(buf),
"Last login: %a %b %e %H:%M:%S %Z %Y", localtime(×tamp));
} else {
strftime(buf, sizeof(buf),
"Timestamp: %a %b %e %H:%M:%S %Z %Y", localtime(×tamp));
}
notify_player(player, cause, player, buf, 0);
}
if (get_int_elt(obj, CREATESTAMP, (int *) ×tamp) != -1) {
strftime(buf, sizeof(buf),
"Created: %a %b %e %H:%M:%S %Z %Y", localtime(×tamp));
if (get_int_elt(obj, USES, &num) != -1) {
snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf),
" Use count: %d", num);
notify_player(player, cause, player, buf, 0);
}
}
/* attributes */
if (!(switches & EXAMINE_PARENT)) {
display_attributes(player, cause, obj, argtwo, (switches & EXAMINE_SORT));
} else {
display_attributes_parent(player, cause, obj, argtwo,
(switches & EXAMINE_SORT));
}
if (Typeof(obj) != TYP_EXIT) {
/* home and dropto are the same. */
if (get_int_elt(obj, HOME, &num) != -1) {
switch (Typeof(obj)) {
case TYP_ROOM:
strcpy(buf, "Dropto: ");
msg = (num == -3) ? "*HOME*" : "None.";
break;
case TYP_THING:
case TYP_PLAYER:
strcpy(buf, "Home: ");
msg = "Does not exist!";
break;
}
if (exists_object(num)) {
strcat(buf, display_name(player, cause, num));
} else {
strcat(buf, msg);
}
notify_player(player, cause, player, buf, 0);
}
} else { /* exit destinations */
if(get_array_elt(obj, DESTS, &dests) != -1) {
register int indx;
if(dests == (int *)NULL) {
notify_player(player, cause, player, "Destination: *UNLINKED*", 0);
} else if(dests[0] == 1) {
if(exists_object(dests[1])) {
snprintf(buf, sizeof(buf), "Destination: %s",
display_name(player, cause, dests[1]));
notify_player(player, cause, player, buf, 0);
} else if(dests[1] == -3) {
strcpy(buf, "Destination: *HOME*");
} else {
snprintf(buf, sizeof(buf), "Destination: *BAD OBJECT #%d*",
dests[1]);
}
} else {
for(indx = 1; indx <= dests[0]; indx++) {
if(exists_object(dests[indx])) {
snprintf(buf, sizeof(buf), "Destination %d: %s", indx,
display_name(player, cause, dests[indx]));
notify_player(player, cause, player, buf, 0);
} else if(dests[indx] == -3) {
snprintf(buf, sizeof(buf), "Destination %d: *HOME*", indx);
} else {
snprintf(buf, sizeof(buf), "Destination %d: *BAD OBJECT #%d*",
indx, dests[indx]);
}
}
}
}
}
/* location */
if (get_int_elt(obj, LOC, &num) != -1) {
if (exists_object(num)) {
snprintf(buf, sizeof(buf), "Location: %s",
display_name(player, cause, num));
} else {
snprintf(buf, sizeof(buf), "Location: *BAD OBJECT #%d*", num);
}
notify_player(player, cause, player, buf, 0);
}
/* parent */
if (get_int_elt(obj, PARENT, &num) != -1) {
if (num != -1) {
if (exists_object(num)) {
snprintf(buf, sizeof(buf), "Parent: %s",
display_name(player, cause, num));
} else {
snprintf(buf, sizeof(buf), "Parent: *BAD OBJECT #%d*", num);
}
notify_player(player, cause, player, buf, 0);
}
}
if (has_contents(obj)) {
/* contents list */
if (get_int_elt(obj, CONTENTS, &num) != -1) {
if (num != -1) {
switch(Typeof(obj)) {
case TYP_ROOM:
notify_player(player, cause, player, "Contents:", 0);
break;
case TYP_PLAYER:
notify_player(player, cause, player, "Carrying:", 0);
break;
default:
notify_player(player, cause, player, "Containing:", 0);
break;
}
notify_list(player, cause, player, num, NOT_DARKOK);
} else {
notify_player(player, cause, player, "No contents.", 0);
}
}
}
if (has_exits(obj)) {
/* exits list */
if (get_int_elt(obj, EXITS, &num) != -1) {
if (num != -1) {
notify_player(player, cause, player, "Exits:", 0);
notify_list(player, cause, player, num, NOT_DARKOK);
} else {
notify_player(player, cause, player, "No exits.", 0);
}
}
}
if (has_rooms(obj) && (switches & EXAMINE_ROOMS)
&& (get_int_elt(obj, ROOMS, &num) != -1)) {
if (num != -1) {
notify_player(player, cause, player, "Rooms:", 0);
notify_list(player, cause, player, num, NOT_DARKOK);
} else {
notify_player(player, cause, player, "No rooms.", 0);
}
}
}
VOID do_inventory(player, cause, switches)
int player, cause, switches;
{
register int header = 0;
int list;
if (get_int_elt(player, CONTENTS, &list) != -1) {
if (list != -1) {
notify_player(player, cause, player, "You are carrying:", 0);
header++;
if (mudconf.compact_contents) {
notify_list2(player, cause, player, list, NOT_DARKOK);
} else {
notify_list(player, cause, player, list, NOT_DARKOK);
}
}
}
if (get_int_elt(player, EXITS, &list) != -1) {
if (list != -1) {
if (!header) {
notify_player(player, cause, player, "You are carrying:", 0);
header++;
}
if (mudconf.compact_contents) {
notify_list2(player, cause, player, list, NOT_DARKOK);
} else {
notify_list(player, cause, player, list, NOT_DARKOK);
}
}
}
if (!header)
notify_player(player, cause, player, "You aren't carrying anything.", 0);
if (mudconf.enable_money)
do_score(player, cause, switches);
}
/* look at an exit */
void look_exit(player, cause, exit, quiet)
int player, cause, exit, quiet;
{
int *dests, curd;
if (!can_hear(player))
return;
if(isTRANSPARENT(exit)) {
int eowner;
if(get_array_elt(exit, DESTS, &dests) == -1) {
logfile(LOG_ERROR, "look_exit: bad dests element on object #%d\n", exit);
notify_bad(player);
return;
}
if(get_int_elt(exit, OWNER, &eowner) == -1) {
logfile(LOG_ERROR, "look_exit: bad owner on object #%d\n", exit);
notify_bad(player);
return;
}
if(dests != (int *)NULL) {
for(curd = 1; curd <= dests[0]; curd++) {
if(!isEXIT(dests[curd])) {
int owner;
if(get_int_elt(dests[curd], OWNER, &owner) == -1) {
logfile(LOG_ERROR, "look_exit: bad owner on object #%d\n",
dests[curd]);
notify_bad(player);
return;
}
if((owner == eowner) || isVISUAL(dests[curd])) {
stamp(exit, STAMP_USED);
look_thing(player, cause, dests[curd], 1);
return;
}
}
}
}
}
stamp(exit, STAMP_USED);
if(controls(player, cause, exit) || isVISUAL(exit))
notify_player(player, cause, player,
display_name(player, cause, exit), 0);
if(has_html(player))
html_desc(player, cause, exit);
act_object(player, cause, exit, DESC, (quiet) ? (char *) NULL : ODESC,
ADESC, -1, "You see nothing special.", (char *) NULL);
}
/* look at a thing */
void look_thing(player, cause, thing, quiet)
int player, cause, thing, quiet;
{
int contents;
if (!can_hear(player))
return;
stamp(thing, STAMP_USED);
if(controls(player, cause, thing) || isVISUAL(thing))
notify_player(player, cause, player,
display_name(player, cause, thing), 0);
if(has_html(player))
html_desc(player, cause, thing);
act_object(player, cause, thing, DESC, (quiet) ? (char *) NULL : ODESC,
ADESC, -1, "You see nothing special.", (char *) NULL);
if (!has_contents(thing) || isOPAQUE(thing)
|| (get_int_elt(thing, CONTENTS, &contents) == -1))
return;
if (contents != -1) {
if (can_see_anything(player, cause, thing)) {
switch (Typeof(thing)) {
case TYP_ROOM:
notify_player(player, cause, player, "Contents:", 0);
break;
case TYP_PLAYER:
notify_player(player, cause, player, "Carrying:", 0);
break;
default:
notify_player(player, cause, player, "Containing:", 0);
break;
}
if (mudconf.compact_contents) {
notify_list2(player, cause, player, contents, 0);
} else {
notify_list(player, cause, player, contents, 0);
}
}
}
}
/* look at location */
void look_location(player, cause, quiet)
int player, cause, quiet;
{
int here, contents, exits;
if (!can_hear(player))
return;
if ((get_int_elt(player, LOC, &here) == -1) || !exists_object(here)) {
if(!quiet)
notify_player(player, cause, player, "You have no location!", NOT_QUIET);
return;
}
stamp(here, STAMP_USED);
notify_player(player, cause, player, display_name(player, cause, here), 0);
if(has_html(player))
html_desc(player, cause, here);
act_object(player, cause, here, (isROOM(here)) ? DESC : IDESC, ODESC,
ADESC, -1, (char *) NULL, (char *) NULL);
if (isROOM(here)) {
act_object(player, cause, here, IDESC, (char *) NULL, (char *) NULL,
-1, (char *) NULL, (char *) NULL);
if (islocked(player, cause, here, LOCK)) {
act_object(player, cause, here, FAIL, OFAIL, AFAIL, -1, (char *) NULL,
(char *) NULL);
} else {
act_object(player, cause, here, SUC, OSUC, ASUC, -1, (char *) NULL,
(char *) NULL);
}
}
if (has_contents(here) && can_see_anything(player, cause, here)) {
if (get_int_elt(here, CONTENTS, &contents) == -1) {
logfile(LOG_ERROR,
"look_location: bad contents reference on object #%d\n", here);
return;
}
notify_player(player, cause, player, "Contents:", 0);
if (mudconf.compact_contents) {
notify_list2(player, cause, player, contents, 0);
} else {
notify_list(player, cause, player, contents, 0);
}
}
if (has_exits(here)) {
if (get_int_elt(here, EXITS, &exits) == -1) {
logfile(LOG_ERROR, "look_location: bad exits reference on object #%d\n",
here);
return;
}
notify_exits(player, cause, player, exits);
}
}
/* Returns 1 if the player can see anything, 0 otherwise. */
int can_see_anything(player, cause, location)
int player, cause, location;
{
int list, contents;
if (location == -1) {
/* get their location */
if ((get_int_elt(player, LOC, &location) == -1) ||
!exists_object(location)) {
logfile(LOG_ERROR,
"can_see_anything: couldn't get location of player #%d\n",
player);
notify_bad(player);
return (0);
}
}
if (get_int_elt(location, CONTENTS, &contents) == -1) {
logfile(LOG_ERROR, "can_see_anything: bad contents reference on #%d\n",
location);
notify_bad(player);
return (0);
}
if (contents == player) {
int foo;
if (get_int_elt(player, NEXT, &foo) == -1) {
logfile(LOG_ERROR, "can_see_anything: bad next reference on #%d\n",
player);
notify_bad(player);
return (0);
}
if (foo == -1)
return (0);
}
/* still here... hmm... loop through list. */
list = contents;
while (list != -1) {
if (can_see(player, cause, list))
return (1);
if (get_int_elt(list, NEXT, &list) == -1) {
logfile(LOG_ERROR, "can_see_anything: bad next reference on #%d\n", list);
notify_bad(player);
return (0);
}
}
/* they cannot see a damn thing! */
return (0);
}
/* Returns a 1 if player can see that specific object, 0 otherwise. */
int can_see(player, cause, obj)
int player, cause, obj;
{
int loc, owner;
if (player == obj)
return (0);
if (mudconf.dark_sleep && isPLAYER(obj) && !isALIVE(obj))
return (0);
if (isROOM(obj))
return (0); /* wee... */
if ((get_int_elt(obj, LOC, &loc) == -1) || !exists_object(loc)) {
logfile(LOG_ERROR, "can_see: couldn't get location of object #%d\n", obj);
return (0);
}
if (isDARK(loc)) {
if (isLIGHT(obj))
return(1);
if (get_int_elt(obj, OWNER, &owner) == -1) {
logfile(LOG_ERROR, "can_see: bad owner reference on object #%d\n", obj);
return (0);
}
/* this is so a wizz won't see so much junk in a dark room. */
if (owner != player)
return (0);
}
if (!isDARK(obj))
return (1);
if (isDARK(obj) && controls(player, cause, obj))
return (1);
return (0);
}
VOID do_use(player, cause, switches, argone)
int player, cause, switches;
char *argone;
{
int obj;
if((argone == (char *)NULL) || (argone[0] == '\0')) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player, "But what do you want to use?",
NOT_QUIET);
return;
}
obj = resolve_object(player, cause, argone,
(!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY
: RSLV_EXITS));
if(obj == -1)
return;
if(islocked(player, cause, obj, ULOCK)) {
if(!(switches & CMD_QUIET))
notify_player(player, cause, player, "You can't use that.", NOT_QUIET);
return;
}
act_object(player, cause, obj, USE, OUSE, AUSE, -1,
"There is no obvious way to use that.", (char *)NULL);
}