public override bool TryGiveItemStack(ItemStack itemstack)
        {
            if (itemstack == null || itemstack.StackSize == 0)
            {
                return(false);
            }

            ItemSlot dummySlot = new DummySlot(null);

            dummySlot.Itemstack = itemstack.Clone();

            ItemStackMoveOperation op = new ItemStackMoveOperation(World, EnumMouseButton.Left, 0, EnumMergePriority.AutoMerge, itemstack.StackSize);

            WeightedSlot wslot = inv.GetBestSuitedSlot(dummySlot, new List <ItemSlot>());

            if (wslot.weight > 0)
            {
                dummySlot.TryPutInto(wslot.slot, ref op);
                itemstack.StackSize -= op.MovedQuantity;
                WatchedAttributes.MarkAllDirty();
                return(op.MovedQuantity > 0);
            }

            return(false);
        }
        private void IsColliding(EntityPos pos, double impactSpeed)
        {
            pos.Motion.Set(0, 0, 0);

            if (!beforeCollided && World is IServerWorldAccessor && World.ElapsedMilliseconds > msCollide + 500)
            {
                if (impactSpeed >= 0.07)
                {
                    World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 32);

                    // Slighty randomize orientation to make it a bit more realistic
                    //pos.Yaw += (float)(World.Rand.NextDouble() * 0.05 - 0.025);
                    //pos.Roll += (float)(World.Rand.NextDouble() * 0.05 - 0.025);

                    // Resend position to client
                    WatchedAttributes.MarkAllDirty();

                    int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1);
                    if (leftDurability <= 0)
                    {
                        Die();
                    }
                }

                TryAttackEntity(impactSpeed);

                msCollide = World.ElapsedMilliseconds;

                beforeCollided = true;
            }
        }
        private void IsColliding(EntityPos pos, double impactSpeed)
        {
            pos.Motion.Set(0, 0, 0);

            if (!beforeCollided && World is IServerWorldAccessor && World.ElapsedMilliseconds > msCollide + 500)
            {
                if (impactSpeed >= 0.07)
                {
                    World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 32);

                    // Resend position to client
                    WatchedAttributes.MarkAllDirty();

                    if (DamageStackOnImpact)
                    {
                        ProjectileStack.Collectible.DamageItem(World, this, new DummySlot(ProjectileStack));
                    }

                    int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1);
                    if (leftDurability <= 0)
                    {
                        Die();
                    }
                }

                TryAttackEntity(impactSpeed);

                msCollide = World.ElapsedMilliseconds;

                beforeCollided = true;
            }
        }
Esempio n. 4
0
        public override void OnInteract(EntityAgent byEntity, ItemSlot slot, Vec3d hitPosition, EnumInteractMode mode)
        {
            base.OnInteract(byEntity, slot, hitPosition, mode);

            if ((byEntity as EntityPlayer)?.Controls.Sneak == true && mode == EnumInteractMode.Interact && byEntity.World.Side == EnumAppSide.Server)
            {
                inv.DiscardAll();
                WatchedAttributes.MarkAllDirty();
            }
        }
