⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 charcontrol.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}

	// check if we have a kilt on, just like our robes
	if (cd.equipment[CS_PANTS] != 0) {
		try {
			const ItemRecord &item = items.get(cd.equipment[CS_PANTS]);
			int type = item.type;
			if (type==IT_PANTS) {
				ItemDisplayDB::Record r = itemdb.getById(item.model);
				if (r.getUInt(ItemDisplayDB::GeosetC)==1) 
					hadRobe = true;
			}
		} catch (...) {}
	}

	// dressup
	for (int i=0; i<NUM_CHAR_SLOTS; i++) {
		int sn = hadRobe ? slotOrderWithRobe[i] : slotOrder[i];
		if (cd.equipment[sn] != 0) AddEquipment(sn, cd.equipment[sn], 10+i, tex);
	}

	// reset geosets
	for (size_t j=0; j<model->geosets.size(); j++) {
		int id = model->geosets[j].id;

		// hide top-of-head if we have hair.
		if (id == 1) model->showGeosets[j] = bald;

		for (int i=1; i<16; i++) {
			int a = i*100, b = (i+1) * 100;
			if (id>a && id<b) model->showGeosets[j] = (id == (a + cd.geosets[i]));
		}
	}

	// finalize texture
	tex.compose(chartex);
	
	// set replacable textures
	model->replaceTextures[1] = chartex;
	model->replaceTextures[2] = capetex;
	model->replaceTextures[6] = hairtex;
	model->replaceTextures[8] = furtex;
	
	model->replaceTextures[11] = gobtex;

	/*
	for (int i=0; i<40; i++) {
		model->atts[i].dr = (model->atts[i].id==cd.hairStyle);
	}
	*/
}

