示例#1
0
void SkeletalCreature::render(Surface *renderer, int xoffset, int yoffset) {
	bool mirror_body_parts = (world.variables["engine_mirror_creature_body_parts"] == 1);

	for (int j = 0; j < 17; j++) {
		int i = cee_zorder[posedirection][j];
		if (i >= SkeletalPartCount()) continue; // CV hackery

		if (engine.version == 1) // TODO: this is hackery to skip tails for C1
			if (i == 6 || i == 13) continue;

		bodypartinfo *part = &cee_bodyparts[i];

		unsigned int ourpose = pose[i];

		bool mirror = false;
		if (i != 14 && i != 15 && mirror_body_parts && ourpose >= 4 && ourpose <= 7) {
			ourpose -= 4;
			mirror = true;
		}

		// adjust for pregnancy/facial expressions/etc as necessary
		if (part->parent == -1) { // body
			ourpose += (pregnancy * (engine.version < 3 ? 10 : 16));
		} else if (i == 1) { // head
			ourpose += (eyesclosed ? (engine.version < 3 ? 10 : 16) : 0)
				+ (facialexpression * (engine.version < 3 ? 20 : 32));
		} else if (i == 16) { // hair
			ourpose += 0; // TODO: 16 * hair
		}

		assert(images[i]);

		renderer->render(images[i], ourpose, partx[i] + adjustx + xoffset, party[i] + adjusty + yoffset, false, 0, mirror);

		if (displaycore) {
			// TODO: we draw a lot of points twice here :)
			int atx = attachmentX(i, 0) + xoffset, aty = attachmentY(i, 0) + yoffset;
			renderer->renderLine(atx - 1, aty, atx + 1, aty, 0xFF0000CC);
			renderer->renderLine(atx, aty - 1, atx, aty + 1, 0xFF0000CC);
			atx = attachmentX(i, 1) + xoffset; aty = attachmentY(i, 1) + yoffset;
			renderer->renderLine(atx - 1, aty, atx + 1, aty, 0xFF0000CC);
			renderer->renderLine(atx, aty - 1, atx, aty + 1, 0xFF0000CC);
		}
	}
}
示例#2
0
void SkeletalCreature::setPose(unsigned int p) {
	posedirection = 0;
	for (int i = 0; i < SkeletalPartCount(); i++)
		pose[i] = p;
	recalculateSkeleton();
}
示例#3
0
void SkeletalCreature::recalculateSkeleton() {
	int lowestx = 0, lowesty = 0, highestx = 0, highesty = 0;

	for (int i = 0; i < SkeletalPartCount(); i++) {
		if (engine.version == 1) // TODO: this is hackery to skip tails for C1
			if (i == 6 || i == 13) continue;

		bodypartinfo *part = &cee_bodyparts[i];

		if (part->parent == -1) {
			partx[i] = 0; party[i] = 0;
		} else {
			attFile &bodyattinfo = att[0];
			attFile &attinfo = att[i];

			int attachx = att[i].attachments[pose[i]][0];
			int attachy = att[i].attachments[pose[i]][1];
			int x, y;

			if (part->parent == 0) { // linking to body
				x = bodyattinfo.attachments[pose[0]][part->attorder * 2];
				y = bodyattinfo.attachments[pose[0]][(part->attorder * 2) + 1];
			} else { // extra limb
				attFile &parentattinfo = att[part->parent];

				x = partx[part->parent] + parentattinfo.attachments[pose[part->parent]][part->attorder * 2]; 
				y = party[part->parent] + parentattinfo.attachments[pose[part->parent]][(part->attorder * 2) + 1];
			}

			x = x - attachx;
			y = y - attachy;

			partx[i] = x; party[i] = y;

			if (x < lowestx) { lowestx = x; }
			if (y < lowesty) { lowesty = y; }
			if (x + (int)images[i]->width(pose[i]) > highestx) { highestx = x + images[i]->width(pose[i]); }
			if (y + (int)images[i]->height(pose[i]) > highesty) { highesty = y + images[i]->height(pose[i]); }
		}
	}

	adjustx = -lowestx;
	adjusty = -lowesty;

	// TODO: muh, we should cooperate with physics system etc
	if (!carriedby && !invehicle && calculated) {
		int orig_footpart = (downfoot_left ? 11 : 12);
		// adjust location to match foot
		moveTo(x - (attachmentX(orig_footpart, 1) - oldfootx), y - (attachmentY(orig_footpart, 1) - oldfooty));
	}

	// work out which foot is down
	int leftfoot = attachmentY(11, 1);
	int rightfoot = attachmentY(12, 1);
	downfoot_left = (rightfoot < leftfoot);

	calculated = true;
	int orig_footpart = (downfoot_left ? 11 : 12);
	oldfootx = attachmentX(orig_footpart, 1);
	oldfooty = attachmentY(orig_footpart, 1);
	
	// recalculate width/height
	height = downfoot_left ? leftfoot : rightfoot;
	width = 50; // TODO: arbitary values bad

	// TODO: muh, we should cooperate with physics system etc
	/*if (carriedby || invehicle)
		downfootroom.reset();
	else
		snapDownFoot();*/
}
示例#4
0
void SkeletalCreature::skeletonInit() {
	// TODO: the exception throwing in here needs some more thought
	// TODO: if we throw an exception when we need to kill the creature off, else segfault :/

	for (int i = 0; i < SkeletalPartCount(); i++) { // CV hackery
		if (engine.version == 1) // TODO: this is hackery to skip tails for C1
			if (i == 6 || i == 13) continue;

		// reset the existing image reference
		images[i].reset();

		// find the relevant gene
		char x = cee_bodyparts[i].letter;
		creatureAppearanceGene *partapp = appearanceGeneForPart(x);

		int partspecies, partvariant;
		partspecies = creature->getGenus();
		if (partapp) {
			if (engine.version > 1) partspecies = partapp->species;
			partvariant = partapp->variant;
		} else {
			partvariant = creature->getVariant();
		}

		int spe = partspecies;

		/*
		 * In order to find a sprite, we try our current stage first, then the stages below us,
		 * and then we try again with all lower variants, and if that fails for female sprites
		 * then we try the whole thing again but trying to find a male sprite.
		 */

		// find relevant sprite
		bool tryfemale = creature->isFemale();
		while (!images[i]) {
			int var = partvariant;
			while (var > -1 && !images[i]) {
				int stage_to_try = creature->getStage();
				while (stage_to_try > -1 && !images[i]) {
					images[i] = world.gallery.getImage(x + dataString(stage_to_try, tryfemale, spe, var));
					stage_to_try--;
				}
				var--;
			}
			if (!tryfemale) break;
			tryfemale = false;
		}
		if (!images[i])
			throw creaturesException(boost::str(boost::format("SkeletalCreature couldn't find an image for part %c of species %d, variant %d, stage %d") % x % (int)partspecies % (int)partvariant % (int)creature->getStage()));
		
		// find relevant ATT data
		std::string attfilename;
		int var = partvariant;
		while (var > -1 && attfilename.empty()) {
			int stage_to_try = creature->getStage();
			while (stage_to_try > -1 && attfilename.empty()) {
				attfilename = world.findFile(std::string("/Body Data/") + x + dataString(stage_to_try, false, spe, var) + ".att");
				stage_to_try--;
			}
			var--;
		}
		if (attfilename.empty())
			throw creaturesException(boost::str(boost::format("SkeletalCreature couldn't find body data for part %c of species %d, variant %d, stage %d") % x % (int)partspecies % (int)partvariant % creature->getStage()));

		// load ATT file
		std::ifstream in(attfilename.c_str());
		if (in.fail())
			throw creaturesException(boost::str(boost::format("SkeletalCreature couldn't load body data for part %c of species %d, variant %d, stage %d (tried file %s)") % x % (int)partspecies % (int)partvariant % creature->getStage() % attfilename));
		in >> att[i];
		
		images[i] = tintBodySprite(images[i]);
	}
}