Example #1
0
        public static void MineVegetable(VegeMined packet)
        {
            PlanetData planet = GameMain.galaxy?.PlanetById(packet.PlanetID);

            if (planet == null)
            {
                return;
            }

            if (packet.isVegetable) // Trees, rocks, leaves, etc
            {
                VegeData  vData  = (VegeData)planet.factory?.GetVegeData(packet.MiningID);
                VegeProto vProto = LDB.veges.Select((int)vData.protoId);
                if (vProto != null && planet.id == GameMain.localPlanet?.id)
                {
                    VFEffectEmitter.Emit(vProto.MiningEffect, vData.pos, vData.rot);
                    VFAudio.Create(vProto.MiningAudio, null, vData.pos, true);
                }
                planet.factory?.RemoveVegeWithComponents(vData.id);
            }
            else // veins
            {
                VeinData  vData  = (VeinData)planet.factory?.GetVeinData(packet.MiningID);
                VeinProto vProto = LDB.veins.Select((int)vData.type);
                if (vProto != null)
                {
                    if (planet.factory?.veinPool[packet.MiningID].amount > 0)
                    {
                        VeinData[]             vPool   = planet.factory?.veinPool;
                        PlanetData.VeinGroup[] vGroups = planet.factory?.planet.veinGroups;
                        long[] vAmounts = planet.veinAmounts;
                        vPool[packet.MiningID].amount         -= 1;
                        vGroups[(int)vData.groupIndex].amount -= 1;
                        vAmounts[(int)vData.type]             -= 1;

                        if (planet.id == GameMain.localPlanet?.id)
                        {
                            VFEffectEmitter.Emit(vProto.MiningEffect, vData.pos, Maths.SphericalRotation(vData.pos, 0f));
                            VFAudio.Create(vProto.MiningAudio, null, vData.pos, true);
                        }
                    }
                    else
                    {
                        PlanetData.VeinGroup[] vGroups = planet.factory?.planet.veinGroups;
                        vGroups[vData.groupIndex].count -= 1;

                        if (planet.id == GameMain.localPlanet?.id)
                        {
                            VFEffectEmitter.Emit(vProto.MiningEffect, vData.pos, Maths.SphericalRotation(vData.pos, 0f));
                            VFAudio.Create(vProto.MiningAudio, null, vData.pos, true);
                        }

                        planet.factory?.RemoveVeinWithComponents(vData.id);
                    }
                }
            }
        }
