public ClothPoint(ClothSystem cs, int pointIndex, double x, double y, double z) { this.cs = cs; this.PointIndex = pointIndex; Pos = new Vec3d(x, y, z); init(); }
public void Attach(ClothSystem sys, ClothPoint point) { if (!entity.WatchedAttributes.HasAttribute("clothIds")) { entity.WatchedAttributes["clothIds"] = new IntArrayAttribute(new int[] { sys.ClothId }); } ClothIds.AddInt(sys.ClothId); point.PinTo(entity, new Vec3f(0, 0.5f, 0)); }
private void attachToBlock(EntityAgent byEntity, BlockPos toPosition, ClothSystem sys, ItemSlot slot) { var pEnds = sys.Ends; // 2 possible cases // - We just created a new rope: use pEnds[1] because its unattached // - We already have both ends attached and want to re-attach the player held end ClothPoint cpoint = pEnds[0].PinnedToEntity?.EntityId == byEntity.EntityId && pEnds[1].Pinned ? pEnds[0] : pEnds[1]; cpoint.PinTo(toPosition, new Vec3f(0.5f, 0.5f, 0.5f)); }
private void attachToEntity(EntityAgent byEntity, Entity toEntity, ClothSystem sys, ItemSlot slot) { if (!toEntity.HasBehavior <EntityBehaviorRopeTieable>()) { if (api.World.Side == EnumAppSide.Client) { (api as ICoreClientAPI).TriggerIngameError(this, "notattachable", Lang.Get("This creature is not tieable")); } return; } var pEnds = sys.Ends; ClothPoint cpoint = pEnds[0].PinnedToEntity?.EntityId == byEntity.EntityId && pEnds[1].Pinned ? pEnds[0] : pEnds[1]; toEntity.GetBehavior <EntityBehaviorRopeTieable>().Attach(sys, cpoint); }
private void onClothTest(int groupId, CmdArgs args) { string arg = args.PopWord(); if (arg == "clear") { clothSystems.Clear(); nextClothId = 1; return; } float xsize = 0.5f + (float)capi.World.Rand.NextDouble() * 3; float zsize = 0.5f + (float)capi.World.Rand.NextDouble() * 3; if (arg == "cloth") { ClothSystem sys = ClothSystem.CreateCloth(capi, this, capi.World.Player.Entity.Pos.AsBlockPos.Add(-1, 2, -1), xsize, zsize); RegisterCloth(sys); EntityAgent byEntity = capi.World.Player.Entity; Vec3d pos = byEntity.ServerPos.XYZ.Add(0, byEntity.LocalEyePos.Y, 0); Vec3f leftPos = pos.AheadCopy(0.5, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw + GameMath.PIHALF).ToVec3f(); Vec3f rightPos = pos.AheadCopy(0.5, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw + GameMath.PIHALF).ToVec3f(); // pin the top right and top left. //sys.Points[0][0].PinTo(byEntity, leftPos); //sys.Points[0][numxpoints - 1].PinTo(byEntity, rightPos); } if (arg == "rope") { xsize = 5; ClothSystem sys = ClothSystem.CreateRope(capi, this, capi.World.Player.Entity.Pos.AsBlockPos.Add(-1, 2, -1), xsize, null); RegisterCloth(sys); EntityAgent byEntity = capi.World.Player.Entity; Vec3d pos = new Vec3d(0, byEntity.LocalEyePos.Y, 0); Vec3d aheadPos = pos.AheadCopy(1, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw); sys.WalkPoints(p => p.Pos.Add(pos.X, pos.Y + p.PointIndex / 100f, pos.Z)); sys.FirstPoint.PinTo(byEntity, aheadPos.ToVec3f()); } }
public void RegisterCloth(ClothSystem sys) { if (api.Side == EnumAppSide.Client) { return; } sys.ClothId = nextClothId++; clothSystems[sys.ClothId] = sys; sys.updateActiveState(EnumActiveStateChange.Default); sapi.Network.GetChannel("clothphysics").BroadcastPacket(new ClothSystemPacket() { ClothSystems = new ClothSystem[] { sys } }); }
public void restoreReferences(ClothSystem cs, IWorldAccessor world) { this.cs = cs; if (pinnedToEntityId != 0) { pinnedTo = world.GetEntityById(pinnedToEntityId); if (pinnedTo == null) { UnPin(); } else { PinTo(pinnedTo, pinnedToOffset); } } }
public override void OnModifiedInInventorySlot(IWorldAccessor world, ItemSlot slot, ItemStack extractedStack = null) { if (!(slot.Inventory is InventoryBasePlayer)) { long ropeHeldByEntityId = slot.Itemstack.Attributes.GetLong("ropeHeldByEntityId"); if (ropeHeldByEntityId != 0) { slot.Itemstack.Attributes.RemoveAttribute("ropeHeldByEntityId"); } int clothId = slot.Itemstack.Attributes.GetInt("clothId"); if (clothId != 0) { ClothSystem sys = cm.GetClothSystem(clothId); if (sys != null) { //sys.Points[0][0].PinTo(byEntity, aheadPos.ToVec3f()); } } } }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) { ClothSystem cs = cm.GetClothSystemAttachedToBlock(blockSel.Position); if (cs != null) { Entity byEntity = byPlayer.Entity; ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot; Vec3d lpos = new Vec3d(0, byEntity.LocalEyePos.Y - 0.25f, 0); Vec3d aheadPos = lpos.AheadCopy(0.25f, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw); // Already handled by ItemRope if (!slot.Empty && slot.Itemstack.Collectible.Code.Path == "rope" && (cs.FirstPoint.PinnedToEntity?.EntityId == byPlayer.Entity.EntityId || cs.LastPoint.PinnedToEntity?.EntityId == byPlayer.Entity.EntityId)) { return(base.OnBlockInteractStart(world, byPlayer, blockSel, ref handling)); } ClothPoint targetPoint = cs.FirstPoint.PinnedToBlockPos == blockSel.Position ? cs.FirstPoint : cs.LastPoint; ItemStack stack = new ItemStack(world.GetItem(new AssetLocation("rope"))); stack.Attributes.SetInt("clothId", cs.ClothId); stack.Attributes.SetLong("ropeHeldByEntityId", byEntity.EntityId); if (byPlayer.InventoryManager.TryGiveItemstack(stack, true)) { targetPoint.PinTo(byPlayer.Entity, aheadPos.ToVec3f()); } else { Entity ei = world.SpawnItemEntity(stack, blockSel.Position.ToVec3d().Add(0.5, 0.5, 0.5)); targetPoint.PinTo(ei, new Vec3f(0, 0.1f, 0)); } handling = EnumHandling.PreventDefault; return(true); } return(base.OnBlockInteractStart(world, byPlayer, blockSel, ref handling)); }
public override void OnCollected(ItemStack stack, Entity entity) { int clothId = stack.Attributes.GetInt("clothId"); if (clothId != 0) { ClothSystem sys = cm.GetClothSystem(clothId); if (sys != null) { ClothPoint p = null; if (sys.FirstPoint.PinnedToEntity is EntityItem) { p = sys.FirstPoint; } if (sys.LastPoint.PinnedToEntity is EntityItem) { p = sys.LastPoint; } if (p != null) { Vec3d lpos = new Vec3d(0, entity.LocalEyePos.Y - 0.3f, 0); Vec3d aheadPos = lpos.AheadCopy(0.1f, entity.SidedPos.Pitch, entity.SidedPos.Yaw).AheadCopy(0.4f, entity.SidedPos.Pitch, entity.SidedPos.Yaw - GameMath.PIHALF); p.PinTo(entity, aheadPos.ToVec3f()); ItemSlot collectedSlot = null; (entity as EntityPlayer).WalkInventory((slot) => { if (!slot.Empty && slot.Itemstack.Attributes.GetInt("clothId") == clothId) { collectedSlot = slot; return(false); } return(true); }); collectedSlot?.Itemstack?.Attributes.SetLong("ropeHeldByEntityId", entity.EntityId); collectedSlot?.MarkDirty(); } } } }
private void detach(ClothSystem sys, ItemSlot slot, EntityAgent byEntity, Entity toEntity, BlockPos pos) { toEntity?.GetBehavior <EntityBehaviorRopeTieable>()?.Detach(sys); sys.WalkPoints(point => { if (point.PinnedToBlockPos != null && point.PinnedToBlockPos.Equals(pos)) { point.UnPin(); } if (point.PinnedToEntity?.EntityId == byEntity.EntityId) { point.UnPin(); } }); if (!sys.PinnedAnywhere) { slot.Itemstack.Attributes.RemoveAttribute("clothId"); cm.UnregisterCloth(sys.ClothId); } }
public void Detach(ClothSystem sys) { if (ClothIds == null) { return; } ClothIds.RemoveInt(sys.ClothId); if (ClothIds.value.Length == 0) { entity.WatchedAttributes.RemoveAttribute("clothIds"); } sys.WalkPoints(point => { if (point.PinnedToEntity?.EntityId == entity.EntityId) { point.UnPin(); } }); }
public override void OnGroundIdle(EntityItem entityItem) { long ropeHeldByEntityId = entityItem.Itemstack.Attributes.GetLong("ropeHeldByEntityId"); if (ropeHeldByEntityId != 0) { entityItem.Itemstack.Attributes.RemoveAttribute("ropeHeldByEntityId"); int clothId = entityItem.Itemstack.Attributes.GetInt("clothId"); if (clothId != 0) { // Console.WriteLine(api.World.Side + ", clothid {0}, dropped on ground.", clothId); ClothSystem sys = cm.GetClothSystem(clothId); if (sys != null) { ClothPoint p = null; if (sys.FirstPoint.PinnedToEntity?.EntityId == ropeHeldByEntityId) { p = sys.FirstPoint; } if (sys.LastPoint.PinnedToEntity?.EntityId == ropeHeldByEntityId) { p = sys.LastPoint; } if (p != null) { // Console.WriteLine(api.World.Side + ", clothid {0}, dropped on ground, now pinned to dropped item.", clothId); p.PinTo(entityItem, new Vec3f(entityItem.SelectionBox.X2 / 2, entityItem.SelectionBox.Y2 / 2, entityItem.SelectionBox.Z2 / 2)); } } } } }
public ClothPoint(ClothSystem cs) { this.cs = cs; Pos = new Vec3d(); init(); }
public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handling) { // Disabled outside of creative mode because its too broken if ((byEntity as EntityPlayer)?.Player?.WorldData.CurrentGameMode != EnumGameMode.Creative) { return; } // sneak = attach // non-sneak = detach int clothId = slot.Itemstack.Attributes.GetInt("clothId"); handling = EnumHandHandling.PreventDefault; ClothSystem sys = null; if (clothId != 0) { sys = cm.GetClothSystem(clothId); if (sys == null) { clothId = 0; } } // Detach if (!byEntity.Controls.Sneak) { if (clothId != 0) { //Console.WriteLine(api.World.Side + ", clothid {0}, detach", clothId); detach(sys, slot, byEntity, entitySel?.Entity, blockSel?.Position); } return; } // Attach if (clothId == 0) { float xsize = 2; sys = ClothSystem.CreateRope(api, cm, byEntity.Pos.AsBlockPos.Add(0, 1, 0), xsize, null); Vec3d lpos = new Vec3d(0, byEntity.LocalEyePos.Y - 0.3f, 0); Vec3d aheadPos = lpos.AheadCopy(0.1f, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw).AheadCopy(0.4f, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw - GameMath.PIHALF); EntityPos pos = byEntity.SidedPos; //Console.WriteLine(api.World.Side + ", clothid {0}, new cloth. attach to self", sys.ClothId); sys.FirstPoint.PinTo(byEntity, aheadPos.ToVec3f()); cm.RegisterCloth(sys); slot.Itemstack.Attributes.SetLong("ropeHeldByEntityId", byEntity.EntityId); slot.Itemstack.Attributes.SetInt("clothId", sys.ClothId); slot.MarkDirty(); } ClothPoint[] pEnds = sys.Ends; if (blockSel != null) { Block block = api.World.BlockAccessor.GetBlock(blockSel.Position); if (blockSel.Position.Equals(pEnds[0].PinnedToBlockPos) || blockSel.Position.Equals(pEnds[1].PinnedToBlockPos)) { //Console.WriteLine(api.World.Side + ", clothid {0}, detach from block", sys.ClothId); detach(sys, slot, byEntity, null, blockSel.Position); return; } if (block.HasBehavior <BlockBehaviorRopeTieable>()) { //Console.WriteLine(api.World.Side + ", clothid {0}, attach to block", sys.ClothId); attachToBlock(byEntity, blockSel.Position, sys, slot); } } if (entitySel != null) { if (entitySel.Entity.EntityId == pEnds[0].PinnedToEntity?.EntityId || entitySel.Entity.EntityId == pEnds[1].PinnedToEntity?.EntityId) { //Console.WriteLine(api.World.Side + ", clothid {0}, detach from entity", sys.ClothId); detach(sys, slot, byEntity, entitySel.Entity, null); return; } //Console.WriteLine(api.World.Side + ", clothid {0}, attach to entity", sys.ClothId); attachToEntity(byEntity, entitySel.Entity, sys, slot); } if (clothId == 0) { sys.WalkPoints(p => p.update(0)); Vec3d startPos = sys.FirstPoint.Pos; Vec3d endPos = sys.LastPoint.Pos; double dx = endPos.X - startPos.X; double dy = endPos.Y - startPos.Y; double dz = endPos.Z - startPos.Z; sys.WalkPoints(p => { float f = p.PointIndex / (float)sys.Length; if (!p.Pinned) { p.Pos.Set(startPos.X + dx * f, startPos.Y + dy * f, startPos.Z + dz * f); } }); sys.setRenderCenterPos(); } // No longer pinned to ourselves if (pEnds[0].PinnedToEntity?.EntityId != byEntity.EntityId && pEnds[1].PinnedToEntity?.EntityId != byEntity.EntityId) { //Console.WriteLine(api.World.Side + ", clothid {0}, rope assigned. removed one from inv.", sys.ClothId); slot.Itemstack.Attributes.RemoveAttribute("clothId"); slot.TakeOut(1); slot.MarkDirty(); } }