Cuboidf[] ToCuboidf(InerhitableRotatableCube cube, Cuboidf parentCube) { if (parentCube == null) { parentCube = DefaultCollisionBox; } return(new Cuboidf[] { cube.InheritedCopy(parentCube) }); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); msLaunch = World.ElapsedMilliseconds; collisionTestBox = CollisionBox.Clone().OmniGrowBy(0.05f); }
private bool CanSpawnAt(IBlockAccessor blockAccessor, EntityProperties type, BlockPos pos, Vec3d posAsVec, BaseSpawnConditions sc, float rain, float temp, float forestDensity, float shrubsDensity) { if (!api.World.BlockAccessor.IsValidPos(pos)) { return(false); } float?lightLevel = blockAccessor.GetLightLevel(pos, EnumLightLevelType.MaxLight); if (lightLevel == null) { return(false); } if (sc.MinLightLevel > lightLevel || sc.MaxLightLevel < lightLevel) { return(false); } if (sc.MinTemp > temp || sc.MaxTemp < temp) { return(false); } if (sc.MinRain > rain || sc.MaxRain < rain) { return(false); } if (sc.MinForest > forestDensity || sc.MaxForest < forestDensity) { return(false); } if (sc.MinShrubs > shrubsDensity || sc.MaxShrubs < shrubsDensity) { return(false); } if (sc.MinForestOrShrubs > Math.Max(forestDensity, shrubsDensity)) { return(false); } Block belowBlock = blockAccessor.GetBlock(pos.X, pos.Y - 1, pos.Z); if (!belowBlock.CanCreatureSpawnOn(blockAccessor, pos.DownCopy(), type, sc)) { return(false); } Block block = blockAccessor.GetBlock(pos); if (!block.WildCardMatch(sc.InsideBlockCodes)) { return(false); } Cuboidf collisionBox = type.SpawnCollisionBox.OmniNotDownGrowBy(0.1f); return(!IsColliding(collisionBox, posAsVec)); }
public BlockFirewoodPile() { CollisionBoxesByFillLevel = new Cuboidf[5][]; for (int i = 0; i <= 4; i++) { CollisionBoxesByFillLevel[i] = new Cuboidf[] { new Cuboidf(0, 0, 0, 1, i * 0.25f, 1) }; } }
public BlockPlatePile() { CollisionBoxesByFillLevel = new Cuboidf[17][]; for (int i = 0; i <= 16; i++) { CollisionBoxesByFillLevel[i] = new Cuboidf[] { new Cuboidf(0.1875f, 0, 0.1875f, 0.8125f, i * 0.125f / 2, 0.8125f) }; } }
public BlockPlankPile() { CollisionBoxesByFillLevel = new Cuboidf[17][]; for (int i = 0; i <= 16; i++) { CollisionBoxesByFillLevel[i] = new Cuboidf[] { new Cuboidf(0, 0, 0, 1, i * 0.125f / 2, 1) }; } }
Cuboidf[] ToCuboidf(params RotatableCube[] cubes) { Cuboidf[] outcubes = new Cuboidf[cubes.Length]; for (int i = 0; i < cubes.Length; i++) { outcubes[i] = cubes[i].RotatedCopy(); } return(outcubes); }
public virtual Cuboidf[] GetSelectionBoxes(IBlockAccessor world, BlockPos pos, IPlayer forPlayer = null) { if (selectionBoxes.Length == 0) { return new Cuboidf[] { Cuboidf.Default() } } ; return(selectionBoxes); }
// Custom implementation for mixed generating/loaded chunk access, since we can spawn entities just fine in either loaded or still generating chunks public bool IsColliding(Cuboidf entityBoxRel, Vec3d pos) { BlockPos blockPos = new BlockPos(); IBlockAccessor blockAccess; int chunksize = wgenBlockAccessor.ChunkSize; Cuboidd entityCuboid = entityBoxRel.ToDouble().Translate(pos); Vec3d blockPosAsVec = new Vec3d(); int minX = (int)(entityBoxRel.X1 + pos.X); int minY = (int)(entityBoxRel.Y1 + pos.Y); int minZ = (int)(entityBoxRel.Z1 + pos.Z); int maxX = (int)Math.Ceiling(entityBoxRel.X2 + pos.X); int maxY = (int)Math.Ceiling(entityBoxRel.Y2 + pos.Y); int maxZ = (int)Math.Ceiling(entityBoxRel.Z2 + pos.Z); for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { blockAccess = wgenBlockAccessor; IWorldChunk chunk = wgenBlockAccessor.GetChunkAtBlockPos(x, y, z); if (chunk == null) { chunk = api.World.BlockAccessor.GetChunkAtBlockPos(x, y, z); blockAccess = api.World.BlockAccessor; } if (chunk == null) { return(true); } chunk.Unpack(); int index = ((y % chunksize) * chunksize + (z % chunksize)) * chunksize + (x % chunksize); Block block = api.World.Blocks[chunk.Blocks[index]]; blockPos.Set(x, y, z); blockPosAsVec.Set(x, y, z); Cuboidf[] collisionBoxes = block.GetCollisionBoxes(blockAccess, blockPos); for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++) { Cuboidf collBox = collisionBoxes[i]; if (collBox != null && entityCuboid.Intersects(collBox, blockPosAsVec)) { return(true); } } } } } return(false); }
public BlockPeatPile() { CollisionBoxesByFillLevel = new Cuboidf[9][]; for (int i = 0; i <= 8; i++) { CollisionBoxesByFillLevel[i] = new Cuboidf[] { new Cuboidf(0, 0, 0, 1, i * 0.125f, 1) }; } }
internal void OnBlockInteract(IPlayer byPlayer, BlockSelection blockSel, bool isBreak) { if (api.World.Side == EnumAppSide.Client) { Cuboidf box = selectionBoxes[blockSel.SelectionBoxIndex]; Vec3i voxelPos = new Vec3i((int)(16 * box.X1), (int)(16 * box.Y1), (int)(16 * box.Z1)); UpdateVoxel(byPlayer, voxelPos, blockSel.Face, isBreak); } }
internal void OnBlockInteract(IPlayer byPlayer, BlockSelection blockSel, bool isBreak) { if (api.World.Side == EnumAppSide.Client && DetailingMode) { Cuboidf box = GetOrCreateVoxelSelectionBoxes(byPlayer)[blockSel.SelectionBoxIndex]; Vec3i voxelPos = new Vec3i((int)(16 * box.X1), (int)(16 * box.Y1), (int)(16 * box.Z1)); UpdateVoxel(byPlayer, byPlayer.InventoryManager.ActiveHotbarSlot, voxelPos, blockSel.Face, isBreak); } }
public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { stepHeight = typeAttributes["stepHeight"].AsFloat(0.6f); for (int i = 0; i < Locomotors.Count; i++) { Locomotors[i].Initialize(properties); } smallerCollisionBox = entity.CollisionBox.Clone().OmniNotDownGrowBy(-0.05f); }
public void Check() { if (entity is EntityPlayer) { EntityPlayer plr = (EntityPlayer)entity; EnumGameMode mode = entity.World.PlayerByUid(plr.PlayerUID).WorldData.CurrentGameMode; if (mode == EnumGameMode.Creative || mode == EnumGameMode.Spectator) { return; } } BlockPos pos = new BlockPos( (int)(entity.ServerPos.X + entity.LocalEyePos.X), (int)(entity.ServerPos.Y + entity.LocalEyePos.Y), (int)(entity.ServerPos.Z + entity.LocalEyePos.Z) ); Block block = entity.World.BlockAccessor.GetBlock(pos); Cuboidf[] collisionboxes = block.GetCollisionBoxes(entity.World.BlockAccessor, pos); Cuboidf box = new Cuboidf(); if (collisionboxes == null) { return; } for (int i = 0; i < collisionboxes.Length; i++) { box.Set(collisionboxes[i]); box.OmniGrowBy(-padding); tmp.Set(pos.X + box.X1, pos.Y + box.Y1, pos.Z + box.Z1, pos.X + box.X2, pos.Y + box.Y2, pos.Z + box.Z2); box.OmniGrowBy(padding); if (tmp.Contains(entity.ServerPos.X + entity.LocalEyePos.X, entity.ServerPos.Y + entity.LocalEyePos.Y, entity.ServerPos.Z + entity.LocalEyePos.Z)) { Cuboidd EntitySuffocationBox = entity.CollisionBox.ToDouble(); if (tmp.Intersects(EntitySuffocationBox)) { DamageSource dmgsrc = new DamageSource() { Source = EnumDamageSource.Block, SourceBlock = block, Type = EnumDamageType.Suffocation }; entity.ReceiveDamage(dmgsrc, 1f); break; } } } }
public virtual void RegenSelectionBoxes(IPlayer byPlayer) { // Create a temporary array first, because the offthread particle system might otherwise access a null collisionbox Cuboidf[] selectionBoxesTmp = new Cuboidf[VoxelCuboids.Count]; CuboidWithMaterial cwm = tmpCuboid; for (int i = 0; i < VoxelCuboids.Count; i++) { FromUint(VoxelCuboids[i], cwm); selectionBoxesTmp[i] = cwm.ToCuboidf(); } this.selectionBoxes = selectionBoxesTmp; }
internal void OnUseOver(IPlayer byPlayer, int selectionBoxIndex, BlockFacing facing, bool mouseMode) { if (selectionBoxIndex < 0 || selectionBoxIndex >= selectionBoxes.Length) { return; } Cuboidf box = selectionBoxes[selectionBoxIndex]; Vec3i voxelPos = new Vec3i((int)(16 * box.X1), (int)(16 * box.Y1), (int)(16 * box.Z1)); OnUseOver(byPlayer, voxelPos, facing, mouseMode); }
public Cuboidf InheritedCopy(Cuboidf parent) { Cuboidf finalCube = new Cuboidf( X1 == null ? parent.X1 : (float)X1, Y1 == null ? parent.Y1 : (float)Y1, Z1 == null ? parent.Z1 : (float)Z1, X2 == null ? parent.X2 : (float)X2, Y2 == null ? parent.Y2 : (float)Y2, Z2 == null ? parent.Z2 : (float)Z2 ); return(finalCube.RotatedCopy(RotateX, RotateY, RotateZ, new Vec3d(0.5, 0.5, 0.5))); }
public override void OnReceivedClientPacket(IPlayer fromPlayer, int packetid, byte[] bytes) { base.OnReceivedClientPacket(fromPlayer, packetid, bytes); if (packetid == 123) { if (Api.World.Rand.NextDouble() < 0.25 && insideLocustCount > 0) { ICoreServerAPI sapi = Api as ICoreServerAPI; int rnd = sapi.World.Rand.Next(Data.EntityCodes.Length); EntityProperties type = Api.World.GetEntityType(new AssetLocation(Data.EntityCodes[rnd])); if (type == null) { return; } Cuboidf collisionBox = new Cuboidf() { X1 = -type.CollisionBoxSize.X / 2, Z1 = -type.CollisionBoxSize.X / 2, X2 = type.CollisionBoxSize.X / 2, Z2 = type.CollisionBoxSize.X / 2, Y2 = type.CollisionBoxSize.Y }.OmniNotDownGrowBy(0.1f); Vec3d spawnPos = new Vec3d(); for (int tries = 0; tries < 15; tries++) { spawnPos.Set(Pos).Add( -0.5 + Api.World.Rand.NextDouble(), -1, -0.5 + Api.World.Rand.NextDouble() ); if (!collisionTester.IsColliding(Api.World.BlockAccessor, collisionBox, spawnPos, false)) { if (herdId == 0) { herdId = GetNextHerdId(); } DoSpawn(type, spawnPos, herdId); break; } } insideLocustCount--; } } }
private void CheckGrowth(float dt) { if (!entity.Alive) { return; } ITreeAttribute hungerTree = entity.WatchedAttributes.GetOrAddTreeAttribute("hunger"); if (entity.World.Calendar.TotalHours >= TimeSpawned + HoursToGrow && hungerTree.GetFloat("saturation", 0) >= SatietyToGrow) { AssetLocation[] entityCodes = AdultEntityCodes; if (entityCodes.Length == 0) { return; } AssetLocation code = entityCodes[entity.World.Rand.Next(entityCodes.Length)]; EntityProperties adultType = entity.World.GetEntityType(code); if (adultType == null) { entity.World.Logger.Error("Misconfigured entity. Entity with code '{0}' is configured (via Grow behavior) to grow into '{1}', but no such entity type was registered.", entity.Code, code); return; } Cuboidf collisionBox = adultType.SpawnCollisionBox; // Delay adult spawning if we're colliding if (entity.World.CollisionTester.IsColliding(entity.World.BlockAccessor, collisionBox, entity.ServerPos.XYZ, false)) { callbackId = entity.World.RegisterCallback(CheckGrowth, 3000); return; } Entity adult = entity.World.ClassRegistry.CreateEntity(adultType); adult.ServerPos.SetFrom(entity.ServerPos); adult.Pos.SetFrom(adult.ServerPos); entity.Die(EnumDespawnReason.Expire, null); entity.World.SpawnEntity(adult); adult.WatchedAttributes.SetInt("generation", entity.WatchedAttributes.GetInt("generation", 0)); } else { callbackId = entity.World.RegisterCallback(CheckGrowth, 3000); } entity.World.FrameProfiler.Mark("entity-checkgrowth"); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); msLaunch = World.ElapsedMilliseconds; collisionTestBox = CollisionBox.Clone().OmniGrowBy(0.05f); if (api.Side == EnumAppSide.Server) { GetBehavior <EntityBehaviorPassivePhysics>().OnPhysicsTickCallback = onPhysicsTickCallback; ep = api.ModLoader.GetModSystem <EntityPartitioning>(); } }
private Cuboidf[] CloneArray(Cuboidf[] array) { if (array == null) { return(null); } int l = array.Length; Cuboidf[] result = new Cuboidf[l]; for (int i = 0; i < l; i++) { result[i] = array[i].Clone(); } return(result); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); msLaunch = World.ElapsedMilliseconds; collisionTestBox = SelectionBox.Clone().OmniGrowBy(0.05f); if (api.Side == EnumAppSide.Server) { GetBehavior <EntityBehaviorPassivePhysics>().OnPhysicsTickCallback = onPhysicsTickCallback; ep = api.ModLoader.GetModSystem <EntityPartitioning>(); } GetBehavior <EntityBehaviorPassivePhysics>().collisionYExtra = 0f; // Slightly cheap hax so that stones/arrows don't collid with fences }
internal Cuboidf[] GetSelectionBoxes(IBlockAccessor blockAccessor, BlockPos pos, ItemStack holdingItemStack = null) { ICoreClientAPI capi = Api as ICoreClientAPI; if (capi == null) { return(null); } VoxelCircuit.EnumCircuitSelectionType selType; Item heldItem = holdingItemStack?.Item; Vec3i compSize = SignalsUtils.GetCircuitComponentSizeFromItem(capi, heldItem); if (heldItem?.Code?.ToString() == "signals:el_wire") { selType = VoxelCircuit.EnumCircuitSelectionType.PlaceWire; } else if (compSize != null) { selType = VoxelCircuit.EnumCircuitSelectionType.PlaceComponent; } else { selType = VoxelCircuit.EnumCircuitSelectionType.PlaceNothing; } Cuboidf[] boxes = Circuit?.GetSelectionBoxes(compSize, selType); if (selType == VoxelCircuit.EnumCircuitSelectionType.PlaceNothing) { Array.Resize(ref boxes, boxes.Length + 1); boxes[boxes.Length - 1] = new Cuboidf(0, 0, 0, 1, 1f / 16, 1); } //----------- Cuboidf[] rotatedBoxes = new Cuboidf[boxes.Length]; Vec3f rotation = SignalsUtils.FacingToRotation(orientation, facing); for (int i = 0; i < boxes.Length; i++) { rotatedBoxes[i] = boxes[i].RotatedCopy(rotation.X, rotation.Y, rotation.Z, new Vec3d(0.5d, 0.5, 0.5)); } return(rotatedBoxes); }
/// <summary> /// Get all blocks colliding with entityBoxRel /// </summary> /// <param name="blockAccessor"></param> /// <param name="entityBoxRel"></param> /// <param name="pos"></param> /// <param name="blocks">The found blocks</param> /// <param name="alsoCheckTouch"></param> /// <returns>If any blocks have been found</returns> public bool GetCollidingCollisionBox(IBlockAccessor blockAccessor, Cuboidf entityBoxRel, Vec3d pos, out CachedCuboidList blocks, bool alsoCheckTouch = true) { blocks = new CachedCuboidList(); BlockPos blockPos = new BlockPos(); Vec3d blockPosVec = new Vec3d(); Cuboidd entityBox = entityBoxRel.ToDouble().Translate(pos); int minX = (int)(entityBoxRel.MinX + pos.X); int minY = (int)(entityBoxRel.MinY + pos.Y - 1); // -1 for the extra high collision box of fences int minZ = (int)(entityBoxRel.MinZ + pos.Z); int maxX = (int)Math.Ceiling(entityBoxRel.MaxX + pos.X); int maxY = (int)Math.Ceiling(entityBoxRel.MaxY + pos.Y); int maxZ = (int)Math.Ceiling(entityBoxRel.MaxZ + pos.Z); for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { Block block = blockAccessor.GetBlock(x, y, z); blockPos.Set(x, y, z); blockPosVec.Set(x, y, z); Cuboidf[] collisionBoxes = block.GetCollisionBoxes(blockAccessor, blockPos); for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++) { Cuboidf collBox = collisionBoxes[i]; if (collBox == null) { continue; } bool colliding = alsoCheckTouch ? entityBox.IntersectsOrTouches(collBox, blockPosVec) : entityBox.Intersects(collBox, blockPosVec); if (colliding) { blocks.Add(collBox, x, y, z, block); } } } } } return(blocks.Count > 0); }
private bool TryStepSmooth(EntityControls controls, EntityPos pos, Vec2d walkVec, float dtFac, List <Cuboidd> stepableBoxes, Cuboidd entityCollisionBox) { if (stepableBoxes == null || stepableBoxes.Count == 0) { return(false); } double gravityOffset = 0.03; // This added constant value is a fugly hack because outposition has gravity added, but has not adjusted its position to the ground floor yet var walkVecOrtho = new Vec2d(walkVec.Y, -walkVec.X).Normalize(); var maxX = Math.Abs(walkVecOrtho.X * 0.3) + 0.001; var minX = -maxX; var maxZ = Math.Abs(walkVecOrtho.Y * 0.3) + 0.001; var minZ = -maxZ; var col = new Cuboidf((float)minX, entity.CollisionBox.Y1, (float)minZ, (float)maxX, entity.CollisionBox.Y2, (float)maxZ); double newYPos = pos.Y; bool foundStep = false; foreach (var stepableBox in stepableBoxes) { double heightDiff = stepableBox.Y2 - entityCollisionBox.Y1 + gravityOffset; Vec3d steppos = new Vec3d(GameMath.Clamp(outposition.X, stepableBox.MinX, stepableBox.MaxX), outposition.Y + heightDiff, GameMath.Clamp(outposition.Z, stepableBox.MinZ, stepableBox.MaxZ)); bool canStep = !collisionTester.IsColliding(entity.World.BlockAccessor, col, steppos, false); if (canStep) { double elevateFactor = controls.Sprint ? 0.10 : controls.Sneak ? 0.025 : 0.05; if (!stepableBox.IntersectsOrTouches(entityCollisionBox)) { newYPos = Math.Max(newYPos, Math.Min(pos.Y + elevateFactor * dtFac, stepableBox.Y2 - entity.CollisionBox.Y1 + gravityOffset)); } else { newYPos = Math.Max(newYPos, pos.Y + elevateFactor * dtFac); } foundStep = true; } } if (foundStep) { pos.Y = newYPos; collisionTester.ApplyTerrainCollision(entity, pos, dtFac, ref outposition); } return(foundStep); }
internal void OnUseOver(IPlayer byPlayer, int selectionBoxIndex) { // box index 0 is the anvil itself if (selectionBoxIndex <= 0 || selectionBoxIndex >= selectionBoxes.Length) { return; } Cuboidf box = selectionBoxes[selectionBoxIndex]; Vec3i voxelPos = new Vec3i((int)(16 * box.X1), (int)(16 * box.Y1) - 10, (int)(16 * box.Z1)); OnUseOver(byPlayer, voxelPos, new BlockSelection() { Position = Pos, SelectionBoxIndex = selectionBoxIndex }); }
public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { stepHeight = typeAttributes["stepHeight"].AsFloat(0.6f); for (int i = 0; i < Locomotors.Count; i++) { Locomotors[i].Initialize(properties); } smallerCollisionBox = entity.CollisionBox.Clone().OmniNotDownGrowBy(-0.1f); if (entity.World.Side == EnumAppSide.Client) { capi = (entity.World.Api as ICoreClientAPI); duringRenderFrame = true; capi.Event.RegisterRenderer(this, EnumRenderStage.Before, "controlledphysics"); } }
public override Cuboidf[] GetSelectionBoxes(IBlockAccessor blockAccessor, BlockPos pos) { var block = blockAccessor.GetBlock(pos.X + OffsetInv.X, pos.Y + OffsetInv.Y, pos.Z + OffsetInv.Z); var blockm = block as IMultiBlockMonolithicSmall; if (blockm != null) { return(blockm.MBGetSelectionBoxes(blockAccessor, pos, OffsetInv)); } // Prevent Stack overflow if (block is BlockMultiblock || block.Id == 0) { return(new Cuboidf[] { Cuboidf.Default() }); } return(block.GetSelectionBoxes(blockAccessor, pos)); }
private void CheckGrowth(float dt) { if (!entity.Alive) { return; } if (entity.World.Calendar.TotalHours >= TimeSpawned + HoursToGrow) { AssetLocation[] entityCodes = AdultEntityCodes; if (entityCodes.Length == 0) { return; } AssetLocation code = entityCodes[entity.World.Rand.Next(entityCodes.Length)]; EntityProperties adultType = entity.World.GetEntityType(code); Cuboidf collisionBox = adultType.SpawnCollisionBox; // Delay adult spawning if we're colliding if (entity.World.CollisionTester.IsColliding(entity.World.BlockAccessor, collisionBox, entity.ServerPos.XYZ, false)) { callbackId = entity.World.RegisterCallback(CheckGrowth, 3000); return; } Entity adult = entity.World.ClassRegistry.CreateEntity(adultType); adult.ServerPos.SetFrom(entity.ServerPos); adult.Pos.SetFrom(adult.ServerPos); entity.Die(EnumDespawnReason.Expire, null); entity.World.SpawnEntity(adult); adult.WatchedAttributes.SetInt("generation", entity.WatchedAttributes.GetInt("generation", 0)); } else { callbackId = entity.World.RegisterCallback(CheckGrowth, 3000); } entity.World.FrameProfiler.Mark("entity-checkgrowth"); }
public Cuboidf[] GetSelectionBoxes() { if (selBoxCrate == null) { selBoxCrate = ownBlock.SelectionBoxes[0].RotatedCopy(0, ((int)Math.Round(rotAngleY * GameMath.RAD2DEG / 90)) * 90, 0, new Vec3d(0.5, 0, 0.5)); selBoxLabel = ownBlock.SelectionBoxes[1].RotatedCopy(0, rotAngleY * GameMath.RAD2DEG, 0, new Vec3d(0.5, 0, 0.5)); } if (Api.Side == EnumAppSide.Client) { var hotbarslot = (Api as ICoreClientAPI).World.Player.InventoryManager.ActiveHotbarSlot; if (hotbarslot?.Itemstack?.ItemAttributes?["pigment"]?["color"].Exists == true) { return(new Cuboidf[] { selBoxCrate, selBoxLabel }); } } return(new Cuboidf[] { selBoxCrate }); }