Example #2
0
        public override void ProcessPacket(VegeMinedPacket packet, NebulaConnection conn)
        {
            if (GameMain.galaxy.PlanetById(packet.PlanetId)?.factory != null && GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.vegePool != null)
            {
                using (Multiplayer.Session.Planets.IsIncomingRequest.On())
                {
                    PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;
                    if (packet.Amount == 0 && factory != null)
                    {
                        if (packet.IsVein)
                        {
                            VeinData  veinData  = factory.GetVeinData(packet.VegeId);
                            VeinProto veinProto = LDB.veins.Select((int)veinData.type);

                            factory.RemoveVeinWithComponents(packet.VegeId);

                            if (veinProto != null)
                            {
                                VFEffectEmitter.Emit(veinProto.MiningEffect, veinData.pos, Maths.SphericalRotation(veinData.pos, 0f));
                                VFAudio.Create(veinProto.MiningAudio, null, veinData.pos, true, 0, -1, -1L);
                            }
                        }
                        else
                        {
                            VegeData  vegeData  = factory.GetVegeData(packet.VegeId);
                            VegeProto vegeProto = LDB.veges.Select(vegeData.protoId);

                            factory.RemoveVegeWithComponents(packet.VegeId);

                            if (vegeProto != null)
                            {
                                VFEffectEmitter.Emit(vegeProto.MiningEffect, vegeData.pos, Maths.SphericalRotation(vegeData.pos, 0f));
                                VFAudio.Create(vegeProto.MiningAudio, null, vegeData.pos, true, 0, -1, -1L);
                            }
                        }
                    }
                    else if (factory != null)
                    {
                        VeinData veinData = factory.GetVeinData(packet.VegeId);
                        PlanetData.VeinGroup[] veinGroups = factory.planet.veinGroups;
                        short groupIndex = veinData.groupIndex;

                        // must be a vein/oil patch (i think the game treats them same now as oil patches can run out too)
                        factory.veinPool[packet.VegeId].amount          = packet.Amount;
                        factory.planet.veinAmounts[(int)veinData.type] -= 1L;
                        veinGroups[groupIndex].amount = veinGroups[groupIndex].amount - 1L;
                    }
                    else
                    {
                        Log.Warn("Received VegeMinedPacket but could not do as i was told :C");
                    }
                }
            }
        }
        public static void MechaDroneLogic_UpdateTargets_Prefix(MechaDroneLogic __instance, Player ___player)
        {
            if (___player.factory != null)
            {
                if (GameMain.data.hidePlayerModel)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because player model is hidden.  This is needed for compatability with the Render Distance mod.");
                    }
                    UpdateTipText("(Player hidden.)");
                    return;
                }

                if (!configEnableMod.Value)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because mod is disabled.");
                    }
                    return;
                }

                if (___player.movementState == EMovementState.Sail)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because movement state is Sail.");
                    }
                    UpdateTipText("(Waiting while Sailing.)");
                    RecallClearingDrones();
                    return;
                }

                if (___player.movementState == EMovementState.Drift && !configEnableClearingWhileDrifting)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping while drifting.");
                    }
                    UpdateTipText("(Waiting while Drifting.)");
                    return;
                }

                if (___player.movementState == EMovementState.Fly && !configEnableClearingWhileFlying)
                {
                    if (configEnableRecallWhileFlying)
                    {
                        if (configEnableDebug)
                        {
                            Logger.LogInfo("Recalling drones.");
                        }
                        RecallClearingDrones();
                    }
                    else if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping while flying.");
                    }
                    UpdateTipText("(Waiting while Flying.)");
                    return;
                }

                if (___player.mecha.coreEnergy < ___player.mecha.droneEjectEnergy)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because of insufficient mecha energy to eject a drone.");
                    }
                    UpdateTipText("(Waiting for ejection energy.)");
                    return;
                }

                if ((___player.planetData.type == EPlanetType.None && !configEnableClearingPlanetGeneric) ||
                    (___player.planetData.type == EPlanetType.Vocano && !configEnableClearingPlanetVocano) ||
                    (___player.planetData.type == EPlanetType.Ocean && !configEnableClearingPlanetOcean) ||
                    (___player.planetData.type == EPlanetType.Desert && !configEnableClearingPlanetDesert) ||
                    (___player.planetData.type == EPlanetType.Ice && !configEnableClearingPlanetIce))
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping planet type " + ___player.planetData.type.ToString());
                    }
                    UpdateTipText("(Waiting on this planet type.)");
                    return;
                }

                int totalDroneTaskingCount = getTotalDroneTaskingCount();
                if (totalDroneTaskingCount >= Math.Min(configMaxClearingDroneCount, ___player.mecha.droneCount))
                {
                    if (configEnableDebug)
                    {
                        var sbc = new StringBuilder();
                        sbc.AppendFormat("Skipping due to number of drone assignments: totalDroneTaskingCount={0}, configMaxClearingDroneCount={1}, player.mecha.droneCount={2}, player.mecha.idleDroneCount={3}",
                                         totalDroneTaskingCount, configMaxClearingDroneCount, ___player.mecha.droneCount, ___player.mecha.idleDroneCount);
                        Logger.LogInfo(sbc.ToString());
                    }
                    UpdateTipText("(Available drones assigned.)");
                    return;
                }

                if (___player.mecha.coreEnergy / ___player.mecha.coreEnergyCap < configReservedPower)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping due to low power.");
                    }
                    UpdateTipText("(Waiting for energy.)");
                    return;
                }

                if (configCollectResourcesFlag)  // ... check configReservedInventorySpace
                {
                    uint numEmptyInventorySlots = 0;
                    for (int gridIdx = 0; gridIdx < ___player.package.size; ++gridIdx)
                    {
                        if (___player.package.grids[gridIdx].count == 0)
                        {
                            numEmptyInventorySlots++;
                        }
                    }
                    if (numEmptyInventorySlots < configReservedInventorySpace)
                    {
                        if (configEnableDebug)
                        {
                            Logger.LogInfo("Too few inventory slots");
                        }
                        UpdateTipText("(Waiting for inventory space.)");
                        return;
                    }
                }

                float closestVegeDistance = ___player.mecha.buildArea * configLimitClearingDistance * 2;
                int   closestVegeId       = -1;
                foreach (VegeData vegeData in ___player.factory.vegePool)
                {
                    VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId);
                    // vegeProto.Type == EVegeType.Detail covers grass and small minable rocks.  So the check includes vegeProto.MiningItem.Length instead.
                    if (vegeProto != null && vegeProto.MiningItem.Length > 0)
                    {
                        if ((vegeProto.Type == EVegeType.Tree && !configEnableClearingItemTree) ||
                            (vegeProto.Type == EVegeType.Stone && !configEnableClearingItemStone) ||
                            (vegeProto.Type == EVegeType.Detail && !configEnableClearingItemDetail) ||
                            (vegeProto.Type == EVegeType.Ice && !configEnableClearingItemIce))
                        {
                            continue;
                        }

                        float distanceToVege = Vector3.Distance(___player.position, vegeData.pos);
                        if (distanceToVege < closestVegeDistance)
                        {
                            bool vegeBeingProcessedFlag = false;
                            foreach (PrebuildData prebuild in ___player.factory.prebuildPool)
                            {
                                if (isDroneClearingPrebuild(prebuild) && prebuild.upEntity == vegeData.id)
                                {
                                    vegeBeingProcessedFlag = true;
                                    break;
                                }
                            }

                            if (!vegeBeingProcessedFlag)
                            {
                                closestVegeDistance = distanceToVege;
                                closestVegeId       = vegeData.id;
                            }
                        }
                    }
                }

                if (closestVegeDistance <= ___player.mecha.buildArea * configLimitClearingDistance)
                {
                    VegeData  vegeData  = ___player.factory.vegePool[closestVegeId];
                    VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId);

                    //var sb = new StringBuilder();
                    //sb.AppendFormat("Initiating mining of {0} to get {1} at power level {2}", vegeProto.Type.ToString(), LDB.items.Select(vegeProto.MiningItem[0]).name, ___player.mecha.coreEnergy / ___player.mecha.coreEnergyCap);
                    //Logger.LogInfo(sb.ToString());

                    PrebuildData prebuild = default;
                    prebuild.protoId  = -1;
                    prebuild.modelId  = 0; // Saves always open as 0
                    prebuild.recipeId = -1;
                    prebuild.refCount = 0;
                    prebuild.upEntity = vegeData.id;
                    prebuild.pos      = prebuild.pos2 = vegeData.pos;
                    prebuild.rot      = vegeData.rot;

                    // This operation will cause a drone to be assigned by MechaDroneLogic.UpdateTargets.
                    int prebuildId = ___player.factory.AddPrebuildData(prebuild);
                    UpdateTipText("(Assigning drones.)");
                }
                else
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("No enabled items within configured distance.");
                    }
                    UpdateTipText("(No more items in range.)");
                }
            }
        }
            // This function is based on PlayerAction_Mine.GameTick
            public void DroneGameTick()
            {
                double        powerFactor = 0.01666666753590107;
                PlanetFactory factory     = this.player.factory;

                if (factory == null)
                {
                    // This has only been seen briefly when the Render Distance mod is transitioning to or from a planet view.
                    return;
                }
                double miningEnergyCost = this.player.mecha.miningPower * powerFactor;
                double energyAvailable;
                float  fractionOfEnergyAvailable;

                this.player.mecha.QueryEnergy(miningEnergyCost, out energyAvailable, out fractionOfEnergyAvailable);
                int miningTime = (int)(this.player.mecha.miningSpeed * configSpeedScaleFactor * fractionOfEnergyAvailable * 10000f + 0.49f);

                VegeData vegeData = factory.GetVegeData(this.miningId);

                this.miningProtoId = (int)vegeData.protoId;
                VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId);

                if (vegeProto != null)
                {
                    this.miningTick += miningTime;
                    this.player.mecha.coreEnergy -= energyAvailable;
                    this.player.mecha.MarkEnergyChange(5, -miningEnergyCost);
                    this.percent = Mathf.Clamp01((float)((double)this.miningTick / (double)(vegeProto.MiningTime * 10000)));
                    if (this.miningTick >= vegeProto.MiningTime * 10000)
                    {
                        System.Random random = new System.Random(vegeData.id + ((this.player.planetData.seed & 16383) << 14));
                        bool          inventoryOverflowFlag = false;
                        int           popupQueueIndex       = 0;
                        for (int itemIdx = 0; itemIdx < vegeProto.MiningItem.Length; itemIdx++)
                        {
                            float randomMiningChance = (float)random.NextDouble();
                            if (randomMiningChance < vegeProto.MiningChance[itemIdx])
                            {
                                int minedItem      = vegeProto.MiningItem[itemIdx];
                                int minedItemCount = (int)((float)vegeProto.MiningCount[itemIdx] * (vegeData.scl.y * vegeData.scl.y) + 0.5f);
                                if (minedItemCount > 0 && LDB.items.Select(minedItem) != null)
                                {
                                    int inventoryOverflowCount = this.player.package.AddItemStacked(minedItem, minedItemCount);
                                    if (inventoryOverflowCount != 0)
                                    {
                                        UIItemup.Up(minedItem, inventoryOverflowCount);
                                        UIRealtimeTip.PopupItemGet(minedItem, inventoryOverflowCount, vegeData.pos + vegeData.pos.normalized, popupQueueIndex++);
                                    }
                                    else  // Unable to fit all items
                                    {
                                        inventoryOverflowFlag = true;
                                    }
                                }
                            }
                        }
                        VFEffectEmitter.Emit(vegeProto.MiningEffect, vegeData.pos, vegeData.rot);
                        VFAudio.Create(vegeProto.MiningAudio, null, vegeData.pos, true);
                        factory.RemoveVegeWithComponents(vegeData.id);
                        GameMain.gameScenario.NotifyOnVegetableMined((int)vegeData.protoId);
                        this.miningType = EObjectType.Entity;  // This change will cause the mission to be completed.
                        this.miningId   = 0;
                        if (inventoryOverflowFlag)
                        {
                            //Logger.LogInfo("Inventory overflow detected.");
                        }
                        this.miningTick = 0;
                    }
                }
                else
                {
                    //Logger.LogInfo("null vegeProto.  Icarus likely removed clearing target.");
                    this.miningType = EObjectType.Entity;  // This change will cause the mission to be completed.
                    this.miningId   = 0;
                    this.miningTick = 0;
                    this.percent    = 0f;
                    factory.RemoveVegeWithComponents(vegeData.id);
                }
            }
