void CMultiMagicMissile::CheckCollision() { if(!pTab) return; for(unsigned int i = 0; i < uiNumber; i++) { if(pTab[i]) { CMagicMissile * pMM = (CMagicMissile *) pTab[i]; if(!pMM->bExplo) { EERIE_SPHERE sphere; sphere.origin = pMM->eCurPos; sphere.radius = 10.f; if(spellinstance != -1 && (CheckAnythingInSphere(&sphere, spells[spellinstance].caster, CAS_NO_SAME_GROUP))) { LaunchMagicMissileExplosion(pMM->eCurPos, 0, spellinstance); ARX_NPC_SpawnAudibleSound(&pMM->eCurPos, entities[spells[spellinstance].caster]); pMM->SetTTL(1000); pMM->bExplo = true; pMM->bMove = false; if(pMM->lLightId != -1) pMM->lLightId = -1; long ttt = ARX_DAMAGES_GetFree(); if(ttt != -1) { damages[ttt].pos = pMM->eCurPos; damages[ttt].radius = 80.f; damages[ttt].damages = (4 + spells[spellinstance].caster_level * ( 1.0f / 5 )) * .8f; damages[ttt].area = DAMAGE_FULL; damages[ttt].duration = -1; damages[ttt].source = spells[spellinstance].caster; damages[ttt].flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damages[ttt].type = DAMAGE_TYPE_MAGICAL; damages[ttt].exist = true; } Color3f rgb(.3f, .3f, .45f); ARX_PARTICLES_Add_Smoke(&pMM->eCurPos, 0, 6, &rgb); } } } } }
void CMultiMagicMissile::CheckCollision(float level, EntityHandle caster) { for(size_t i = 0; i < pTab.size(); i++) { CMagicMissile * missile = (CMagicMissile *) pTab[i]; if(missile->bExplo) continue; Sphere sphere; sphere.origin = missile->eCurPos; sphere.radius = 10.f; if(CheckAnythingInSphere(sphere, caster, CAS_NO_SAME_GROUP)) { LaunchMagicMissileExplosion(missile->eCurPos, m_mrCheat); ARX_NPC_SpawnAudibleSound(missile->eCurPos, entities[caster]); missile->SetTTL(1000); missile->bExplo = true; missile->bMove = false; missile->lLightId = LightHandle::Invalid; DamageParameters damage; damage.pos = missile->eCurPos; damage.radius = 80.f; damage.damages = (4 + level * ( 1.0f / 5 )) * .8f; damage.area = DAMAGE_FULL; damage.duration = -1; damage.source = caster; damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damage.type = DAMAGE_TYPE_MAGICAL; DamageCreate(damage); Color3f rgb(.3f, .3f, .45f); ARX_PARTICLES_Add_Smoke(&missile->eCurPos, 0, 6, &rgb); } } }
void RuneOfGuardingSpell::Update(float timeDelta) { if(m_pSpellFx) { m_pSpellFx->Update(timeDelta); m_pSpellFx->Render(); CRuneOfGuarding * pCRG=(CRuneOfGuarding *)m_pSpellFx; if (pCRG) { Sphere sphere; sphere.origin = pCRG->eSrc; sphere.radius=std::max(m_level*15.f,50.f); if (CheckAnythingInSphere(sphere,m_caster,CAS_NO_SAME_GROUP | CAS_NO_BACKGROUND_COL | CAS_NO_ITEM_COL| CAS_NO_FIX_COL | CAS_NO_DEAD_COL)) { ARX_BOOMS_Add(pCRG->eSrc); LaunchFireballBoom(&pCRG->eSrc,(float)m_level); DoSphericDamage(pCRG->eSrc, 4.f * m_level, 30.f * m_level, DAMAGE_AREA, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL, m_caster); m_duration=0; ARX_SOUND_PlaySFX(SND_SPELL_RUNE_OF_GUARDING_END, &sphere.origin); } } } }
void ManageCombatModeAnimations() { arx_assert(entities.player()); Entity * const io = entities.player(); AnimLayer & layer1 = io->animlayer[1]; ANIM_HANDLE ** alist=io->anims; WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType(); if(weapontype == WEAPON_BARE && LAST_WEAPON_TYPE != weapontype) { if(layer1.cur_anim != alist[ANIM_BARE_WAIT]) { changeAnimation(io, 1, alist[ANIM_BARE_WAIT]); AimTime = 0; } } switch(weapontype) { case WEAPON_BARE: // BARE HANDS PLAYER MANAGEMENT if(layer1.cur_anim == alist[ANIM_BARE_WAIT]) { AimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + CurrFightPos * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); AimTime = (unsigned long)(arxtime); } else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(io, SM_STRIKE, "bare"); PlayerWeaponBlocked = -1; CurrFightPos = 0; AimTime = 0; } else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT+j*3]) { if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP); CurrFightPos = 0; AimTime = (unsigned long)(arxtime); PlayerWeaponBlocked = -1; } else if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.2f && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.8f && PlayerWeaponBlocked == -1 ) { long id = -1; if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT]) { id = io->obj->fastaccess.left_attach; } else { // Strike Right id = io->obj->fastaccess.primary_attach; } if(id != -1) { Sphere sphere; sphere.origin = io->obj->vertexlist3[id].v; sphere.radius = 25.f; EntityHandle num; if(CheckAnythingInSphere(sphere, PlayerEntityHandle, 0, &num)) { float dmgs = (player.m_miscFull.damages + 1) * STRIKE_AIMTIME; if(ARX_DAMAGES_TryToDoDamage(io->obj->vertexlist3[id].v, dmgs, 40, PlayerEntityHandle)) { PlayerWeaponBlocked = layer1.ctime; } ARX_PARTICLES_Spawn_Spark(sphere.origin, int(dmgs), 2); if(ValidIONum(num)) { ARX_SOUND_PlayCollision(entities[num]->material, MATERIAL_FLESH, 1.f, 1.f, sphere.origin, NULL); } } } } } } break; case WEAPON_DAGGER: // DAGGER PLAYER MANAGEMENT // Waiting and receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_DAGGER_WAIT]) { AimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + CurrFightPos * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); AimTime = (unsigned long)(arxtime); } else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(io, SM_STRIKE, "dagger"); CurrFightPos = 0; AimTime = 0; } else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT+j*3]) { if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(PlayerWeaponBlocked == -1 && ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0)) { PlayerWeaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); CurrFightPos = 0; AimTime = (unsigned long)(arxtime); PlayerWeaponBlocked = -1; } if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1); } } } break; case WEAPON_1H: // 1HANDED PLAYER MANAGEMENT // Waiting and Received Strike Impulse if(layer1.cur_anim == alist[ANIM_1H_WAIT]) { AimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + CurrFightPos * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); AimTime = (unsigned long)(arxtime); } else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(io, SM_STRIKE, "1h"); CurrFightPos = 0; AimTime = 0; } else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT+j*3]) { if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(PlayerWeaponBlocked == -1 && ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0)) { PlayerWeaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); CurrFightPos = 0; AimTime = 0; PlayerWeaponBlocked = -1; } if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1); } } } break; case WEAPON_2H: // 2HANDED PLAYER MANAGEMENT // Waiting and Receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_2H_WAIT]) { AimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + CurrFightPos * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); AimTime = (unsigned long)(arxtime); } else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(io, SM_STRIKE, "2h"); CurrFightPos = 0; AimTime = 0; } else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT+j*3]) { if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(PlayerWeaponBlocked == -1 && ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0)) { PlayerWeaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); CurrFightPos = 0; AimTime = 0; PlayerWeaponBlocked = -1; } if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1); } } } break; case WEAPON_BOW: // MISSILE PLAYER MANAGEMENT if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE]) { if(GLOBAL_SLOWDOWN != 1.f) BOW_FOCAL += Original_framedelay; else BOW_FOCAL += framedelay; if(BOW_FOCAL > 710) BOW_FOCAL = 710; } // Waiting and Receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_MISSILE_WAIT]) { AimTime = (unsigned long)(arxtime); if(eeMousePressed1() && Player_Arrow_Count() > 0) { changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]); io->isHit = false; } } if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1] && (layer1.flags & EA_ANIMEND)) { AimTime = 0; changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_2]); EERIE_LINKEDOBJ_LinkObjectToObject(io->obj, arrowobj, "left_attach", "attach", NULL); } // Now go for strike cycle... if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_CYCLE], EA_LOOP); AimTime = (unsigned long)(arxtime); } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE] && !eeMousePressed1()) { EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj); changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE]); SendIOScriptEvent(io, SM_STRIKE, "bow"); StrikeAimtime(); STRIKE_AIMTIME = (float)(BOW_FOCAL)/710.f; Entity * quiver = Player_Arrow_Count_Decrease(); float poisonous = 0.f; if(quiver) { poisonous = quiver->poisonous; if(quiver->poisonous_count > 0) { quiver->poisonous_count--; if(quiver->poisonous_count <= 0) quiver->poisonous = 0; } ARX_DAMAGES_DurabilityLoss(quiver, 1.f); // TODO is this needed ?, quivers seem to self destruct via script, but maybe not all if(ValidIOAddress(quiver) && quiver->durability <= 0.f) { ARX_INTERACTIVE_DestroyIOdelayed(quiver); } } float aimratio = STRIKE_AIMTIME; if(sp_max && poisonous < 3.f) poisonous = 3.f; Vec3f orgPos = player.pos + Vec3f(0.f, 40.f, 0.f); if(io->obj->fastaccess.left_attach >= 0) { orgPos = io->obj->vertexlist3[io->obj->fastaccess.left_attach].v; } Anglef orgAngle = player.angle; PlayerLaunchArrow_Test(aimratio, poisonous, orgPos, orgAngle); if(sp_max) { Anglef angle; Vec3f pos = player.pos + Vec3f(0.f, 40.f, 0.f); angle.setYaw(player.angle.getYaw()); angle.setPitch(player.angle.getPitch() + 8); angle.setRoll(player.angle.getRoll()); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setYaw(player.angle.getYaw()); angle.setPitch(player.angle.getPitch() - 8); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setYaw(player.angle.getYaw()); angle.setPitch(player.angle.getPitch() + 4.f); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setYaw(player.angle.getYaw()); angle.setPitch(player.angle.getPitch() - 4.f); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); } AimTime = 0; } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE]) { BOW_FOCAL -= Original_framedelay; if(BOW_FOCAL < 0) BOW_FOCAL = 0; if(layer1.flags & EA_ANIMEND) { BOW_FOCAL = 0; changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP); AimTime = 0; PlayerWeaponBlocked = -1; EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj); } } break; } LAST_WEAPON_TYPE = weapontype; }
void CLightning::Render() { if(ulCurrentTime >= ulDuration) return; if(m_iTTL <= 0) { fTotoro = 0; fMySize = 2; ReCreate(8); } Vec3f ePos; float fBeta = 0.f; float falpha = 0.f; if(m_isMassLightning) { ePos = Vec3f_ZERO; } else { ePos = m_pos; fBeta = m_beta; falpha = m_alpha; } float f = 1.5f * fMySize; m_cnodetab[0].f = randomVec(-f, f); RenderMaterial mat; mat.setCulling(Renderer::CullNone); mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); float fbeta = fBeta + rnd() * 2 * fMySize; for(size_t i = 0; i < m_nbtotal && i <= fTotoro; i++) { CLightningNode & node = m_cnodetab[i]; Vec3f astart = m_cnodetab[node.parent].pos + m_cnodetab[node.parent].f; float temp = 1.5f * fMySize; Vec3f z_z = m_cnodetab[node.parent].f + randomVec(-temp, temp); float zz = node.size + node.size * 0.3f * rnd(); float xx = node.size * glm::cos(glm::radians(-fbeta)); node.f = z_z; Vec3f a = node.pos + z_z; if(!m_isMassLightning) { Vec3f vv2; Vec3f vv1 = astart; vv1 = VRotateX(vv1, (falpha)); vv2 = VRotateY(vv1, 180 - MAKEANGLE(fBeta)); astart = vv2; vv1 = a; vv1 = VRotateX(vv1, (falpha)); vv2 = VRotateY(vv1, 180 - MAKEANGLE(fBeta)); a = vv2; astart += ePos; a += ePos; } if(i % 4 == 0) { Sphere sphere; sphere.origin = a; sphere.radius = std::min(node.size, 50.f); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP)) { DamageParameters damage; damage.pos = sphere.origin; damage.radius = sphere.radius; damage.damages = m_fDamage * m_level * ( 1.0f / 3 ); damage.area = DAMAGE_FULL; damage.duration = 1; damage.source = m_caster; damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damage.type = DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_LIGHTNING; DamageCreate(damage); } } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_ZERO; q.v[2].uv = Vec2f_Y_AXIS; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart + Vec3f(0.f, zz, 0.f); q.v[2].p = a + Vec3f(0.f, zz, 0.f); q.v[3].p = a; drawQuadRTP(mat, q); } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart - Vec3f(0.f, zz, 0.f); q.v[2].p = a - Vec3f(0.f, zz, 0.f); q.v[3].p = a; drawQuadRTP(mat, q); } zz *= glm::sin(glm::radians(fbeta)); { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart + Vec3f(xx, 0.f, zz); q.v[2].p = a + Vec3f(xx, 0.f, zz); q.v[3].p = a; drawQuadRTP(mat, q); } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_ZERO; q.v[2].uv = Vec2f_Y_AXIS; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart - Vec3f(xx, 0.f, zz); q.v[2].p = a - Vec3f(xx, 0.f, zz); q.v[3].p = a; drawQuadRTP(mat, q); } } }
//*********************************************************************************************** // flags & 1 = blood spawn only //----------------------------------------------------------------------------------------------- //*********************************************************************************************** bool ARX_EQUIPMENT_Strike_Check(Entity * io_source, Entity * io_weapon, float ratioaim, long flags, EntityHandle targ) { ARX_PROFILE_FUNC(); arx_assert(io_source); arx_assert(io_weapon); bool ret = false; EntityHandle source = io_source->index(); EntityHandle weapon = io_weapon->index(); Sphere sphere; EXCEPTIONS_LIST_Pos = 0; float drain_life = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_DRAIN_LIFE); float paralyse = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_PARALYZE); BOOST_FOREACH(const EERIE_ACTIONLIST & action, io_weapon->obj->actionlist) { float rad = GetHitValue(action.name); if(rad == -1) continue; sphere.origin = actionPointPosition(io_weapon->obj, action.idx); sphere.radius = rad; if(source != PlayerEntityHandle) sphere.radius += 15.f; std::vector<EntityHandle> sphereContent; if(CheckEverythingInSphere(sphere, source, targ, sphereContent)) { BOOST_FOREACH(const EntityHandle & content, sphereContent) { if(ValidIONum(content) && !(entities[content]->ioflags & IO_BODY_CHUNK)) { long HIT_SPARK = 0; EXCEPTIONS_LIST[EXCEPTIONS_LIST_Pos] = content; EXCEPTIONS_LIST_Pos++; if(EXCEPTIONS_LIST_Pos >= MAX_IN_SPHERE) EXCEPTIONS_LIST_Pos--; Entity * target = entities[content]; Vec3f pos; Color color = Color::white; long hitpoint = -1; float curdist = 999999.f; Vec3f vector = (sphere.origin - target->pos) * Vec3f(1.f, 0.5f, 1.f); vector = glm::normalize(vector); for(size_t ii = 0; ii < target->obj->facelist.size(); ii++) { if(target->obj->facelist[ii].facetype & POLY_HIDE) continue; float d = glm::distance(sphere.origin, target->obj->vertexlist3[target->obj->facelist[ii].vid[0]].v); if(d < curdist) { hitpoint = target->obj->facelist[ii].vid[0]; curdist = d; } } if(hitpoint >= 0) { color = (target->ioflags & IO_NPC) ? target->_npcdata->blood_color : Color::white; pos = target->obj->vertexlist3[hitpoint].v; } else ARX_DEAD_CODE(); float dmgs = 0.f; if(!(flags & 1)) { Vec3f posi; if(hitpoint >= 0) { posi = target->obj->vertexlist3[hitpoint].v; dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim, &posi); } else { dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim); } if(target->ioflags & IO_NPC) { ret = true; target->spark_n_blood = 0; target->_npcdata->SPLAT_TOT_NB = 0; if(drain_life > 0.f) { float life_gain = std::min(dmgs, drain_life); life_gain = std::min(life_gain, target->_npcdata->lifePool.current); life_gain = std::max(life_gain, 0.f); ARX_DAMAGES_HealInter(io_source, life_gain); } if(paralyse > 0.f) { float ptime = std::min(dmgs * 1000.f, paralyse); ARX_SPELLS_Launch(SPELL_PARALYSE, weapon, SPELLCAST_FLAG_NOMANA | SPELLCAST_FLAG_NOCHECKCANCAST , 5, content, (long)(ptime)); } } if(io_source == entities.player()) ARX_DAMAGES_DurabilityCheck(io_weapon, 0.2f); } if(dmgs > 0.f || ((target->ioflags & IO_NPC) && target->spark_n_blood == SP_BLOODY)) { if(target->ioflags & IO_NPC) { target->spark_n_blood = SP_BLOODY; if(!(flags & 1)) { ARX_PARTICLES_Spawn_Splat(pos, dmgs, color); Sphere sp; float power; power = (dmgs * ( 1.0f / 40 )) + 0.7f; Vec3f vect; vect.x = target->obj->vertexlist3[hitpoint].v.x - io_source->pos.x; vect.y = 0; vect.z = target->obj->vertexlist3[hitpoint].v.z - io_source->pos.z; vect = glm::normalize(vect); sp.origin.x = target->obj->vertexlist3[hitpoint].v.x + vect.x * 30.f; sp.origin.y = target->obj->vertexlist3[hitpoint].v.y; sp.origin.z = target->obj->vertexlist3[hitpoint].v.z + vect.z * 30.f; sp.radius = 3.5f * power * 20; if(CheckAnythingInSphere(sp, PlayerEntityHandle, CAS_NO_NPC_COL)) { Color3f rgb = color.to<float>(); Sphere splatSphere; splatSphere.origin = sp.origin; splatSphere.radius = 30.f; SpawnGroundSplat(splatSphere, rgb, 1); } } ARX_PARTICLES_Spawn_Blood2(pos, dmgs, color, target); } else { if(target->ioflags & IO_ITEM) ARX_PARTICLES_Spawn_Spark(pos, Random::get(0, 3), SpawnSparkType_Default); else ARX_PARTICLES_Spawn_Spark(pos, Random::get(0, 30), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); if(io_source == entities.player()) HIT_SPARK = 1; } } else if((target->ioflags & IO_NPC) && (dmgs <= 0.f || target->spark_n_blood == SP_SPARKING)) { unsigned int nb; if(target->spark_n_blood == SP_SPARKING) nb = Random::get(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ARX_PARTICLES_Spawn_Spark(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if(!(target->ioflags & IO_NPC)) HIT_SPARK = 1; } else if(dmgs <= 0.f && ((target->ioflags & IO_FIX) || (target->ioflags & IO_ITEM))) { unsigned int nb; if(target->spark_n_blood == SP_SPARKING) nb = Random::get(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ARX_PARTICLES_Spawn_Spark(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if (!(target->ioflags & IO_NPC)) HIT_SPARK = 1; } if(HIT_SPARK) { if(!io_source->isHit) { ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f); io_source->isHit = true; std::string _weapon_material = "metal"; const std::string * weapon_material = &_weapon_material; if(!io_weapon->weaponmaterial.empty()) { weapon_material = &io_weapon->weaponmaterial; } char bkg_material[128]; if(ARX_MATERIAL_GetNameById(target->material, bkg_material)) ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, NULL); } } } } } const EERIEPOLY * ep = CheckBackgroundInSphere(sphere); if(ep) { if(io_source == entities.player()) { if(!io_source->isHit) { ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f); io_source->isHit = true; std::string _weapon_material = "metal"; const std::string * weapon_material = &_weapon_material; if(!io_weapon->weaponmaterial.empty()) { weapon_material = &io_weapon->weaponmaterial; } std::string bkg_material = "earth"; if(ep && ep->tex && !ep->tex->m_texName.empty()) bkg_material = GetMaterialString(ep->tex->m_texName); ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, io_source); } } ARX_PARTICLES_Spawn_Spark(sphere.origin, Random::get(0, 10), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(sphere.origin, io_source); } } return ret; }
void ARX_PARTICLES_Update(EERIE_CAMERA * cam) { ARX_PROFILE_FUNC(); if(!ACTIVEBKG) { return; } if(ParticleCount == 0) { return; } const ArxInstant now = arxtime.now(); long pcc = ParticleCount; for(size_t i = 0; i < MAX_PARTICLES && pcc > 0; i++) { PARTICLE_DEF * part = &particle[i]; if(!part->exist) { continue; } long framediff = part->timcreation + part->tolive - now; long framediff2 = now - part->timcreation; if(framediff2 < long(part->delay)) { continue; } if(part->delay > 0) { part->timcreation += part->delay; part->delay=0; if((part->m_flags & DELAY_FOLLOW_SOURCE) && part->sourceionum != EntityHandle() && entities[part->sourceionum]) { part->ov = *part->source; Entity * target = entities[part->sourceionum]; Vec3f vector = (part->ov - target->pos) * Vec3f(1.f, 0.5f, 1.f); vector = glm::normalize(vector); part->move = vector * Vec3f(18.f, 5.f, 18.f) + randomVec(-0.5f, 0.5f); } continue; } if(!part->is2D) { EERIE_BKG_INFO * bkgData = getFastBackgroundData(part->ov.x, part->ov.z); if(!bkgData || !bkgData->treat) { part->exist = false; ParticleCount--; continue; } } if(framediff <= 0) { if((part->m_flags & FIRE_TO_SMOKE) && Random::getf() > 0.7f) { part->ov += part->move; part->tolive = part->tolive * 1.375f; part->m_flags &= ~FIRE_TO_SMOKE; part->tc = smokeparticle; part->scale = glm::abs(part->scale * 2.4f); part->rgb = Color3f::gray(.45f); part->move *= 0.5f; part->siz *= 1.f / 3; part->timcreation = now; framediff = part->tolive; } else { part->exist = false; ParticleCount--; continue; } } float val = (part->tolive - framediff) * 0.01f; Vec3f in = part->ov + part->move * val; Vec3f inn = in; if(part->m_flags & GRAVITY) { in.y = inn.y = inn.y + 1.47f * val * val; } float fd = float(framediff2) / float(part->tolive); float r = 1.f - fd; if(part->m_flags & FADE_IN_AND_OUT) { long t = part->tolive / 2; if(framediff2 <= t) { r = float(framediff2) / float(t); } else { r = 1.f - float(framediff2 - t) / float(t); } } if(!part->is2D) { Sphere sp; sp.origin = in; TexturedVertex out; EE_RTP(inn, out); if(out.rhw < 0 || out.p.z > cam->cdepth * fZFogEnd) { continue; } if(part->m_flags & SPLAT_GROUND) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * 10.f; if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb; PolyBoomAddSplat(sp, rgb, 0); } part->exist = false; ParticleCount--; continue; } } if(part->m_flags & SPLAT_WATER) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * Random::getf(10.f, 30.f); if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb * 0.5f; PolyBoomAddSplat(sp, rgb, 2); } part->exist = false; ParticleCount--; continue; } } if((part->m_flags & DISSIPATING) && out.p.z < 0.05f) { out.p.z *= 20.f; r *= out.p.z; } } if(r <= 0.f) { pcc--; continue; } if(part->m_flags & PARTICLE_GOLDRAIN) { float v = Random::getf(-0.1f, 0.1f); if(part->rgb.r + v <= 1.f && part->rgb.r + v > 0.f && part->rgb.g + v <= 1.f && part->rgb.g + v > 0.f && part->rgb.b + v <= 1.f && part->rgb.b + v > 0.f) { part->rgb = Color3f(part->rgb.r + v, part->rgb.g + v, part->rgb.b + v); } } Color color = (part->rgb * r).to<u8>(); if(player.m_improve) { color.g = 0; } TextureContainer * tc = part->tc; if(tc == explo[0] && (part->m_flags & PARTICLE_ANIMATED)) { long animrange = part->cval2 - part->cval1; long num = long(float(framediff2) / float(part->tolive) * animrange); num = glm::clamp(num, long(part->cval1), long(part->cval2)); tc = explo[num]; } float siz = part->siz + part->scale.x * fd; RenderMaterial mat; mat.setTexture(tc); mat.setDepthTest(!(part->m_flags & PARTICLE_NOZBUFFER)); if(part->m_flags & PARTICLE_SUB2) { mat.setBlendType(RenderMaterial::Subtractive2); color.a = glm::clamp(r * 1.5f, 0.f, 1.f) * 255; } else if(part->m_flags & SUBSTRACT) { mat.setBlendType(RenderMaterial::Subtractive); } else { mat.setBlendType(RenderMaterial::Additive); } if(part->m_flags & ROTATING) { if(!part->is2D) { float rott = MAKEANGLE(float(now + framediff2) * part->m_rotation); float temp = (part->zdec) ? 0.0001f : 2.f; float size = std::max(siz, 0.f); EERIEAddSprite(mat, in, size, color, temp, rott); } } else if(part->is2D) { float siz2 = part->siz + part->scale.y * fd; EERIEAddBitmap(mat, in, siz, siz2, tc, color); } else { float temp = (part->zdec) ? 0.0001f : 2.f; EERIEAddSprite(mat, in, siz, color, temp); } pcc--; } }
void RuneOfGuardingSpell::Update(float timeDelta) { ulCurrentTime += timeDelta; if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); float fa = 1.0f - rnd() * 0.15f; light->intensity = 0.7f + 2.3f * fa; light->fallend = 350.f; light->fallstart = 150.f; light->rgb = Color3f(1.0f, 0.2f, 0.2f); light->time_creation = (unsigned long)(arxtime); light->duration = 200; } Vec3f pos = m_pos + Vec3f(0.f, -20.f, 0.f); RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); Anglef stiteangle; Color3f stitecolor; float stiteangleb = float(ulCurrentTime) * 0.01f; stiteangle.setYaw(0); stiteangle.setRoll(0); stiteangle.setPitch(stiteangleb * 0.1f); stitecolor = Color3f(0.4f, 0.4f, 0.6f); float scale = std::sin(ulCurrentTime * 0.015f); Vec3f stitescale = Vec3f(1.f, -0.1f, 1.f); Draw3DObject(slight, stiteangle, pos, stitescale, stitecolor, mat); stiteangle.setPitch(stiteangleb); stitecolor = Color3f(0.6f, 0.f, 0.f); stitescale = Vec3f(2.f) * (1.f + 0.01f * scale); Draw3DObject(ssol, stiteangle, pos, stitescale, stitecolor, mat); stitecolor = Color3f(0.6f, 0.3f, 0.45f); stitescale = Vec3f(1.8f) * (1.f + 0.02f * scale); Draw3DObject(srune, stiteangle, pos, stitescale, stitecolor, mat); for(int n = 0; n < 4; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = pos + (Vec3f(40.f, 0.f, 40.f) * Vec3f(frand2(), 0.f, frand2())); pd->move = Vec3f(0.8f, -4.f, 0.8f) * Vec3f(frand2(), rnd(), frand2()); pd->scale = Vec3f(-0.1f); pd->tolive = Random::get(2600, 3200); pd->tc = tex_p2; pd->siz = 0.3f; pd->rgb = Color3f(.4f, .4f, .6f); } Sphere sphere = Sphere(m_pos, std::max(m_level * 15.f, 50.f)); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP | CAS_NO_BACKGROUND_COL | CAS_NO_ITEM_COL| CAS_NO_FIX_COL | CAS_NO_DEAD_COL)) { ARX_BOOMS_Add(m_pos); LaunchFireballBoom(m_pos, (float)m_level); DoSphericDamage(Sphere(m_pos, 30.f * m_level), 4.f * m_level, DAMAGE_AREA, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL, m_caster); ARX_SOUND_PlaySFX(SND_SPELL_RUNE_OF_GUARDING_END, &m_pos); m_duration = 0; } }
//----------------------------------------------------------------------------- void CMultiMagicMissile::CheckCollision(float _fPlayer_Magic_Level) { if (pTab) { for (UINT i = 0 ; i < uiNumber ; i++) { if (pTab[i]) { CMagicMissile * pMM = (CMagicMissile *) pTab[i]; if (pMM->bExplo == false) { EERIE_SPHERE sphere; sphere.origin.x = pMM->eCurPos.x; sphere.origin.y = pMM->eCurPos.y; sphere.origin.z = pMM->eCurPos.z; sphere.radius = 10.f; if ((spellinstance != -1) && (CheckAnythingInSphere(&sphere, spells[spellinstance].caster, CAS_NO_SAME_GROUP))) { EERIE_3D eE3D; eE3D.x = pMM->eCurPos.x; eE3D.y = pMM->eCurPos.y; eE3D.z = pMM->eCurPos.z; LaunchMagicMissileExplosion(pMM->eCurPos, 0, spellinstance); ARX_NPC_SpawnAudibleSound(&pMM->eCurPos, inter.iobj[spells[spellinstance].caster]); pMM->SetTTL(1000); pMM->bExplo = true; pMM->bMove = false; if (pMM->lLightId != -1) { pMM->lLightId = -1; } long ttt = ARX_DAMAGES_GetFree(); if (ttt != -1) { damages[ttt].pos.x = pMM->eCurPos.x; damages[ttt].pos.y = pMM->eCurPos.y; damages[ttt].pos.z = pMM->eCurPos.z; damages[ttt].radius = 80.f; damages[ttt].damages = (4 + spells[spellinstance].caster_level * DIV5) * .8f; damages[ttt].area = DAMAGE_FULL; damages[ttt].duration = -1; damages[ttt].source = spells[spellinstance].caster; damages[ttt].flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damages[ttt].type = DAMAGE_TYPE_MAGICAL; damages[ttt].exist = TRUE; } EERIE_RGB rgb; rgb.r = 0.3f; rgb.g = 0.3f; rgb.b = 0.45f; ARX_PARTICLES_Add_Smoke(&pMM->eCurPos, 0, 6, &rgb); } } } } } }
void MagicMissileSpell::Update() { for(size_t i = 0; i < pTab.size(); i++) { CMagicMissile * missile = pTab[i]; if(missile->bExplo) continue; Sphere sphere = Sphere(missile->eCurPos, 10.f); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP)) { LaunchMagicMissileExplosion(missile->eCurPos, m_mrCheat); ARX_NPC_SpawnAudibleSound(missile->eCurPos, entities[m_caster]); missile->SetTTL(ArxDurationMs(1000)); missile->bExplo = true; missile->bMove = false; missile->lLightId = LightHandle(); DamageParameters damage; damage.pos = missile->eCurPos; damage.radius = 80.f; damage.damages = (4 + m_level * ( 1.0f / 5 )) * .8f; damage.area = DAMAGE_FULL; damage.duration = ArxDuration(-1); damage.source = m_caster; damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damage.type = DAMAGE_TYPE_MAGICAL; DamageCreate(damage); Color3f rgb(.3f, .3f, .45f); ARX_PARTICLES_Add_Smoke(missile->eCurPos, 0, 6, rgb); } } for(size_t i = 0 ; i < pTab.size() ; i++) { pTab[i]->Update(ArxDurationMs(g_framedelay)); } { // CheckAllDestroyed long nbmissiles = 0; for(size_t i = 0; i < pTab.size(); i++) { CMagicMissile *pMM = pTab[i]; if(pMM->bMove) nbmissiles++; } if(nbmissiles == 0) m_duration = ArxDuration_ZERO; } for(size_t i = 0; i < pTab.size(); i++) { pTab[i]->Render(); CMagicMissile * pMM = pTab[i]; EERIE_LIGHT * el = lightHandleGet(pMM->lLightId); if(el) { el->intensity = 0.7f + 2.3f * pMM->lightIntensityFactor; el->pos = pMM->eCurPos; el->creationTime = arxtime.now(); } } }
void ManageCombatModeAnimations() { arx_assert(entities.player()); if(player.m_aimTime > 0) { player.m_aimTime += g_platformTime.lastFrameDuration(); } Entity * const io = entities.player(); AnimLayer & layer1 = io->animlayer[1]; ANIM_HANDLE ** alist = io->anims; WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType(); if(weapontype == WEAPON_BARE && LAST_WEAPON_TYPE != weapontype) { if(layer1.cur_anim != alist[ANIM_BARE_WAIT]) { changeAnimation(io, 1, alist[ANIM_BARE_WAIT]); player.m_aimTime = 0; } } switch(weapontype) { case WEAPON_BARE: { // BARE HANDS PLAYER MANAGEMENT if(layer1.cur_anim == alist[ANIM_BARE_WAIT]) { player.m_aimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + player.m_strikeDirection * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); player.m_aimTime = PlatformDuration::ofRaw(1); } else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(NULL, io, SM_STRIKE, "bare"); player.m_weaponBlocked = AnimationDuration::ofRaw(-1); // TODO inband signaling AnimationDuration player.m_strikeDirection = 0; player.m_aimTime = 0; } else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT + j * 3]) { if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP); player.m_strikeDirection = 0; player.m_aimTime = PlatformDuration::ofRaw(1); player.m_weaponBlocked = AnimationDuration::ofRaw(-1); } else if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.2f && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.8f && player.m_weaponBlocked == AnimationDuration::ofRaw(-1)) { ActionPoint id = ActionPoint(); if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT]) { id = io->obj->fastaccess.left_attach; } else { // Strike Right id = io->obj->fastaccess.primary_attach; } if(id != ActionPoint()) { Sphere sphere; sphere.origin = actionPointPosition(io->obj, id); sphere.radius = 25.f; EntityHandle num; if(CheckAnythingInSphere(sphere, EntityHandle_Player, 0, &num)) { float dmgs = (player.m_miscFull.damages + 1) * player.m_strikeAimRatio; if(ARX_DAMAGES_TryToDoDamage(actionPointPosition(io->obj, id), dmgs, 40, EntityHandle_Player)) { player.m_weaponBlocked = layer1.ctime; } ParticleSparkSpawnContinous(sphere.origin, unsigned(dmgs), SpawnSparkType_Success); if(ValidIONum(num)) { static PlatformInstant lastHit = 0; PlatformInstant now = g_platformTime.frameStart(); if(now - lastHit > toPlatformDuration(layer1.ctime)) { ARX_SOUND_PlayCollision(entities[num]->material, MATERIAL_FLESH, 1.f, 1.f, sphere.origin, NULL); lastHit = now; } } } } } } } break; } case WEAPON_DAGGER: { // DAGGER PLAYER MANAGEMENT // Waiting and receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_DAGGER_WAIT]) { player.m_aimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + player.m_strikeDirection * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); player.m_aimTime = PlatformDuration::ofRaw(1); } else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(NULL, io, SM_STRIKE, "dagger"); player.m_strikeDirection = 0; player.m_aimTime = 0; } else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]) { if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1) && ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0)) { player.m_weaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); player.m_strikeDirection = 0; player.m_aimTime = PlatformDuration::ofRaw(1); player.m_weaponBlocked = AnimationDuration::ofRaw(-1); } if( player.m_weaponBlocked != AnimationDuration::ofRaw(-1) && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1); } } } break; } case WEAPON_1H: { // 1HANDED PLAYER MANAGEMENT // Waiting and Received Strike Impulse if(layer1.cur_anim == alist[ANIM_1H_WAIT]) { player.m_aimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + player.m_strikeDirection * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); player.m_aimTime = PlatformDuration::ofRaw(1); } else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(NULL, io, SM_STRIKE, "1h"); player.m_strikeDirection = 0; player.m_aimTime = 0; } else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT + j * 3]) { if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1) && ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0)) { player.m_weaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); player.m_strikeDirection = 0; player.m_aimTime = 0; player.m_weaponBlocked = AnimationDuration::ofRaw(-1); } if( player.m_weaponBlocked != AnimationDuration::ofRaw(-1) && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1); } } } break; } case WEAPON_2H: { // 2HANDED PLAYER MANAGEMENT // Waiting and Receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_2H_WAIT]) { player.m_aimTime = 0; if(eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + player.m_strikeDirection * 3]); io->isHit = false; } } // Now go for strike cycle... for(long j = 0; j < 4; j++) { if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP); player.m_aimTime = PlatformDuration::ofRaw(1); } else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT + j * 3]); strikeSpeak(io); SendIOScriptEvent(NULL, io, SM_STRIKE, "2h"); player.m_strikeDirection = 0; player.m_aimTime = 0; } else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT + j * 3]) { if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1) && ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0)) { player.m_weaponBlocked = layer1.ctime; } } if(layer1.flags & EA_ANIMEND) { changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP); layer1.flags &= ~(EA_PAUSED | EA_REVERSE); player.m_strikeDirection = 0; player.m_aimTime = 0; player.m_weaponBlocked = AnimationDuration::ofRaw(-1); } if( player.m_weaponBlocked != AnimationDuration::ofRaw(-1) && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f ) { Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]]; ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1); } } } break; } case WEAPON_BOW: { // MISSILE PLAYER MANAGEMENT if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE]) { player.m_bowAimRatio += bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration())); if(player.m_bowAimRatio > 1.f) player.m_bowAimRatio = 1.f; } // Waiting and Receiving Strike Impulse if(layer1.cur_anim == alist[ANIM_MISSILE_WAIT]) { player.m_aimTime = PlatformDuration::ofRaw(1); if(eeMousePressed1() && Player_Arrow_Count() > 0) { changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]); io->isHit = false; } } if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1] && (layer1.flags & EA_ANIMEND)) { player.m_aimTime = 0; changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_2]); EERIE_LINKEDOBJ_LinkObjectToObject(io->obj, arrowobj, "left_attach", "attach", NULL); } // Now go for strike cycle... if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2] && (layer1.flags & EA_ANIMEND)) { changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_CYCLE], EA_LOOP); player.m_aimTime = PlatformDuration::ofRaw(1); } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE] && !eeMousePressed1()) { EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj); changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE]); SendIOScriptEvent(NULL, io, SM_STRIKE, "bow"); StrikeAimtime(); player.m_strikeAimRatio = player.m_bowAimRatio; Entity * quiver = Player_Arrow_Count_Decrease(); float poisonous = 0.f; if(quiver) { poisonous = quiver->poisonous; if(quiver->poisonous_count > 0) { quiver->poisonous_count--; if(quiver->poisonous_count <= 0) quiver->poisonous = 0; } ARX_DAMAGES_DurabilityLoss(quiver, 1.f); // TODO is this needed ?, quivers seem to self destruct via script, but maybe not all if(ValidIOAddress(quiver) && quiver->durability <= 0.f) { ARX_INTERACTIVE_DestroyIOdelayed(quiver); } } float aimratio = player.m_strikeAimRatio; if(sp_max && poisonous < 3.f) poisonous = 3.f; Vec3f orgPos = player.pos + Vec3f(0.f, 40.f, 0.f); if(io->obj->fastaccess.left_attach != ActionPoint()) { orgPos = actionPointPosition(io->obj, io->obj->fastaccess.left_attach); } Anglef orgAngle = player.angle; PlayerLaunchArrow_Test(aimratio, poisonous, orgPos, orgAngle); if(sp_max) { Anglef angle; Vec3f pos = player.pos + Vec3f(0.f, 40.f, 0.f); angle.setPitch(player.angle.getPitch()); angle.setYaw(player.angle.getYaw() + 8); angle.setRoll(player.angle.getRoll()); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setPitch(player.angle.getPitch()); angle.setYaw(player.angle.getYaw() - 8); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setPitch(player.angle.getPitch()); angle.setYaw(player.angle.getYaw() + 4.f); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); angle.setPitch(player.angle.getPitch()); angle.setYaw(player.angle.getYaw() - 4.f); PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle); } player.m_aimTime = 0; } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE]) { player.m_bowAimRatio -= bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration())); if(player.m_bowAimRatio < 0) player.m_bowAimRatio = 0; if(layer1.flags & EA_ANIMEND) { player.m_bowAimRatio = 0; changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP); player.m_aimTime = 0; player.m_weaponBlocked = AnimationDuration::ofRaw(-1); EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj); } } break; } } LAST_WEAPON_TYPE = weapontype; }
void RuneOfGuardingSpell::Update() { EERIE_LIGHT * light = lightHandleGet(m_light); if(light) { float fa = Random::getf(0.85f, 1.0f); light->intensity = 0.7f + 2.3f * fa; light->fallend = 350.f; light->fallstart = 150.f; light->rgb = Color3f(1.0f, 0.2f, 0.2f); light->creationTime = g_gameTime.now(); light->duration = GameDurationMs(200); } Vec3f pos = m_pos + Vec3f(0.f, -20.f, 0.f); RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); Anglef stiteangle; Color3f stitecolor; float stiteangleb = m_elapsed / GameDurationMs(100); stiteangle.setPitch(0); stiteangle.setRoll(0); stiteangle.setYaw(stiteangleb * 0.1f); stitecolor = Color3f(0.4f, 0.4f, 0.6f); float scale = std::sin(m_elapsed / GameDurationMsf(66.6666666f)); Vec3f stitescale = Vec3f(1.f, -0.1f, 1.f); Draw3DObject(slight, stiteangle, pos, stitescale, stitecolor, mat); stiteangle.setYaw(stiteangleb); stitecolor = Color3f(0.6f, 0.f, 0.f); stitescale = Vec3f(2.f) * (1.f + 0.01f * scale); Draw3DObject(ssol, stiteangle, pos, stitescale, stitecolor, mat); stitecolor = Color3f(0.6f, 0.3f, 0.45f); stitescale = Vec3f(1.8f) * (1.f + 0.02f * scale); Draw3DObject(srune, stiteangle, pos, stitescale, stitecolor, mat); for(int n = 0; n < 4; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = pos + arx::randomOffsetXZ(40.f); pd->move = arx::linearRand(Vec3f(-0.8f, -4.f, -0.8f), Vec3f(0.8f, 0.f, 0.8f)); pd->scale = Vec3f(-0.1f); pd->tolive = Random::getu(2600, 3200); pd->tc = tex_p2; pd->siz = 0.3f; pd->rgb = Color3f(.4f, .4f, .6f); } Sphere sphere = Sphere(m_pos, std::max(m_level * 15.f, 50.f)); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP | CAS_NO_BACKGROUND_COL | CAS_NO_ITEM_COL | CAS_NO_FIX_COL | CAS_NO_DEAD_COL)) { spawnFireHitParticle(m_pos, 0); PolyBoomAddScorch(m_pos); LaunchFireballBoom(m_pos, m_level); DoSphericDamage(Sphere(m_pos, 30.f * m_level), 4.f * m_level, DAMAGE_AREA, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL, m_caster); ARX_SOUND_PlaySFX(g_snd.SPELL_RUNE_OF_GUARDING_END, &m_pos); requestEnd(); } }