Exemple #1
0
    public static UnitState NextState(Unit unit)   //returns next state
    //todo: if enemies approach them they start attacking? or only if the user puts them in attack mode
    //if they don't start attacking do they run away?

    //todo: only show mating thought when having a baby (make the f*****g process longer)
    //todo: add actions that happen from every state here!
    {
        if (unit.shouldDie)
        {
            UnitActions.Die(unit); return(UnitState.Dead);
        }

        switch (unit.unitState)
        {
        case UnitState.Wander: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            //rethink this
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (UnitQueries.NeedsChange(unit))
            {
                return(UnitState.TargetBase);
            }                                                                           //TODO this should probably override everything cause it seems like a bug otherwise
            if (UnitQueries.IsHungry(unit) && UnitQueries.FoodSourceAvailable(unit))
            {
                UnitActions.TargetFood(unit); return(UnitState.TargetFood);
            }
            if (UnitQueries.IsThirsty(unit))
            {
                UnitActions.TargetWater(unit); return(UnitState.TargetWater);
            }
            if (UnitQueries.IsHorny(unit) && UnitQueries.AvailableMate(unit))
            {
                return(UnitState.TargetMate);
            }
            if (UnitQueries.GenetiumAvailable(unit) && !UnitQueries.IsStorageFull(unit))           //todo: make funuction is genetium available? (unit storage not full, genetium enough genetium, genetium chosen in species)
            {
                UnitActions.TargetGenetium(unit); return(UnitState.TargetGenetium);
            }
            if (UnitQueries.IsCarryingGenetium(unit))
            {
                return(UnitState.TargetBase);
            }
            UnitActions.Wander(unit);
            break;
        }

        case UnitState.TargetWater: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            //if (!UnitQueries.SeesWater(unit)) { return UnitState.Wander; }
            if (UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Drink);
            }

            break;
        }

        case UnitState.TargetFood: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            //todo handle change of food source as its targetting
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            //if (!UnitQueries.SeesFood(unit)) { return UnitState.Wander; }
            if (UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Eat);
            }
            break;
        }

        case UnitState.TargetMate: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            UnitActions.TargetMate(unit);
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (!UnitQueries.AvailableMate(unit))
            {
                return(UnitState.Wander);
            }
            if (UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Mate);
            }
            break;
        }

        case UnitState.TargetGenetium: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            //if (UnitQueries.IsThreatened(unit)) { return UnitState.Wander; }
            if (UnitQueries.IsHungry(unit) && UnitQueries.FoodSourceAvailable(unit))
            {
                UnitActions.TargetFood(unit); return(UnitState.TargetFood);
            }
            if (UnitQueries.IsThirsty(unit))
            {
                UnitActions.TargetWater(unit); return(UnitState.TargetWater);
            }
            //todo handle change of genetium source as its targetting
            if (UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Harvest);
            }

            break;
        }

        case UnitState.TargetBase: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            UnitActions.TargetBase(unit);
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (UnitQueries.IsHungry(unit) && UnitQueries.FoodSourceAvailable(unit))
            {
                UnitActions.TargetFood(unit); return(UnitState.TargetFood);
            }
            if (UnitQueries.IsThirsty(unit))
            {
                UnitActions.TargetWater(unit); return(UnitState.TargetWater);
            }
            if (UnitQueries.IsNearTarget(unit))
            {
                UnitActions.ReachBase(unit); return(UnitState.Wander);
            }
            break;
        }

        case UnitState.TargetEnemy: {
            UnitActions.TargetEnemy(unit);
            //if (UnitQueries.HasLowHealth(unit)) { return UnitState.Flee; }
            //if (UnitQueries.IsVeryHungry(unit)) { return UnitState.Flee; }
            //if (UnitQueries.IsVeryThirsty(unit)) { return UnitState.Flee; }
            if (UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Attack);
            }
            if (!UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.Wander);
            }
            break;
        }

        //todo: change food and genetium to be near the known food target
        case UnitState.Drink: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (UnitQueries.IsQuenched(unit))
            {
                UnitActions.TurnQuenched(unit); return(UnitState.Wander);
            }
            UnitActions.Drink(unit);
            break;
        }

        case UnitState.Eat: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            //todo handle change of food source as its eating
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (UnitQueries.IsFed(unit))
            {
                UnitActions.TurnFed(unit); return(UnitState.Wander);
            }
            UnitActions.Eat(unit);
            break;
        }

        case UnitState.Mate: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            if (!UnitQueries.IsHorny(unit))
            {
                return(UnitState.Wander);
            }
            UnitActions.Mate(unit);
            break;
        }

        case UnitState.Harvest: {
            if (unit.isBeingOverride)
            {
                return(UnitState.Override);
            }

            //todo handle change of genetium source as its harvesting
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }
            if (!UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.Wander);
            }
            if (UnitQueries.IsStorageFull(unit))
            {
                return(UnitState.Wander);
            }
            if (!UnitQueries.GenetiumAvailable(unit))
            {
                return(UnitState.Wander);
            }
            UnitActions.Harvest(unit);
            break;
        }

        case UnitState.Attack: {
            //if (unit.isBeingOverride) return UnitState.Override;

            if (UnitQueries.IsTargettedEnemyDead(unit))
            {
                return(UnitState.Wander);
            }
            if (!UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.Wander);
            }
            //if (UnitQueries.HasLowHealth(unit)) { return UnitState.Flee; }

            if (!UnitQueries.IsNearTarget(unit))
            {
                return(UnitState.TargetEnemy);
            }

            UnitActions.Attack(unit);
            break;
        }

        case UnitState.Flee: {
            UnitActions.Flee(unit);
            if (!UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.Wander);
            }
            break;
        }

        case UnitState.Override: {
            //todo: think how override behaves with enemies in range
            if (UnitQueries.IsNearTarget(unit))
            {
                UnitActions.StopOverride(unit); return(UnitState.Wander);
            }
            if (UnitQueries.EnemyInRange(unit))
            {
                return(UnitState.TargetEnemy);
            }

            break;
        }
        }

        return(unit.unitState); //no state change
    }