< Summary

Class:DCL.Bots.BotsController
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BotsController/BotsController.cs
Covered lines:11
Uncovered lines:122
Coverable lines:133
Total lines:312
Line coverage:8.2% (11 of 133)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BotsController()0%110100%
EnsureGlobalSceneAndCatalog()0%30500%
BuildRandomizedCollectionsURL()0%12300%
PopulateCatalog(...)0%6002400%
InstantiateBotsAtWorldPos()0%56700%
InstantiateBotsAtCoords()0%30500%
InstantiateBot(...)0%12300%
RemoveBot(...)0%6200%
ClearBots()0%6200%
GetRandomizedWearablesSet()0%1101000%
UpdateEntityTransform(...)0%2100%
GetPBTransform(...)0%2100%
Log(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BotsController/BotsController.cs

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using DCL.Controllers;
 4using DCL.Interface;
 5using DCL.Models;
 6using DCL.Helpers;
 7using Google.Protobuf;
 8using UnityEngine;
 9using DCL.Configuration;
 10using Random = UnityEngine.Random;
 11
 12namespace DCL.Bots
 13{
 14    /// <summary>
 15    /// Bots Tool: BotsController
 16    ///
 17    /// Used to spawn bots/avatarShapes for debugging and profiling purposes.
 18    /// </summary>
 19    public class BotsController : IBotsController
 20    {
 21        private ParcelScene globalScene;
 53122        private List<string> randomizedCollections = new List<string>();
 53123        private List<string> instantiatedBots = new List<string>();
 53124        private List<string> eyesWearableIds = new List<string>();
 53125        private List<string> eyebrowsWearableIds = new List<string>();
 53126        private List<string> mouthWearableIds = new List<string>();
 53127        private List<string> hairWearableIds = new List<string>();
 53128        private List<string> facialWearableIds = new List<string>();
 53129        private List<string> upperBodyWearableIds = new List<string>();
 53130        private List<string> lowerBodyWearableIds = new List<string>();
 53131        private List<string> feetWearableIds = new List<string>();
 53132        private List<string> bodyshapeWearableIds = new List<string>();
 33
 34        /// <summary>
 35        /// Makes sure the Catalogue with all the wearables has already been loaded, otherwise it loads it
 36        /// </summary>
 37        private IEnumerator EnsureGlobalSceneAndCatalog()
 38        {
 039            if (globalScene != null)
 040                yield break;
 41
 042            globalScene = Environment.i.world.state.loadedScenes[Environment.i.world.state.globalSceneIds[0]] as ParcelS
 43
 044            CatalogController.wearableCatalog.Clear();
 45
 046            yield return WearablesFetchingHelper.GetRandomCollections(20, true, randomizedCollections);
 47
 048            List<WearableItem> wearableItems = new List<WearableItem>();
 049            yield return WearablesFetchingHelper.GetWearableItems(BuildRandomizedCollectionsURL(), wearableItems);
 50
 051            PopulateCatalog(wearableItems);
 052        }
 53
 54        string BuildRandomizedCollectionsURL()
 55        {
 056            if (randomizedCollections.Count == 0)
 057                return null;
 58
 059            string finalUrl = WearablesFetchingHelper.WEARABLES_FETCH_URL;
 60
 061            finalUrl += "collectionId=" + randomizedCollections[0];
 062            for (int i = 1; i < randomizedCollections.Count; i++)
 63            {
 064                finalUrl += "&collectionId=" + randomizedCollections[i];
 65            }
 66
 067            return finalUrl;
 68        }
 69
 70        /// <summary>
 71        /// Populates the catalogue and internal avatar-part divided collections for optimized randomization
 72        /// </summary>
 73        /// <param name="newWearables">The list of WearableItem objects to be added to the catalog</param>
 74        private void PopulateCatalog(List<WearableItem> newWearables)
 75        {
 076            foreach (var wearableItem in newWearables)
 77            {
 078                switch (wearableItem.data.category)
 79                {
 80                    case WearableLiterals.Categories.EYES:
 081                        eyesWearableIds.Add(wearableItem.id);
 082                        break;
 83                    case WearableLiterals.Categories.EYEBROWS:
 084                        eyebrowsWearableIds.Add(wearableItem.id);
 085                        break;
 86                    case WearableLiterals.Categories.MOUTH:
 087                        mouthWearableIds.Add(wearableItem.id);
 088                        break;
 89                    case WearableLiterals.Categories.FEET:
 090                        feetWearableIds.Add(wearableItem.id);
 091                        break;
 92                    case WearableLiterals.Categories.HAIR:
 093                        hairWearableIds.Add(wearableItem.id);
 094                        break;
 95                    case WearableLiterals.Categories.FACIAL:
 096                        facialWearableIds.Add(wearableItem.id);
 097                        break;
 98                    case WearableLiterals.Categories.LOWER_BODY:
 099                        lowerBodyWearableIds.Add(wearableItem.id);
 0100                        break;
 101                    case WearableLiterals.Categories.UPPER_BODY:
 0102                        upperBodyWearableIds.Add(wearableItem.id);
 0103                        break;
 104                    case WearableLiterals.Categories.BODY_SHAPE:
 0105                        bodyshapeWearableIds.Add(wearableItem.id);
 106                        break;
 107                }
 108            }
 109
 0110            CatalogController.i.AddWearablesToCatalog(newWearables);
 0111        }
 112
 113        /// <summary>
 114        /// Instantiates bots using the config file param values. It defaults some uninitialized values using the player
 115        /// </summary>
 116        /// <param name="config">The config file to be used</param>
 117        public IEnumerator InstantiateBotsAtWorldPos(WorldPosInstantiationConfig config)
 118        {
 0119            yield return EnsureGlobalSceneAndCatalog();
 120
 0121            if (config.xPos == EnvironmentSettings.UNINITIALIZED_FLOAT)
 122            {
 0123                Log($"X Position value wasn't provided... using player's current X Position.");
 0124                config.xPos = DCLCharacterController.i.characterPosition.unityPosition.x;
 125            }
 126
 0127            if (config.yPos == EnvironmentSettings.UNINITIALIZED_FLOAT)
 128            {
 0129                Log($"Y Position value wasn't provided... using player's current Y Position.");
 0130                config.yPos = DCLCharacterController.i.characterPosition.unityPosition.y;
 131            }
 132
 0133            if (config.zPos == EnvironmentSettings.UNINITIALIZED_FLOAT)
 134            {
 0135                Log($"Z Position value wasn't provided... using player's current Z Position.");
 0136                config.zPos = DCLCharacterController.i.characterPosition.unityPosition.z;
 137            }
 138
 0139            Log($"Instantiating {config.amount} randomized avatars inside a {config.areaWidth}x{config.areaDepth} area p
 140
 0141            Vector3 randomizedAreaPosition = new Vector3();
 0142            for (int i = 0; i < config.amount; i++)
 143            {
 0144                randomizedAreaPosition.Set(Random.Range(config.xPos, config.xPos + config.areaWidth), config.yPos, Rando
 0145                InstantiateBot(randomizedAreaPosition);
 146            }
 147
 0148            Log($"Finished instantiating {config.amount} avatars. They may take some time to appear while their wearable
 0149        }
 150
 151        /// <summary>
 152        /// Instantiates bots using the config file param values. It defaults some uninitialized values using the player
 153        /// </summary>
 154        /// <param name="config">The config file to be used</param>
 155        public IEnumerator InstantiateBotsAtCoords(CoordsInstantiationConfig config)
 156        {
 0157            if (config.xCoord == EnvironmentSettings.UNINITIALIZED_FLOAT)
 158            {
 0159                Log($"X Coordinate value wasn't provided... using player's current scene base X coordinate.");
 0160                config.xCoord = Mathf.Floor(DCLCharacterController.i.characterPosition.worldPosition.x / ParcelSettings.
 161            }
 162
 0163            if (config.yCoord == EnvironmentSettings.UNINITIALIZED_FLOAT)
 164            {
 0165                Log($"Y Coordinate value wasn't provided... using player's current scene base Y coordinate.");
 0166                config.yCoord = Mathf.Floor(DCLCharacterController.i.characterPosition.worldPosition.z / ParcelSettings.
 167            }
 168
 0169            var worldPosConfig = new WorldPosInstantiationConfig()
 170            {
 171                amount = config.amount,
 172                xPos = config.xCoord * ParcelSettings.PARCEL_SIZE,
 173                yPos = DCLCharacterController.i.characterPosition.unityPosition.y - DCLCharacterController.i.characterCo
 174                zPos = config.yCoord * ParcelSettings.PARCEL_SIZE,
 175                areaWidth = config.areaWidth,
 176                areaDepth = config.areaDepth
 177            };
 178
 0179            Log($"Instantiating {config.amount} randomized avatars inside a {config.areaWidth}x{config.areaDepth} area p
 180
 0181            yield return InstantiateBotsAtWorldPos(worldPosConfig);
 0182        }
 183
 184        /// <summary>
 185        /// Instantiates an entity with an AvatarShape component, with randomized wearables, at the given position
 186        /// </summary>
 187        /// <param name="position">The world position of the randomized bot</param>
 188        void InstantiateBot(Vector3 position)
 189        {
 0190            string entityId = "BOT-" + instantiatedBots.Count;
 191
 0192            AvatarModel avatarModel = new AvatarModel()
 193            {
 194                name = entityId,
 195                hairColor = Color.white,
 196                eyeColor = Color.white,
 197                skinColor = Color.white,
 198                bodyShape = Random.Range(0, 2) == 0 ? WearableLiterals.BodyShapes.FEMALE : WearableLiterals.BodyShapes.M
 199                wearables = GetRandomizedWearablesSet()
 200            };
 201
 0202            globalScene.CreateEntity(entityId);
 0203            globalScene.EntityComponentCreateOrUpdateWithModel(entityId, CLASS_ID_COMPONENT.AVATAR_SHAPE, avatarModel);
 0204            UpdateEntityTransform(globalScene, entityId, position, Quaternion.identity, Vector3.one);
 205
 0206            instantiatedBots.Add(entityId);
 0207        }
 208
 209        /// <summary>
 210        ///Removes an instantiated bot. Every bot has its ID as its avatar name.
 211        /// </summary>
 212        /// <param name="targetEntityId">The target bot ID. Every bot has its ID as its avatar name.</param>
 213        public void RemoveBot(string targetEntityId)
 214        {
 0215            if (!instantiatedBots.Contains(targetEntityId))
 0216                return;
 217
 0218            globalScene.RemoveEntity(targetEntityId);
 0219            instantiatedBots.Remove(targetEntityId);
 0220        }
 221
 222        /// <summary>
 223        /// Removes all instantiated bots.
 224        /// </summary>
 225        public void ClearBots()
 226        {
 0227            while (instantiatedBots.Count > 0)
 228            {
 0229                RemoveBot(instantiatedBots[0]);
 230            }
 0231        }
 232
 233        /// <summary>
 234        /// Randomizes a whole avatar set of wearables and returns a list with all the wearable IDs
 235        /// </summary>
 236        List<string> GetRandomizedWearablesSet()
 237        {
 0238            var wearablesSet = new List<string>();
 239
 0240            if (eyesWearableIds.Count > 0)
 0241                wearablesSet.Add(eyesWearableIds[Random.Range(0, eyesWearableIds.Count)]);
 242
 0243            if (eyebrowsWearableIds.Count > 0)
 0244                wearablesSet.Add(eyebrowsWearableIds[Random.Range(0, eyebrowsWearableIds.Count)]);
 245
 0246            if (mouthWearableIds.Count > 0)
 0247                wearablesSet.Add(mouthWearableIds[Random.Range(0, mouthWearableIds.Count)]);
 248
 0249            if (hairWearableIds.Count > 0)
 0250                wearablesSet.Add(hairWearableIds[Random.Range(0, hairWearableIds.Count)]);
 251
 0252            if (facialWearableIds.Count > 0)
 0253                wearablesSet.Add(facialWearableIds[Random.Range(0, facialWearableIds.Count)]);
 254
 0255            if (upperBodyWearableIds.Count > 0)
 0256                wearablesSet.Add(upperBodyWearableIds[Random.Range(0, upperBodyWearableIds.Count)]);
 257
 0258            if (lowerBodyWearableIds.Count > 0)
 0259                wearablesSet.Add(lowerBodyWearableIds[Random.Range(0, lowerBodyWearableIds.Count)]);
 260
 0261            if (feetWearableIds.Count > 0)
 0262                wearablesSet.Add(feetWearableIds[Random.Range(0, feetWearableIds.Count)]);
 263
 0264            if (bodyshapeWearableIds.Count > 0)
 0265                wearablesSet.Add(bodyshapeWearableIds[Random.Range(0, bodyshapeWearableIds.Count)]);
 266
 0267            return wearablesSet;
 268        }
 269
 270        void UpdateEntityTransform(ParcelScene scene, string entityId, Vector3 position, Quaternion rotation, Vector3 sc
 271        {
 0272            PB_Transform pB_Transform = GetPBTransform(position, rotation, scale);
 0273            scene.EntityComponentCreateOrUpdate(
 274                entityId,
 275                CLASS_ID_COMPONENT.TRANSFORM,
 276                System.Convert.ToBase64String(pB_Transform.ToByteArray())
 277            );
 0278        }
 279
 280        public PB_Transform GetPBTransform(Vector3 position, Quaternion rotation, Vector3 scale)
 281        {
 0282            PB_Transform pbTranf = new PB_Transform();
 0283            pbTranf.Position = new PB_Vector3();
 0284            pbTranf.Position.X = position.x;
 0285            pbTranf.Position.Y = position.y;
 0286            pbTranf.Position.Z = position.z;
 0287            pbTranf.Rotation = new PB_Quaternion();
 0288            pbTranf.Rotation.X = rotation.x;
 0289            pbTranf.Rotation.Y = rotation.y;
 0290            pbTranf.Rotation.Z = rotation.z;
 0291            pbTranf.Rotation.W = rotation.w;
 0292            pbTranf.Scale = new PB_Vector3();
 0293            pbTranf.Scale.X = scale.x;
 0294            pbTranf.Scale.Y = scale.y;
 0295            pbTranf.Scale.Z = scale.z;
 0296            return pbTranf;
 297        }
 298
 299        /// <summary>
 300        /// Logs the tool messages in console regardless of the "Debug.unityLogger.logEnabled" value.
 301        /// </summary>
 302        private void Log(string message)
 303        {
 0304            bool originalLogEnabled = Debug.unityLogger.logEnabled;
 0305            Debug.unityLogger.logEnabled = true;
 306
 0307            Debug.Log("BotsController - " + message);
 308
 0309            Debug.unityLogger.logEnabled = originalLogEnabled;
 0310        }
 311    }
 312}