public CreepBody UpdateBody(JSONObject objIn, CreepBody bodyIn)
    {
        // this does not come in a list form like the orginal array
        //"body":{ "0":{ "type":"tough","hits":100,"boost":"XGHO2"},"1":{ "type":"tough","hits":100,"boost":"XGHO2"} }
        int totalBody = bodyIn.parts.Length;

        for (int i = 0; i < totalBody; i++)
        {
            if (objIn.HasField(i.ToString()))
            {
                if (objIn[i.ToString()].HasField("hits"))
                {
                    int newHits = 0;
                    objIn[i.ToString()].GetField(ref newHits, "hits");
                    active[i] = newHits > 0 ? true : false;
                    parts[i]  = active[i] ? objIn[i.ToString()]["type"].ToString().Replace("\"", "") : "empty";
                }
            }
        }
        return(bodyIn);
    }
        public void CreateParts(CreepBody bodyIn, GameObject lastRing)
        {
            // initialize variables
            if (bodyPart == null)
            {
                bodyPart = Resources.Load <GameObject>("bodyPart");
            }
            int totalParts = bodyIn.parts.Length;

            moveParts = 0;
            ringOut   = lastRing;
            body      = bodyIn;
            if (partGOs.Count <= 0)
            {
                partGOs = new Dictionary <string, GameObject>();
            }
            if (partNumbers.Count <= 0)
            {
                partNumbers = new Dictionary <string, int>();
            }
            // get total number of each part
            CountParts();
            int bottomParts = totalParts - moveParts;

            if (moveParts > 0)
            {
                float  currentPercent = moveParts * 0.02f;
                string nextPart       = "move";
                if (!partGOs.ContainsKey(nextPart))
                {
                    GameObject nextGO = Instantiate(bodyPart, ringOut.transform);
                    partGOs.Add(nextPart, nextGO);
                }
                Image _image = partGOs[nextPart].GetComponent <Image>();
                _image.fillAmount = currentPercent;
                _image.fillOrigin = 0;
                _image.color      = PartColor(nextPart);
                RectTransform _rect = partGOs[nextPart].GetComponent <RectTransform>();
                _rect.localEulerAngles = new Vector3(0, 0, 3.6f * moveParts);
                totalParts            -= partNumbers[nextPart];
                partNumbers.Remove(nextPart);
            }
            while (partNumbers.Count > 0)
            {
                float currentPercent = bottomParts * 0.02f;
                // rank largest to smallest
                string nextPart = MostParts();
                // add GO for parts largest to smallest
                if (!partGOs.ContainsKey(nextPart))
                {
                    GameObject nextGO = Instantiate(bodyPart, ringOut.transform);
                    partGOs.Add(nextPart, nextGO);
                }
                // largest is base, add smaller parts to outside
                Image _image = partGOs[nextPart].GetComponent <Image>();
                _image.fillAmount = currentPercent;
                _image.color      = PartColor(nextPart);
                _image.fillOrigin = 2;
                RectTransform _rect = partGOs[nextPart].GetComponent <RectTransform>();
                _rect.localEulerAngles = new Vector3(0, 0, 3.6f * bottomParts);
                totalParts            -= partNumbers[nextPart];
                bottomParts            = totalParts;
                partNumbers.Remove(nextPart);
            }
            // return GameObject
        }
    public void CreepData(JSONObject dataIn)
    {
        if (dataIn == null)
        {
            DeleteCreep(); return;
        }
        _id = dataIn["_id"] != null ? dataIn["_id"].ToString().Replace("\"", "") : _id;
        //user = dataIn["user"] != null ? dataIn["user"].ToString().Replace("\"", "") : _id;
        int x = dataIn["x"] != null?Int32.Parse(dataIn["x"].ToString()) : lastPosition.x;

        int y = dataIn["y"] != null?Int32.Parse(dataIn["y"].ToString()) : lastPosition.y;

        if (lastPosition == new Vector2Int(-100, -100))
        {
            lastPosition = new Vector2Int(x, -y + 50);
        }
        if (lastPosition.x != x || lastPosition.y != y)
        {
            moving        = true;
            newPosition   = lastPosition.y != y ? new Vector2Int(x, -y + 50) : new Vector2Int(x, y);
            moveStartTime = Time.time;
            int newDir = new Dir(lastPosition, newPosition).dir;
            StartCoroutine(TurnTo(newDir));
            v3lastPosition = new Vector3(lastPosition.x * 0.16f + 0.08f, lastPosition.y * 0.16f + 0.08f, -1f);
            v3newPosition  = new Vector3(newPosition.x * 0.16f + 0.08f, newPosition.y * 0.16f + 0.08f, -1f);
            moveDistance   = Vector3.Distance(v3lastPosition, v3newPosition);
        }
        if (dataIn["energy"] != null)
        {
            int e = Int32.Parse(dataIn["energy"].ToString());
            if ((energy == -1 && e == 0) || e != energy)
            {
                if (energyCapacity == 0 && dataIn["energyCapacity"])
                {
                    energyCapacity = Int32.Parse(dataIn["energyCapacity"].ToString());
                }
                SetEnergy(e);
            }
        }
        if (dataIn["name"] != null)
        {
            name = dataIn["name"].ToString().Replace("\"", "");
        }
        if (dataIn["hits"] != null)
        {
            hits = Int32.Parse(dataIn["hits"].ToString());
        }
        if (dataIn.HasField("user"))
        {
            dataIn.GetField(ref user, "user");
        }
        if ((user == "2" || user == "3") && creepTough != null)
        {
            Destroy(creepTough);
            creepTough = null;
        }
        if (dataIn.HasField("body"))
        {
            if (creepBody.parts.Length <= 0)
            {
                creepBody = new CreepBody(dataIn["body"]);
            }
            if (creepBody.parts.Length > 0)
            {
                maxHits = creepBody.parts.Length * 100;
            }
            if (creepParts == null)
            {
                creepParts = transform.GetChild(2).gameObject;
            }

            //creepParts.TryGetComponent<PartMaker>(out pM);
            if (pM == null && !(user == "2" || user == "3"))
            {
                pM = creepParts.AddComponent <PartMaker>();
                pM.CreateParts(creepBody, creepParts);
            }
        }
        if (dataIn.HasField("actionLog"))
        {
            //"attacked":null,"healed":null,"attack":null,"rangedAttack":null,"rangedMassAttack":null,"rangedHeal":null,"harvest":{"x":33,"y":14},"heal":null,"repair":null,"build":null,"say":null,"upgradeController":null,"reserveController":null
            var actionLog = dataIn.GetField("actionLog");
            foreach (var action in actionLog.keys)
            {
                if (actionLog[action].type == JSONObject.Type.NULL)
                {
                    if (lastAction == action)
                    {
                        lastAction = null;
                    }
                    continue;
                }
                string actionType = Convert.ToString(action);
                int    tarX       = 0;
                int    tarY       = 0;
                if (actionLog[action].HasField("x"))
                {
                    actionLog[action].GetField(ref tarX, "x");
                }
                if (actionLog[action].HasField("y"))
                {
                    actionLog[action].GetField(ref tarY, "y");
                }
                tarY = 50 - tarY;
                Vector2Int targetPos = new Vector2Int(tarX, tarY);
                lastTarget = targetPos;
                if (actionType == "upgradeController" || actionType == "rangedHeal" || actionType == "rangedAttack" || actionType == "repair" || actionType == "build")
                {
                    lastAction = actionType;
                    ShootTarget(targetPos, actionType);
                }
                if (actionType == "attack" || actionType == "harvest" || actionType == "heal" || actionType == "reserveController")
                {
                    lastAction = actionType;
                    Dir newDir = new Dir(lastPosition, targetPos);
                    //StartCoroutine(TurnTo(newDir.dir));
                    //if (!moving)
                    //{
                    //Debug.Log("Starting Bumpto");
                    StartCoroutine(StartBump(newDir));
                    //}
                }
            }
        }
    }