Пример #1
0
void perform_mob_flag_list(struct char_data * ch, char *arg)
{
  int num, mob_flag, found = 0, len;
  struct char_data *mob;
  char buf[MAX_STRING_LENGTH];

  mob_flag = atoi(arg);

  if (mob_flag < 0 || mob_flag > NUM_MOB_FLAGS) {
    send_to_char(ch, "Invalid flag number!\r\n");
    return;
  }

  len = snprintf(buf, sizeof(buf), "Listing mobiles with %s%s%s flag set.\r\n", QYEL, action_bits[mob_flag], QNRM);

  for(num=0;num<=top_of_mobt;num++) {
    if(IS_SET_AR((mob_proto[num].char_specials.saved.act), mob_flag)) {

      if ((mob = read_mobile(num, REAL)) != NULL) {
        char_to_room(mob, 0);
        len += snprintf(buf + len, sizeof(buf) - len, "%s%3d. %s[%s%5d%s]%s Level %s%-3d%s %s%s\r\n", CCNRM(ch, C_NRM),++found,
                      CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_MOB_VNUM(mob), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM),
                      CCYEL(ch, C_NRM), GET_LEVEL(mob), CCNRM(ch, C_NRM), GET_NAME(mob), CCNRM(ch, C_NRM));
        extract_char(mob); /* Finished with the mob - remove it from the MUD */
        if (len > sizeof(buf))
		  break;
      }
    }
  }
  if (!found)
    send_to_char(ch,"None Found!\r\n");
  else
    page_string(ch->desc, buf, TRUE);
  return;
}
Пример #2
0
void perform_mob_level_list(struct char_data * ch, char *arg)
{
  int num, mob_level, found = 0, len;
  struct char_data *mob;
  char buf[MAX_STRING_LENGTH];

  mob_level = atoi(arg);

  if (mob_level < 0 || mob_level > 99) {
    send_to_char(ch, "Invalid mob level!\r\n");
    return;
  }

  len = snprintf(buf, sizeof(buf), "Listing mobiles of level %s%d%s\r\n", QYEL, mob_level, QNRM);
  for(num=0;num<=top_of_mobt;num++) {
    if((mob_proto[num].player.level) == mob_level) {

      if ((mob = read_mobile(num, REAL)) != NULL) {
        char_to_room(mob, 0);
        len += snprintf(buf + len, sizeof(buf) - len, "%s%3d. %s[%s%5d%s]%s %s%s\r\n", CCNRM(ch, C_NRM),++found,
                      CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_MOB_VNUM(mob), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM),
                      GET_NAME(mob), CCNRM(ch, C_NRM));
        extract_char(mob); /* Finished with the mob - remove it from the MUD */
        if (len > sizeof(buf))
		  break;
      }
    }
  }
  if (!found)
    send_to_char(ch,"None Found!\r\n");
  else
    page_string(ch->desc, buf, TRUE);

  return;
}
Пример #3
0
void quest_list(struct char_data *ch, struct char_data *qm, char argument[MAX_INPUT_LENGTH])
{
  qst_vnum vnum;
  qst_rnum rnum;

  if ((vnum = find_quest_by_qmnum(ch, GET_MOB_VNUM(qm), atoi(argument))) == NOTHING)
    send_to_char(ch, "That is not a valid quest!\r\n");
  else if ((rnum = real_quest(vnum)) == NOTHING)
    send_to_char(ch, "That is not a valid quest!\r\n");
  else if (QST_INFO(rnum)) {
    send_to_char(ch,"Complete Details on Quest %d \tc%s\tn:\r\n%s",
                      vnum,
         QST_DESC(rnum),
         QST_INFO(rnum));
    if (QST_PREV(rnum) != NOTHING)
      send_to_char(ch, "You have to have completed quest %s first.\r\n",
          QST_NAME(real_quest(QST_PREV(rnum))));
    if (QST_TIME(rnum) != -1)
      send_to_char(ch,
         "There is a time limit of %d turn%s to complete the quest.\r\n",
          QST_TIME(rnum),
          QST_TIME(rnum) == 1 ? "" : "s");
  } else
    send_to_char(ch, "There is no further information on that quest.\r\n");
}
Пример #4
0
void quest_join(struct char_data *ch, struct char_data *qm, char argument[MAX_INPUT_LENGTH])
{
  qst_vnum vnum;
  qst_rnum rnum;
  char buf[MAX_INPUT_LENGTH];

  if (!*argument)
    snprintf(buf, sizeof(buf),
             "%s What quest did you wish to join?", GET_NAME(ch));
  else if (GET_QUEST(ch) != NOTHING)
    snprintf(buf, sizeof(buf),
             "%s But you are already part of a quest!", GET_NAME(ch));
  else if((vnum = find_quest_by_qmnum(ch, GET_MOB_VNUM(qm), atoi(argument))) == NOTHING)
    snprintf(buf, sizeof(buf),
             "%s I don't know of such a quest!", GET_NAME(ch));
  else if ((rnum = real_quest(vnum)) == NOTHING)
    snprintf(buf, sizeof(buf),
             "%s I don't know of such a quest!", GET_NAME(ch));
  else if (GET_LEVEL(ch) < QST_MINLEVEL(rnum))
    snprintf(buf, sizeof(buf),
             "%s You are not experienced enough for that quest!", GET_NAME(ch));
  else if (GET_LEVEL(ch) > QST_MAXLEVEL(rnum))
    snprintf(buf, sizeof(buf),
             "%s You are too experienced for that quest!", GET_NAME(ch));
  else if (is_complete(ch, vnum))
    snprintf(buf, sizeof(buf),
             "%s You have already completed that quest!", GET_NAME(ch));
  else if ((QST_PREV(rnum) != NOTHING) && !is_complete(ch, QST_PREV(rnum)))
    snprintf(buf, sizeof(buf),
             "%s That quest is not available to you yet!", GET_NAME(ch));
  else if ((QST_PREREQ(rnum) != NOTHING) &&
           (real_object(QST_PREREQ(rnum)) != NOTHING) &&
           (get_obj_in_list_num(real_object(QST_PREREQ(rnum)),
       ch->carrying) == NULL))
    snprintf(buf, sizeof(buf),
             "%s You need to have %s first!", GET_NAME(ch),
      obj_proto[real_object(QST_PREREQ(rnum))].short_description);
  else {
    act("You join the quest.",    TRUE, ch, NULL, NULL, TO_CHAR);
    act("$n has joined a quest.", TRUE, ch, NULL, NULL, TO_ROOM);
    snprintf(buf, sizeof(buf),
             "%s Listen carefully to the instructions.", GET_NAME(ch));
    do_tell(qm, buf, cmd_tell, 0);
    set_quest(ch, rnum);
    send_to_char(ch, "%s", QST_INFO(rnum));
    if (QST_TIME(rnum) != -1)
      snprintf(buf, sizeof(buf),
        "%s You have a time limit of %d turn%s to complete the quest.",
        GET_NAME(ch), QST_TIME(rnum), QST_TIME(rnum) == 1 ? "" : "s");
    else
      snprintf(buf, sizeof(buf),
        "%s You can take however long you want to complete the quest.",
 GET_NAME(ch));
  }
  do_tell(qm, buf, cmd_tell, 0);
  save_char(ch);
}
Пример #5
0
void extract_mobile_all(mob_vnum vnum)
{
  struct char_data *next, *ch;

  for (ch = character_list; ch; ch = next) {
    next = ch->next;
    if (GET_MOB_VNUM(ch) == vnum)
      extract_char(ch);
  }
}
Пример #6
0
/* attaches mob's name and vnum to msg and sends it to script_log */
void mob_log(char_data *mob, char *msg)
{
    char buf[MAX_INPUT_LENGTH + 100];

    void script_log(char *msg);

    sprintf(buf, "Mob (%s, VNum %d): %s",
	             GET_SHORT(mob), GET_MOB_VNUM(mob), msg);
    script_log(buf);
}
Пример #7
0
/**
* WARNING: This function actually deletes a mobile from the world.
*
* @param char_data *ch The person doing the deleting.
* @param mob_vnum vnum The vnum to delete.
*/
void olc_delete_mobile(char_data *ch, mob_vnum vnum) {	
	void extract_pending_chars();
	void remove_mobile_from_table(char_data *mob);
	
	char_data *proto, *mob_iter, *next_mob;
	descriptor_data *desc;
	struct global_data *glb, *next_glb;
	room_template *rmt, *next_rmt;
	sector_data *sect, *next_sect;
	crop_data *crop, *next_crop;
	bld_data *bld, *next_bld;
	bool found;
	
	if (!(proto = mob_proto(vnum))) {
		msg_to_char(ch, "There is no such mobile %d.\r\n", vnum);
		return;
	}
	
	if (HASH_COUNT(mobile_table) <= 1) {
		msg_to_char(ch, "You can't delete the last mob.\r\n");
		return;
	}
		
	// remove mobs from the list: DO THIS FIRST
	for (mob_iter = character_list; mob_iter; mob_iter = next_mob) {
		next_mob = mob_iter->next;
		
		if (IS_NPC(mob_iter)) {
			if (GET_MOB_VNUM(mob_iter) == vnum) {
				// this is the removed mob
				act("$n has been deleted.", FALSE, mob_iter, NULL, NULL, TO_ROOM);
				extract_char(mob_iter);
			}
		}
	}
	// their data will already be free, so we need to clear them out now
	extract_pending_chars();
	
	// pull from hash ONLY after removing from the world
	remove_mobile_from_table(proto);

	// save mob index and mob file now so there's no trouble later
	save_index(DB_BOOT_MOB);
	save_library_file_for_vnum(DB_BOOT_MOB, vnum);
	
	// update buildings
	HASH_ITER(hh, building_table, bld, next_bld) {
		found = delete_mob_from_spawn_list(&GET_BLD_SPAWNS(bld), vnum);
		found |= delete_from_interaction_list(&GET_BLD_INTERACTIONS(bld), TYPE_MOB, vnum);
		if (found) {
			save_library_file_for_vnum(DB_BOOT_BLD, GET_BLD_VNUM(bld));
		}
	}
Пример #8
0
/* attaches mob's name and vnum to msg and sends it to script_log */
void mob_log(char_data *mob, const char *format, ...)
{
  va_list args;
  char output[MAX_STRING_LENGTH];
    
  snprintf(output, sizeof(output), "Mob (%s, VNum %d):: %s", 
                   GET_SHORT(mob), GET_MOB_VNUM(mob), format);

  va_start(args, format);
  script_vlog(output, args);
  va_end(args);
}
Пример #9
0
/**
* For the .list command.
*
* @param char_data *mob The thing to list.
* @param bool detail If TRUE, provide additional details
* @return char* The line to show (without a CRLF).
*/
char *list_one_mobile(char_data *mob, bool detail) {
	static char output[MAX_STRING_LENGTH];
	char flags[MAX_STRING_LENGTH];
	
	bitvector_t show_flags = MOB_BRING_A_FRIEND | MOB_SENTINEL | MOB_AGGRESSIVE | MOB_MOUNTABLE | MOB_ANIMAL | MOB_AQUATIC | MOB_NO_ATTACK | MOB_SPAWNED | MOB_CHAMPION | MOB_FAMILIAR | MOB_EMPIRE | MOB_CITYGUARD | MOB_GROUP | MOB_HARD | MOB_DPS | MOB_TANK | MOB_CASTER | MOB_VAMPIRE | MOB_HUMAN;
	
	if (detail) {
		if (IS_SET(MOB_FLAGS(mob), show_flags)) {
			sprintbit(MOB_FLAGS(mob) & show_flags, action_bits, flags, TRUE);
		}
		else {
			*flags = '\0';
		}
		
		snprintf(output, sizeof(output), "[%5d] %s (%s) %s", GET_MOB_VNUM(mob), GET_SHORT_DESC(mob), level_range_string(GET_MIN_SCALE_LEVEL(mob), GET_MAX_SCALE_LEVEL(mob), 0), flags);
	}
	else {
		snprintf(output, sizeof(output), "[%5d] %s", GET_MOB_VNUM(mob), GET_SHORT_DESC(mob));
	}
	
	return output;
}
Пример #10
0
/* Used by Peter the captain of the royal guard */
int member_of_royal_guard(struct char_data * chChar)
{
  int ch_num;

  if (!chChar || !IS_NPC(chChar))
    return FALSE;

  ch_num = GET_MOB_VNUM(chChar);
  return (ch_num == CASTLE_ITEM(3) ||
	  ch_num == CASTLE_ITEM(6) ||
	  (ch_num > CASTLE_ITEM(7) && ch_num < CASTLE_ITEM(12)) ||
	  (ch_num > CASTLE_ITEM(23) && ch_num < CASTLE_ITEM(26)));
}
Пример #11
0
/* Used mainly by BANZAI:ng NPC:s */
int member_of_staff(struct char_data * chChar)
{
  int ch_num;

  if (!IS_NPC(chChar))
    return (FALSE);

  ch_num = GET_MOB_VNUM(chChar);
  return (ch_num == CASTLE_ITEM(1) ||
	  (ch_num > CASTLE_ITEM(2) && ch_num < CASTLE_ITEM(15)) ||
	  (ch_num > CASTLE_ITEM(15) && ch_num < CASTLE_ITEM(18)) ||
	  (ch_num > CASTLE_ITEM(18) && ch_num < CASTLE_ITEM(30)));
}
Пример #12
0
void do_mob_report (struct char_data *ch)
{
	struct char_data *mob; 
	FILE *reportfile; 
	int i;

	if (!(reportfile = fopen("report.mob", "w"))) {
		mlog("SYSERR:  Mob report file unavailable.");
		send_to_char ("Report.mob could not be generated.\r\n",ch);
		return;
	}
	sprintf(buf, "MOBS\n----\n");
	for (i=0; i<top_of_mobt;i++) {
		mob=read_mobile(i, REAL);
		char_to_room(mob, 0);
		sprintf(buf+strlen(buf), "[%5d] %s  Spec Proc: ",
		GET_MOB_VNUM(mob), GET_NAME(mob));

		if (mob_index[GET_MOB_RNUM(mob)].func!=NULL)
			get_spec_name(GET_MOB_RNUM(mob), buf2,'m');
		else sprintf(buf2, "none"); 
		sprintf(buf+strlen(buf), "%s\n",buf2);

		sprintf(buf+strlen(buf),mob->player.description);
		sprintf(buf+strlen(buf),"Difficulty: %d   XP: %d  HP: %d  Mana: %d  Gold %d\n",
		GET_DIFFICULTY(mob), GET_EXP(mob), GET_MAX_HIT(mob), GET_MAX_MANA(mob), GET_GOLD(mob));
		sprintf(buf+strlen(buf),"Passive Defense: %d   Damage Reduction: %d  ", 
		GET_PD(mob), GET_REDUCTION(mob));
		sprintf(buf+strlen(buf), "Attack Type: %s\n",
		attack_hit_text[mob->mob_specials.attack_type].singular);

		sprintbit(MOB_FLAGS(mob), action_bits, buf2, sizeof(buf2));
		sprintf(buf+strlen(buf),"Flags:  %s\n", buf2);

		sprintbit(AFF_FLAGS(mob), affected_bits, buf2, sizeof(buf2));
		sprintf(buf+strlen(buf),"Affects:  %s\n\n-------\n", buf2);
		extract_char(mob);
		fprintf(reportfile, buf);
		buf[0]='\0';
	}/*for i=0...*/
	fclose (reportfile);
	send_to_char ("report.mob printed\r\n",ch);
}
Пример #13
0
/* Function: member_of_royal_guard. Returns TRUE if the character is a guard on
 * duty, otherwise FALSE. Used by Peter the captain of the royal guard. */
int member_of_royal_guard(struct char_data *chChar)
{
  int ch_num;

  if (!chChar || !IS_NPC(chChar))
    return (FALSE);

  ch_num = GET_MOB_VNUM(chChar);

  if (ch_num == castle_virtual(3) || ch_num == castle_virtual(6))
    return (TRUE);

  if (ch_num > castle_virtual(7) && ch_num < castle_virtual(12))
    return (TRUE);

  if (ch_num > castle_virtual(23) && ch_num < castle_virtual(26))
    return (TRUE);

  return (FALSE);
}
Пример #14
0
static void extract_mobile_all(mob_vnum vnum)
{
  struct char_data *next, *ch;
  int i;

  for (ch = character_list; ch; ch = next) {
    next = ch->next;
    if (GET_MOB_VNUM(ch) == vnum) {
			if ((i = GET_MOB_RNUM(ch)) != NOBODY) {
	    if (ch->player.name && ch->player.name != mob_proto[i].player.name)
          free(ch->player.name);
				ch->player.name = NULL;
				
        if (ch->player.title && ch->player.title != mob_proto[i].player.title)
          free(ch->player.title);
				ch->player.title = NULL;
				
        if (ch->player.short_descr && ch->player.short_descr != mob_proto[i].player.short_descr)
          free(ch->player.short_descr);
				ch->player.short_descr = NULL;
				
        if (ch->player.long_descr && ch->player.long_descr != mob_proto[i].player.long_descr)
          free(ch->player.long_descr);
				ch->player.long_descr = NULL;
				
        if (ch->player.description && ch->player.description != mob_proto[i].player.description)
          free(ch->player.description);
				ch->player.description = NULL;
    
        /* free script proto list if it's not the prototype */
        if (ch->proto_script && ch->proto_script != mob_proto[i].proto_script)
          free_proto_script(ch, MOB_TRIGGER);			
				ch->proto_script = NULL;
			}
      extract_char(ch);
		}
  }
}
Пример #15
0
/* Routine: member_of_staff. Used to see if a character is a member of the 
 * castle staff. Used mainly by BANZAI:ng NPC:s. */
int member_of_staff(struct char_data *chChar)
{
  int ch_num;

  if (!IS_NPC(chChar))
    return (FALSE);

  ch_num = GET_MOB_VNUM(chChar);

  if (ch_num == castle_virtual(1))
    return (TRUE);

  if (ch_num > castle_virtual(2) && ch_num < castle_virtual(15))
    return (TRUE);

  if (ch_num > castle_virtual(15) && ch_num < castle_virtual(18))
    return (TRUE);

  if (ch_num > castle_virtual(18) && ch_num < castle_virtual(30))
    return (TRUE);

  return (FALSE);
}
Пример #16
0
void write_mobs_to_disk(int zone)
{
    int counter, realcounter;
    FILE *fp;
    struct char_data *mob;
    zone = real_zone(zone);
    int i;

    // ideally, this would just fill a VTable with vals...maybe one day

    sprintf(buf, "%s/%d.mob", MOB_PREFIX, zone_table[zone].number);
    fp = fopen(buf, "w+");

    /* start running through all mobiles in this zone */
    for (counter = zone_table[zone].number * 100;
            counter <= zone_table[zone].top;
            counter++) {
        /* write mobile to disk */
        realcounter = real_mobile(counter);

        if (realcounter >= 0) {
            mob = mob_proto+realcounter;
            if (!strcmp("an unfinished mob", GET_NAME(mob)))
                continue;
            fprintf(fp, "#%ld\n", GET_MOB_VNUM(mob));

            fprintf(fp,
                    "Keywords:\t%s\n"
                    "Name:\t%s\n"
                    "RoomDesc:$\n%s\n~\n",
                    mob->player.physical_text.keywords?
                    mob->player.physical_text.keywords : "mob unnamed",
                    mob->player.physical_text.name?
                    mob->player.physical_text.name : "An unnamed mob",
                    cleanup(buf2, mob->player.physical_text.room_desc?
                            mob->player.physical_text.room_desc : "An unnamed mob is here."));
            fprintf(fp, "LookDesc:$\n%s~\n",
                    cleanup(buf2,
                            mob->player.physical_text.look_desc?
                            mob->player.physical_text.look_desc
                            : "An unnamed mob is here."));

            if (mob->mob_specials.arrive)
                fprintf(fp, "ArriveMsg:\t%s\n", mob->mob_specials.arrive);
            if (mob->mob_specials.leave)
                fprintf(fp, "LeaveMsg:\t%s\n", mob->mob_specials.leave);

            fprintf(fp,
                    "MobFlags:\t%s\n"
                    "AffFlags:\t%s\n"
                    "Race:\t%s\n"
                    "Gender:\t%s\n",
                    MOB_FLAGS(mob).ToString(),
                    AFF_FLAGS(mob).ToString(),
                    npc_classes[(int)mob->player.race],
                    genders[(int)mob->player.sex]);

            if (mob->char_specials.position != POS_STANDING)
                fprintf(fp, "Position:\t%s\n",
                        position_types[(int)mob->char_specials.position]);
            if (mob->mob_specials.default_pos)
                fprintf(fp, "DefaultPos:\t%s\n",
                        position_types[(int)mob->mob_specials.default_pos]);

            if (mob->mob_specials.attack_type != TYPE_HIT)
                fprintf(fp, "AttackType:\t%s\n",
                        attack_types[mob->mob_specials.attack_type-TYPE_HIT]);

            fprintf(fp,
                    "[ATTRIBUTES]\n"
                    "\tBod:\t%d\n"
                    "\tQui:\t%d\n"
                    "\tStr:\t%d\n"
                    "\tCha:\t%d\n"
                    "\tInt:\t%d\n"
                    "\tWil:\t%d\n"
                    "\tMag:\t%d\n",
                    GET_REAL_BOD(mob), GET_REAL_QUI(mob), GET_REAL_STR(mob),
                    GET_REAL_CHA(mob), GET_REAL_INT(mob), GET_REAL_WIL(mob),
                    mob->real_abils.mag / 100);
            fprintf(fp,
                    "[POINTS]\n"
                    "\tHeight:\t%d\n"
                    "\tWeight:\t%d\n",
                    mob->player.height, mob->player.weight);

            if (GET_LEVEL(mob) > 0)
                fprintf(fp, "\tLevel:\t%d\n", GET_LEVEL(mob));
            if (int(GET_MAX_PHYSICAL(mob) / 100) != 10)
                fprintf(fp, "\tMaxPhys:\t%d\n", int(GET_MAX_PHYSICAL(mob) / 100));
            if (int(GET_MAX_MENTAL(mob) / 100) != 10)
                fprintf(fp, "\tMaxMent:\t%d\n", int(GET_MAX_MENTAL(mob) / 100));
            if (GET_BALLISTIC(mob) > 0)
                fprintf(fp, "\tBallistic:\t%d\n", GET_BALLISTIC(mob));
            if (GET_IMPACT(mob) > 0)
                fprintf(fp, "\tImpact:\t%d\n", GET_IMPACT(mob));
            if (GET_NUYEN(mob) > 0)
                fprintf(fp, "\tCash:\t%d\n", GET_NUYEN(mob));
            if (GET_BANK(mob) > 0)
                fprintf(fp, "\tBank:\t%d\n", GET_BANK(mob));
            if (GET_KARMA(mob) > 0)
                fprintf(fp, "\tKarma:\t%d\n", GET_KARMA(mob));
            fprintf(fp, "[SKILLS]\n");

            for (i = 0; i <= 8; i = i +2)
                if (mob->mob_specials.mob_skills[i])
                    fprintf(fp, "\t%s:\t%d\n", skills[mob->mob_specials.mob_skills[i]].name,
                            mob->mob_specials.mob_skills[i+1]);



            fprintf(fp, "BREAK\n");
        } // close if statement
    } // close for loop

    fprintf(fp, "END\n");
    fclose(fp);

    write_index_file("mob");
}
Пример #17
0
/*
 * find_first_step: given a source room and a target room, find the first
 * step on the shortest path from the source to the target.
 *
 * Intended usage: in mobile_activity, give a mob a dir to go if they're
 * tracking another mob or a PC.  Or, a 'track' skill for PCs.
 */
int find_first_step(room_rnum src, room_rnum target, CHAR_DATA * ch)
{

	int curr_dir, edge, through_doors;
	room_rnum curr_room, rnum_start = FIRST_ROOM, rnum_stop = top_of_world;

	if (src < FIRST_ROOM || src > top_of_world || target < FIRST_ROOM || target > top_of_world)
	{
		log("SYSERR: Illegal value %d or %d passed to find_first_step. (%s)", src, target, __FILE__);
		return (BFS_ERROR);
	}

	if (src == target)
		return (BFS_ALREADY_THERE);

	// clear marks first, some OLC systems will save the mark.
	if (IS_NPC(ch))
	{
		// Запрещаем искать мобам  в другой зоне ...
		if (world[src]->zone != world[target]->zone)
			return (BFS_ERROR);

		get_zone_rooms(world[src]->zone, &rnum_start, &rnum_stop);
		// Запрещаем мобам искать через двери ...
		through_doors = FALSE;
		edge = EDGE_ZONE;
	}
	else
	{
		// Игроки полноценно ищут в мире.
		through_doors = TRUE;
		edge = EDGE_WORLD;
	}

	for (curr_room = rnum_start; curr_room <= rnum_stop; curr_room++)
		UNMARK(curr_room);

	MARK(src);

	// переписано на вектор без реального очищения, чтобы не заниматься сотнями аллокаций памяти в секунду зря -- Krodo
	static std::vector<bfs_queue_struct> bfs_queue;
	static struct bfs_queue_struct temp_queue;

	// first, enqueue the first steps, saving which direction we're going.
	for (curr_dir = 0; curr_dir < NUM_OF_DIRS; curr_dir++)
		if (VALID_EDGE(src, curr_dir, edge, through_doors))
		{
			MARK(TOROOM(src, curr_dir));
			temp_queue.room = TOROOM(src, curr_dir);
			temp_queue.dir = curr_dir;
			bfs_queue.push_back(temp_queue);
		}
	// now, do the classic BFS.
	for (unsigned int i = 0; i < bfs_queue.size(); ++i)
	{
		if (bfs_queue[i].room == target)
		{
			curr_dir = bfs_queue[i].dir;
			bfs_queue.clear();
			return curr_dir;
		}
		else
		{
			for (curr_dir = 0; curr_dir < NUM_OF_DIRS; curr_dir++)
			{
				if (VALID_EDGE(bfs_queue[i].room, curr_dir, edge, through_doors))
				{
					MARK(TOROOM(bfs_queue[i].room, curr_dir));
					temp_queue.room = TOROOM(bfs_queue[i].room, curr_dir);
					temp_queue.dir = bfs_queue[i].dir;
					bfs_queue.push_back(temp_queue);
				}
			}
		}
	}
	bfs_queue.clear();
	sprintf(buf, "Mob (mob: %s vnum: %d) can't find path.", GET_NAME(ch), GET_MOB_VNUM(ch));
	mudlog(buf, NRM, -1, ERRLOG, TRUE);
	return (BFS_NO_PATH);
}
Пример #18
0
void mobile_activity(void)
{
  struct char_data *ch, *next_ch, *vict;
  struct obj_data *obj, *best_obj;
  int door, found, max;
  memory_rec *names;

  for (ch = character_list; ch; ch = next_ch) {
    next_ch = ch->next;

    if (!IS_MOB(ch))
      continue;

    /* Examine call for special procedure */
    if (MOB_FLAGGED(ch, MOB_SPEC) && !no_specials) {
      if (mob_index[GET_MOB_RNUM(ch)].func == NULL) {
	log("SYSERR: %s (#%d): Attempting to call non-existing mob function.",
		GET_NAME(ch), GET_MOB_VNUM(ch));
	REMOVE_BIT_AR(MOB_FLAGS(ch), MOB_SPEC);
      } else {
        char actbuf[MAX_INPUT_LENGTH] = "";
	if ((mob_index[GET_MOB_RNUM(ch)].func) (ch, ch, 0, actbuf))
	  continue;		/* go to next char */
      }
    }

    /* If the mob has no specproc, do the default actions */
    if (FIGHTING(ch) || !AWAKE(ch))
      continue;

    /* hunt a victim, if applicable */
    hunt_victim(ch);

    /* Scavenger (picking up objects) */
    if (MOB_FLAGGED(ch, MOB_SCAVENGER))
      if (world[IN_ROOM(ch)].contents && !rand_number(0, 10)) {
	max = 1;
	best_obj = NULL;
	for (obj = world[IN_ROOM(ch)].contents; obj; obj = obj->next_content)
	  if (CAN_GET_OBJ(ch, obj) && GET_OBJ_COST(obj) > max) {
	    best_obj = obj;
	    max = GET_OBJ_COST(obj);
	  }
	if (best_obj != NULL) {
	  obj_from_room(best_obj);
	  obj_to_char(best_obj, ch);
	  act("$n gets $p.", FALSE, ch, best_obj, 0, TO_ROOM);
	}
      }

    /* Mob Movement */
    if (!MOB_FLAGGED(ch, MOB_SENTINEL) && (GET_POS(ch) == POS_STANDING) &&
       ((door = rand_number(0, 18)) < DIR_COUNT) && CAN_GO(ch, door) &&
       !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB) &&
       !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_DEATH) &&
       (!MOB_FLAGGED(ch, MOB_STAY_ZONE) ||
           (world[EXIT(ch, door)->to_room].zone == world[IN_ROOM(ch)].zone))) 
    {
      /* If the mob is charmed, do not move the mob. */
      if (ch->master == NULL)
        perform_move(ch, door, 1);
    }

    /* Aggressive Mobs */
     if (!MOB_FLAGGED(ch, MOB_HELPER) && (!AFF_FLAGGED(ch, AFF_BLIND) || !AFF_FLAGGED(ch, AFF_CHARM))) {
      found = FALSE;
      for (vict = world[IN_ROOM(ch)].people; vict && !found; vict = vict->next_in_room) {
	if (IS_NPC(vict) || !CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE))
	  continue;

	if (MOB_FLAGGED(ch, MOB_WIMPY) && AWAKE(vict))
	  continue;

	if (MOB_FLAGGED(ch, MOB_AGGRESSIVE  ) ||
	   (MOB_FLAGGED(ch, MOB_AGGR_EVIL   ) && IS_EVIL(vict)) ||
	   (MOB_FLAGGED(ch, MOB_AGGR_NEUTRAL) && IS_NEUTRAL(vict)) ||
	   (MOB_FLAGGED(ch, MOB_AGGR_GOOD   ) && IS_GOOD(vict))) {

          /* Can a master successfully control the charmed monster? */
          if (aggressive_mob_on_a_leash(ch, ch->master, vict))
            continue;

	  hit(ch, vict, TYPE_UNDEFINED);
	  found = TRUE;
	}
      }
    }

    /* Mob Memory */
    if (MOB_FLAGGED(ch, MOB_MEMORY) && MEMORY(ch)) {
      found = FALSE;
      for (vict = world[IN_ROOM(ch)].people; vict && !found; vict = vict->next_in_room) {
	if (IS_NPC(vict) || !CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE))
	  continue;

	for (names = MEMORY(ch); names && !found; names = names->next) {
	  if (names->id != GET_IDNUM(vict))
            continue;

          /* Can a master successfully control the charmed monster? */
          if (aggressive_mob_on_a_leash(ch, ch->master, vict))
            continue;

          found = TRUE;
          act("'Hey!  You're the fiend that attacked me!!!', exclaims $n.", FALSE, ch, 0, 0, TO_ROOM);
          hit(ch, vict, TYPE_UNDEFINED);
        }
      }
    }

    /* Charmed Mob Rebellion: In order to rebel, there need to be more charmed 
     * monsters than the person can feasibly control at a time.  Then the
     * mobiles have a chance based on the charisma of their leader.
     * 1-4 = 0, 5-7 = 1, 8-10 = 2, 11-13 = 3, 14-16 = 4, 17-19 = 5, etc. */
    if (AFF_FLAGGED(ch, AFF_CHARM) && ch->master && num_followers_charmed(ch->master) > (GET_CHA(ch->master) - 2) / 3) {
      if (!aggressive_mob_on_a_leash(ch, ch->master, ch->master)) {
        if (CAN_SEE(ch, ch->master) && !PRF_FLAGGED(ch->master, PRF_NOHASSLE))
          hit(ch, ch->master, TYPE_UNDEFINED);
        stop_follower(ch);
      }
    }

    /* Helper Mobs */
    if (MOB_FLAGGED(ch, MOB_HELPER) && (!AFF_FLAGGED(ch, AFF_BLIND) || !AFF_FLAGGED(ch, AFF_CHARM))) 
    {
      found = FALSE;
      for (vict = world[IN_ROOM(ch)].people; vict && !found; vict = vict->next_in_room) 
      {
	      if (ch == vict || !IS_NPC(vict) || !FIGHTING(vict))
          continue; 
	      if (IS_NPC(FIGHTING(vict)) || ch == FIGHTING(vict))
          continue;

	      act("$n jumps to the aid of $N!", FALSE, ch, 0, vict, TO_ROOM);
	      hit(ch, FIGHTING(vict), TYPE_UNDEFINED);
	      found = TRUE;
      }
    }

    /* Add new mobile actions here */

  }				/* end for() */
}
Пример #19
0
void mobile_activity(void)
{
  register struct char_data *ch, *next_ch, *vict;
  struct char_data *min_vict = NULL;
  struct obj_data *obj, *next_obj, *best_obj, *cont;
  int door, found, max, where;
  int casual, max_abil=0, curr_abil, gold;
  memory_rec *names;
  room_rnum target_room;

  extern int no_specials;
  ACMD(do_get);

  for (ch = character_list; ch; ch = next_ch) {
    next_ch = ch->next;
    
    if (!IS_MOB(ch))
      continue;
    
    //lance ripristina il master!
 	  if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_SAVE))
 		  chkmaster(ch);

    // Examine call for special procedure
    if (MOB_FLAGGED(ch, MOB_SPEC) && !no_specials) {
      if (mob_index[GET_MOB_RNUM(ch)].func == NULL) {
	      sprintf(buf, "SYSERR: %s (#%d): Attempting to call non-existing mob func", GET_NAME(ch), GET_MOB_VNUM(ch));
	      log(buf);
	      REMOVE_BIT(MOB_FLAGS(ch), MOB_SPEC);
      }
      else {
	      //(mob_index[GET_MOB_RNUM(ch)].func) (ch, ch, 0, "");
	      if ((mob_index[GET_MOB_RNUM(ch)].func) (ch, ch, 0, ""))
	        continue;	     /*  go to next char*/
      }
    }

// If the mob has no specproc, do the default actions
    if (FIGHTING(ch) || !AWAKE(ch))
      continue;

// Nuovo Scavenger (picking up objects) by Rusty 
    if (MOB_FLAGGED(ch, MOB_SCAVENGER))
	  if (world[ch->in_room].contents && (number(0, 10) > 5)) {
		  max = -1000;
		  best_obj = NULL;
		  for (obj = world[ch->in_room].contents; obj; obj = obj->next_content)
	  	if (CAN_GET_OBJ(ch, obj) && objlevel(obj) > max) {
			  best_obj = obj;
			  max = objlevel(obj);
			}
    
		  if (best_obj != NULL) {
			  obj_from_room(best_obj);
			  obj_to_char(best_obj, ch);
			  act("$n prende $p.", FALSE, ch, best_obj, 0, TO_ROOM);

// Orione, tolta la procedura che fa indossare l'eq raccolto ai mob scavenger
// Scavenger Plus:Mob wear the best object
/*
			  where=find_eq_pos(ch, best_obj, 0);
			  if (CAN_WEAR(best_obj, ITEM_WEAR_WIELD))
			    where=WEAR_WIELD;

			  if ( (where>0) && GET_EQ(ch,where)) {
				  // se ce l'ha gia!
				  if ((objlevel((ch)->equipment[where]))< objlevel(best_obj)) {
				    obj_to_char((obj=unequip_char(ch, where)), ch);
					  act("$n smette di usare $p.", FALSE, ch, obj, 0, TO_ROOM);
				  } 
				  else {
					  where = NUM_WEARS; // cioe' oggetto non indossabile
				  }

				  if (GET_LEVEL(ch)>=objlevel(best_obj)) {
					  if (where>=0 && where <NUM_WEARS) {
						  obj_from_char(best_obj);
						  equip_char(ch,best_obj,where);
						  wear_message(ch,best_obj,where);
					  }
				  }
			  }
*/
		  }
	  } //End ifif