Esempio n. 5
0
        public override void OnGameTick(float dt)
        {
            base.OnGameTick(dt);
            if (ShouldDespawn)
            {
                return;
            }

            EntityPos pos = LocalPos;

            stuck = Collided;
            if (stuck)
            {
                pos.Pitch = GameMath.PIHALF;
                pos.Roll  = 0;
                pos.Yaw   = GameMath.PIHALF;
            }
            else
            {
                pos.Pitch = (World.ElapsedMilliseconds / 300f) % GameMath.TWOPI;
                pos.Roll  = 0;
                pos.Yaw   = (World.ElapsedMilliseconds / 400f) % GameMath.TWOPI;
            }

            if (stuck)
            {
                if (!beforeCollided && World is IServerWorldAccessor)
                {
                    float strength = GameMath.Clamp((float)motionBeforeCollide.Length() * 4, 0, 1);

                    if (CollidedHorizontally)
                    {
                        pos.Motion.X = motionBeforeCollide.X * 0.8f;
                        pos.Motion.Z = motionBeforeCollide.Z * 0.8f;

                        if (strength > 0.08f && World.Rand.NextDouble() > 0.2f)
                        {
                            World.SpawnCubeParticles(LocalPos.XYZ.OffsetCopy(0, 0.2, 0), ProjectileStack, 0.2f, 20);
                            Die();
                        }
                    }

                    if (CollidedVertically && motionBeforeCollide.Y <= 0)
                    {
                        pos.Motion.Y = GameMath.Clamp(motionBeforeCollide.Y * -0.4f, -0.1f, 0.1f);
                    }



                    World.PlaySoundAt(new AssetLocation("sounds/thud"), this, null, false, 32, strength);

                    // Slighty randomize orientation to make it a bit more realistic
                    //pos.Yaw += (float)(World.Rand.NextDouble() * 0.05 - 0.025);
                    //pos.Roll += (float)(World.Rand.NextDouble() * 0.05 - 0.025);

                    // Resend position to client
                    WatchedAttributes.MarkAllDirty();
                }

                beforeCollided = true;
                return;
            }


            if (World is IServerWorldAccessor)
            {
                Entity entity = World.GetNearestEntity(ServerPos.XYZ, 5f, 5f, (e) => {
                    if (e.EntityId == this.EntityId || (FiredBy != null && e.EntityId == FiredBy.EntityId && World.ElapsedMilliseconds - msLaunch < 500) || !e.IsInteractable)
                    {
                        return(false);
                    }

                    double dist = e.CollisionBox.ToDouble().Translate(e.ServerPos.X, e.ServerPos.Y, e.ServerPos.Z).ShortestDistanceFrom(ServerPos.X, ServerPos.Y, ServerPos.Z);
                    return(dist < 0.5f);
                });

                if (entity != null)
                {
                    bool didDamage = entity.ReceiveDamage(new DamageSource()
                    {
                        Source = EnumDamageSource.Entity, SourceEntity = FiredBy == null ? this : FiredBy, Type = EnumDamageType.BluntAttack
                    }, Damage);
                    World.PlaySoundAt(new AssetLocation("sounds/thud"), this, null, false, 32);
                    World.SpawnCubeParticles(entity.LocalPos.XYZ.OffsetCopy(0, 0.2, 0), ProjectileStack, 0.2f, 20);

                    if (FiredBy is EntityPlayer && didDamage)
                    {
                        World.PlaySoundFor(new AssetLocation("sounds/player/projectilehit"), (FiredBy as EntityPlayer).Player, false, 24);
                    }

                    Die();
                    return;
                }
            }

            beforeCollided = false;
            motionBeforeCollide.Set(pos.Motion.X, pos.Motion.Y, pos.Motion.Z);

            SetRotation();
        }
