コード例 #1
0
        private void FacilityQuery(Entity entity,
                                   ref HexFacility.Component facility,
                                   ref BaseUnitStatus.Component status,
                                   ref SpatialEntityId entityId)
        {
            var hexIndex = facility.HexIndex;
            var side     = status.Side;

            if (HexDic.ContainsKey(hexIndex) == false)
            {
                return;
            }

            var hex = HexDic[hexIndex];

            if (hex.Side == status.Side)
            {
                return;
            }

            changedCount++;
            hex.Side = status.Side;
            this.UpdateSystem.SendEvent(new HexBase.SideChanged.Event(new SideChangedEvent(side)), hex.EntityId.EntityId);

            //Debug.LogFormat("Updated Index:{0} Side:{1}", hexIndex, side);
        }
コード例 #2
0
        private void TargetQuery(Entity entity,
                                 ref CommanderStatus.Component commander,
                                 ref CommanderTeam.Component team,
                                 ref BaseUnitStatus.Component status,
                                 ref UnitActionData action,
                                 ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (status.Type != UnitType.Commander)
            {
                return;
            }

            if (status.Order == OrderType.Idle)
            {
                return;
            }

            var trans = EntityManager.GetComponentObject <Transform>(entity);
            var pos   = trans.position;

            applyOrder(status, entityId, pos, action.SightRange, ref commander, ref team);
        }
コード例 #3
0
        public void OnAddEntity_should_add_entity_and_command_components()
        {
            using (var wrappedOp = WorkerOpFactory.CreateAddEntityOp(TestEntityId))
            {
                receiveSystem.OnAddEntity(wrappedOp.Op);
            }

            Assert.IsTrue(worker.TryGetEntity(new EntityId(TestEntityId), out var entity));

            var id = new SpatialEntityId(); // Default value

            Assert.DoesNotThrow(() => { id = entityManager.GetComponentData <SpatialEntityId>(entity); });
            Assert.AreEqual(TestEntityId, id.EntityId.Id);

            ComponentType[] worldCommandComponentTypes =
            {
                ComponentType.Create <WorldCommands.CreateEntity.CommandSender>(),
                ComponentType.Create <WorldCommands.DeleteEntity.CommandSender>(),
                ComponentType.Create <WorldCommands.EntityQuery.CommandSender>(),
                ComponentType.Create <WorldCommands.ReserveEntityIds.CommandSender>()
            };

            foreach (var type in worldCommandComponentTypes)
            {
                Assert.IsTrue(entityManager.HasComponent(entity, type));
            }

            Assert.IsTrue(entityManager.HasComponent(entity,
                                                     ComponentType.Create <FirstComponentDispatcher.CommandComponent>()));
            Assert.IsTrue(entityManager.HasComponent(entity,
                                                     ComponentType.Create <SecondComponentDispatcher.CommandComponent>()));
        }
コード例 #4
0
        public static bool IsOwningWorker(SpatialEntityId entityId, World workerWorld)
        {
            var entityManager = workerWorld.GetOrCreateManager <EntityManager>();
            var worker        = workerWorld.GetExistingManager <WorkerSystem>();

            if (worker == null)
            {
                throw new InvalidOperationException("Provided World does not have an associated worker");
            }

            if (!worker.TryGetEntity(entityId.EntityId, out var entity))
            {
                throw new InvalidOperationException(
                          $"Entity with SpatialOS Entity ID {entityId.EntityId.Id} is not in this worker's view");
            }

            if (!entityManager.HasComponent <OwningWorker.Component>(entity))
            {
                return(false);
            }

            var ownerId = entityManager.GetComponentData <OwningWorker.Component>(entity).WorkerId;

            return(worker.Connection.GetWorkerId() == ownerId);
        }
コード例 #5
0
        private void Query(Unity.Entities.Entity entity,
                           Transform transform,
                           ref CoalStocks.Component stocks,
                           ref BaseUnitStatus.Component status,
                           ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            var pos = transform.position;

            int addCoal = 0;

            var count = Physics.OverlapSphereNonAlloc(pos, gatherRange, colls, this.CoalLayer);

            for (var i = 0; i < count; i++)
            {
                var col = colls[i];
                if (col.TryGetComponent <CoalInfoObject>(out var coal) == false)
                {
                    continue;
                }

                addCoal += coal.Gather();
            }

            if (addCoal > 0)
            {
                stocks.Stock += addCoal;
            }
        }
