/// <summary>Overridden from <see cref="Engine.EntitySystem.Entity.OnTick()"/>.</summary> protected override void OnTick() { base.OnTick(); if (force != 0) { foreach (MapObject obj in ObjectsInRegion) { if (obj.IsSetForDeletion) { continue; } //impulse if (impulsePerSecond != 0) { PhysicsModel objPhysicsModel = obj.PhysicsModel; if (objPhysicsModel != null) { foreach (Body body in objPhysicsModel.Bodies) { if (body.Static) { continue; } EngineRandom random = World.Instance.Random; float distanceCoef = GetDistanceCoefficient(body.Position); float randomCoef = 1.0f + random.NextFloatCenter() * .1f; float v = impulsePerSecond * force * distanceCoef * randomCoef * TickDelta; Vec3 point = new Vec3( random.NextFloat() * .1f, random.NextFloat() * .1f, random.NextFloat() * .1f); body.AddForce(ForceType.GlobalAtLocalPos, TickDelta, Rotation * new Vec3(v, 0, 0), point); } } } if (InfluenceType != null || DamagePerSecond != 0) { Dynamic dynamic = obj as Dynamic; if (dynamic != null) { float distanceCoef = GetDistanceCoefficient(obj.Position); if (InfluenceType != null) { dynamic.AddInfluence(InfluenceType, InfluenceTimePerSecond * distanceCoef * TickDelta, true); } if (DamagePerSecond != 0) { dynamic.DoDamage(null, obj.Position, null, DamagePerSecond * distanceCoef * TickDelta, false); } } } } } }
private void DoEffect() { float radius = Type.Radius; float radiusInv = 1.0f / radius; List <MapObject> objects = mapObjectListAllocator.Alloc(); List <DamageItem> damageItems = damageItemListAllocator.Alloc(); //generate objects list Map.Instance.GetObjects(new Sphere(Position, radius), delegate(MapObject obj) { if (Type.IgnoreReasonObject && obj == ReasonObject) { return; } objects.Add(obj); }); //enumerate objects foreach (MapObject obj in objects) { if (obj.IsSetForDeletion) { continue; } if (!obj.Visible) { continue; } PhysicsModel objPhysicsModel = obj.PhysicsModel; float totalObjImpulse = 0; float totalObjDamage = 0; if (Type.Impulse != 0 && objPhysicsModel != null) { float bodyCountInv = 1.0f / objPhysicsModel.Bodies.Length; foreach (Body body in objPhysicsModel.Bodies) { if (body.Static) { continue; } Vec3 dir = body.Position - Position; float distance = dir.Normalize(); if (distance < radius) { float objImpulse = MathFunctions.Cos((distance * radiusInv) * (MathFunctions.PI / 2)) * Type.Impulse * DamageCoefficient; objImpulse *= bodyCountInv; //forcePos for torque Vec3 forcePos; { Vec3 gabarites = body.GetGlobalBounds().GetSize() * .05f; EngineRandom random = World.Instance.Random; forcePos = new Vec3( random.NextFloatCenter() * gabarites.X, random.NextFloatCenter() * gabarites.Y, random.NextFloatCenter() * gabarites.Z); } body.AddForce(ForceType.GlobalAtLocalPos, 0, dir * objImpulse, forcePos); totalObjImpulse += objImpulse; } } } if (Type.Damage != 0) { Dynamic dynamic = obj as Dynamic; if (dynamic != null) { float distance = (dynamic.Position - Position).Length(); if (distance < radius) { float objDamage = MathFunctions.Cos((distance * radiusInv) * (MathFunctions.PI / 2)) * Type.Damage * DamageCoefficient; //add damages to cache and apply after influences (for correct influences work) damageItems.Add(new DamageItem(dynamic, obj.Position, objDamage)); //dynamic.DoDamage( dynamic, obj.Position, objDamage, false ); totalObjDamage += objDamage; } } } //PlayerCharacter contusion if (totalObjDamage > 10 && totalObjImpulse > 500) { PlayerCharacter playerCharacter = obj as PlayerCharacter; if (playerCharacter != null) { playerCharacter.ContusionTimeRemaining += totalObjDamage * .05f; } } //Influence if (Type.InfluenceType != null && (totalObjDamage != 0 || totalObjImpulse != 0)) { Dynamic dynamic = obj as Dynamic; if (dynamic != null) { float coef = 0; if (Type.Damage != 0) { coef = totalObjDamage / Type.Damage; } if (Type.Impulse != 0) { coef = Math.Max(coef, totalObjImpulse / Type.Impulse); } if (coef > 1) { coef = 1; } if (coef != 0) { dynamic.AddInfluence(Type.InfluenceType, Type.InfluenceMaxTime * coef, true); } } } } //Create splash for water CreateWaterPlaneSplash(); //Apply damages foreach (DamageItem item in damageItems) { if (!item.dynamic.IsSetForDeletion) { item.dynamic.DoDamage(this, item.position, null, item.damage, false); } } mapObjectListAllocator.Free(objects); damageItemListAllocator.Free(damageItems); }