Esempio n. 1
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));
		}
	}
/**
* WARNING: This function actually deletes a crop.
*
* @param char_data *ch The person doing the deleting.
* @param crop_vnum vnum The vnum to delete.
*/
void olc_delete_crop(char_data *ch, crop_vnum vnum) {
	void remove_crop_from_table(crop_data *crop);
	extern const sector_vnum climate_default_sector[NUM_CLIMATES];
	
	obj_data *obj, *next_obj;
	descriptor_data *desc;
	struct map_data *map;
	room_data *room;
	crop_data *crop;
	sector_data *base = NULL;
	int count;
	
	if (!(crop = crop_proto(vnum))) {
		msg_to_char(ch, "There is no such crop %d.\r\n", vnum);
		return;
	}
	
	if (HASH_COUNT(crop_table) <= 1) {
		msg_to_char(ch, "You can't delete the last crop.\r\n");
		return;
	}

	// remove it from the hash table first
	remove_crop_from_table(crop);
	
	// save base sect for later
	base = sector_proto(climate_default_sector[GET_CROP_CLIMATE(crop)]);

	// save index and crop file now
	save_index(DB_BOOT_CROP);
	save_library_file_for_vnum(DB_BOOT_CROP, vnum);
	
	// update world
	count = 0;
	LL_FOREACH(land_map, map) {
		room = real_real_room(map->vnum);
		
		if (map->crop_type == crop || (room && ROOM_CROP(room) == crop)) {
			if (!room) {
				room = real_room(map->vnum);
			}
			set_crop_type(room, NULL);	// remove it explicitly
			change_terrain(room, GET_SECT_VNUM(base));
			++count;
		}
	}
/**
* WARNING: This function actually deletes a craft recipe.
*
* @param char_data *ch The person doing the deleting.
* @param craft_vnum vnum The vnum to delete.
*/
void olc_delete_craft(char_data *ch, craft_vnum vnum) {
	void cancel_gen_craft(char_data *ch);
	void remove_craft_from_table(craft_data *craft);
	
	craft_data *craft;
	char_data *iter;
	
	if (!(craft = craft_proto(vnum))) {
		msg_to_char(ch, "There is no such craft %d.\r\n", vnum);
		return;
	}
	
	if (HASH_COUNT(craft_table) <= 1) {
		msg_to_char(ch, "You can't delete the last craft.\r\n");
		return;
	}
	
	// find players who are crafting it and stop them (BEFORE removing from table)
	for (iter = character_list; iter; iter = iter->next) {
		if (!IS_NPC(iter) && GET_ACTION(iter) == ACT_GEN_CRAFT && GET_ACTION_VNUM(iter, 0) == GET_CRAFT_VNUM(craft)) {
			msg_to_char(iter, "The craft you were making has been deleted.\r\n");
			cancel_gen_craft(iter);
		}
	}
	
	// remove from table -- nothing else to check here
	remove_craft_from_table(craft);

	// save index and craft file now
	save_index(DB_BOOT_CRAFT);
	save_library_file_for_vnum(DB_BOOT_CRAFT, vnum);
	
	syslog(SYS_OLC, GET_INVIS_LEV(ch), TRUE, "OLC: %s has deleted craft recipe %d", GET_NAME(ch), vnum);
	msg_to_char(ch, "Craft recipe %d deleted.\r\n", vnum);
	
	free_craft(craft);
}
/**
* Searches for all uses of a craft and displays them.
*
* @param char_data *ch The player.
* @param craft_vnum vnum The craft vnum.
*/
void olc_search_craft(char_data *ch, craft_vnum vnum) {
	char buf[MAX_STRING_LENGTH];
	craft_data *craft = craft_proto(vnum);
	int size, found;
	
	if (!craft) {
		msg_to_char(ch, "There is no craft %d.\r\n", vnum);
		return;
	}
	
	found = 0;
	size = snprintf(buf, sizeof(buf), "Occurrences of craft %d (%s):\r\n", vnum, GET_CRAFT_NAME(craft));
	
	// crafts are not found anywhere in the world yet
	
	if (found > 0) {
		size += snprintf(buf + size, sizeof(buf) - size, "%d location%s shown\r\n", found, PLURAL(found));
	}
	else {
		size += snprintf(buf + size, sizeof(buf) - size, " none\r\n");
	}
	
	page_string(ch->desc, buf, TRUE);
}
/**
* WARNING: This function actually deletes a building.
*
* @param char_data *ch The person doing the deleting.
* @param bld_vnum vnum The vnum to delete.
*/
void olc_delete_building(char_data *ch, bld_vnum vnum) {
	void check_for_bad_buildings();
	extern bool delete_link_rule_by_type_value(struct adventure_link_rule **list, int type, any_vnum value);
	void remove_building_from_table(bld_data *bld);
	
	descriptor_data *desc;
	room_data *room, *next_room;
	craft_data *craft, *next_craft;
	adv_data *adv, *next_adv;
	bld_data *bld;
	int count;
	bool found, deleted = FALSE;
	
	if (!(bld = building_proto(vnum))) {
		msg_to_char(ch, "There is no such building %d.\r\n", vnum);
		return;
	}
	
	if (HASH_COUNT(building_table) <= 1) {
		msg_to_char(ch, "You can't delete the last building.\r\n");
		return;
	}
	
	// pull from hash
	remove_building_from_table(bld);

	// save index and building file now
	save_index(DB_BOOT_BLD);
	save_library_file_for_vnum(DB_BOOT_BLD, vnum);
	
	// update world
	count = 0;
	HASH_ITER(world_hh, world_table, room, next_room) {
		if (IS_ANY_BUILDING(room) && BUILDING_VNUM(room) == vnum) {
			if (GET_ROOM_VNUM(room) >= MAP_SIZE) {
				delete_room(room, FALSE);	// must call check_all_exits
				deleted = TRUE;
			}
			else {
				// map room
				if (ROOM_PEOPLE(room)) {
					act("The building has been deleted.", FALSE, ROOM_PEOPLE(room), NULL, NULL, TO_CHAR | TO_ROOM);
				}
				disassociate_building(room);
			}
		}
	}
	if (deleted) {
		check_all_exits();
	}
	
	// adventure zones
	HASH_ITER(hh, adventure_table, adv, next_adv) {
		found = delete_link_rule_by_type_value(&GET_ADV_LINKING(adv), ADV_LINK_BUILDING_EXISTING, vnum);
		found |= delete_link_rule_by_type_value(&GET_ADV_LINKING(adv), ADV_LINK_BUILDING_NEW, vnum);
		found |= delete_link_rule_by_type_value(&GET_ADV_LINKING(adv), ADV_LINK_PORTAL_BUILDING_EXISTING, vnum);
		found |= delete_link_rule_by_type_value(&GET_ADV_LINKING(adv), ADV_LINK_PORTAL_BUILDING_NEW, vnum);
		
		if (found) {
			save_library_file_for_vnum(DB_BOOT_ADV, GET_ADV_VNUM(adv));
		}
	}