Gorun Gork Project

En esta sección se atenderán las dudas relacionadas con sistemas de gestión de la calidad, procedimientos, buenas prácticas, normas y todo lo relacionado con aseguramiento de la calidad

Moderator: julianmartinez16

User avatar
Garnable
Posts: 33
Joined: Mon Jan 22, 2018 11:25 am

Re: Gorun Gork Project

Post by Garnable » Thu May 10, 2018 6:13 pm

Sprint 16, Semana 16: Jueves 10/05 a Jueves 17/05
- Optimizar multijugador actual [2]
- Comando "Decir" en multijugador [2]
- Comando "Examinar" en multijugador [2]
Total de esfuerzo de este sprint: 6

Repositorio:
https://github.com/Garnll/GorunGorkText ... nlineStuff

¿Qué hemos hecho?
- Se hizo que los jugadores pudieran "verse" en las habitaciones y que se puedan mover en ellas, reflejando esto en los demás jugadores.

¿Qué vamos a hacer?
Para este lunes:
- Optimizar ciertos aspectos que quedaron del trabajo de network (como poder tener más de 2 jugadores sin crear un bucle infinito de eventos)
- Agregar el comando "Decir" en multijugador para que los jugadores en una habitación puedan hablar entre ellos

¿Qué dificultades tuvimos?
- Networking sigue siendo confuso y requiere tiempo de estudio.
- Por lo anterior, ciertas actividades de Single-Player tuvieron que ser aplazadas hasta tener tiempo para terminarlas.

EVIDENCIAS:

Diagrama de Clases de Network:
Image

Sistema de Network:

Code: Select all

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Manager de todo los callbacks para el Networking de Photon
/// </summary>
public class NetworkManager : Photon.PunBehaviour, IPunObservable {

    public static NetworkManager Instance = null;

    public GameController controller;
    public GameObject playerInstancePrefab;
    public PlayerInstancesManager playerInstanceManager;
    public string gameVersion = "0.1";
    public byte maxPlayers = 10;

    [HideInInspector] public bool isConnecting;
    [HideInInspector] public bool connected;

    private void Awake()
    {
        isConnecting = false;
        connected = false;
        Instance = this;
        PhotonNetwork.autoJoinLobby = false;
        PhotonNetwork.automaticallySyncScene = true;
    }

    public void ConnectToServer()
    {
        isConnecting = true;

        if (PhotonNetwork.connected)
        {
            PhotonNetwork.JoinRandomRoom();
        }
        else
        {
            PhotonNetwork.ConnectUsingSettings(gameVersion);
        }
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnPhotonRandomJoinFailed(object[] codeAndMsg)
    {
        PhotonNetwork.CreateRoom(null, new RoomOptions() { MaxPlayers = this.maxPlayers }, null);
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("Conectado a habitación. ");
        isConnecting = false;
        connected = true;

        string[] newPlayer = StoreMyPlayerData();

        photonView.RPC("NewPlayerJoined", PhotonTargets.Others, newPlayer);
    }

    public override void OnDisconnectedFromPhoton()
    {
        Debug.Log("Desconectado de Photon. ");
        connected = false;
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
    }

    public string[] StoreMyPlayerData()
    {
        return new string[]
        {
            controller.playerManager.playerName,
            controller.playerManager.gender,
            controller.playerManager.playerLevel.ToString(),
            controller.playerManager.currentHealth.ToString(),
            controller.playerManager.currentVisibility.ToString(),
            controller.playerRoomNavigation.currentPosition.ToString()
        };
    }

    public PlayerInstance CreatePlayerInstance(string[] playerData)
    {
        PlayerInstance newPlayer = Instantiate(playerInstancePrefab).GetComponent<PlayerInstance>();

        newPlayer.playerName = playerData[0];
        newPlayer.playerGender = playerData[1];
        Int32.TryParse(playerData[2], out newPlayer.playerLevel);
        Int32.TryParse(playerData[3], out newPlayer.currentHealth);
        Int32.TryParse(playerData[4], out newPlayer.currentVisibility);
        newPlayer.currentRoom = RoomsChecker.RoomObjectFromVector(
            RoomsChecker.RoomPositionFromText(playerData[5])
            );

        playerInstanceManager.playerInstancesOnScene.Add(newPlayer.playerName, newPlayer);

        return newPlayer;
    }

    [PunRPC]
    public void InstantiateAlreadyExistingPlayers(string[] playerData)
    {
        Debug.Log("Player entered");
        PlayerInstance oldPlayer = CreatePlayerInstance(playerData);

        if (oldPlayer.currentRoom != null)
        {
            if (oldPlayer.currentRoom == controller.playerRoomNavigation.currentRoom)
            {
                Debug.Log("Jugador en la habitación");
                controller.playerRoomNavigation.currentRoom.AddPlayerInRoom(oldPlayer);
                controller.playerRoomNavigation.ShowPlayersInRoom();
            }
        }
    }

    [PunRPC]
    public void NewPlayerJoined(string[] playerData)
    {
        Debug.Log("Player entered");
        PlayerInstance newPlayer = CreatePlayerInstance(playerData);

        if (newPlayer.currentRoom != null)
        {
            newPlayer.currentRoom.PlayerEnteredRoom(newPlayer, controller);
        }

        photonView.RPC("InstantiateAlreadyExistingPlayers", PhotonTargets.Others, StoreMyPlayerData());

    }

    #region Exploration Players

    public void MyPlayerChangedRooms(string playerID, Vector3 newPosition)
    {
        photonView.RPC("PlayerChangedRoom", PhotonTargets.Others, playerID, newPosition.ToString());
    }

    [PunRPC]
    public void PlayerChangedRoom(string playerID, string newRoomPosition)
    {
        Debug.Log(playerID + " Cambió habitaciones hacia " + newRoomPosition);

        if (RoomsChecker.roomsDictionary.ContainsKey(
            RoomsChecker.RoomPositionFromText(newRoomPosition)
            ))
        {
            if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerID))
            {
                playerInstanceManager.playerInstancesOnScene[playerID].currentRoom =
                    RoomsChecker.RoomObjectFromVector(
                    RoomsChecker.RoomPositionFromText(newRoomPosition)
                    );

                controller.playerRoomNavigation.currentRoom.PlayerLeftRoom(
                    playerInstanceManager.playerInstancesOnScene[playerID], controller);

                controller.playerRoomNavigation.currentRoom.PlayerEnteredRoom(
                    playerInstanceManager.playerInstancesOnScene[playerID],
                    controller
                    );
            }
        }
    }

    #endregion

}

Ckecklists:
Diseño: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Código: https://docs.google.com/spreadsheets/d/ ... sp=sharing

Se puede ver el estado del Burndown Chart en: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Image
Sebastián Lagoueyte Marín
000132622
Gestión de Calidad de Software
Ingeniería en Diseño de Entretenimiento Digital

User avatar
Garnable
Posts: 33
Joined: Mon Jan 22, 2018 11:25 am

Re: Gorun Gork Project

Post by Garnable » Mon May 14, 2018 8:34 am

Sprint 16, continuación

Repositorio:
https://github.com/Garnll/GorunGorkText ... nlineStuff

¿Qué hemos hecho?
- Hicimos ajustes al Network Manager para que fuera más eficiente
- Corregimos bugs varios referentes a la conexión entre jugadores
- Agregamos un botón extra en los lugares que visita el jugador para poder borrarlas sin dañar el proyecto (debug)
- Se adelantó gran parte del diseño de las habitaciones
- Las salidas de los lugares ahora se marcan
- Se adelantó la inclusión de contenido en el juego