コード例 #6
0
        private void TeamQuery(Entity entity,
                               ref CommanderSight.Component sight,
                               ref CommanderTeam.Component team,
                               ref BaseUnitStatus.Component status,
                               ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsOfficer(status.Type) == false)
            {
                return;
            }

            if (status.Order == OrderType.Idle)
            {
                return;
            }

            if (status.Rank == 0)
            {
                return;
            }

            var trans = EntityManager.GetComponentObject <Transform>(entity);
            var pos   = trans.position;

            team.FollowerInfo.UnderCommanders.Clear();

            var rank   = status.Rank - 1;
            var range  = RangeDictionary.GetBoidsRange(status.Rank);
            var allies = getAllyUnits(status.Side, pos, range, allowDead: false, GetSingleUnitTypes(UnitType.Commander));

            foreach (var unit in allies)
            {
                if (unit.id == entityId.EntityId)
                {
                    continue;
                }

                BaseUnitStatus.Component?sts;
                if (this.TryGetComponent(unit.id, out sts) == false)
                {
                    continue;
                }

                if (sts.Value.Rank != rank)
                {
                    continue;
                }

                team.FollowerInfo.UnderCommanders.Add(unit.id);
            }
        }
コード例 #7
0
        private void Query(Entity entity,
                           ref BaseUnitReviveTimer.Component revive,
                           ref BaseUnitStatus.Component status,
                           ref SpatialEntityId entityId)
        {
            if (revive.IsStart == false)
            {
                return;
            }

            if (status.Type.BaseType() == UnitBaseType.Fixed)
            {
                return;
            }

            switch (status.State)
            {
            case UnitState.None:
                return;

            case UnitState.Alive:
                revive.IsStart  = false;
                revive.RestTime = 0.0f;
                return;
            }

            if (revive.RestTime > 0)
            {
                revive.RestTime -= deltaTime;
            }

            var id = entityId.EntityId;

            if (revive.RestTime < 0 && deletedIds.Contains(id) == false)
            {
                var request = new WorldCommands.DeleteEntity.Request
                              (
                    id,
                    context: new DeleteUnitContext()
                {
                    entityId = id
                }
                              );
                this.CommandSystem.SendCommand(request);
                deletedIds.Add(id);
            }
        }
コード例 #8
0
        private void Query(Entity entity,
                           ref StrongholdSight.Component sight,
                           ref BaseUnitStatus.Component status,
                           ref HexFacility.Component hex,
                           ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsBuilding(status.Type) == false)
            {
                return;
            }

            if (status.Side == UnitSide.None)
            {
                return;
            }

            var inter = sight.Interval;

            if (CheckTime(ref inter) == false)
            {
                return;
            }

            sight.Interval = inter;

            var trans = EntityManager.GetComponentObject <Transform>(entity);

            var targets   = sight.TargetStrongholds;
            var enemySide = sight.StrategyVector.Side;
            var vector    = sight.StrategyVector.Vector.ToUnityVector();
            var corners   = sight.FrontLineCorners;
            var hexes     = sight.TargetHexes;

            var order = GetTarget(trans.position, hex.HexIndex, this.FrontHexes, this.HexIndexes, status.Side, enemySide, hexes, corners);

            sight.TargetStrongholds = targets;
            sight.FrontLineCorners  = corners;
            sight.TargetHexes       = hexes;
            status.Order            = order;
        }
コード例 #9
0
        private void Query(Entity entity,
                           ref WorldTimer.Component timer,
                           ref SpatialEntityId entityId)
        {
            if (UnityEngine.Random.Range(0, upInter) != 0)
            {
                return;
            }

            timer.UtcSeconds = this.seconds;

            var info = new UpdateTimerInfo
            {
                CurrentSeconds = seconds,
            };

            this.UpdateSystem.SendEvent(new WorldTimer.Updates.Event(info), entityId.EntityId);
        }