// Mob BodyGuard !?       
    if (MOB_FLAGGED(ch, MOB_BGUARD) && (ch->master)) {
      if (   (FIGHTING(ch->master) && (npc_rescue(ch, ch->master) == FALSE))
	        || (ch->master && WHOKILLED(ch->master)) ) {
        act("$N Si schiera Prontamente al tuo fianco!", FALSE,ch->master, 0, ch, TO_CHAR);
	      act("$n Si schiera prontamente al fianco di $N", FALSE, ch, 0, ch->master, TO_ROOM);
	      if (WHOKILLED(ch->master))	
	        hit(ch, WHOKILLED(ch->master), TYPE_UNDEFINED);/*in ogni caso assiste*/
	      else
	        hit(ch, FIGHTING(ch->master), TYPE_UNDEFINED);/*in ogni caso assiste*/
	    }
     
      if (FIGHTING(ch)) {
	      npc_rescue(ch, ch->master);
		    if (WHOKILLED(ch->master))
		      hit(ch, WHOKILLED(ch->master), TYPE_UNDEFINED);  /*in ogni caso assiste*/
		    continue;
		  }	  
    }

//MOB_THIEF
    if (   MOB_FLAGGED(ch, MOB_CRIMINAL)  && (GET_POS(ch) == POS_RESTING)
        && IS_AFFECTED(ch, AFF_HIDE) && GET_HIT(ch) >= 2*GET_MAX_HIT(ch)/3) {
      appear(ch);
      GET_POS(ch)=POS_STANDING;
    }
    if (   MOB_FLAGGED(ch, MOB_CRIMINAL) 
        && ( GET_POS(ch) == POS_STANDING) 
        && ( (casual = number(0, 11)) < 6 ) ) {   // 50%  Rubare

      // cerca le vittime  1) Devono aver almeno 1 coin  
      //                   2) Deve aver una buona prob di farcela
      for (found=FALSE, min_vict = NULL, vict = world[ch->in_room].people; vict; vict = vict->next_in_room) {
	      if (CAN_SEE(ch, vict) && (vict != ch)) {
	        if ((min_vict == NULL) || (max_abil < 100)) {
	        //se ha il 100% tanto vale fermarsi
	        //Calcolo dell abilita:presa esattamente da D n'D

	          curr_abil = MIN(90, (10*(GET_LEVEL(ch)) - 5*GET_LEVEL(vict)));
	          curr_abil -=  dex_app[GET_DEX(vict)].reaction;
	          if (GET_POS(vict) < POS_STANDING)
	            curr_abil += 200;
	    // Se la vittima e' addormentata-stunned - incap o morta ovviamente
	    //  deruberai questa sicuramente

	          if (   (curr_abil >= 40) 
	              && (GET_GOLD(vict) != 0) 
	              && (curr_abil > max_abil) ) {
	            min_vict = vict;
	            max_abil = curr_abil;
	            found=TRUE;
	          }
	        }
	      }
      }
      // Se ha trovato la vittima
      if (found == TRUE) {
	      if ((casual = number(1, 100)) > max_abil) {
	        if (!IS_NPC(min_vict))
	          act(" $n cerca di prendere dei soldi dal tuo Borsello", FALSE, ch, 0, min_vict, TO_CHAR);
	        else {
	          act("Oops...", FALSE, ch, 0, min_vict, TO_ROOM);
	          act("$n cerca di rubare soldi a $N..Ma viene Scoperto! ", FALSE, ch, 0, min_vict, TO_ROOM);
	        }
	        
	        //Beccato ... fa 2 tentativi di fuga
	        if (((door = number(1, 7)) < NUM_OF_DIRS) && CAN_GO(ch, door) &&
	             !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	        if ((door -= 1) < NUM_OF_DIRS && CAN_GO(ch, door) &&
	             !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	        if ((door += 2) < NUM_OF_DIRS && CAN_GO(ch, door) &&
	             !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	        
	        if (IS_NPC(min_vict)) {
	          act("$n Urla: $N e' uno sporco LADRO!!!!", FALSE, min_vict, 0, ch, TO_ROOM);
	          hit(min_vict, ch, TYPE_UNDEFINED);
	        }
	      }
	      // Il Bastardo ce la fa!
	      else {
	        if (GET_POS(min_vict) < 5) {
	          GET_GOLD(ch) += GET_GOLD(min_vict);
	          GET_GOLD(min_vict) = 0;    //la ripulisce completamente
	        }
	        else {
	          gold = number((GET_GOLD(min_vict) / 10), (GET_GOLD(min_vict) / 2));
	          //gold = MIN(5000, gold);
	          if (gold > 0) {
	            GET_GOLD(ch) += gold;
	            GET_GOLD(min_vict) -= gold;
	            if (GET_GOLD(min_vict) < 0)
	              GET_GOLD(min_vict) = 0;
	          }
	        }
	        // Dopo il furto si allontana
	        if (((door = number(1, 6)) < NUM_OF_DIRS) && CAN_GO(ch, door) &&
	           !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	        if ((door -=1) < NUM_OF_DIRS && CAN_GO(ch, door) &&
	           !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	        if ((door +=2) < NUM_OF_DIRS && CAN_GO(ch, door) &&
	           !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	          perform_move(ch,door,1,CAN_SHOW_ROOM);
	      }
      }
      else { // Nessuna vittima appetibile:se ne va!
	      
	      if (((door = number(0, 6)) < NUM_OF_DIRS) && CAN_GO(ch, door) &&
	          !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) )
	        perform_move(ch, door, 1, CAN_SHOW_ROOM);
      }
    }

// Mob Sciacalli indossano EQ    
    if (MOB_FLAGGED(ch, MOB_NECRO) && !FIGHTING(ch) && AWAKE(ch))
    if (world[ch->in_room].contents) {
	    max = -1000;
	    best_obj=NULL;
	    for (cont = world[ch->in_room].contents;cont;cont = cont->next_content)
	    if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
	      for (obj = cont->contains; obj; obj = next_obj) {
		      next_obj = obj->next_content;
		      if (obj != NULL) {
		        if (CAN_SEE_OBJ(ch, obj) && ( (max = objlevel(obj)) <= GET_LEVEL(ch)) ) {
		          perform_get_from_container(ch, obj, cont, FIND_OBJ_INV);
		          if (obj != NULL) {
		            where = find_eq_pos(ch, obj, 0);
		            if (CAN_WEAR(obj, ITEM_WEAR_HOLD))
			            where = WEAR_HOLD;
		            if (GET_OBJ_TYPE(obj)==ITEM_LIGHT)
			            where = WEAR_LIGHT;
		            if (CAN_WEAR(obj, ITEM_WEAR_WIELD))
			            where = WEAR_WIELD;
		            if (where < 0) {
			            sprintf(buf,"SYSERR:pos < 0 ,in cont %s obj %d %s In room %d", 
			                        cont->name, 
			                        GET_OBJ_RNUM(obj), 
			                        obj->name, 
			                        IN_ROOM(ch));
			            log(buf);
			            where = NUM_WEARS;
		            }
		            
		            if (GET_EQ(ch, where) && where < NUM_WEARS) {
			            if ((objlevel((ch)->equipment[where])) < objlevel(obj)) {
			              obj_to_char((best_obj = unequip_char(ch, where)), ch);
			              act("$n smette di usare $p.",FALSE, ch, best_obj, 0, TO_ROOM);
			            }
			            else
			              where = NUM_WEARS;
		            }
		            if (where >= 0 && where < NUM_WEARS) {
			            wear_message(ch, obj, where);
			            obj_from_char(obj);
			            equip_char(ch, obj, where);
		            }
		          }
		        }
		      }
	      }
	    } //End forif
	  } //End ifif

// Mob Movement
    if (HUNTING(ch)) 
      hunt_victim(ch);
    else {
	    if (MOB_FLAGGED(ch , MOB_SEARCHER)) {}
 	    else {
        if (ch->in_room != NOWHERE) {
          if (!IS_IN_WILD(ch)) {
            if (   !MOB_FLAGGED(ch, MOB_SENTINEL) 
                && (GET_POS(ch) == POS_STANDING) 
                && (   (door = number(0, 8)) < NUM_OF_DIRS) 
                    && CAN_GO(ch, door) 
                    && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) 
                    && (   !MOB_FLAGGED(ch, MOB_STAY_ZONE) 
                        || (world[EXIT(ch, door)->to_room].zone == world[ch->in_room].zone))) {
              perform_move(ch, door, 1, CAN_SHOW_ROOM);
            }
          }
          else {  // E' in wilderness
            if (MOB_FLAGGED(ch, MOB_WILDHUNT)) 
              door = wild_mobhunter(ch);
            else 
              door = number(0, 8);
            
            if (door >= 0 && door < NUM_OF_DIRS) 
              target_room = wild_target_room(ch, door);
            else 
              target_room = -1;
            
            if (   !MOB_FLAGGED(ch, MOB_SENTINEL) 
                && (GET_POS(ch) == POS_STANDING) 
                && (target_room != -1) 
                && (   !MOB_FLAGGED(ch, MOB_STAY_ZONE) 
                    || (world[target_room].wild_rnum == world[ch->in_room].wild_rnum))) {
              perform_move(ch, door, 1, CAN_SHOW_ROOM);
            }
          }
        }	
      }
    }

// Aggressive Mobs
    if (MOB_FLAGGED(ch, MOB_AGGRESSIVE | MOB_AGGR_TO_ALIGN)) {
      found = FALSE;
      for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) {
	      if (IS_NPC(vict) || !CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE))
	        continue;
	      if (number(0, 3) < 2)
	        continue; // Simple simulate Random a Joke from Phantom ;P
	      if (GET_ABIL (vict, ABIL_TRATTATIVA) >= EXPERT_LIV)
	        continue; // I pg con trattativa ad esperto fanno pace con gli aggressivi (by Spini)
	      if (controllo_volo(ch, vict))
		continue;
	      if (affected_by_spell (vict, SPELLSKILL, DISEASE_PESTE))
		continue;

	      if (MOB_FLAGGED(ch, MOB_AGGR_NO_PROP) && (MASTER_ID(ch)==GET_IDNUM(vict)))
	        continue;
	      if (MOB_FLAGGED(ch, MOB_AGGR_NO_CLAN) && (CLAN_ID(ch)==GET_CLAN(vict)))
	        continue;
	      if (MOB_FLAGGED(ch, MOB_AGGR_NO_AL_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == ALLIANCE))
	        continue;
	      if (MOB_FLAGGED(ch, MOB_AGGR_NO_EN_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == WAR))
	        continue;
	      if (MOB_FLAGGED(ch, MOB_AGGR_NO_PC_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == PEACE))
	        continue;
	      if (MOB_FLAGGED(ch, MOB_AGGR_VAS_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == VASSALLO))
	  	    continue;

        if (   !MOB_FLAGGED(ch, MOB_AGGR_TO_ALIGN) 
            || (MOB_FLAGGED(ch, MOB_AGGR_EVIL) && IS_EVIL(vict)) 
            || (MOB_FLAGGED(ch, MOB_AGGR_NEUTRAL) && IS_NEUTRAL(vict)) 
            || (MOB_FLAGGED(ch, MOB_AGGR_GOOD) && IS_GOOD(vict)) ) {
	        if (GET_MOB_SPEC(ch)== thief)
	          npc_backstab(ch,vict);
	        else
	          hit(ch, vict, TYPE_UNDEFINED);
	        found = TRUE;
	      }
      }
    }

// Mob Memory
    if (MOB_FLAGGED(ch, MOB_MEMORY) && MEMORY(ch)) {
      found = FALSE;
      for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) {
        if (!CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE))
          continue;
        for (names = MEMORY(ch); names && !found; names = names->next)
        if (names->id == GET_IDNUM(vict)) {
          found = TRUE;
          act("$n esclama, 'Hey!! Tu sei il tipo che mi ha attaccato!!!'", FALSE, ch, 0, 0, TO_ROOM);
          hit(ch, vict, TYPE_UNDEFINED);
        } //End forif
      }
    }