¿Qué vamos a hacer?
Para este jueves:
- Comando "Examinar" agregado
- Terminar inclusión de contenido

¿Qué dificultades tuvimos?
- Aunque no es una dificultad, el scrum de esta semana está midiendo la velocidad de la programación de network, por lo cual la inclusión de contenido y mejoras visuales no se están viendo reflejadas por el burndown chart. Lo cual no significa que no se estén haciendo.


EVIDENCIAS:

GUI actual:
Image

Diagrama de clases:
Image

Network Manager (estado actual):

Code: Select all

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Manager de todo los callbacks para el Networking de Photon
/// </summary>
public class NetworkManager : Photon.PunBehaviour, IPunObservable {

    public static NetworkManager Instance = null;

    public GameController controller;
    public GameObject playerInstancePrefab;
    public PlayerInstancesManager playerInstanceManager;
    public string gameVersion = "0.1";
    public byte maxPlayers = 10;

    [HideInInspector] public bool isConnecting;
    [HideInInspector] public bool connected;

    private void Awake()
    {
        isConnecting = false;
        connected = false;
        Instance = this;
        PhotonNetwork.autoJoinLobby = false;
        PhotonNetwork.automaticallySyncScene = true;
    }

    public void ConnectToServer()
    {
        isConnecting = true;

        if (PhotonNetwork.connected)
        {
            PhotonNetwork.JoinRandomRoom();
        }
        else
        {
            PhotonNetwork.ConnectUsingSettings(gameVersion);
        }
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnPhotonRandomJoinFailed(object[] codeAndMsg)
    {
        PhotonNetwork.CreateRoom(null, new RoomOptions() { MaxPlayers = this.maxPlayers }, null);
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("Conectado a habitación. ");
        isConnecting = false;
        connected = true;

        PhotonNetwork.player.NickName = controller.playerManager.playerName;

        string[] newPlayer = StoreMyPlayerData();

        photonView.RPC("NewPlayerJoined", PhotonTargets.Others, newPlayer, PhotonNetwork.player.ID);
    }

    public override void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
    {
        PlayerDisconnected(otherPlayer.NickName);
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
    }

    public string[] StoreMyPlayerData()
    {
        return new string[]
        {
            controller.playerManager.playerName,
            PhotonNetwork.player.ID.ToString(),

            controller.playerManager.gender,
            controller.playerManager.playerLevel.ToString(),

            controller.playerManager.characteristics.playerJob.jobName,
            controller.playerManager.characteristics.playerRace.raceName,
            controller.playerManager.currentState.stateName,

            controller.playerManager.characteristics.currentStrength.ToString(),
            controller.playerManager.characteristics.currentIntelligence.ToString(),
            controller.playerManager.characteristics.currentResistance.ToString(),
            controller.playerManager.characteristics.currentDexterity.ToString(),

            controller.playerManager.currentHealth.ToString(),

            controller.playerManager.currentVisibility.ToString(),

            controller.playerRoomNavigation.currentPosition.ToString()

        };
    }

    public PlayerInstance CreatePlayerInstance(string[] playerData)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerData[0]))
        {
            Debug.Log("Player already exists");
            return null;
        }

        PlayerInstance newPlayer = Instantiate(playerInstancePrefab).GetComponent<PlayerInstance>();

        newPlayer.playerName = playerData[0];
        Int32.TryParse(playerData[1], out newPlayer.playerUserID);

        newPlayer.playerGender = playerData[2];
        Int32.TryParse(playerData[3], out newPlayer.playerLevel);

        newPlayer.playerJob = StringsIntoObjectsInator.Instance.JobFromString(playerData[4]);
        newPlayer.playerRace = StringsIntoObjectsInator.Instance.RaceFromString(playerData[5]);
        newPlayer.playerState = StringsIntoObjectsInator.Instance.StateFromString(playerData[6]);

        float.TryParse(playerData[7], out newPlayer.strength);
        float.TryParse(playerData[8], out newPlayer.intelligence);
        float.TryParse(playerData[9], out newPlayer.resistance);
        float.TryParse(playerData[10], out newPlayer.dexterity);

        Int32.TryParse(playerData[11], out newPlayer.currentHealth);

        Int32.TryParse(playerData[12], out newPlayer.currentVisibility);

        newPlayer.currentRoom = RoomsChecker.RoomObjectFromVector(
            RoomsChecker.RoomPositionFromText(playerData[13])
            );

        playerInstanceManager.playerInstancesOnScene.Add(newPlayer.playerName, newPlayer);

        return newPlayer;
    }

    [PunRPC]
    public void InstantiateAlreadyExistingPlayers(string[] playerData)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerData[0]))
        {
            Debug.Log("Player already exists here");
            return;
        }

        Debug.Log("Player entered");
        PlayerInstance oldPlayer = CreatePlayerInstance(playerData);

        if (oldPlayer.currentRoom != null)
        {
            oldPlayer.currentRoom.AddPlayerInRoom(oldPlayer);

            if (oldPlayer.currentRoom == controller.playerRoomNavigation.currentRoom)
            {
                Debug.Log("Jugador en la habitación");
                controller.playerRoomNavigation.ShowPlayersInRoom();
            }
        }
    }

    [PunRPC]
    public void NewPlayerJoined(string[] playerData, int playerID)
    {
        Debug.Log("Player entered");
        PlayerInstance newPlayer = CreatePlayerInstance(playerData);

        if (newPlayer.currentRoom != null)
        {
            newPlayer.currentRoom.PlayerEnteredRoom(newPlayer, controller);
        }

        photonView.RPC("InstantiateAlreadyExistingPlayers", PhotonPlayer.Find(playerID), StoreMyPlayerData());

    }

    public void PlayerDisconnected(string playerName)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            PlayerInstance oldPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

            if (oldPlayer.currentRoom == controller.playerRoomNavigation.currentRoom)
            {
                controller.LogStringWithoutReturn(playerName + " se ha desvanecido frente a tus ojos.");
            }

            oldPlayer.currentRoom.RemovePlayerInRoom(oldPlayer);
            Destroy(playerInstanceManager.playerInstancesOnScene[playerName].gameObject);

            playerInstanceManager.playerInstancesOnScene.Remove(playerName);
        }
    }

    #region Players Exploring Methods

    public void MyPlayerChangedRooms(string playerID, Vector3 newPosition)
    {
        photonView.RPC("PlayerChangedRoom", PhotonTargets.Others, playerID, newPosition.ToString());
    }

    [PunRPC]
    public void PlayerChangedRoom(string playerName, string newRoomPosition)
    {
        if (RoomsChecker.roomsDictionary.ContainsKey(
            RoomsChecker.RoomPositionFromText(newRoomPosition)
            ))
        {
            if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
            {
                PlayerInstance otherPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

                //Se borra al jugador de la habitación, revisando que nosotros no estuvieramos ahi
                otherPlayer.currentRoom.PlayerLeftRoom(
                    playerInstanceManager.playerInstancesOnScene[playerName], controller);

                //Se cambia la habitación actual del jugador
                otherPlayer.currentRoom =
                    RoomsChecker.RoomObjectFromVector(
                    RoomsChecker.RoomPositionFromText(newRoomPosition)
                    );

                //Se agrega al jugador a la nueva habitación
                otherPlayer.currentRoom.PlayerEnteredRoom(
                    playerInstanceManager.playerInstancesOnScene[playerName],
                    controller
                    );
            }
        }
    }

    #endregion


    #region Players say something

    public void SayThingInRoom(string thingToSay, string playerName)
    {
        photonView.RPC("ThingBeingSaidToeveryone", PhotonTargets.Others, thingToSay, playerName);
    }

    public void SayThingInRoomToPlayer(string thingToSay, string myPlayerName, int otherPlayerID)
    {
        photonView.RPC("ThingBeingSaidToSomeone", PhotonPlayer.Find(otherPlayerID), thingToSay, myPlayerName, otherPlayerID);
    }

    [PunRPC]
    public void ThingBeingSaidToeveryone(string thingSaid, string playerName)
    {
        if (!playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            return;
        }

        PlayerInstance speakingPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

        if (controller.playerRoomNavigation.currentRoom.playersInRoom.Contains(speakingPlayer))
        {
            string thingSomeoneSaid = string.Format("{0}: \"{1}\" ", playerName, thingSaid);
            controller.LogStringWithoutReturn(thingSomeoneSaid);
        }
    }

    [PunRPC]
    public void ThingBeingSaidToSomeone(string thingSaid, string playerName, int otherPlayerID)
    {
        if (!playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            return;
        }

        PlayerInstance speakingPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

        if (controller.playerRoomNavigation.currentRoom.playersInRoom.Contains(speakingPlayer))
        {
            string thingSomeoneSaid = string.Format("{0} te dice: \"{1}\" ", playerName, thingSaid);
            controller.LogStringWithoutReturn(thingSomeoneSaid);
        }
    }

    #endregion
}
Input "Say" (Decir), ahora online:

Code: Select all

using UnityEngine;

/// <summary>
/// Input que el usuario utiliza para decir cosas a todos en la habitación.
/// </summary>
[CreateAssetMenu(menuName = "Gorun Gork/InputActions/Say")]
public class SayInput : InputActions {

    PlayerInstance playerToSpeakTo;

    /// <summary>
    /// Responde exactamente lo que dijo el jugador menos el input.
    /// </summary>
    /// <param name="controller"></param>
    /// <param name="separatedInputWords"></param>
    public override void RespondToInput(GameController controller, string[] separatedInputWords)
    {
        playerToSpeakTo = null;

        if (separatedInputWords.Length <= 1)
        {
            controller.LogStringWithReturn("Ibas a decir algo pero te quedaste callado.");
        }

        separatedInputWords =  CheckDifferentPossibilities(separatedInputWords);

        if (!playerToSpeakTo)
        {
            NetworkManager.Instance.SayThingInRoom(SayJustTheString(separatedInputWords), controller.playerManager.playerName);
            controller.LogStringWithReturn(SayExactString(separatedInputWords));
        }
        else
        {
            if (controller.playerRoomNavigation.currentRoom.playersInRoom.Contains(playerToSpeakTo))
            {
                NetworkManager.Instance.SayThingInRoomToPlayer(SayJustTheString(separatedInputWords),
                    controller.playerManager.playerName,
                    playerToSpeakTo.playerUserID);

                controller.LogStringWithReturn(SayExactString(separatedInputWords, playerToSpeakTo.playerName));
            }
            else
            {
                controller.LogStringWithReturn(playerToSpeakTo.playerName + " no está en este lugar...");
            }
        }
    }

    /// <summary>
    /// Detecta qué dijo el jugador y elimina el input para devolver solo el resto de cosas.
    /// </summary>
    /// <param name="stringToSay"></param>
    /// <returns></returns>
    private string SayExactString(string[] stringToSay)
    {
        stringToSay[0] = "Dices a todos:";
        stringToSay[1] = "\"" + stringToSay[1];
        stringToSay[stringToSay.Length - 1] = stringToSay[stringToSay.Length - 1] + "\"";

        string combinedStrings = string.Join(" ", stringToSay);

        return combinedStrings;
    }

    private string SayExactString(string[] stringToSay, string otherPlayer)
    {
        stringToSay[0] = "Le dices a " +  otherPlayer + ":";
        stringToSay[1] = "\"" + stringToSay[1];
        stringToSay[stringToSay.Length - 1] = stringToSay[stringToSay.Length - 1] + "\"";

        string combinedStrings = string.Join(" ", stringToSay);

        return combinedStrings;
    }

    /// <summary>
    /// Quita el primer input y deja el resto como una string
    /// </summary>
    /// <param name="stringToSay"></param>
    /// <returns></returns>
    private string SayJustTheString(string[] stringToSay)
    {
        string[] newString = new string[stringToSay.Length - 1];

        for (int i = 1; i < stringToSay.Length; i++)
        {
            newString[i - 1] = stringToSay[i];
        }

        string combinedStrings = string.Join(" ", newString);

        return combinedStrings;
    }


    private string[] CheckDifferentPossibilities(string[] lastString)
    {
        int playerPossiblePosition = 1;

        if (lastString.Length > 2)
        {
            if (lastString[1] == "a")
            {
                playerPossiblePosition = 2;
            }
        }
        if (lastString.Length == playerPossiblePosition + 1)
        {
            return lastString;
        }

        if (NetworkManager.Instance.playerInstanceManager.playerInstancesOnScene.ContainsKey(lastString[playerPossiblePosition]))
        {
            playerToSpeakTo = NetworkManager.Instance.playerInstanceManager.playerInstancesOnScene[lastString[playerPossiblePosition]];

            string[] newString = new string[lastString.Length - playerPossiblePosition];

            newString[0] = "";

            for (int i = 0; i <= playerPossiblePosition; i++)
            {
                newString[0] += lastString[i];
            }

            for (int i = 1; i < newString.Length; i++)
            {
                newString[i] = lastString[i + playerPossiblePosition];
            }

            return newString;
        }
        else
        {
            return lastString;
        }
    }
}

Se puede ver el estado del Burndown Chart en: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Image
Sebastián Lagoueyte Marín
000132622
Gestión de Calidad de Software
Ingeniería en Diseño de Entretenimiento Digital

User avatar
Garnable
Posts: 33
Joined: Mon Jan 22, 2018 11:25 am

Re: Gorun Gork Project

Post by Garnable » Wed May 16, 2018 9:58 pm

Sprint 17, Semana 17: Jueves 17/05 a Jueves 24/05
- Programar Combate Multijugador [3]
- Continuar Agregando contenido [3]
- Crear interfaces para sistema de crafteo [2]
- Programar comandos de crafteo [3]
Total de esfuerzo de este sprint: 11

Repositorio:
https://github.com/Garnll/GorunGorkText ... nlineStuff

¿Qué hemos hecho?
- Se hizo la primera versión del comando Examinar de forma online
- Se continuó adelantando la inclusión de contendio

¿Qué vamos a hacer?
Para este lunes:
- Terminaremos las habitaciones que ya están en el proyecto.
- Empezaremos a agregar multijugador de combate

¿Qué dificultades tuvimos?
- Otros proyectos tomaron nuestro tiempo
- Se tuvo que desacelerar el progreso para poder re-hacer ciertas habitaciones.

EVIDENCIAS:

Network Controller:

Code: Select all

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Manager de todo los callbacks para el Networking de Photon
/// </summary>
public class NetworkManager : Photon.PunBehaviour, IPunObservable {

    public static NetworkManager Instance = null;

    public GameController controller;
    public GameObject playerInstancePrefab;
    public PlayerInstancesManager playerInstanceManager;
    public string gameVersion = "0.1";
    public byte maxPlayers = 10;

    [HideInInspector] public bool isConnecting;
    [HideInInspector] public bool connected;

    private void Awake()
    {
        isConnecting = false;
        connected = false;
        Instance = this;
        PhotonNetwork.autoJoinLobby = false;
        PhotonNetwork.automaticallySyncScene = true;
    }

