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; }
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; }
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"); }
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); }
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); } }
/* 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); }
/** * 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)); } }
/* 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); }
/** * 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; }
/* 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))); }
/* 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))); }
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); }
/* 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); }
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); } } }
/* 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); }
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"); }
/* * 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); }
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() */ }
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() }
/* 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); }
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; }
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; }
/** * 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; }
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; } }
/* * 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; }