public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoObjectExplosive protoObjectExplosive, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning ServerTimersSystem.AddAction( // the delay is quite small and just needed to ensure // that the charred ground spawned some time after this object is destroyed delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)epicenterPosition; if (!Server.World.GetTile(tilePosition) .StaticObjects .Any(so => so.ProtoStaticWorldObject is ObjectCharredGround)) { // spawn charred ground var objectCharredGround = Server.World.CreateStaticWorldObject <ObjectCharredGround>(tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ObjectCharredGround.ServerSetWorldOffset(objectCharredGround, objectCharredGroundOffset.ToVector2F()); } } }); // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character != null ? character.SharedGetFinalStatsCache() : FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: null, protoObjectExplosive: protoObjectExplosive, damageDescription: damageDescriptionCharacters); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }
public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoObjectExplosive protoObjectExplosive, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning ServerTimersSystem.AddAction( delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)epicenterPosition; // remove existing charred ground objects at the same tile foreach (var staticWorldObject in Shared.WrapInTempList( Server.World.GetTile(tilePosition).StaticObjects)) { if (staticWorldObject.ProtoStaticWorldObject is ObjectCharredGround) { Server.World.DestroyObject(staticWorldObject); } } // spawn charred ground var objectCharredGround = Server.World .CreateStaticWorldObject <ObjectCharredGround>(tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ObjectCharredGround.ServerSetWorldOffset(objectCharredGround, (Vector2F)objectCharredGroundOffset); } }); // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character?.SharedGetFinalStatsCache() ?? FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: null, protoObjectExplosive: protoObjectExplosive, damageDescription: damageDescriptionCharacters); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }
public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoExplosive protoExplosive, [CanBeNull] IProtoItemWeapon protoWeapon, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning var protoObjectCharredGround = explosionPreset.ProtoObjectCharredGround; if (protoObjectCharredGround is not null) { ServerTimersSystem.AddAction( delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)(epicenterPosition - protoObjectCharredGround.Layout.Center); var canSpawnCharredGround = true; var tile = Server.World.GetTile(tilePosition); if (tile.ProtoTile.Kind != TileKind.Solid || tile.EightNeighborTiles.Any(t => t.ProtoTile.Kind != TileKind.Solid)) { // allow charred ground only on solid ground canSpawnCharredGround = false; } if (canSpawnCharredGround) { // remove existing charred ground objects at the same tile foreach (var staticWorldObject in Shared.WrapInTempList( tile.StaticObjects) .EnumerateAndDispose()) { switch (staticWorldObject.ProtoStaticWorldObject) { case ProtoObjectCharredGround _: Server.World.DestroyObject(staticWorldObject); break; case IProtoObjectDeposit _: // don't show charred ground over resource deposits (it looks wrong) canSpawnCharredGround = false; break; } } } if (canSpawnCharredGround && PveSystem.ServerIsPvE) { var bounds = protoObjectCharredGround.Layout.Bounds; if (LandClaimSystem.SharedIsLandClaimedByAnyone( new RectangleInt(tilePosition, bounds.Size + (1, 1)))) { // ensure that it's not possible to create charred ground in a land claim area in PvE canSpawnCharredGround = false; } } if (canSpawnCharredGround) { // spawn charred ground var objectCharredGround = Server.World.CreateStaticWorldObject(protoObjectCharredGround, tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ProtoObjectCharredGround.ServerSetWorldOffset(objectCharredGround, (Vector2F)objectCharredGroundOffset); } } }); } // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character?.SharedGetFinalStatsCache() ?? FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: protoWeapon, protoAmmo: null, damageDescription: damageDescriptionCharacters, protoExplosive: protoExplosive); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }