コード例 #1
0
    public override void ReceiveUpdate(BSONObject bsonObj)
    {
        bool changed = false;

        if (!bsonObj.ContainsKey("trunks"))
        {
            return;
        }
        BSONArray trunks = bsonObj["trunks"].ArrayValue;

        foreach (BSONObject obj in trunks)
        {
            Guid       id    = obj["id"];
            TrunkPiece piece = this.trunkPieces.FirstOrDefault(p => p.ID == id);

            if (piece != null && (piece.Position != obj["pos"] || piece.Rotation != obj["rot"]))
            {
                piece.Position       = obj["pos"];
                piece.Rotation       = obj["rot"];
                piece.Velocity       = obj["v"];
                piece.LastUpdateTime = TimeUtil.Seconds;
                changed = true;
            }
        }

        if (changed)
        {
            if (this.UpRooted)
            {
                this.Position = this.trunkPieces.First().Position;
            }
            this.lastKeyframeTime = bsonObj["time"];
            this.LastUpdateTime   = TimeUtil.Seconds;
        }
    }
コード例 #2
0
    void FellTree(INetObject killer)
    {
        // create the initial trunk piece
        var trunkPiece = new TrunkPiece()
        {
            ID = Guid.NewGuid(), SliceStart = 0f, SliceEnd = 1f,
        };

        // clear tree occupancy
        if (this.Species.BlockType != null)
        {
            var treeBlockCheck = this.Position.Round + Vector3i.Up;
            while (World.GetBlock(treeBlockCheck).GetType() == this.Species.BlockType)
            {
                World.DeleteBlock(treeBlockCheck);
                treeBlockCheck += Vector3i.Up;
            }
        }

        this.trunkPieces.Add(trunkPiece);

        if (killer is Player)
        {
            this.SetPhysicsController((INetObjectViewer)killer);
            killer.RPC("YellTimber");
            Animal.AlertNearbyAnimals(this.Position, 30);
        }

        this.RPC("FellTree", trunkPiece.ID, this.resourceMultiplier);

        // break off any branches that are young
        for (int branchID = 0; branchID < this.branches.Count(); branchID++)
        {
            var branch = this.branches[branchID];
            if (branch == null)
            {
                continue;
            }

            var branchAge = Mathf.Clamp01((float)((this.GrowthPercent - branch.SpawnAge) / (branch.MatureAge - branch.SpawnAge)));
            if (branchAge <= .5f)
            {
                this.DestroyBranch(branchID);
            }
        }

        if (killer is Player)
        {
            PlantSimEvents.OnTreeFelled.Invoke((killer as Player).DisplayName);
        }

        //Add air pollution (minor)
        WorldLayerManager.ClimateSim.AddAirPollution(new WorldPosition3i(this.Position.XYZi), -this.Species.ReleasesCO2ppmPerDay);

        this.Save();
    }
コード例 #3
0
    private bool TrySliceTrunk(Player player, float slicePoint)
    {
        lock (this) // prevent threading issues due to multiple choppers
        {
            // find the trunk piece this is coming from
            TrunkPiece target = this.trunkPieces.Where(p => p.SliceStart <slicePoint && p.SliceEnd> slicePoint).FirstOrDefault();
            if (target == null)
            {
                return(false);
            }
            else
            {
                // if this is a tiny slice, clamp to the nearest valid size
                const float minPieceResources = 5f;
                float       minPieceSize      = minPieceResources / this.resourceMultiplier;
                float       targetSize        = target.SliceEnd - target.SliceStart;
                float       targetResources   = targetSize * this.resourceMultiplier;
                float       newPieceSize      = target.SliceEnd - slicePoint;
                float       newPieceResources = newPieceSize * this.resourceMultiplier;
                if (targetResources <= minPieceResources)
                {
                    return(false);                             // can't slice, too small
                }
                if (targetResources < (2 * minPieceResources)) // if smaller than 2x the min size, slice directly in half
                {
                    slicePoint = target.SliceStart + (.5f * targetSize);
                }
                else if (newPieceSize < minPieceSize)                       // round down to nearest slice point where the resulting block will be the size of the log
                {
                    slicePoint = target.SliceEnd - minPieceSize;
                }
                else if (slicePoint - target.SliceStart <= minPieceSize)    // round up
                {
                    slicePoint = target.SliceStart + minPieceSize;
                }

                // slice and assign new IDs (New piece is always the back end of the source piece)
                var newPiece = new TrunkPiece()
                {
                    ID         = Guid.NewGuid(),
                    SliceStart = slicePoint,
                    SliceEnd   = target.SliceEnd,
                    Position   = target.Position,
                    Rotation   = target.Rotation,
                };
                this.trunkPieces.Add(newPiece);
                target.SliceEnd = slicePoint;

                // ensure the pieces are listed in order
                this.trunkPieces.Sort((a, b) => a.SliceStart.CompareTo(b.SliceStart));

                // reciprocate to clients
                this.RPC("SliceTrunk", slicePoint, target.ID, newPiece.ID);

                PlantSimEvents.OnLogChopped.Invoke(player.DisplayName);

                this.Save();
                return(true);
            }
        }
    }
コード例 #4
0
 private int GetBasePickupSize(TrunkPiece trunk)
 {
     return(Math.Max((int)Math.Round((trunk.SliceEnd - trunk.SliceStart) * resourceMultiplier), 1));
 }
コード例 #5
0
 private bool CanPickup(TrunkPiece trunk)
 {
     return(this.GetBasePickupSize(trunk) <= maxTrunkPickupSize);
 }