Ejemplo n.º 1
0
        // Copy from TeleporterHelper, but uses a different strategy so they don't spawn on top of the person
        public static Vector3?FindSafeTeleportDestination(Vector3 characterFootPosition, CharacterBody characterBodyOrPrefabComponent, Xoroshiro128Plus rng)
        {
            Vector3?  result    = null;
            SpawnCard spawnCard = ScriptableObject.CreateInstance <SpawnCard>();

            spawnCard.hullSize = characterBodyOrPrefabComponent.hullClassification;
            //spawnCard.nodeGraphType = MapNodeGroup.GraphType.Ground;
            spawnCard.prefab = Resources.Load <GameObject>("SpawnCards/HelperPrefab");
            DirectorPlacementRule placementRule = new DirectorPlacementRule
            {
                placementMode = DirectorPlacementRule.PlacementMode.Approximate,
                position      = characterFootPosition
            };

            DirectorCore.GetMonsterSpawnDistance(DirectorCore.MonsterSpawnDistance.Close,
                                                 out placementRule.minDistance, out placementRule.maxDistance);
            GameObject gameObject = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(spawnCard, placementRule, rng));

            if (gameObject)
            {
                result = new Vector3?(gameObject.transform.position);
                Destroy(gameObject);
            }
            Destroy(spawnCard);
            return(result);
        }
