Exemplo n.º 1
0
static EERIE_3DOBJ * TheoToEerie_Fast(const res::path & texpath, const res::path & file, bool pbox) {
	
	EERIE_3DOBJ * ret = ARX_FTL_Load(file);
	if(ret) {
		if(pbox) {
			EERIE_PHYSICS_BOX_Create(ret);
		}
		return ret;
	}
	
#if !BUILD_EDIT_LOADSAVE
	ARX_UNUSED(texpath);
#else
	
	ret = GetExistingEerie(file);
	if(ret) {
		ret = Eerie_Copy(ret);
	}
	
	if(!ret) {
		
		size_t size = 0;
		char * adr = resources->readAlloc(file, size);
		if(!adr) {
			LogWarning << "Object not found: " << file;
			return NULL;
		}
		
		ret = TheoToEerie(adr, size, texpath, file);
		if(!ret) {
			free(adr);
			return NULL;
		}
		
		EERIE_OBJECT_CenterObjectCoordinates(ret);
		free(adr);
	}
	
	CreateNeighbours(ret);
	EERIEOBJECT_AddClothesData(ret);
	KillNeighbours(ret);
	
	if(ret->cdata) {
		EERIE_COLLISION_SPHERES_Create(ret); // Must be out of the Neighbours zone
	}
	
	if(pbox) {
		EERIE_PHYSICS_BOX_Create(ret);
	}
	
	ARX_FTL_Save(fs::paths.user / file.string(), ret);
	
#endif // BUILD_EDIT_LOADSAVE
	
	return ret;
}
/*!
 * \brief Spawns a body part from NPC
 * \param ioo
 * \param num
 */
static void ARX_NPC_SpawnMember(Entity * ioo, ObjSelection num) {
	
	if(!ioo)
		return;

	EERIE_3DOBJ * from = ioo->obj;

	if(!from || num == ObjSelection() || (size_t)num.handleData() >= from->selections.size())
		return;

	EERIE_3DOBJ * nouvo = new EERIE_3DOBJ;

	if(!nouvo)
		return;

	size_t nvertex = from->selections[num.handleData()].selected.size();

	long gore = -1;

	for(size_t k = 0; k < from->texturecontainer.size(); k++) {
		if(from->texturecontainer[k]
		   && boost::contains(from->texturecontainer[k]->m_texName.string(), "gore"))
		{
			gore = k;
			break;
		}
	}

	for(size_t k = 0; k < from->facelist.size(); k++) {
		if(from->facelist[k].texid == gore) {
			if(   IsNearSelection(from, from->facelist[k].vid[0], num)
			   || IsNearSelection(from, from->facelist[k].vid[1], num)
			   || IsNearSelection(from, from->facelist[k].vid[2], num)
			) {
				nvertex += 3;
			}
		}
	}

	nouvo->vertexlist.resize(nvertex);
	nouvo->vertexlist3.resize(nvertex);

	long inpos = 0;
	long * equival = (long *)malloc(sizeof(long) * from->vertexlist.size());
	if(!equival) {
		delete nouvo;
		return;
	}

	for(size_t k = 0; k < from->vertexlist.size(); k++) {
		equival[k] = -1;
	}
	
	const EERIE_SELECTIONS & cutSelection = from->selections[num.handleData()];

	arx_assert(0 < cutSelection.selected.size());

	for(size_t k = 0; k < cutSelection.selected.size(); k++) {
		inpos = cutSelection.selected[k];
		equival[cutSelection.selected[k]] = k;
		
		nouvo->vertexlist[k] = from->vertexlist[cutSelection.selected[k]];
		nouvo->vertexlist[k].v = from->vertexlist3[cutSelection.selected[k]].v;
		nouvo->vertexlist[k].v -= ioo->pos;
		nouvo->vertexlist[k].vert.p = nouvo->vertexlist[k].v;
		
		nouvo->vertexlist[k].vert.color = from->vertexlist[k].vert.color;
		nouvo->vertexlist[k].vert.uv = from->vertexlist[k].vert.uv;
		
		nouvo->vertexlist3[k] = nouvo->vertexlist[k];
	}

	size_t count = cutSelection.selected.size();

	for(size_t k = 0; k < from->facelist.size(); k++) {
		if(from->facelist[k].texid == gore) {
			if(   IsNearSelection(from, from->facelist[k].vid[0], num)
			   || IsNearSelection(from, from->facelist[k].vid[1], num)
			   || IsNearSelection(from, from->facelist[k].vid[2], num)
			) {
				for(long j = 0; j < 3; j++) {
					equival[from->facelist[k].vid[j]] = count;

					if(count < nouvo->vertexlist.size()) {
						nouvo->vertexlist[count] = from->vertexlist[from->facelist[k].vid[j]];
						nouvo->vertexlist[count].v = from->vertexlist3[from->facelist[k].vid[j]].v;
						nouvo->vertexlist[count].v -= ioo->pos;
						nouvo->vertexlist[count].vert.p = nouvo->vertexlist[count].v;

						nouvo->vertexlist3[count] = nouvo->vertexlist[count];
					} else {
						equival[from->facelist[k].vid[j]] = -1;
					}

					count++;
				}
			}
		}
	}

	float min = nouvo->vertexlist[0].vert.p.y;
	long nummm = 0;

	for(size_t k = 1; k < nouvo->vertexlist.size(); k++) {
		if(nouvo->vertexlist[k].vert.p.y > min) {
			min = nouvo->vertexlist[k].vert.p.y;
			nummm = k;
		}
	}
	
	nouvo->origin = nummm;
	nouvo->point0 = nouvo->vertexlist[nouvo->origin].v;
	
	for(size_t k = 0; k < nouvo->vertexlist.size(); k++) {
		nouvo->vertexlist[k].vert.p = nouvo->vertexlist[k].v -= nouvo->point0;
		nouvo->vertexlist[k].vert.color = Color(255, 255, 255, 255).toRGBA();
	}
	
	nouvo->point0 = Vec3f_ZERO;
	
	nouvo->pbox = NULL;
	nouvo->pdata = NULL;
	nouvo->cdata = NULL;
	nouvo->sdata = NULL;
	nouvo->ndata = NULL;
	
	size_t nfaces = 0;
	for(size_t k = 0; k < from->facelist.size(); k++) {
		if(   equival[from->facelist[k].vid[0]] != -1
		   && equival[from->facelist[k].vid[1]] != -1
		   && equival[from->facelist[k].vid[2]] != -1
		) {
			nfaces++;
		}
	}

	if(nfaces) {
		nouvo->facelist.reserve(nfaces);

		for(size_t k = 0; k < from->facelist.size(); k++) {
			if(   equival[from->facelist[k].vid[0]] != -1
			   && equival[from->facelist[k].vid[1]] != -1
			   && equival[from->facelist[k].vid[2]] != -1
			) {
				EERIE_FACE newface = from->facelist[k];
				newface.vid[0] = (unsigned short)equival[from->facelist[k].vid[0]];
				newface.vid[1] = (unsigned short)equival[from->facelist[k].vid[1]];
				newface.vid[2] = (unsigned short)equival[from->facelist[k].vid[2]];
				nouvo->facelist.push_back(newface);
			}
		}

		long gore = -1;

		for(size_t k = 0; k < from->texturecontainer.size(); k++) {
			if(from->texturecontainer[k]
			   && boost::contains(from->texturecontainer[k]->m_texName.string(), "gore")
			) {
				gore = k;
				break;
			}
		}

		for(size_t k = 0; k < nouvo->facelist.size(); k++) {
			nouvo->facelist[k].facetype &= ~POLY_HIDE;

			if(nouvo->facelist[k].texid == gore) {
				nouvo->facelist[k].facetype |= POLY_DOUBLESIDED;
			}
		}
	}
	
	free(equival);
	nouvo->texturecontainer = from->texturecontainer;
	
	nouvo->linked.clear();
	nouvo->originaltextures = NULL;
	
	Entity * io = new Entity("noname", EntityInstance(0));
	
	io->_itemdata = new IO_ITEMDATA();
	
	io->ioflags = IO_ITEM | IO_NOSAVE | IO_MOVABLE;
	io->script.size = 0;
	io->script.data = NULL;
	io->gameFlags |= GFLAG_NO_PHYS_IO_COL;
	
	EERIE_COLLISION_Cylinder_Create(io);
	EERIE_PHYSICS_BOX_Create(nouvo);
	if(!nouvo->pbox){
		delete nouvo;
		return;
	}
	
	io->infracolor = Color3f::blue * 0.8f;
	io->collision = COLLIDE_WITH_PLAYER;
	io->m_icon = NULL;
	io->scriptload = 1;
	io->obj = nouvo;
	io->lastpos = io->initpos = io->pos = ioo->obj->vertexlist3[inpos].v;
	io->angle = ioo->angle;
	
	io->gameFlags = ioo->gameFlags;
	io->halo = ioo->halo;
	
	io->angle.setYaw(Random::getf(340.f, 380.f));
	io->angle.setPitch(Random::getf(0.f, 360.f));
	io->angle.setRoll(0);
	io->obj->pbox->active = 1;
	io->obj->pbox->stopcount = 0;
	
	io->velocity = Vec3f_ZERO;
	io->stopped = 1;
	
	Vec3f vector;
	vector.x = -std::sin(glm::radians(io->angle.getPitch()));
	vector.y = std::sin(glm::radians(io->angle.getYaw())) * 2.f;
	vector.z = std::cos(glm::radians(io->angle.getPitch()));
	vector = glm::normalize(vector);
	io->rubber = 0.6f;
	
	io->no_collide = ioo->index();
	
	io->gameFlags |= GFLAG_GOREEXPLODE;
	io->animBlend.lastanimtime = arxtime.now_ul();
	io->soundtime = 0;
	io->soundcount = 0;

	EERIE_PHYSICS_BOX_Launch(io->obj, io->pos, io->angle, vector);
}