Example #5
0
        // collision with vegetation, landing sound effect
        private void UpdateExtraSoundEffects(PlayerAnimationUpdate packet)
        {
            if (localPlanetId < 0)
            {
                return;
            }

            if (localPlanetId > 0)
            {
                PlanetData    pData          = GameMain.galaxy.PlanetById(localPlanetId);
                PlanetPhysics pPhys          = (pData != null) ? pData.physics : null;
                PlanetFactory pFactory       = (pData != null) ? pData.factory : null;
                float         tmpMaxAltitude = rootTransform.localPosition.magnitude - pData.realRadius;
                if (tmpMaxAltitude > 1000f)
                {
                    tmpMaxAltitude = 1000f;
                }

                if (rootAnimation.RunSlow.enabled || rootAnimation.RunFast.enabled || rootAnimation.Drift.enabled || rootAnimation.DriftF.enabled || rootAnimation.DriftR.enabled || rootAnimation.DriftL.enabled)
                {
                    bool ground = IsGrounded();

                    if (DriftDetermineInWater(pData))
                    {
                        if (maxAltitude > 1f && pData.waterItemId > 0)
                        {
                            VFAudio audio = VFAudio.Create("landing-water", base.transform, Vector3.zero, false, 0);
                            audio.volumeMultiplier = Mathf.Clamp01(maxAltitude / 5f + 0.5f);
                            audio.Play();
                            PlayFootstepEffect(true, 0f, true);
                            PlayFootstepEffect(false, 0f, true);
                        }
                        maxAltitude = 0f;
                    }
                    if (ground && maxAltitude > 3f)
                    {
                        VFAudio audio = VFAudio.Create("landing", base.transform, Vector3.zero, false, 0);
                        audio.volumeMultiplier = Mathf.Clamp01(maxAltitude / 25f + 0.5f);
                        audio.Play();
                        maxAltitude = 0f;
                    }
                    if (!ground && tmpMaxAltitude > maxAltitude)
                    {
                        maxAltitude = tmpMaxAltitude;
                    }
                }
                else
                {
                    maxAltitude = 15f;
                }

                // NOTE: the pPhys can only be loaded if the player trying to load it has the planet actually loaded (meaning he is on the same planet or near it)
                if (pPhys != null && pFactory != null && packet.horzSpeed > 5f)
                {
                    int number = Physics.OverlapSphereNonAlloc(base.transform.localPosition, 1.8f, collider, 1024, QueryTriggerInteraction.Collide);
                    for (int i = 0; i < number; i++)
                    {
                        int          colId = pPhys.nearColliderLogic.FindColliderId(collider[i]);
                        ColliderData cData = pPhys.GetColliderData(colId);
                        if (cData.objType == EObjectType.Vegetable && cData.objId > 0)
                        {
                            VegeData  vData  = pFactory.vegePool[cData.objId];
                            VegeProto vProto = LDB.veges.Select((int)vData.protoId);
                            if (vProto != null && vProto.CollideAudio > 0 && vegeCollideColdTime <= 0)
                            {
                                VFAudio.Create(vProto.CollideAudio, base.transform, Vector3.zero, true, 0);
                                vegeCollideColdTime = UnityEngine.Random.value * 0.23f + 0.1f;
                            }
                        }
                    }
                }
            }

            if (vegeCollideColdTime > 0)
            {
                vegeCollideColdTime -= Time.deltaTime * 2;
            }
            else
            {
                vegeCollideColdTime = 0;
            }
        }