    public void ConnectToServer()
    {
        isConnecting = true;

        if (PhotonNetwork.connected)
        {
            PhotonNetwork.JoinRandomRoom();
        }
        else
        {
            PhotonNetwork.ConnectUsingSettings(gameVersion);
        }
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnPhotonRandomJoinFailed(object[] codeAndMsg)
    {
        PhotonNetwork.CreateRoom(null, new RoomOptions() { MaxPlayers = this.maxPlayers }, null);
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("Conectado a habitación. ");
        isConnecting = false;
        connected = true;

        PhotonNetwork.player.NickName = controller.playerManager.playerName;

        string[] newPlayer = StoreMyPlayerData();

        photonView.RPC("NewPlayerJoined", PhotonTargets.Others, newPlayer, PhotonNetwork.player.ID);
    }

    public override void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
    {
        PlayerDisconnected(otherPlayer.NickName);
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
    }

    public string[] StoreMyPlayerData()
    {
        return new string[]
        {
            controller.playerManager.playerName,
            PhotonNetwork.player.ID.ToString(),

            controller.playerManager.gender,
            controller.playerManager.playerLevel.ToString(),

            controller.playerManager.characteristics.playerJob.jobName,
            controller.playerManager.characteristics.playerRace.raceName,
            controller.playerManager.currentState.stateName,

            controller.playerManager.characteristics.currentStrength.ToString(),
            controller.playerManager.characteristics.currentIntelligence.ToString(),
            controller.playerManager.characteristics.currentResistance.ToString(),
            controller.playerManager.characteristics.currentDexterity.ToString(),

            controller.playerManager.currentHealth.ToString(),

            controller.playerManager.currentVisibility.ToString(),

            controller.playerRoomNavigation.currentPosition.ToString()

        };
    }

    public PlayerInstance CreatePlayerInstance(string[] playerData)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerData[0]))
        {
            Debug.Log("Player already exists");
            return null;
        }

        PlayerInstance newPlayer = Instantiate(playerInstancePrefab).GetComponent<PlayerInstance>();

        UpdatePlayerInstancesStats(newPlayer, playerData);

        playerInstanceManager.playerInstancesOnScene.Add(newPlayer.playerName, newPlayer);

        return newPlayer;
    }

    public void UpdatePlayerInstancesStats(PlayerInstance newPlayer, string[] playerData)
    {
        newPlayer.playerName = playerData[0];
        Int32.TryParse(playerData[1], out newPlayer.playerUserID);

        newPlayer.playerGender = playerData[2];
        Int32.TryParse(playerData[3], out newPlayer.playerLevel);

        newPlayer.playerJob = StringsIntoObjectsInator.Instance.JobFromString(playerData[4]);
        newPlayer.playerRace = StringsIntoObjectsInator.Instance.RaceFromString(playerData[5]);
        newPlayer.playerState = StringsIntoObjectsInator.Instance.StateFromString(playerData[6]);

        float.TryParse(playerData[7], out newPlayer.strength);
        float.TryParse(playerData[8], out newPlayer.intelligence);
        float.TryParse(playerData[9], out newPlayer.resistance);
        float.TryParse(playerData[10], out newPlayer.dexterity);

        Int32.TryParse(playerData[11], out newPlayer.currentHealth);

        Int32.TryParse(playerData[12], out newPlayer.currentVisibility);

        newPlayer.currentRoom = RoomsChecker.RoomObjectFromVector(
            RoomsChecker.RoomPositionFromText(playerData[13])
            );
    }

    [PunRPC]
    public void InstantiateAlreadyExistingPlayers(string[] playerData)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerData[0]))
        {
            Debug.Log("Player already exists here");
            return;
        }

        Debug.Log("Player entered");
        PlayerInstance oldPlayer = CreatePlayerInstance(playerData);

        if (oldPlayer.currentRoom != null)
        {
            oldPlayer.currentRoom.AddPlayerInRoom(oldPlayer);

            if (oldPlayer.currentRoom == controller.playerRoomNavigation.currentRoom)
            {
                Debug.Log("Jugador en la habitación");
                controller.playerRoomNavigation.ShowPlayersInRoom();
            }
        }
    }

    [PunRPC]
    public void NewPlayerJoined(string[] playerData, int playerID)
    {
        Debug.Log("Player entered");
        PlayerInstance newPlayer = CreatePlayerInstance(playerData);

        if (newPlayer.currentRoom != null)
        {
            newPlayer.currentRoom.PlayerEnteredRoom(newPlayer, controller);
        }

        photonView.RPC("InstantiateAlreadyExistingPlayers", PhotonPlayer.Find(playerID), StoreMyPlayerData());

    }

    public void PlayerDisconnected(string playerName)
    {
        if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            PlayerInstance oldPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

            if (oldPlayer.currentRoom == controller.playerRoomNavigation.currentRoom)
            {
                controller.LogStringWithoutReturn(playerName + " se ha desvanecido frente a tus ojos.");
            }

            oldPlayer.currentRoom.RemovePlayerInRoom(oldPlayer);
            Destroy(playerInstanceManager.playerInstancesOnScene[playerName].gameObject);

            playerInstanceManager.playerInstancesOnScene.Remove(playerName);
        }
    }

    #region Players Exploring Methods

    public void MyPlayerChangedRooms(string playerID, Vector3 newPosition)
    {
        photonView.RPC("PlayerChangedRoom", PhotonTargets.Others, playerID, newPosition.ToString());
    }

    [PunRPC]
    public void PlayerChangedRoom(string playerName, string newRoomPosition)
    {
        if (RoomsChecker.roomsDictionary.ContainsKey(
            RoomsChecker.RoomPositionFromText(newRoomPosition)
            ))
        {
            if (playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
            {
                PlayerInstance otherPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

                //Se borra al jugador de la habitación, revisando que nosotros no estuvieramos ahi
                otherPlayer.currentRoom.PlayerLeftRoom(
                    playerInstanceManager.playerInstancesOnScene[playerName], controller);

                //Se cambia la habitación actual del jugador
                otherPlayer.currentRoom =
                    RoomsChecker.RoomObjectFromVector(
                    RoomsChecker.RoomPositionFromText(newRoomPosition)
                    );

                //Se agrega al jugador a la nueva habitación
                otherPlayer.currentRoom.PlayerEnteredRoom(
                    playerInstanceManager.playerInstancesOnScene[playerName],
                    controller
                    );
            }
        }
    }

    #endregion


    #region Players say something

    public void SayThingInRoom(string thingToSay, string playerName)
    {
        photonView.RPC("ThingBeingSaidToeveryone", PhotonTargets.Others, thingToSay, playerName);
    }

    public void SayThingInRoomToPlayer(string thingToSay, string myPlayerName, int otherPlayerID)
    {
        photonView.RPC("ThingBeingSaidToSomeone", PhotonPlayer.Find(otherPlayerID), thingToSay, myPlayerName, otherPlayerID);
    }

    [PunRPC]
    public void ThingBeingSaidToeveryone(string thingSaid, string playerName)
    {
        if (!playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            return;
        }

        PlayerInstance speakingPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

        if (controller.playerRoomNavigation.currentRoom.playersInRoom.Contains(speakingPlayer))
        {
            string thingSomeoneSaid = string.Format("{0}: \"{1}\" ", playerName, thingSaid);
            controller.LogStringWithoutReturn(thingSomeoneSaid);
        }
    }

    [PunRPC]
    public void ThingBeingSaidToSomeone(string thingSaid, string playerName, int otherPlayerID)
    {
        if (!playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            return;
        }

        PlayerInstance speakingPlayer = playerInstanceManager.playerInstancesOnScene[playerName];

        if (controller.playerRoomNavigation.currentRoom.playersInRoom.Contains(speakingPlayer))
        {
            string thingSomeoneSaid = string.Format("{0} te dice: \"{1}\" ", playerName, thingSaid);
            controller.LogStringWithoutReturn(thingSomeoneSaid);
        }
    }

    #endregion

    #region Player Examination

    public void AskForCurrentStats(string playerName)
    {
        if (!playerInstanceManager.playerInstancesOnScene.ContainsKey(playerName))
        {
            return;
        }

        PlayerInstance player = playerInstanceManager.playerInstancesOnScene[playerName];


        photonView.RPC("UpdateInstance", PhotonPlayer.Find(player.playerUserID), PhotonNetwork.player.ID);
    }

    [PunRPC]
    public void UpdateInstance(int playerID)
    {
        string[] myUpdate = StoreMyPlayerData();

        photonView.RPC("ExamineTarget", PhotonPlayer.Find(playerID), controller.playerManager.playerName, myUpdate);
    }

    [PunRPC]
    public void ExamineTarget(string playerName, string[] playerUpdated)
    {
        UpdatePlayerInstancesStats(playerInstanceManager.playerInstancesOnScene[playerName], playerUpdated);

        controller.LogStringWithoutReturn(playerName);
        controller.LogStringWithoutReturn(string.Join("\n", playerUpdated));
    }

    #endregion
}
ExamineInput:

Code: Select all

using UnityEngine;

/// <summary>
/// Input que el usuario utiliza para examinar objetos y/o personajes.
/// </summary>
[CreateAssetMenu(menuName = "Gorun Gork/InputActions/Examine")]
public class ExamineInput : InputActions {

    /// <summary>
    /// Revisa el input del usuario, y determina si se puede examinar o no lo que se está diciendo.
    /// En ambos casos envía una respuesta.
    /// </summary>
    /// <param name="controller"></param>
    /// <param name="separatedInputWords"></param>
    public override void RespondToInput(GameController controller, string[] separatedInputWords, string[] separatedCompleteInputWords)
    {
        if (separatedInputWords.Length > 1)
        {
            string noun = separatedInputWords[1];
            string nounWithCapitals = separatedCompleteInputWords[1];

            if (NetworkManager.Instance.playerInstanceManager.playerInstancesOnScene.ContainsKey(nounWithCapitals))
            {
                NetworkManager.Instance.AskForCurrentStats(nounWithCapitals);
                return;
            }

            if (noun == "habitacion" || noun == "" || noun == "lugar")
            {
                controller.LogStringWithReturn(controller.RefreshCurrentRoomDescription());
                return;
            }
        }
        else
        {
            controller.LogStringWithReturn(controller.RefreshCurrentRoomDescription());
            return;
        }

		InteractableObject o = controller.playerManager.inventoryManager.tryOpen(separatedInputWords);

		if (o != null) {
			controller.LogStringWithReturn(o.Open());
		}
		else {
			InteractableObject objectToExamine =
				controller.itemHandler.SearchObjectInRoomOrInventory(separatedInputWords, true, true);

			if (objectToExamine != null) {
				controller.itemHandler.ExamineObject(objectToExamine);
			}
		}
    }
}

Ckecklists:
Diseño: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Código: https://docs.google.com/spreadsheets/d/ ... sp=sharing

Se puede ver el estado del Burndown Chart en: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Image
Sebastián Lagoueyte Marín
000132622
Gestión de Calidad de Software
Ingeniería en Diseño de Entretenimiento Digital

User avatar
Garnable
Posts: 33
Joined: Mon Jan 22, 2018 11:25 am

Re: Gorun Gork Project

Post by Garnable » Sun May 20, 2018 10:49 pm

Sprint 17, continuación

Repositorio:
https://github.com/Garnll/GorunGorkText ... nlineStuff

¿Qué hemos hecho?
- Avanzamos en programar el combate en multijugador
- Se agregó contenido a las habitaciones

¿Qué vamos a hacer?
Para este jueves:
- Terminaremos la implementación del combate multijugador.
- Se seguirá agregando contenido
- Se implementará el sistema de crafteo, con sus interfaces

¿Qué dificultades tuvimos?
- Otro trabajo para otra materia tomó más tiempo del esperado.
- Adelantos de otros finales también consumieron tiempo.


EVIDENCIAS:

Presentación Final:


Combat Controller (incompleto):

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Controlador de todo lo que haría el gamecontroller durante el combate.
/// </summary>
public class CombatController : MonoBehaviour {

	public float pace = 0.1f;
    public float battleTimeInMins = 2;
    private float currentBattleTime = 0;

    public InventoryManager inventoryManager;
    [Space(10)]
    public GameObject combatLayout;
    public RectTransform contentContainer;
    [Space(10)]
    public PlayerUIDuringCombat playerUI;
    public EnemyUIDuringCombat enemyUI;

	public PlayerText playerText;

    List<string> habilitiesText = new List<string>();
    private EnemyNPC enemy;
    private PlayerInstance enemyPlayer;
    private Queue<string> enemyLog = new Queue<string>();
    private PlayerManager player;
    private Queue<string> playerLog = new Queue<string>();

    private bool inInventory = false;
    private bool vsPlayer = false;
    private int inventoryPage = 1;

	public Gradient playerColorGradient;
	public Gradient enemyColorGradient;

	[Space(10)]
	public Gradient playerTurnColor;
	public Gradient enemyTurnColor;

    int lemonsWon;

    public PlayerInstance TryToFightPlayer(string[] keywordGiven, RoomObject currentRoom)
    {
        string[] newString = new string[keywordGiven.Length - 1];

        for (int i = 1; i < keywordGiven.Length; i++)
        {
            newString[i - 1] = keywordGiven[i];
        }

        foreach (string keyworkByPlayer in newString)
        {
            if (NetworkManager.Instance.playerInstanceManager.playerInstancesOnScene.ContainsKey(keyworkByPlayer))
            {
                vsPlayer = true;
                return NetworkManager.Instance.playerInstanceManager.playerInstancesOnScene[keyworkByPlayer];
            }
        }

        return null;
    }

    /// <summary>
    /// Revisa entre los templates de la habitación actual buscando el keyword dado por el jugador.
    /// Devuelve el enemigo que encuentre.
    /// </summary>
    /// <param name="keywordGiven"></param>
    /// <param name="currentRoom"></param>
    /// <returns></returns>
    public NPCTemplate TryToFight(string[] keywordGiven, RoomObject currentRoom)
    {
		string[] newString = new string[keywordGiven.Length - 1];

		for (int i = 1; i < keywordGiven.Length; i++) {
			newString[i - 1] = keywordGiven[i];
		}

        vsPlayer = false;

        for (int i = 0; i < currentRoom.npcTemplatesInRoom.Count; i++)
        {
            NPCTemplate npc = currentRoom.npcTemplatesInRoom[i];

            if (npc.GetType() == typeof(EnemyNPCTemplate))
            {
				foreach (string keyword in npc.keywords) {
					foreach (string keyworkByPlayer in newString) {
						if (keyword == keyworkByPlayer) {
							return npc;
						}
					}
                }
            }
        }

        return null;
    }

    /// <summary>
    /// Comienza preparaciones del combate, inicializa variables de enemy y player.
    /// </summary>
    /// <param name="npc"></param>
    /// <param name="thisPlayer"></param>
    public void PrepareFight(EnemyNPC npc, PlayerManager thisPlayer)
    {
        enemy = npc;
        player = thisPlayer;
        lemonsWon = 0;
        currentBattleTime = battleTimeInMins*60;

        GameState.Instance.ChangeCurrentState(GameState.GameStates.combatPreparation);
    }

