Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RoomSpawnpoint #110

Merged
merged 7 commits into from
Nov 5, 2024
Merged

Fix RoomSpawnpoint #110

merged 7 commits into from
Nov 5, 2024

Conversation

SrLicht
Copy link

@SrLicht SrLicht commented Sep 24, 2024

Description

Describe the changes
Fixes RoomSpawnPoint when used in Surface and also changing the spawn eventarg to WaitingForPlayers.

What is the current behavior? (You can also link to an open issue here)

What is the new behavior? (if this is a feature change)

Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

Other information:
Proof what the change is working and dont brake the position

PillsSpawnPoints its a List of RoomSpawnPoints where some are in Surface
imagen

imagen


Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentations

Submission checklist

  • I have checked the project can be compiled
  • I have tested my changes and it worked as expected

Patches (if there are any changes related to Harmony patches)

  • I have checked no IL patching errors in the console

Other

  • Still requires more testing

* Preventing use of TransformPoint(Offset) in Surface Room

* Added more delay
@SrLicht
Copy link
Author

SrLicht commented Sep 24, 2024

I fixed uwu @Josephfallen

@Josephfallen
Copy link

Thank you @SrLicht I'll look over it once I finish my code :)

@SrLicht
Copy link
Author

SrLicht commented Sep 24, 2024

Thank you n-n

I've already tested the changes and they work before my items appeared in Y 2000 and now they appear correctly in Surface

@Josephfallen
Copy link

@SrLicht If you want it reviewed you have to make it public

Copy link

@Josephfallen Josephfallen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If tested, It looks good

Copy link

@VALERA771 VALERA771 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If tested

After so much testing for a while, if CustomItems spawn too early they are not properly registered and spawn but without being custom items, also the locker spawn does not work because the base game did not finish generating all the lockers on the map yet, by adding this delay all those problems were eliminated.  I also thought it was fair to add a Try catch Log.Error in case there is any error when spawning custom items, currently if there is any you have no way of knowing.

Translated with DeepL.com (free version)
@SrLicht
Copy link
Author

SrLicht commented Oct 5, 2024

I was too lazy to type the commit from my damn cell phone so I used a translator.