// Helper Mobs Paladino del bene
    if (   MOB_FLAGGED(ch, MOB_HELPER)
        && !MOB_FLAGGED(ch, MOB_CRIMINALHELPER) ) {
      found = FALSE;
      for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room)
      if (   ch != vict 
          && IS_NPC(vict) 
          && FIGHTING(vict) 
          && !IS_NPC(FIGHTING(vict)) 
          && ch != FIGHTING(vict) ) {			
        if (   MOB_FLAGGED(vict, MOB_CRIMINAL)
            || (   (ch->master)
                && (FIGHTING(vict) == ch->master) ) ) {
	        hit(ch, vict, TYPE_UNDEFINED);
	        found = TRUE;
	      } 		
	      else { 
	        act("$n arriva in aiuto di $N!", FALSE, ch, 0, vict, TO_ROOM);
	        hit(ch, FIGHTING(vict), TYPE_UNDEFINED);
	        found = TRUE;
	      }
	    } //End forif
    }
	
// Helper Mobs Servo del male
    if (   MOB_FLAGGED(ch, MOB_CRIMINALHELPER)
        && !MOB_FLAGGED(ch, MOB_HELPER) ) {
      found = FALSE;
      for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room)
      if (   ch != vict 
          && IS_NPC(vict) 
          && FIGHTING(vict) 
          && !IS_NPC(FIGHTING(vict)) 
          && ch != FIGHTING(vict) ) {			
        if (   MOB_FLAGGED(vict, MOB_CRIMINAL)
            || (   (ch->master) 
                && (vict == ch->master) ) ) {
          act("$n arriva in aiuto di $N!", FALSE, ch, 0, vict, TO_ROOM);
          hit(ch, FIGHTING(vict), TYPE_UNDEFINED);
          found = TRUE;
        }
      } //End forif
    }
	
// Add new mobile actions here

  }				// end for()
}
Пример #20
0
/* do_simple_move assumes
 *    1. That there is no master and no followers.
 *    2. That the direction exists.
 *
 *   Returns :
 *   1 : If succes.
 *   0 : If fail
 */
int do_simple_move(struct char_data *ch, int dir, int need_specials_check)
{
  room_rnum was_in;
  struct char_data *i;
  /*
   * Check for special routines (North is 1 in command list, but 0 here) Note
   * -- only check if following; this avoids 'double spec-proc' bug
   */
  if (need_specials_check && special(ch, dir + 1, "")) { 
    return (0);
  }

  /* charmed? */
  if (AFF_FLAGGED(ch, AFF_CHARM) && ch->master && ch->in_room == ch->master->in_room) {
    send_to_char("The thought of leaving your master makes you weep.\r\n", ch);
    act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM);
    return (0);
  }

  /* if this room or the one we're going to needs a boat, check for one */
  if ((SECT(ch->in_room) == SECT_WATER_NOSWIM) ||
      (SECT(EXIT(ch, dir)->to_room) == SECT_WATER_NOSWIM)) {
    if (!has_boat(ch)) {
      send_to_char("You need a boat to go there.\r\n", ch);
      return (0);
    }
  }

  if((IS_CARRYING_W(ch) > (CAN_CARRY_W(ch) * 2) && GET_LEVEL(ch) < LVL_GOD && !IS_NPC(ch))) {
    send_to_char("You are to heavy to move! Drop something!\r\n", ch);
    return (0);
  }
  
  if(IS_NPC_FISH(ch)) {
    if(SECT(EXIT(ch, dir)->to_room) != SECT_BRIDGE && SECT(EXIT(ch, dir)->to_room) != SECT_WATER_SWIM && SECT(EXIT(ch, dir)->to_room) !=  SECT_WATER_NOSWIM) {
//       sprintf(buf, "%s %d", dirs[dir], SECT(EXIT(ch, dir)->to_room));
//       mobsay(ch, buf);
       return FALSE;

     }
     if(GET_MOB_VNUM(ch) < 1500 && ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_SALT_FISH)) {
       return FALSE;
     }
   }

  if (SECT(EXIT(ch, dir)->to_room) != SECT_FOREST) {
    if (IS_NPC_WOLF(ch) || IS_NPC_CRAB(ch) || IS_NPC_SKELETON(ch)) {
       return (0);
   }
  }

  /* move points needed is avg. move loss for src and destination sect type */
  if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_TUNNEL) &&
      num_pc_in_room(&(world[EXIT(ch, dir)->to_room])) > 1) {
    send_to_char("There isn't enough room there for more than one person!\r\n", ch);
    return (0);
  }
  /* Mortals and low level gods cannot enter greater god rooms. */
  if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_GODROOM) &&
	GET_LEVEL(ch) < LVL_GRGOD) {
    send_to_char("You aren't godly enough to use that room!\r\n", ch);
    return (0);
  }


  /* Now we know we're allow to go into the room. */

  if(AFF_FLAGGED(ch, AFF_FISHING) || GET_FISHON(ch)) {
    REMOVE_BIT(AFF_FLAGS(ch), AFF_FISHING);
    GET_FISHON(ch) = 0;
    GET_REELIN(ch) = 0;
    send_to_char("You stop fishing.\r\n", ch);
    act("$n stops fishing.", FALSE, ch, 0, 0, TO_ROOM);
  }

  if (!AFF_FLAGGED(ch, AFF_SNEAK) && !AFF_FLAGGED(ch, AFF_INVISIBLE)) {
    if(IS_NPC(ch)) { 
      switch(GET_RACE(ch)) {
        case RACE_NPC_MAMMAL:
        case RACE_NPC_HIGHHUMAN:
        case RACE_NPC_GOBLIN:
        case RACE_NPC_PIG:
        case RACE_NPC_WOLF:
        case RACE_NPC_CHICKEN:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_AVIAN:
          sprintf(buf2, "$n flits %s.", dirs[dir]); 
          break;
        case RACE_NPC_SHEEP:
        case RACE_NPC_GOAT:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_SKELETON:
          sprintf(buf2, "$n shambles %s.", dirs[dir]);
          break;
        case RACE_NPC_COW:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_CRAB:
          sprintf(buf2, "$n scurries %s.", dirs[dir]);
          break;
        case RACE_NPC_FISH:
          sprintf(buf2, "$n swims %s.", dirs[dir]);
          break;
        case RACE_NPC_INSECT:
          sprintf(buf2, "$n buzzes %s.", dirs[dir]);
          break;
        default:
          sprintf(buf2, "$n leaves %s.", dirs[dir]);
          break;
      }
    }
    else {
       sprintf(buf2, "$n leaves %s.", dirs[dir]);
    }
    if(SECT(ch->in_room) == SECT_WATER_SWIM && !IS_NPC_FISH(ch)) {
       sprintf(buf2, "$n splashes through the water, heading %s.", dirs[dir]);
    }
    act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  }
  was_in = ch->in_room;


  char_from_room(ch);
  char_to_room(ch, world[was_in].dir_option[dir]->to_room);

  if (!AFF_FLAGGED(ch, AFF_SNEAK)) {
    if(!AFF_FLAGGED(ch, AFF_INVISIBLE)) {
      act("$n has arrived.", FALSE, ch, 0, 0, TO_ROOM);
    }
  }
  if (ch->desc != NULL)
    look_at_room(ch, 0);

  if(IS_NPC_CRAB(ch) || IS_NPC_LIVESTOCK(ch)) {
    for (i = world[ch->in_room].people; i; i = i->next_in_room) {
    
       if(IS_NPC_WOLF(i) && IS_NPC_CRAB(ch)) {
            sprintf(buf, "%s sees %s and tries to run!\r\n", GET_NAME(ch), GET_NAME(i));
            send_to_room(buf, ch->in_room);
            if(!number(0, 2)) {
              do_flee(ch, NULL, 0, 0);
            }
            if(i->in_room == ch->in_room && !number(0, 2)) {
              hit(i, ch, TYPE_UNDEFINED);
            }
      }
      if((IS_NPC_SKELETON(i) || IS_NPC_WOLF(i)) && IS_NPC_LIVESTOCK(ch)) {
          if(ch->master) {
            sprintf(buf, "%s sees %s and %s in absolute terror!\r\n", GET_NAME(ch), GET_NAME(i), livestock_afraid_vocals[(int)GET_RACE(ch)]);
            send_to_room(buf, ch->in_room);
            if(!number(0, 2)) {
              do_flee(ch, NULL, 0, 0);
            }
            if(i->in_room == ch->in_room && !number(0, 2)) {
              hit(i, ch, TYPE_UNDEFINED);
            }
          }
      }
    }
    return (1);
  }
  if (ROOM_FLAGGED(ch->in_room, ROOM_DEATH) && GET_LEVEL(ch) < LVL_IMMORT) {
    log_death_trap(ch);
    death_cry(ch);
    extract_char(ch);
    return (0);
  }
  return (1);
}
Пример #21
0
void another_hour(void)
{
    bool new_month = FALSE;
    struct char_data *ch, *next;
    char *temp;

    time_info.hours++;

    switch (time_info.hours) {
    case 7:
        weather_info.sunlight = SUN_RISE;
        if (weather_info.sky == SKY_CLOUDLESS)
            temp = "^y";
        else
            temp = "^L";
        sprintf(buf, "%sThe sun rises in the east.^n\r\n", temp);
        send_to_outdoor(buf);
        for (ch = character_list; ch; ch = next) {
            next = ch->next;
            if (IS_SPIRIT(ch) && GET_MOB_VNUM(ch) >= 25 && GET_MOB_VNUM(ch) <= 41) {
                act("$n abruptly fades from the physical plane.", TRUE, ch, 0, 0, TO_ROOM);
                act("Arrgh!  The sun is rising!  Goodbye!", FALSE, ch, 0, 0, TO_CHAR);
                extract_char(ch);
            }
        }
        break;
    case 9:
        weather_info.sunlight = SUN_LIGHT;
        switch (weather_info.sky) {
        case SKY_CLOUDLESS:
            temp = "^Y";
            break;
        case SKY_CLOUDY:
        case SKY_RAINING:
            temp = "^n";
            break;
        case SKY_LIGHTNING:
            temp = "^L";
            break;
        default:
            temp = "^Y";
            break;
        }
        sprintf(buf, "%sThe day has begun.^n\r\n", temp);
        send_to_outdoor(buf);
        break;
    case 18:
        weather_info.sunlight = SUN_SET;
        switch (weather_info.sky) {
        case SKY_CLOUDLESS:
            temp = "^r";
            break;
        case SKY_CLOUDY:
            temp = "^B";
            break;
        case SKY_RAINING:
            temp = "^b";
            break;
        case SKY_LIGHTNING:
            temp = "^L";
            break;
        default:
            temp = "^r";
            break;
        }
        sprintf(buf, "%sThe sun slowly disappears in the west.^n\r\n", temp);
        send_to_outdoor(buf);
        for (ch = character_list; ch; ch = next) {
            next = ch->next;
            if (IS_SPIRIT(ch) && GET_MOB_VNUM(ch) >= 25 && GET_MOB_VNUM(ch) <= 41) {
                act("$n abruptly fades from the physical plane.", TRUE, ch, 0, 0, TO_ROOM);
                act("You sense the sun setting, and dissolve yourself.", FALSE, ch, 0, 0, TO_CHAR);
                extract_char(ch);
            }
        }
        break;
    case 21:
        weather_info.sunlight = SUN_DARK;
        if (weather_info.sky == SKY_CLOUDLESS)
            sprintf(buf, "^bThe night has begun. The moon is %s.^n\r\n",moon[weather_info.moonphase]);
        else
            sprintf(buf, "^LThe night has begun.^n\r\n");

        send_to_outdoor(buf);
        break;
    }

    if (time_info.hours > 23) {
        time_info.hours -= 24;
        time_info.day++;
        time_info.weekday++;
        if (time_info.weekday > 6)
            time_info.weekday = 0;

        if (((time_info.month == 3) || (time_info.month == 5) ||
                (time_info.month == 8) || (time_info.month == 10)) &&
                (time_info.day > 29))
            new_month = TRUE;
        else if ((time_info.month == 1) && (time_info.day > 27))
            new_month = TRUE;
        else if (time_info.day > 30)
            new_month = TRUE;
        if (new_month) {
            time_info.day = 0;
            time_info.month++;

            if (time_info.month > 11) {
                time_info.month = 0;
                time_info.year++;
            }
        }
    }
    if(time_info.day < 7)
        weather_info.moonphase = MOON_NEW;
    else if(time_info.day > 7 && time_info.day < 14)
        weather_info.moonphase = MOON_WAX;
    else if(time_info.day > 14 && time_info.day < 21)
        weather_info.moonphase = MOON_FULL;
    else
        weather_info.moonphase = MOON_WANE;

}
Пример #22
0
void list_mob_zone (struct char_data *ch, int whichzone)
{

	int i=0;
	int j=0;
	mob_vnum first_z_mob=0; /*vnum of first mob in zone list*/
	mob_vnum last_z_mob=0; /*vnum of last mob in zone list */
	int char_zone = ((GET_ROOM_VNUM(IN_ROOM(ch)))/100); /*initialize to current zone    */
	char *mbuf = get_buffer(MAX_STRING_LENGTH);

	mbuf[0]='\0'; 
	if (whichzone > (-1))
		char_zone = whichzone; /*see if specific zone was passed as arg*/

	while (j!= char_zone) {
		first_z_mob++;
		j=(GET_MOB_VNUM(&mob_proto[i])/100);
		i++;

		/*
		 * some zones have 100+ rooms but not 100+ items/mobs.
		 * To find the needed mobs/objects, 
		 * search backwards for previous zone w/them.
		 */
		if (j>char_zone) {
			if (char_zone>0) {
				char_zone--;
				first_z_mob=0;
				i=0;
				j=0; 
			} else {
				extended_mudlog(NRM, SYSL_BUGS, TRUE, "mlist looked for a zone < 0");
				release_buffer(mbuf);
				return;
			}
		}
	}

	first_z_mob --;
	last_z_mob=first_z_mob;


	while (j == char_zone) {
		j=(GET_MOB_VNUM(&mob_proto[i])/100);
		last_z_mob++;
		i++; 
	}

	if (first_z_mob<0)
		first_z_mob ++;
	for (i=first_z_mob;i<last_z_mob;i++) {
		sprintf(mbuf+strlen(mbuf),"[%5d] %-30s  (difficulty %d)\r\n",
		GET_MOB_VNUM(&mob_proto[i]),
		mob_proto[i].player.short_descr,
		mob_proto[i].mob_specials.difficulty); 
	}
	if (strlen(mbuf)<5)
		send_to_char ("There are no mobs in the zone you requested.\r\n",ch);
	else
		page_string (ch->desc,mbuf,1);

	release_buffer(mbuf);
	return;
}
Пример #23
0
/**
* Checks for common mob problems and reports them to ch.
*
* @param char_data *mob The mob to audit.
* @param char_data *ch The person to report to.
* @return bool TRUE if any problems were reported; FALSE if all good.
*/
bool audit_mobile(char_data *mob, char_data *ch) {
	extern adv_data *get_adventure_for_vnum(rmt_vnum vnum);
	
	bool is_adventure = (get_adventure_for_vnum(GET_MOB_VNUM(mob)) != NULL);
	char temp[MAX_STRING_LENGTH], *ptr;
	bool problem = FALSE;

	if (!str_cmp(GET_PC_NAME(mob), "mobile new")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Keywords not set");
		problem = TRUE;
	}
	
	ptr = GET_PC_NAME(mob);
	do {
		ptr = any_one_arg(ptr, temp);
		if (*temp && !str_str(GET_SHORT_DESC(mob), temp) && !str_str(GET_LONG_DESC(mob), temp)) {
			olc_audit_msg(ch, GET_MOB_VNUM(mob), "Keyword '%s' not found in strings", temp);
			problem = TRUE;
		}
	} while (*ptr);
	
	if (!str_cmp(GET_SHORT_DESC(mob), "a new mobile")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc not set");
		problem = TRUE;
	}
	any_one_arg(GET_SHORT_DESC(mob), temp);
	if ((fill_word(temp) || reserved_word(temp)) && isupper(*temp)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc capitalized");
		problem = TRUE;
	}
	if (ispunct(GET_SHORT_DESC(mob)[strlen(GET_SHORT_DESC(mob)) - 1])) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc has punctuation");
		problem = TRUE;
	}
	
	ptr = GET_SHORT_DESC(mob);
	do {
		ptr = any_one_arg(ptr, temp);
		// remove trailing punctuation
		while (*temp && ispunct(temp[strlen(temp)-1])) {
			temp[strlen(temp)-1] = '\0';
		}
		if (*temp && !fill_word(temp) && !reserved_word(temp) && !isname(temp, GET_PC_NAME(mob))) {
			olc_audit_msg(ch, GET_MOB_VNUM(mob), "Suggested missing keyword '%s'", temp);
			problem = TRUE;
		}
	} while (*ptr);
	
	if (!str_cmp(GET_LONG_DESC(mob), "A new mobile is standing here.\r\n")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc not set");
		problem = TRUE;
	}
	if (!ispunct(GET_LONG_DESC(mob)[strlen(GET_LONG_DESC(mob)) - 3])) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc missing punctuation");
		problem = TRUE;
	}
	if (islower(*GET_LONG_DESC(mob))) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc not capitalized");
		problem = TRUE;
	}
	if (!is_adventure && GET_MAX_SCALE_LEVEL(mob) == 0) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "No maximum scale level on non-adventure mob");
		problem = TRUE;
	}
	if (MOB_ATTACK_TYPE(mob) == TYPE_RESERVED) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Invalid attack type");
		problem = TRUE;
	}
	if (MOB_FLAGGED(mob, MOB_ANIMAL) && !has_interaction(mob->interactions, INTERACT_SKIN)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Animal has no skin");
		problem = TRUE;
	}
	if (MOB_FLAGGED(mob, MOB_ANIMAL) && !has_interaction(mob->interactions, INTERACT_BUTCHER)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Animal can't be butchered");
		problem = TRUE;
	}
	
	return problem;
}
Пример #24
0
void autoquest_trigger_check(struct char_data *ch, struct char_data *vict,
                struct obj_data *object, int type)
{
  struct char_data *i;
  qst_rnum rnum;
  int found = TRUE;