    public void PrepareFight(PlayerInstance otherPlayer, PlayerManager thisPlayer)
    {
        enemyPlayer = otherPlayer;
        player = thisPlayer;
        lemonsWon = 0;
        currentBattleTime = battleTimeInMins * 60;

        GameState.Instance.ChangeCurrentState(GameState.GameStates.combatPreparation);
    }

    /// <summary>
    /// Inicia la batalla una vez la UI de exploración haya acabado de copiar.
    /// </summary>
    /// <returns></returns>
    public IEnumerator StartFight()
    {
        yield return new WaitUntil(() => player.controller.writing == false && player.controller.HasFinishedWriting());

        GameState.Instance.ChangeCurrentState(GameState.GameStates.combat);

        ChangeLayout();

        if (vsPlayer)
        {
            InitializeEnemyPlayer();
        }
        else
        {
            InitializeEnemy();
        }


        InitializePlayer();

        CancelInvoke();
        ClearCollections();
        StopAllCoroutines();
        StartCoroutine(UpdateTurns());

        if (!vsPlayer)
        {
            if (enemy.myAI == null)
            {
                enemy.myAI = enemy.GetComponent<EnemyNPCAI>();
            }
            enemy.myAI.player = player;
            enemy.myAI.myNPC = enemy;
            enemy.myAI.StartAI();
        }

    }

    /// <summary>
    /// Limpia los logs antiguos de jugador y enemigo.
    /// </summary>
    private void ClearCollections()
    {
        enemyLog.Clear();
        playerLog.Clear();
    }

    /// <summary>
    /// Cambia el layout del juego para volverse el que debe aparecer durante el comabte.
    /// </summary>
    private void ChangeLayout()
    {
        player.controller.NullCurrentDisplay();

        GameObject newCombat = Instantiate(combatLayout, contentContainer);

        playerUI.InstantiateMyStuff(newCombat.GetComponent<RectTransform>());
        enemyUI.InstantiateMyStuff(newCombat.GetComponent<RectTransform>());
    }

    private IEnumerator UpdateTurns()
    {
        while (GameState.Instance.CurrentState == GameState.GameStates.combat)
        {
			yield return new WaitForSecondsRealtime(pace);
            currentBattleTime -= pace;
            SetEnemyDescription();

            if (currentBattleTime <= 0)
            {
                currentBattleTime = 0;
                EndCombatByTime();
            }

            player.ChargeTurn();
            if (!vsPlayer)
            {
                enemy.ChargeBySecond();
            }
            
        }
    }

    /// <summary>
    /// Recibe y maneja el input del jugador durante este estado de combate.
    /// </summary>
    /// <param name="input"></param>
    public void ReceiveInput(string[] input, HabilitiesTextInput habilitiesInput)
    {
        if (inInventory)
        {
            switch (input[0])
            {
                case "<":
                    if (inventoryManager.DisplayInventory(this, inventoryPage - 1))
                    {
                        inventoryPage -= 1;
                    }
                    break;

                case ">":
                    if (inventoryManager.DisplayInventory(this, inventoryPage + 1))
                    {
                        inventoryPage += 1;
                    }
                    break;

                case "s":
                    ExitInventory();
                    break;

                default:
                    UpdatePlayerLog("-");
                    break;
            }
        }

        if (player.currentTurn < player.MaxTurn && !inInventory)
        {
            UpdatePlayerLog("Aún no es tu turno.");
            return;
        }

        if (input.Length >= 1 && !inInventory)
        {
            if (input.Length == 1)
            {
                switch (input[0])
                {
                    case "0":
                        if (vsPlayer)
                        {

                        }
                        else
                        {
                            player.AttackInCombat(enemy);
                        }
                        break;

                    case "1":
                        EnterInInventory();
                        break;

                    case "2":
                        player.RepositionInCombat();
                        break;

                    case "3":
                        if (vsPlayer)
                        {

                        }
                        else
                        {
                            player.TryToEscape(enemy);
                        }
                        break;

                    default:
                        UpdatePlayerLog("-");
                        break;
                }
            }
            else
            {
                if (!vsPlayer)
                {
                    habilitiesInput.CheckHabilitiesInputDuringCombat(input, player.controller, enemy);
                }
                UpdatePlayerTurn();
            }
        }
        else if (inInventory)
        {
            switch (input[0])
            {
                case "0":
                    
                    break;

                case "1":
                    
                    break;

                case "2":
                    
                    break;

                default:
                    UpdatePlayerLog("-");
                    break;
            }
        }
    }

    #region Jugador en combate

    /// <summary>
    /// Inicializa GUI del jugador.
    /// </summary>
    private void InitializePlayer()
    {
        player.StartCombat();
		playerUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color = 
			playerColorGradient.Evaluate(player.currentHealth / player.MaxHealth);

		playerUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
			playerTurnColor.Evaluate(player.currentTurn / player.MaxTurn);

		playerUI.lifeText.color = playerTurnColor.Evaluate(player.currentTurn / player.MaxTurn);

		ChangePlayerState();

        UpdatePlayerLife();

        UpdatePlayerTurn();

        UpdatePlayerWill();

        SetPlayerHabilities();

        SetPlayerOptions();

        playerUI.logText.text = ("");

    }

    /// <summary>
    /// Cambia el tituloo del jugador para reflejar su CharacterEffectiveState actual.
    /// </summary>
    public void ChangePlayerState ()
    {
        string state = "";

		playerText.updateText();

        if (player.currentState != player.defaultState)
        {
            state = " <" + TextConverter.MakeFirstLetterUpper(player.currentState.stateName) + ">";
            UpdatePlayerLog("¡Has entrado en " + TextConverter.MakeFirstLetterUpper(player.currentState.stateName) 
                + "!");
        }

        playerUI.title.text = "<b>" + TextConverter.MakeFirstLetterUpper(player.playerName) + "</b>" + "\n" +
            TextConverter.MakeFirstLetterUpper(player.characteristics.playerRace.raceName) + " " +
            TextConverter.MakeFirstLetterUpper(player.characteristics.playerJob.jobName) +
            state;
    }

	/// <summary>
	/// Cambia la GUI del jugador para mostrar la vida actual.
	/// </summary>
	/// 

    public void UpdatePlayerLife()
    {
		float t = player.currentHealth / player.MaxHealth;
		Color oldColor = playerUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;


		playerUI.lifeSlider.maxValue = player.MaxHealth;
        playerUI.lifeSlider.value = player.currentHealth;
		playerUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color = 
			Color.Lerp(playerColorGradient.Evaluate(t), oldColor, t);


		playerUI.lifeText.text = ((player.currentHealth / player.MaxHealth) * 100).ToString("0") + "%";

		playerUI.lifeText.color = Color.Lerp(playerColorGradient.Evaluate(t), oldColor, t); ;

		playerText.updateText();

	}

    /// <summary>
    /// Cambia la GUI del jugador para mostrar su carga de turno actual.
    /// </summary>
    public void UpdatePlayerTurn()
    {
		float t = player.currentTurn / player.MaxTurn;
		Color oldColor = playerUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;

        playerUI.turnSlider.maxValue = player.MaxTurn;
        playerUI.turnSlider.value = player.currentTurn;
		playerUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
			Color.Lerp(playerTurnColor.Evaluate(t), oldColor, t);

    }

    /// <summary>
    /// Cambia la GUI del jugador para mostrar su voluntad actual.
    /// </summary>
    public void UpdatePlayerWill()
    {
        playerUI.willText.text = "V[" + player.currentWill + "/" + player.MaxWill + "]";
    }

