/** * 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)); } }
// update sects HASH_ITER(hh, sector_table, sect, next_sect) { found = delete_mob_from_spawn_list(&GET_SECT_SPAWNS(sect), vnum); found |= delete_from_interaction_list(&GET_SECT_INTERACTIONS(sect), TYPE_MOB, vnum); if (found) { save_library_file_for_vnum(DB_BOOT_SECTOR, GET_SECT_VNUM(sect)); } }
// update room templates HASH_ITER(hh, room_template_table, rmt, next_rmt) { found = delete_from_spawn_template_list(&GET_RMT_SPAWNS(rmt), ADV_SPAWN_MOB, vnum); found |= delete_from_interaction_list(&GET_RMT_INTERACTIONS(rmt), TYPE_MOB, vnum); if (found) { save_library_file_for_vnum(DB_BOOT_RMT, GET_RMT_VNUM(rmt)); } }
// update crops HASH_ITER(hh, crop_table, crop, next_crop) { found = delete_mob_from_spawn_list(&GET_CROP_SPAWNS(crop), vnum); found |= delete_from_interaction_list(&GET_CROP_INTERACTIONS(crop), TYPE_MOB, vnum); if (found) { save_library_file_for_vnum(DB_BOOT_CROP, GET_CROP_VNUM(crop)); } }
// crafts HASH_ITER(hh, craft_table, craft, next_craft) { if (GET_CRAFT_TYPE(craft) == CRAFT_TYPE_BUILD && GET_CRAFT_BUILD_TYPE(craft) == vnum) { GET_CRAFT_BUILD_TYPE(craft) = NOTHING; SET_BIT(GET_CRAFT_FLAGS(craft), CRAFT_IN_DEVELOPMENT); save_library_file_for_vnum(DB_BOOT_CRAFT, GET_CRAFT_VNUM(craft)); } }
/** * 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; } }
/** * Function to save a player's changes to an craft recipe (or a new one). * * @param descriptor_data *desc The descriptor who is saving. */ void save_olc_craft(descriptor_data *desc) { extern int sort_crafts_by_data(craft_data *a, craft_data *b); craft_data *proto, *craft = GET_OLC_CRAFT(desc); craft_vnum vnum = GET_OLC_VNUM(desc); UT_hash_handle hh, sorted_hh; // have a place to save it? if (!(proto = craft_proto(vnum))) { proto = create_craft_table_entry(vnum); } // free prototype strings and pointers if (GET_CRAFT_NAME(proto)) { free(GET_CRAFT_NAME(proto)); } if (GET_CRAFT_RESOURCES(proto)) { free(GET_CRAFT_RESOURCES(proto)); } // sanity if (!GET_CRAFT_NAME(craft) || !*GET_CRAFT_NAME(craft)) { if (GET_CRAFT_NAME(craft)) { free(GET_CRAFT_NAME(craft)); } GET_CRAFT_NAME(craft) = str_dup("unnamed recipe"); } // save data back over the proto-type hh = proto->hh; // save old hash handles sorted_hh = proto->sorted_hh; *proto = *craft; // copy all data proto->vnum = vnum; // ensure correct vnum proto->hh = hh; // restore hash handles proto->sorted_hh = sorted_hh; // and save to file save_library_file_for_vnum(DB_BOOT_CRAFT, vnum); // ... and re-sort HASH_SRT(sorted_hh, sorted_crafts, sort_crafts_by_data); }
/** * Creates a new crop entry. * * @param crop_vnum vnum The number to create. * @return crop_data* The new crop's prototype. */ crop_data* create_crop_table_entry(crop_vnum vnum) { void add_crop_to_table(crop_data *crop); crop_data *crop; // sanity if (crop_proto(vnum)) { log("SYSERR: Attempting to insert crop at existing vnum %d", vnum); return crop_proto(vnum); } CREATE(crop, crop_data, 1); init_crop(crop); GET_CROP_VNUM(crop) = vnum; add_crop_to_table(crop); // save index and crop file now save_index(DB_BOOT_CROP); save_library_file_for_vnum(DB_BOOT_CROP, vnum); return crop; }
/** * Creates a new craft table entry. * * @param craft_vnum vnum The number to create. * @return craft_data* The new recipe's prototypes. */ craft_data *create_craft_table_entry(craft_vnum vnum) { void add_craft_to_table(craft_data *craft); craft_data *craft; // sanity if (craft_proto(vnum)) { log("SYSERR: Attempting to insert craft at existing vnum %d", vnum); return craft_proto(vnum); } CREATE(craft, craft_data, 1); init_craft(craft); GET_CRAFT_VNUM(craft) = vnum; add_craft_to_table(craft); // save index and craft file now save_index(DB_BOOT_CRAFT); save_library_file_for_vnum(DB_BOOT_CRAFT, vnum); return craft; }
/** * Creates a new building entry. * * @param bld_vnum vnum The number to create. * @return bld_data *The new building's prototype. */ bld_data *create_building_table_entry(bld_vnum vnum) { void add_building_to_table(bld_data *bld); bld_data *bld; // sanity if (building_proto(vnum)) { log("SYSERR: Attempting to insert building at existing vnum %d", vnum); return building_proto(vnum); } CREATE(bld, bld_data, 1); init_building(bld); GET_BLD_VNUM(bld) = vnum; add_building_to_table(bld); // save index and building file now save_index(DB_BOOT_BLD); save_library_file_for_vnum(DB_BOOT_BLD, vnum); return bld; }
/** * Creates a new mob entry. * * @param mob_vnum vnum The number to create. * @return char_data* The new mob's prototype. */ char_data *create_mob_table_entry(mob_vnum vnum) { void add_mobile_to_table(char_data *mob); char_data *mob; // sanity if (mob_proto(vnum)) { log("SYSERR: Attempting to insert mobile at existing vnum %d", vnum); return mob_proto(vnum); } CREATE(mob, char_data, 1); clear_char(mob); mob->vnum = vnum; SET_BIT(MOB_FLAGS(mob), MOB_ISNPC); // need this for some macroes add_mobile_to_table(mob); // 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); return mob; }
/** * 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); }
// update objects HASH_ITER(hh, object_table, obj, next_obj) { if (OBJ_FLAGGED(obj, OBJ_PLANTABLE) && GET_OBJ_VAL(obj, VAL_FOOD_CROP_TYPE) == vnum) { GET_OBJ_VAL(obj, VAL_FOOD_CROP_TYPE) = NOTHING; save_library_file_for_vnum(DB_BOOT_OBJ, GET_OBJ_VNUM(obj)); } }
// update mob interactions HASH_ITER(hh, mobile_table, mob_iter, next_mob) { if (delete_from_interaction_list(&mob_iter->interactions, TYPE_MOB, vnum)) { save_library_file_for_vnum(DB_BOOT_MOB, mob_iter->vnum); } }
// update globals HASH_ITER(hh, globals_table, glb, next_glb) { found = delete_from_interaction_list(&GET_GLOBAL_INTERACTIONS(glb), TYPE_MOB, vnum); if (found) { save_library_file_for_vnum(DB_BOOT_GLB, GET_GLOBAL_VNUM(glb)); } }
/** * 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)); } }