void CharControl::RefreshNPCModel()
{
	if (hairtex != 0) {
		texturemanager.del(hairtex);
		hairtex = 0;
	}
	if (furtex != 0) {
		texturemanager.del(furtex);
		furtex = 0;
	}
	if (capetex != 0) {
		texturemanager.del(capetex);
		capetex = 0;
	}

	for (int i=0; i<16; i++) cd.geosets[i] = 1;

	// facial hair/decorations
	cd.geosets[1] = cd.geosets[2] = cd.geosets[3] = 0;

	// show ears
	cd.geosets[7] = 2;

	CharTexture tex;

	// base layer
	tex.addLayer(customSkin, CR_BASE, 0);
	
	CharSectionsDB::Record rec = chardb.getByParams(cd.race, cd.gender, CharSectionsDB::SkinType, 0, cd.skinColor, cd.useNPC);
	
	// Tauren fur
	const char *furtexname = rec.getString(CharSectionsDB::Tex2);
	if (strlen(furtexname)) furtex = texturemanager.add(furtexname);

	// facial hair geosets
	try {
		CharFacialHairDB::Record frec = facialhairdb.getByParams(cd.race, cd.gender, cd.facialHair);
		cd.geosets[1] = frec.getUInt(CharFacialHairDB::Geoset100);
		cd.geosets[2] = frec.getUInt(CharFacialHairDB::Geoset200);
		cd.geosets[3] = frec.getUInt(CharFacialHairDB::Geoset300);
	} catch (CharFacialHairDB::NotFound) {}
	
	// hair + hair on face
	try {
		CharSectionsDB::Record rec = chardb.getByParams(cd.race, cd.gender, CharSectionsDB::HairType, cd.hairStyle, cd.hairColor, cd.useNPC);
		const char* hairtexfn = rec.getString(CharSectionsDB::Tex1);
		if (strlen(hairtexfn)) 
			hairtex = texturemanager.add(hairtexfn);
		else {
			try {
				rec = chardb.getByParams(cd.race, cd.gender, CharSectionsDB::HairType, 1, cd.hairColor, cd.useNPC);
				hairtexfn = rec.getString(CharSectionsDB::Tex1);
				if (strlen(hairtexfn)) 
					hairtex = texturemanager.add(hairtexfn);
				else 
					hairtex = 0;
			} catch (CharSectionsDB::NotFound) {
				hairtex = 0;
			}
		}
		tex.addLayer(rec.getString(CharSectionsDB::Tex2), CR_FACE_LOWER, 3);
		tex.addLayer(rec.getString(CharSectionsDB::Tex3), CR_FACE_UPPER, 3);
	} catch (CharSectionsDB::NotFound) {
		hairtex = 0;
	}

	bool bald = false;
	
	// select hairstyle geoset(s)
	for (CharHairGeosetsDB::Iterator it = hairdb.begin(); it != hairdb.end(); ++it) {
		if (it->getUInt(CharHairGeosetsDB::Race)==cd.race && it->getUInt(CharHairGeosetsDB::Gender)==cd.gender) {
			unsigned int id = it->getUInt(CharHairGeosetsDB::Geoset);
			unsigned int section = it->getUInt(CharHairGeosetsDB::Section);
			if (id!=0) {
				for (size_t j=0; j<model->geosets.size(); j++) {
					if (model->geosets[j].id == id) {
						//std::cout << "Hair:\t" << id << "\t" << section << "\t" << ((cd.hairStyle==section) && cd.showHair) << "\n";
						model->showGeosets[j] = (cd.hairStyle==section);
					}
				}
			} else if (cd.hairStyle == section) 
				bald = true;
		}
	}
	
	// check if we have a robe on
	bool hadRobe = false;
	if (cd.equipment[CS_CHEST] != 0) {
		try {
			const ItemRecord &item = items.get(cd.equipment[CS_CHEST]);
			int type = item.type;
			if (type==IT_ROBE) {
				ItemDisplayDB::Record r = itemdb.getById(item.model);
				if (r.getUInt(ItemDisplayDB::GeosetC)==1) hadRobe = true;
			}
		} catch (...) {}
	}
	

	/*
	// check if we have a kilt on, just like our robes
	if (cd.equipment[CS_PANTS] != 0) {
		try {
			const ItemRecord &item = items.get(cd.equipment[CS_PANTS]);
			int type = item.type;
			if (type==IT_PANTS) {
				ItemDisplayDB::Record r = itemdb.getById(item.model);
				if (r.getUInt(ItemDisplayDB::GeosetC)==1) 
					hadRobe = true;
			}
		} catch (...) {}
	}
	*/

	// dressup
	for (int i=0; i<NUM_CHAR_SLOTS; i++) {
		int sn = hadRobe ? slotOrderWithRobe[i] : slotOrder[i];
		if (cd.equipment[sn] != 0) AddEquipment(sn, cd.equipment[sn], 10+i, tex);
	}
	

	// reset geosets
	for (size_t j=0; j<model->geosets.size(); j++) {
		int id = model->geosets[j].id;
		
		// hide top-of-head if we have hair.
		if (id == 1) model->showGeosets[j] = bald;

		for (int i=1; i<16; i++) {
			int a = i*100, b = (i+1) * 100;
			if (id>a && id<b) model->showGeosets[j] = (id == (a + cd.geosets[i]));
		}
	}

	// finalize texture
	tex.compose(chartex);
	
	// set replacable textures
	model->replaceTextures[1] = chartex;
	model->replaceTextures[2] = capetex;
	model->replaceTextures[6] = hairtex;
	model->replaceTextures[8] = furtex;
	
	model->replaceTextures[11] = gobtex;
}

