public override EntityPosition GetPosition(IDynamicEntity owner) { var pos = new EntityPosition(); if (!owner.EntityState.IsBlockPicked) { return(pos); } // Get the chunk where the entity will be added and check if another entity is present inside this block var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.NewBlockPosition); foreach (var entity in workingchunk.Entities.OfType <IBlockLocationRoot>()) { if (entity.BlockLocationRoot == BlockLocationRoot) { // IBlockLocationRoot Entity already present at this location return(pos); } } pos.Position = new Vector3D(owner.EntityState.NewBlockPosition.X + 0.5f, owner.EntityState.NewBlockPosition.Y, owner.EntityState.NewBlockPosition.Z + 0.5f); pos.Rotation = Quaternion.Identity; pos.Valid = true; return(pos); }
public IToolImpact BlockImpact(IDynamicEntity owner, bool runOnServer = false) { var entity = owner; var impact = new BlockToolImpact { SrcBlueprintId = BluePrintId }; if (entity.EntityState.IsBlockPicked) { //Do Dynamic entity collision testing (Cannot place a block if a dynamic entity intersect. var blockBB = new BoundingBox(entity.EntityState.NewBlockPosition, entity.EntityState.NewBlockPosition + Vector3.One); foreach (var dynEntity in EntityFactory.DynamicEntityManager.EnumerateAround(entity.EntityState.NewBlockPosition)) { var dynBB = new BoundingBox(dynEntity.Position.AsVector3(), dynEntity.Position.AsVector3() + dynEntity.DefaultSize); if (blockBB.Intersects(ref dynBB)) { impact.Message = "Cannot place a block where someone is standing"; return(impact); } } // Get the chunk where the entity will be added and check if another block static entity is present inside this block var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.NewBlockPosition); if (workingchunk == null) { //Impossible to find chunk, chunk not existing, event dropped impact.Message = "Chunk is not existing, event dropped"; impact.Dropped = true; return(impact); } foreach (var staticEntity in workingchunk.Entities.OfType <IBlockLocationRoot>()) { if (staticEntity.BlockLocationRoot == entity.EntityState.NewBlockPosition) { impact.Message = "There is something there, remove it first " + staticEntity.BlockLocationRoot; return(impact); } } //Add new block var cursor = LandscapeManager.GetCursor(entity.EntityState.NewBlockPosition); if (cursor == null) { //Impossible to find chunk, chunk not existing, event dropped impact.Message = "Block not existing, event dropped"; impact.Dropped = true; return(impact); } if (cursor.Read() == WorldConfiguration.CubeId.Air) { if (!EntityFactory.Config.IsInfiniteResources) { var charEntity = owner as CharacterEntity; if (charEntity == null) { impact.Message = "Character entity is expected"; return(impact); } var slot = charEntity.Inventory.FirstOrDefault(s => s.Item.StackType == StackType); if (slot == null) { // we have no more items in the inventory, remove from the hand slot = charEntity.Equipment[EquipmentSlotType.Hand]; impact.Success = charEntity.Equipment.TakeItem(slot.GridPosition); } else { impact.Success = charEntity.Inventory.TakeItem(slot.GridPosition); } if (!impact.Success) { impact.Message = "Unable to take an item from the inventory"; return(impact); } } cursor.Write(CubeId); impact.Success = true; impact.CubeId = CubeId; if (SoundEngine != null && EntityFactory.Config.ResourcePut != null) { SoundEngine.StartPlay3D(EntityFactory.Config.ResourcePut, entity.EntityState.NewBlockPosition + new Vector3(0.5f)); } return(impact); } } impact.Message = "Pick a cube to use this tool"; return(impact); }
public override EntityPosition GetPosition(IDynamicEntity owner) { var pos = new EntityPosition(); Vector3I?newBlockPos = null; var playerRotation = owner.HeadRotation.GetLookAtVector(); if (owner.EntityState.IsBlockPicked) { newBlockPos = owner.EntityState.NewBlockPosition; } else if (owner.EntityState.IsEntityPicked && owner.EntityState.PickedEntityLink.IsStatic) { var entity = owner.EntityState.PickedEntityLink.ResolveStatic(LandscapeManager); if (entity is BlockItem) { newBlockPos = owner.EntityState.PickedEntityPosition.ToCubePosition(); var rotation = entity.Rotation; var normal = Vector3.TransformNormal(owner.EntityState.PickPointNormal, Matrix.RotationQuaternion(rotation)); var converted = new Vector3I((int)Math.Round(normal.X, MidpointRounding.ToEven), (int)Math.Round(normal.Y, MidpointRounding.ToEven), (int)Math.Round(normal.Z, MidpointRounding.ToEven)); newBlockPos += converted; } } if (newBlockPos == null) { return(pos); } var cursor = LandscapeManager.GetCursor(newBlockPos.Value); if (cursor == null || cursor.Read() != WorldConfiguration.CubeId.Air || LandscapeManager.GetChunkFromBlock(newBlockPos.Value).Entities.OfType <BlockItem>().Any(i => i.BlockLocationRoot == newBlockPos)) { return(pos); } // locate the entity, set translation in World space pos.Position = new Vector3D(newBlockPos.Value.X + 0.5f, newBlockPos.Value.Y, newBlockPos.Value.Z + 0.5f); //Set Orientation double entityRotation; if (Math.Abs(playerRotation.Z) >= Math.Abs(playerRotation.X)) { if (playerRotation.Z < 0) { entityRotation = MathHelper.Pi; pos.Orientation = ItemOrientation.North; } else { entityRotation = 0; pos.Orientation = ItemOrientation.South; } } else { if (playerRotation.X < 0) { entityRotation = MathHelper.PiOver2; pos.Orientation = ItemOrientation.East; } else { entityRotation = -MathHelper.PiOver2; pos.Orientation = ItemOrientation.West; } } //Specific Item Rotation for this instance pos.Rotation = Quaternion.RotationAxis(new Vector3(0, 1, 0), (float)entityRotation); pos.Valid = true; return(pos); }
public override EntityPosition GetPosition(IDynamicEntity owner) { var pos = new EntityPosition(); if (!AllowFreeMount && !owner.EntityState.IsBlockPicked) { return(pos); } if (!MountPoint.HasFlag(BlockFace.Top) && owner.EntityState.PickPointNormal.Y == 1) { return(pos); } if (!MountPoint.HasFlag(BlockFace.Bottom) && owner.EntityState.PickPointNormal.Y == -1) { return(pos); } if (!MountPoint.HasFlag(BlockFace.Sides) && (owner.EntityState.PickPointNormal.X != 0 || owner.EntityState.PickPointNormal.Z != 0)) { return(pos); } if (BlockEmptyRequired && owner.EntityState.IsBlockPicked) { //Get the chunk where the entity will be added and check if another entity is not present at the destination root block ! var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.PickedBlockPosition); if (workingchunk == null) { return(pos); } foreach (var entity in workingchunk.Entities.OfType <BlockLinkedItem>().Where(x => x.Linked && x.LinkedCube == owner.EntityState.PickedBlockPosition)) { if (entity.BlockLocationRoot == owner.EntityState.NewBlockPosition && entity.LinkedCube == owner.EntityState.PickedBlockPosition) { //CubePlaced Entity already present at this location return(pos); } } } // locate the entity if (owner.EntityState.PickPointNormal.Y == 1) // = Put on TOP { if (BlockFaceCentered) { var newBlockPos = owner.EntityState.IsBlockPicked ? owner.EntityState.NewBlockPosition : owner.EntityState.PickPoint.ToCubePosition(); pos.Position = new Vector3D( newBlockPos + new Vector3(0.5f - (float)owner.EntityState.PickPointNormal.X / 2, owner.EntityState.PickPoint.Y % 1, 0.5f - (float)owner.EntityState.PickPointNormal.Z / 2) ); } else { pos.Position = new Vector3D(owner.EntityState.PickPoint); } } else if (owner.EntityState.PickPointNormal.Y == -1) //PUT on cube Bottom = (Ceiling) { pos.Position = new Vector3D(owner.EntityState.PickPoint); pos.Position.Y -= DefaultSize.Y; } else //Put on a side { if (BlockFaceCentered) { var newBlockPos = owner.EntityState.IsBlockPicked ? owner.EntityState.NewBlockPosition : owner.EntityState.PickPoint.ToCubePosition(); pos.Position = new Vector3D( newBlockPos + new Vector3(0.5f - (float)owner.EntityState.PickPointNormal.X / 2, 0.5f, 0.5f - (float)owner.EntityState.PickPointNormal.Z / 2) ); } else { pos.Position = new Vector3D(owner.EntityState.PickPoint); } pos.Position += new Vector3D(owner.EntityState.PickPointNormal.X == -1 ? -0.01 : 0, 0, owner.EntityState.PickPointNormal.Z == -1 ? -0.01 : 0); var slope = 0d; if (owner.EntityState.PickPointNormal.X == -1) { slope = -Math.PI / 2; } if (owner.EntityState.PickPointNormal.X == 1) { slope = Math.PI / 2; // ok } if (owner.EntityState.PickPointNormal.Z == -1) { slope = Math.PI; // ok } if (owner.EntityState.PickPointNormal.Z == 1) { slope = 0; } pos.Rotation = Quaternion.RotationAxis(new Vector3(0, 1, 0), (float)slope); } pos.Valid = true; return(pos); }
private IToolImpact BlockHit(IDynamicEntity owner) { var impact = new BlockToolImpact { SrcBlueprintId = BluePrintId, Position = owner.EntityState.PickedBlockPosition }; var cursor = LandscapeManager.GetCursor(owner.EntityState.PickedBlockPosition); if (cursor == null) { //Impossible to find chunk, chunk not existing, event dropped impact.Message = "Block not existing, event dropped"; impact.Dropped = true; return(impact); } cursor.OwnerDynamicId = owner.DynamicId; if (cursor.PeekProfile().Indestructible) { impact.Message = "Indestrutible cube, cannot be removed !"; return(impact); } DamageTag damage; var cube = cursor.Read(out damage); if (cube != WorldConfiguration.CubeId.Air) { impact.CubeId = cube; var profile = cursor.PeekProfile(); var hardness = profile.Hardness; if (damage == null) { damage = new DamageTag { Strength = (int)hardness, TotalStrength = (int)hardness }; } var toolBlockDamage = Damage; if (SpecialDamages != null) { var index = SpecialDamages.FindIndex(cd => cd.CubeId == cube); if (index != -1) { toolBlockDamage = SpecialDamages[index].Damage; } } damage.Strength -= toolBlockDamage; if (toolBlockDamage > 0 && SoundEngine != null) { if (profile.HitSounds.Count > 0) { var random = new Random(); var sound = profile.HitSounds[random.Next(0, profile.HitSounds.Count)]; SoundEngine.StartPlay3D(sound, owner.EntityState.PickedBlockPosition + new Vector3(0.5f)); } } if (damage.Strength <= 0) { var chunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.PickedBlockPosition); if (chunk == null) { //Impossible to find chunk, chunk not existing, event dropped impact.Message = "Chunk is not existing, event dropped"; impact.Dropped = true; return(impact); } chunk.Entities.RemoveAll <BlockLinkedItem>(e => e.Linked && e.LinkedCube == owner.EntityState.PickedBlockPosition, owner.DynamicId); cursor.Write(WorldConfiguration.CubeId.Air); #region TreeSoul remove logic foreach (var treeSoul in EntityFactory.LandscapeManager.AroundEntities(owner.EntityState.PickedBlockPosition, 16).OfType <TreeSoul>()) { var treeBp = EntityFactory.Config.TreeBluePrintsDico[treeSoul.TreeTypeId]; if (cube != treeBp.FoliageBlock && cube != treeBp.TrunkBlock) { continue; } var treeLSystem = new TreeLSystem(); var treeBlocks = treeLSystem.Generate(treeSoul.TreeRndSeed, (Vector3I)treeSoul.Position, treeBp); // did we remove the block of the tree? if (treeBlocks.Exists(b => b.WorldPosition == owner.EntityState.PickedBlockPosition)) { treeSoul.IsDamaged = true; // count removed trunk blocks var totalTrunks = treeBlocks.Count(b => b.BlockId == treeBp.TrunkBlock); var existsTrunks = treeBlocks.Count(b => { if (b.BlockId == treeBp.TrunkBlock) { cursor.GlobalPosition = b.WorldPosition; return(cursor.Read() == treeBp.TrunkBlock); } return(false); }); if (existsTrunks < totalTrunks / 2) { treeSoul.IsDying = true; } } } #endregion if (SoundEngine != null && EntityFactory.Config.ResourceTake != null) { SoundEngine.StartPlay3D(EntityFactory.Config.ResourceTake, owner.EntityState.PickedBlockPosition + new Vector3(0.5f)); } var charEntity = owner as CharacterEntity; if (charEntity == null) { impact.Message = "Charater entity is expected"; return(impact); } var putItems = new List <KeyValuePair <IItem, int> >(); putItems.Add(new KeyValuePair <IItem, int>((IItem)EntityFactory.CreateFromBluePrint(cube), 1)); if (profile.Transformations != null) { var random = new FastRandom(owner.EntityState.PickedEntityPosition.GetHashCode() ^ owner.EntityState.Entropy); foreach (var itemTransformation in profile.Transformations) { if (random.NextDouble() < itemTransformation.TransformChance) { // don't give the block putItems.Clear(); foreach (var slot in itemTransformation.GeneratedItems) { putItems.Add(new KeyValuePair <IItem, int>((Item)EntityFactory.CreateFromBluePrint(slot.BlueprintId), slot.Count)); } break; } } } // in case of infinite resources we will not add more than 1 block entity var existingSlot = charEntity.FindSlot(s => s.Item.BluePrintId == cube); if (!EntityFactory.Config.IsInfiniteResources || existingSlot == null) { if (!charEntity.Inventory.PutMany(putItems)) { impact.Message = "Can't put the item(s) to inventory"; } } impact.CubeId = WorldConfiguration.CubeId.Air; } else if (damage.Strength >= hardness) { cursor.Write(cube); } else { cursor.Write(cube, damage); } impact.Success = true; return(impact); } impact.Message = "Cannot hit air block"; return(impact); }