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); }