public IToolImpact Use(IDynamicEntity owner) { IToolImpact checkImpact; if (!CanDoBlockAction(owner, out checkImpact)) { return(checkImpact); } var impact = new BlockToolImpact { SrcBlueprintId = BluePrintId }; var cursor = LandscapeManager.GetCursor(owner.EntityState.PickedBlockPosition); if (cursor == null) { impact.Dropped = true; return(impact); } cursor.OwnerDynamicId = owner.DynamicId; var selectedCube = cursor.Read(); var treeSystem = new TreeLSystem(); bool removed = false; foreach (var soul in EntityFactory.LandscapeManager.AroundChunks(owner.Position, 16).SelectMany(c => c.Entities.Enumerate <TreeSoul>())) { var treeBlueprint = EntityFactory.Config.TreeBluePrintsDico[soul.TreeTypeId]; if (selectedCube != treeBlueprint.TrunkBlock && selectedCube != treeBlueprint.FoliageBlock) { continue; } var blocks = treeSystem.Generate(soul.TreeRndSeed, BlockHelper.EntityToBlock(soul.Position), treeBlueprint); if (blocks.Any(b => b.WorldPosition == owner.EntityState.PickedBlockPosition)) { cursor.RemoveEntity(soul.GetLink()); removed = true; break; } } if (!removed) { impact.Message = "This is not an alive tree"; return(impact); } TakeFromPlayer(owner); return(impact); }
public IToolImpact Use(IDynamicEntity owner) { IToolImpact checkImpact; if (!CanDoEntityAction(owner, out checkImpact)) { return(checkImpact); } var impact = new EntityToolImpact(); if (owner.EntityState.PickedEntityLink.IsDynamic) { impact.Message = "Only static entities allowed to use"; return(impact); } var entity = owner.EntityState.PickedEntityLink.ResolveStatic(LandscapeManager); if (entity == null) { impact.Message = "There is no entity by this link"; return(impact); } //Trigger item activation (Make it play sound, open, ...) if (entity is IUsableEntity) { var usable = (IUsableEntity)entity; usable.Use(); impact.Success = true; impact.EntityId = entity.StaticId; return(impact); } var cursor = LandscapeManager.GetCursor(entity.Position); if (cursor == null) { impact.Dropped = true; return(impact); } if (!entity.IsPickable) { impact.Message = "You need a special tool to pick this item"; return(impact); } cursor.OwnerDynamicId = owner.DynamicId; return(TakeImpact(owner, entity, impact, cursor, this)); }
public IToolImpact Use(IDynamicEntity owner) { IToolImpact checkImpact; if (!CanDoEntityAction(owner, out checkImpact)) { return(checkImpact); } var impact = new EntityToolImpact { SrcBlueprintId = BluePrintId }; if (owner.EntityState.PickedEntityLink.IsDynamic) { impact.Message = "Only static entities allowed to use"; return(impact); } var entity = owner.EntityState.PickedEntityLink.ResolveStatic(LandscapeManager); if (entity == null) { impact.Message = "Unable to resolve the link"; return(impact); } var cursor = LandscapeManager.GetCursor(entity.Position); if (cursor == null) { impact.Dropped = true; return(impact); } cursor.OwnerDynamicId = owner.DynamicId; return(HandTool.TakeImpact(owner, entity, impact, cursor, this)); }
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); }
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); }