Esempio n. 6
0
        public override void OnGameTick(float dt)
        {
            base.OnGameTick(dt);
            if (ShouldDespawn)
            {
                return;
            }

            EntityPos pos = SidedPos;

            stuck     = Collided;
            pos.Pitch = GameMath.PIHALF;
            pos.Roll  = 0;
            pos.Yaw   = GameMath.PIHALF;

            if (stuck)
            {
                if (!beforeCollided && World is IServerWorldAccessor)
                {
                    float strength = GameMath.Clamp((float)motionBeforeCollide.Length() * 4, 0, 1);

                    if (CollidedHorizontally || CollidedVertically)
                    {
                        OnImpact();
                        return;
                    }

                    // Resend position to client
                    WatchedAttributes.MarkAllDirty();
                }

                beforeCollided = true;
                return;
            }


            if (World is IServerWorldAccessor)
            {
                Entity entity = World.GetNearestEntity(ServerPos.XYZ, 5f, 5f, (e) => {
                    if (e.EntityId == this.EntityId || (FiredBy != null && e.EntityId == FiredBy.EntityId && World.ElapsedMilliseconds - msLaunch < 500) || !e.IsInteractable)
                    {
                        return(false);
                    }

                    double dist = e.CollisionBox.ToDouble().Translate(e.ServerPos.X, e.ServerPos.Y, e.ServerPos.Z).ShortestDistanceFrom(ServerPos.X, ServerPos.Y, ServerPos.Z);
                    return(dist < 0.5f);
                });

                if (entity != null)
                {
                    entity.ReceiveDamage(new DamageSource()
                    {
                        Source = EnumDamageSource.Entity, SourceEntity = this, Type = EnumDamageType.BluntAttack
                    }, Damage);
                    OnImpact();
                    return;
                }
            }

            beforeCollided = false;
            motionBeforeCollide.Set(pos.Motion.X, pos.Motion.Y, pos.Motion.Z);
        }
        public override void OnInteract(EntityAgent byEntity, ItemSlot slot, Vec3d hitPosition, EnumInteractMode mode)
        {
            IPlayer plr = (byEntity as EntityPlayer)?.Player;

            if (plr != null && !byEntity.World.Claims.TryAccess(plr, Pos.AsBlockPos, EnumBlockAccessFlags.Use))
            {
                plr.InventoryManager.ActiveHotbarSlot.MarkDirty();
                WatchedAttributes.MarkAllDirty();
                return;
            }

            if (mode == EnumInteractMode.Interact && byEntity.RightHandItemSlot != null)
            {
                ItemSlot handslot = byEntity.RightHandItemSlot;
                if (handslot.Empty)
                {
                    // Start from armor slot because it can't wear clothes atm
                    for (int i = 0; i < GearInventory.Count; i++)
                    {
                        ItemSlot gslot = GearInventory[i];
                        if (gslot.Empty)
                        {
                            continue;
                        }

                        if (gslot.TryPutInto(byEntity.World, handslot) > 0)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    if (!ItemSlotCharacter.IsDressType(slot.Itemstack, EnumCharacterDressType.ArmorBody) && !ItemSlotCharacter.IsDressType(slot.Itemstack, EnumCharacterDressType.ArmorHead) && !ItemSlotCharacter.IsDressType(slot.Itemstack, EnumCharacterDressType.ArmorLegs))
                    {
                        (byEntity.World.Api as ICoreClientAPI)?.TriggerIngameError(this, "cantplace", "Cannot place dresses on armor stands");

                        return;
                    }
                }


                WeightedSlot sinkslot = GearInventory.GetBestSuitedSlot(handslot);
                if (sinkslot.weight > 0 && sinkslot.slot != null)
                {
                    handslot.TryPutInto(byEntity.World, sinkslot.slot);
                    return;
                }


                bool empty = true;
                for (int i = 0; i < GearInventory.Count; i++)
                {
                    ItemSlot gslot = GearInventory[i];
                    empty &= gslot.Empty;
                }

                if (empty && byEntity.Controls.Sneak)
                {
                    ItemStack stack = new ItemStack(byEntity.World.GetItem(new AssetLocation("armorstand")));
                    if (!byEntity.TryGiveItemStack(stack))
                    {
                        byEntity.World.SpawnItemEntity(stack, ServerPos.XYZ);
                    }
                    Die();
                    return;
                }
            }



            if (!Alive || World.Side == EnumAppSide.Client || mode == 0)
            {
                //base.OnInteract(byEntity, slot, hitPosition, mode);
                return;
            }


            base.OnInteract(byEntity, slot, hitPosition, mode);
        }
Esempio n. 8
0
        private void RefreshBuyingSellingInventory(float refreshChance = 1.1f)
        {
            if (TradeProps == null)
            {
                return;
            }

            TradeProps.Buying.List.Shuffle(World.Rand);
            int buyingQuantity = Math.Min(TradeProps.Buying.List.Length, TradeProps.Buying.MaxItems);

            TradeProps.Selling.List.Shuffle(World.Rand);
            int sellingQuantity = Math.Min(TradeProps.Selling.List.Length, TradeProps.Selling.MaxItems);

            // Pick quantity items from the trade list that the trader doesn't already sell
            // Slots 0..15: Selling slots
            // Slots 16..19: Buying cart
            // Slots 20..35: Buying slots
            // Slots 36..39: Selling cart
            // Slot 40: Money slot

            Stack <TradeItem> newBuyItems  = new Stack <TradeItem>();
            Stack <TradeItem> newsellItems = new Stack <TradeItem>();

            ItemSlotTrade[] sellingSlots = Inventory.SellingSlots;
            ItemSlotTrade[] buyingSlots  = Inventory.BuyingSlots;

            #region Avoid duplicate sales

            for (int i = 0; i < TradeProps.Selling.List.Length; i++)
            {
                if (newsellItems.Count >= sellingQuantity)
                {
                    break;
                }

                TradeItem item = TradeProps.Selling.List[i];
                item.Resolve(World, "tradeItem resolver");

                bool alreadySelling = sellingSlots.Any((slot) => slot?.Itemstack != null && slot.TradeItem.Stock > 0 && item.ResolvedItemstack?.Equals(World, slot.Itemstack, GlobalConstants.IgnoredStackAttributes) == true);

                if (!alreadySelling)
                {
                    newsellItems.Push(item);
                }
            }

            for (int i = 0; i < TradeProps.Buying.List.Length; i++)
            {
                if (newBuyItems.Count >= buyingQuantity)
                {
                    break;
                }

                TradeItem item = TradeProps.Buying.List[i];
                item.Resolve(World, "tradeItem resolver");

                bool alreadySelling = buyingSlots.Any((slot) => slot?.Itemstack != null && slot.TradeItem.Stock > 0 && item.ResolvedItemstack?.Equals(World, slot.Itemstack, GlobalConstants.IgnoredStackAttributes) == true);

                if (!alreadySelling)
                {
                    newBuyItems.Push(item);
                }
            }
            #endregion

            replaceTradeItems(newBuyItems, buyingSlots, buyingQuantity, refreshChance);
            replaceTradeItems(newsellItems, sellingSlots, sellingQuantity, refreshChance);

            ITreeAttribute tree = GetOrCreateTradeStore();
            Inventory.ToTreeAttributes(tree);
            WatchedAttributes.MarkAllDirty();
        }
        public override void OnGameTick(float dt)
        {
            base.OnGameTick(dt);
            if (ShouldDespawn)
            {
                return;
            }

            if (OnGround && CanCollect(null))
            {
                Api.World.SpawnItemEntity(ProjectileStack, ServerPos.XYZ);
                Die();
                return;
            }


            EntityPos pos = SidedPos;

            pos.Pitch = World.ElapsedMilliseconds / 250f % GameMath.TWOPI;
            pos.Roll  = World.ElapsedMilliseconds / 250f % GameMath.TWOPI;
            pos.Yaw   = World.ElapsedMilliseconds / 250f % GameMath.TWOPI;

            if (Collided)
            {
                if (!beforeCollided && World is IServerWorldAccessor)
                {
                    float strength = GameMath.Clamp((float)motionBeforeCollide.Length() * 4, 0, 1);

                    if (CollidedHorizontally)
                    {
                        pos.Motion.X = motionBeforeCollide.X * 0.8f;
                        pos.Motion.Z = motionBeforeCollide.Z * 0.8f;
                    }

                    if (CollidedVertically && motionBeforeCollide.Y <= 0)
                    {
                        pos.Motion.Y = GameMath.Clamp(motionBeforeCollide.Y * -0.4f, -0.1f, 0.1f);
                    }

                    World.PlaySoundAt(new AssetLocation("game:sounds/thud"), this, null, false, 32, strength);
                    WatchedAttributes.MarkAllDirty();
                }

                beforeCollided = true;
                return;
            }

            if (World is IServerWorldAccessor && ((ItemCage)ProjectileStack.Item)?.IsEmpty == true)
            {
                Entity entity = World.GetNearestEntity(ServerPos.XYZ, 5f, 5f, (e) =>
                {
                    if (e.EntityId == this.EntityId || (FiredBy != null && e.EntityId == FiredBy.EntityId && World.ElapsedMilliseconds - launchMs < 500) || !e.IsInteractable)
                    {
                        return(false);
                    }

                    double dist = e.CollisionBox.ToDouble().Translate(e.ServerPos.X, e.ServerPos.Y, e.ServerPos.Z).ShortestDistanceFrom(ServerPos.X, ServerPos.Y, ServerPos.Z);
                    return(dist < 0.5f);
                });

                if (entity != null && (entity as EntityPlayer) == null && entity.Alive)
                {
                    bool didDamage = entity.ReceiveDamage(new DamageSource()
                    {
                        Source = EnumDamageSource.Entity, SourceEntity = FiredBy ?? (this), Type = EnumDamageType.BluntAttack
                    }, Damage);
                    World.PlaySoundAt(new AssetLocation("game:sounds/thud"), this, null, false, 32);
                    World.SpawnCubeParticles(entity.SidedPos.XYZ.OffsetCopy(0, 0.2, 0), ProjectileStack, 0.2f, 20);

                    if (FiredBy is EntityPlayer && didDamage)
                    {
                        World.PlaySoundFor(new AssetLocation("game:sounds/player/projectilehit"), (FiredBy as EntityPlayer).Player, false, 24);
                    }

                    if (entity.GetBehavior("health") is EntityBehaviorHealth behavior)
                    {
                        float captureChance = ProjectileStack.Collectible.Attributes["defaultcapturechance"].AsFloat();

                        ItemStack baitStack = ProjectileStack.Attributes.GetItemstack("bait");
                        baitStack?.ResolveBlockOrItem(entity.World);
                        if (baitStack != null && Core.AllBaits.TryGetValue(baitStack.Collectible.Code, out var captureEntities))
                        {
                            foreach (var captureEntity in captureEntities)
                            {
                                if (captureEntity.Code == entity.Code.ToString())
                                {
                                    captureChance = captureEntity.CaptureChance;
                                    break;
                                }
                            }
                        }

                        float efficiency = ProjectileStack.Collectible.Attributes["efficiency"].AsFloat();
                        captureChance += (1 - behavior.Health / behavior.MaxHealth) * efficiency; // -1% hp = (+1% * efficiency) capture chance

                        if (captureChance < random.NextDouble())
                        {
                            float breakChance = ProjectileStack.Collectible.Attributes["breakchance"].AsFloat();
                            if (breakChance >= random.NextDouble())
                            {
                                FiredBy.SendMessage(Lang.Get(ConstantsCore.ModId + ":cage-broken"));
                            }
                            else
                            {
                                FiredBy.SendMessage(Lang.Get(ConstantsCore.ModId + ":cage-mistake"));

                                //Api.World.SpawnItemEntity(ProjectileStack, ServerPos.XYZ);
                                AssetLocation caseCode  = ProjectileStack.Collectible.CodeWithVariant("type", "case");
                                ItemStack     caseStack = new ItemStack(Api.World.GetItem(caseCode));
                                Api.World.SpawnItemEntity(caseStack, ServerPos.XYZ);
                            }
                        }
                        else
                        {
                            AssetLocation location = ProjectileStack.Item?.CodeWithVariant("type", "full");
                            ItemStack     full     = new ItemStack(Api.World.GetItem(location));

                            SaveEntityInAttributes(entity, full, "capture");
                            full.Attributes.SetString("capturename", entity.GetName());

                            Api.World.SpawnItemEntity(full, entity.Pos.XYZ);

                            FiredBy.SendMessage(Lang.Get(ConstantsCore.ModId + ":cage-captured"));
                            entity.Die(EnumDespawnReason.Removed);
                        }

                        Die();
                    }
                }
            }

            beforeCollided = false;
            motionBeforeCollide.Set(pos.Motion.X, pos.Motion.Y, pos.Motion.Z);
        }