Co-authored-by: Alex Rouse <alex@leronix.net>
Comment on lines -21 to +22
Timing.CallDelayed(0.5f, () => // Delay its necessary for the spawnpoints of lockers and rooms to be generated.
Timing.CallDelayed(2, () => // The delay is necessary because the generation of the lockers takes time, due to the way they are made in the base game.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be good if exiled OnWaitingPlayer get call when locker have finish to spawn too

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imagen
And how do you know when the lockers are created?

The Exiled lockers are created in the Awake of the base game lockers but the only way to know if they are already created would be to increase the delay that OnWaitingForPlayers already has.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fuck that kinda problematic yeah

@louis1706
Copy link

Write bug report for locker not being prepared when OnWaitingPlayer is call

@SrLicht
Copy link
Author

SrLicht commented Oct 20, 2024

Write bug report for locker not being prepared when OnWaitingPlayer is call

In Github or Discord ?

@iamalexrouse
Copy link

Write bug report for locker not being prepared when OnWaitingPlayer is call

In Github or Discord ?

In GitHub is usually better, but it's more preference and GitHub allows for issues to be linked with pull requests.

@louis1706
Copy link

Write bug report for locker not being prepared when OnWaitingPlayer is call

In Github or Discord ?

Discord & Github (or only github)

@SrLicht
Copy link
Author

SrLicht commented Oct 21, 2024

@louis1706
What do you think about this ?

Spawn the customitems in RoundStarted but move the spawn handler to a coroutine with a delay of a couple of frames to avoid lag when spawning too many items.

/// <summary>
/// Spawns <see cref="CustomItem"/>s inside <paramref name="spawnPoints"/>.
/// </summary>
/// <param name="spawnPoints">The spawn points <see cref="IEnumerable{T}"/>.</param>
/// <param name="limit">The spawn limit.</param>
/// <returns>Returns the number of spawned items.</returns>
public virtual uint Spawn(IEnumerable<SpawnPoint> spawnPoints, uint limit)
{
    uint spawned = 0;

    foreach (SpawnPoint spawnPoint in spawnPoints)
    {
        Log.Debug($"Attempting to spawn {Name} at {spawnPoint.Position}.");

        // Check if the spawn chance or the limit prevents spawning.
        if (Loader.Random.NextDouble() * 100 >= spawnPoint.Chance || (limit > 0 && spawned >= limit))
            continue;

        spawned++;

        // Call the private method to handle the item spawn with delay.
        Timing.RunCoroutine(SpawnItemWithDelay(spawnPoint));
    }

    return spawned;
}
        /// <summary>
        /// Handles the spawning logic for a single item at a given spawn point,
        /// including any necessary delays to prevent spawning too many items at once.
        /// </summary>
        /// <param name="spawnPoint">The spawn point where the item should be spawned.</param>
        /// <returns>Yields control back to allow other items to spawn with a delay.</returns>
        protected virtual IEnumerator<float> SpawnItemWithDelay(SpawnPoint spawnPoint)
        {
            // Special handling for dynamic spawn points, such as spawning inside lockers.
#pragma warning disable CS0618 // Type or member is obsolete
            if (spawnPoint is DynamicSpawnPoint dynamicSpawnPoint && dynamicSpawnPoint.Location == SpawnLocationType.InsideLocker)
            {
                for (int i = 0; i < 50; i++)
                {
                    if (Map.Lockers is null)
                    {
                        Log.Debug($"{nameof(Spawn)}: Locker list is null.");
                        continue;
                    }

                    Locker locker = Map.Lockers[Loader.Random.Next(Map.Lockers.Count)];

                    if (locker is null)
                    {
                        Log.Debug($"{nameof(Spawn)}: Selected locker is null.");
                        continue;
                    }

                    if (locker.Loot is null)
                    {
                        Log.Debug($"{nameof(Spawn)}: Invalid locker location. Attempting to find a new one..");
                        continue;
                    }

                    if (locker.Chambers is null)
                    {
                        Log.Debug($"{nameof(Spawn)}: Locker chambers are null");
                        continue;
                    }

                    LockerChamber chamber = locker.Chambers[Loader.Random.Next(Mathf.Max(0, locker.Chambers.Length - 1))];

                    if (chamber is null)
                    {
                        Log.Debug($"{nameof(Spawn)}: Chamber is null");
                        continue;
                    }

                    Vector3 position = chamber._spawnpoint.transform.position;
                    Pickup? pickup = Spawn(position, null);

                    // Update firearm status if applicable.
                    if (pickup?.Base is BaseFirearmPickup firearmPickup && this is CustomWeapon customWeapon)
                    {
                        firearmPickup.Status = new FirearmStatus(customWeapon.ClipSize, firearmPickup.Status.Flags, firearmPickup.Status.Attachments);
                        firearmPickup.NetworkStatus = firearmPickup.Status;
                    }

                    Log.Debug($"Spawned {Name} at {position} ({spawnPoint.Name})");

                    // Delay before attempting the next spawn.
                    yield return Timing.WaitForSeconds(0.1f);
                    break;
                }
            }
            else
            {
                Pickup? pickup = Spawn(spawnPoint.Position, null);

                // Update firearm status if applicable.
                if (pickup?.Base is BaseFirearmPickup firearmPickup && this is CustomWeapon customWeapon)
                {
                    firearmPickup.Status = new FirearmStatus(customWeapon.ClipSize, firearmPickup.Status.Flags, firearmPickup.Status.Attachments);
                    firearmPickup.NetworkStatus = firearmPickup.Status;
                }

                Log.Debug($"Spawned {Name} at {spawnPoint.Position} ({spawnPoint.Name})");

                // Delay before attempting the next spawn.
                yield return Timing.WaitForSeconds(0.1f);
            }
#pragma warning restore CS0618 // Type or member is obsolete
        }
        

Testings

I was testing a few rounds and spawned around 50 pickups at the start of the round and did not notice any micro-lags from using the method.

imagen

@VALERA771 VALERA771 merged commit 85b4e80 into ExMod-Team:dev Nov 5, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants