Esempio n. 1
0
        private void Update()
        {
            gameStateUpdateTimer            += Time.deltaTime;
            gameResearchHashUpdateTimer     += Time.deltaTime;
            productionStatisticsUpdateTimer += Time.deltaTime;

            if (gameStateUpdateTimer > GAME_STATE_UPDATE_INTERVAL)
            {
                gameStateUpdateTimer = 0;
                SendPacket(new GameStateUpdate()
                {
                    State = new GameState(TimeUtils.CurrentUnixTimestampMilliseconds(), GameMain.gameTick)
                });
            }

            if (gameResearchHashUpdateTimer > GAME_RESEARCH_UPDATE_INTERVAL)
            {
                gameResearchHashUpdateTimer = 0;
                if (GameMain.data.history.currentTech != 0)
                {
                    TechState state = GameMain.data.history.techStates[GameMain.data.history.currentTech];
                    SendPacket(new GameHistoryResearchUpdatePacket(GameMain.data.history.currentTech, state.hashUploaded));
                }
            }

            if (productionStatisticsUpdateTimer > STATISTICS_UPDATE_INTERVAL)
            {
                productionStatisticsUpdateTimer = 0;
                StatisticsManager.SendBroadcastIfNeeded();
            }

            PacketProcessor.ProcessPacketQueue();
        }
Esempio n. 2
0
    void Initializing()
    {
        TechTreeList      = new List <TechState>();
        FacilityList      = new List <TechRecipe.FacilityInfo>();
        ActorList         = new List <TechRecipe.ProcessActorInfo>();
        ResearchStateList = new List <ResearchState>();

        TechState newState;

        foreach (var Info in TechRecipeCall.TechInfoList)
        {
            newState           = new TechState();
            newState.Info      = Info;
            newState.Completed = false;
            newState.Possible  = false;

            TechTreeList.Add(newState);
        }

        ResearchState FirstResearch = new ResearchState();

        FirstResearch.LabatoryList = new List <GameObject>();
        FirstResearch.TargetState  = TechTreeList[0];
        ResearchStateList.Add(FirstResearch);
        CompleteResearch(FirstResearch);

        CheckTechPossible();
    }
        public override void ProcessPacket(GameHistoryUnlockTechPacket packet, NebulaConnection conn)
        {
            Log.Info($"Unlocking tech (ID: {packet.TechId})");
            using (Multiplayer.Session.History.IsIncomingRequest.On())
            {
                // Let the default method give back the items
                GameMain.mainPlayer.mecha.lab.ManageTakeback();

                // Update techState
                TechProto techProto = LDB.techs.Select(packet.TechId);
                TechState techState = GameMain.history.techStates[packet.TechId];
                if (techState.curLevel >= techState.maxLevel)
                {
                    techState.curLevel     = techState.maxLevel;
                    techState.hashUploaded = techState.hashNeeded;
                    techState.unlocked     = true;
                }
                else
                {
                    techState.curLevel++;
                    techState.hashUploaded = 0L;
                    techState.hashNeeded   = techProto.GetHashNeeded(techState.curLevel);
                }
                // UnlockTech() unlocks tech to techState.maxLevel, so change it to curLevel temporarily
                int maxLevl = techState.maxLevel;
                techState.maxLevel = techState.curLevel;
                GameMain.history.techStates[packet.TechId] = techState;
                GameMain.history.UnlockTech(packet.TechId);
                techState.maxLevel = maxLevl;
                GameMain.history.techStates[packet.TechId] = techState;
                GameMain.history.DequeueTech();
            }
        }
Esempio n. 4
0
        public void ProcessPacket(GameHistoryResearchUpdatePacket packet, NebulaConnection conn)
        {
            GameHistoryData data = GameMain.data.history;

            if (packet.TechId != data.currentTech)
            {
                //Wait for the authoritative packet to enqueu new tech first
                return;
            }
            TechState state = data.techStates[data.currentTech];

            state.hashUploaded = packet.HashUploaded;
            data.techStates[data.currentTech] = state;
        }
