Example #1
0
        public static bool GetBelowGroundSpawnPoint(ref SpawnPoint spawnPoint, SpawnerStateSetting setting, Location spawnLocation, WIGroup spawnGroup)
        {
            bool succeeded = false;

            spawnPoint = new SpawnPoint();
            switch (setting.Method)
            {
            case SpawnerPlacementMethod.SherePoint:
                //cast a ray from the center of the location outwards
                Vector3    starget = (UnityEngine.Random.onUnitSphere * spawnLocation.worlditem.ActiveRadius) + spawnLocation.worlditem.tr.position;
                Vector3    sscale  = Vector3.one;
                RaycastHit hit;
                if (Physics.Linecast(spawnLocation.worlditem.tr.position, starget, out hit, Globals.LayersTerrain))
                {
                    spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(hit.point);
                    spawnPoint.Transform.Rotation = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles;                     //random forward vector, normal up vector
                    spawnPoint.Transform.Scale    = sscale;
                    switch (hit.collider.gameObject.layer)
                    {
                    case Globals.LayerNumFluidTerrain:
                        spawnPoint.HitWater = true;
                        break;

                    case Globals.LayerNumSolidTerrain:
                    default:
                        spawnPoint.HitTerrainMesh = true;
                        break;
                    }
                    succeeded = true;
                }
                break;

            case SpawnerPlacementMethod.TopDown:
            default:
                //get a random point in sphere scaled to the location's radius
                mTerrainHit.groundedHeight = spawnLocation.worlditem.ActiveRadius;
                mRandomSphere            = UnityEngine.Random.onUnitSphere * mTerrainHit.groundedHeight;
                mRandomSphere.y          = 0f;
                mTerrainHit.feetPosition = mRandomSphere + spawnLocation.worlditem.tr.position;
                //get the terrain height in world space, then store it in local space
                //WorldChunk chunk = spawnLocation.worlditem.Group.GetParentChunk ();
                mTerrainHit.feetPosition.y    = GameWorld.Get.TerrainHeightAtInGamePosition(ref mTerrainHit);
                spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(mTerrainHit.feetPosition);
                spawnPoint.Transform.Rotation = Quaternion.LookRotation(SVector3.Random(-1f, 1f), mTerrainHit.normal).eulerAngles;
                spawnPoint.Transform.Scale    = Vector3.one;
                spawnPoint.HitWater           = mTerrainHit.hitWater;
                spawnPoint.HitTerrainMesh     = mTerrainHit.hitTerrainMesh;
                if (!mTerrainHit.isGrounded)
                {
                    Debug.Log("TERRAIN HIT WAS NOT GROUNDED");
                }
                succeeded = true;
                break;
            }
            return(succeeded);
        }
Example #2
0
 public static bool TrySpawnPoint(SpawnerStateSetting setting, SpawnPoint spawnPoint, Location spawnLocation)
 {
     return(true);
 }
