Exemplo n.º 1
0
    public void MakeBody()
    {
        if (!gotShaderIds)
        {
            GetShaderIDs();
        }
        flags        = new CreatureRawFlags(race.flags);
        bodyCategory = FindBodyCategory(caste);
        //If there's already any spawned parts, we need to clear them so we can remake the body from scratch.
        if (spawnedParts.Count > 0)
        {
            foreach (var part in spawnedParts)
            {
                if (part.Value != null)
                {
                    if (Application.isPlaying)
                    {
                        Destroy(part.Value.gameObject);
                    }
                    else
                    {
                        DestroyImmediate(part.Value.gameObject);
                    }
                }
            }
            spawnedParts.Clear();
        }
        //Clearing this will serve the purpose of resetting the inventory.
        inventoryModes = new InventoryMode[0];
        //They're made standing, so the current state should reflect that.
        onGround = false;
        float unitVolume = caste.adult_size;

        if (unit != null && unit.size_info != null)
        {
            unitVolume = unit.size_info.size_cur;
        }
        unitVolume = UnitScaler.GetAdjustedUnitSize(unitVolume);

        float scale = unitVolume / caste.total_relsize * 10;

        MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();

        bodyScale = BodyDefinition.GetBodyScale(bodyCategory, race, caste);

        Vector3 unitShape = Vector3.one;

        for (int i = 0; i < caste.body_appearance_modifiers.Count; i++)
        {
            var mod   = caste.body_appearance_modifiers[i];
            int value = 100;
            if (unit != null && unit.appearance != null)
            {
                value = unit.appearance.body_modifiers[i];
            }
            else
            {
                value = UnityEngine.Random.Range(mod.mod_min, mod.mod_max);
            }
            switch (mod.type)
            {
            case "BROADNESS":
                unitShape.x = value / 100f;
                break;

            case "HEIGHT":
                unitShape.y = value / 100f;
                break;

            case "LENGTH":
                unitShape.z = value / 100f;
                break;

            default:
                break;
            }
        }

        bodyScale = BodyPart.MultiplyScales(bodyScale, unitShape);

        for (int i = 0; i < caste.body_parts.Count; i++)
        {
            var part = caste.body_parts[i];
            if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL])
            {
                continue;
            }

            var spawnedPart = new GameObject().AddComponent <BodyPart>();
            spawnedPart.name     = string.Format("{0} ({1})", part.token, part.category);
            spawnedPart.token    = part.token;
            spawnedPart.category = part.category;
            spawnedPart.flags    = new BodyPartFlags(part.flags);
            spawnedPart.volume   = part.relsize * scale;
            spawnedPart.layers   = part.layers;



            var model = BodyDefinition.GetPart(bodyCategory, race, caste, part);
            if (model != null)
            {
#if UNITY_EDITOR
                var placedModel = (BodyPartModel)UnityEditor.PrefabUtility.InstantiatePrefab(model);
#else
                var placedModel = Instantiate(model);
#endif
                placedModel.transform.SetParent(spawnedPart.transform);
                placedModel.CollectEquipment();
                spawnedPart.modeledPart = placedModel;
            }

            if (spawnedPart.modeledPart == null)
            {
                var cube = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent <VolumeKeeper>();
                if ((Application.isPlaying))
                {
                    Destroy(cube.GetComponent <BoxCollider>());
                }
                else
                {
                    DestroyImmediate(cube.GetComponent <BoxCollider>());
                }

                cube.name = spawnedPart.name + " cube";
                cube.transform.SetParent(spawnedPart.transform);
                cube.volume = spawnedPart.volume;
                cube.FixVolume();
                cube.gameObject.AddComponent <BodyLayer>();
                spawnedPart.placeholder = cube;
                if (skinMat == null)
                {
                    skinMat = Resources.Load <Material>("Skin");
                }
                cube.GetComponent <MeshRenderer>().sharedMaterial = skinMat;
            }
            if (spawnedPart.flags.upperbody)
            {
                upperBody = spawnedPart;
                foreach (var item in spawnedPart.GetComponentsInChildren <BodyPartChildPlaceholder>())
                {
                    if (item.category == ":ATTACH:")
                    {
                        riderPosition = item.transform;
                        break;
                    }
                }
            }
            if (spawnedPart.flags.lowerbody)
            {
                lowerBody = spawnedPart;
            }
            var modeledLayers = spawnedPart.GetComponentsInChildren <BodyLayer>();
            foreach (var modeledLayer in modeledLayers)
            {
                modeledLayer.parentPart = spawnedPart;
            }
            foreach (var layer in part.layers)
            {
                var matchedLayers = Array.FindAll(modeledLayers, x => x.layerName == layer.layer_name);
                if (matchedLayers.Length == 0)
                {
                    matchedLayers = Array.FindAll(modeledLayers, x => string.IsNullOrEmpty(x.layerName));
                    if (matchedLayers.Length == 0)
                    {
                        spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer));
                    }
                    else
                    {
                        bool matchedAny = false;
                        foreach (var matchedLayer in matchedLayers)
                        {
                            if (!matchedLayer.placed)
                            {
                                matchedLayer.layerRaw = layer;
                                spawnedPart.layerModels.Add(matchedLayer);
                                matchedLayer.placed = true;
                                matchedAny          = true;
                                break;
                            }
                        }
                        if (!matchedAny)
                        {
                            spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer));
                        }
                    }
                }
                else
                {
                    bool matchedAny = false;
                    foreach (var matchedLayer in matchedLayers)
                    {
                        if (!matchedLayer.placed)
                        {
                            matchedLayer.layerRaw = layer;
                            spawnedPart.layerModels.Add(matchedLayer);
                            matchedLayer.placed = true;
                            matchedAny          = true;
                            break;
                        }
                    }
                    if (!matchedAny)
                    {
                        spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer));
                    }
                }
            }
            foreach (var modeledLayer in modeledLayers)
            {
                if (!modeledLayer.placed)
                {
                    modeledLayer.gameObject.SetActive(false);
                }
            }

            foreach (var layerModel in spawnedPart.layerModels)
            {
                if (layerModel == null || !(layerModel is BodyLayer))
                {
                    continue;
                }
                ((BodyLayer)layerModel).ApplyMaterials(race, propertyBlock);
            }
            spawnedParts[i] = spawnedPart;
        }
        for (int modNum = 0; modNum < caste.modifier_idx.Count; modNum++)
        {
            if (!spawnedParts.ContainsKey(caste.part_idx[modNum]))
            {
                continue;
            }
            var mod  = caste.modifiers[caste.modifier_idx[modNum]];
            var part = spawnedParts[caste.part_idx[modNum]];
            if (caste.layer_idx[modNum] >= 0)
            {
                var layer = part.layerModels[caste.layer_idx[modNum]];
                if (layer != null)
                {
                    layer.AddMod(new BodyPart.ModValue(mod, (unit != null && unit.appearance != null) ? unit.appearance.bp_modifiers[modNum] : 100));
                }
            }
            else
            {
                part.mods.Add(new BodyPart.ModValue(mod, (unit != null && unit.appearance != null) ? unit.appearance.bp_modifiers[modNum] : 100));
            }
        }

        for (int modNum = 0; modNum < caste.color_modifiers.Count; modNum++)
        {
            var colorMod = caste.color_modifiers[modNum];

            int seed = Mathf.Abs(GetInstanceID() * modNum) % colorMod.patterns.Count;
            for (int i = 0; i < colorMod.body_part_id.Count; i++)
            {
                var part = spawnedParts[colorMod.body_part_id[i]];
                if (part == null || !part.gameObject.activeSelf)
                {
                    continue;
                }
                var layer = part.layerModels[colorMod.tissue_layer_id[i]];
                if (layer == null || !layer.IsActive || !(layer is BodyLayer))
                {
                    continue;
                }
                PatternDescriptor pattern;
                if (unit != null && unit.appearance != null)
                {
                    pattern = colorMod.patterns[unit.appearance.colors[modNum]];
                }
                else
                {
                    pattern = colorMod.patterns[seed];
                }
                var matIndex   = ContentLoader.GetPatternIndex(race.tissues[layer.TissueID].material);
                var shapeIndex = ContentLoader.GetShapeIndex(race.tissues[layer.TissueID].material);
                if (colorMod.start_date > 0 && unit != null)
                {
                    ((BodyLayer)layer).ApplyPattern(pattern, Mathf.InverseLerp(colorMod.start_date * 1200, colorMod.end_date * 1200, unit.age), propertyBlock, matIndex, shapeIndex);
                }
                else
                {
                    ((BodyLayer)layer).ApplyPattern(pattern, 1, propertyBlock, matIndex, shapeIndex);
                }
            }
        }
        for (int i = 0; i < caste.body_parts.Count; i++)
        {
            if (!spawnedParts.ContainsKey(i))
            {
                continue;
            }
            var part = caste.body_parts[i];
            if (!spawnedParts.ContainsKey(part.parent))
            {
                spawnedParts[i].transform.SetParent(transform);
            }
            else
            {
                spawnedParts[i].transform.SetParent(spawnedParts[part.parent].transform);
                spawnedParts[i].parent = spawnedParts[part.parent];
                spawnedParts[part.parent].children.Add(spawnedParts[i]);
            }
            if (part.parent < 0)
            {
                rootPart = spawnedParts[i];
            }
            if (spawnedParts[i].flags.stance)
            {
                stanceCount++;
            }
        }

        foreach (var part in spawnedParts)
        {
            foreach (var layer in part.Value.layerModels)
            {
                if (layer != null && (layer is BodyLayer))
                {
                    ((BodyLayer)layer).ApplyMods();
                }
            }
        }

        if (rootPart == null)
        {
            return; //There's no root part, means there's no body.
        }
        //Use this when we do body part mods.
        //for(int i = 0; i < caste.modifier_idx.Count; i++)
        //{
        //    var modifier = caste.modifiers[caste.modifier_idx[i]];
        //    var part = caste.body_parts[caste.part_idx[i]];
        //}


        rootPart.Arrange(this);
        foreach (var part in spawnedParts)
        {
            if (part.Value.flags.head)
            {
                part.Value.transform.localScale *= GameSettings.Instance.units.chibiness;
            }
        }


        if (unit != null && unit.wounds != null)
        {
            foreach (var wound in unit.wounds)
            {
                foreach (var woundPart in wound.parts)
                {
                    if (spawnedParts.ContainsKey(woundPart.body_part_id))
                    {
                        spawnedParts[woundPart.body_part_id].gameObject.SetActive(!wound.severed_part);
                    }
                }
            }
        }

        bounds = rootPart.GetComponentInChildren <MeshRenderer>().bounds;
        foreach (var item in rootPart.GetComponentsInChildren <MeshRenderer>())
        {
            bounds.Encapsulate(item.bounds);
        }
        rootPart.transform.localPosition = new Vector3(0, -bounds.min.y, 0);
    }
Exemplo n.º 2
0
    public void MakeBody()
    {
        flags        = new CreatureRawFlags(race.flags);
        bodyCategory = FindBodyCategory(caste);
        if (spawnedParts.Count > 0)
        {
            foreach (var part in spawnedParts)
            {
                Destroy(part.Value.gameObject);
            }
            spawnedParts.Clear();
        }
        float scale = caste.adult_size / (float)caste.total_relsize * 10;

        if (unit != null && unit.size_info != null)
        {
            scale = unit.size_info.size_cur / (float)caste.total_relsize * 10;
        }
        MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();

        bodyScale = BodyDefinition.GetBodyScale(bodyCategory, race, caste);

        Vector3 unitShape = Vector3.one;

        for (int i = 0; i < caste.body_appearance_modifiers.Count; i++)
        {
            var mod   = caste.body_appearance_modifiers[i];
            int value = 100;
            if (unit != null && unit.appearance != null)
            {
                value = unit.appearance.body_modifiers[i];
            }
            else
            {
                value = UnityEngine.Random.Range(mod.mod_min, mod.mod_max);
            }
            switch (mod.type)
            {
            case "BROADNESS":
                unitShape.x = value / 100f;
                break;

            case "HEIGHT":
                unitShape.y = value / 100f;
                break;

            case "LENGTH":
                unitShape.z = value / 100f;
                break;

            default:
                break;
            }
        }

        bodyScale = BodyPart.MultiplyScales(bodyScale, unitShape);

        for (int i = 0; i < caste.body_parts.Count; i++)
        {
            var part = caste.body_parts[i];
            if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL])
            {
                continue;
            }

            var spawnedPart = new GameObject().AddComponent <BodyPart>();
            spawnedPart.name     = string.Format("{0} ({1})", part.token, part.category);
            spawnedPart.token    = part.token;
            spawnedPart.category = part.category;
            spawnedPart.flags    = new BodyPartFlags(part.flags);
            spawnedPart.volume   = part.relsize * scale;
            spawnedPart.layers   = part.layers;



            var model = BodyDefinition.GetPart(bodyCategory, race, caste, part);
            if (model != null)
            {
                var placedModel = Instantiate(model);
                placedModel.transform.SetParent(spawnedPart.transform);
                placedModel.CollectEquipment();
                spawnedPart.modeledPart = placedModel;
            }

            if (spawnedPart.modeledPart == null)
            {
                var cube = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent <VolumeKeeper>();
                if ((Application.isPlaying))
                {
                    Destroy(cube.GetComponent <BoxCollider>());
                }
                else
                {
                    DestroyImmediate(cube.GetComponent <BoxCollider>());
                }

                cube.name = spawnedPart.name + " cube";
                cube.transform.SetParent(spawnedPart.transform);
                cube.volume = spawnedPart.volume;
                cube.FixVolume();
                cube.gameObject.AddComponent <BodyLayer>();
                spawnedPart.placeholder = cube;
                if (skinMat == null)
                {
                    skinMat = Resources.Load <Material>("Skin");
                }
                cube.GetComponent <MeshRenderer>().sharedMaterial = skinMat;
            }
            if (spawnedPart.flags.upperbody)
            {
                upperBody = spawnedPart;
                foreach (var item in spawnedPart.GetComponentsInChildren <BodyPartChildPlaceholder>())
                {
                    if (item.category == ":ATTACH:")
                    {
                        riderPosition = item.transform;
                        break;
                    }
                }
            }
            if (spawnedPart.flags.lowerbody)
            {
                lowerBody = spawnedPart;
            }
            var modeledLayers = spawnedPart.GetComponentsInChildren <BodyLayer>();
            foreach (var layer in part.layers)
            {
                var matchedLayers = Array.FindAll(modeledLayers, x => x.layerName == layer.layer_name);
                if (matchedLayers.Length == 0)
                {
                    matchedLayers = Array.FindAll(modeledLayers, x => string.IsNullOrEmpty(x.layerName));
                    if (matchedLayers.Length < 0)
                    {
                        spawnedPart.layerModels.Add(null);
                    }
                    else
                    {
                        bool matchedAny = false;
                        foreach (var matchedLayer in matchedLayers)
                        {
                            if (!matchedLayer.placed)
                            {
                                matchedLayer.layerRaw = layer;
                                spawnedPart.layerModels.Add(matchedLayer);
                                matchedLayer.placed = true;
                                matchedAny          = true;
                                break;
                            }
                        }
                        if (!matchedAny)
                        {
                            spawnedPart.layerModels.Add(null);
                        }
                    }
                }
                else
                {
                    bool matchedAny = false;
                    foreach (var matchedLayer in matchedLayers)
                    {
                        if (!matchedLayer.placed)
                        {
                            matchedLayer.layerRaw = layer;
                            spawnedPart.layerModels.Add(matchedLayer);
                            matchedLayer.placed = true;
                            matchedAny          = true;
                            break;
                        }
                    }
                    if (!matchedAny)
                    {
                        spawnedPart.layerModels.Add(null);
                    }
                }
            }
            foreach (var modeledLayer in modeledLayers)
            {
                if (!modeledLayer.placed)
                {
                    modeledLayer.gameObject.SetActive(false);
                }
            }

            foreach (var layerModel in spawnedPart.layerModels)
            {
                if (layerModel == null)
                {
                    continue;
                }
                var renderer = layerModel.GetComponentInChildren <MeshRenderer>();
                if (renderer != null)
                {
                    var tissue = race.tissues[layerModel.layerRaw.tissue_id];
                    var color  = ContentLoader.GetColor(tissue.material);
                    var index  = ContentLoader.GetPatternIndex(tissue.material);
                    propertyBlock.SetColor("_MatColor", color);
                    propertyBlock.SetFloat("_MatIndex", index);
                    renderer.SetPropertyBlock(propertyBlock);
                }
            }
            spawnedParts[i] = spawnedPart;
        }
        for (int modNum = 0; modNum < caste.modifier_idx.Count; modNum++)
        {
            if (!spawnedParts.ContainsKey(caste.part_idx[modNum]))
            {
                continue;
            }
            var mod  = caste.modifiers[caste.modifier_idx[modNum]];
            var part = spawnedParts[caste.part_idx[modNum]];
            if (caste.layer_idx[modNum] >= 0)
            {
                var layer = part.layerModels[caste.layer_idx[modNum]];
                if (layer != null)
                {
                    layer.mods.Add(new BodyPart.ModValue(mod, modNum));
                }
            }
            else
            {
                part.mods.Add(new BodyPart.ModValue(mod, modNum));
            }
        }

        for (int modNum = 0; modNum < caste.color_modifiers.Count; modNum++)
        {
            var mod = caste.color_modifiers[modNum];
            //Temp fix until actual creatures are being read.
            if (mod.start_date > 0)
            {
                continue;
            }
            int seed = Mathf.Abs(GetInstanceID() * modNum) % mod.patterns.Count;
            for (int i = 0; i < mod.body_part_id.Count; i++)
            {
                var part = spawnedParts[mod.body_part_id[i]];
                if (part == null || !part.gameObject.activeSelf)
                {
                    continue;
                }
                var layer = part.layerModels[mod.tissue_layer_id[i]];
                if (layer == null || !layer.gameObject.activeSelf)
                {
                    continue;
                }
                ColorDefinition colorDef;
                if (unit != null && unit.appearance != null)
                {
                    colorDef = mod.patterns[unit.appearance.colors[modNum]].colors[0];
                }
                else
                {
                    colorDef = mod.patterns[seed].colors[0];
                }
                var color = new Color32((byte)colorDef.red, (byte)colorDef.green, (byte)colorDef.blue, 128);
                var index = ContentLoader.GetPatternIndex(race.tissues[layer.layerRaw.tissue_id].material);
                propertyBlock.SetColor("_MatColor", color);
                propertyBlock.SetFloat("_MatIndex", index);
                var renderer = layer.GetComponentInChildren <MeshRenderer>();
                if (renderer != null)
                {
                    renderer.SetPropertyBlock(propertyBlock);
                }
            }
        }
        for (int i = 0; i < caste.body_parts.Count; i++)
        {
            if (!spawnedParts.ContainsKey(i))
            {
                continue;
            }
            var part = caste.body_parts[i];
            if (!spawnedParts.ContainsKey(part.parent))
            {
                spawnedParts[i].transform.SetParent(transform);
            }
            else
            {
                spawnedParts[i].transform.SetParent(spawnedParts[part.parent].transform);
                spawnedParts[i].parent = spawnedParts[part.parent];
                spawnedParts[part.parent].children.Add(spawnedParts[i]);
            }
            if (part.parent < 0)
            {
                rootPart = spawnedParts[i];
            }
            if (spawnedParts[i].flags.stance)
            {
                stanceCount++;
            }
        }

        if (rootPart == null)
        {
            return; //There's no root part, means there's no body.
        }
        //Use this when we do body part mods.
        //for(int i = 0; i < caste.modifier_idx.Count; i++)
        //{
        //    var modifier = caste.modifiers[caste.modifier_idx[i]];
        //    var part = caste.body_parts[caste.part_idx[i]];
        //}


        rootPart.Arrange(this);
        bounds = rootPart.GetComponentInChildren <MeshRenderer>().bounds;
        foreach (var item in rootPart.GetComponentsInChildren <MeshRenderer>())
        {
            bounds.Encapsulate(item.bounds);
        }
        rootPart.transform.localPosition = new Vector3(0, -bounds.min.y, 0);
    }