Esempio n. 5
0
        public override void Update()
        {
            PacketProcessor.ProcessPacketQueue();

            if (Multiplayer.Session.IsGameLoaded)
            {
                gameResearchHashUpdateTimer     += Time.deltaTime;
                productionStatisticsUpdateTimer += Time.deltaTime;
                dysonLaunchUpateTimer           += Time.deltaTime;
                dysonSphereUpdateTimer          += Time.deltaTime;
                warningUpdateTimer += Time.deltaTime;

                if (gameResearchHashUpdateTimer > GAME_RESEARCH_UPDATE_INTERVAL)
                {
                    gameResearchHashUpdateTimer = 0;
                    if (GameMain.data.history.currentTech != 0)
                    {
                        TechState state = GameMain.data.history.techStates[GameMain.data.history.currentTech];
                        SendPacket(new GameHistoryResearchUpdatePacket(GameMain.data.history.currentTech, state.hashUploaded, state.hashNeeded));
                    }
                }

                if (productionStatisticsUpdateTimer > STATISTICS_UPDATE_INTERVAL)
                {
                    productionStatisticsUpdateTimer = 0;
                    Multiplayer.Session.Statistics.SendBroadcastIfNeeded();
                }

                if (dysonLaunchUpateTimer > LAUNCH_UPDATE_INTERVAL)
                {
                    dysonLaunchUpateTimer = 0;
                    Multiplayer.Session.Launch.SendBroadcastIfNeeded();
                }

                if (dysonSphereUpdateTimer > DYSONSPHERE_UPDATE_INTERVAL)
                {
                    dysonSphereUpdateTimer = 0;
                    Multiplayer.Session.DysonSpheres.UpdateSphereStatusIfNeeded();
                }

                if (warningUpdateTimer > WARNING_UPDATE_INTERVAL)
                {
                    warningUpdateTimer = 0;
                    Multiplayer.Session.Warning.SendBroadcastIfNeeded();
                }
            }
        }
        public override void ProcessPacket(GameHistoryResearchUpdatePacket packet, NebulaConnection conn)
        {
            GameHistoryData data = GameMain.data.history;

            if (packet.TechId != data.currentTech)
            {
                NebulaModel.Logger.Log.Warn($"CurrentTech mismatch! Server:{packet.TechId} Local:{data.currentTech}");
                //Replace currentTech to match with server
                data.currentTech  = packet.TechId;
                data.techQueue[0] = packet.TechId;
            }
            TechState state = data.techStates[data.currentTech];

            state.hashUploaded = packet.HashUploaded;
            state.hashNeeded   = packet.HashNeeded;
            data.techStates[data.currentTech] = state;
        }
Esempio n. 7
0
        private static void UnlockTechRecursive(int techId, GameHistoryData history)
        {
            TechState state = history.TechState(techId);
            TechProto proto = LDB.techs.Select(techId);

            foreach (var techReq in proto.PreTechs)
            {
                if (!history.TechState(techReq).unlocked)
                {
                    UnlockTechRecursive(techReq, history);
                }
            }
            foreach (var techReq in proto.PreTechsImplicit)
            {
                if (!history.TechState(techReq).unlocked)
                {
                    UnlockTechRecursive(techReq, history);
                }
            }
            foreach (var itemReq in proto.itemArray)
            {
                if (itemReq.preTech is not null && !history.TechState(itemReq.preTech.ID).unlocked)
                {
                    UnlockTechRecursive(itemReq.preTech.ID, history);
                }
            }

            int current = state.curLevel;

            for (; current < state.maxLevel; current++)
            {
                for (int j = 0; j < proto.UnlockFunctions.Length; j++)
                {
                    history.UnlockTechFunction(proto.UnlockFunctions[j], proto.UnlockValues[j], current);
                }
            }

            history.UnlockTech(techId);
        }
Esempio n. 8
0
        public static void ParallelizeFactoryGameTick(ILContext il)
        {
            ILCursor c = new ILCursor(il);

            int forIndex     = 3;
            var factoriesFld = typeof(GameData).GetField(nameof(GameData.factories), BindingFlags.Public | BindingFlags.Instance);

            Func <Instruction, bool>[] searchArray = new Func <Instruction, bool>[]
            {
                x => x.MatchLdcI4(0),
                x => x.MatchStloc(out forIndex),
                x => x.MatchBr(out _),
                x => x.MatchLdarg(0),
                x => x.MatchLdfld(factoriesFld),
                x => x.MatchLdloc(forIndex),
                x => x.MatchLdelemRef(),
                x => x.MatchBrfalse(out _),
                x => x.MatchLdarg(0),
                x => x.MatchLdfld(factoriesFld),
                x => x.MatchLdloc(forIndex),
                x => x.MatchLdelemRef(),
                x => x.MatchLdarg(1),
                x => x.MatchCallOrCallvirt(typeof(PlanetFactory).GetMethod(nameof(PlanetFactory.GameTick), BindingFlags.Public | BindingFlags.Instance)),
                x => x.MatchLdloc(forIndex),
                x => x.MatchLdcI4(1),
                x => x.MatchAdd(),
                x => x.MatchStloc(forIndex),
                x => x.MatchLdloc(forIndex),
                x => x.MatchLdarg(0),
                x => x.MatchLdfld(typeof(GameData).GetField(nameof(GameData.factoryCount), BindingFlags.Public | BindingFlags.Instance)),
                x => x.MatchBlt(out _)
            };

            c.GotoNext(MoveType.Before, searchArray);

            var retLabel = c.MarkLabel();

            c.Index -= 1;

            c.Emit(OpCodes.Ldarg_0);
            c.Emit(OpCodes.Ldarg_1);

            c.EmitDelegate <Func <GameData, long, bool> >((data, time) =>
            {
                bool flag           = false;
                int currentTech     = data.history.currentTech;
                TechProto techProto = LDB.techs.Select(currentTech);
                TechState techState = default(TechState);
                if (currentTech > 0 && techProto != null && techProto.IsLabTech && GameMain.history.techStates.ContainsKey(currentTech))
                {
                    techState = data.history.techStates[currentTech];
                    flag      = true;
                }
                if (flag && Math.Abs(techState.hashUploaded - techState.hashNeeded) < 7200L)
                {
                    return(true);
                }
                else
                {
                    Parallel.ForEach(data.factories, (factory) => { if (factory is not null)
                                                                    {
                                                                        factory.GameTick(time);
                                                                    }
                                     });

                    return(false);
                }
            });

            c.Index += searchArray.Length;
            var branchLabel = c.MarkLabel();

            c.GotoLabel(retLabel, MoveType.Before);

            c.Emit(OpCodes.Brfalse, branchLabel);
        }
