Beispiel #1
0
        public Entity SpawnCreature(EntityCommandBuffer cb, ECreatureId cId, int priority)
        {
            Entity entity             = cb.CreateEntity(_creatureArchetype);
            CreatureDescription descr = CreatureDescriptions[(int)cId];

            Sprite2DRenderer s = new Sprite2DRenderer();
            LayerSorting     l = new LayerSorting();
            Creature         c = new Creature {
                id = (int)cId
            };
            HealthPoints hp = new HealthPoints {
                max = descr.health, now = descr.health
            };
            AttackStat att = new AttackStat {
                range = descr.attackRange
            };
            Sight sight = new Sight {
                SightRadius = descr.sightRadius
            };
            PatrollingState     patrol   = new PatrollingState();
            MeleeAttackMovement movement = new MeleeAttackMovement();
            Speed speed = new Speed {
                SpeedRate = descr.speed
            };
            Mobile mobile = new Mobile {
                Destination = new float3(0, 0, 0), Initial = new float3(0, 0, 0), MoveTime = 0, Moving = false
            };
            Animated animated = new Animated {
                Id = descr.spriteId, Direction = Direction.Right, Action = Action.None, AnimationTime = 0, AnimationTrigger = false
            };
            ArmorClass ac = new ArmorClass {
                AC = descr.ac
            };
            TurnPriorityComponent tp = new TurnPriorityComponent {
                Value = priority
            };

            // Only tint sprites if ascii
            s.color   = GlobalGraphicsSettings.ascii ? descr.asciiColor : Color.Default;
            s.color.a = 0.0f; // Start invisible
            s.sprite  = SpriteSystem.IndexSprites[SpriteSystem.ConvertToGraphics(descr.ascii)];
            l.layer   = 2;

            cb.SetComponent(entity, s);
            cb.SetComponent(entity, c);
            cb.SetComponent(entity, l);
            cb.SetComponent(entity, hp);
            cb.SetComponent(entity, att);
            cb.SetComponent(entity, sight);
            cb.SetComponent(entity, movement);
            cb.SetComponent(entity, patrol);
            cb.SetComponent(entity, speed);
            cb.SetComponent(entity, mobile);
            cb.SetComponent(entity, animated);
            cb.SetComponent(entity, ac);

            return(entity);
        }
        protected override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            if (_cachedMapSize.x != _gss.View.Width || _cachedMapSize.y != _gss.View.Height)
            {
                ResizeMaps(_gss.View.Width, _gss.View.Height);
            }

            var clearJob = new ClearMapsJob()
            {
                FlagsMap  = _flagMap,
                EntityMap = _entityMap
            };

            var clearJobHandle = clearJob.Schedule(inputDependencies);

            var fillJob = new FillMapsJob()
            {
                MapSize             = _cachedMapSize,
                FlagsMap            = _flagMap,
                EntityMap           = _entityMap,
                EntityType          = GetArchetypeChunkEntityType(),
                WorldCoordType      = GetArchetypeChunkComponentType <WorldCoord>(true),
                BlockedMovementType = GetArchetypeChunkComponentType <BlockMovement>(true),
                DoorType            = GetArchetypeChunkComponentType <Door>(true),
                HostileType         = GetArchetypeChunkComponentType <tag_Attackable>(true),
                PlayerType          = GetArchetypeChunkComponentType <Player>(true)
            };
            var fillJobHandle = fillJob.Schedule(_mapFillQuery, clearJobHandle);

            var pendingMoves        = new NativeQueue <PendingMove>(Allocator.TempJob);
            var pendingWaits        = new NativeQueue <PendingWait>(Allocator.TempJob);
            var pendingAttacks      = new NativeQueue <PendingAttack>(Allocator.TempJob);
            var pendingOpens        = new NativeQueue <PendingDoorOpen>(Allocator.TempJob);
            var pendingInteractions = new NativeQueue <PendingInteractions>(Allocator.TempJob);

            var actionJob = new ConsumeActionsJob()
            {
                MapSize             = _cachedMapSize,
                ActionQueue         = _tms.ActionQueue,
                FlagsMap            = _flagMap,
                EntityMap           = _entityMap,
                PendingMoves        = pendingMoves,
                PendingWaits        = pendingWaits,
                PendingAttacks      = pendingAttacks,
                PendingOpens        = pendingOpens,
                PendingInteractions = pendingInteractions
            };
            var actionJobHandle = actionJob.Schedule(fillJobHandle);

            actionJobHandle.Complete();

            // TODO: Jobify?
            var         log = EntityManager.World.GetExistingSystem <LogSystem>();
            PendingMove pm;

            while (pendingMoves.TryDequeue(out pm))
            {
                var trans = _gss.View.ViewCoordToWorldPos(new int2(pm.Wc.x, pm.Wc.y));
                if (GlobalGraphicsSettings.ascii)
                {
                    EntityManager.SetComponentData(pm.Ent, new Translation {
                        Value = trans
                    });
                }
                else
                {
                    var anim   = EntityManager.World.GetExistingSystem <AnimationSystem>();
                    var mobile = EntityManager.GetComponentData <Mobile>(pm.Ent);
                    mobile.Initial     = EntityManager.GetComponentData <Translation>(pm.Ent).Value;
                    mobile.Destination = trans;
                    EntityManager.SetComponentData(pm.Ent, mobile);
                    anim.StartAnimation(pm.Ent, Action.Move, pm.Dir);
                    _inv.LogItemsAt(pm.Wc);
                }
                EntityManager.SetComponentData(pm.Ent, pm.Wc);
            }

            PendingWait pw;

            while (pendingWaits.TryDequeue(out pw))
            {
                if (EntityManager.HasComponent <Player>(pw.Ent))
                {
                    log.AddLog(pw.Ouch ? "You bumped into a wall. Ouch." : "You wait a turn.");
                }

                var anim = EntityManager.World.GetExistingSystem <AnimationSystem>();
                anim.StartAnimation(pw.Ent, pw.Ouch ? Action.Bump : Action.Wait, pw.Dir);
            }

            int pendingAttackCount = pendingAttacks.Count;

            if (pendingAttackCount > 0)
            {
                NativeArray <PendingAttack> sortedPendingAttacks =
                    new NativeArray <PendingAttack>(pendingAttackCount, Allocator.Temp);
                for (int i = 0; i < pendingAttackCount; i++)
                {
                    sortedPendingAttacks[i] = pendingAttacks.Dequeue();
                }

                sortedPendingAttacks.Sort(new PendingAttackComparer());
                for (int i = 0; i < pendingAttackCount; i++)
                {
                    PendingAttack pa         = sortedPendingAttacks[i];
                    AttackStat    att        = EntityManager.GetComponentData <AttackStat>(pa.Attacker);
                    Creature      attacker   = EntityManager.GetComponentData <Creature>(pa.Attacker);
                    HealthPoints  hp         = EntityManager.GetComponentData <HealthPoints>(pa.Defender);
                    Creature      defender   = EntityManager.GetComponentData <Creature>(pa.Defender);
                    HealthPoints  attackerHp = EntityManager.GetComponentData <HealthPoints>(pa.Attacker);
                    ArmorClass    defAC      = EntityManager.GetComponentData <ArmorClass>(pa.Defender);

                    if (attackerHp.now <= 0) // don't let the dead attack, is this hack? Maybe.
                    {
                        continue;
                    }
                    string attackerName = CreatureLibrary.CreatureDescriptions[attacker.id].name;
                    string defenderName = CreatureLibrary.CreatureDescriptions[defender.id].name;

                    // Play animation even if the creature misses
                    var anim = EntityManager.World.GetExistingSystem <AnimationSystem>();
                    anim.StartAnimation(pa.Attacker, Action.Attack, pa.AttackerDir);

                    if (DiceRoller.Roll(1, 20, 0) >= defAC.AC)
                    {
                        int  dmg      = RandomRogue.Next(att.range.x, att.range.y);
                        bool firstHit = hp.now == hp.max;

                        hp.now -= dmg;

                        bool playerAttack = attackerName == "Player";
                        bool killHit      = hp.now <= 0;

                        string logStr;

                        if (playerAttack && killHit && firstHit)
                        {
                            logStr = string.Concat("You destroy the ", defenderName);
                            logStr = string.Concat(logStr, ".");
                            ExperiencePoints xp = EntityManager.GetComponentData <ExperiencePoints>(pa.Attacker);
                            xp.now += hp.max; //XP awarded equals the defenders max hp
                            EntityManager.SetComponentData(pa.Attacker, xp);
                        }
                        else if (playerAttack)
                        {
                            logStr = string.Concat(string.Concat(string.Concat(string.Concat(
                                                                                   "You hit the ",
                                                                                   defenderName),
                                                                               " for "),
                                                                 dmg.ToString()),
                                                   " damage!");

                            if (killHit)
                            {
                                logStr = string.Concat(logStr, " Killing it.");
                                ExperiencePoints xp = EntityManager.GetComponentData <ExperiencePoints>(pa.Attacker);
                                xp.now += hp.max; //XP awarded equals the defenders max hp
                                EntityManager.SetComponentData(pa.Attacker, xp);
                            }
                        }
                        else
                        {
                            bool playerHit = false;
                            if (defenderName == "Player")
                            {
                                defenderName = "you";
                                playerHit    = true;
                            }

                            logStr = string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(
                                                                                                 attackerName,
                                                                                                 " hits "),
                                                                                             defenderName),
                                                                               " for "),
                                                                 dmg.ToString()),
                                                   " damage!");

                            if (playerHit)
                            {
                                _gss.LastPlayerHurtLog = logStr;
                            }
                        }

                        log.AddLog(logStr);

                        EntityManager.SetComponentData(pa.Defender, hp);
                    }
                    else
                    {
                        string logStr = attackerName;
                        logStr = string.Concat(logStr, " swings at ");
                        logStr = string.Concat(logStr, defenderName);
                        logStr = string.Concat(logStr, ".  But missed!");

                        log.AddLog(logStr);
                    }
                }

                sortedPendingAttacks.Dispose();
            }

            PendingDoorOpen pd;

            while (pendingOpens.TryDequeue(out pd))
            {
                if (EntityManager.HasComponent <Player>(pd.OpeningEntity))
                {
                    log.AddLog("You opened a door.");
                }
                Sprite2DRenderer s = EntityManager.GetComponentData <Sprite2DRenderer>(pd.DoorEnt);
                var door           = EntityManager.GetComponentData <Door>(pd.DoorEnt);
                door.Locked = false;
                door.Opened = true;
                EntityManager.RemoveComponent(pd.DoorEnt, typeof(BlockMovement));
                EntityManager.SetComponentData(pd.DoorEnt, door);
                EntityManager.SetComponentData(pd.DoorEnt, s);
            }

            PendingInteractions pi;

            while (pendingInteractions.TryDequeue(out pi))
            {
                using (var entities = EntityManager.GetAllEntities(Allocator.TempJob))
                {
                    foreach (Entity e in entities)
                    {
                        if (EntityManager.HasComponent(e, typeof(WorldCoord)) &&
                            EntityManager.HasComponent(e, typeof(Collectible)))
                        {
                            WorldCoord coord = EntityManager.GetComponentData <WorldCoord>(e);
                            int2       ePos  = new int2(coord.x, coord.y);

                            if (pi.InteractPos.x == ePos.x && pi.InteractPos.y == ePos.y)
                            {
                                _inv.CollectItemsAt(new EntityCommandBuffer(Allocator.TempJob), coord);
                            }
                        }

                        if (EntityManager.HasComponent(e, typeof(WorldCoord)) &&
                            EntityManager.HasComponent(e, typeof(Stairway)))
                        {
                            WorldCoord coord = EntityManager.GetComponentData <WorldCoord>(e);
                            int2       ePos  = new int2(coord.x, coord.y);

                            if (pi.InteractPos.x == ePos.x && pi.InteractPos.y == ePos.y)
                            {
                                if (EntityManager.HasComponent(e, typeof(Stairway)))
                                {
                                    _gss.MoveToNextLevel(new EntityCommandBuffer(Allocator.TempJob));
                                }
                            }
                        }
                    }
                }
            }

            // Cleanup
            pendingMoves.Dispose();
            pendingAttacks.Dispose();
            pendingWaits.Dispose();
            pendingOpens.Dispose();
            pendingInteractions.Dispose();

            return(actionJobHandle);
        }
