Ejemplo n.º 1
0
    public void CmdThrow(EquipSlot equipSlot, Vector3 worldTargetPos, int aim)
    {
        var inventorySlot = Inventory[equipSlot];

        if (playerScript.canNotInteract() || equipSlot != EquipSlot.leftHand && equipSlot != EquipSlot.rightHand ||
            !SlotNotEmpty(equipSlot))
        {
            return;
        }

        GameObject throwable = inventorySlot.Item;
        Vector3    playerPos = playerScript.PlayerSync.ServerState.WorldPosition;

        InventoryManager.ClearInvSlot(inventorySlot);

        var throwInfo = new ThrowInfo
        {
            ThrownBy  = gameObject,
            Aim       = (BodyPartType)aim,
            OriginPos = playerPos,
            TargetPos = worldTargetPos,
            //Clockwise spin from left hand and Counterclockwise from the right hand
            SpinMode = equipSlot == EquipSlot.leftHand ? SpinMode.Clockwise : SpinMode.CounterClockwise,
        };

        throwable.GetComponent <CustomNetTransform>().Throw(throwInfo);

        //Simplified counter-impulse for players in space
        if (playerScript.PlayerSync.IsWeightlessServer)
        {
            playerScript.PlayerSync.Push(Vector2Int.RoundToInt(-throwInfo.Trajectory.normalized));
        }
    }
    /// <summary>
    /// Hit for thrown (non-tile-snapped) items
    /// </summary>
    private void OnHit(Vector3Int pos, ThrowInfo info, IReadOnlyCollection <LivingHealthMasterBase> hitCreatures)
    {
        if (ItemAttributes == null)
        {
            return;
        }
        if (hitCreatures == null || hitCreatures.Count <= 0)
        {
            return;
        }

        foreach (var creature in hitCreatures)
        {
            if (creature.gameObject == info.ThrownBy)
            {
                continue;
            }
            //Remove cast to int when moving health values to float
            var damage  = (int)(ItemAttributes.ServerThrowDamage);
            var hitZone = info.Aim.Randomize();
            creature.ApplyDamageToBodyPart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone);
            Chat.AddThrowHitMsgToChat(gameObject, creature.gameObject, hitZone);
            AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: 1f);
            SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.GenericHit, transform.position, audioSourceParameters, sourceObj: gameObject);
        }
    }
Ejemplo n.º 3
0
    protected virtual void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects, List <TilemapDamage> tiles)
    {
        if (!ItemAttributes)
        {
            Logger.LogWarningFormat("{0}: Tried to hit stuff at pos {1} but have no ItemAttributes.", Category.Throwing, gameObject.name, pos);
            return;
        }
        //Hurting tiles
        for (var i = 0; i < tiles.Count; i++)
        {
            var tileDmg = tiles[i];
            var damage  = ( int )(ItemAttributes.throwDamage * 2);
            tileDmg.DoThrowDamage(pos, info, damage);
        }

        //Hurting objects
        if (objects != null && objects.Count > 0 && !Equals(info, ThrowInfo.NoThrow))
        {
            for (var i = 0; i < objects.Count; i++)
            {
                //Remove cast to int when moving health values to float
                var damage  = (int)(ItemAttributes.throwDamage * 2);
                var hitZone = info.Aim.Randomize();
                objects[i].ApplyDamage(info.ThrownBy, damage, DamageType.Brute, hitZone);
                PostToChatMessage.SendThrowHitMessage(gameObject, objects[i].gameObject, damage, hitZone);
            }
            //hit sound
            PlaySoundMessage.SendToAll("GenericHit", transform.position, 1f);
        }
        else
        {
            //todo different sound for no-damage hit?
            PlaySoundMessage.SendToAll("GenericHit", transform.position, 0.8f);
        }
    }
    /// <summary>
    /// Hit for thrown (non-tile-snapped) items
    /// </summary>
    protected virtual void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects, List <TilemapDamage> tiles)
    {
        if (ItemAttributes == null)
        {
            Logger.LogWarningFormat("{0}: Tried to hit stuff at pos {1} but have no ItemAttributes.", Category.Throwing, gameObject.name, pos);
            return;
        }
        //Hurting tiles
        for (var i = 0; i < tiles.Count; i++)
        {
            var tileDmg = tiles[i];
            var damage  = (int)(ItemAttributes.ServerThrowDamage * 2);
            tileDmg.DoThrowDamage(pos, info, damage);
        }

        //Hurting objects
        if (objects != null && objects.Count > 0)
        {
            for (var i = 0; i < objects.Count; i++)
            {
                //Remove cast to int when moving health values to float
                var damage  = (int)(ItemAttributes.ServerThrowDamage * 2);
                var hitZone = info.Aim.Randomize();
                objects[i].ApplyDamageToBodypart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone);
                Chat.AddThrowHitMsgToChat(gameObject, objects[i].gameObject, hitZone);
            }
            //hit sound
            SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 1f);
        }
        else
        {
            //todo different sound for no-damage hit?
            SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 0.8f);
        }
    }
