bool ControlTargetSpell::CanLaunch() { if(!ValidIONum(m_target)) { return false; } long tcount = 0; for(size_t ii = 1; ii < entities.size(); ii++) { const EntityHandle handle = EntityHandle(ii); Entity * ioo = entities[handle]; if(!ioo || !(ioo->ioflags & IO_NPC)) { continue; } if(ioo->_npcdata->lifePool.current <= 0.f || ioo->show != SHOW_FLAG_IN_SCENE) { continue; } if(ioo->groups.find("demon") == ioo->groups.end()) { continue; } if(closerThan(ioo->pos, m_caster_pos, 900.f)) { tcount++; } } if(tcount == 0) { return false; } return true; }
Vec3f SpellBase::getTargetPos(EntityHandle source, EntityHandle target) { Vec3f targetPos; if(target == EntityHandle()) { // no target... targeted by sight if(source == EntityHandle_Player) { // no target... player spell targeted by sight targetPos = player.pos; targetPos += angleToVectorXZ(player.angle.getYaw()) * 60.f; targetPos.y += std::sin(glm::radians(player.angle.getPitch())) * 60.f; } else { // TODO entities[target] with target < 0 ??? - uh oh! targetPos = entities[target]->pos; targetPos += angleToVectorXZ(entities[target]->angle.getYaw()) * 60.f; targetPos += Vec3f(0.f, -120.f, 0.f); } } else if(target == EntityHandle_Player) { // player target targetPos = player.pos; } else { // IO target targetPos = entities[target]->pos; } return targetPos; }
void SummonCreatureSpell::End() { lightHandleDestroy(m_light); // need to killio if(ValidIONum(m_summonedEntity)) { Entity * io = entities[m_summonedEntity]; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &io->pos); if(io->scriptload && (io->ioflags & IO_NOSAVE)) { AddRandomSmoke(io, 100); Vec3f posi = io->pos; posi.y -= 100.f; MakeCoolFx(posi); LightHandle nn = GetFreeDynLight(); if(lightHandleIsValid(nn)) { EERIE_LIGHT * light = lightHandleGet(nn); light->intensity = Random::getf(0.7f, 2.7f); light->fallend = 600.f; light->fallstart = 400.f; light->rgb = Color3f(1.0f, 0.8f, 0.0f); light->pos = posi; light->duration = 600; } io->destroyOne(); } } m_summonedEntity = EntityHandle(); }
void MassParalyseSpell::Launch() { ARX_SOUND_PlaySFX(SND_SPELL_MASS_PARALYSE); m_duration = (m_launchDuration > -1) ? m_launchDuration : 10000; for(size_t ii = 0; ii < entities.size(); ii++) { const EntityHandle handle = EntityHandle(ii); Entity * tio = entities[handle]; if(handle == m_caster || !tio || !(tio->ioflags & IO_NPC)) { continue; } if(tio->show != SHOW_FLAG_IN_SCENE) { continue; } if(tio->ioflags & IO_FREEZESCRIPT) { continue; } if(fartherThan(tio->pos, entities[m_caster]->pos, 500.f)) { continue; } tio->ioflags |= IO_FREEZESCRIPT; ARX_NPC_Kill_Spell_Launch(tio); m_targets.push_back(tio->index()); } }
void SummonCreatureSpell::Launch() { m_fManaCostPerSecond = 1.9f; m_requestSummon = false; m_summonedEntity = EntityHandle(); m_hasDuration = m_launchDuration >= 0; m_duration = m_hasDuration ? m_launchDuration : 0; Vec3f target; float beta; GetTargetAndBeta(target, beta); m_megaCheat = (m_caster == EntityHandle_Player && cur_mega == 10); m_targetPos = target; ARX_SOUND_PlaySFX(SND_SPELL_SUMMON_CREATURE, &m_targetPos); m_fissure.Create(target, MAKEANGLE(player.angle.getYaw())); m_fissure.SetDuration(GameDurationMs(2000), GameDurationMs(500), GameDurationMs(1500)); m_fissure.SetColorBorder(Color3f::red); m_fissure.SetColorRays1(Color3f::red); m_fissure.SetColorRays2(Color3f::yellow * .5f); EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 0.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f::red; light->pos = m_fissure.m_eSrc; } }
void Add3DBoom(const Vec3f & position) { Vec3f poss = position; ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &poss); float dist = fdist(player.pos - Vec3f(0, 160.f, 0.f), position); if(dist < 300) { Vec3f vect = (player.pos - position - Vec3f(0.f, 160.f, 0.f)) / dist; player.physics.forces += vect * ((300.f - dist) * 0.0125f); } for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * entity = entities[handle]; if(!entity || entity->show != 1 || !(entity->ioflags & IO_ITEM)) { continue; } if(!entity->obj || !entity->obj->pbox) { continue; } for(long k = 0; k < entity->obj->pbox->nb_physvert; k++) { float dist = fdist(entity->obj->pbox->vert[k].pos, position); if(dist < 300.f) { entity->obj->pbox->active = 1; entity->obj->pbox->stopcount = 0; Vec3f vect = (entity->obj->pbox->vert[k].pos - position) / dist; entity->obj->pbox->vert[k].velocity += vect * ((300.f - dist) * 10.f); } } } }
void SummonCreatureSpell::Launch() { m_hasDuration = true; m_fManaCostPerSecond = 1.9f; m_requestSummon = false; m_summonedEntity = EntityHandle(); m_duration = (m_launchDuration > -1) ? m_launchDuration : 2000000; Vec3f target; float beta; GetTargetAndBeta(target, beta); m_megaCheat = (m_caster == PlayerEntityHandle && cur_mega == 10); m_targetPos = target; ARX_SOUND_PlaySFX(SND_SPELL_SUMMON_CREATURE, &m_targetPos); m_fissure.Create(target, MAKEANGLE(player.angle.getPitch())); m_fissure.SetDuration(2000, 500, 1500); m_fissure.SetColorBorder(Color3f::red); m_fissure.SetColorRays1(Color3f::red); m_fissure.SetColorRays2(Color3f::yellow * .5f); m_light = GetFreeDynLight(); if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = 0.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f::red; light->pos = m_fissure.m_eSrc; } }
void MassIncinerateSpell::Launch() { ARX_SOUND_PlaySFX(SND_SPELL_MASS_INCINERATE); m_duration = 20000; long nb_targets=0; for(size_t ii = 0; ii < entities.size(); ii++) { const EntityHandle handle = EntityHandle(ii); Entity * tio = entities[handle]; if(handle == m_caster || !tio || !(tio->ioflags & IO_NPC)) { continue; } if(tio->_npcdata->lifePool.current <= 0.f || tio->show != SHOW_FLAG_IN_SCENE) { continue; } if(fartherThan(tio->pos, entities[m_caster]->pos, 500.f)) { continue; } tio->sfx_flag |= SFX_TYPE_YLSIDE_DEATH | SFX_TYPE_INCINERATE; tio->sfx_time = arxtime.now_ul(); nb_targets++; m_targets.push_back(tio->index()); } if(nb_targets) { m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_INCINERATE_LOOP, &m_caster_pos, 1.f, ARX_SOUND_PLAY_LOOPED); } else { m_snd_loop = audio::INVALID_ID; } }
static void drawDebugEntities() { for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * entity = entities[handle]; if(!entity) { continue; } Color color = Color::white; bool visible = true; switch(entity->show) { case SHOW_FLAG_DESTROYED: continue; // Don't even display the name case SHOW_FLAG_IN_INVENTORY: continue; case SHOW_FLAG_ON_PLAYER: continue; case SHOW_FLAG_LINKED: continue; case SHOW_FLAG_NOT_DRAWN: color = Color::magenta; visible = false; break; case SHOW_FLAG_HIDDEN: color = Color::yellow; visible = false; break; case SHOW_FLAG_MEGAHIDE: color = Color::green; visible = false; break; case SHOW_FLAG_KILLED: color = Color::red; visible = false; break; case SHOW_FLAG_IN_SCENE: color = Color::white; visible = true; break; case SHOW_FLAG_TELEPORTING: color = Color::blue; visible = true; break; } if((entity->ioflags & IO_CAMERA) || (entity->ioflags & IO_MARKER)) { color = Color::gray(0.7f), visible = false; } if(DRAGINTER == entity) { color = Color::white, visible = true; } if(visible) { drawDebugBoundingBox(entity->bbox2D, Color::blue); } if(closerThan(entity->pos, player.pos, DebugTextMaxDistance)) { if(visible && entity->bbox2D.valid()) { int x = (entity->bbox2D.min.x + entity->bbox2D.max.x) / 2; int y = entity->bbox2D.min.y - hFontDebug->getLineHeight() - 2; UNICODE_ARXDrawTextCenter(hFontDebug, Vec2f(x, y), entity->idString(), color); } else { drawTextAt(hFontDebug, entity->pos, entity->idString(), color); } if(entity->obj) { for(size_t j = 0; j < entity->obj->linked.size(); j++) { Vec3f pos = actionPointPosition(entity->obj, entity->obj->linked[j].lidx); Entity * other = entity->obj->linked[j].io; drawTextAt(hFontDebug, pos, other->idString(), Color::cyan); } } } } }
void CheckForIgnition(const Vec3f & pos, float radius, bool mode, long flag) { if(!(flag & 1)) for(size_t i = 0; i < MAX_LIGHTS; i++) { EERIE_LIGHT * el = GLight[i]; if(el == NULL) continue; if((el->extras & EXTRAS_EXTINGUISHABLE) && (el->extras & (EXTRAS_SEMIDYNAMIC | EXTRAS_SPAWNFIRE | EXTRAS_SPAWNSMOKE))) { if((el->extras & EXTRAS_FIREPLACE) && (flag & 2)) continue; if(!fartherThan(pos, el->pos, radius)) { if(mode) { if (!(el->extras & EXTRAS_NO_IGNIT)) el->m_ignitionStatus = true; } else { el->m_ignitionStatus = false; } } } } for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * io = entities[handle]; if( io && io->show == SHOW_FLAG_IN_SCENE && io->obj && !(io->ioflags & IO_UNDERWATER) && io->obj->fastaccess.fire >= 0 ) { if(closerThan(pos, io->obj->vertexlist3[io->obj->fastaccess.fire].v, radius)) { if(mode && io->ignition <= 0 && io->obj->fastaccess.fire >= 0) { io->ignition = 1; } else if(!mode && io->ignition > 0) { if(io->obj->fastaccess.fire >= 0) { io->ignition = 0; lightHandleDestroy(io->ignit_light); if(io->ignit_sound != audio::INVALID_ID) { ARX_SOUND_Stop(io->ignit_sound); io->ignit_sound = audio::INVALID_ID; } } else if(!(flag & 2)) io->ignition = 0.00001f; } } } } }
//! \brief Releases Equiped Id from player static void ARX_EQUIPMENT_Release(EntityHandle id) { if(ValidIONum(id)) { for(size_t i = 0; i < MAX_EQUIPED; i++) { if(player.equiped[i] == id) { player.equiped[i] = EntityHandle(); } } } }
void ARX_SCRIPT_ResetAll(bool init) { for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * e = entities[handle]; if(e && !e->scriptload) { ARX_SCRIPT_Reset(e, init); } } }
Entity * EntityManager::getById(const std::string & name, Entity * self) const { EntityHandle handle = getById(name); if(handle == EntityHandle()) { return NULL; } else if(handle == EntityHandle_Self) { return self; } else { return entries[handle.handleData()]; } }
void ARX_NPC_RestoreCuts() { for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * e = entities[handle]; if(e && (e->ioflags & IO_NPC) && e->_npcdata->cuts) { ARX_NPC_ApplyCuts(e); } } }
EntityHandle EntityManager::getById(const std::string & idString) const { if(idString.empty() || idString == "none") { return EntityHandle::Invalid; } else if(idString == "self" || idString == "me") { return EntityHandle(-2); } else if(idString == "player") { return PlayerEntityHandle; } return m_impl->getById(idString); }
EntityHandle EntityManager::getById(const std::string & idString) const { if(idString.empty() || idString == "none") { return EntityHandle(); } else if(idString == "self" || idString == "me") { return EntityHandle_Self; } else if(idString == "player") { return EntityHandle_Player; } return m_impl->getById(idString); }
static void drawDebugEntityPhysicsCylinders() { for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * entity = entities[handle]; if(!entity || !closerThan(entity->pos, player.pos, DebugPhysicsMaxDistance)) continue; drawDebugCollisionShape(entity->obj); drawDebugEntityPhysicsCylinder(entity); } }
void RenderSystem::receive(const AnimationChangedMessage& msg) { auto animatedSprite = getAnimatedSprite(msg.entity); auto render = entityx::Entity(msg.entity).component<RenderComponent>(); if(render->currentAnimation != animatedSprite->getCurrentAnimation()) { std::string oldAnimation = animatedSprite->getCurrentAnimation(); animatedSprite->setCurrentAnimation(render->currentAnimation); if(render->onAnimationChangedFunc.valid()) render->onAnimationChangedFunc.call(EntityHandle(msg.entity), oldAnimation, render->currentAnimation); } }
EntityHandle EntityManager::getById(const EntityId & id) const { if(id.isSpecial()) { if(id.className().empty()) { return EntityHandle::Invalid; } else if(id.className() == "self" || id.className() == "me") { return EntityHandle(-2); } else if(id.className() == "player") { return PlayerEntityHandle; } } return m_impl->getById(id.string()); }
static void EntityLeavingLastZone(Entity * io, ARX_PATH * last) { SendIOScriptEvent(NULL, io, SM_LEAVEZONE, last->name); if(!last->controled.empty()) { EntityHandle t = entities.getById(last->controled); if(t != EntityHandle()) { ScriptParameters parameters; parameters.push_back(io->idString()); parameters.push_back(last->name); SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters); } } }
void ARX_EQUIPMENT_UnEquipPlayerWeapon() { if(ValidIONum(player.equiped[EQUIP_SLOT_WEAPON])) { Entity * pioOldDragInter = DRAGINTER; DRAGINTER = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(DRAGINTER) ARX_SOUND_PlayInterface(SND_INVSTD); ARX_EQUIPMENT_UnEquip(entities.player(), entities[player.equiped[EQUIP_SLOT_WEAPON]]); DRAGINTER = pioOldDragInter; } player.equiped[EQUIP_SLOT_WEAPON] = EntityHandle(); }
static EERIE_3DOBJ * GetExistingEerie(const res::path & file) { for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * e = entities[handle]; if(e != NULL && !e->tweaky && e->obj) { EERIE_3DOBJ * obj = e->obj; if(!obj->originaltextures && e->obj->file == file) { return e->obj; } } } return NULL; }
static void EntityEnteringCurrentZone2(Entity * io, ARX_PATH * current) { io->inzone_show = io->show; SendIOScriptEvent(NULL, io, SM_ENTERZONE, current->name); if(!current->controled.empty()) { EntityHandle t = entities.getById(current->controled); if(t != EntityHandle()) { ScriptParameters parameters; parameters.push_back(io->idString()); parameters.push_back(current->name); SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters); } } }
void CControlTarget::Create(Vec3f aeSrc, float afBeta) { SetDuration(ulDuration); eSrc = aeSrc; float fBetaRad = glm::radians(afBeta); float fBetaRadCos = glm::cos(fBetaRad); float fBetaRadSin = glm::sin(fBetaRad); eTarget = eSrc + Vec3f(-fBetaRadSin * 1000.f, 100.f, fBetaRadCos * 1000.f); for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * e = entities[handle]; if(e) { eTarget = e->pos; } } int end = 20 - 1; v1a[0].p = eSrc + Vec3f(0.f, 100.f, 0.f); v1a[end].p = eTarget; Vec3f h; Vec3f s = eSrc; Vec3f e = eSrc; int i = 0; while(Visible(s, e, NULL, &h) && i < 20) { e.x -= fBetaRadSin * 50; e.z += fBetaRadCos * 50; i++; } pathways[0].p = eSrc + Vec3f(0.f, 100.f, 0.f); pathways[9].p = eTarget; Split(pathways, 0, 9, 150); for(int i = 0; i < 9; i++) { if(pathways[i].p.y >= eSrc.y + 150) { pathways[i].p.y = eSrc.y + 150; } } fTrail = 0; }
ScriptResult SendMsgToAllIO(ScriptMessage msg, const std::string & params) { ScriptResult ret = ACCEPT; for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * e = entities[handle]; if(e) { if(SendIOScriptEvent(e, msg, params) == REFUSE) { ret = REFUSE; } } } return ret; }
bool ARX_DAMAGES_TryToDoDamage(const Vec3f & pos, float dmg, float radius, EntityHandle source) { bool ret = false; for(size_t i = 0; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * io = entities[handle]; if(io != NULL && (entities[handle]->gameFlags & GFLAG_ISINTREATZONE) && io->show == SHOW_FLAG_IN_SCENE && source != handle ) { float threshold; float rad = radius + 5.f; if(io->ioflags & IO_FIX) { threshold = 510; rad += 10.f; } else if(io->ioflags & IO_NPC) { threshold = 250; } else { threshold = 350; } if(closerThan(pos, io->pos, threshold) && SphereInIO(io, Sphere(pos, rad))) { if(io->ioflags & IO_NPC) { if(ValidIONum(source)) ARX_EQUIPMENT_ComputeDamages(entities[source], io, 1.f); ret = true; } if(io->ioflags & IO_FIX) { ARX_DAMAGES_DamageFIX(io, dmg, source, false); ret = true; } } } } return ret; }
void RiseDeadSpell::Launch() { float beta; Vec3f target; GetTargetAndBeta(target, beta); m_targetPos = target; ARX_SOUND_PlaySFX(SND_SPELL_RAISE_DEAD, &m_targetPos); // TODO this tolive value is probably never read m_duration = (m_launchDuration > -1) ? m_launchDuration : 2000000; m_hasDuration = true; m_fManaCostPerSecond = 1.2f; m_creationFailed = false; m_entity = EntityHandle(); m_fissure.Create(target, beta); m_fissure.SetDuration(2000, 500, 1800); m_fissure.SetColorBorder(Color3f(0.5, 0.5, 0.5)); m_fissure.SetColorRays1(Color3f(0.5, 0.5, 0.5)); m_fissure.SetColorRays2(Color3f(1.f, 0.f, 0.f)); if(!lightHandleIsValid(m_light)) { m_light = GetFreeDynLight(); } if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = 1.3f; light->fallend = 450.f; light->fallstart = 380.f; light->rgb = Color3f::black; light->pos = target - Vec3f(0.f, 100.f, 0.f); light->duration = 200; light->time_creation = (unsigned long)(arxtime); } m_duration = m_fissure.GetDuration(); }
bool ARX_SPELLS_AnalyseSPELL() { SpellcastFlags flags = 0; if(GInput->actionPressed(CONTROLS_CUST_STEALTHMODE) || bPrecastSpell) { flags |= SPELLCAST_FLAG_PRECAST; } bPrecastSpell = false; SpellType spell; if(SpellSymbol[0] == RUNE_MEGA && SpellSymbol[1] == RUNE_MEGA && SpellSymbol[2] == RUNE_MEGA && SpellSymbol[3] == RUNE_AAM && SpellSymbol[4] == RUNE_VITAE && SpellSymbol[5] == RUNE_TERA) { cur_mega = 10; spell = SPELL_SUMMON_CREATURE; } else { spell = getSpell(SpellSymbol); } if(spell == SPELL_NONE) { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); if(player.SpellToMemorize.bSpell) { CurrSpellSymbol = 0; player.SpellToMemorize.bSpell = false; } return false; } return ARX_SPELLS_Launch(spell, EntityHandle_Player, flags, -1, EntityHandle(), ArxDuration(-1)); }
void ARX_SCRIPT_AllowInterScriptExec() { ARX_PROFILE_FUNC(); // FIXME static local variable static long ppos = 0; if(arxtime.is_paused()) { return; } EVENT_SENDER = NULL; long heartbeat_count = std::min(long(entities.size()), 10l); for(long n = 0; n < heartbeat_count; n++) { EntityHandle i = EntityHandle(ppos++); if(i >= long(entities.size())){ ppos = 0; return; } if(entities[i] == NULL || !(entities[i]->gameFlags & GFLAG_ISINTREATZONE)) { continue; } if(!entities[i]->mainevent.empty()) { // Copy the even name to a local variable as it may change during execution // and cause unexpected behavior in SendIOScriptEvent std::string event = entities[i]->mainevent; SendIOScriptEvent(entities[i], SM_NULL, std::string(), event); } else { SendIOScriptEvent(entities[i], SM_MAIN); } } }
//----------------------------------------------------------------------------- // Spawns a Projectile using type, starting position/TargetPosition void ARX_MISSILES_Spawn(Entity * io, ARX_SPELLS_MISSILE_TYPE type, const Vec3f & startpos, const Vec3f & targetpos) { long i(ARX_MISSILES_GetFree()); if (i == -1) return; missiles[i].owner = (io == NULL) ? EntityHandle() : io->index(); missiles[i].type = type; missiles[i].lastpos = missiles[i].startpos = startpos; float dist; dist = 1.0F / fdist(startpos, targetpos); missiles[i].velocity = (targetpos - startpos) * dist; missiles[i].lastupdate = missiles[i].timecreation = (unsigned long)(arxtime); switch (type) { case MISSILE_NONE: break; case MISSILE_FIREBALL: { missiles[i].tolive = 6000; missiles[i].velocity *= 0.8f; missiles[i].longinfo = GetFreeDynLight(); if(lightHandleIsValid(missiles[i].longinfo)) { EERIE_LIGHT * light = lightHandleGet(missiles[i].longinfo); light->intensity = 1.3f; light->fallend = 420.f; light->fallstart = 250.f; light->rgb = Color3f(1.f, .8f, .6f); light->pos = startpos; } ARX_SOUND_PlaySFX(SND_SPELL_FIRE_WIND, &missiles[i].startpos, 2.0F); ARX_SOUND_PlaySFX(SND_SPELL_FIRE_LAUNCH, &missiles[i].startpos, 2.0F); } } }