/**
* Checks for common craft recipe problems and reports them to ch.
*
* @param craft_data *craft The item 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_craft(craft_data *craft, char_data *ch) {
	bool problem = FALSE;

	if (GET_CRAFT_REQUIRES_OBJ(craft) == NOTHING && GET_CRAFT_ABILITY(craft) == NO_ABIL) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft requires no object or ability");
		problem = TRUE;
	}
	if (IS_SET(GET_CRAFT_FLAGS(craft), CRAFT_IN_DEVELOPMENT)) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "IN-DEVELOPMENT");
		problem = TRUE;
	}
	if (!IS_SET(GET_CRAFT_FLAGS(craft), CRAFT_APIARIES | CRAFT_GLASS) && GET_CRAFT_RESOURCES(craft)[0].vnum == NOTHING) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft requires no resources");
		problem = TRUE;
	}
	if (!IS_SET(GET_CRAFT_FLAGS(craft), CRAFT_SOUP) && (GET_CRAFT_OBJECT(craft) == NOTHING || !obj_proto(GET_CRAFT_OBJECT(craft))) && (GET_CRAFT_BUILD_TYPE(craft) == NOTHING || !building_proto(GET_CRAFT_BUILD_TYPE(craft)))) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft makes nothing");
		problem = TRUE;
	}
	if (!str_cmp(GET_CRAFT_NAME(craft), "unnamed recipe")) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft not named");
		problem = TRUE;
	}
	if (GET_CRAFT_TYPE(craft) == CRAFT_TYPE_ERROR) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft type not set");
		problem = TRUE;
	}
	if (GET_CRAFT_TYPE(craft) != CRAFT_TYPE_BUILD && GET_CRAFT_OBJECT(craft) != NOTHING && GET_CRAFT_OBJECT(craft) != GET_CRAFT_VNUM(craft)) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft creates item with different vnum");
		problem = TRUE;
	}
	if (GET_CRAFT_TYPE(craft) == CRAFT_TYPE_BUILD && GET_CRAFT_BUILD_TYPE(craft) != NOTHING && GET_CRAFT_BUILD_TYPE(craft) != GET_CRAFT_VNUM(craft)) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft creates building with different vnum");
		problem = TRUE;
	}
	if (GET_CRAFT_QUANTITY(craft) == 0 && GET_CRAFT_TYPE(craft) != CRAFT_TYPE_BUILD) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft creates 0 quantity");
		problem = TRUE;
	}
	if (GET_CRAFT_TIME(craft) == 0 && GET_CRAFT_TYPE(craft) != CRAFT_TYPE_BUILD) {
		olc_audit_msg(ch, GET_CRAFT_VNUM(craft), "Craft requires 0 time");
		problem = TRUE;
	}
		
	return problem;
}
Example #2
0
/**
* formerly obj_from_store
*
* @param FILE *fl The open item file.
* @param obj_vnum vnum The vnum of the item being loaded, or NOTHING for non-prototyped item.
* @param int *location A place to bind the current WEAR_x position of the item; also used to track container contents.
* @param char_data *notify Optional: A person to notify if an item is updated (NULL for none).
* @return obj_data* The loaded item, or NULL if it's not available.
*/
obj_data *Obj_load_from_file(FILE *fl, obj_vnum vnum, int *location, char_data *notify) {
	void scale_item_to_level(obj_data *obj, int level);

	char line[MAX_INPUT_LENGTH], error[MAX_STRING_LENGTH], s_in[MAX_INPUT_LENGTH];
	obj_data *proto = obj_proto(vnum);
	struct extra_descr_data *ex;
	obj_data *obj, *new;
	bool end = FALSE;
	int length, i_in[3];
	int l_in;
	bool seek_end = FALSE;
	
	// up-front
	*location = 0;
	
	// load based on vnum or, if NOTHING, create anonymous object
	if (proto) {
		obj = read_object(vnum, FALSE);
	}
	else {
		// what we do here depends on input ... if the vnum was real, but no proto, it's a deleted obj
		if (vnum == NOTHING) {
			obj = create_obj();
		}
		else {
			obj = NULL;
			seek_end = TRUE;	// signal it to skip obj data
		}
	}
	
	// default to version 0
	if (obj) {
		OBJ_VERSION(obj) = 0;
	}
	
	// for fread_string
	sprintf(error, "Obj_load_from_file %d", vnum);
	
	// for more readable if/else chain	
	#define OBJ_FILE_TAG(src, tag, len)  (!strn_cmp((src), (tag), ((len) = strlen(tag))))

	while (!end) {
		if (!get_line(fl, line)) {
			log("SYSERR: Unexpected end of obj file in Obj_load_from_file");
			exit(1);
		}
		
		if (OBJ_FILE_TAG(line, "End", length)) {
			end = TRUE;
		}
		else if (seek_end) {
			// are we looking for the end of the object? ignore this line
			// WARNING: don't put any ifs that require "obj" above seek_end; obj is not guaranteed
			continue;
		}
		else if (OBJ_FILE_TAG(line, "Version:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				OBJ_VERSION(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Location:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0]) == 1) {
				*location = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Keywords:", length)) {
			if (GET_OBJ_KEYWORDS(obj) && (!proto || GET_OBJ_KEYWORDS(obj) != GET_OBJ_KEYWORDS(proto))) {
				free(GET_OBJ_KEYWORDS(obj));
			}
			GET_OBJ_KEYWORDS(obj) = fread_string(fl, error);
		}
		else if (OBJ_FILE_TAG(line, "Short-desc:", length)) {
			if (GET_OBJ_SHORT_DESC(obj) && (!proto || GET_OBJ_SHORT_DESC(obj) != GET_OBJ_SHORT_DESC(proto))) {
				free(GET_OBJ_SHORT_DESC(obj));
			}
			GET_OBJ_SHORT_DESC(obj) = fread_string(fl, error);
		}
		else if (OBJ_FILE_TAG(line, "Long-desc:", length)) {
			if (GET_OBJ_LONG_DESC(obj) && (!proto || GET_OBJ_LONG_DESC(obj) != GET_OBJ_LONG_DESC(proto))) {
				free(GET_OBJ_LONG_DESC(obj));
			}
			GET_OBJ_LONG_DESC(obj) = fread_string(fl, error);
		}
		else if (OBJ_FILE_TAG(line, "Action-desc:", length)) {
			if (GET_OBJ_ACTION_DESC(obj) && (!proto || GET_OBJ_ACTION_DESC(obj) != GET_OBJ_ACTION_DESC(proto))) {
				free(GET_OBJ_ACTION_DESC(obj));
			}
			GET_OBJ_ACTION_DESC(obj) = fread_string(fl, error);
		}
		else if (OBJ_FILE_TAG(line, "Extra-desc:", length)) {
			if (proto && obj->ex_description == proto->ex_description) {
				obj->ex_description = NULL;
			}
			
			CREATE(ex, struct extra_descr_data, 1);
			ex->next = obj->ex_description;
			obj->ex_description = ex;
			
			ex->keyword = fread_string(fl, error);
			ex->description = fread_string(fl, error);
		}
		else if (OBJ_FILE_TAG(line, "Val-0:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_VAL(obj, 0) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Val-1:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_VAL(obj, 1) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Val-2:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_VAL(obj, 2) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Type:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_TYPE(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Wear:", length)) {
			if (sscanf(line + length + 1, "%s", s_in)) {
				GET_OBJ_WEAR(obj) = asciiflag_conv(s_in);
			}
		}
		else if (OBJ_FILE_TAG(line, "Flags:", length)) {
			if (sscanf(line + length + 1, "%s", s_in)) {
				GET_OBJ_EXTRA(obj) = asciiflag_conv(s_in);
			}
		}
		else if (OBJ_FILE_TAG(line, "Affects:", length)) {
			if (sscanf(line + length + 1, "%s", s_in)) {
				obj->obj_flags.bitvector = asciiflag_conv(s_in);
			}
		}
		else if (OBJ_FILE_TAG(line, "Timer:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_TIMER(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Current-scale:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_CURRENT_SCALE_LEVEL(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Min-scale:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_MIN_SCALE_LEVEL(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Max-scale:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_MAX_SCALE_LEVEL(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Material:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_OBJ_MATERIAL(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Last-empire:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				obj->last_empire_id = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Last-owner:", length)) {
			if (sscanf(line + length + 1, "%d", &l_in)) {
				obj->last_owner_id = l_in;
			}
		}
		else if (OBJ_FILE_TAG(line, "Stolen-timer:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				obj->stolen_timer = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Autostore-timer:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				GET_AUTOSTORE_TIMER(obj) = i_in[0];
			}
		}
		else if (OBJ_FILE_TAG(line, "Apply:", length)) {
			if (sscanf(line + length + 1, "%d %d %d", &i_in[0], &i_in[1], &i_in[2])) {
				obj->affected[i_in[0]].location = i_in[1];
				obj->affected[i_in[0]].modifier = i_in[2];
			}
		}
		else if (OBJ_FILE_TAG(line, "Bound-to:", length)) {
			if (sscanf(line + length + 1, "%d", &i_in[0])) {
				struct obj_binding *bind;
				CREATE(bind, struct obj_binding, 1);
				bind->idnum = i_in[0];
				bind->next = OBJ_BOUND_TO(obj);
				OBJ_BOUND_TO(obj) = bind;
			}
		}
		else if (OBJ_FILE_TAG(line, "Trigger:", length)) {