Ejemplo n.º 5
0
    public void CmdRequestThrow(string slot, Vector3 worldTargetPos, int aim)
    {
        if (playerScript.canNotInteract() || slot != "leftHand" && slot != "rightHand" || !SlotNotEmpty(slot))
        {
            RollbackPrediction(slot);
            return;
        }
        GameObject throwable = Inventory[slot];

        Vector3 playerPos = playerScript.playerSync.ServerState.WorldPosition;

        EquipmentPool.DisposeOfObject(gameObject, throwable);
        ClearInventorySlot(slot);
        var throwInfo = new ThrowInfo {
            ThrownBy  = gameObject,
            Aim       = (BodyPartType)aim,
            OriginPos = playerPos,
            TargetPos = worldTargetPos,
            //Clockwise spin from left hand and Counterclockwise from the right hand
            SpinMode = slot == "leftHand" ? SpinMode.Clockwise : SpinMode.CounterClockwise,
        };

        throwable.GetComponent <CustomNetTransform>().Throw(throwInfo);

        //Simplified counter-impulse for players in space
        if (playerScript.playerSync.IsInSpace)
        {
            playerScript.playerSync.Push(Vector2Int.RoundToInt(-throwInfo.Trajectory.normalized));
        }
    }
Ejemplo n.º 6
0
        public override IEnumerable <ThrowInfo> Throw(FlowController flow, FlowOutputSet outSet, ThrowStmt throwStmt, MemoryEntry throwedValue)
        {
            //TODO this is only simple implementation
            var exceptionObj = (ObjectValue)throwedValue.PossibleValues.First();

            var catchBlocks = outSet.ReadControlVariable(CatchBlocks_Storage).ReadMemory(outSet.Snapshot);

            var throwBranches = new List <ThrowInfo>();

            //find catch blocks with valid scope and matching catch condition
            foreach (InfoValue <CatchBlockDescription> blockInfo in catchBlocks.PossibleValues)
            {
                var throwedType = outSet.ObjectType(exceptionObj).QualifiedName;

                //check catch condition
                if (blockInfo.Data.CatchedType.QualifiedName != throwedType)
                {
                    continue;
                }

                var branch = new ThrowInfo(blockInfo.Data, throwedValue);
                throwBranches.Add(branch);
            }

            return(throwBranches);
        }
Ejemplo n.º 7
0
        public override MemoryEntry Exit(ExitEx exit, MemoryEntry status)
        {
            var end = new ThrowInfo(new CatchBlockDescription(Flow.ProgramEnd, new GenericQualifiedName(), null), status);

            Flow.SetThrowBranching(new[] { end }, true);
            // Exit expression never returns, but it is still expression so it must return something
            return(new MemoryEntry(OutSet.AnyValue));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Updates throw information stored in current point
        /// </summary>
        /// <param name="info">Throw information that has to be compatilbe with current point</param>
        internal void ReThrow(ThrowInfo info)
        {
            if (!CatchDescription.Equals(info.Catch))
            {
                throw new NotSupportedException("Cannot rethrow with given info");
            }

            _info = info;
        }
Ejemplo n.º 9
0
        void Game_onThrowSuccess(ThrowInfo info)
        {
            StopUpdateLoop();

            if (_timeNextThrow < TimeEndFight)
            {
                _scoreInFight += info.score;
            }
        }
Ejemplo n.º 10
0
        private void ThrowStart(ThrowInfo throwInfo)
        {
            if (throwInfo.ThrownBy.GetComponent <NetworkIdentity>() == null)
            {
                return;
            }

            Chat.AddActionMsgToChat(throwInfo.ThrownBy, $"You throw the {dieName}...", $"{throwInfo.ThrownBy.ExpensiveName()} throws the {dieName}...");
        }
Ejemplo n.º 11
0
 private void OnThrown(ThrowInfo info)
 {
     if (DMMath.Prob(chanceToBreak))
     {
         Spawn.ServerPrefab(brokenItem, gameObject.AssumedWorldPosServer());
         SoundManager.PlayNetworkedAtPos(useCustomSound ? customSound : SingletonSOSounds.Instance.GlassBreak01, gameObject.AssumedWorldPosServer());
         Despawn.ServerSingle(gameObject);
     }
 }
Ejemplo n.º 12
0
        private void fatalError(FlowController flow, bool removeFlowChildren)
        {
            var catchedType   = new GenericQualifiedName(new QualifiedName(new Name(string.Empty)));
            var catchVariable = new VariableIdentifier(string.Empty);
            var description   = new CatchBlockDescription(flow.ProgramEnd, catchedType, catchVariable);
            var info          = new ThrowInfo(description, new MemoryEntry());

            var throws = new ThrowInfo[] { info };

            flow.SetThrowBranching(throws, removeFlowChildren);
        }
Ejemplo n.º 13
0
        private void OnKnifeThrowSuccess(ThrowInfo info)
        {
            for (int i = 0; i < m_behaviours.Length; i++)
            {
                m_behaviours[i].PostKnifeThrowSuccess(this, info);
            }

            if (knifeThrowSuccess != null)
            {
                knifeThrowSuccess(info);
            }
        }
        private void ThrowItem(CustomNetTransform cnt, Vector3 throwVector)
        {
            Vector3   vector    = cnt.transform.rotation * throwVector;
            ThrowInfo throwInfo = new ThrowInfo
            {
                ThrownBy        = gameObject,
                Aim             = (BodyPartType)Random.Range(0, 13),
                OriginWorldPos  = ContainerWorldPosition,
                WorldTrajectory = vector,
                SpinMode        = DMMath.Prob(50) ? SpinMode.Clockwise : SpinMode.CounterClockwise
            };

            cnt.Throw(throwInfo);
        }
Ejemplo n.º 15
0
    void HandleCoinCleanup(CoinInfo InCoinInfo)
    {
        ThrowInfo TossResults = new ThrowInfo();

        if (InCoinInfo.OurRoll && InCoinInfo.OurResizer)
        {
            TossResults.result       = InCoinInfo.OurRoll.GetRollstate();
            TossResults.radius       = InCoinInfo.OurResizer.GetRadius();
            TossResults.depth        = InCoinInfo.OurResizer.GetDepth();
            TossResults.hasValidData = true;
            switch (TossResults.result)
            {
            case RollState.Edge:
                NumEdge++;
                break;

            case RollState.Heads:
                NumHeads++;
                break;

            case RollState.Tails:
                NumTails++;
                break;
            }
        }
        else
        {
            if (!InCoinInfo.OurRoll)
            {
                Debug.LogError("Invalid Current Roll Component.");
            }
            if (!InCoinInfo.OurResizer)
            {
                Debug.LogError("Invalid Current Resizer Component.");
            }
        }
        if (TossResults.hasValidData)
        {
            Tosses.Add(TossResults);
        }
        else
        {
            Debug.LogError("Invalid Toss Data.");
        }
        if (InCoinInfo.OurCoin)
        {
            Destroy(InCoinInfo.OurCoin);
            CoinsInfo.Remove(InCoinInfo);
        }
    }
Ejemplo n.º 16
0
		private void ThrowItem(ObjectBehaviour item, Vector3 throwVector)
		{
			Vector3 vector = item.transform.rotation * throwVector;
			var spin = RandomSpin();
			ThrowInfo throwInfo = new ThrowInfo
			{
				ThrownBy = gameObject,
				Aim = BodyPartType.Chest,
				OriginWorldPos = transform.position,
				WorldTrajectory = vector,
				SpinMode = spin
			};

			CustomNetTransform itemTransform = item.GetComponent<CustomNetTransform>();
			if (itemTransform == null) return;
			itemTransform.Throw(throwInfo);
		}
Ejemplo n.º 17
0
    public void Shot(ThrowInfo [] throwInfos)
    {
        m_throwedDice = throwInfos;
        if(m_throwedDice == null)
        {
            Debug.LogError("if(m_throwedDice == null)");
            return;
        }

        m_buttonShot.gameObject.SetActive (false);
        m_number.text = "";

        foreach(var x in m_throwedDice)
        {
            x.Reset();
            x.Shot(StopedDice);
        }
    }
Ejemplo n.º 18
0
    private void DamageTiles(Vector3Int pos, ThrowInfo info, List <TilemapDamage> tiles)
    {
        if (ItemAttributes == null)
        {
            return;
        }
        if (tiles == null || tiles.Count <= 0)
        {
            return;
        }

        //Hurting tiles
        foreach (var tileDmg in tiles)
        {
            var damage = (int)(ItemAttributes.ServerThrowDamage);
            tileDmg.DoThrowDamage(pos, info, damage);
        }
    }
Ejemplo n.º 19
0
        private static void FinishThrow(ThrowInfo info)
        {
            Mobile from = info.From;
            Mobile to   = info.To;
            int    min  = info.DamageMin;
            int    max  = info.DamageMax;
            bool   b    = info.Break;
            Item   item = info.Item;

            to.Damage(Utility.RandomMinMax(min, max), from);

            if (b)
            {
                int count = Utility.RandomMinMax(1, 4);

                for (int i = 0; i < count; ++i)
                {
                    Point3D p = new Point3D(to.Location);

                    p.X += Utility.RandomMinMax(-1, 1);
                    p.Y += Utility.RandomMinMax(-1, 1);

                    if (!from.Map.CanFit(p.X, p.Y, p.Z, 16, false, true))
                    {
                        p.Z = from.Map.GetAverageZ(p.X, p.X);

                        if (p.Z == to.Z || !from.Map.CanFit(p.X, p.Y, p.Z, 16, false, true))
                        {
                            continue;
                        }
                    }

                    StoolLeg leg = new StoolLeg();
                    leg.MoveToWorld(p, from.Map);
                }
            }

            if (item != null)
            {
                item.MoveToWorld(to.Location, to.Map);
            }
        }
        void ThrowItem(ObjectBehaviour item, Vector3 throwVector)
        {
            Vector3   vector    = item.transform.rotation * throwVector;
            ThrowInfo throwInfo = new ThrowInfo
            {
                ThrownBy        = Matrix.transform.parent.gameObject,
                Aim             = BodyPartType.Chest,
                OriginWorldPos  = ContainerWorldPosition,
                WorldTrajectory = vector,
                SpinMode        = SpinMode.Clockwise          // TODO: randomise this
            };

            CustomNetTransform itemTransform = item.GetComponent <CustomNetTransform>();

            if (itemTransform == null)
            {
                return;
            }
            itemTransform.Throw(throwInfo);
        }
Ejemplo n.º 21
0
    public void Throw(ThrowInfo info)
    {
        OnThrowStart.Invoke(info);

        SetPosition(info.OriginWorldPos, false);

        float throwSpeed = ItemAttributes.ThrowSpeed * 10;         //tiles per second
        float throwRange = ItemAttributes.ThrowRange;

        Vector2 worldImpulse = info.WorldTrajectory.normalized;

        var correctedInfo = info;

        //limit throw range here
        if (info.WorldTrajectory.magnitude > throwRange)
        {
            correctedInfo.WorldTrajectory = Vector3.ClampMagnitude(info.WorldTrajectory, throwRange);
            //			Logger.Log( $"Throw distance clamped to {correctedInfo.Trajectory.magnitude}, " +
            //			           $"target changed {info.TargetPos}->{correctedInfo.TargetPos}" );
        }

        //add player momentum
        float playerMomentum = 0f;
        //If throwing nearby, do so at 1/2 speed (looks clunky otherwise)
        float speedMultiplier = Mathf.Clamp(correctedInfo.WorldTrajectory.magnitude / (throwRange <= 0 ? 1 : throwRange), 0.6f, 1f);

        serverState.Speed          = (Random.Range(-0.2f, 0.2f) + throwSpeed + playerMomentum) * speedMultiplier;
        correctedInfo.InitialSpeed = serverState.Speed;

        serverState.WorldImpulse = worldImpulse;
        if (info.SpinMode != SpinMode.None)
        {
            serverState.SpinFactor = (sbyte)(Mathf.Clamp(throwSpeed * (2f / (int)ItemAttributes.Size + 1), sbyte.MinValue, sbyte.MaxValue) *
                                             (info.SpinMode == SpinMode.Clockwise ? 1 : -1));
        }
        serverState.ActiveThrow = correctedInfo;
        //		Logger.Log( $"Throw:{correctedInfo} {serverState}" );
        NotifyPlayers();
    }
Ejemplo n.º 22
0
    /// <summary>
    /// Hit for thrown (non-tile-snapped) items
    /// </summary>
    private void OnHit(Vector3Int pos, ThrowInfo info, IReadOnlyCollection <LivingHealthBehaviour> hitCreatures)
    {
        if (ItemAttributes == null)
        {
            return;
        }
        if (hitCreatures == null || hitCreatures.Count <= 0)
        {
            return;
        }

        foreach (var creature in hitCreatures)
        {
            //Remove cast to int when moving health values to float
            var damage  = (int)(ItemAttributes.ServerThrowDamage);
            var hitZone = info.Aim.Randomize();
            creature.ApplyDamageToBodypart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone);
            Chat.AddThrowHitMsgToChat(gameObject, creature.gameObject, hitZone);
        }

        SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 1f, sourceObj: gameObject);
    }
Ejemplo n.º 23
0
        public void Process()
        {
            float Damagedealt    = AngleAndIntensity.magnitude;
            float EnergyExpended = 0;
            var   v3int          = new Vector3Int(Location.x, Location.y, 0);

            var metaTileMap = matrix.MetaTileMap;

            if (Damagedealt <= 0)
            {
                return;
            }

            if (metaTileMap == null)
            {
                return;
            }

            EnergyExpended = metaTileMap.ApplyDamage(v3int, Damagedealt,
                                                     MatrixManager.LocalToWorldInt(v3int, matrix.MatrixInfo), AttackType.Bomb);

            if (Damagedealt > 100)
            {
                var Node = matrix.GetMetaDataNode(v3int);
                if (Node != null)
                {
                    foreach (var electricalData in Node.ElectricalData)
                    {
                        electricalData.InData.DestroyThisPlease();
                    }

                    SavedPipes.Clear();
                    SavedPipes.AddRange(Node.PipeData);
                    foreach (var Pipe in SavedPipes)
                    {
                        Pipe.pipeData.DestroyThis();
                    }
                }
            }


            foreach (var integrity in matrix.Get <Integrity>(v3int, true))
            {
                //Throw items
                if (integrity.GetComponent <ItemAttributesV2>() != null)
                {
                    ThrowInfo throwInfo = new ThrowInfo
                    {
                        //the thrown object is itself for now, in case ThrownBy breaks if null
                        ThrownBy        = integrity.gameObject,
                        Aim             = BodyPartType.Chest,
                        OriginWorldPos  = integrity.RegisterTile.WorldPosition,
                        WorldTrajectory = AngleAndIntensity.Rotate90(),
                        SpinMode        = RandomUtils.RandomSpin()
                    };

                    integrity.GetComponent <CustomNetTransform>().Throw(throwInfo);
                }

                //And do damage to objects
                integrity.ApplyDamage(Damagedealt, AttackType.Bomb, DamageType.Brute);
            }

            foreach (var player in matrix.Get <ObjectBehaviour>(v3int, ObjectType.Player, true))
            {
                // do damage
                player.GetComponent <PlayerHealthV2>().ApplyDamageAll(null, Damagedealt, AttackType.Bomb, DamageType.Brute);
            }

            foreach (var line in PresentLines)
            {
                line.ExplosionStrength -= EnergyExpended * (line.ExplosionStrength / Damagedealt);
            }
            AngleAndIntensity = Vector2.zero;
        }
