// Use this for initialization
    void Start()
    {
        pool = LevelSettings.GetFirstMatchingPrefabPool(PrefabPoolName);
        if (pool == null)
        {
            enabled = false;
        }

        UIManager.Instance.PlayBossIntro();
    }
Пример #2
0
	// Use this for initialization
	void Start () {
	   pool = LevelSettings.GetFirstMatchingPrefabPool(PrefabPoolName);
        if (pool == null)
        {
            enabled = false;
        }

        if (BossWave)
        {
            SpawnEnemy(NumToSpawn.Max);
        }
    }
Пример #3
0
        /// <summary>
        /// This method gets called whenever the object is spawned or starts in a Scene (from Awake event)
        /// </summary>
        /// <param name="spawned">True if spawned, false if in the Scene at beginning.</param>
        protected virtual void SpawnedOrAwake(bool spawned = true)
        {
            if (listener != null) {
                listener.Spawned(this);
            }

            KilledBy = null;
            _waitingToDestroy = false;

            _childrenToDestroy.Clear();

            if (parentDestroyedAction != SpawnerDestroyedBehavior.DoNothing && parentKillableForParentDestroyed != null) {
                parentKillableForParentDestroyed.RecordChildToDie(this);
            }

            // anything you want to do each time this is spawned.
            if (_timesRespawned == 0) {
                isVisible = false;
                _becameVisible = false;
            }

            _isDespawning = false;
            _spawnTime = Time.time;
            _isTemporarilyInvincible = false;

            if (respawnType != RespawnType.None && !_spawnLocationSet) {
                _respawnLocation = Trans.position;
                _spawnLocationSet = true;
            }

            // respawning from "respawn" setting.
            if (_timesRespawned > 0) {
                Trans.position = _respawnLocation;
            } else {
                // register child Killables with parent, if any
                var aParent = Trans.parent;
                while (aParent != null) {
                    _parentKillable = aParent.GetComponent<Killable>();
                    if (_parentKillable == null) {
                        aParent = aParent.parent;
                        continue;
                    }

                    _parentKillable.RegisterChildKillable(this);
                    break;
                }
            }

            currentHitPoints = hitPoints.Value;

            _damageTaken = 0;
            _damagePrefabsSpawned = 0;

            if (deathPrefabPoolName != null && deathPrefabSource == WaveSpecifics.SpawnOrigin.PrefabPool) {
                _deathPrefabWavePool = LevelSettings.GetFirstMatchingPrefabPool(deathPrefabPoolName);
                if (_deathPrefabWavePool == null) {
                    LevelSettings.LogIfNew("Death Prefab Pool '" + deathPrefabPoolName + "' not found for Killable '" +
                                           name + "'.");
                }
            }
            if (damagePrefabSpawnMode != DamagePrefabSpawnMode.None && damagePrefabPoolName != null &&
                damagePrefabSource == SpawnSource.PrefabPool) {
                _damagePrefabWavePool = LevelSettings.GetFirstMatchingPrefabPool(damagePrefabPoolName);
                if (_damagePrefabWavePool == null) {
                    LevelSettings.LogIfNew("Damage Prefab Pool '" + _damagePrefabWavePool + "' not found for Killable '" +
                                           name + "'.");
                }
            }

            if (damagePrefabSpawnMode != DamagePrefabSpawnMode.None && damagePrefabSource == SpawnSource.Specific &&
                damagePrefabSpecific == null) {
                LevelSettings.LogIfNew(string.Format("Damage Prefab for '{0}' is not assigned.", Trans.name));
            }

            CheckForValidVariables();

            StopAllCoroutines(); // for respawn purposes.
            StartCoroutine(CoUpdate());

            deathDespawnBehavior = DeathDespawnBehavior.ReturnToPool;

            if (invincibleOnSpawn) {
                TemporaryInvincibility(invincibleTimeSpawn.Value);
            }
        }
Пример #4
0
        private bool SetupNextWave(bool scanForWave, bool isRestart)
        {
            _repeatTimer = null;

            if (activeMode == LevelSettings.ActiveItemMode.Never) {
                // even in repeating waves.
                return false;
            }

            if (isRestart && _currentWave == null) {
                return false; // can't restart because the current wave isn't configured in this Spawner.
            }

            var shouldInit = scanForWave || isRestart;

            if (scanForWave && !isRestart) {
                // find wave
                _settingUpWave = true;
                _currentWave = FindWave(LevelSettings.CurrentLevel, LevelSettings.CurrentWaveInfo.sequencedWaveNumber);

                // validate for all things that could go wrong!
                if (_currentWave == null || !_currentWave.enableWave) {
                    return false;
                }

                // check "active mode" for conditions
                switch (activeMode) {
                    case LevelSettings.ActiveItemMode.Never:
                        return false;
                    case LevelSettings.ActiveItemMode.IfWorldVariableInRange:
                        if (activeItemCriteria.statMods.Count == 0) {
                            return false;
                        }
                        // ReSharper disable once ForCanBeConvertedToForeach
                        for (var i = 0; i < activeItemCriteria.statMods.Count; i++) {
                            var stat = activeItemCriteria.statMods[i];
                            var variable = WorldVariableTracker.GetWorldVariable(stat._statName);
                            if (variable == null) {
                                return false;
                            }
                            var varVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? variable.CurrentIntValue
                                : variable.CurrentFloatValue;

                            var min = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? stat._modValueIntMin
                                : stat._modValueFloatMin;
                            var max = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? stat._modValueIntMax
                                : stat._modValueFloatMax;

                            if (min > max) {
                                LevelSettings.LogIfNew(
                                    "The Min cannot be greater than the Max for Active Item Limit in Syncro Spawner '" +
                                    _trans.name + "'.");
                                return false;
                            }

                            if (varVal < min || varVal > max) {
                                return false;
                            }
                        }

                        break;
                    case LevelSettings.ActiveItemMode.IfWorldVariableOutsideRange:
                        if (activeItemCriteria.statMods.Count == 0) {
                            return false;
                        }
                        // ReSharper disable once ForCanBeConvertedToForeach
                        for (var i = 0; i < activeItemCriteria.statMods.Count; i++) {
                            var stat = activeItemCriteria.statMods[i];
                            var variable = WorldVariableTracker.GetWorldVariable(stat._statName);
                            if (variable == null) {
                                return false;
                            }
                            var varVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? variable.CurrentIntValue
                                : variable.CurrentFloatValue;

                            var min = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? stat._modValueIntMin
                                : stat._modValueFloatMin;
                            var max = stat._varTypeToUse == WorldVariableTracker.VariableType._integer
                                ? stat._modValueIntMax
                                : stat._modValueFloatMax;

                            if (min > max) {
                                LevelSettings.LogIfNew(
                                    "The Min cannot be greater than the Max for Active Item Limit in Syncro Spawner '" +
                                    _trans.name + "'.");
                                return false;
                            }

                            if (varVal >= min && varVal <= max) {
                                return false;
                            }
                        }

                        break;
                }

                if (_currentWave.MinToSpwn.Value == 0 || _currentWave.MaxToSpwn.Value == 0) {
                    return false;
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (scanForWave &&
                    _currentWave.WaveDelaySec.Value + _currentWave.TimeToSpawnEntireWave.Value >=
                    LevelSettings.CurrentWaveInfo.WaveDuration &&
                    LevelSettings.CurrentWaveInfo.waveType == LevelSettings.WaveType.Timed) {
                    LevelSettings.LogIfNew(
                        string.Format(
                            "Wave TimeToSpawnWholeWave plus Wave DelaySeconds must be less than the current LevelSettings wave duration, occured in spawner: {0}, wave# {1}, level {2}.",
                            name,
                            _currentWave.SpawnWaveNumber + 1,
                            _currentWave.SpawnLevelNumber + 1));
                    return false;
                }

                if (_currentWave.MinToSpwn.Value > _currentWave.MaxToSpwn.Value) {
                    LevelSettings.LogIfNew(
                        string.Format(
                            "Wave MinToSpawn cannot be greater than Wave MaxToSpawn, occured in spawner: {0}, wave# {1}, level {2}.",
                            name,
                            _currentWave.SpawnWaveNumber + 1,
                            _currentWave.SpawnLevelNumber + 1));
                    return false;
                }

                if (_currentWave.repeatWaveUntilNew &&
                    _currentWave.repeatPauseMinimum.Value > _currentWave.repeatPauseMaximum.Value) {
                    LevelSettings.LogIfNew(
                        string.Format(
                            "Wave Repeat Pause Min cannot be greater than Wave Repeat Pause Max, occurred in spawner: {0}, wave# {1}, level {2}.",
                            name,
                            _currentWave.SpawnWaveNumber + 1,
                            _currentWave.SpawnLevelNumber + 1));
                    return false;
                }
            }

            if (LevelSettings.IsLoggingOn) {
                var waveStatus = isRestart ? "Restarting" : string.Empty;
                if (string.IsNullOrEmpty(waveStatus)) {
                    waveStatus = scanForWave ? "Starting" : "Repeating";
                }

                Debug.Log(string.Format("{0} matching wave from spawner: {1}, wave# {2}, level {3}.",
                    waveStatus,
                    name,
                    _currentWave.SpawnWaveNumber + 1,
                    _currentWave.SpawnLevelNumber + 1));
            }

            if (_currentWave.spawnSource == WaveSpecifics.SpawnOrigin.PrefabPool) {
                var poolTrans = LevelSettings.GetFirstMatchingPrefabPool(_currentWave.prefabPoolName);
                if (poolTrans == null) {
                    LevelSettings.LogIfNew(
                        string.Format(
                            "Spawner '{0}' wave# {1}, level {2} is trying to use a Prefab Pool that can't be found.",
                            name,
                            _currentWave.SpawnWaveNumber + 1,
                            _currentWave.SpawnLevelNumber + 1));
                    _spawnerValid = false;
                    _currentWave = null;
                    return false;
                }

                _wavePool = poolTrans;
            } else {
                _wavePool = null;
            }

            _settingUpWave = false;

            CheckForValidVariablesForWave(_currentWave);

            _spawnedWaveMembers.Clear();

            _currentWaveSize = Random.Range(_currentWave.MinToSpwn.Value, _currentWave.MaxToSpwn.Value);
            _currentWaveLength = _currentWave.TimeToSpawnEntireWave.Value;

            _itemsToCompleteWave = (int)(_currentWaveSize * _currentWave.waveCompletePercentage * .01f);

            if (_currentWave.repeatWaveUntilNew) {
                if (shouldInit &&
                    (LevelSettings.CurrentWaveInfo.waveType != LevelSettings.WaveType.Elimination ||
                     _currentWave.curWaveRepeatMode == WaveSpecifics.RepeatWaveMode.Endless)) {
                    // only the first time!
                    _currentWave.repetitionsToDo.Value = int.MaxValue;
                }

                _currentWaveSize += (_waveRepetitionNumber * _currentWave.repeatItemInc.Value);
                _currentWaveSize = Math.Min(_currentWaveSize, _currentWave.repeatItemLmt.Value); // cannot exceed limits

                _currentWaveLength += (_waveRepetitionNumber * _currentWave.repeatTimeInc.Value);
                _currentWaveLength = Math.Min(_currentWaveLength, _currentWave.repeatTimeLmt.Value);
                // cannot exceed limits
            }

            _currentWaveLength = Math.Max(0f, _currentWaveLength);

            if (shouldInit) {
                // not on wave repeat!
                _waveRepetitionNumber = 0;
            }

            _waveStartTime = Time.time;
            _waveFinishedSpawning = false;
            _levelSettingsNotifiedOfCompletion = false;
            _countSpawned = 0;
            _singleSpawnTime = _currentWaveLength / _currentWaveSize;

            if (_currentWave.enableLimits) {
                _currentRandomLimitDistance = Random.Range(-_currentWave.doNotSpawnRandomDist.Value,
                    _currentWave.doNotSpawnRandomDist.Value);
            }

            return true;
        }
Пример #5
0
    private void ExpandCollapseAll(WavePrefabPool pool, bool isExpand)
    {
        UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "toggle expand / collapse all");

        foreach (var poolItem in pool.poolItems) {
            poolItem.isExpanded = isExpand;
        }
    }
Пример #6
0
    // ReSharper disable once FunctionComplexityOverflow
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();

        _settings = (WavePrefabPool)target;
        _poolTrans = _settings.transform;

        WorldVariableTracker.ClearInGamePlayerStats();

        DTInspectorUtility.DrawTexture(CoreGameKitInspectorResources.LogoTexture);

        _isDirty = false;

        var allStats = KillerVariablesHelper.AllStatNames;

        var myParent = _settings.transform.parent;
        LevelSettings levelSettings = null;

        if (myParent != null) {
            var levelSettingObj = myParent.parent;
            if (levelSettingObj != null) {
                levelSettings = levelSettingObj.GetComponent<LevelSettings>();
            }
        }

        if (levelSettings == null) {
            return;
        }

        EditorGUI.indentLevel = 0;
        var newSeq = (WavePrefabPool.PoolDispersalMode)EditorGUILayout.EnumPopup("Spawn Sequence", _settings.dispersalMode);
        if (newSeq != _settings.dispersalMode) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Spawn Sequence");
            _settings.dispersalMode = newSeq;
        }
        if (_settings.dispersalMode == WavePrefabPool.PoolDispersalMode.Randomized) {
            var newExhaust = EditorGUILayout.Toggle("Exhaust before repeat", _settings.exhaustiveList);
            if (newExhaust != _settings.exhaustiveList) {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "toggle Exhaust before repeat");
                _settings.exhaustiveList = newExhaust;
            }
        }

        var hadNoListener = _settings.listener == null;
        var newListener = (WavePrefabPoolListener)EditorGUILayout.ObjectField("Listener", _settings.listener, typeof(WavePrefabPoolListener), true);
        if (newListener != _settings.listener) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "assign Listener");
            _settings.listener = newListener;
            if (hadNoListener && _settings.listener != null) {
                _settings.listener.sourcePrefabPoolName = _settings.transform.name;
            }
        }

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Scene Objects Using");

        GUI.contentColor = DTInspectorUtility.BrightButtonColor;
        if (GUILayout.Button("List", EditorStyles.toolbarButton, GUILayout.MinWidth(55))) {
            FindMatchingSpawners(_poolTrans, false);
        }
        GUILayout.Space(10);
        if (GUILayout.Button("Select", EditorStyles.toolbarButton, GUILayout.MinWidth(55))) {
            FindMatchingSpawners(_poolTrans, true);
        }
        GUILayout.FlexibleSpace();

        GUI.contentColor = Color.white;
        EditorGUILayout.EndHorizontal();

        DTInspectorUtility.VerticalSpace(4);

        if (!Application.isPlaying) {
            EditorGUILayout.BeginVertical();
            var anEvent = Event.current;

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(4);
            GUI.color = DTInspectorUtility.DragAreaColor;
            var dragArea = GUILayoutUtility.GetRect(0f, 30f, GUILayout.ExpandWidth(true));
            GUI.Box(dragArea, "Drag prefabs here in bulk to add them to the Pool!");
            GUI.color = Color.white;

            switch (anEvent.type) {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!dragArea.Contains(anEvent.mousePosition)) {
                        break;
                    }

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (anEvent.type == EventType.DragPerform) {
                        DragAndDrop.AcceptDrag();

                        foreach (var dragged in DragAndDrop.objectReferences) {
                            AddPoolItem(dragged);
                        }
                    }
                    Event.current.Use();
                    break;
            }
            GUILayout.Space(4);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            DTInspectorUtility.VerticalSpace(4);
        }

        EditorGUI.indentLevel = 0;

        var state = _settings.isExpanded;
        var text = string.Format("Prefab Pool Items ({0})", _settings.poolItems.Count);

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTInspectorUtility.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTInspectorUtility.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

        #if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
        #else
        text = "<b><size=11>" + text + "</size></b>";
        #endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (state != _settings.isExpanded) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "toggle expand Prefab Pool Items");
            _settings.isExpanded = state;
        }
        // BUTTONS...
        EditorGUILayout.BeginHorizontal(GUILayout.MinWidth(16));

        DTInspectorUtility.ResetColors();

        var alphaSort = false;

        //DTInspectorUtility.UseLightSkinButtonColor();
        // Add expand/collapse buttons if there are items in the list
        if (_settings.poolItems.Count > 0) {
            GUI.contentColor = DTInspectorUtility.BrightButtonColor;
            alphaSort = GUILayout.Button("Alpha Sort", EditorStyles.toolbarButton, GUILayout.Height(16));

            const string collapseIcon = "Collapse";
            var content = new GUIContent(collapseIcon, "Click to collapse all");
            var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton, GUILayout.Height(16));

            const string expandIcon = "Expand";
            content = new GUIContent(expandIcon, "Click to expand all");
            var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton, GUILayout.Height(16));
            if (masterExpand) {
                ExpandCollapseAll(_settings, true);
            }
            if (masterCollapse) {
                ExpandCollapseAll(_settings, false);
            }
            GUI.contentColor = Color.white;
        } else {
            GUILayout.FlexibleSpace();
        }

        EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

        var topAdded = false;

        var addText = string.Format("Click to add Pool item{0}.", _settings.poolItems.Count > 0 ? " before the first" : "");

        GUI.contentColor = DTInspectorUtility.AddButtonColor;
        // Main Add button
        if (GUILayout.Button(new GUIContent("Add", addText), EditorStyles.toolbarButton, GUILayout.Height(16))) {
            topAdded = true;
        }
        GUI.contentColor = Color.white;

        GUILayout.Space(4);

        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndHorizontal();

        int? itemToDelete = null;
        int? itemToInsert = null;
        int? itemToShiftUp = null;
        int? itemToShiftDown = null;
        int? itemToClone = null;

        if (_settings.isExpanded) {
            if (_settings.poolItems.Count > 0) {
               DTInspectorUtility.BeginGroupedControls();
            }
            for (var i = 0; i < _settings.poolItems.Count; i++) {
                var item = _settings.poolItems[i];

                DTInspectorUtility.StartGroupHeader(1);

                EditorGUILayout.BeginHorizontal();
                EditorGUI.indentLevel = 1;

                var sName = "";
                if (!item.isExpanded) {
                    if (item.prefabToSpawn == null) {
                        sName = " " + LevelSettings.EmptyValue;
                    } else {
                        sName = " (" + item.prefabToSpawn.name + ")";
                    }
                }

                var sDisabled = "";
                var itemDisabled = item.activeMode == LevelSettings.ActiveItemMode.Never;
                if (!item.isExpanded && itemDisabled) {
                    sDisabled = " - DISABLED";
                }

                var newItemExpanded = DTInspectorUtility.Foldout(item.isExpanded,
                  string.Format("Pool Item #{0}{1}{2}", (i + 1), sName, sDisabled));
                if (newItemExpanded != item.isExpanded) {
                    UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "toggle expand Pool Item");
                    item.isExpanded = newItemExpanded;
                }

                GUILayout.FlexibleSpace();

                if (Application.isPlaying) {
                    GUI.contentColor = DTInspectorUtility.BrightTextColor;
                    var itemCount = _settings.PoolInstancesOfIndex(i);
                    GUILayout.Label("Remaining: " + itemCount);
                    GUI.contentColor = Color.white;
                }

                var poolItemButton = DTInspectorUtility.AddFoldOutListItemButtons(i, _settings.poolItems.Count, "Pool Item", false, true, true);

                switch (poolItemButton) {
                    case DTInspectorUtility.FunctionButtons.Remove:
                        itemToDelete = i;
                        _isDirty = true;
                        break;
                    case DTInspectorUtility.FunctionButtons.Add:
                        itemToInsert = i;
                        _isDirty = true;
                        break;
                    case DTInspectorUtility.FunctionButtons.ShiftUp:
                        itemToShiftUp = i;
                        _isDirty = true;
                        break;
                    case DTInspectorUtility.FunctionButtons.ShiftDown:
                        itemToShiftDown = i;
                        _isDirty = true;
                        break;
                    case DTInspectorUtility.FunctionButtons.Copy:
                        itemToClone = i;
                        _isDirty = true;
                        break;
                }

                EditorGUI.indentLevel = 0;
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                if (itemDisabled) {
                    DTInspectorUtility.ShowColorWarningBox("This item is currently disabled and will never spawn.");
                }

                if (!item.isExpanded) {
                    EditorGUILayout.EndVertical();
                    continue;
                }
                EditorGUI.indentLevel = 0;

                if (item.prefabToSpawn == null && !itemDisabled) {
                    DTInspectorUtility.ShowColorWarningBox("Nothing will spawn when this item is chosen from the pool.");
                }

                var newActive = (LevelSettings.ActiveItemMode)EditorGUILayout.EnumPopup("Active Mode", item.activeMode);
                if (newActive != item.activeMode) {
                    UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "toggle Active Mode");
                    item.activeMode = newActive;
                }

                switch (item.activeMode) {
                    case LevelSettings.ActiveItemMode.IfWorldVariableInRange:
                    case LevelSettings.ActiveItemMode.IfWorldVariableOutsideRange:
                        var missingStatNames = new List<string>();
                        missingStatNames.AddRange(allStats);
                        missingStatNames.RemoveAll(delegate(string obj) {
                            return item.activeItemCriteria.HasKey(obj);
                        });

                        var newStat = EditorGUILayout.Popup("Add Active Limit", 0, missingStatNames.ToArray());
                        if (newStat != 0) {
                            AddActiveLimit(missingStatNames[newStat], item);
                        }

                        if (item.activeItemCriteria.statMods.Count == 0) {
                            DTInspectorUtility.ShowRedErrorBox("You have no Active Limits. Item will never be Active.");
                        } else {
                            EditorGUILayout.Separator();

                            int? indexToDelete = null;

                            for (var j = 0; j < item.activeItemCriteria.statMods.Count; j++) {
                                var modifier = item.activeItemCriteria.statMods[j];
                                EditorGUILayout.BeginHorizontal();
                                GUILayout.Space(15);
                                var statName = modifier._statName;
                                GUILayout.Label(statName);

                                GUILayout.FlexibleSpace();
                                GUILayout.Label("Min");

                                switch (modifier._varTypeToUse) {
                                    case WorldVariableTracker.VariableType._integer:
                                        var newMin = EditorGUILayout.IntField(modifier._modValueIntMin, GUILayout.MaxWidth(60));
                                        if (newMin != modifier._modValueIntMin) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Active Limit Min");
                                            modifier._modValueIntMin = newMin;
                                        }

                                        GUILayout.Label("Max");
                                        var newMax = EditorGUILayout.IntField(modifier._modValueIntMax, GUILayout.MaxWidth(60));
                                        if (newMax != modifier._modValueIntMax) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Active Limit Max");
                                            modifier._modValueIntMax = newMax;
                                        }
                                        break;
                                    case WorldVariableTracker.VariableType._float:
                                        var newMinFloat = EditorGUILayout.FloatField(modifier._modValueFloatMin, GUILayout.MaxWidth(60));
                                        if (newMinFloat != modifier._modValueFloatMin) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Active Limit Min");
                                            modifier._modValueFloatMin = newMinFloat;
                                        }

                                        GUILayout.Label("Max");
                                        var newMaxFloat = EditorGUILayout.FloatField(modifier._modValueFloatMax, GUILayout.MaxWidth(60));
                                        if (newMaxFloat != modifier._modValueFloatMax) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Active Limit Max");
                                            modifier._modValueFloatMax = newMaxFloat;
                                        }
                                        break;
                                    default:
                                        Debug.LogError("Add code for varType: " + modifier._varTypeToUse.ToString());
                                        break;
                                }
                                var oldBG = GUI.backgroundColor;

                                GUI.backgroundColor = DTInspectorUtility.DeleteButtonColor;
                                if (GUILayout.Button(new GUIContent("Delete", "Remove this limit"), EditorStyles.miniButtonMid, GUILayout.MaxWidth(64))) {
                                    indexToDelete = j;
                                }
                                GUI.backgroundColor = oldBG;
                                GUILayout.Space(5);
                                EditorGUILayout.EndHorizontal();

                                var min = modifier._varTypeToUse == WorldVariableTracker.VariableType._integer ? modifier._modValueIntMin : modifier._modValueFloatMin;
                                var max = modifier._varTypeToUse == WorldVariableTracker.VariableType._integer ? modifier._modValueIntMax : modifier._modValueFloatMax;

                                if (min > max) {
                                    DTInspectorUtility.ShowRedErrorBox(modifier._statName + " Min cannot exceed Max, please fix!");
                                }
                            }

                            DTInspectorUtility.ShowColorWarningBox("Limits are inclusive: i.e. 'Above' means >=");
                            if (indexToDelete.HasValue) {
                                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "delete Active Limit");
                                item.activeItemCriteria.DeleteByIndex(indexToDelete.Value);
                            }

                            DTInspectorUtility.VerticalSpace(2);
                        }

                        break;
                }

                var newPrefab = (Transform)EditorGUILayout.ObjectField("Prefab", item.prefabToSpawn, typeof(Transform), true);
                if (newPrefab != item.prefabToSpawn) {
                    UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "change Prefab");
                    item.prefabToSpawn = newPrefab;
                }

                KillerVariablesHelper.DisplayKillerInt(ref _isDirty, item.thisWeight, "Weight", _settings);
                EditorGUILayout.EndVertical();
                DTInspectorUtility.AddSpaceForNonU5();
            }

            if (_settings.poolItems.Count > 0) {
                DTInspectorUtility.EndGroupedControls();
            }
        }

        if (topAdded) {
            var newItem = new WavePrefabPoolItem();
            var index = 0;
            if (_settings.poolItems.Count > 0) {
                index = _settings.poolItems.Count - 1;
            }

            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "add Prefab Pool Item");
            _settings.poolItems.Insert(index, newItem);
        } else if (itemToDelete.HasValue) {
            if (_settings.poolItems.Count == 1) {
                DTInspectorUtility.ShowAlert("You cannot delete the only Prefab Pool item. Delete the entire Pool from the hierarchy if you wish.");

            } else {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "remove Prefab Pool Item");
                _settings.poolItems.RemoveAt(itemToDelete.Value);
            }
        } else if (itemToInsert.HasValue) {
            var newItem = new WavePrefabPoolItem();
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "add Prefab Pool Item");
            _settings.poolItems.Insert(itemToInsert.Value + 1, newItem);
        }

        if (itemToClone.HasValue)
        {
            var newItem = _settings.poolItems[itemToClone.Value].Clone();
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "clone Prefab Pool Item");
            _settings.poolItems.Insert(itemToClone.Value, newItem);
        }

        if (itemToShiftUp.HasValue) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "shift up Prefab Pool Item");
            var item = _settings.poolItems[itemToShiftUp.Value];
            _settings.poolItems.Insert(itemToShiftUp.Value - 1, item);
            _settings.poolItems.RemoveAt(itemToShiftUp.Value + 1);
        }

        if (itemToShiftDown.HasValue) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "shift down Prefab Pool Item");
            var index = itemToShiftDown.Value + 1;
            var item = _settings.poolItems[index];
            _settings.poolItems.Insert(index - 1, item);
            _settings.poolItems.RemoveAt(index + 1);
        }

        if (alphaSort) {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "Alpha Sort Prefab Pool Items");
            _settings.poolItems.Sort(delegate(WavePrefabPoolItem x, WavePrefabPoolItem y) {
                if (x.prefabToSpawn == null) {
                    return -1;
                }
                if (y.prefabToSpawn == null) {
                    return 1;
                }

                return x.prefabToSpawn.name.CompareTo(y.prefabToSpawn.name);
            });
        }

        if (GUI.changed || topAdded || _isDirty) {
            EditorUtility.SetDirty(target);	// or it won't save the data!!
        }

        //DrawDefaultInspector();
    }