  if (IS_NPC(ch))
    return;
  if (GET_QUEST(ch) == NOTHING)  /* No current quest, skip this */
    return;
  if (GET_QUEST_TYPE(ch) != type)
    return;
  if ((rnum = real_quest(GET_QUEST(ch))) == NOTHING)
    return;
  switch (type) {
    case AQ_OBJ_FIND:
      if (QST_TARGET(rnum) == GET_OBJ_VNUM(object))
        generic_complete_quest(ch);
      break;
    case AQ_ROOM_FIND:
      if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number)
        generic_complete_quest(ch);
      break;
    case AQ_MOB_FIND:
      for (i=world[IN_ROOM(ch)].people; i; i = i->next_in_room)
        if (IS_NPC(i))
          if (QST_TARGET(rnum) == GET_MOB_VNUM(i))
            generic_complete_quest(ch);
      break;
    case AQ_MOB_KILL:
      if (!IS_NPC(ch) && IS_NPC(vict) && (ch != vict))
          if (QST_TARGET(rnum) == GET_MOB_VNUM(vict))
            generic_complete_quest(ch);
      break;
    case AQ_MOB_SAVE:
       if (ch == vict)
        found = FALSE;
      for (i = world[IN_ROOM(ch)].people; i && found; i = i->next_in_room)
          if (i && IS_NPC(i) && !MOB_FLAGGED(i, MOB_NOTDEADYET))
            if ((GET_MOB_VNUM(i) != QST_TARGET(rnum)) &&
                !AFF_FLAGGED(i, AFF_CHARM))
              found = FALSE;
      if (found)
        generic_complete_quest(ch);
      break;
    case AQ_OBJ_RETURN:
      if (IS_NPC(vict) && (GET_MOB_VNUM(vict) == QST_RETURNMOB(rnum)))
        if (object && (GET_OBJ_VNUM(object) == QST_TARGET(rnum)))
          generic_complete_quest(ch);
      break;
    case AQ_ROOM_CLEAR:
      if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number) {
        for (i = world[IN_ROOM(ch)].people; i && found; i = i->next_in_room)
          if (i && IS_NPC(i) && !MOB_FLAGGED(i, MOB_NOTDEADYET))
            found = FALSE;
        if (found)
   generic_complete_quest(ch);
      }
      break;
    default:
      log("SYSERR: Invalid quest type passed to autoquest_trigger_check");
      break;
  }
}
Пример #25
0
/*
 * Write the char to the file.
 *
 * @param ch the character to be written
 * @param fp the file to write to
 */
void fwrite_char( struct char_data *ch, FILE *fp )
{
  extern struct race_data * races;
  
  struct affected_type *paf;
  int          sn, i;
  
  fprintf( fp, "#%s\n", IS_NPC( ch ) ? "MOB" : "PLAYER"		);
  
  fprintf( fp, "Name        %s~\n",	GET_NAME(ch)			);
  fprintf( fp, "ShtDsc      %s~\n",	GET_SHORT_DESC(ch) ?
	   GET_SHORT_DESC(ch) : "" );
  fprintf( fp, "LngDsc      %s~\n",	GET_LONG_DESC(ch) ?
	   GET_LONG_DESC(ch) : "" );
  fprintf( fp, "Dscr        %s~\n",	GET_DESCRIPTION(ch) ?
	   GET_DESCRIPTION(ch) : "" );
  // fprintf( fp, "Prmpt       %s~\n",	ch->pcdata->prompt	);
  fprintf( fp, "Sx          %d\n",	GET_SEX(ch)			);
  fprintf( fp, "Race        %s~\n",	races[ (int)GET_RACE(ch) ].name );
  fprintf( fp, "Lvl         %d\n",	GET_LEVEL(ch)			);
  fprintf( fp, "Trst        %d\n",	GET_TRUST(ch)			);
  /*
    fprintf( fp, "Playd       %ld\n",
    GET_PLAYED(ch) + (int)( time( 0 ) - GET_LOGON(ch) )		);
  */
  // fprintf( fp, "Note        %ld\n",   (unsigned long)ch->last_note );
  fprintf( fp, "Room        %ld\n",
	   (  ch->in_room == NOWHERE && ch->was_in_room )
	   ? ch->was_in_room : ch->in_room );
  
  fprintf( fp, "HpMnMv      %d %d %d %d %d %d\n",
	   GET_HIT(ch), GET_MAX_HIT(ch),
	   GET_MANA(ch), GET_MAX_MANA(ch),
	   GET_MOVE(ch), GET_MAX_MOVE(ch) );
  fprintf( fp, "Gold        %ld\n",	GET_GOLD(ch)		);
  fprintf( fp, "Exp         %ld\n",	GET_EXP(ch)		);
  fprintf( fp, "Act         %lld\n",  PLR_FLAGS(ch)           );
  fprintf( fp, "Act2        %lld\n",  PLR2_FLAGS(ch)          );
  fprintf( fp, "Pref        %lld\n",  PRF_FLAGS(ch)		);
  fprintf( fp, "Pref2       %lld\n",  PRF2_FLAGS(ch)		);
  fprintf( fp, "AffdBy      %lld\n",	AFF_FLAGS(ch)		);
  fprintf( fp, "AffdBy2     %lld\n",	AFF2_FLAGS(ch)		);
  /* Bug fix from Alander */
  fprintf( fp, "Pos         %d\n",
	   GET_POS(ch) == POS_FIGHTING ? POS_STANDING : GET_POS(ch) );
  fprintf( fp, "Prac        %d\n",    GET_PRACTICES(ch)       );
  fprintf( fp, "PAlign      %d\n",	GET_PERMALIGN(ch)	);
  fprintf( fp, "CAlign      %d\n",	GET_ALIGNMENT(ch)	);
  fprintf( fp, "SavThr      " );
  for ( i = 0; i < NUM_SAVES; i++ )
    fprintf( fp, "%d%s",    GET_SAVE(ch, i), (i != NUM_SAVES-1 ? ", " : "\n")	);
  fprintf( fp, "Hitroll     %d\n",	GET_HITROLL(ch)		);
  fprintf( fp, "Damroll     %d\n",	GET_DAMROLL(ch)		);
  fprintf( fp, "Armr        " );
  for ( i = 0; i < ARMOR_LIMIT; i++ )
    fprintf( fp, "%d%s",   GET_AC(ch, i), (i != ARMOR_LIMIT-1 ? ", " : "\n") );
  fprintf( fp, "Wimp        %d\n",	GET_WIMP_LEV(ch)	);
  
  if ( IS_NPC( ch ) ) {
    fprintf( fp, "Vnum        %ld\n",	GET_MOB_VNUM(ch)	);
  } else {
    fprintf( fp, "Paswd       %s~\n",	GET_PASSWD(ch)		);
    fprintf( fp, "Poofin      %s~\n",	POOFIN(ch) ?
	     POOFIN(ch) : "" );
    fprintf( fp, "Poofout     %s~\n",	POOFOUT(ch) ?
	     POOFOUT(ch) : "" );
    fprintf( fp, "Ttle        %s~\n",	GET_TITLE(ch) ?
	     GET_TITLE(ch) : "" );
    fprintf( fp, "AtrPrm      %d/%d %d %d %d %d %d %d\n",
	     ch->real_abils.str,
	     ch->real_abils.str_add,
	     ch->real_abils.intel,
	     ch->real_abils.wis,
	     ch->real_abils.dex,
	     ch->real_abils.con,
	     ch->real_abils.cha,
	     ch->real_abils.will );
    
    fprintf( fp, "AtrMd       %d/%d %d %d %d %d %d %d\n",
	     ch->aff_abils.str, 
	     ch->aff_abils.str_add, 
	     ch->aff_abils.intel, 
	     ch->aff_abils.wis, 
	     ch->aff_abils.dex, 
	     ch->aff_abils.con, 
	     ch->aff_abils.cha, 
	     ch->aff_abils.will );
    
    fprintf( fp, "Conditions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_COND(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    fprintf( fp, "Addictions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_ADDICT(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    for ( sn = 0; sn < MAX_SKILLS; sn++ ) {
      if ( skill_name( sn ) &&
           strcmp( skill_name( sn ), "!UNUSED!" ) &&
           GET_SKILL(ch, sn) > 0 ) {
	fprintf( fp, "Skill       %d '%s'\n",
		 GET_SKILL(ch, sn),
		 skill_name( sn ) );
      }
    }
  }
  
  for ( paf = ch->affected; paf; paf = paf->next )  {
    fprintf( fp, "Afft       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  for ( paf = ch->affected2; paf; paf = paf->next )  {
    fprintf( fp, "Afft2       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  fprintf( fp, "End\n\n" );
  return;
}