Ejemplo n.º 24
0
		private static void FinishThrow( ThrowInfo info )
		{
			Mobile from = info.From;
			Mobile to = info.To;
			int min = info.DamageMin;
			int max = info.DamageMax;
			bool b = info.Break;
			Item item = info.Item;

			to.Damage( Utility.RandomMinMax( min, max ), from );

			if ( b )
			{
				int count = Utility.RandomMinMax( 1, 4 );

				for ( int i = 0; i < count; ++i )
				{
					Point3D p = new Point3D( to.Location );

					p.X += Utility.RandomMinMax(-1, 1);
					p.Y += Utility.RandomMinMax(-1, 1);

					if ( !from.Map.CanFit( p.X, p.Y, p.Z, 16, false, true ) )
					{
						p.Z = from.Map.GetAverageZ( p.X, p.X );

						if ( p.Z == to.Z || !from.Map.CanFit( p.X, p.Y, p.Z, 16, false, true ) )
							continue;
					}

					StoolLeg leg = new StoolLeg();
					leg.MoveToWorld( p, from.Map );
				}
			}

			if ( item != null )
				item.MoveToWorld( to.Location, to.Map );
		}
Ejemplo n.º 25
0
 public bool Equals(ThrowInfo other)
 {
     return(OriginWorldPos.Equals(other.OriginWorldPos) && WorldTrajectory.Equals(other.WorldTrajectory));
 }
Ejemplo n.º 26
0
 private void ThrowEnd(ThrowInfo throwInfo)
 {
     this.RestartCoroutine(WaitForSide(), ref waitForSide);
 }
Ejemplo n.º 27
0
 private void ThrowStart(ThrowInfo throwInfo)
 {
     Chat.AddActionMsgToChat(throwInfo.ThrownBy, $"You throw the {dieName}...", $"{throwInfo.ThrownBy} throws the {dieName}...");
 }
Ejemplo n.º 28
0
 protected override void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects,
                               List <TilemapDamage> tiles)
 {
     //base.OnHit( pos, info, objects, tiles );
     //umm todo
 }
Ejemplo n.º 29
0
 public void DoThrowDamage(Vector3Int worldTargetPos, ThrowInfo throwInfo, int dmgAmt)
 {
     DoMeleeDamage(new Vector2(worldTargetPos.x, worldTargetPos.y), throwInfo.ThrownBy, dmgAmt);
 }
Ejemplo n.º 30
0
    private static bool ServerPerformRemove(InventoryMove toPerform, Pickupable pickupable)
    {
        if (pickupable.ItemSlot == null)
        {
            Logger.LogTraceFormat("Attempted to remove {0} from inventory but item is not in a slot." +
                                  " remove will not be performed.", Category.Inventory, pickupable.name);
            return(false);
        }

        var fromSlot = toPerform.FromSlot;

        if (fromSlot == null)
        {
            Logger.LogTraceFormat("Attempted to remove {0} from inventory but from slot was null." +
                                  " Move will not be performed.", Category.Inventory, pickupable.name);
            return(false);
        }

        if (fromSlot.Item == null)
        {
            Logger.LogTraceFormat("Attempted to remove {0} from inventory but from slot {1} had no item in it." +
                                  " Move will not be performed.", Category.Inventory, pickupable.name, fromSlot);
            return(false);
        }

        //update pickupable's item and slot's item
        pickupable._SetItemSlot(null);
        fromSlot._ServerRemoveItem();

        //decide how it should be removed
        var removeType      = toPerform.RemoveType;
        var holder          = fromSlot.GetRootStorageOrPlayer();
        var holderPushPull  = holder?.GetComponent <PushPull>();
        var parentContainer = holderPushPull == null ? null : holderPushPull.parentContainer;

        if (parentContainer != null && removeType == InventoryRemoveType.Throw)
        {
            Logger.LogTraceFormat("throwing from slot {0} while in container {1}. Will drop instead.", Category.Inventory,
                                  fromSlot,
                                  parentContainer.name);
            removeType = InventoryRemoveType.Drop;
        }

        if (removeType == InventoryRemoveType.Despawn)
        {
            // destroy (safe to skip invnetory despawn check because we already performed necessary inventory logic)
            _ = Despawn.ServerSingle(pickupable.gameObject, true);
        }
        else if (removeType == InventoryRemoveType.Drop)
        {
            // drop where it is
            // determine where it will appear
            if (parentContainer != null)
            {
                // TODO: Not a big fan of this bespoke logic for dealing with dropping in closet control. Try to refactor this
                Logger.LogTraceFormat("Dropping from slot {0} while in container {1}", Category.Inventory,
                                      fromSlot,
                                      parentContainer.name);
                var closetControl = parentContainer.GetComponent <ClosetControl>();
                if (closetControl == null)
                {
                    Logger.LogWarningFormat("Dropping from slot {0} while in container {1}, but container type was not recognized. " +
                                            "Currently only ClosetControl is supported. Please add code to handle this case.", Category.Inventory,
                                            fromSlot,
                                            holderPushPull.parentContainer.name);
                    return(false);
                }
                //vanish it and set its parent container
                ServerVanish(fromSlot);
                var objBehavior = pickupable.GetComponent <ObjectBehaviour>();
                if (objBehavior == null)
                {
                    Logger.LogTraceFormat("Dropping object {0} while in container {1}, but dropped object had" +
                                          " no object behavior. Cannot drop.", Category.Inventory,
                                          pickupable,
                                          holderPushPull.parentContainer.name);
                    return(false);
                }
                closetControl.ServerAddInternalItem(objBehavior);

                return(true);
            }

            var     holderPlayer   = holder?.GetComponent <PlayerSync>();
            var     cnt            = pickupable.GetComponent <CustomNetTransform>();
            var     holderPosition = holder?.gameObject.AssumedWorldPosServer();
            Vector3 targetWorldPos = holderPosition.GetValueOrDefault(Vector3.zero) + (Vector3)toPerform.WorldTargetVector.GetValueOrDefault(Vector2.zero);
            if (holderPlayer != null)
            {
                // dropping from player
                // Inertia drop works only if player has external impulse (space floating etc.)
                cnt.InertiaDrop(targetWorldPos, holderPlayer.SpeedServer,
                                holderPlayer.ServerImpulse);
            }
            else
            {
                // dropping from not-held storage
                cnt.AppearAtPositionServer(targetWorldPos);
            }
        }
        else if (removeType == InventoryRemoveType.Throw)
        {
            // throw / eject
            // determine where it will be thrown from
            var cnt = pickupable.GetComponent <CustomNetTransform>();
            var assumedWorldPosServer = holder.gameObject.AssumedWorldPosServer();
            var throwInfo             = new ThrowInfo
            {
                ThrownBy        = holder.gameObject,
                Aim             = toPerform.ThrowAim.GetValueOrDefault(BodyPartType.Chest),
                OriginWorldPos  = assumedWorldPosServer,
                WorldTrajectory = toPerform.WorldTargetVector.GetValueOrDefault(Vector2.zero),
                SpinMode        = toPerform.ThrowSpinMode.GetValueOrDefault(SpinMode.Clockwise)
            };
            // dropping from player
            // Inertia drop works only if player has external impulse (space floating etc.)
            cnt.Throw(throwInfo);

            // Counter-impulse for players in space
            holderPushPull.Pushable.NewtonianMove((-throwInfo.WorldTrajectory).NormalizeTo2Int(), speed: (int)cnt.Size + 1);
        }
        // NOTE: vanish doesn't require any extra logic. The item is already at hiddenpos and has
        // already been removed from the inventory system.

        foreach (var onMove in pickupable.GetComponents <IServerInventoryMove>())
        {
            onMove.OnInventoryMoveServer(toPerform);
        }

        return(true);
    }
Ejemplo n.º 31
0
 public bool Equals(ThrowInfo other)
 {
     return(OriginPos.Equals(other.OriginPos) && TargetPos.Equals(other.TargetPos));
 }
Ejemplo n.º 32
0
 public virtual void PostKnifeThrowSuccess(ILocalGame game, ThrowInfo info)
 {
 }