コード例 #10
0
        private void PlayerQuery(Transform transform,
                                 ref BaseUnitStatus.Component status,
                                 ref PlayerInfo.Component player,
                                 ref SpatialEntityId spatialId)
        {
            UnitInfo info = null;

            playerUnitList.Add(unitQueue.Count > 0 ? unitQueue.Dequeue() : new UnitInfo());

            var index = playerUnitList.Count - 1;

            info       = playerUnitList[index];
            info.id    = spatialId.EntityId;
            info.pos   = transform.position;
            info.rot   = transform.rotation;
            info.type  = status.Type;
            info.side  = status.Side;
            info.order = status.Order;
            info.state = status.State;
            info.rank  = status.Rank;
        }
コード例 #11
0
        private void Query(Entity entity,
                           ref BaseUnitStatus.Component status,
                           ref BaseUnitHealth.Component health,
                           ref SpatialEntityId entityId)
        {
            var trans = EntityManager.GetComponentObject <Transform>(entity);

            if (trans == null)
            {
                return;
            }

            var range = RangeDictionary.UIRange;
            var diff  = trans.position - this.Camera.transform.position;

            if (diff.sqrMagnitude > range * range)
            {
                return;
            }

            var view = this.Camera.WorldToViewportPoint(trans.position);

            if (viewBounds.Contains(view) == false)
            {
                return;
            }

            var ui = GetOrCreateUI(entityId.EntityId);

            if (ui == null)
            {
                return;
            }

            var pos = RectTransformUtility.WorldToScreenPoint(this.Camera, trans.position + ui.Offset);

            ui.SetInfo(pos, health.Health, health.MaxHealth, false);
        }
コード例 #12
0
        private void Query(Entity entity,
                           ref HexBase.Component hex,
                           ref HexPower.Component power,
                           ref Position.Component position,
                           ref SpatialEntityId entityId)
        {
            if (hex.Attribute.IsTargetable() == false)
            {
                return;
            }

            if (hexDic.ContainsKey(hex.Index) == false)
            {
                hexDic[hex.Index] = new HexLocalInfo();
            }

            hexDic[hex.Index].Index    = hex.Index;
            hexDic[hex.Index].HexId    = hex.HexId;
            hexDic[hex.Index].Side     = hex.Side;
            hexDic[hex.Index].EntityId = entityId;
            hexDic[hex.Index].Powers   = power.SidePowers;
            hexDic[hex.Index].isActive = power.IsActive;
        }
コード例 #13
0
        private void MovementQuery(Entity entity,
                                   ref MovementData movement,
                                   ref NavPathData path,
                                   ref BaseUnitSight.Component sight,
                                   ref BaseUnitStatus.Component status,
                                   ref SpatialEntityId entityId)
        {
            movement.MoveSpeed = 0.0f;
            movement.RotSpeed  = 0.0f;

            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsAutomaticallyMoving(status.Type) == false)
            {
                return;
            }

            var unit = EntityManager.GetComponentObject <UnitTransform>(entity);

            // check ground
            if (unit == null || unit.GetGrounded(out var hitInfo) == false)
            {
                return;
            }

            if (sight.State == TargetState.None)
            {
                return;
            }

            var trans = unit.transform;
            var pos   = trans.position;

            Vector3?tgt    = null;
            Vector3 spread = Vector3.zero;

            var id = entityId.EntityId;

            if (vectorDic.ContainsKey(id))
            {
                //tgt = vectorDic[id].boidTarget;
                spread = vectorDic[id].spread;
            }

            if (tgt == null)
            {
                tgt = sight.GetTargetPosition(this.Origin, pos);
            }

            tgt = CheckNavPathAndTarget(tgt.Value, pos, unit.SizeRadius, sight.State, entityId.EntityId.Id, ref path);

            if (RangeDictionary.IsSpreadValid(spread))
            {
                var length = (tgt.Value - pos).magnitude;
                tgt += spread * Mathf.Max(1.0f, (length / RangeDictionary.SpreadSize));
            }

            var positionDiff = tgt.Value - pos;

            var forward = get_forward(positionDiff, sight.TargetRange);

            MovementDictionary.TryGet(status.Type, out var speed, out var rot);

            var isRotate = rotate(rot, trans, positionDiff);

            if (forward != 0.0f)
            {
                movement.MoveSpeed = forward * speed;
            }

            if (isRotate != 0)
            {
                movement.RotSpeed = rot * isRotate;
            }
        }
コード例 #14
0
        private void Query(Entity entity,
                           ref StrategyOrderManager.Component manager,
                           ref BaseUnitStatus.Component status,
                           ref SpatialEntityId spatialEntityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (status.Type != UnitType.HeadQuarter)
            {
                return;
            }

            var inter = manager.Interval;

            if (CheckTime(ref inter) == false)
            {
                return;
            }

            manager.Interval = inter;

            var trans = EntityManager.GetComponentObject <Transform>(entity);
            var range = RangeDictionary.Get(FixedRangeType.HeadQuarterRange);

            var enemy = getNearestEnemy(status.Side, trans.position);

            if (enemy == null)
            {
                return;
            }

            var entityId = new EntityId();

            entityId = enemy.id;

            var target = manager.TargetHq;

            if (target.HeadQuarterId != entityId)
            {
                manager.TargetHq = new TargetHeadQuartersInfo()
                {
                    HeadQuarterId = enemy.id,
                    Side          = enemy.side,
                    Position      = enemy.pos.ToWorldCoordinates(this.Origin),
                };
            }

            var st_range = RangeDictionary.Get(FixedRangeType.StrongholdRange);
            var allies   = getAllyUnits(status.Side, trans.position);
            var diff     = (enemy.pos - trans.position).normalized;

            foreach (var unit in allies)
            {
                if (unit.type != UnitType.Stronghold)
                {
                    continue;
                }

                SendCommand(unit.id, enemy.side, diff * st_range);
            }
        }
コード例 #15
0
        private void Query(Entity entity,
                           ref UnitActionData action,
                           ref GunComponent.Component gun,
                           ref PostureAnimation.Component anim,
                           ref BaseUnitTarget.Component target,
                           ref BaseUnitStatus.Component status,
                           ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsOffensive(status.Type) == false)
            {
                return;
            }

            if (target.State != TargetState.ActionTarget)
            {
                return;
            }

            var current = Time.ElapsedTime;

            var id = entityId.EntityId.Id;

            if (this.EnemyPositionsContainer == null ||
                this.EnemyPositionsContainer.TryGetValue(id, out var enemyPositions) == false)
            {
                return;
            }

            Vector3?epos = null;

            if (enemyPositions.Count > 0)
            {
                epos = enemyPositions[0].ToWorkerPosition(this.Origin);

                var container = EntityManager.GetComponentObject <PostureBoneContainer>(entity);
                Attack(container, current, epos.Value, entityId, ref gun);
            }

            var  type   = AnimTargetType.None;
            bool isDiff = false;

            if (epos != null)
            {
                isDiff = anim.AnimTarget.Position.ToWorkerPosition(this.Origin) != epos.Value;
                type   = AnimTargetType.Position;
            }

            if (anim.AnimTarget.Type != type || isDiff)
            {
                var animTarget = anim.AnimTarget;
                animTarget.Type = type;

                if (epos != null)
                {
                    animTarget.Position = epos.Value.ToWorldPosition(this.Origin);
                }

                anim.AnimTarget = animTarget;
            }
        }
