public override void Perform(MobUpdateContext context) { NavMesh navMesh = context.moveRequest.Room.runtime_nav_mesh; float max_range = 5.0f; // Compute max range from mob type uint[] navCells = navMesh.ComputeNavCellsInRadius(context.mob.Position, max_range, false); Random rng = context.mob.AIState.behavior_data.GetMobRandomNumberGenerator(); RNGUtilities.DeterministicKnuthShuffle(rng, navCells); Point3d targetPosition = new Point3d(context.mob.Position); // Pick the first random nav cell in range that we have line of sight to foreach (uint navCellIndex in navCells) { Point3d testTarget = navMesh.ComputeNavCellCenter(navCellIndex); bool canSee = navMesh.PointCanSeeOtherPoint(context.mob.Position, testTarget); if (canSee) { targetPosition = testTarget; break; } } // Compute the side effect of actually moving the mob on the update context context.MoveMob(targetPosition); context.MobPostDialog("Soo bored..."); }
private void RandomlyRemoveRooms( Random rng) { int originalRoomCount = m_roomGrid.GetLength(0) * m_roomGrid.GetLength(1) * m_roomGrid.GetLength(2); int roomCount = originalRoomCount; // Determine the minimum number of rooms we allow for this level Range <float> roomDensityRange = m_worldTemplate.DungeonRoomDensity; float roomDensity = RNGUtilities.RandomFloat(rng, roomDensityRange.Min, roomDensityRange.Max); int minRoomCount = (int)(Math.Ceiling((float)originalRoomCount * roomDensity)); // Generate a randomized list of rooms IList <RoomIndex> randomRoomIndices = GetRoomIndexList(); RNGUtilities.DeterministicKnuthShuffle(rng, randomRoomIndices); // Randomly remove rooms one at time until we can't remove any more foreach (RoomIndex roomIndex in randomRoomIndices) { if (CanRemoveRoomFromGrid(roomIndex)) { RemoveRoomFromGrid(roomIndex); roomCount--; if (roomCount <= minRoomCount) { break; } } } }
private string GenerateNewSessionKey() { // Generate a random 128-bit string string newSessionKey = RNGUtilities.CreateNonDeterministicRandomBase64String(SESSION_KEY_BITS); // Make sure this is actually a new key while (m_sessions.ContainsKey(newSessionKey)) { newSessionKey = RNGUtilities.CreateNonDeterministicRandomBase64String(SESSION_KEY_BITS); } return(newSessionKey); }
public static MobSpawner CreateMobSpawner(RoomKey roomKey, MobSpawnerTemplate template, MobSpawnTableSet spawnTableSet, Random rng) { MobSpawner newMobSpawner = new MobSpawner(); newMobSpawner.m_room_key = new RoomKey(roomKey); newMobSpawner.m_mob_spawner_id = -1; // spawner ID not set until this gets saved into the DB newMobSpawner.m_position = new Point3d(template.Position); newMobSpawner.m_remaining_spawn_count = RNGUtilities.RandomInt(rng, 0, template.MaxSpawnCount); newMobSpawner.m_random_seed = rng.Next(); newMobSpawner.m_spawn_table = spawnTableSet.GetMobSpawnTableByName(template.SpawnTableName); return(newMobSpawner); }
public static int CreateGame( AsyncRPGDataContext context, int account_id, string game_name, GameConstants.eDungeonSize dungeonSize, GameConstants.eDungeonDifficulty dungeonDifficulty, bool irc_enabled, string irc_server, int irc_port, bool irc_encryption_enabled) { int new_game_id = -1; // Create a random 256-bit (32 byte) encryption key for encrypting chat string irc_encryption_key = RNGUtilities.CreateNonDeterministicRandomBase64String(256); Debug.Assert(irc_encryption_key.Length == 44); if (irc_server.Length == 0) { irc_server = IrcConstants.DEFAULT_IRC_SERVER; } if (irc_port < IrcConstants.LOWEST_VALID_IRC_PORT || irc_port > IrcConstants.HIGHEST_VALID_IRC_PORT) { irc_port = IrcConstants.DEFAULT_IRC_PORT; } { Games newGame = new Games { OwnerAccountID = account_id, Name = game_name, DungeonSize = (int)dungeonSize, DungeonDifficulty = (int)dungeonDifficulty, IrcEnabed = irc_enabled, IrcServer = irc_server, IrcPort = irc_port, IrcEncryptionKey = irc_encryption_key, IrcEncryptionEnabed = irc_encryption_enabled }; context.Games.InsertOnSubmit(newGame); context.SubmitChanges(); new_game_id = newGame.GameID; } return(new_game_id); }
private bool ChooseMobSpawners( RequestCache requestCache, out string result_code) { bool success = true; int desiredSpawnCount = m_max_spawn_count - m_current_spawn_count; result_code = SuccessMessages.GENERAL_SUCCESS; // Compute a list of all the occupied nav cells List <int> occupiedNavCells = requestCache.GetMobs(m_room.room_key).Select(m => m_room.runtime_nav_mesh.ComputeNavRefAtPoint(m.Position).NavCellIndex).ToList(); // Only use mob spawners that have a non zero remaining spawn count // and don't have a mob currently standing over stop of it. List <MobSpawner> availableMobSpawners = (from s in m_room.mobSpawners where s.RemainingSpawnCount > 0 && !occupiedNavCells.Contains(m_room.runtime_nav_mesh.ComputeNavRefAtPoint(s.Position).NavCellIndex) select s).ToList <MobSpawner>(); // Shuffle the list and pick the top N spawners (where N is based on difficulty) if (availableMobSpawners.Count > 0) { RNGUtilities.DeterministicKnuthShuffle(m_room.random_seed, availableMobSpawners); for (int spawnerIndex = 0; spawnerIndex < availableMobSpawners.Count && spawnerIndex < desiredSpawnCount; spawnerIndex++) { m_chosenMobSpawners.Add(availableMobSpawners[spawnerIndex]); } } return(success); }
private int CreateFullyConnectedRoomGrid( Random rng) { int lateralRoomCount = m_worldTemplate.DungeonLateralRoomCount; int floorCount = m_worldTemplate.DungeonFloorCount; int totalRoomCount = lateralRoomCount * lateralRoomCount * floorCount; m_roomGrid = new RoomLayout[lateralRoomCount, lateralRoomCount, floorCount]; m_minRoomKey = new RoomKey(m_gameId, -lateralRoomCount / 2, -lateralRoomCount / 2, 0); // Fully connect the rooms on each floor, but leave each floor unconnected initially for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid, RoomIndexIterator.eIterationType.allRooms); iterator.Valid; iterator.Next()) { RoomIndex roomIndex = iterator.Current; RoomKey roomKey = new RoomKey( m_gameId, roomIndex.X - lateralRoomCount / 2, roomIndex.Y - lateralRoomCount / 2, roomIndex.Z); RoomLayout room = new RoomLayout(roomKey); if (roomIndex.X > 0) { room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_x, true); } if (roomIndex.X < lateralRoomCount - 1) { room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_x, true); } if (roomIndex.Y > 0) { room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_y, true); } if (roomIndex.Y < lateralRoomCount - 1) { room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_y, true); } m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z] = room; } // Randomly add stairs connecting each floor for (int z_index = 0; z_index < floorCount - 1; z_index++) { Range <int> stairsRange = m_worldTemplate.StairsPerFloor; IList <RoomIndex> randomRoomIndices = GetRoomIndexListForFloor(z_index); int desiredStairsCount = RNGUtilities.RandomInt(rng, stairsRange.Min, stairsRange.Max); int currentStairsCount = 0; RNGUtilities.DeterministicKnuthShuffle(rng, randomRoomIndices); foreach (RoomIndex roomIndex in randomRoomIndices) { Room room = m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z]; Room roomAbove = m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z + 1]; // Only consider rooms of the configuration X+X-Y+Y- to add stairs to // because we only have rooms with stairs for the templates // X+X-Y+Y-Z+ and X+X-Y+Y-Z- // We do this so that we can get away with 18 room templates rather than 64 if (room.RoomHasAllPossibleDoors && !room.RoomHasStairs) { room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_z, true); roomAbove.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_z, true); ++currentStairsCount; } if (currentStairsCount >= desiredStairsCount) { break; } } } return(totalRoomCount); }
public static Portal CreatePortal(Room room, MathConstants.eSignedDirection roomSide) { Portal newPortal = new Portal(); newPortal.portal_id = -1; // portal ID not set until this portal gets saved into the DB newPortal.target_portal_id = -1; newPortal.room_side = roomSide; newPortal.room_x = room.room_key.x; newPortal.room_y = room.room_key.y; newPortal.room_z = room.room_key.z; switch (roomSide) { case MathConstants.eSignedDirection.positive_x: { Point3d p1 = WorldConstants.ROOM_BOUNDS.Max; Point3d p0 = p1 - Vector3d.I * WorldConstants.PORTAL_WIDTH - Vector3d.J * WorldConstants.ROOM_Y_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.negative_x: { Point3d p0 = WorldConstants.ROOM_BOUNDS.Min; Point3d p1 = p0 + Vector3d.I * WorldConstants.PORTAL_WIDTH + Vector3d.J * WorldConstants.ROOM_Y_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.positive_y: { Point3d p1 = WorldConstants.ROOM_BOUNDS.Max; Point3d p0 = p1 - Vector3d.I * WorldConstants.ROOM_X_SIZE - Vector3d.J * WorldConstants.PORTAL_WIDTH; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.negative_y: { Point3d p0 = WorldConstants.ROOM_BOUNDS.Min; Point3d p1 = p0 + Vector3d.I * WorldConstants.ROOM_X_SIZE + Vector3d.J * WorldConstants.PORTAL_WIDTH; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.positive_z: case MathConstants.eSignedDirection.negative_z: { int column = RNGUtilities.RandomInt(WorldConstants.ROOM_X_TILES / 3, 2 * WorldConstants.ROOM_X_TILES / 3); int row = RNGUtilities.RandomInt(WorldConstants.ROOM_Y_TILES / 3, 2 * WorldConstants.ROOM_Y_TILES / 3); Point3d p0 = WorldConstants.GetTilePosition(column, row); Point3d p1 = p0 + Vector3d.I * WorldConstants.ROOM_TILE_SIZE + Vector3d.J * WorldConstants.ROOM_TILE_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; } return(newPortal); }