void CharControl::AddEquipment(int slot, int itemnum, int layer, CharTexture &tex)
{
	if (slot==CS_PANTS && cd.geosets[13]==2) return; // if we are wearing a robe, no pants for us! ^_^

	try {
		const ItemRecord &item = items.get(itemnum);
		int type = item.type;
		ItemDisplayDB::Record r = itemdb.getById(item.model);

		// shirt sleeves
		if (type==IT_SHIRT || type==IT_CHEST || type==IT_ROBE) {
			cd.geosets[8] = 1 + r.getUInt(ItemDisplayDB::GeosetA);
		}

		// pants sleeves
		if (type==IT_PANTS) {
			cd.geosets[9] = 1 + r.getUInt(ItemDisplayDB::GeosetB);
		}

		// boots
		if (type==IT_BOOTS) {
			cd.geosets[5] = 1 + r.getUInt(ItemDisplayDB::GeosetA);
		}

		// gloves
		if (type==IT_GLOVES) {
			cd.geosets[4] = 1 + r.getUInt(ItemDisplayDB::GeosetA);
		}

		// Tabard
		if (type == IT_TABARD) {
			cd.geosets[12] = 2;
		}

		// capes
		if (type==IT_CAPE) {
			cd.geosets[15] = 1 + r.getUInt(ItemDisplayDB::GeosetA);
			// load the cape texture
			const char *tex = r.getString(ItemDisplayDB::Skin);
			if (tex && strlen(tex)) capetex = texturemanager.add(AnimControl::makeSkinTexture("Item\\ObjectComponents\\Cape\\",tex));
		}

		// robe
		if (cd.geosets[13]==1) cd.geosets[13] = 1 + r.getUInt(ItemDisplayDB::GeosetC);
		if (cd.geosets[13]==2) {
			cd.geosets[5] = 0;		// hide the boots
			cd.geosets[9] = 0;		// hide the pants
			cd.geosets[12] = 0;		// also hide the tabard.
		}

		// gloves - this is so gloves have preference over shirt sleeves.
		// must be a more 'accurate' way of checking against this.
		if (cd.geosets[4] > 1) cd.geosets[8] = 0;

		tex.addLayer(makeItemTexture(CR_ARM_UPPER,r.getString(ItemDisplayDB::TexArmUpper)).c_str(),CR_ARM_UPPER, layer);
		tex.addLayer(makeItemTexture(CR_ARM_LOWER,r.getString(ItemDisplayDB::TexArmLower)).c_str(),CR_ARM_LOWER, layer);
		tex.addLayer(makeItemTexture(CR_TORSO_UPPER,r.getString(ItemDisplayDB::TexChestUpper)).c_str(),CR_TORSO_UPPER, layer);
		tex.addLayer(makeItemTexture(CR_TORSO_LOWER,r.getString(ItemDisplayDB::TexChestLower)).c_str(),CR_TORSO_LOWER, layer);
		tex.addLayer(makeItemTexture(CR_LEG_UPPER,r.getString(ItemDisplayDB::TexLegUpper)).c_str(),CR_LEG_UPPER, layer);
		tex.addLayer(makeItemTexture(CR_LEG_LOWER,r.getString(ItemDisplayDB::TexLegLower)).c_str(),CR_LEG_LOWER, layer);
		tex.addLayer(makeItemTexture(CR_HAND,r.getString(ItemDisplayDB::TexHands)).c_str(),CR_HAND, layer);
		tex.addLayer(makeItemTexture(CR_FOOT,r.getString(ItemDisplayDB::TexFeet)).c_str(),CR_FOOT, layer);

		// Display our customised tabard
		if (type==IT_TABARD && td.showCustom)	{
			tex.addLayer(td.GetBackgroundTex(CR_TORSO_UPPER).c_str(), CR_TORSO_UPPER, layer);
			tex.addLayer(td.GetBackgroundTex(CR_TORSO_LOWER).c_str(), CR_TORSO_LOWER, layer);
			tex.addLayer(td.GetIconTex(CR_TORSO_UPPER).c_str(), CR_TORSO_UPPER, layer);
			tex.addLayer(td.GetIconTex(CR_TORSO_LOWER).c_str(), CR_TORSO_LOWER, layer);
			tex.addLayer(td.GetBorderTex(CR_TORSO_UPPER).c_str(), CR_TORSO_UPPER, layer);
			tex.addLayer(td.GetBorderTex(CR_TORSO_LOWER).c_str(), CR_TORSO_LOWER, layer);
		}

	} catch (ItemDisplayDB::NotFound) {}
}