コード例 #16
0
        private void Query(Entity entity,
                           ref BaseUnitSight.Component sight,
                           ref UnitActionData action,
                           ref BaseUnitStatus.Component status,
                           ref BaseUnitTarget.Component target,
                           ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (status.Order == OrderType.Idle)
            {
                return;
            }

            if (UnitUtils.IsWatcher(status.Type) == false)
            {
                return;
            }

            // initial
            target.State = TargetState.None;

            var id = entityId.EntityId.Id;

            if (enemyPositionsContainer.ContainsKey(id) == false)
            {
                enemyPositionsContainer[id] = new List <FixedPointVector3>();
            }

            var enemyPositions = enemyPositionsContainer[id];

            enemyPositions.Clear();

            var trans = EntityManager.GetComponentObject <Transform>(entity);
            var pos   = trans.position;

            UnitInfo enemy      = null;
            var      sightRange = action.SightRange;

            var backBuffer = sightRange / 2;

            if (status.Type == UnitType.Commander)
            {
                backBuffer += RangeDictionary.AllyRange / 2;
            }

            // strategy target
            SetStrategyTarget(pos, backBuffer, ref sight, ref target);

            // keep logic
            if (status.Order == OrderType.Keep)
            {
                sightRange *= target.PowerRate;
            }

            enemy = getNearestEnemy(status.Side, pos, sightRange);

            if (enemy != null)
            {
                var tgtPos = sight.TargetPosition.ToWorkerPosition(this.Origin);
                var epos   = enemy.pos.ToWorldPosition(this.Origin);

                if (Vector3.Dot(tgtPos - pos, enemy.pos - pos) > 0)
                {
                    target.State         = TargetState.ActionTarget;
                    sight.TargetPosition = epos;
                    sight.TargetSize     = enemy.size;
                }

                enemyPositions.Add(epos);
            }

            float range;

            switch (target.State)
            {
            case TargetState.ActionTarget:
                range = action.AttackRange;
                range = AttackLogicDictionary.GetOrderRange(status.Order, range) * target.PowerRate;
                break;

            default:
                range = RangeDictionary.BodySize;
                break;
            }

            // set behind
            if (status.Type == UnitType.Commander)
            {
                var addRange = RangeDictionary.AllyRange / 2;
                range += AttackLogicDictionary.RankScaled(addRange, status.Rank);
            }

            sight.TargetRange = range;
            sight.State       = target.State;
        }
コード例 #17
0
        private void Query(Transform trans,
                           ref TurretHub.Component turret,
                           ref BaseUnitStatus.Component status,
                           ref HexFacility.Component hex,
                           ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsBuilding(status.Type) == false)
            {
                return;
            }

            var datas = turret.TurretsDatas;

            if (IsNeedRenewTurrets(datas) == false)
            {
                return;
            }

            var units = getAllUnits(trans.position, HexDictionary.HexEdgeLength, allowDead: true, GetSingleUnitTypes(UnitType.Turret));

            removeKeys.Clear();
            foreach (var k in datas.Keys)
            {
                removeKeys.Add(k);
            }

            bool changed = false;

            var hexIndex = hex.HexIndex;

            foreach (var u in units)
            {
                if (hexIndex != uint.MaxValue && HexUtils.IsInsideHex(this.Origin, hexIndex, u.pos, HexDictionary.HexEdgeLength) == false)
                {
                    continue;
                }

                if (TryGetComponent <TurretComponent.Component>(u.id, out var comp) == false)
                {
                    continue;
                }

                int masterId = comp.Value.MasterId;

                if (datas.ContainsKey(u.id))
                {
                    var val = datas[u.id];
                    if (CheckDiffTurretInfo(ref val, u.side, masterId, u.id))
                    {
                        datas[u.id] = val;
                        changed     = true;
                    }

                    removeKeys.Remove(u.id);
                }
                else
                {
                    datas[u.id] = new TurretInfo(u.side, masterId, u.id);
                    changed     = true;
                }
            }

            if (removeKeys.Count == 0 && changed == false)
            {
                return;
            }

            foreach (var k in removeKeys)
            {
                datas.Remove(k);
            }

            turret.TurretsDatas = datas;
        }
コード例 #18
0
        private void FactoryQuery(Unity.Entities.Entity entity,
                                  ref UnitFactory.Component factory,
                                  ref ResourceComponent.Component resource,
                                  ref BaseUnitStatus.Component status,
                                  ref Position.Component position,
                                  ref StrongholdSight.Component sight,
                                  ref SpatialEntityId entityId)
        {
            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsBuilding(status.Type) == false)
            {
                return;
            }

            if (status.Order == OrderType.Idle)
            {
                return;
            }

            FollowerOrder?f_order      = null;
            SuperiorOrder?s_order      = null;
            TeamOrder?    team_order   = null;
            TurretOrder?  turret_order = null;

            FactoryOrderType orderType = FactoryOrderType.None;

            if (factory.SuperiorOrders.Count > 0)
            {
                s_order   = factory.SuperiorOrders[0];
                orderType = FactoryOrderType.Superior;
            }
            else if (factory.FollowerOrders.Count > 0)
            {
                f_order   = factory.FollowerOrders[0];
                orderType = FactoryOrderType.Follower;
            }
            else if (factory.TeamOrders.Count > 0)
            {
                team_order = factory.TeamOrders[0];
                orderType  = FactoryOrderType.Team;
            }
            else if (factory.TurretOrders.Count > 0)
            {
                turret_order = factory.TurretOrders[0];
                orderType    = FactoryOrderType.Turret;
            }

            if (orderType == FactoryOrderType.None)
            {
                return;
            }

            // calc time cost
            int   resourceCost;
            float timeCost;

            if (CalcOrderCost(out resourceCost, out timeCost, f_order, s_order, team_order) == false)
            {
                return;
            }

            //Debug.LogFormat("ResourceCost:{0} TimeCost:{1}", resourceCost, timeCost);

            if (factory.CurrentType == FactoryOrderType.None)
            {
                if (resource.Resource < resourceCost)
                {
                    //Debug.LogFormat("ResourcePoor:{0}", resource.Resource);
                    return;
                }

                factory.ProductInterval = IntervalCheckerInitializer.InitializedChecker(timeCost);
                factory.CurrentType     = orderType;
                resource.Resource      -= resourceCost;
            }

            factoryInter = factory.ProductInterval;
            if (CheckTime(ref factoryInter) == false)
            {
                return;
            }

            Coordinates?random = null;

            if (sight.StrategyVector.Side != UnitSide.None)
            {
                random = GetEmptyCoordinates(entityId.EntityId, position.Coords, sight.StrategyVector.Vector, height_buffer, factory.Containers);
            }

            if (random == null)
            {
                //Debug.LogFormat("There is no Empty");
                return;
            }

            //Debug.LogFormat("CreateUnit!");

            factory.ProductInterval = factoryInter;

            var            coords   = random.Value;//GetEmptyCoordinates(entityId.EntityId, position.Coords, height_buffer, factory.Containers);
            EntityTemplate template = null;

            bool     finished = false;
            UnitType type     = UnitType.None;

            if (s_order != null)
            {
                template = CreateSuperior(factory.SuperiorOrders, coords, out finished);
                type     = UnitType.Commander;
            }
            else if (f_order != null)
            {
                template = CreateFollower(factory.FollowerOrders, coords, f_order.Value.Customer, out finished);
                type     = UnitType.Soldier;
            }

            if (template != null)
            {
                var request = new WorldCommands.CreateEntity.Request
                              (
                    template,
                    context: new ProductOrderContext()
                {
                    f_order      = f_order,
                    s_order      = s_order,
                    type         = type,
                    strongholdId = entityId.EntityId,
                    container    = new UnitContainer(coords.ToFixedPointVector3(), ContainerState.Created)
                }
                              );
                this.CommandSystem.SendCommand(request);
            }
            else if (team_order != null)
            {
                CreateTeam(factory.TeamOrders, status.Side, entityId.EntityId, coords, out finished);
            }
            else if (turret_order != null)
            {
                // todo turret
            }

            if (finished)
            {
                factory.CurrentType = FactoryOrderType.None;
            }
        }
コード例 #19
0
        private void PowerQuery(Entity entity,
                                ref HexPower.Component power,
                                ref HexBase.Component hex,
                                ref SpatialEntityId entityId)
        {
            var hexSide = hex.Side;

            if (hexSide == UnitSide.None)
            {
                return;
            }

            power.SidePowers.TryGetValue(hexSide, out var current);

            if (current <= 0)
            {
                power.SidePowers[hexSide] = 0;
                current = 0;
            }

            if (resourceDictionary.TryGetValue(hex.Index, out var resourceValue))
            {
                power.SidePowers[hexSide] = current + (float)(resourceValue * deltaTime);
            }

            var ids = HexUtils.GetNeighborHexIndexes(hex.Index);

            targetIds.Clear();
            foreach (var id in ids)
            {
                if (base.HexDic.ContainsKey(id) == false)
                {
                    continue;
                }

                var  h      = base.HexDic[id];
                bool isFlow = false;
                if (h.Side == hexSide)
                {
                    if (current > h.CurrentPower + current * flowValueRate)
                    {
                        isFlow = true;
                    }
                }
                else if (h.Side == UnitSide.None)
                {
                    isFlow = true;
                }

                if (isFlow)
                {
                    targetIds.Add(id);
                }
            }

            var totalFlow = (float)(flowValueRate * deltaTime * current);
            var count     = targetIds.Count;
            var flow      = totalFlow / count;

            foreach (var id in targetIds)
            {
                float val = flow;
                if (power.SidePowers[hexSide] > flow)
                {
                    power.SidePowers[hexSide] -= flow;
                }
                else
                {
                    val = power.SidePowers[hexSide];
                    power.SidePowers[hexSide] = 0;
                }

                var h   = base.HexDic[id];
                var key = h.EntityId.EntityId;
                if (flowDictionary.ContainsKey(key))
                {
                    var powerDic = flowDictionary[key];
                    if (powerDic.ContainsKey(hexSide))
                    {
                        powerDic[hexSide] += val;
                    }
                    else
                    {
                        powerDic[hexSide] = val;
                    }
                }
                else
                {
                    flowDictionary[key] = new Dictionary <UnitSide, float>();
                    flowDictionary[key].Add(hexSide, val);
                }
            }
        }
