public override void OnGameTick(float deltaTime) { if (entity.State == EnumEntityState.Inactive) { return; } Vec3d pos = entity.LocalPos.XYZ; pushVector.Set(0, 0, 0); Vec3d p = new Vec3d(); entity.World.GetEntitiesAround(pos, 10, 5, (e) => { EntityPos epos = e.LocalPos; double distanceSq = epos.SquareDistanceTo(pos); if (e != entity && distanceSq < touchDistance * touchDistance && e.HasBehavior("repulseagents") && e.IsInteractable) { p.Set(pos.X - epos.X, pos.Y - epos.Y, pos.Z - epos.Z); p.Normalize().Mul(1 - GameMath.Sqrt(distanceSq) / touchDistance); pushVector.Add(p.X, p.Y, p.Z); } return(false); }); pushVector.X = GameMath.Clamp(pushVector.X, -3, 3); pushVector.Y = GameMath.Clamp(pushVector.Y, -3, 3); pushVector.Z = GameMath.Clamp(pushVector.Z, -3, 3); entity.LocalPos.Motion.Add(pushVector.X / 15, pushVector.Y / 30, pushVector.Z / 15); entity.World.FrameProfiler.Mark("entity-repulse"); }
public override void OnEntitySpawn() { base.OnEntitySpawn(); id = entity.World.RegisterGameTickListener(dt => { runAwayFrom = null; try { runAwayFrom = poiRegistry.GetNearestPoi(entity.ServerPos.XYZ, 100, (poi) => { if (poi == null) { return(false); } float?fear = (poi as IPointOfFear)?.FearRadius; if (fear == null) { return(false); } return(poi.Position.DistanceTo(entity.Pos.XYZ) < fear && poi.Type == "scary"); }) as IPointOfFear; if (runAwayFrom == null) { return; } goTo = goTo ?? runAwayFrom.Position.AheadCopy(runAwayFrom.FearRadius + 5, 0, rand.NextDouble() * 360); while (goTo.AsBlockPos.GetBlock(entity.Api).Id != 0 && goTo.AsBlockPos.Y < world.BlockAccessor.MapSizeY) { goTo.Add(0, 1, 0); } } catch (Exception) { } }, 4000 + rand.Next(0, 1000)); }
private bool WalkEntity(Entity e) { if (!e.hasRepulseBehavior || !e.IsInteractable || e == entity) { return(true); } double dx = ownPosRepulseX - e.ownPosRepulse.X; double dy = ownPosRepulseY - e.ownPosRepulse.Y; double dz = ownPosRepulseZ - e.ownPosRepulse.Z; double distSq = dx * dx + dy * dy + dz * dz; double minDistSq = entity.touchDistanceSq + e.touchDistanceSq; if (distSq >= minDistSq) { return(true); } double pushForce = (1 - distSq / minDistSq) / Math.Max(0.001f, GameMath.Sqrt(distSq)); double px = dx * pushForce; double py = dy * pushForce; double pz = dz * pushForce; float hisSize = e.SelectionBox.Length * e.SelectionBox.Height; float pushDiff = GameMath.Clamp(hisSize / mySize, 0, 1); pushVector.Add(px * pushDiff, py * pushDiff, pz * pushDiff); return(true); }
public Vec3d RandomParticlePos(BlockFacing facing = null) { Random rand = Api.World.Rand; IBlockAccessor blockAccess = Api.World.BlockAccessor; Cuboidf box = Block.GetParticleBreakBox(blockAccess, Pos, facing); if (facing == null) { return(new Vec3d( Pos.X + box.X1 + 1 / 32f + rand.NextDouble() * (box.XSize - 1 / 16f), Pos.Y + box.Y1 + 1 / 32f + rand.NextDouble() * (box.YSize - 1 / 16f), Pos.Z + box.Z1 + 1 / 32f + rand.NextDouble() * (box.ZSize - 1 / 16f) )); } else { bool haveBox = box != null; Vec3i facev = facing.Normali; Vec3d outpos = new Vec3d( Pos.X + 0.5f + facev.X / 1.9f + (haveBox && facing.Axis == EnumAxis.X ? (facev.X > 0 ? box.X2 - 1 : box.X1) : 0), Pos.Y + 0.5f + facev.Y / 1.9f + (haveBox && facing.Axis == EnumAxis.Y ? (facev.Y > 0 ? box.Y2 - 1 : box.Y1) : 0), Pos.Z + 0.5f + facev.Z / 1.9f + (haveBox && facing.Axis == EnumAxis.Z ? (facev.Z > 0 ? box.Z2 - 1 : box.Z1) : 0) ); outpos.Add( (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.X)), (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.Y)) - (facing == BlockFacing.DOWN ? 0.1f : 0f), (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.Z)) ); return(outpos); } }
private void WalkEntity(Entity e) { double hisTouchDistance = (e.CollisionBox.X2 - e.CollisionBox.X1) / 2; EntityPos epos = e.LocalPos; hisPos.Set( epos.X + (e.CollisionBox.X2 - e.OriginCollisionBox.X2), epos.Y + (e.CollisionBox.Y2 - e.OriginCollisionBox.Y2), epos.Z + (e.CollisionBox.Z2 - e.OriginCollisionBox.Z2) ); double centerToCenterDistance = GameMath.Sqrt(hisPos.SquareDistanceTo(ownPos)); if (e != entity && centerToCenterDistance < ownTouchDistance + hisTouchDistance && e.HasBehavior("repulseagents") && e.IsInteractable) { tmppos.Set(ownPos.X - hisPos.X, ownPos.Y - hisPos.Y, ownPos.Z - hisPos.Z); tmppos.Normalize().Mul(1 - centerToCenterDistance / (ownTouchDistance + hisTouchDistance)); float hisSize = e.CollisionBox.Length * e.CollisionBox.Height; float mySize = entity.CollisionBox.Length * entity.CollisionBox.Height; float pushDiff = GameMath.Clamp(hisSize / mySize, 0, 1); pushVector.Add(tmppos.X * pushDiff, tmppos.Y * pushDiff, tmppos.Z * pushDiff); } }
public override bool ContinueExecute(float dt) { goTo = goTo ?? runAwayFrom.Position.AheadCopy(runAwayFrom.FearRadius + 5, 0, rand.NextDouble() * 360); while (goTo.AsBlockPos.GetBlock(entity.Api).Id != 0 && goTo.AsBlockPos.Y < world.BlockAccessor.MapSizeY) { goTo.Add(0, 1, 0); } pathTraverser.NavigateTo(goTo, moveSpeed, OnGoalReached, OnStuck); return(ShouldExecute()); }
private void OnGoalReached() { fleeState = !fleeState; if (fleeState) { pathTraverser.WalkTowards(targetPos.Add(0, 1, 0), moveSpeed, 1f, OnGoalReached, OnStuck); } else { pathTraverser.WalkTowards(targetPos, moveSpeed, 1f, OnGoalReached, OnStuck); } }
public override void OnFinalizeFrame(float dt) { base.OnFinalizeFrame(dt); entityPos.Set(owningEntity.Pos.X, owningEntity.Pos.Y, owningEntity.Pos.Z); entityPos.Add(owningEntity.SelectionBox.X2 - owningEntity.OriginSelectionBox.X2, 0, owningEntity.SelectionBox.Z2 - owningEntity.OriginSelectionBox.Z2); if (!IsInRangeOfBlock()) { // Because we cant do it in here capi.Event.EnqueueMainThreadTask(() => TryClose(), "closedlg"); } }
public override void OnFinalizeFrame(float dt) { base.OnFinalizeFrame(dt); entityPos.Set(owningEntity.Pos.X, owningEntity.Pos.Y, owningEntity.Pos.Z); entityPos.Add(owningEntity.CollisionBox.X2 - owningEntity.OriginCollisionBox.X2, 0, owningEntity.CollisionBox.Z2 - owningEntity.OriginCollisionBox.Z2); if (!IsInRangeOfBlock()) { // Because we cant do it in here capi.Event.RegisterCallback((deltatime) => TryClose(), 0); } }
public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ref EnumHandling handled) { testBlockPos.Clear(); lworld = world; if (world.Side != EnumAppSide.Server) { return; } BlockPos pos = blockPos; targetPos = world.GetNearestEntity(pos.ToVec3d(), 64, 64).Pos.AsBlockPos; Vec3d posv = pos.ToVec3d(); Vec3d tgtv = targetPos.ToVec3d(); BlockPos mP = ((posv.Add(tgtv)) / 2).AsBlockPos; int sR = (int)mP.DistanceTo(pos) + 4; var grid = new CubeGrid(sR * 2, sR * 2, sR * 2); if (!grid.isInBounds(world, targetPos) || !grid.isPassable(world, targetPos) || !grid.isWalkable(world, targetPos)) { return; } for (int x = mP.X - sR; x <= mP.X + sR; x++) { for (int y = mP.Y - sR; y <= mP.Y + sR; y++) { for (int z = mP.Z - sR; z <= mP.Z + sR; z++) { BlockPos currentPos = new BlockPos(x, y, z); if (grid.isInBounds(world, currentPos) && grid.isPassable(world, currentPos) && grid.isWalkable(world, currentPos)) { grid.air.Add(currentPos); } else { grid.walls.Add(currentPos); } } } } var astar = new AStarSearch(world, grid, pos, targetPos); DrawGrid(world, astar, mP, sR); world.BlockAccessor.SetBlock(2278, pos); //world.BlockAccessor.SetBlock(2279, mP); world.BlockAccessor.SetBlock(2278, targetPos); testBlockPos.Add(targetPos); testBlockPos.Add(pos); //testBlockPos.Add(mP); return; }
private void onTick25msClient(float dt) { double squeezeRel = mashStack?.Attributes.GetDouble("squeezeRel", 1) ?? 1; if (MashSlot.Empty || renderer.juiceTexPos == null || squeezeRel >= 1) { return; } int[] cols = renderer.juiceTexPos.RndColors; var rand = Api.World.Rand; liquidParticles.MinQuantity = (float)juiceableLitresLeft / 10f; for (int i = 0; i < 4; i++) { BlockFacing face = BlockFacing.HORIZONTALS[i]; liquidParticles.Color = cols[rand.Next(cols.Length)]; Vec3d minPos = face.Plane.Startd.Add(-0.5, 0, -0.5); Vec3d maxPos = face.Plane.Endd.Add(-0.5, 0, -0.5); minPos.Mul(8 / 16f); maxPos.Mul(8 / 16f); maxPos.Y = 5 / 16f - (1 - squeezeRel) * 0.25f; minPos.Add(face.Normalf.X * 1.2f / 16f, 0, face.Normalf.Z * 1.2f / 16f); maxPos.Add(face.Normalf.X * 1.2f / 16f, 0, face.Normalf.Z * 1.2f / 16f); liquidParticles.MinPos = minPos; liquidParticles.AddPos = maxPos.Sub(minPos); liquidParticles.MinPos.Add(Pos).Add(0.5, 1, 0.5); Api.World.SpawnParticles(liquidParticles); } if (squeezeRel < 0.9f) { liquidParticles.MinPos = Pos.ToVec3d().Add(6 / 16f, 0.7f, 6 / 16f); liquidParticles.AddPos.Set(4 / 16f, 0f, 4 / 16f); for (int i = 0; i < 3; i++) { liquidParticles.Color = cols[rand.Next(cols.Length)]; Api.World.SpawnParticles(liquidParticles); } } }
public List <BlockPos> MakeGrid(IWorldAccessor world, BlockPos targetPos, BlockPos startPos) { BlockPos pos = startPos; Vec3d posv = pos.ToVec3d(); Vec3d tgtv = targetPos.ToVec3d(); BlockPos mP = ((posv.Add(tgtv)) / 2).AsBlockPos; int sR = (int)mP.DistanceTo(pos) + 4; var grid = new CubeGrid(sR * 2, sR * 2, sR * 2); if (!grid.isInBounds(world, targetPos) || !grid.isPassable(world, targetPos) || !grid.isWalkable(world, targetPos)) { return(new List <BlockPos> { startPos }); } for (int x = mP.X - sR; x <= mP.X + sR; x++) { for (int y = mP.Y - sR; y <= mP.Y + sR; y++) { for (int z = mP.Z - sR; z <= mP.Z + sR; z++) { BlockPos currentPos = new BlockPos(x, y, z); if (grid.isInBounds(world, currentPos) && grid.isPassable(world, currentPos) && grid.isWalkable(world, currentPos)) { grid.air.Add(currentPos); } else { grid.walls.Add(currentPos); } } } } var astar = new AStarSearch(world, grid, pos, targetPos); return(CurrentPath(world, astar, mP, sR)); }
/// <summary> /// Gets the point in between. /// </summary> /// <param name="point1">The point1.</param> /// <param name="point2">The point2.</param> /// <param name="percent">The percent.</param> /// <param name="wholeProgress">The whole progress.</param> /// <param name="isFirstLoop">if set to <c>true</c> [is first loop].</param> /// <param name="isLastLoop">if set to <c>true</c> [is last loop].</param> /// <returns>CamNode.</returns> internal new CamNode GetPointInBetween(CamNode point1, CamNode point2, double percent, double wholeProgress, bool isFirstLoop, bool isLastLoop) { var newCamPoint = base.GetPointInBetween(point1, point2, percent, wholeProgress, isFirstLoop, isLastLoop); var angle = wholeProgress * 360; var center = _target.GetPosition(); if (center == null) { return(newCamPoint); } var centerPoint = new Vec3d(center.X, center.Y, center.Z); var newPoint = new Vec3d(_sphereOrigin.X, _sphereOrigin.Y, _sphereOrigin.Z) { Y = 0 }; var matrix = new Matrix3d(); Matrix3d.RotY(angle * GameMath.DEG2RAD); matrix.Transform(newPoint); newPoint.Y = _yAxis.ValueAt(wholeProgress) - center.Y; newPoint.Normalize(); newPoint.Scale(_radius); newPoint.Add(centerPoint); newCamPoint.X = newPoint.X; newCamPoint.Y = newPoint.Y; newCamPoint.Z = newPoint.Z; return(newCamPoint); }
private bool TryCircleTarget() { // Console.WriteLine("try circle target"); bool giveUpWhenNoPath = targetPos.SquareDistanceTo(entity.Pos) < 12 * 12; int searchDepth = 3500; attackPattern = EnumAttackPattern.CircleTarget; lastPathfindOk = false; // If we cannot find a path to the target, let's circle it! float angle = (float)Math.Atan2(entity.ServerPos.X - targetPos.X, entity.ServerPos.Z - targetPos.Z); for (int i = 0; i < 3; i++) { // We need to avoid crossing the path of the target, so we do only small angle variation between us and the target double randAngle = angle + 0.5 + world.Rand.NextDouble() / 2; double distance = 4 + world.Rand.NextDouble() * 6; double dx = GameMath.Sin(randAngle) * distance; double dz = GameMath.Cos(randAngle) * distance; targetPos.Add(dx, 0, dz); int tries = 0; bool ok = false; BlockPos tmp = new BlockPos((int)targetPos.X, (int)targetPos.Y, (int)targetPos.Z); int dy = 0; while (tries < 5) { // Down ok? if (world.BlockAccessor.GetBlock(tmp.X, tmp.Y - dy, tmp.Z).SideSolid[BlockFacing.UP.Index] && !world.CollisionTester.IsColliding(world.BlockAccessor, entity.SelectionBox, new Vec3d(tmp.X + 0.5, tmp.Y - dy + 1, tmp.Z + 0.5), false)) { ok = true; targetPos.Y -= dy; targetPos.Y++; break; } // Up ok? if (world.BlockAccessor.GetBlock(tmp.X, tmp.Y + dy, tmp.Z).SideSolid[BlockFacing.UP.Index] && !world.CollisionTester.IsColliding(world.BlockAccessor, entity.SelectionBox, new Vec3d(tmp.X + 0.5, tmp.Y + dy + 1, tmp.Z + 0.5), false)) { ok = true; targetPos.Y += dy; targetPos.Y++; break; } tries++; dy++; } if (ok) { pathTraverser.NavigateTo_Async(targetPos.Clone(), moveSpeed, MinDistanceToTarget(), OnGoalReached, OnStuck, OnCircleTargetUnable, searchDepth, 1); return(true); } } return(false); }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) { if (blockSel == null) { return(false); } ILiquidMetalSink be = byEntity.World.BlockAccessor.GetBlockEntity(blockSel.Position) as ILiquidMetalSink; if (be == null) { return(false); } if (!be.CanReceiveAny) { return(false); } KeyValuePair <ItemStack, int> contents = GetContents(byEntity.World, slot.Itemstack); if (!be.CanReceive(contents.Key)) { return(false); } float speed = 1.5f; float temp = GetTemperature(byEntity.World, slot.Itemstack); if (byEntity.World is IClientWorldAccessor) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); tf.Origin.Set(0.5f, 0.2f, 0.5f); tf.Translation.Set(0, 0, -Math.Min(0.25f, speed * secondsUsed / 4)); tf.Scale = 1f + Math.Min(0.25f, speed * secondsUsed / 4); tf.Rotation.X = Math.Max(-110, -secondsUsed * 90 * speed); byEntity.Controls.UsingHeldItemTransformBefore = tf; } IPlayer byPlayer = null; if (byEntity is EntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID); } if (secondsUsed > 1 / speed) { if ((int)(30 * secondsUsed) % 3 == 1) { Vec3d pos = byEntity.Pos.XYZ .Ahead(0.1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw) .Ahead(1.0f, byEntity.Pos.Pitch, byEntity.Pos.Yaw - GameMath.PIHALF) ; pos.Y += byEntity.LocalEyePos.Y - 0.4f; smokePouring.MinPos = pos.AddCopy(-0.15, -0.15, -0.15); Vec3d blockpos = blockSel.Position.ToVec3d().Add(0.5, 0.2, 0.5); bigMetalSparks.MinQuantity = Math.Max(0.2f, 1 - (secondsUsed - 1) / 4); if ((int)(30 * secondsUsed) % 7 == 1) { bigMetalSparks.MinPos = pos; bigMetalSparks.MinVelocity.Set(-2, -1, -2); bigMetalSparks.AddVelocity.Set(4, 1, 4); byEntity.World.SpawnParticles(bigMetalSparks, byPlayer); byEntity.World.SpawnParticles(smokePouring, byPlayer); } float y2 = 0; Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); Cuboidf[] collboxs = block.GetCollisionBoxes(byEntity.World.BlockAccessor, blockSel.Position); for (int i = 0; collboxs != null && i < collboxs.Length; i++) { y2 = Math.Max(y2, collboxs[i].Y2); } // Metal Spark on the mold bigMetalSparks.MinVelocity.Set(-2, 1, -2); bigMetalSparks.AddVelocity.Set(4, 5, 4); bigMetalSparks.MinPos = blockpos.AddCopy(-0.25, y2 - 2 / 16f, -0.25); bigMetalSparks.AddPos.Set(0.5, 0, 0.5); bigMetalSparks.VertexFlags = (byte)GameMath.Clamp((int)temp - 770, 48, 128); byEntity.World.SpawnParticles(bigMetalSparks, byPlayer); // Smoke on the mold byEntity.World.SpawnParticles( Math.Max(1, 12 - (secondsUsed - 1) * 6), ColorUtil.ToRgba(50, 220, 220, 220), blockpos.AddCopy(-0.5, y2 - 2 / 16f, -0.5), blockpos.Add(0.5, y2 - 2 / 16f + 0.15, 0.5), new Vec3f(-0.5f, 0f, -0.5f), new Vec3f(0.5f, 0f, 0.5f), 1.5f, -0.05f, 0.75f, EnumParticleModel.Quad, byPlayer ); } int transferedAmount = Math.Min(2, contents.Value); be.ReceiveLiquidMetal(contents.Key, ref transferedAmount, temp); int newAmount = Math.Max(0, contents.Value - (2 - transferedAmount)); slot.Itemstack.Attributes.SetInt("units", newAmount); if (newAmount <= 0 && byEntity.World is IServerWorldAccessor) { string emptiedCode = Attributes["emptiedBlockCode"].AsString(); slot.Itemstack = new ItemStack(byEntity.World.GetBlock(AssetLocation.Create(emptiedCode, Code.Domain))); slot.MarkDirty(); // Since we change the item stack we have to call this ourselves OnHeldInteractStop(secondsUsed, slot, byEntity, blockSel, entitySel); return(false); } return(true); } return(true); }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) { if (blockSel == null) { return(false); } if (slot.Itemstack.TempAttributes.GetInt("refilled") > 0) { return(false); } float prevsecondsused = slot.Itemstack.TempAttributes.GetFloat("secondsUsed"); slot.Itemstack.TempAttributes.SetFloat("secondsUsed", secondsUsed); float remainingwater = GetRemainingWateringSeconds(slot.Itemstack); SetRemainingWateringSeconds(slot.Itemstack, remainingwater -= secondsUsed - prevsecondsused); if (remainingwater <= 0) { return(false); } IWorldAccessor world = byEntity.World; BlockPos targetPos = blockSel.Position; if (api.World.Side == EnumAppSide.Server) { var beburningBh = world.BlockAccessor.GetBlockEntity(blockSel.Position.AddCopy(blockSel.Face))?.GetBehavior <BEBehaviorBurning>(); if (beburningBh != null) { beburningBh.KillFire(false); } beburningBh = world.BlockAccessor.GetBlockEntity(blockSel.Position)?.GetBehavior <BEBehaviorBurning>(); if (beburningBh != null) { beburningBh.KillFire(false); } Vec3i voxelPos = new Vec3i(); for (int dx = -2; dx < 2; dx++) { for (int dy = -2; dy < 2; dy++) { for (int dz = -2; dz < 2; dz++) { int x = (int)(blockSel.HitPosition.X * 16); int y = (int)(blockSel.HitPosition.Y * 16); int z = (int)(blockSel.HitPosition.Z * 16); if (x + dx < 0 || x + dx > 15 || y + dy < 0 || y + dy > 15 || z + dz < 0 || z + dz > 15) { continue; } voxelPos.Set(x + dx, y + dy, z + dz); int faceAndSubPosition = CollectibleBehaviorArtPigment.BlockSelectionToSubPosition(blockSel.Face, voxelPos); Block decorblock = world.BlockAccessor.GetDecor(blockSel.Position, faceAndSubPosition); if (decorblock?.FirstCodePart() == "caveart") { world.BlockAccessor.BreakDecor(blockSel.Position, blockSel.Face, faceAndSubPosition); } } } } } Block block = world.BlockAccessor.GetBlock(blockSel.Position); bool notOnSolidblock = false; if ((block.CollisionBoxes == null || block.CollisionBoxes.Length == 0) && !block.IsLiquid()) { notOnSolidblock = true; targetPos = targetPos.DownCopy(); } BlockEntityFarmland be = world.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityFarmland; if (be != null) { be.WaterFarmland(secondsUsed - prevsecondsused); } float speed = 3f; if (world.Side == EnumAppSide.Client) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); tf.Origin.Set(0.5f, 0.2f, 0.5f); tf.Translation.Set(-Math.Min(0.25f, speed * secondsUsed / 2), 0, 0); tf.Rotation.Z = GameMath.Min(60, secondsUsed * 90 * speed, 120 - remainingwater * 4); byEntity.Controls.UsingHeldItemTransformBefore = tf; } IPlayer byPlayer = null; if (byEntity is EntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID); } if (secondsUsed > 1 / speed) { Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition); if (notOnSolidblock) { pos.Y = (int)pos.Y + 0.05; } WaterParticles.MinPos = pos.Add(-0.125 / 2, 1 / 16f, -0.125 / 2); byEntity.World.SpawnParticles(WaterParticles, byPlayer); } return(true); }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) { if (blockSel == null) { return(false); } if (slot.Itemstack.TempAttributes.GetInt("refilled") > 0) { return(false); } float prevsecondsused = slot.Itemstack.TempAttributes.GetFloat("secondsUsed"); slot.Itemstack.TempAttributes.SetFloat("secondsUsed", secondsUsed); float remainingwater = GetRemainingWateringSeconds(slot.Itemstack); SetRemainingWateringSeconds(slot.Itemstack, remainingwater -= secondsUsed - prevsecondsused); if (remainingwater <= 0) { return(false); } IWorldAccessor world = byEntity.World; BlockPos targetPos = blockSel.Position; Block facingBlock = world.BlockAccessor.GetBlock(blockSel.Position.AddCopy(blockSel.Face)); if (facingBlock.Code.Path == "fire") { world.BlockAccessor.SetBlock(0, blockSel.Position.AddCopy(blockSel.Face)); } Block block = world.BlockAccessor.GetBlock(blockSel.Position); bool notOnSolidblock = false; if ((block.CollisionBoxes == null || block.CollisionBoxes.Length == 0) && !block.IsLiquid()) { notOnSolidblock = true; targetPos = targetPos.DownCopy(); } BlockEntityFarmland be = world.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityFarmland; if (be != null) { be.WaterFarmland(secondsUsed - prevsecondsused); } float speed = 4f; if (world.Side == EnumAppSide.Client) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); tf.Origin.Set(0.5f, 0.2f, 0.5f); tf.Translation.Set(-Math.Min(0.25f, speed * secondsUsed / 4), 0, 0); tf.Rotation.Z = GameMath.Min(60, secondsUsed * 90 * speed, 80 - remainingwater * 5); byEntity.Controls.UsingHeldItemTransformBefore = tf; } IPlayer byPlayer = null; if (byEntity is EntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID); } if (secondsUsed > 1 / speed) { Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition); if (notOnSolidblock) { pos.Y = (int)pos.Y + 0.05; } WaterParticles.MinPos = pos.Add(-0.125 / 2, 1 / 16f, -0.125 / 2); byEntity.World.SpawnParticles(WaterParticles, byPlayer); } return(true); }
public override void DoRender2D(float dt) { if (isSpectator || (nameTagTexture == null && debugTagTexture == null)) { return; } if ((entity as EntityPlayer)?.ServerControls.Sneak == true && debugTagTexture == null) { return; } IRenderAPI rapi = capi.Render; EntityPlayer entityPlayer = capi.World.Player.Entity; Vec3d aboveHeadPos; if (capi.World.Player.Entity.EntityId == entity.EntityId) { if (rapi.CameraType == EnumCameraMode.FirstPerson) { return; } aboveHeadPos = new Vec3d(entityPlayer.CameraPos.X + entityPlayer.LocalEyePos.X, entityPlayer.CameraPos.Y + 0.4 + entityPlayer.LocalEyePos.Y, entityPlayer.CameraPos.Z + entityPlayer.LocalEyePos.Z); } else { var thisMount = (entity as EntityAgent)?.MountedOn; var selfMount = entityPlayer.MountedOn; if (thisMount?.MountSupplier != null && thisMount.MountSupplier == selfMount?.MountSupplier) { var mpos = thisMount.MountSupplier.GetMountOffset(entity); aboveHeadPos = new Vec3d(entityPlayer.CameraPos.X + entityPlayer.LocalEyePos.X, entityPlayer.CameraPos.Y + 0.4 + entityPlayer.LocalEyePos.Y, entityPlayer.CameraPos.Z + entityPlayer.LocalEyePos.Z); aboveHeadPos.Add(mpos); } else { float f = 1; /*if (entity.Code.Path.Contains("bot") && entity.AnimManager.ActiveAnimationsByAnimCode.ContainsKey("sitflooridle")) * { * f = 0.55f; * }*/ aboveHeadPos = new Vec3d(entity.Pos.X, entity.Pos.Y + entity.SelectionBox.Y2 * f + 0.2, entity.Pos.Z); } } double offX = entity.SelectionBox.X2 - entity.OriginSelectionBox.X2; double offZ = entity.SelectionBox.Z2 - entity.OriginSelectionBox.Z2; aboveHeadPos.Add(offX, 0, offZ); Vec3d pos = MatrixToolsd.Project(aboveHeadPos, rapi.PerspectiveProjectionMat, rapi.PerspectiveViewMat, rapi.FrameWidth, rapi.FrameHeight); // Z negative seems to indicate that the name tag is behind us \o/ if (pos.Z < 0) { return; } float scale = 4f / Math.Max(1, (float)pos.Z); float cappedScale = Math.Min(1f, scale); if (cappedScale > 0.75f) { cappedScale = 0.75f + (cappedScale - 0.75f) / 2; } float offY = 0; double dist = entityPlayer.Pos.SquareDistanceTo(entity.Pos); if (nameTagTexture != null && (!showNameTagOnlyWhenTargeted || capi.World.Player.CurrentEntitySelection?.Entity == entity) && renderRange * renderRange > dist) { float posx = (float)pos.X - cappedScale * nameTagTexture.Width / 2; float posy = rapi.FrameHeight - (float)pos.Y - (nameTagTexture.Height * Math.Max(0, cappedScale)); rapi.Render2DTexture( nameTagTexture.TextureId, posx, posy, cappedScale * nameTagTexture.Width, cappedScale * nameTagTexture.Height, 20 ); offY += nameTagTexture.Height; } if (debugTagTexture != null) { float posx = (float)pos.X - cappedScale * debugTagTexture.Width / 2; float posy = rapi.FrameHeight - (float)pos.Y - (offY + debugTagTexture.Height) * Math.Max(0, cappedScale); rapi.Render2DTexture( debugTagTexture.TextureId, posx, posy - offY, cappedScale * debugTagTexture.Width, cappedScale * debugTagTexture.Height, 20 ); } if (messageTextures != null) { offY += 0; foreach (MessageTexture mt in messageTextures) { offY += (mt.tex.Height * cappedScale) + 4; float posx = (float)pos.X - cappedScale * mt.tex.Width / 2; float posy = (float)pos.Y + offY; rapi.Render2DTexture( mt.tex.TextureId, posx, rapi.FrameHeight - posy, cappedScale * mt.tex.Width, cappedScale * mt.tex.Height, 20 ); } } }
public void update(float dt) { if (pinned) { if (pinnedTo != null) { if (pinnedTo.ShouldDespawn && pinnedTo.DespawnReason?.reason != EnumDespawnReason.Unload) { UnPin(); return; } // New ideas: // don't apply force onto the player/entity on compression // apply huge forces onto the player on strong extension (to prevent massive stretching) (just set player motion to 0 or so. or we add a new countermotion field thats used in EntityControlledPhysics?) float weight = pinnedTo.Properties.Weight; float counterTensionStrength = GameMath.Clamp(50f / weight, 0.1f, 2f); bool extraResist = (pinnedTo as EntityAgent)?.Controls.Sneak == true || pinnedTo.AnimManager?.IsAnimationActive("sit") == true || pinnedTo.AnimManager?.IsAnimationActive("sleep") == true; float tensionResistStrength = weight / 10f * (extraResist ? 200 : 0); pinOffsetTransform.Identity(); pinOffsetTransform.RotateY(pinnedTo.SidedPos.Yaw - pinnedToOffsetStartYaw); tmpvec.Set(pinnedToOffset.X, pinnedToOffset.Y, pinnedToOffset.Z, 1); Vec4f outvec = pinOffsetTransform.TransformVector(tmpvec); EntityPos pos = pinnedTo.SidedPos; Pos.Set(pos.X + outvec.X, pos.Y + outvec.Y, pos.Z + outvec.Z); bool pushable = !(pinnedTo is EntityPlayer eplr && eplr.Player.WorldData.CurrentGameMode == EnumGameMode.Creative); if (pushable && extension > 0) // Do not act on compressive force { float f = counterTensionStrength * dt * 0.003f; pos.Motion.Add( GameMath.Clamp(Math.Abs(TensionDirection.X) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.X), GameMath.Clamp(Math.Abs(TensionDirection.Y) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.Y), GameMath.Clamp(Math.Abs(TensionDirection.Z) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.Z) ); } Velocity.Set(0, 0, 0); } else { Velocity.Set(0, 0, 0); accum1s += dt; if (accum1s >= 1) { accum1s = 0; Block block = cs.api.World.BlockAccessor.GetBlock(PinnedToBlockPos); if (!block.HasBehavior <BlockBehaviorRopeTieable>()) { UnPin(); } } } return; } // Calculate the force on this ball Vec3f force = Tension.Clone(); force.Y -= GravityStrength * 10; // Calculate the acceleration Vec3f acceleration = force * (float)InvMass; if (CollideFlags == 0) { acceleration.X += (float)cs.windSpeed.X * InvMass; } // Update velocity Vec3f nextVelocity = Velocity + (acceleration * dt); // Damp the velocity nextVelocity *= dampFactor; // Collision detection float size = 0.1f; cs.pp.HandleBoyancy(Pos, nextVelocity, cs.boyant, GravityStrength, dt, size); CollideFlags = cs.pp.UpdateMotion(Pos, nextVelocity, size); dt *= 0.99f; Pos.Add(nextVelocity.X * dt, nextVelocity.Y * dt, nextVelocity.Z * dt); Velocity.Set(nextVelocity); Tension.Set(0, 0, 0); }