    /// <summary>
    /// Muestra las habilidades disponibles del jugador.
    /// </summary>
    public void SetPlayerHabilities()
    {
        if (inInventory)
        {
            return;
        }

        habilitiesText.Clear();

        habilitiesText.Add("[0] Atacar");
        for (int i = 0; i < player.characteristics.playerJob.jobHabilities.Count; i++)
        {
            Hability currentHability = player.characteristics.playerJob.jobHabilities[i];

            if (currentHability.isAvailable)
            {
                habilitiesText.Add("[0." +
                    currentHability.jobIdentifier + "." +
                    currentHability.habilityID + "] " +
                    TextConverter.MakeFirstLetterUpper(currentHability.habilityName));
            }
            else
            {
                habilitiesText.Add("<color=#696969>" + 
                    "[0." +
                    currentHability.jobIdentifier + "." +
                    currentHability.habilityID + "] " +
                    TextConverter.MakeFirstLetterUpper(currentHability.habilityName) +
                    ". . . . . . "+
                    "</color>");
            }
        }

        playerUI.habilitiesText.text = string.Join("\n", habilitiesText.ToArray());
    }

    /// <summary>
    /// Pone un texto alterno en el lugar donde irían las habilidades del jugador.
    /// </summary>
    public void SetPlayerHabilities(string newText)
    {
        playerUI.habilitiesText.text = newText;
    }

    /// <summary>
    /// Cambia la GUI del jugador para mostrar sus opciones actuales.
    /// </summary>
    public void SetPlayerOptions()
    {
        if (inInventory)
        {
            return;
        }

        inventoryPage = 1;

        if (vsPlayer)
        {

        }
        else
        {

            playerUI.optionsText.text = "[1] Inventario \n" +
                "[2] Reposicionamiento \n" +
                "[3] Escapar (" + player.characteristics.other.EscapeProbability(player, enemy).ToString("0") + "%)";
        }
    }

    public void EnterInInventory()
    {
        inInventory = true;
        UpdatePlayerLog("Abres el inventario");
        player.currentTurn -= player.MaxTurn * 0.5f;
        inventoryManager.DisplayInventory(this, inventoryPage);
    }

    public void ExitInventory()
    {
        inInventory = false;
        UpdatePlayerLog("Sales del inventario");
        SetPlayerOptions();
        SetPlayerHabilities();
    }

    public void SetPlayerInventoryOptions(string newText)
    {
        playerUI.optionsText.text = newText;
    }

    /// <summary>
    /// Actualiza el log actual del jugador, mostrando eventos que él realice o le sucedan.
    /// </summary>
    public void UpdatePlayerLog(string newLog)
    {
        playerLog.Enqueue(newLog);

        if (playerLog.Count > 3)
        {
            playerLog.Dequeue();
        }

        playerUI.logText.text = string.Join("\n", playerLog.ToArray());

        if (vsPlayer)
        {

        }
        else
        {
            UpdateEnemyLogOnly("-");
        }
    }

    /// <summary>
    /// Actualiza el log actual del jugador sin enviarle un mensaje extra al log del enemigo.
    /// </summary>
    /// <param name="newLog"></param>
    public void UpdatePlayerLogOnly(string newLog)
    {
        playerLog.Enqueue(newLog);

        if (playerLog.Count > 3)
        {
            playerLog.Dequeue();
        }

        playerUI.logText.text = string.Join("\n", playerLog.ToArray());
    }

    #endregion

    #region Enemy NPC

    /// <summary>
    /// Inicializa GUI del enemigo.
    /// </summary>
    private void InitializeEnemy()
    {
        enemy.StartCombat(this);
		enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
		enemyColorGradient.Evaluate(enemy.currentHealth / enemy.maxHealth);

		enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
		enemyTurnColor.Evaluate(enemy.currentTurn / enemy.maxTurn);

		enemyUI.lifeText.color = enemyColorGradient.Evaluate(enemy.currentHealth / enemy.maxHealth);

		ChangeEnemyState();

        UpdateEnemyLife();

        UpdateEnemyTurn();

        SetEnemyDescription();

        enemyUI.logText.text = ("");
      
    }

    /// <summary>
    /// Cambia la GUI del npc enemigo para reflejar su CharacterEffectiveState actual.
    /// </summary>
    public void ChangeEnemyState()
    {
        string state = "";

        if (enemy.currentState != enemy.myTemplate.defaultState)
        {
            state = " <" + TextConverter.MakeFirstLetterUpper(enemy.currentState.stateName) + ">";
            UpdatePlayerLog("El " + TextConverter.MakeFirstLetterUpper(enemy.myTemplate.npcName) +
               " ha entrado en " + TextConverter.MakeFirstLetterUpper(enemy.currentState.stateName)
                + "!");
        }

        enemyUI.title.text = "<b>" + TextConverter.MakeFirstLetterUpper(enemy.myTemplate.npcName) + "</b>" + "\n" +
              TextConverter.MakeFirstLetterUpper(enemy.myTemplate.npcRace.raceName) + " " +
            TextConverter.MakeFirstLetterUpper(enemy.myTemplate.npcJob.jobName) +
            state;

        enemy.myTemplate.npcRace.ActivatePassiveHability(enemy);
    }

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su vida actual.
    /// </summary>
    public void UpdateEnemyLife()
    {
		float t = enemy.currentHealth / enemy.maxHealth;
		Color oldColor = enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;

		enemyUI.lifeSlider.maxValue = enemy.myTemplate.MaxHealth;
        enemyUI.lifeSlider.value = enemy.currentHealth;
        enemyUI.lifeText.text = ((enemy.currentHealth / enemy.myTemplate.MaxHealth) * 100).ToString("0") + "%";

		enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
			Color.Lerp(enemyColorGradient.Evaluate(t), oldColor, t);

		enemyUI.lifeText.color = Color.Lerp(enemyColorGradient.Evaluate(t), oldColor, t);
	}

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su carga de turno actual.
    /// </summary>
    public void UpdateEnemyTurn()
    {
		float t = enemy.currentTurn / enemy.maxTurn;
		Color oldColor = enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;

		enemyUI.turnSlider.maxValue = enemy.myTemplate.MaxTurn;
        enemyUI.turnSlider.value = enemy.currentTurn;
		enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
			Color.Lerp(enemyTurnColor.Evaluate(t), oldColor, t);
	}

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su descipción detallada.
    /// </summary>
    public void SetEnemyDescription()
    {
        enemyUI.descriptionText.text = "Deshabilitado en: " +  (currentBattleTime / 60).ToString("0.##") + "\n" +
            enemy.myTemplate.npcDetailedDescription;
    }

    /// <summary>
    /// Actualiza el Log del enemigo mostrando sus acciones y cosas que recibe. Envia un mensaje "-" al log del jugador.
    /// </summary>
    public void UpdateEnemyLog(string newLog)
    {
        enemyLog.Enqueue(newLog);

        if (enemyLog.Count > 3)
        {
            enemyLog.Dequeue();
        }

        enemyUI.logText.text = string.Join("\n", enemyLog.ToArray());

        UpdatePlayerLogOnly("-");
    }

    /// <summary>
    /// Actualiza el Log del enemigo mostrando acciones y consecuencias de acciones. No envía mensajes al log del jugador.
    /// </summary>
    public void UpdateEnemyLogOnly(string newLog)
    {
        enemyLog.Enqueue(newLog);

        if (enemyLog.Count > 3)
        {
            enemyLog.Dequeue();
        }

        enemyUI.logText.text = string.Join("\n", enemyLog.ToArray());
    }



    private void EndCombatByTime()
    {
        UpdatePlayerLog("¡Se acabó el tiempo!");

        if (player.currentHealth >= enemy.currentHealth)
        {
            EndCombat(enemy);
        }
        else
        {
            EndCombat(player);
        }
    }

    #endregion


    #region Enemy Jugador

