private void PlaceDungeon() { for (var i = 0; i < _cells.Length; i++) { var tileOffset = RandomRogue.Next(4); switch (_cells[i]) { case Type.eWall: _ecb.AddComponent(_view.ViewTiles[i], new Wall { TileOffset = tileOffset }); _ecb.AddComponent(_view.ViewTiles[i], new BlockMovement()); break; case Type.eHallway: case Type.eFloor: case Type.eDoor: _ecb.AddComponent(_view.ViewTiles[i], new Floor { TileOffset = tileOffset }); break; case Type.eEmpty: break; default: throw new ArgumentOutOfRangeException("Placing unknown type"); } } }
private void PlaceCreatures() { for (int i = 0; i < _dungeonGenParams.CreatureSpawns.Length; i++) { CreatureSpawnParams spawnParams = _dungeonGenParams.CreatureSpawns[i]; int creatureCount = RandomRogue.Next(spawnParams.SpawnMin, spawnParams.SpawnMax + 1); for (int j = 0; j < creatureCount; j++) { int cIdx = RandomRogue.Next(0, spawnParams.Creatures.Length); var worldCoord = GetRandomPositionInRandomRoom(); var viewCoord = _view.ViewCoordToWorldPos(worldCoord); Entity cEntity = _creatureLibrary.SpawnCreature(_ecb, spawnParams.Creatures[cIdx], _creaturnOrderIndex++); _ecb.SetComponent(cEntity, new WorldCoord { x = worldCoord.x, y = worldCoord.y }); _ecb.SetComponent(cEntity, new Translation { Value = viewCoord }); _ecb.SetComponent(cEntity, new PatrollingState { destination = GetRandomPositionInRandomRoom() }); } } }
public void GenerateDungeon(EntityCommandBuffer cb, View view, CreatureLibrary cl, ArchetypeLibrary al, int level, bool isFinalLevel) { _ecb = cb; _view = view; _creatureLibrary = cl; _archetypeLibrary = al; _dungeonGenParams = DungeonLibrary.GetDungeonParams(level, isFinalLevel); _creaturnOrderIndex = 0; ClearDungeon(cb, view); _cells = new Type[_view.ViewTiles.Length]; int maxRoom = 0; int maxRoomSize = 0; int minRoomSize = 0; Entities.WithAll <DungeonGenerator>().ForEach((Entity e, ref DungeonGenerator gen) => { maxRoom = gen.MaxNumberOfRooms; maxRoomSize = gen.MaxRoomSize; minRoomSize = gen.MinRoomSize; numberOfCollectibles = gen.NumberOfCollectibles; }); for (int i = 0; i < maxRoom; i++) { int newWidth = RandomRogue.Next(minRoomSize, maxRoomSize); int newHeight = RandomRogue.Next(minRoomSize, maxRoomSize); int newX = RandomRogue.Next(1, _view.Width - newWidth); int newY = RandomRogue.Next(1, _view.Height - newHeight); Room newRoom = new Room(newX, newY, newWidth, newHeight); if (!RoomIntersectExistingRooms(newRoom)) { _rooms.Add(newRoom); } } // Create the rooms, and then the hallways CreateRooms(); CreateHallways(); CreateDoors(); CreateTraps(); CreateGold(); CreateCollectibles(); CreateHealingItems(); // TODO: Add loot - this is added in GenerateCollectible in GameSystem PlaceCreatures(); PlaceDungeon(); PlacePlayer(level == 1); PlaceExit(isFinalLevel); }
private void CreateTraps() { int trapCount = RandomRogue.Next(_dungeonGenParams.TrapSpawn.SpawnMin, _dungeonGenParams.TrapSpawn.SpawnMax + 1); for (int i = 0; i < trapCount; i++) { var trapCoord = GetRandomPositionInRandomRoom(); _archetypeLibrary.CreateSpearTrap(_ecb, trapCoord, _view.ViewCoordToWorldPos(trapCoord)); } }
public static int Roll(int numberOfDice, int dNumber, int modifier) { int total = 0; for (int i = 0; i < numberOfDice; i++) { total += RandomRogue.Next(1, dNumber); } total += modifier; return(total); }
private void CreateGold() { // Saving the num in a variable so it can be used for // the replay system, if need be int goldPiles = RandomRogue.Next(_dungeonGenParams.GoldSpawn.SpawnMin, _dungeonGenParams.GoldSpawn.SpawnMax + 1); for (int i = 0; i < goldPiles; i++) { //TODO: figure out how it can know to avoid tiles that already have an entity var goldCoord = GetRandomPositionInRandomRoom(); _archetypeLibrary.CreateGold(_ecb, goldCoord, _view.ViewCoordToWorldPos(goldCoord)); } }
public void MoveToInGame(EntityCommandBuffer cb) { // Start at 0th level CurrentLevel = 0; LastDungeonNumber = RandomRogue.Next(5, 10); var log = EntityManager.World.GetExistingSystem <LogSystem>(); var tms = EntityManager.World.GetExistingSystem <TurnManagementSystem>(); GenerateLevel(); tms.ResetTurnCount(); log.AddLog("Welcome! Use the arrow keys to explore, z to interact and x to wait."); _state = eGameState.InGame; }
void CreateCollectibles() { for (int i = 0; i < _dungeonGenParams.CollectibleSpawns.Length; i++) { var collectibleSpawn = _dungeonGenParams.CollectibleSpawns[i]; var spawnCount = RandomRogue.Next(collectibleSpawn.SpawnMin, collectibleSpawn.SpawnMax + 1); for (int j = 0; j < spawnCount; j++) { //TODO: figure out how it can know to avoid tiles that already have an entity var collectibleCoord = GetRandomPositionInRandomRoom(); _archetypeLibrary.CreateCollectible(_ecb, collectibleCoord, _view.ViewCoordToWorldPos(collectibleCoord)); } } }
void CreateHealingItems() { for (int i = 0; i < _dungeonGenParams.PotionSpawns.Length; i++) { var potionSpawnParam = _dungeonGenParams.PotionSpawns[i]; int spawnCount = RandomRogue.Next(potionSpawnParam.SpawnMin, potionSpawnParam.SpawnMax + 1); for (int j = 0; j < spawnCount; j++) { var potionCoord = GetRandomPositionInRandomRoom(); var healAmount = RandomRogue.Next(potionSpawnParam.ValueMin, potionSpawnParam.ValueMax + 1); _archetypeLibrary.CreateHealingItem(_ecb, potionCoord, _view.ViewCoordToWorldPos(potionCoord), healAmount); } } }
private void CreateHallways() { for (int i = 0; i < _rooms.Count - 1; i++) { int2 room1Pos = _rooms[i].GetCenterTile(); int2 room2Pos = _rooms[i + 1].GetCenterTile(); int initialHallwayDirection = RandomRogue.Next(0, 1); //start horizontal if (initialHallwayDirection == 0) { CreateHorizontalHallway(room1Pos.y, room1Pos.x, room2Pos.x); CreateVerticalHallway(room2Pos.x, room1Pos.y, room2Pos.y); } //start vertical else { CreateVerticalHallway(room1Pos.x, room1Pos.y, room2Pos.y); CreateHorizontalHallway(room2Pos.y, room1Pos.x, room2Pos.x); } } }
public void GetRandomCollectible(EntityCommandBuffer ecb, Entity entity, CanBePickedUp c, HealthBonus hb) { if (collectiblesList.Count <= 0) { return; } var colEntry = collectiblesList[RandomRogue.Next(0, collectiblesList.Count)]; c.appearance.sprite = GlobalGraphicsSettings.ascii ? colEntry.spriteAscii : colEntry.spriteGraphics; c.description = colEntry.description; c.name = colEntry.name; ecb.SetComponent(entity, c); if (colEntry.healthBonus != 0) { hb.healthAdded = colEntry.healthBonus; //TODO: fix this //entityManager.SetComponentData(entity, hb); ecb.SetComponent(entity, hb); } }
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); }
void CreateDoors() { // Check all hallway tiles to see if we can sdd a door. for (var i = 0; i < _cells.Length; i++) { var current = _cells[i]; if (current != Type.eHallway) { continue; } var xy = View.IndexToXY(i, _view.Width); var neighbourUpXy = xy; neighbourUpXy.y--; var neighbourUp = _cells[View.XYToIndex(neighbourUpXy, _view.Width)]; var neighbourDownXy = xy; neighbourDownXy.y++; var neighbourDown = _cells[View.XYToIndex(neighbourDownXy, _view.Width)]; var neighbourRightXy = xy; neighbourRightXy.x++; var neighbourRight = _cells[View.XYToIndex(neighbourRightXy, _view.Width)]; var neighbourLeftXy = xy; neighbourLeftXy.x--; var neighbourLeft = _cells[View.XYToIndex(neighbourLeftXy, _view.Width)]; var horizontal = false; var vertical = false; // Check if doors can be made if (neighbourLeft == Type.eHallway && neighbourRight == Type.eFloor && neighbourUp == Type.eWall && neighbourDown == Type.eWall) { horizontal = true; } if (neighbourRight == Type.eHallway && neighbourLeft == Type.eFloor && neighbourUp == Type.eWall && neighbourDown == Type.eWall) { horizontal = true; } if (neighbourUp == Type.eHallway && neighbourDown == Type.eFloor && neighbourRight == Type.eWall && neighbourLeft == Type.eWall) { vertical = true; } if (neighbourDown == Type.eHallway && neighbourUp == Type.eFloor && neighbourRight == Type.eWall && neighbourLeft == Type.eWall) { vertical = true; } // Set as door if door possible if (horizontal || vertical) { _cells[i] = Type.eDoor; } if (vertical) { // Horizontal doors fit in vertical openings _horizontalDoors.Add(xy); } if (horizontal) { // Vertical doors fit in horizontal openings _verticalDoors.Add(xy); } } // Apply doors foreach (var doorCoord in _horizontalDoors) { if (RandomRogue.Next(TinyRogueConstants.DoorProbability) == 0) { _archetypeLibrary.CreateDoorway(_ecb, doorCoord, _view.ViewCoordToWorldPos(doorCoord), true); } } foreach (var doorCoord in _verticalDoors) { if (RandomRogue.Next(TinyRogueConstants.DoorProbability) == 0) { _archetypeLibrary.CreateDoorway(_ecb, doorCoord, _view.ViewCoordToWorldPos(doorCoord), false); } } }
public int2 GetRandomPositionInRandomRoom() { Room room = _rooms[RandomRogue.Next(0, _rooms.Count)]; return(room.GetRandomTile()); }
public int2 GetRandomTile() { int2 pos = new int2(RandomRogue.Next(startX + 1, startX + width - 1), RandomRogue.Next(startY + 1, startY + height - 1)); return(pos); }
public int2 GetPlayerStartPosition() { Room startRoom = _rooms[RandomRogue.Next(0, _rooms.Count)]; return(startRoom.GetRandomTile()); }