public List <object> QueryGame(string playerName, int intQueryType, int[] arguments) { var queryType = (GameQueryType)intQueryType; var result = new List <object> { intQueryType }; var player = FindPlayer(playerName); if (player?.Entity.Being.IsAlive != true) { return(result); } var manager = player.Entity.Manager; var context = new SerializationContext(_dbContext, player.Entity, _gameServices); switch (queryType) { case GameQueryType.SlottableAbilities: var slot = arguments[0]; result.Add(slot); var abilities = new List <object>(); result.Add(abilities); foreach (var slottableAbilityEntity in manager.AbilitiesToAffectableRelationship[player.EntityId]) { var ability = slottableAbilityEntity.Ability; if (!ability.IsUsable) { continue; } if (slot == AbilitySlottingSystem.DefaultMeleeAttackSlot) { if (ability.Template?.Type == AbilityType.DefaultAttack && ((WieldingAbility)ability.Template).ItemType == ItemType.WeaponMelee) { abilities.Add(AbilitySnapshot.Serialize(slottableAbilityEntity, null, context)); } } else if (slot == AbilitySlottingSystem.DefaultRangedAttackSlot) { if (ability.Template?.Type == AbilityType.DefaultAttack && ((WieldingAbility)ability.Template).ItemType == ItemType.WeaponRanged) { abilities.Add(AbilitySnapshot.Serialize(slottableAbilityEntity, null, context)); } } else if ((ability.Activation & ActivationType.Slottable) != 0 && ability.Template?.Type != AbilityType.DefaultAttack) { abilities.Add(AbilitySnapshot.Serialize(slottableAbilityEntity, null, context)); } } break; case GameQueryType.PlayerAttributes: result.Add(LevelActorSnapshot.SerializeAttributes(player.Entity, SenseType.Sight, context)); break; case GameQueryType.PlayerAdaptations: result.Add(PlayerSnapshot.SerializeAdaptations(player.Entity, context)); break; case GameQueryType.PlayerSkills: result.Add(PlayerSnapshot.SerializeSkills(player.Entity, context)); break; case GameQueryType.ActorAttributes: var actorKnowledge = manager.FindEntity(arguments[0])?.Knowledge; result.Add(LevelActorSnapshot.SerializeAttributes( actorKnowledge?.KnownEntity, actorKnowledge?.SensedType ?? SenseType.None, context)); break; case GameQueryType.ItemAttributes: var itemEntity = manager.FindEntity(arguments[0]); var item = itemEntity?.Item; var itemKnowledge = itemEntity?.Knowledge; if (item != null) { result.Add(InventoryItemSnapshot.SerializeAttributes(itemEntity, SenseType.Sight, context)); } else { result.Add(InventoryItemSnapshot.SerializeAttributes( itemKnowledge?.KnownEntity, itemKnowledge?.SensedType ?? SenseType.None, context)); } break; case GameQueryType.AbilityAttributes: var abilityEntity = manager.FindEntity(arguments[0]); var ownerEntity = abilityEntity.Ability.OwnerEntity; var activatorEntity = abilityEntity.Ability.OwnerEntity.HasComponent(EntityComponent.Item) ? player.Entity : ownerEntity; result.Add(AbilitySnapshot.SerializeAttributes(abilityEntity, activatorEntity, context)); break; default: throw new InvalidOperationException($"Query type {intQueryType} not supported"); } return(result); }
public static List <object> Serialize( GameEntity levelEntity, EntityState?state, LevelSnapshot snapshot, SerializationContext context) { var manager = context.Manager; var level = levelEntity.Level; List <object> properties; switch (state) { case null: case EntityState.Added: var knownTerrain = new List <short>(); for (short j = 0; j < level.KnownTerrain.Length; j++) { var feature = level.KnownTerrain[j]; if (feature != (byte)MapFeature.Unexplored) { knownTerrain.Add(j); knownTerrain.Add(feature); } } var wallNeighbours = new List <short>(); for (short j = 0; j < level.WallNeighbours.Length; j++) { if (level.KnownTerrain[j] == (byte)MapFeature.Unexplored) { continue; } var neighbours = level.WallNeighbours[j] & (byte)DirectionFlags.Cross; if (neighbours != (byte)DirectionFlags.None) { wallNeighbours.Add(j); wallNeighbours.Add((byte)neighbours); } } var visibleTerrain = new List <short>(); for (short j = 0; j < level.VisibleTerrain.Length; j++) { var visibility = level.VisibleTerrain[j]; if (visibility != 0) { visibleTerrain.Add(j); visibleTerrain.Add(visibility); } } properties = state == null ? new List <object>(10) : new List <object>(11) { (int)state }; properties.Add(GetActors(levelEntity, manager) .Select(a => LevelActorSnapshot.Serialize(a, null, context)).ToList()); properties.Add(GetItems(levelEntity, manager) .Select(t => LevelItemSnapshot.Serialize(t, null, null, context)).ToList()); properties.Add(GetConnections(levelEntity, manager) .Select(c => ConnectionSnapshot.Serialize(c, null, context)).ToList()); properties.Add(knownTerrain); properties.Add(wallNeighbours); properties.Add(visibleTerrain); properties.Add(level.BranchName); properties.Add(level.Depth); properties.Add(level.Width); properties.Add(level.Height); return(properties); default: var levelEntry = context.DbContext.Entry(level); properties = new List <object> { (int)state }; var i = 2; var serializedActors = GameTransmissionProtocol.Serialize( GetActors(levelEntity, manager), snapshot.ActorsSnapshot, LevelActorSnapshot.Serialize, context); if (serializedActors.Count > 0) { properties.Add(i); properties.Add(serializedActors); } i++; var serializedItems = GameTransmissionProtocol.Serialize( GetItems(levelEntity, manager), snapshot.ItemsSnapshot, LevelItemSnapshot.Serialize, context); if (serializedItems.Count > 0) { properties.Add(i); properties.Add(serializedItems); } i++; var serializedConnections = GameTransmissionProtocol.Serialize( GetConnections(levelEntity, manager), snapshot.ConnectionsSnapshot, ConnectionSnapshot.Serialize, context); if (serializedConnections.Count > 0) { properties.Add(i); properties.Add(serializedConnections); } if (levelEntry.State != EntityState.Unchanged) { i++; var wallNeighboursChanges = new List <object>(); var knownTerrainChanges = new List <object>(level.KnownTerrainChanges.Count * 2); if (level.KnownTerrainChanges.Count > 0) { foreach (var terrainChange in level.KnownTerrainChanges) { knownTerrainChanges.Add(terrainChange.Key); knownTerrainChanges.Add(terrainChange.Value); wallNeighboursChanges.Add(terrainChange.Key); wallNeighboursChanges.Add(level.WallNeighbours[terrainChange.Key] & (byte)DirectionFlags.Cross); } } if (level.TerrainChanges.Count > 0) { foreach (var terrainChange in level.TerrainChanges) { if (level.VisibleTerrain[terrainChange.Key] == 0) { continue; } knownTerrainChanges.Add(terrainChange.Key); knownTerrainChanges.Add(terrainChange.Value); } } if (knownTerrainChanges.Count > 0) { properties.Add(i); properties.Add(knownTerrainChanges); } i++; if (level.WallNeighboursChanges.Count > 0) { foreach (var wallNeighboursChange in level.WallNeighboursChanges) { if (level.VisibleTerrain[wallNeighboursChange.Key] == 0) { continue; } wallNeighboursChanges.Add(wallNeighboursChange.Key); wallNeighboursChanges.Add(wallNeighboursChange.Value & (byte)DirectionFlags.Cross); } } if (wallNeighboursChanges.Count > 0) { properties.Add(i); properties.Add(wallNeighboursChanges); } i++; if (level.VisibleTerrainChanges.Count > 0) { properties.Add(i); var changes = new object[level.VisibleTerrainChanges.Count * 2]; var j = 0; foreach (var visibleTerrainChange in level.VisibleTerrainChanges) { changes[j++] = visibleTerrainChange.Key; changes[j++] = visibleTerrainChange.Value; } properties.Add(changes); } } return(properties.Count > 1 ? properties : null); } }