Example #3
0
        public IEnumerator SpawnItemsOverTime()
        {
            System.Random random = new System.Random(Profile.Get.CurrentGame.Seed + worlditem.GetHashCode());

            Location location = null;

            if (!worlditem.Is <Location> (out location))
            {
                mIsSpawning = false;
                yield break;
            }

            while (!Player.Local.HasSpawned || location.LocationGroup == null || !location.LocationGroup.Is(WIGroupLoadState.Loaded))
            {
                yield return(null);

                if (worlditem.Is(WIActiveState.Invisible) || !worlditem.Is(WILoadState.Initialized))
                {
                    //Debug.Log ("We went invisible before we could spawn in " + name);
                    mIsSpawning = false;
                    yield break;
                }
            }

            WIGroup spawnGroup = location.LocationGroup;

            for (int i = 0; i < State.SpawnerSettings.Count; i++)
            {
                SpawnerStateSetting setting = State.SpawnerSettings [i];
                if (setting.TimeToSpawn)
                {
                    setting.LastManualSpawnPointIndex = 0;                    //reset this just in case
                    var enumerator = GetSpawnPoints(setting, location, spawnGroup, Player.Local, random).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        if (!spawnGroup.Is(WIGroupLoadState.Initialized | WIGroupLoadState.Loading | WIGroupLoadState.Loaded))
                        {
                            //whoops, it unloaded
                            yield break;
                        }
                        SpawnPoint spawnPoint = enumerator.Current;
                        //wait a tick after fetching the spawn point
                        yield return(null);

                        if (spawnPoint != SpawnPoint.Empty)
                        {
                            var spawn = Spawn(spawnPoint, setting, location, spawnGroup, random);
                            while (spawn.MoveNext())
                            {
                                yield return(spawn.Current);
                            }
                        }
                        double waitUntil = WorldClock.RealTime + Globals.SpawnerRTYieldInterval + UnityEngine.Random.value * 0.25f;
                        while (WorldClock.RealTime < waitUntil)
                        {
                            yield return(null);
                        }
                    }
                    int gameHoursToNextSpawnTime = random.Next(setting.MinHoursBetweenSpawns, setting.MaxHoursBetweenSpawns);
                    setting.NextSpawnTime = WorldClock.AdjustedRealTime + WorldClock.HoursToSeconds(gameHoursToNextSpawnTime);
                }
                yield return(null);
            }

            mIsSpawning = false;
            yield break;
        }
Example #4
0
        public static IEnumerator Spawn(SpawnPoint spawnPoint, SpawnerStateSetting setting, Location location, WIGroup spawnGroup, System.Random random)
        {
            switch (setting.Type)
            {
            case SpawnerType.WorldItems:
            default:
                WorldItem  newSpawnedItem = null;
                WICategory cat            = null;
                if (WorldItems.Get.Category(setting.CategoryName, out cat))
                {
                    spawnPoint.Transform.Position.y += setting.UpVectorPadding;
                    if (WorldItems.CloneRandomFromCategory(cat, spawnGroup, spawnPoint.Transform, setting.Flags, setting.NumTimesSpawned, setting.NumAttempts, out newSpawnedItem))
                    {
                        //adjust spawn point
                        spawnPoint.Transform.Rotation    = spawnPoint.Transform.Rotation + newSpawnedItem.Props.Global.BaseRotation;
                        spawnPoint.Transform.Position.y += setting.UpVectorPadding;
                        //apply to newly spawned item
                        newSpawnedItem.Props.Local.Transform.CopyFrom(spawnPoint.Transform);
                        if (setting.DropThenFreeze)
                        {
                            newSpawnedItem.Props.Local.FreezeOnStartup = false;
                            newSpawnedItem.Props.Local.FreezeOnSleep   = true;
                            newSpawnedItem.gameObject.AddComponent <FreezeOnSleep> ().worlditem = newSpawnedItem;
                        }
                        else
                        {
                            yield return(null);
                        }
                        if (!string.IsNullOrEmpty(setting.SendMessageToSpawnedItem))
                        {
                            //Debug.Log ("Sending message to item: " + setting.SendMessageToSpawnedItem);
                            newSpawnedItem.SendMessage(setting.SendMessageToSpawnedItem, SendMessageOptions.DontRequireReceiver);
                        }
                    }
                    else
                    {
                        //Debug.Log ("Couldn't clone from category " + setting.CategoryName);
                    }
                }
                else
                {
                    //Debug.Log ("Couldn't get category " + setting.CategoryName);
                }
                break;

            case SpawnerType.Characters:
                //TEMP just use bandit camp since that's the only thing that uses spawners for characters
                BanditCamp camp = null;
                if (location.worlditem.Is <BanditCamp> (out camp))
                {
                    Character character = null;
                    //if we've gotten this far we must have found or created a node, so assume it's there
                    if (Characters.SpawnRandomCharacter(spawnPoint.nodeState.actionNode, camp.State.TemplateName, setting.Flags, location.LocationGroup, out character))
                    {
                        camp.AddBandit(character);
                    }
                }
                break;


            case SpawnerType.Creatures:
                spawnPoint.Transform.Position.y += setting.UpVectorPadding;
                CreatureDen den = null;
                if (location.worlditem.Is <CreatureDen> (out den))
                {
                    Creature creature = null;
                    Creatures.SpawnCreature(den, spawnGroup, spawnPoint.Transform.Position, out creature);
                }
                break;
            }
            yield break;
        }
Example #5
0
        public static bool GetAboveGroundSpawnPoint(ref SpawnPoint spawnPoint, SpawnerStateSetting setting, Location spawnLocation, WIGroup spawnGroup)
        {
            bool succeeded = false;

            spawnPoint = new SpawnPoint();
            switch (setting.Method)
            {
            case SpawnerPlacementMethod.SherePoint:
                //cast a ray from the center of the location outwards
                Vector3    starget = (UnityEngine.Random.onUnitSphere * spawnLocation.worlditem.ActiveRadius) + spawnLocation.worlditem.tr.position;
                Vector3    sscale  = Vector3.one;
                RaycastHit hit;
                if (Physics.Linecast(spawnLocation.worlditem.tr.position, starget, out hit, Globals.LayersTerrain))
                {
                    spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(hit.point);
                    spawnPoint.Transform.Rotation = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles;                     //random forward vector, normal up vector
                    spawnPoint.Transform.Scale    = sscale;
                    switch (hit.collider.gameObject.layer)
                    {
                    case Globals.LayerNumFluidTerrain:
                        spawnPoint.HitWater = true;
                        break;

                    case Globals.LayerNumSolidTerrain:
                    default:
                        spawnPoint.HitTerrainMesh = true;
                        break;
                    }
                    succeeded = true;
                }
                break;

            case SpawnerPlacementMethod.SpawnPoint:
                STransform manualPoint = null;
                if (!setting.NextManualSpawnPoint(out manualPoint))
                {
                    //whoops, we're out
                    return(false);
                }
                //no need to do any searching
                spawnPoint.Transform.CopyFrom(manualPoint);
                spawnPoint.HitWater       = false;
                spawnPoint.HitTerrainMesh = false;
                succeeded = true;
                break;

            case SpawnerPlacementMethod.TopDown:
            default:
                //get a random point in sphere scaled to the location's radius
                mTerrainHit.groundedHeight = spawnLocation.worlditem.ActiveRadius;
                mTerrainHit.feetPosition   = (UnityEngine.Random.insideUnitSphere * mTerrainHit.groundedHeight) + spawnLocation.worlditem.tr.position;
                mTerrainHit.feetPosition.y = GameWorld.Get.TerrainHeightAtInGamePosition(ref mTerrainHit);
                if (mTerrainHit.hitTerrain || mTerrainHit.hitTerrainMesh || (setting.SpawnOnStructureMeshes && mTerrainHit.hitStructureMesh))
                {
                    spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(mTerrainHit.feetPosition);
                    spawnPoint.Transform.Rotation = Quaternion.LookRotation(SVector3.Random(-1f, 1f), mTerrainHit.normal).eulerAngles;
                    spawnPoint.Transform.Scale    = Vector3.one;
                    spawnPoint.HitWater           = mTerrainHit.hitWater;
                    spawnPoint.HitTerrainMesh     = mTerrainHit.hitTerrainMesh;
                    succeeded = true;
                }
                else
                {
                    Debug.Log("SPAWNER " + spawnLocation.name + ": Failed because either didn't hit terrain (" + mTerrainHit.hitTerrain.ToString()
                              + ") or didn't hit terrain mesh (" + mTerrainHit.hitTerrainMesh.ToString()
                              + ") or can't spawn on structures (" + mTerrainHit.hitStructureMesh.ToString());
                    succeeded = false;
                }
                break;
            }
            return(succeeded);
        }
Example #6
0
 public static bool GetInteriorSpawnPoint(ref SpawnPoint spawnPoint, SpawnerStateSetting setting, Location spawnLocation, WIGroup spawnGroup)
 {
     return(true);
 }