Ejemplo n.º 2
0
        private static void CreateEclipseDoppelganger(CharacterMaster master, Xoroshiro128Plus rng)
        {
            var card = DoppelgangerSpawnCard.FromMaster(master);

            if (card is null)
            {
                return;
            }
            if (card.prefab is null)
            {
                card.prefab = MasterCatalog.GetMasterPrefab(defaultMasterIndex);
            }

            Transform spawnOnTarget;

            DirectorCore.MonsterSpawnDistance input;
            if (TeleporterInteraction.instance)
            {
                spawnOnTarget = TeleporterInteraction.instance.transform;
                input         = DirectorCore.MonsterSpawnDistance.Close;
            }
            else
            {
                spawnOnTarget = master.GetBody().coreTransform;
                input         = DirectorCore.MonsterSpawnDistance.Far;
            }
            DirectorPlacementRule directorPlacementRule = new DirectorPlacementRule
            {
                spawnOnTarget = spawnOnTarget,
                placementMode = DirectorPlacementRule.PlacementMode.NearestNode
            };

            DirectorCore.GetMonsterSpawnDistance(input, out directorPlacementRule.minDistance, out directorPlacementRule.maxDistance);
            DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(card, directorPlacementRule, rng);

            directorSpawnRequest.teamIndexOverride     = new TeamIndex?(TeamIndex.Monster);
            directorSpawnRequest.ignoreTeamMemberLimit = true;

            CombatSquad squad = null;

            DirectorSpawnRequest directorSpawnRequest2 = directorSpawnRequest;

            directorSpawnRequest2.onSpawnedServer = DelegateHelper.Combine(directorSpawnRequest2.onSpawnedServer, (res) =>
            {
                if (squad is null)
                {
                    squad = UnityEngine.Object.Instantiate <GameObject>(Resources.Load <GameObject>("Prefabs/NetworkedObjects/Encounters/ShadowCloneEncounter")).GetComponent <CombatSquad>();
                }
                squad.AddMember(res.spawnedInstance.GetComponent <CharacterMaster>());
            });

            DirectorCore.instance.TrySpawnObject(directorSpawnRequest);

            if (squad is not null)
            {
                NetworkServer.Spawn(squad.gameObject);
            }
            UnityEngine.Object.Destroy(card);
        }
        public bool AttemptSpawnOnTarget(On.RoR2.CombatDirector.orig_AttemptSpawnOnTarget orig, CombatDirector self, Transform spawnTarget, DirectorPlacementRule.PlacementMode placementMode)
        {
            //this.GetComponent< behaviourName as MonoBehaviour>



            if (self.gameObject == this.gameObject)
            {
                var credit       = self.monsterCredit;
                var monsterCards = self.monsterCards;


                //MoreShrines.Print("We good?");


                if (!this.cardPoolInitialized)
                {
                    List <CardPool> cardPools = new List <CardPool>();

                    foreach (var category in monsterCards.categories)
                    {
                        foreach (var card in category.cards)
                        {
                            if (cardPools.Any(pool => pool.cost == card.cost))
                            {
                                cardPools.Find(pool => pool.cost == card.cost).cards.Add(card);
                            }
                            else
                            {
                                var pool = new CardPool();
                                pool.cost = card.cost;
                                pool.cards.Add(card);
                                cardPools.Add(pool);
                            }
                        }
                    }
                    cardPoolInitialized = true;
                    cardPools.Sort((item1, item2) => { return(item1.cost.CompareTo(item2.cost)); });


                    var poolIndex = 0;

                    CardPool currentBasePool = cardPools[0];

                    foreach (var pool in cardPools)
                    {
                        if (pool.cost * countToSpawn < credit)
                        {
                            currentBasePool = pool;
                        }
                        else
                        {
                            break;
                        }
                        poolIndex++;
                    }

                    MoreShrines.Print("Preparing to spawn " + countToSpawn + " monsters.");

                    CardPool buffPool = cardPools[0];

                    var buffCount = 0;
                    for (var i = 0; i < countToSpawn; i++)
                    {
                        var count = countToSpawn - i;

                        if (cardPools.Count > poolIndex + 1)
                        {
                            if (((countToSpawn - count) * currentBasePool.cost) + (count * cardPools[poolIndex + 1].cost) < credit)
                            {
                                buffPool = cardPools[poolIndex + 1];
                                buffCount++;
                            }
                        }
                    }

                    for (var i = 0; i < countToSpawn - buffCount; i++)
                    {
                        finalSpawnOrder.Add(currentBasePool);
                    }

                    for (var i = 0; i < buffCount; i++)
                    {
                        finalSpawnOrder.Add(buffPool);
                    }
                }

                //

                if (finalSpawnOrder.Count > 0)
                {
                    self.currentMonsterCard = finalSpawnOrder[0].cards[Random.Range(0, finalSpawnOrder[0].cards.Count - 1)];
                    SpawnCard             spawnCard             = self.currentMonsterCard.spawnCard;
                    DirectorPlacementRule directorPlacementRule = new DirectorPlacementRule
                    {
                        placementMode   = placementMode,
                        spawnOnTarget   = spawnTarget,
                        preventOverhead = self.currentMonsterCard.preventOverhead
                    };
                    DirectorCore.GetMonsterSpawnDistance(self.currentMonsterCard.spawnDistance, out directorPlacementRule.minDistance, out directorPlacementRule.maxDistance);
                    directorPlacementRule.minDistance *= self.spawnDistanceMultiplier;
                    DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(spawnCard, directorPlacementRule, self.rng);
                    directorSpawnRequest.ignoreTeamMemberLimit = self.ignoreTeamSizeLimit;
                    directorSpawnRequest.teamIndexOverride     = new TeamIndex?(self.teamIndex);
                    directorSpawnRequest.onSpawnedServer       = new Action <SpawnCard.SpawnResult>(onCardSpawned);
                    if (!DirectorCore.instance.TrySpawnObject(directorSpawnRequest))
                    {
                        /*
                         * Debug.LogFormat("Spawn card {0} failed to spawn. Aborting cost procedures.", new object[]
                         * {
                         * spawnCard
                         * });*/
                        self.enabled = false;
                        return(false);
                    }
                }
                else
                {
                    self.enabled = false;
                    return(false);
                }


                self.spawnCountInCurrentWave += 1;

                return(true);
            }
            else
            {
                return(orig(self, spawnTarget, placementMode));
            }
        }