Esempio n. 9
0
        public static void AddPlanetFactoryData(PlanetFactory planetFactory)
        {
            var factorySystem    = planetFactory.factorySystem;
            var transport        = planetFactory.transport;
            var veinPool         = planetFactory.planet.factory.veinPool;
            var miningSpeedScale = (double)GameMain.history.miningSpeedScale;

            for (int i = 1; i < factorySystem.minerCursor; i++)
            {
                var miner = factorySystem.minerPool[i];
                if (i != miner.id)
                {
                    continue;
                }

                var productId = miner.productId;
                var veinId    = (miner.veinCount != 0) ? miner.veins[miner.currentVeinIndex] : 0;

                if (miner.type == EMinerType.Water)
                {
                    productId = planetFactory.planet.waterItemId;
                }
                else if (productId == 0)
                {
                    productId = veinPool[veinId].productId;
                }

                if (productId == 0)
                {
                    continue;
                }


                EnsureId(ref counter, productId);

                float frequency = 60f / (float)((double)miner.period / 600000.0);
                float speed     = (float)(0.0001 * (double)miner.speed * miningSpeedScale);

                float production = 0f;
                if (factorySystem.minerPool[i].type == EMinerType.Water)
                {
                    production = frequency * speed;
                }
                if (factorySystem.minerPool[i].type == EMinerType.Oil)
                {
                    production = frequency * speed * (float)((double)veinPool[veinId].amount * (double)VeinData.oilSpeedMultiplier);
                }
                if (factorySystem.minerPool[i].type == EMinerType.Vein)
                {
                    production = frequency * speed * miner.veinCount;
                }
                production = Math.Min(BELT_MAX_ITEMS_PER_MINUTE, production);

                counter[productId].production += production;
                counter[productId].producers++;
            }
            for (int i = 1; i < factorySystem.assemblerCursor; i++)
            {
                var assembler = factorySystem.assemblerPool[i];
                if (assembler.id != i || assembler.recipeId == 0)
                {
                    continue;
                }

                var frequency = 60f / (float)((double)assembler.timeSpend / 600000.0);
                var speed     = (float)(0.0001 * (double)assembler.speed);

                for (int j = 0; j < assembler.requires.Length; j++)
                {
                    var productId = assembler.requires[j];
                    EnsureId(ref counter, productId);

                    counter[productId].consumption += frequency * speed * assembler.requireCounts[j];
                    counter[productId].consumers++;
                }

                for (int j = 0; j < assembler.products.Length; j++)
                {
                    var productId = assembler.products[j];
                    EnsureId(ref counter, productId);

                    counter[productId].production += frequency * speed * assembler.productCounts[j];
                    counter[productId].producers++;
                }
            }
            for (int i = 1; i < factorySystem.fractionateCursor; i++)
            {
                var fractionator = factorySystem.fractionatePool[i];
                if (fractionator.id != i)
                {
                    continue;
                }

                if (fractionator.fluidId != 0)
                {
                    var productId = fractionator.fluidId;
                    EnsureId(ref counter, productId);

                    counter[productId].consumption += 60f * 30f * fractionator.produceProb;
                    counter[productId].consumers++;
                }
                if (fractionator.productId != 0)
                {
                    var productId = fractionator.productId;
                    EnsureId(ref counter, productId);

                    counter[productId].production += 60f * 30f * fractionator.produceProb;
                    counter[productId].producers++;
                }
            }
            for (int i = 1; i < factorySystem.ejectorCursor; i++)
            {
                var ejector = factorySystem.ejectorPool[i];
                if (ejector.id != i)
                {
                    continue;
                }

                EnsureId(ref counter, ejector.bulletId);

                counter[ejector.bulletId].consumption += 60f / (float)(ejector.chargeSpend + ejector.coldSpend) * 600000f;
                counter[ejector.bulletId].consumers++;
            }
            for (int i = 1; i < factorySystem.siloCursor; i++)
            {
                var silo = factorySystem.siloPool[i];
                if (silo.id != i)
                {
                    continue;
                }

                EnsureId(ref counter, silo.bulletId);

                counter[silo.bulletId].consumption += 60f / (float)(silo.chargeSpend + silo.coldSpend) * 600000f;
                counter[silo.bulletId].consumers++;
            }

            for (int i = 1; i < factorySystem.labCursor; i++)
            {
                var lab = factorySystem.labPool[i];
                if (lab.id != i)
                {
                    continue;
                }
                float frequency = 60f / (float)((double)lab.timeSpend / 600000.0);

                if (lab.matrixMode)
                {
                    for (int j = 0; j < lab.requires.Length; j++)
                    {
                        var productId = lab.requires[j];
                        EnsureId(ref counter, productId);

                        counter[productId].consumption += frequency * lab.requireCounts[j];
                        counter[productId].consumers++;
                    }

                    for (int j = 0; j < lab.products.Length; j++)
                    {
                        var productId = lab.products[j];
                        EnsureId(ref counter, productId);

                        counter[productId].production += frequency * lab.productCounts[j];
                        counter[productId].producers++;
                    }
                }
                else if (lab.researchMode && lab.techId > 0)
                {
                    // In this mode we can't just use lab.timeSpend to figure out how long it takes to consume 1 item (usually a cube)
                    // So, we figure out how many hashes a single cube represents and use the research mode research speed to come up with what is basically a research rate
                    var techProto = LDB.techs.Select(lab.techId);
                    if (techProto == null)
                    {
                        continue;
                    }
                    TechState techState = GameMain.history.TechState(techProto.ID);
                    for (int index = 0; index < techProto.itemArray.Length; ++index)
                    {
                        var item          = techProto.Items[index];
                        var cubesNeeded   = techProto.GetHashNeeded(techState.curLevel) * techProto.ItemPoints[index] / 3600L;
                        var researchRate  = GameMain.history.techSpeed * 60.0f;
                        var hashesPerCube = (float)techState.hashNeeded / cubesNeeded;
                        var researchFreq  = hashesPerCube / researchRate;
                        EnsureId(ref counter, item);
                        counter[item].consumers++;
                        counter[item].consumption += researchFreq * GameMain.history.techSpeed;
                    }
                }
            }
            double gasTotalHeat       = planetFactory.planet.gasTotalHeat;
            var    collectorsWorkCost = transport.collectorsWorkCost;

            for (int i = 1; i < transport.stationCursor; i++)
            {
                var station = transport.stationPool[i];
                if (station == null || station.id != i || !station.isCollector)
                {
                    continue;
                }

                float collectSpeedRate = (gasTotalHeat - collectorsWorkCost > 0.0) ? ((float)((miningSpeedScale * gasTotalHeat - collectorsWorkCost) / (gasTotalHeat - collectorsWorkCost))) : 1f;

                for (int j = 0; j < station.collectionIds.Length; j++)
                {
                    var productId = station.collectionIds[j];
                    EnsureId(ref counter, productId);

                    counter[productId].production += 60f * TICKS_PER_SEC * station.collectionPerTick[j] * collectSpeedRate;
                    counter[productId].producers++;
                }
            }
            for (int i = 1; i < planetFactory.powerSystem.genCursor; i++)
            {
                var generator = planetFactory.powerSystem.genPool[i];
                if (generator.id != i)
                {
                    continue;
                }
                var isFuelConsumer = generator.fuelHeat > 0 && generator.fuelId > 0 && generator.productId == 0;
                if ((generator.productId == 0 || generator.productHeat == 0) && !isFuelConsumer)
                {
                    continue;
                }

                if (isFuelConsumer)
                {
                    // account for fuel consumption by power generator
                    var productId = generator.fuelId;
                    EnsureId(ref counter, productId);

                    counter[productId].consumption += 60.0f * TICKS_PER_SEC * generator.useFuelPerTick / generator.fuelHeat;
                    counter[productId].consumers++;
                }
                else
                {
                    var productId = generator.productId;
                    EnsureId(ref counter, productId);

                    counter[productId].production += 60.0f * TICKS_PER_SEC * generator.capacityCurrentTick / generator.productHeat;
                    counter[productId].producers++;
                    if (generator.catalystId > 0)
                    {
                        // account for consumption of critical photons by ray receivers
                        EnsureId(ref counter, generator.catalystId);
                        counter[generator.catalystId].consumption += RAY_RECEIVER_GRAVITON_LENS_CONSUMPTION_RATE_PER_MIN;
                        counter[generator.catalystId].consumers++;
                    }
                }
            }
        }