void CharControl::RefreshItem(int slot)
{
	// delete all attachments in that slot
	charAtt->delSlot(slot);

	int itemnum = cd.equipment[slot];
	if (itemnum!=0) {
		// load new model(s)
		int id1=-1, id2=-1;
		string path;
		//float sc = 1.0f;

		if (slot==CS_HEAD) {
			id1 = 11;
			path = "Item\\ObjectComponents\\Head\\";
		}
		else if (slot==CS_SHOULDER) {
			id1 = 6;
			id2 = 5;
			path = "Item\\ObjectComponents\\Shoulder\\";
		}
		else if (slot == CS_HAND_LEFT) 
			id1 = 2;
		else if (slot == CS_HAND_RIGHT) 
			id1 = 1;
		else 
			return;

		if (slot==CS_HAND_LEFT || slot==CS_HAND_RIGHT) {
			if (items.get(itemnum).type == IT_SHIELD) {
				path = "Item\\ObjectComponents\\Shield\\";
				id1 = 0;
			}
			else 
				path = "Item\\ObjectComponents\\Weapon\\";

			// If we're sheathing our weapons, relocate the items to
			// their correct positions
			if (bSheathe && items.get(itemnum).sheath>0)
			{	
				id1 = items.get(itemnum).sheath;
				if (id1==32 && slot==CS_HAND_LEFT)
					id1 = 33;
				
				if (id1==26 && items.get(itemnum).subclass==7 && slot==CS_HAND_RIGHT)
					id1 = 27;

				/*
				26 = upper right back
				27 = upper left back
				28 = center back
				30 = upside down, upper left back -- staves, spears
				32 = left hip
				33 = right hip
				*/
			}
		}

		try {
			const ItemRecord &item = items.get(itemnum);
			ItemDisplayDB::Record r = itemdb.getById(item.model);

			GLuint tex;
			string mp;
			bool succ = false;
			Attachment *att = NULL;
			Model *m = NULL;

			if (id1>=0) {
				mp = path + r.getString(ItemDisplayDB::Model);

				if (slot==CS_HEAD) {
					// sigh, head items have more crap to sort out
					mp = mp.substr(0, mp.length()-4); // delete .mdx
					mp.append("_");
					try {
						CharRacesDB::Record race = racedb.getById(cd.race);
						mp.append(race.getString(CharRacesDB::ShortName));
						mp.append(cd.gender?"F":"M");
						mp.append(".m2");
					} catch (CharRacesDB::NotFound) {
						mp = "";
					}
				}

				if (mp.length()) {
					att = charAtt->addChild(mp.c_str(), id1, slot);
					if (att) {
						m = static_cast<Model*>(att->model);
						if (m->ok) {
							mp = path + r.getString(ItemDisplayDB::Skin);
							mp.append(".blp");
							tex = texturemanager.add(mp);
							m->replaceTextures[2] = tex;
							succ = true;
						}
					}
				}
			}
			if (id2>=0) {
				mp = path + r.getString(ItemDisplayDB::Model2);
				if (mp.length()) {
					att = charAtt->addChild(mp.c_str(), id2, slot);
					if (att) {
						m = static_cast<Model*>(att->model);
						if (m->ok) {
							mp = path + r.getString(ItemDisplayDB::Skin2);
							mp.append(".blp");
							tex = texturemanager.add(mp);
							m->replaceTextures[2] = tex;
							succ = true;
						}
					}
				}
			}

			if (succ) {
				// okay, see if we have any glowy effects

				int visualid = r.getInt(ItemDisplayDB::Visuals);
				
				if (visualid == 0) {
					if ((modelViewer->enchants->RHandEnchant > -1) && (slot == CS_HAND_RIGHT)) {
						visualid = modelViewer->enchants->RHandEnchant;
					} else if ((modelViewer->enchants->LHandEnchant > -1) && (slot == CS_HAND_LEFT)) {
						visualid = modelViewer->enchants->LHandEnchant;
					}
				}

				if (m == NULL)
					m = static_cast<Model*>(att->model);

				if (visualid > 0) {
					try {
						ItemVisualDB::Record vis = visualdb.getById(visualid);
						for (int i=0; i<5; i++) {
							// try all five visual slots
							int effectid = vis.getInt(ItemVisualDB::Effect1 + i);
							if (effectid==0 || m->attLookup[i]<0) continue;

							try {
								ItemVisualEffectDB::Record eff = effectdb.getById(effectid);
								const char *filename = eff.getString(ItemVisualEffectDB::Model);

								att->addChild(filename, i, -1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -