AwakeMUD-0.51Beta/area/
AwakeMUD-0.51Beta/doc/
AwakeMUD-0.51Beta/lib/
AwakeMUD-0.51Beta/lib/etc/
AwakeMUD-0.51Beta/lib/fixer_data/
AwakeMUD-0.51Beta/lib/misc/
AwakeMUD-0.51Beta/lib/plrobjs/
AwakeMUD-0.51Beta/lib/plrobjs/A-E/
AwakeMUD-0.51Beta/lib/plrobjs/K-O/
AwakeMUD-0.51Beta/lib/plrobjs/U-Z/
AwakeMUD-0.51Beta/lib/plrspells/A-E/
AwakeMUD-0.51Beta/lib/plrtext/A-E/
AwakeMUD-0.51Beta/lib/world/
AwakeMUD-0.51Beta/lib/world/mob/
AwakeMUD-0.51Beta/lib/world/obj/
AwakeMUD-0.51Beta/lib/world/qst/
AwakeMUD-0.51Beta/lib/world/shp/
AwakeMUD-0.51Beta/lib/world/wld/
AwakeMUD-0.51Beta/lib/world/zon/
//  file: dblist.cc
//  authors: Chris Dickey, Andrew Hynek
//  purpose: contains the ObjList functions
//  Copyright (c) 1996 by Chris Dickey,
//  some parts Copyright (c) 1998 by Andrew Hynek

#include <stdio.h>

#include "structs.h"
#include "awake.h"
#include "comm.h"
#include "db.h"
#include "utils.h"
#include "dblist.h"
#include "handler.h"

// extern vars
extern struct room_data *world;

// extern funcs
extern void print_object_location(int, struct obj_data *, struct char_data *, int);
extern int isname(char *str, char *namelist);

int objList::PrintList(struct char_data *ch, const char *arg)
{
  register nodeStruct<struct obj_data *> *temp = head, *next;
  register int num = 0;
  bool ground = FALSE;

  ground = !strcmp( arg, "ground" );

  while (temp) {
    next = temp->next;
    if (!temp->data->name) {
      if (temp->data->item_number) {
        sprintf(buf, "Object #%d has no name.", temp->data->item_number);
        log(buf);
      } else {
        log("Object with no name and no number...deleting from list:");
        sprintf(buf, "#:%d, R:%d, T:%d, W:%d, E:%d, Wt:%d, C:%d\n"
                "M:%d, B:%d, Sd:%s, D:%s, Ld:%s\r\n"
                "0:%d, 1:%d, 2:%d, 3:%d, 4:%d, 5:%d, 6:%d, 7:%d, 8:%d, 9:%d\r\n",
                temp->data->item_number, temp->data->in_room,
                GET_OBJ_TYPE(temp->data), GET_OBJ_WEAR(temp->data),
                GET_OBJ_EXTRA(temp->data), GET_OBJ_WEIGHT(temp->data),
                GET_OBJ_COST(temp->data), GET_OBJ_MATERIAL(temp->data),
                GET_OBJ_BARRIER(temp->data), temp->data->short_description,
                temp->data->description, temp->data->long_description,
                GET_OBJ_VAL(temp->data, 0), GET_OBJ_VAL(temp->data, 1),
                GET_OBJ_VAL(temp->data, 2), GET_OBJ_VAL(temp->data, 3),
                GET_OBJ_VAL(temp->data, 4), GET_OBJ_VAL(temp->data, 5),
                GET_OBJ_VAL(temp->data, 6), GET_OBJ_VAL(temp->data, 7),
                GET_OBJ_VAL(temp->data, 8), GET_OBJ_VAL(temp->data, 9));
        log(buf);
        if (temp->data->worn_by)
          act("$p suddenly disappears.", FALSE, temp->data->worn_by,
              temp->data, 0, TO_CHAR);
        else if (temp->data->carried_by)
          act("$p suddenly disappears.", FALSE, temp->data->carried_by,
              temp->data, 0, TO_CHAR);
        else if (temp->data->in_room > 0) {
          sprintf(buf, "%s suddenly disappears.\r\n", temp->data->short_description);
          send_to_room(buf, temp->data->in_room);
        }
        extract_obj(temp->data);
      }
    } else if (CAN_SEE_OBJ(ch, temp->data) 
	       && (isname((char *)arg, temp->data->name)
		   || (ground 
		       && temp->data->carried_by == NULL
		       && temp->data->in_obj == NULL
		       && temp->data->worn_by == NULL
		       && temp->data->in_room > 0
		       && (temp->data->in_room < 320||temp->data->in_room>=421))))
      print_object_location(++num, temp->data, ch, TRUE);

    temp = next;
  }

  return num;
}

void objList::Traverse(void (*func)(struct obj_data *))
{
  for (nodeStruct<struct obj_data *> *temp = head; temp; temp = temp->next)
    func(temp->data);
}

// this function searches through the list and returns a pointer to the
// object whose object rnum matches num
struct obj_data *objList::FindObj(int num)
{
  register nodeStruct<struct obj_data *> *temp;
  for (temp = head; temp; temp = temp->next)
    if (num == GET_OBJ_RNUM(temp->data))
      return temp->data;

  return NULL;
}

// this function searches through the list and returns a pointer to the
// object whose name matches 'name' and who is the 'num'th object in the
// list
struct obj_data *objList::FindObj(struct char_data *ch, char *name, int num)
{
  register struct nodeStruct<struct obj_data *> *temp = head;
  register int i = 0;

  while (temp && (i <= num)) {
    if (isname(name, temp->data->name) && CAN_SEE_OBJ(ch, temp->data) &&
        (++i == num))
      return temp->data;
    temp = temp->next;
  }

  return NULL;
}

// this function updates pointers to this particular prototype--necessary
// for OLC so objects on the mud get updated with the correct values
void objList::UpdateObjs(const struct obj_data *proto, int rnum)
{
  static struct nodeStruct<struct obj_data *> *temp;
  static struct obj_data old;

  for (temp = head; temp; temp = temp->next) {
    if (temp->data->item_number == rnum) {
      old = *temp->data;
      *temp->data = *proto;
      temp->data->in_room = old.in_room;
      temp->data->item_number = rnum;
      temp->data->carried_by = old.carried_by;
      temp->data->worn_by = old.worn_by;
      temp->data->worn_on = old.worn_on;
      temp->data->in_obj = old.in_obj;
      temp->data->contains = old.contains;
      temp->data->next_content = old.next_content;
      temp->data->obj_flags.condition = old.obj_flags.condition;
      if (temp->data->carried_by)
        affect_total(temp->data->carried_by);
      else if (temp->data->worn_by)
        affect_total(temp->data->worn_by);
    }
  }
}

// this function runs through the list and checks the timers of each
// object, extracting them if their timers hit 0
void objList::UpdateCounters(void)
{
  static nodeStruct<struct obj_data *> *temp, *next;

  for (temp = head; temp; temp = next) {
    next = temp->next;

    /* anti-twink measure...no decay until there's no eq in it */
    if ( IS_OBJ_STAT(temp->data, ITEM_CORPSE) && GET_OBJ_VAL(temp->data, 4) == 1
        && temp->data->contains != NULL )
      continue;

    // only corpses and immloaded items usually have timers
    if (IS_OBJ_STAT(temp->data, ITEM_CORPSE) || IS_OBJ_STAT(temp->data, ITEM_IMMLOAD)) {
      if (GET_OBJ_TIMER(temp->data) > 1) {
        GET_OBJ_TIMER(temp->data)--;
      } else {
        if (temp->data->carried_by)
          act("$p decays in your hands.", FALSE, temp->data->carried_by,
              temp->data, 0, TO_CHAR);
        else if (temp->data->worn_by)
          act("$p decays in your hands.", FALSE, temp->data->worn_by,
              temp->data, 0, TO_CHAR);
        else if ((temp->data->in_room != NOWHERE) &&
                 (world[temp->data->in_room].people)) {
          act("$p crumbles into dust.", TRUE, world[temp->data->in_room].people,
              temp->data, 0, TO_ROOM);
          act("$p crumbles into dust.", TRUE, world[temp->data->in_room].people,
              temp->data, 0, TO_CHAR);
        }
        // here we make sure to remove all items from the object
        struct obj_data *next_thing, *temp2;
        for (temp2 = temp->data->contains; temp2; temp2 = next_thing) {
          next_thing = temp2->next_content;     /*Next in inventory */

          if (!(IS_OBJ_STAT(temp->data, ITEM_CORPSE) &&
              !GET_OBJ_VAL(temp->data, 4) && GET_OBJ_TYPE(temp2) != ITEM_MONEY)) {
            obj_from_obj(temp2);
            if (temp->data->in_obj)
              obj_to_obj(temp2, temp->data->in_obj);
            else if (temp->data->carried_by)
              obj_to_room(temp2, temp->data->carried_by->in_room);
            else if (temp->data->worn_by)
              obj_to_room(temp2, temp->data->worn_by->in_room);
            else if (temp->data->in_room != NOWHERE)
              obj_to_room(temp2, temp->data->in_room);
            else assert(FALSE);
          } else extract_obj(temp2);
        }
        next = temp->next;  // just to make sure...
        extract_obj(temp->data);
      }
    }
  }
}

// this function updates the objects in the list whose real numbers are
// greater than num--necessary for olc--but maybe obsolete once the new
// structures come into effect
void objList::UpdateNums(int num)
{
  register nodeStruct<struct obj_data *> *temp;
  // just loop through the list and update
  for (temp = head; temp; temp = temp->next)
    if (GET_OBJ_RNUM(temp->data) >= num)
      GET_OBJ_RNUM(temp->data)++;
}

/* this function goes through each object, and if it has a spec, calls it */
void objList::CallSpec()
{
  nodeStruct<struct obj_data *> *temp;

  for (temp = head; temp; temp = temp->next)
    if (GET_OBJ_SPEC(temp->data) != NULL)
      GET_OBJ_SPEC(temp->data) (NULL, temp->data, 0, "");
}

void objList::RemoveObjs()
{
  nodeStruct<struct obj_data *> *temp = head, *last;

  while (temp) {
    last = temp->next;

    if (from_ip_zone(GET_OBJ_VNUM(temp->data)) ||
        IS_OBJ_STAT(temp->data, ITEM_VOLATILE)) {
      if (temp->data->carried_by
	  && !IS_NPC(temp->data->carried_by)
	  && GET_LEVEL(temp->data->carried_by) < LVL_LEGEND) {
        act("$p decays into nothing.", FALSE, temp->data->carried_by,
            temp->data, 0, TO_CHAR);
        extract_obj(temp->data);
      } else if (temp->data->worn_by && !IS_NPC(temp->data->worn_by) &&
                 GET_LEVEL(temp->data->worn_by) < LVL_LEGEND) {
        act("$p decays into nothing.", FALSE, temp->data->carried_by,
            temp->data, 0, TO_CHAR);
        extract_obj(temp->data);
      }
    }

    temp = last;
  }
}

void objList::RemoveObjNum(int num)
{
  nodeStruct<struct obj_data *> *temp, *next;

  for (temp = head; temp; temp = next) {
    next = temp->next;

    if (GET_OBJ_RNUM(temp->data) == num) {
      if (temp->data->carried_by)
        act("$p disintegrates.", FALSE, temp->data->carried_by,
            temp->data, 0, TO_CHAR);
      else if (temp->data->worn_by)
        act("$p disintegrates.", FALSE, temp->data->carried_by,
            temp->data, 0, TO_CHAR);
      else if (temp->data->in_room != NOWHERE && world[temp->data->in_room].people) {
        act("$p disintegrates.", TRUE, world[temp->data->in_room].people,
            temp->data, 0, TO_ROOM);
        act("$p disintegrates.", TRUE, world[temp->data->in_room].people,
            temp->data, 0, TO_CHAR);
      }
      extract_obj(temp->data);
    }
  }
}

void objList::RemoveQuestObjs(int id)
{
  nodeStruct<struct obj_data *> *temp, *next;

  for (temp = head; temp; temp = next) {
    next = temp->next;

    if (temp->data->obj_flags.quest_id == id)
      extract_obj(temp->data);
  }
}