コード例 #20
0
        private void DeviceQuery(Unity.Entities.Entity entity,
                                 ref DominationStamina.Component domination,
                                 ref BaseUnitStatus.Component status,
                                 ref SpatialEntityId entityId)
        {
            if (status.Side != UnitSide.None)
            {
                return;
            }

            if (status.Type != UnitType.Stronghold)
            {
                return;
            }

            float range    = domination.Range;
            var   staminas = domination.SideStaminas;

            var trans = EntityManager.GetComponentObject <Transform>(entity);
            var pos   = trans.position;
            var list  = getAllUnits(pos, range, allowDead: false, AttackLogicDictionary.DominationUnitTypes);

            sumsDic.Clear();
            foreach (var unit in list)
            {
                DominationDevice.Component?comp = null;
                if (TryGetComponent(unit.id, out comp) == false)
                {
                    continue;
                }

                var speed = 1.5f;

                switch (comp.Value.Type)
                {
                case DominationDeviceType.Capturing:
                    AffectCapture(unit.side, speed, sumsDic);
                    break;

                case DominationDeviceType.Jamming:
                    AffectJamming(unit.side, speed, sumsDic);
                    break;
                }
            }

            if (this.HexIndexes != null)
            {
                foreach (var kvp in this.HexIndexes)
                {
                    if (HexUtils.IsInsideHex(this.Origin, kvp.Key, pos, HexDictionary.HexEdgeLength) == false)
                    {
                        continue;
                    }

                    var hex = kvp.Value;
                    if (HexUtils.TryGetOneSidePower(hex.SidePowers, out var side, out var val))
                    {
                        if (sumsDic.ContainsKey(side))
                        {
                            sumsDic[side] += val;
                        }
                        else
                        {
                            sumsDic[side] = val;
                        }
                    }
                    break;
                }
            }

            // check over
            if (sumsDic.Count == 0)
            {
                return;
            }

            UnitSide firstSide  = UnitSide.None;
            float    firstValue = 0.0f;
            float    underSum   = 0.0f;

            foreach (var kvp in sumsDic)
            {
                if (kvp.Value > firstValue)
                {
                    underSum  += firstValue;
                    firstSide  = kvp.Key;
                    firstValue = kvp.Value;
                }
                else
                {
                    underSum += kvp.Value;
                }
            }

            if (firstValue <= underSum)
            {
                return;
            }

            var over = firstValue - underSum;

            if (staminas.ContainsKey(firstSide) == false)
            {
                staminas[firstSide] = over;
            }
            else
            {
                staminas[firstSide] += over;
            }

            this.keys.Clear();
            this.keys.AddRange(staminas.Keys);

            foreach (var k in this.keys)
            {
                if (k != firstSide && staminas.ContainsKey(k))
                {
                    var val = staminas[k];
                    staminas[k] = Mathf.Max(0.0f, val - over);
                }
            }

            // capture
            if (staminas[firstSide] >= domination.MaxStamina)
            {
                Capture(entityId.EntityId, firstSide);
                staminas.Clear();
            }

            domination.SideStaminas = staminas;
        }