void ParticleSparkSpawnContinous(const Vec3f & pos, unsigned rate, SpawnSparkType type) { float amount = float(rate) * (g_platformTime.lastFrameDuration() / PlatformDurationMsf(66.666666f)); unsigned count = unsigned(amount); if(Random::getf() < (amount - float(count))) { count++; } ParticleSparkSpawn(pos, count, type); }
//*********************************************************************************************** // 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(); 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 sphere; sphere.origin = actionPointPosition(io_weapon->obj, action.idx); sphere.radius = rad; if(source != EntityHandle_Player) 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)) { bool HIT_SPARK = false; 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) { ArxDuration ptime = ArxDurationMs(std::min(dmgs * 1000.f, paralyse)); ARX_SPELLS_Launch(SPELL_PARALYSE, weapon, SPELLCAST_FLAG_NOMANA | SPELLCAST_FLAG_NOCHECKCANCAST, 5, content, 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); Vec3f vertPos = target->obj->vertexlist3[hitpoint].v; float power = (dmgs * ( 1.0f / 40 )) + 0.7f; Vec3f vect; vect.x = vertPos.x - io_source->pos.x; vect.y = 0; vect.z = vertPos.z - io_source->pos.z; vect = glm::normalize(vect); Sphere sp; sp.origin.x = vertPos.x + vect.x * 30.f; sp.origin.y = vertPos.y; sp.origin.z = vertPos.z + vect.z * 30.f; sp.radius = 3.5f * power * 20; if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { Color3f rgb = color.to<float>(); Sphere splatSphere; splatSphere.origin = sp.origin; splatSphere.radius = 30.f; PolyBoomAddSplat(splatSphere, rgb, 1); } } ARX_PARTICLES_Spawn_Blood2(pos, dmgs, color, target); } else { if(target->ioflags & IO_ITEM) ParticleSparkSpawn(pos, Random::getu(0, 3), SpawnSparkType_Default); else ParticleSparkSpawn(pos, Random::getu(0, 30), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); if(io_source == entities.player()) HIT_SPARK = true; } } 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::getu(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ParticleSparkSpawn(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if(!(target->ioflags & IO_NPC)) HIT_SPARK = true; } 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::getu(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ParticleSparkSpawn(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if (!(target->ioflags & IO_NPC)) HIT_SPARK = true; } 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; } if(target->material != MATERIAL_NONE) { const char * matStr = ARX_MATERIAL_GetNameById(target->material); ARX_SOUND_PlayCollision(*weapon_material, matStr, 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); } } ParticleSparkSpawn(sphere.origin, Random::getu(0, 10), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(sphere.origin, io_source); } } return ret; }