    /// <summary>
    /// Inicializa GUI del enemigo.
    /// </summary>
    private void InitializeEnemyPlayer()
    {
        enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
        enemyColorGradient.Evaluate(enemyPlayer.currentHealth / enemyPlayer.enemyStats.maxHealth);

        enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
        enemyTurnColor.Evaluate(enemyPlayer.enemyStats.currentTurn / enemyPlayer.enemyStats.maxTurn);

        enemyUI.lifeText.color = enemyColorGradient.Evaluate(enemyPlayer.currentHealth / enemyPlayer.enemyStats.maxHealth);

        ChangeEnemyPlayerState();

        UpdateEnemyPlayerLife();

        UpdateEnemyPlayerTurn();

        SetEnemyPlayerDescription();

        enemyUI.logText.text = ("");

    }

    /// <summary>
    /// Cambia la GUI del npc enemigo para reflejar su CharacterEffectiveState actual.
    /// </summary>
    public void ChangeEnemyPlayerState()
    {
        string state = "";

        if (enemyPlayer.playerState.GetType() != typeof(NormalState))
        {
            state = " <" + TextConverter.MakeFirstLetterUpper(enemyPlayer.playerState.stateName) + ">";
            UpdatePlayerLog(enemyPlayer.playerName +
               " ha entrado en " + TextConverter.MakeFirstLetterUpper(enemyPlayer.playerState.stateName)
                + "!");
        }

        enemyUI.title.text = "<b>" + enemyPlayer.playerName + "</b>" + "\n" +
              TextConverter.MakeFirstLetterUpper(enemyPlayer.playerRace.raceName) + " " +
            TextConverter.MakeFirstLetterUpper(enemyPlayer.playerJob.jobName) +
            state;
    }

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su vida actual.
    /// </summary>
    public void UpdateEnemyPlayerLife()
    {
        float t = enemyPlayer.currentHealth / enemyPlayer.enemyStats.maxHealth;
        Color oldColor = enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;

        enemyUI.lifeSlider.maxValue = enemyPlayer.enemyStats.maxHealth;
        enemyUI.lifeSlider.value = enemyPlayer.currentHealth;
        enemyUI.lifeText.text = ((enemyPlayer.currentHealth / enemyPlayer.enemyStats.maxHealth) * 100).ToString("0") + "%";

        enemyUI.lifeSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
            Color.Lerp(enemyColorGradient.Evaluate(t), oldColor, t);

        enemyUI.lifeText.color = Color.Lerp(enemyColorGradient.Evaluate(t), oldColor, t);
    }

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su carga de turno actual.
    /// </summary>
    public void UpdateEnemyPlayerTurn()
    {
        float t = enemyPlayer.enemyStats.currentTurn / enemyPlayer.enemyStats.maxTurn;
        Color oldColor = enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color;

        enemyUI.turnSlider.maxValue = enemyPlayer.enemyStats.maxTurn;
        enemyUI.turnSlider.value = enemyPlayer.enemyStats.currentTurn;
        enemyUI.turnSlider.fillRect.GetComponent<UnityEngine.UI.Image>().color =
            Color.Lerp(enemyTurnColor.Evaluate(t), oldColor, t);
    }

    /// <summary>
    /// Cambia la GUI del npc enemigo mostrando su descipción detallada.
    /// </summary>
    public void SetEnemyPlayerDescription()
    {
        enemyUI.descriptionText.text = "Deshabilitado en: " + (currentBattleTime / 60).ToString("0.##") + "\n" +
            "";
    }

    /// <summary>
    /// Actualiza el Log del enemigo mostrando sus acciones y cosas que recibe. Envia un mensaje "-" al log del jugador.
    /// </summary>
    public void UpdateEnemyPlayerLog(string newLog)
    {
        enemyLog.Enqueue(newLog);

        if (enemyLog.Count > 3)
        {
            enemyLog.Dequeue();
        }

        enemyUI.logText.text = string.Join("\n", enemyLog.ToArray());

        UpdatePlayerLogOnly("-");
    }

    /// <summary>
    /// Actualiza el Log del enemigo mostrando acciones y consecuencias de acciones. No envía mensajes al log del jugador.
    /// </summary>
    public void UpdateEnemyPlayerLogOnly(string newLog)
    {
        enemyLog.Enqueue(newLog);

        if (enemyLog.Count > 3)
        {
            enemyLog.Dequeue();
        }

        enemyUI.logText.text = string.Join("\n", enemyLog.ToArray());
    }


    #endregion

    #region finalizar combate

    /// <summary>
    /// Termina el combate con el Npc Enemigo como perdedor.
    /// </summary>
    public IEnumerator EndCombat(EnemyNPC loser)
    {
        EndAllCombat();
        yield return new WaitForSecondsRealtime(2);
        GameState.Instance.ChangeCurrentState(GameState.GameStates.exploration);
        ReturnToRoom("¡Ganaste!");
        WinLemons(50);
    }

    /// <summary>
    /// Termina el combate cuando el npc enemigo huye.
    /// </summary>
    public IEnumerator EndCombatByEscaping(EnemyNPC runner)
    {
        EndAllCombat();
        yield return new WaitForSecondsRealtime(2);
        GameState.Instance.ChangeCurrentState(GameState.GameStates.exploration);
        ReturnToRoom("¡El enemigo huyó!");
        WinLemons(10);
    }

    /// <summary>
    /// Termina el combate con el jugador como perdedor.
    /// </summary>
    public IEnumerator EndCombat(PlayerManager loser)
    {
        EndAllCombat();
        yield return new WaitForSecondsRealtime(2);
        GameState.Instance.ChangeCurrentState(GameState.GameStates.exploration);
        ReturnToRoom("¡Perdiste!");
    }

    /// <summary>
    /// Termina el combate cuando el jugador huye.
    /// </summary>
    public IEnumerator EndCombatByEscaping(PlayerManager runner)
    {
        EndAllCombat();
        yield return new WaitForSecondsRealtime(2);
        GameState.Instance.ChangeCurrentState(GameState.GameStates.exploration);
        ReturnToRoom("¡Huiste!");
    }

    /// <summary>
    /// Termina el estado del combate en todos sus sentidos.
    /// </summary>
    private void EndAllCombat()
    {
        if (!vsPlayer)
        {
            enemy.myAI.StopAI();
        }
        CancelInvoke();
        GameState.Instance.ChangeCurrentState(GameState.GameStates.none);
        player.controller.CreateNewDisplay();
    }


    private void WinLemons(int factor)
    {
        lemonsWon = (int)Random.Range(factor, factor * 1.5f);
        player.controller.itemHandler.inventoryManager.AddLemons(lemonsWon);
    }

    /// <summary>
    /// Devuelve el jugador a la habitación en la que estaba antes del combate.
    /// </summary>
    /// <param name="endMessage"></param>
    private void ReturnToRoom(string endMessage)
    {
        player.controller.NullCurrentDisplay();
        player.controller.LogStringWithReturn(" ");
        player.controller.LogStringWithReturn("Fin del combate.");
        if (lemonsWon > 0)
        {
            player.controller.LogStringWithReturn("¡Ganaste " + lemonsWon.ToString() + " Limones por la batalla!");
        }

        player.controller.LogStringWithReturn(player.controller.RefreshCurrentRoomDescription());
        player.controller.LogStringWithoutReturn(endMessage);
    }

    #endregion
}

Se puede ver el estado del Burndown Chart en: https://docs.google.com/spreadsheets/d/ ... sp=sharing
Image
Sebastián Lagoueyte Marín
000132622
Gestión de Calidad de Software
Ingeniería en Diseño de Entretenimiento Digital

Post Reply