Example #7
0
        public IEnumerable <SpawnPoint> GetSpawnPoints(SpawnerStateSetting setting, Location location, WIGroup spawnGroup, PlayerBase player, System.Random random)
        {
            //figure out how many we need
            setting.NumAttempts       = 0;
            setting.NumFailedAttempts = 0;

            int numExistingObjects = spawnGroup.NumChildItemsByCategory(setting.CategoryName, setting.MaxSpawnedObjects);             //TODO make sure this works
            int numObjectsToSpawn  = random.Next(setting.MinSpawnedObjects, setting.MaxSpawnedObjects) - numExistingObjects;

            if (numObjectsToSpawn <= 0)
            {
                //we don't need any more right now
                                #if UNITY_EDITOR
                Debug.Log("Skipping spawning in " + name + " because num objects to spawn is <= 0");
                                #endif
                yield break;
            }
            bool succeededThisAttempt = false;

            switch (setting.Type)
            {
            case SpawnerType.Characters:
                //when we're spawning characters, we need action nodes
                WorldChunk             chunk      = spawnGroup.GetParentChunk();
                List <ActionNodeState> nodeStates = null;
                if (chunk.GetNodesForLocation(location.worlditem.StaticReference.FullPath, out nodeStates))
                {
                    for (int i = 0; i < nodeStates.Count; i++)
                    {
                        mNextSpawnPoint.nodeState = nodeStates [i];
                        yield return(mNextSpawnPoint);
                    }
                }
                else
                {
                    nodeStates = new List <ActionNodeState> ();
                    Debug.Log("Didn't find spawn points at location, so we're going to create some");
                    //if we can't find any nodes for this location
                    //that means we've never spawned here before
                    //we need to create some nodes
                    for (int i = 0; i < numObjectsToSpawn; i++)
                    {
                        //are we totally done?
                        if (setting.NumFailedAttempts >= setting.MaxFailedAttempts)
                        {
                            yield break;
                        }
                        //if not, try to get another spawn point
                        if (spawnGroup.Props.Interior)
                        {
                            succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                        }
                        else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround)
                        {
                            succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                        }
                        else
                        {
                            succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                        }
                        //did we do it?
                        if (succeededThisAttempt)
                        {
                            //hooray we created a new action node
                            setting.NumAttempts++;
                            //turn this spawn point into an action node
                            ActionNodeState nodeState = new ActionNodeState();
                            nodeState.Name  = location.worlditem.FileName + "-Spawn-" + nodeStates.Count.ToString();
                            nodeState.Type  = ActionNodeType.Generic;
                            nodeState.Users = ActionNodeUsers.AnyOccupant;
                            nodeState.Transform.CopyFrom(mNextSpawnPoint.Transform);
                            mNextSpawnPoint.nodeState = nodeState;
                            ActionNode node = chunk.SpawnActionNode(spawnGroup, nodeState, location.worlditem.tr);
                            yield return(mNextSpawnPoint);
                        }
                        else
                        {
                            //boo, we failed
                            setting.NumFailedAttempts++;
                        }
                    }
                }
                nodeStates.Clear();
                nodeStates = null;
                break;

            default:
                //when we're spawning other things, we just need spawn points
                //ok, try to spawn this stuff
                for (int i = 0; i < numObjectsToSpawn; i++)
                {
                    //are we totally done?
                    if (setting.NumFailedAttempts >= setting.MaxFailedAttempts)
                    {
                        yield break;
                    }
                    //if not, try to get another spawn point
                    if (spawnGroup.Props.Interior)
                    {
                        succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                    }
                    else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround)
                    {
                        succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                    }
                    else
                    {
                        succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup);
                    }
                    //did we do it?
                    if (succeededThisAttempt)
                    {
                        //hooray, we got another spawn point
                        setting.NumAttempts++;
                        yield return(mNextSpawnPoint);
                    }
                    else
                    {
                        //boo, we failed
                        setting.NumFailedAttempts++;
                        yield return(SpawnPoint.Empty);
                    }
                }
                break;
            }
            yield break;
        }