diff --git a/Assets/Prefabs/Traps/FloatingOnWater.prefab b/Assets/Prefabs/Traps/FloatingOnWater.prefab index 074cb67..0068f33 100644 --- a/Assets/Prefabs/Traps/FloatingOnWater.prefab +++ b/Assets/Prefabs/Traps/FloatingOnWater.prefab @@ -63,6 +63,7 @@ Transform: m_Children: - {fileID: 8460854531351183923} - {fileID: 7432853164086773831} + - {fileID: 8523851343712122817} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -281,6 +282,11 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 3074371251208262866, guid: 2cb12feb62290af4ab4634e7ac62b956, + type: 3} + propertyPath: m_Center.y + value: -1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 2cb12feb62290af4ab4634e7ac62b956, type: 3} --- !u!4 &7432853164086773831 stripped @@ -364,3 +370,80 @@ Transform: type: 3} m_PrefabInstance: {fileID: 7437530684430511324} m_PrefabAsset: {fileID: 0} +--- !u!1001 &8528138131228372493 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 7729055451593449897} + m_Modifications: + - target: {fileID: 1133981147424236, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_Name + value: Cube_Underwater + objectReference: {fileID: 0} + - target: {fileID: 1133981147424236, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalPosition.y + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6060536008043278799, guid: e5fac62723232674aa487c9073f1ca07, + type: 3} + propertyPath: is_Walkable + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6060536008043278799, guid: e5fac62723232674aa487c9073f1ca07, + type: 3} + propertyPath: isWater + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: e5fac62723232674aa487c9073f1ca07, type: 3} +--- !u!4 &8523851343712122817 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 4721099042904524, guid: e5fac62723232674aa487c9073f1ca07, + type: 3} + m_PrefabInstance: {fileID: 8528138131228372493} + m_PrefabAsset: {fileID: 0} diff --git a/Assets/Prefabs/Traps/InGroundTrap.prefab b/Assets/Prefabs/Traps/InGroundTrap.prefab index eadbde3..6758fb6 100644 --- a/Assets/Prefabs/Traps/InGroundTrap.prefab +++ b/Assets/Prefabs/Traps/InGroundTrap.prefab @@ -107,6 +107,16 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 6060536008043278799, guid: e5fac62723232674aa487c9073f1ca07, + type: 3} + propertyPath: is_Walkable + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6060536008043278799, guid: e5fac62723232674aa487c9073f1ca07, + type: 3} + propertyPath: isPit + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e5fac62723232674aa487c9073f1ca07, type: 3} --- !u!4 &1068379521905336273 stripped diff --git a/Assets/Scenes/GameMode Scenes/RacetrackGameMode.unity b/Assets/Scenes/GameMode Scenes/RacetrackGameMode.unity index dea66ae..276b665 100644 --- a/Assets/Scenes/GameMode Scenes/RacetrackGameMode.unity +++ b/Assets/Scenes/GameMode Scenes/RacetrackGameMode.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2532e240363c6624567e7f47cd6645a78f97e4c79dbc57ccb226fff8a749f9f -size 25946 +oid sha256:39df638172c07d5d3aaf8f76028a3f49445d7a18bb3e18d8956797a2587d6e63 +size 25929 diff --git a/Assets/Scenes/RaceTrack 4-player alpha.unity b/Assets/Scenes/RaceTrack 4-player alpha.unity index 706fcc4..521fb9e 100644 --- a/Assets/Scenes/RaceTrack 4-player alpha.unity +++ b/Assets/Scenes/RaceTrack 4-player alpha.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2fcdafd3ea73e1e59c963afedb10dafee204cac96e5a3914fedd692e3d74a3b -size 2720958 +oid sha256:8a88996c6bfd31688f0b46e64f918125b639084deb91f199c306dda93b01aca4 +size 2624360 diff --git a/Assets/Scripts/Block.cs b/Assets/Scripts/Block.cs index cad973c..2729cc0 100644 --- a/Assets/Scripts/Block.cs +++ b/Assets/Scripts/Block.cs @@ -18,6 +18,12 @@ public class Block : MonoBehaviour [Tooltip("Can this type of block be walked on")] public bool is_Walkable = true; + [Tooltip("Is this block underwater?")] + public bool isWater = false; + + [Tooltip("Is this block at the bottom of a pit?")] + public bool isPit = false; + [Tooltip("Can this block be spawned on")] public bool isSpawnable = false; diff --git a/Assets/Scripts/Character.cs b/Assets/Scripts/Character.cs index ccf2dd7..df5ad74 100644 --- a/Assets/Scripts/Character.cs +++ b/Assets/Scripts/Character.cs @@ -11,6 +11,11 @@ public class Character : MonoBehaviour Animator characterAnimator; public bool isTuteLevel = false; + public bool inWater = false; //Am I in the water? + public bool inPit = false; //Did I fall into a pit? + public bool stuck = false; //Am I still stuck? + public bool justMoved = false; //Was the logic block I just executed a move command? + #region Inspector Fields [SerializeField] @@ -25,6 +30,9 @@ public class Character : MonoBehaviour public Inventory Inventory; public bool CloneInventoryOnStart = false; + [Tooltip("How many lives to start out with")] + public int lives = 5; + [SerializeField] [Tooltip("Character to display")] private string CharacterModel = "Bear"; @@ -262,6 +270,86 @@ public class Character : MonoBehaviour StartCoroutine(PushLeftCoroutine(transform, speed)); } + + public void respawnCharacter() + { + /* Will introduce more complex criteria for choosing where to respawn the player in future + * For now: if the square one back (x =- 1) from the pit is walkable and unoccupied, then put them there + * Otherwise, try the next square back, etc, until we find an available one + */ + + Block currentBlock = null; + //We start from the position of our pit, at ground level + Vector3 currentPos = new Vector3(this.transform.position.x, this.transform.position.y, this.transform.position.z); + + Debug.Log("Commencing respawn"); + + //Hardcoding the number of iterations for now for simplicity, should change this later + for (int i = 0; i < 100; i++) + { + //First we check one back + currentPos.x -= 1; + Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z); + if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here? + { + Debug.Log("Block exists"); + if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it? + { + Debug.Log("Block is walkable"); + //Don't yet have a check for whether it's occupied + break; //If it is, we stop here + } + } + + //If the block one back isn't an option, we check to the left and right + currentPos.z += 1; + Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z); + if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here? + { + Debug.Log("Block exists"); + if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it? + { + Debug.Log("Block is walkable"); + //Don't yet have a check for whether it's occupied + break; //If it is, we stop here + } + } + currentPos.z -= 2; + Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z); + if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here? + { + Debug.Log("Block exists"); + if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it? + { + Debug.Log("Block is walkable"); + //Don't yet have a check for whether it's occupied + break; //If it is, we stop here + } + } + + //If we've gotten this far and haven't found an available spot, we move back a row and try again + currentPos.z += 1; + } + + //Having found our target block, we move the character there + if (currentBlock != null) + { + this.transform.position = currentBlock.VisualPosition; + this.inPit = false; + this._currentBlock = currentBlock; + Debug.Log("Moved " + this.name + " to " + + this.transform.position.x + ", " + + this.transform.position.y + ", " + + this.transform.position.z + ", " + + " inPit = " + inPit); + } + else + { + Debug.Log("Failed to find anywhere to put " + this.name); + } + + } + /// /// Upon collision with a floating block, collect its /// Upon collision with the end portal, end of level diff --git a/Assets/Scripts/GameMode/ColorGameMode/ColorGameMode.cs b/Assets/Scripts/GameMode/ColorGameMode/ColorGameMode.cs index b7b0cb4..fccf28f 100644 --- a/Assets/Scripts/GameMode/ColorGameMode/ColorGameMode.cs +++ b/Assets/Scripts/GameMode/ColorGameMode/ColorGameMode.cs @@ -35,6 +35,17 @@ public class ColorGameMode : GameMode Debug.Log("Not scrolling"); } + //At the end of each round, any stuck players are freed to resume moving next round + foreach (PlayerData player in allPlayers) + { + player.character.stuck = false; + + if (player.character.inPit) + { + player.character.respawnCharacter(); + } + } + RoundCount++; } @@ -57,7 +68,24 @@ public class ColorGameMode : GameMode /// Block moved onto protected override void OnPlayerFinishedMove(Character character, ClientData client, Block currentBlock) { - //Commented out because we don't do this in the racetrack mode, but I don't know what would break if I just deleted this + handleFalling(character, client, currentBlock, character.justMoved); + + /*Debug.Log("Moved to square at " + currentBlock.transform.position.x + ", " + + currentBlock.transform.position.y + ", " + + currentBlock.transform.position.z); + + //If a character has fallen in the water or into a pit, we mark that fact, and they lose the rest of their turn + character.inWater = currentBlock.isWater; + character.inPit = currentBlock.isPit; + + if (character.inWater == true || character.inPit == true) + { + character.stuck = true; + } + + Debug.Log("inWater = " + character.inWater + ", inPit = " + character.inPit + ", stuck = " + character.stuck);*/ + + //Commented out because we don't do this in the racetrack mode /*ClientData OwnedClient; Material overlay = null; @@ -103,6 +131,12 @@ public class ColorGameMode : GameMode { foreach (PlayerData player in allPlayers) { + /* The justMoved variable is used to determine whether a player taking their turn in the water should become stuck + * (because they moved into/in the water), or not (because they're turning while remaining in the same square) + * It's not needed from move to move, so we clear it + */ + player.character.justMoved = false; + if (BlocksOwned.ContainsKey(player.client)) player.client.SceneScore = BlocksOwned[player.client].Count; else @@ -131,6 +165,26 @@ public class ColorGameMode : GameMode return false; } + private void handleFalling(Character character, ClientData client, Block currentBlock, bool didMove) + { + //If a character has fallen in the water or into a pit, we mark that fact, and they lose the rest of their turn + character.inWater = currentBlock.isWater; + character.inPit = currentBlock.isPit; + + if (didMove && (character.inWater || character.inPit)) + { + character.stuck = true; + } + + if (character.inPit) + { + character.lives -= 1; + } + + Debug.Log("inWater = " + character.inWater + ", inPit = " + character.inPit + ", stuck = " + character.stuck); + + } + private IEnumerator AnimateBlock(Material mat, float time) { diff --git a/Assets/Scripts/Logic/BlockReader.cs b/Assets/Scripts/Logic/BlockReader.cs index 157426a..f04e89f 100644 --- a/Assets/Scripts/Logic/BlockReader.cs +++ b/Assets/Scripts/Logic/BlockReader.cs @@ -58,6 +58,20 @@ public class BlockReader /// Returns false if other readers should wait for this one to run again public bool Read(Character character,float speedMultiplier, out float TotalAnimationTime) { + //If the character has become stuck, they forfeit their remaining moves - we skip directly to their end of their chain + if (character.stuck == true) + { + Debug.Log("Character is stuck! No moving!"); + TotalAnimationTime = 0; + //return true; + + currentBlockIndex = LogicChain.Count; + } + else + { + Debug.Log("Character is not stuck"); + } + //return that this is done if no more blocks left in chain if (LogicChain.Count <= currentBlockIndex) { diff --git a/Assets/Scripts/Logic/Blocks/Move.cs b/Assets/Scripts/Logic/Blocks/Move.cs index 496b7a2..fa47ec8 100644 --- a/Assets/Scripts/Logic/Blocks/Move.cs +++ b/Assets/Scripts/Logic/Blocks/Move.cs @@ -21,6 +21,7 @@ public class Move : LogicBlock /// Player to move protected override void BlockLogic(Character player, float animationTime) { + player.justMoved = true; player.Move(direction, animationTime); } diff --git a/Assets/Scripts/Traps/FloatingOnWater.cs b/Assets/Scripts/Traps/FloatingOnWater.cs index 381504f..019f28d 100644 --- a/Assets/Scripts/Traps/FloatingOnWater.cs +++ b/Assets/Scripts/Traps/FloatingOnWater.cs @@ -21,13 +21,23 @@ public class FloatingOnWater : MonoBehaviour } void OnTriggerEnter(Collider other) { + Debug.Log("OnTriggerEnter for water tile at " + + this.transform.position.x + ", " + + this.transform.position.y + ", " + + this.transform.position.z + ", " + + "other.gameObject.name = " + other.gameObject.name); for(int i = 0; i < Names.Count; i++) { + Debug.Log("Checking name: " + Names[i]); + if (other.gameObject.name == Names[i]) { + Debug.Log(Names[i] + " is in the water!"); characterInWater = true; charName = other.gameObject.name; } + + Debug.Log("characterInWater = " + characterInWater); } }