Beispiel #3
0
        public Entity SpawnPlayer(EntityManager entityManager)
        {
            Entity entity             = entityManager.CreateEntity(_playerArchetype);
            CreatureDescription descr = CreatureDescriptions[(int)ECreatureId.Player];

            Creature c = new Creature {
                id = (int)ECreatureId.Player
            };
            HealthPoints hp = new HealthPoints {
                max = descr.health, now = descr.health
            };
            AttackStat att = new AttackStat {
                range = descr.attackRange
            };
            Level lvl = new Level {
                level = 1
            };
            ExperiencePoints exp = new ExperiencePoints {
                now = 0, next = LevelSystem.GetXPRequiredForLevel(1)
            };
            GoldCount gp = new GoldCount {
                count = 0
            };
            Mobile mobile = new Mobile {
                Destination = new float3(0, 0, 0), Initial = new float3(0, 0, 0), MoveTime = 0, Moving = false
            };
            Animated animated = new Animated {
                Id = descr.spriteId, Direction = Direction.Right, Action = Action.None, AnimationTime = 0, AnimationTrigger = false
            };
            Sight sight = new Sight {
                SightRadius = 4
            };
            ArmorClass ac = new ArmorClass {
                AC = descr.ac
            };
            TurnPriorityComponent tp = new TurnPriorityComponent {
                Value = -1
            };

            // Only tint sprites if ascii
            Sprite2DRenderer s = new Sprite2DRenderer();
            LayerSorting     l = new LayerSorting {
                order = 2
            };

            s.color  = GlobalGraphicsSettings.ascii ? descr.asciiColor : Color.Default;
            s.sprite = SpriteSystem.IndexSprites[SpriteSystem.ConvertToGraphics(descr.ascii)];
            l.layer  = 2;

            entityManager.SetComponentData(entity, s);
            entityManager.SetComponentData(entity, c);
            entityManager.SetComponentData(entity, l);
            entityManager.SetComponentData(entity, hp);
            entityManager.SetComponentData(entity, att);
            entityManager.SetComponentData(entity, lvl);
            entityManager.SetComponentData(entity, exp);
            entityManager.SetComponentData(entity, gp);
            entityManager.SetComponentData(entity, mobile);
            entityManager.SetComponentData(entity, animated);
            entityManager.SetComponentData(entity, sight);
            entityManager.SetComponentData(entity, ac);
            entityManager.SetComponentData(entity, tp);

            return(entity);
        }