private Action ExtractAction(BGA.NotificationData notif) { try { switch (notif.type) { case BGA.NotificationData.Type.SIMPLE_NOTE: { return(new ActionSimpleNote(notif.GetSimpleNoteMessage())); } case BGA.NotificationData.Type.ACTIONCARD_PLAYED: { string playerId = notif.GetPlayerId(0); int value = notif.GetActionCardValue(); return(new ActionCard(ActionType.ACTION_CARD, playerId, value)); } case BGA.NotificationData.Type.CHOOSE_COMBATCARD: { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); return(new ActionCard(ActionType.COMBAT_CARD, playerId)); } case BGA.NotificationData.Type.CHOOSE_MYCOMBATCARD: { string playerId = gameData.board.viewerId; int value = notif.GetCombatCardValue(); return(new ActionCard(ActionType.COMBAT_CARD, playerId, value)); } case BGA.NotificationData.Type.REVEAL_COMBATCARD: { string playerId = notif.GetPlayerId(0); int value = notif.GetCombatCardValue(); int total = notif.GetCombatTotalValue(); return(new ActionCard(ActionType.COMBAT_CARD, playerId, value, total)); } case BGA.NotificationData.Type.JUMP: { string playerId = notif.GetPlayerId(0); return(new ActionCard(ActionType.JUMP, playerId)); } case BGA.NotificationData.Type.CHARACTER_GET_OUT: // getout and score { string playerId = notif.GetCharacterOwner(); string tokenName = gameData.board.ConvertToGame(notif.GetCharacterName()); int score = notif.GetCharacterPoints(); int charPoints = notif.GetCharacterPoints(); List <int> removeTokenIds = notif.GetRemoveTokenIds(); return(new ActionRemove(playerId, tokenName, score, charPoints, removeTokenIds)); } case BGA.NotificationData.Type.REMOVE_TOKENS: // speed potion, fireballwand { if (notif.GetPlayerName() != null) // speed potion { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); string tokenName = gameData.board.ConvertToGame(notif.GetCharacterName()); int score = 0; int charPoints = 0; List <int> removeTokenIds = notif.GetRemoveTokenIds(); return(new ActionRemove(playerId, tokenName, score, charPoints, removeTokenIds)); } else // fireballwand { Logger.Instance.Log("WARNING", "Network Interface: Extraction of Unused notification type " + notif.typeAsString + " (for fireballwand) skipped"); return(new Action()); } } case BGA.NotificationData.Type.CHARACTER_HEALED: // troll regeneration or clerc healing { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); string tokenName = gameData.board.ConvertToGame(notif.GetHealerType()); // Troll or Clerc Debug.Assert(notif.GetHealerOwnerId() == playerId); int targetId = notif.GetHealerTargetId(); return(new ActionHeal(playerId, tokenName, targetId)); } case BGA.NotificationData.Type.CHARACTER_MOVED: { string playerId = notif.GetPlayerId(0); int tokenId = notif.GetArgId(0); string tokenName = gameData.board.ConvertToGame(notif.GetArgType(0)); int x = gameData.board.ConvertX(notif.GetArgX(0)); int y = gameData.board.ConvertY(notif.GetArgY(0)); return(new ActionMove(playerId, tokenId, tokenName, x, y)); } case BGA.NotificationData.Type.COMBATCARD_REVEALED: // direct kill by firewand, killed because carrier killed, fall on trap, combat draw/win/loss { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); string tokenName = "unknown"; // gameData.board.ConvertToGame(notif.GetCharacterName()); // this information is not given anymore int attackerScore = notif.GetAttackerScore(); int defenderScore = notif.GetDefenderScore(); string winnerId = notif.GetWinnerId(); List <int> woundedIds = notif.GetWoundedIds(); List <int> killedIds = notif.GetKilledIds(); int attackerCardValue = notif.GetAttackerCardValue(); // -1 if not a combat result int defenderCardValue = notif.GetDefenderCardValue(); // -1 if not a combat result return(new ActionCombatEnd(playerId, tokenName, attackerScore, defenderScore, winnerId, woundedIds, killedIds, attackerCardValue, defenderCardValue)); } case BGA.NotificationData.Type.COMBAT_START: { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); List <string> attackers = notif.GetAttackerNames(); List <string> defenders = notif.GetDefenderNames(); return(new ActionCombatStart(playerId, attackers, defenders)); } case BGA.NotificationData.Type.GAMESTATE_CHANGE: case BGA.NotificationData.Type.LEAVE_GAMESTATE: { bool leave = (notif.type == BGA.NotificationData.Type.LEAVE_GAMESTATE); string gameStateName = notif.GetGameStateName(); string activePlayer = notif.GetNewActivePlayer(); return(new ActionStateChange(gameStateName, activePlayer, leave)); } case BGA.NotificationData.Type.HERSE_MANIPULATED: { string newState = notif.GetHerseManipulatedNewState(); ActionType type = (newState == "broken") ? ActionType.DESTROYDOOR : ((newState == "open") ? ActionType.OPENDOOR : ActionType.CLOSEDOOR); int x1 = gameData.board.ConvertX(notif.GetHerseManipulatedCharacterLocationX()); int y1 = gameData.board.ConvertY(notif.GetHerseManipulatedCharacterLocationY()); int x2 = gameData.board.ConvertX(notif.GetHerseManipulatedDirectionX()); int y2 = gameData.board.ConvertY(notif.GetHerseManipulatedDirectionY()); return(new ActionDoor(type, x1, y1, x2, y2)); } case BGA.NotificationData.Type.ROOM_DISCOVERED: { string playerId = notif.GetPlayerId(0); //int tokenId = notif.GetArgId(0); int tileIndex = gameData.board.ConvertTile(notif.GetTileId()); Debug.Assert(tileIndex >= 0 && tileIndex < 8); string tileName = gameData.board.ConvertToGame(notif.GetTileType().ToString()); int orientation = gameData.board.ConverTileOrientation(notif.GetTileOrientation(), notif.GetTileType()); return(new ActionRoomDiscovered(playerId /*, tokenId*/, tileIndex, tileName, orientation)); } case BGA.NotificationData.Type.ROOM_ROTATED: { string playerId = GetPlayerIdFromName(notif.GetPlayerName()); string tokenName = gameData.board.ConvertToGame(notif.GetCharacterName()); int tileIndex = gameData.board.ConvertTile(notif.GetTileId()); Debug.Assert(tileIndex >= 0 && tileIndex < 8); bool clockwize = notif.GetTileRotationClockwize(); int nbAction = notif.GetTileRotationNbAction(); int direction = gameData.board.ConverTileOrientation(notif.GetTileRotationDirection(), notif.GetTileType()); return(new ActionRoomRotated(playerId, tokenName, tileIndex, clockwize, nbAction, direction)); } case BGA.NotificationData.Type.TOKENS_TO_PLACE_UPDATE: case BGA.NotificationData.Type.TOKENS_UPDATE: { ActionTokensUpdate.Destination destination; switch (GetCurrentOnlineState()) { case "characterChoice": if (notif.type == BGA.NotificationData.Type.TOKENS_TO_PLACE_UPDATE) // unnecessary update { Logger.Instance.Log("DETAIL", "Network Interface: Extraction of Unused notification type " + notif.typeAsString + " skipped"); return(new Action()); } else { Debug.Assert(notif.GetTokensUpdateLocation() == "initial"); destination = ActionTokensUpdate.Destination.STARTING_LINE; } break; case "placeToken": Debug.Assert(notif.type == BGA.NotificationData.Type.TOKENS_UPDATE); Debug.Assert(notif.GetTokensUpdateLocation() == "ontile"); destination = ActionTokensUpdate.Destination.ROOM; break; case "revealCharacters": Debug.Assert(notif.type == BGA.NotificationData.Type.TOKENS_UPDATE); Debug.Assert(notif.GetTokensUpdateLocation() == "ingame"); destination = ActionTokensUpdate.Destination.REVEAL; break; case "playerChooseAction": case "movingCharacter": Debug.Assert(notif.type == BGA.NotificationData.Type.TOKENS_TO_PLACE_UPDATE); Debug.Assert(notif.GetTokensUpdateLocation() == "to_place"); destination = ActionTokensUpdate.Destination.TO_PLACE; break; default: if (notif.type == BGA.NotificationData.Type.TOKENS_TO_PLACE_UPDATE) { Logger.Instance.Log("DETAIL", "Network Interface: Extraction of Unused notification type " + notif.typeAsString + " skipped"); return(new Action()); } else { destination = ActionTokensUpdate.Destination.BOARD; } break; } var action = new ActionTokensUpdate(destination); for (int i = 0; i < notif.GetArgsCount(); i++) { int tokenId = notif.GetArgId(i); string playerId = notif.GetPlayerId(i); string tokenName = gameData.board.ConvertToGame(notif.GetArgType(i)); bool isItem = notif.IsItemToken(i); string location = notif.GetArgLocation(i); switch (location) { case "ontile": int tileIndex = gameData.board.ConvertTile(notif.GetArgLocationArg(i)); Debug.Assert(tileIndex >= 0 && tileIndex < 8); action.tokens.Add(new TokenUpdateData(tokenId, playerId, tokenName, isItem, tileIndex)); break; case "initial": case "ingame": case "carried": case "removed": int x = gameData.board.ConvertX(notif.GetArgX(i)); int y = gameData.board.ConvertY(notif.GetArgY(i)); Debug.Assert(x >= 0 && x < gManager.longueurPlateau() && y >= 0 && y < gManager.hauteurPlateau()); int holdingCharacterId = notif.GetTokenHolderId(i); action.tokens.Add(new TokenUpdateData(tokenId, playerId, tokenName, isItem, x, y, holdingCharacterId)); break; case "to_place": action.tokens.Add(new TokenUpdateData(tokenId, playerId, tokenName, isItem, 0)); break; case "not_placed": default: Debug.Assert(false, "not implemented"); break; } } return(action); } case BGA.NotificationData.Type.PASS: { return(new ActionPass()); } case BGA.NotificationData.Type.GAMESTATE_MULTIPLEACTIVEUPDATE: { List <string> players = notif.GetActivePlayersList(); return(new ActionMultiPlayerState(players)); } case BGA.NotificationData.Type.UPDATE_REFLEXIONTIME: { string playerId = notif.GetPlayerId(); int delta = notif.GetTimerDelta(); int max = notif.GetTimerMax(); return(new ActionUpdateTimer(playerId, delta, max)); } case BGA.NotificationData.Type.NEWACTIONCARDS: case BGA.NotificationData.Type.UPDATE_MECHANISMLOCATIONS: case BGA.NotificationData.Type.TOKENS_TO_PLACE_LIST: Logger.Instance.Log("DETAIL", "Network Interface: Extraction of Unused notification type " + notif.typeAsString + " skipped"); return(new Action()); case BGA.NotificationData.Type.DUMMY: Logger.Instance.Log("WARNING", "Network Interface: Extraction of Unexpected notification type " + notif.typeAsString + " skipped"); return(new Action()); default: Logger.Instance.Log("WARNING", "Network Interface: Extraction of Unknown notification type " + notif.typeAsString + " skipped"); return(new Action()); } } catch (System.Exception e) { Logger.Instance.Log("ERROR", "Network Interface: Extraction of action from notification " + notif.typeAsString + " failed " + e.ToString()); return(new Action()); } }