void RiseDeadSpell::Update(float timeDelta) { if(m_creationFailed) { m_light = LightHandle(); return; } m_duration+=200; m_fissure.Update(timeDelta); m_fissure.Render(); if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = 0.7f + 2.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(0.8f, 0.2f, 0.2f); light->duration=800; light->time_creation = (unsigned long)(arxtime); } unsigned long tim = m_fissure.ulCurrentTime; if(tim > 3000 && m_entity == EntityHandle() && !m_creationFailed) { ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &m_targetPos); Cylinder phys = Cylinder(m_targetPos, 50, -200); float anything = CheckAnythingInCylinder(phys, NULL, CFLAG_JUST_TEST); if(glm::abs(anything) < 30) { const char * cls = "graph/obj3d/interactive/npc/undead_base/undead_base"; Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD); if(io) { ARX_INTERACTIVE_HideGore(io); RestoreInitialIOStatusOfIO(io); io->summoner = m_caster; io->ioflags|=IO_NOSAVE; m_entity = io->index(); io->scriptload=1; ARX_INTERACTIVE_Teleport(io, phys.origin); SendInitScriptEvent(io); if(ValidIONum(m_caster)) { EVENT_SENDER = entities[m_caster]; } else { EVENT_SENDER = NULL; } SendIOScriptEvent(io,SM_SUMMONED); Vec3f pos = m_fissure.m_eSrc; pos += randomVec3f() * 100.f; pos += Vec3f(-50.f, 50.f, -50.f); MakeCoolFx(pos); } m_light = LightHandle(); } else { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); m_creationFailed = true; m_duration=0; } } else if(!arxtime.is_paused() && tim < 4000) { if(Random::getf() > 0.95f) { MakeCoolFx(m_fissure.m_eSrc); } } }
bool Manage3DCursor(Entity * io, bool simulate) { arx_assert(io); if(BLOCK_PLAYER_CONTROLS) return false; float ag = player.angle.getYaw(); if(ag > 180) ag = ag - 360; float drop_miny = (float)(g_size.center().y) - g_size.center().y * (ag * (1.f/70)); if(DANAEMouse.y < drop_miny) return false; Anglef temp = Anglef::ZERO; if(io->ioflags & IO_INVERTED) { temp.setYaw(180.f); temp.setPitch(-MAKEANGLE(270.f - io->angle.getPitch() - (player.angle.getPitch() - STARTED_ANGLE))); } else { temp.setPitch(MAKEANGLE(270.f - io->angle.getPitch() - (player.angle.getPitch() - STARTED_ANGLE))); } EERIE_3D_BBOX bbox; for(size_t i = 0; i < io->obj->vertexlist.size(); i++) { bbox.add(io->obj->vertexlist[i].v); } Vec3f mvectx = angleToVectorXZ(player.angle.getPitch() - 90.f); Vec2f mod = Vec2f(Vec2i(DANAEMouse) - g_size.center()) / Vec2f(g_size.center()) * Vec2f(160.f, 220.f); mvectx *= mod.x; Vec3f mvecty(0, mod.y, 0); Vec3f orgn = player.pos; orgn += angleToVector(player.angle) * 50.f; orgn += mvectx; orgn.y += mvecty.y; Vec3f dest = player.pos; dest += angleToVector(player.angle) * 10000.f; dest += mvectx; dest.y += mvecty.y * 5.f; Vec3f pos = orgn; Vec3f movev = glm::normalize(dest - orgn); float lastanything = 0.f; float height = -(bbox.max.y - bbox.min.y); if(height > -30.f) height = -30.f; Vec3f objcenter = bbox.min + (bbox.max - bbox.min) * Vec3f(0.5f); Vec3f collidpos = Vec3f_ZERO; bool collidpos_ok = false; { float maxdist = 0.f; for(size_t i = 0; i < io->obj->vertexlist.size(); i++) { const EERIE_VERTEX & vert = io->obj->vertexlist[i]; float dist = glm::distance(Vec2f(objcenter.x, objcenter.z), Vec2f(vert.v.x, vert.v.z)) - 4.f; maxdist = std::max(maxdist, dist); } if(io->obj->pbox) { Vec2f tmpVert(io->obj->pbox->vert[0].initpos.x, io->obj->pbox->vert[0].initpos.z); for(int i = 1; i < io->obj->pbox->nb_physvert; i++) { const PHYSVERT & physVert = io->obj->pbox->vert[i]; float dist = glm::distance(tmpVert, Vec2f(physVert.initpos.x, physVert.initpos.z)) + 14.f; maxdist = std::max(maxdist, dist); } } Cylinder cyl2; const float inc = 10.f; long iterating = 40; cyl2.height = std::min(-30.f, height); cyl2.radius = glm::clamp(maxdist, 20.f, 150.f); while(iterating > 0) { cyl2.origin = pos + movev * inc + Vec3f(0.f, bbox.max.y, 0.f); float anything = CheckAnythingInCylinder(cyl2, io, CFLAG_JUST_TEST | CFLAG_COLLIDE_NOCOL | CFLAG_NO_NPC_COLLIDE); if(anything < 0.f) { if(iterating == 40) { CANNOT_PUT_IT_HERE = 1; // TODO is this correct ? return true; } iterating = 0; collidpos = cyl2.origin; if(lastanything < 0.f) { pos.y += lastanything; collidpos.y += lastanything; } } else { pos = cyl2.origin; lastanything = anything; } iterating--; } collidpos_ok = iterating == -1; } objcenter = VRotateY(objcenter, temp.getPitch()); collidpos.x -= objcenter.x; collidpos.z -= objcenter.z; pos.x -= objcenter.x; pos.z -= objcenter.z; if(!collidpos_ok) { CANNOT_PUT_IT_HERE = 1; return false; } if(collidpos_ok && closerThan(player.pos, pos, 300.f)) { if(simulate) { ARX_INTERACTIVE_Teleport(io, pos, true); io->gameFlags &= ~GFLAG_NOCOMPUTATION; glm::quat rotation = glm::toQuat(toRotationMatrix(temp)); if(SPECIAL_DRAGINTER_RENDER) { if(glm::abs(lastanything) > glm::abs(height)) { TransformInfo t(collidpos, rotation, io->scale); static const float invisibility = 0.5f; DrawEERIEInter(io->obj, t, io, false, invisibility); } else { TransformInfo t(pos, rotation, io->scale); float invisibility = Cedric_GetInvisibility(io); DrawEERIEInter(io->obj, t, io, false, invisibility); } } } else { if(glm::abs(lastanything) > std::min(glm::abs(height), 12.0f)) { Entity * io = DRAGINTER; ARX_PLAYER_Remove_Invisibility(); io->obj->pbox->active = 1; io->obj->pbox->stopcount = 0; io->pos = collidpos; io->velocity = Vec3f_ZERO; io->stopped = 1; movev.x *= 0.0001f; movev.y = 0.1f; movev.z *= 0.0001f; Vec3f viewvector = movev; Anglef angle = temp; io->soundtime = 0; io->soundcount = 0; EERIE_PHYSICS_BOX_Launch(io->obj, io->pos, angle, viewvector); ARX_SOUND_PlaySFX(SND_WHOOSH, &pos); io->show = SHOW_FLAG_IN_SCENE; Set_DragInter(NULL); } else { ARX_PLAYER_Remove_Invisibility(); ARX_SOUND_PlayInterface(SND_INVSTD); ARX_INTERACTIVE_Teleport(io, pos, true); io->angle.setYaw(temp.getYaw()); io->angle.setPitch(270.f - temp.getPitch()); io->angle.setRoll(temp.getRoll()); io->stopped = 0; io->show = SHOW_FLAG_IN_SCENE; io->obj->pbox->active = 0; Set_DragInter(NULL); } } GRenderer->SetCulling(Renderer::CullNone); return true; } else { CANNOT_PUT_IT_HERE=-1; } return false; }
void SummonCreatureSpell::Update() { if(arxtime.is_paused()) return; float elapsed = arxtime.now_f() - m_timcreation; if(elapsed <= 4000) { if(Random::getf() > 0.7f) { Vec3f pos = m_fissure.m_eSrc; MakeCoolFx(pos); } m_fissure.Update(g_framedelay); m_fissure.Render(); m_requestSummon = true; m_summonedEntity = EntityHandle(); } else if(m_requestSummon) { lightHandleDestroy(m_light); m_requestSummon = false; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &m_targetPos); Cylinder phys = Cylinder(m_targetPos, 50, -200); float anything = CheckAnythingInCylinder(phys, NULL, CFLAG_JUST_TEST); if(glm::abs(anything) < 30) { long tokeep; res::path cls; if(m_megaCheat) { if(Random::getf() > 0.5f) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else { tokeep = 0; cls = "graph/obj3d/interactive/npc/y_mx/y_mx"; } } else if(Random::getf() > 0.997f || (sp_max && Random::getf() > 0.8f) || (cur_mr >= 3 && Random::getf() > 0.3f)) { tokeep = 0; cls = "graph/obj3d/interactive/npc/y_mx/y_mx"; } else if(Random::getf() > 0.997f || (cur_rf >= 3 && Random::getf() > 0.8f) || (cur_mr >= 3 && Random::getf() > 0.3f)) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else if(m_level >= 9) { tokeep = 1; cls = "graph/obj3d/interactive/npc/demon/demon"; } else if(Random::getf() > 0.98f) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else { tokeep = 0; cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base"; } Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD); if(!io) { cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base"; tokeep = 0; io = AddNPC(cls, -1, IO_IMMEDIATELOAD); } if(io) { RestoreInitialIOStatusOfIO(io); io->summoner = m_caster; io->scriptload = 1; if(tokeep == 1) { io->ioflags |= IO_NOSAVE; } io->pos = phys.origin; SendInitScriptEvent(io); if(tokeep < 0) { io->scale=1.65f; io->physics.cyl.radius=25; io->physics.cyl.height=-43; io->speed_modif=1.f; } if(ValidIONum(m_caster)) { EVENT_SENDER = entities[m_caster]; } else { EVENT_SENDER = NULL; } SendIOScriptEvent(io,SM_SUMMONED); for(long j = 0; j < 3; j++) { Vec3f pos = m_fissure.m_eSrc; pos += randomVec3f() * 100.f; pos += Vec3f(-50.f, 50.f, -50.f); MakeCoolFx(pos); } if(tokeep==1) m_summonedEntity = io->index(); else m_summonedEntity = EntityHandle(); } } } else if(m_summonedEntity == EntityHandle()) { m_duration = 0; } }