Skip to content
This repository was archived by the owner on Jul 8, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 54 additions & 5 deletions EXILED/Exiled.API/Features/Toys/AdminToy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@

namespace Exiled.API.Features.Toys
{
using System;
using System.Collections.Generic;
using System.Linq;

using AdminToys;

using Enums;
using Exiled.API.Interfaces;
using Footprinting;
using InventorySystem.Items;
using Interfaces;
using Mirror;

using UnityEngine;

/// <summary>
Expand Down Expand Up @@ -183,6 +180,52 @@ public static AdminToy Get(AdminToyBase adminToyBase)
public static T Get<T>(AdminToyBase adminToyBase)
where T : AdminToy => Get(adminToyBase) as T;

/// <summary>
/// Creates a new <see cref="AdminToy"/>.
/// </summary>
/// <param name="position"> The position of the <see cref="AdminToy"/>.</param>
/// <param name="rotation"> The rotation of the <see cref="AdminToy"/>.</param>
/// <param name="scale"> The scale of the <see cref="AdminToy"/>.</param>
/// <param name="spawn"> Whether the <see cref="AdminToy"/> should be initially spawned.</param>
/// <typeparam name="T"> The specific type of <see cref="AdminToyBase"/> to instantiate (e.g., <see cref="CapybaraToy"/>, <see cref="TextToy"/>).</typeparam>
/// <returns> The new <see cref="AdminToy"/>.</returns>
/// <exception cref="InvalidOperationException"> Thrown if no prefab with a <typeparamref name="T"/> component exists in <see cref="NetworkClient.prefabs"/>.</exception>
public static AdminToy Create<T>(Vector3? position, Vector3? rotation, Vector3? scale, bool spawn)
where T : AdminToyBase
{
if (PrefabCache<T>.Prefab == null)
{
T t = default(T);
using (Dictionary<uint, GameObject>.ValueCollection.Enumerator enumerator = NetworkClient.prefabs.Values.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (enumerator.Current != null && enumerator.Current.TryGetComponent(out t))
{
break;
}
}
}

if (t == null)
{
throw new InvalidOperationException(string.Format("No prefab in NetworkClient.prefabs has component type {0}", typeof(T)));
}

PrefabCache<T>.Prefab = t;
}
Comment on lines +196 to +216

Choose a reason for hiding this comment

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

uhm why ?

Copy link
Author

Choose a reason for hiding this comment

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

without that, the prefab are null.

Choose a reason for hiding this comment

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

but why using PrefabCache ?

Choose a reason for hiding this comment

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

PrefabHelper.GetPrefab(PrefabType);


T t2 = UnityEngine.Object.Instantiate(PrefabCache<T>.Prefab);
t2.transform.position = position ?? Vector3.zero;
t2.transform.rotation = Quaternion.Euler(rotation ?? Vector3.zero);
t2.transform.localScale = scale ?? Vector3.one;

if (spawn)
NetworkServer.Spawn(t2.gameObject);

return Get(t2);
}

/// <summary>
/// Spawns the toy into the game. Use <see cref="UnSpawn"/> to remove it.
/// </summary>
Expand All @@ -201,5 +244,11 @@ public void Destroy()
BaseToAdminToy.Remove(AdminToyBase);
NetworkServer.Destroy(AdminToyBase.gameObject);
}

private static class PrefabCache<T>
where T : AdminToyBase
{
public static T Prefab { get; set; }
}
}
}
31 changes: 27 additions & 4 deletions EXILED/Exiled.API/Features/Toys/Capybara.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace Exiled.API.Features.Toys
{
using AdminToys;
using Enums;
using Exiled.API.Interfaces;
using Interfaces;
using Mirror;
using UnityEngine;

/// <summary>
/// A wrapper class for <see cref="CapybaraToy"/>.
Expand All @@ -34,12 +36,33 @@ internal Capybara(CapybaraToy capybaraToy)
public CapybaraToy Base { get; }

/// <summary>
/// Gets or sets a value indicating whether the capybara can be collided with.
/// Gets or sets a value indicating whether the capybara can be collided with. Only server side.
/// </summary>
public bool Collidable
{
get => Base.Network_collisionsEnabled;
set => Base.Network_collisionsEnabled = value;
get => Base.CollisionsEnabled;
set => Base.CollisionsEnabled = value;
}

/// <summary>
/// Creates a new <see cref="Capybara"/>.
/// </summary>
/// <param name="posititon"> The position of the <see cref="Capybara"/>.</param>
/// <param name="rotation"> The rotation of the <see cref="Capybara"/>.</param>
/// <param name="scale"> The scale of the <see cref="Capybara"/>.</param>
/// <param name="spawn"> Whether the <see cref="Capybara"/> should be initially spawned.</param>
/// <returns> The new <see cref="Capybara"/>.</returns>
public static Capybara Create(Vector3? posititon, Vector3? rotation, Vector3? scale, bool spawn)
{
Capybara capybara = new Capybara(Object.Instantiate(Prefab));
capybara.Position = posititon ?? Vector3.zero;
capybara.Rotation = Quaternion.Euler(rotation ?? Vector3.zero);
capybara.Scale = scale ?? Vector3.one;

if (spawn)
capybara.Spawn();

return capybara;
}
}
}
33 changes: 29 additions & 4 deletions EXILED/Exiled.API/Features/Toys/Text.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Exiled.API.Features.Toys
{
using AdminToys;
using Enums;
using Exiled.API.Interfaces;
using Interfaces;
using UnityEngine;

/// <summary>
Expand All @@ -20,9 +20,9 @@ public class Text : AdminToy, IWrapper<TextToy>
/// <summary>
/// Initializes a new instance of the <see cref="Text"/> class.
/// </summary>
/// <param name="speakerToy">The <see cref="TextToy"/> of the toy.</param>
internal Text(TextToy speakerToy)
: base(speakerToy, AdminToyType.TextToy) => Base = speakerToy;
/// <param name="textToy">The <see cref="TextToy"/> of the toy.</param>
internal Text(TextToy textToy)
: base(textToy, AdminToyType.TextToy) => Base = textToy;

/// <summary>
/// Gets the prefab.
Expand Down Expand Up @@ -51,5 +51,30 @@ public Vector2 DisplaySize
get => Base.Network_displaySize;
set => Base.Network_displaySize = value;
}

/// <summary>
/// Creates a new <see cref="Text"/>.
/// </summary>
/// <param name="newText"> The text to shown <see cref="TextFormat"/>.</param>
/// <param name="displaySize"> The size of the <see cref="DisplaySize"/>.</param>
/// <param name="posititon"> The position of the <see cref="Text"/>.</param>
/// <param name="rotation"> The rotation of the <see cref="Text"/>.</param>
/// <param name="scale"> The scale of the <see cref="Text"/>.</param>
/// <param name="spawn"> Whether the <see cref="Text"/> should be initially spawned.</param>
/// <returns> The new <see cref="Text"/>.</returns>
public static Text Create(string newText, Vector2? displaySize, Vector3? posititon, Vector3? rotation, Vector3? scale, bool spawn)
{
Text text = new Text(Object.Instantiate(Prefab));
text.Position = posititon ?? Vector3.zero;
text.Rotation = Quaternion.Euler(rotation ?? Vector3.zero);
text.Scale = scale ?? Vector3.one;

text.TextFormat = newText ?? string.Empty;
text.DisplaySize = displaySize ?? TextToy.DefaultDisplaySize;

if (spawn)
text.Spawn();
return text;
}
}
}