#Identify the color of the SCP-330 candy used by a player.
1 messages · Page 1 of 1 (latest)
i think there is a using scp 330 event or smth
Yes, I noticed that, but the event seems to only include PickUp and Interact, not eating.
Did I overlook something or make a mistake?
is there not wrapper for Scp330Pickup?
I’m not asking about picking up candies, but specifically detecting the color when a player eats them.
@clever vault
private void PlayerEvents_UsingItem(PlayerUsingItemEventArgs ev)
{
if(ev.UsableItem.Base is Scp330Bag bag)
{
bag.Candies.TryGet(bag.SelectedCandyId, out CandyKindID candy);
if(candy == CandyKindID.Rainbow)
{
// Do stuff
}
}
}
Something like this might work?
(Havent tested it)
it's just about casting
To anyone reading this later:
It seems that SCP-330 candy is only considered actually consumed after approximately 2 seconds of the consumption animation (this is an assumption). As a result, the timing of using and used events does not seem to align well with the actual moment of consumption.
This situation might require using Harmony, or perhaps another solution you can think of that works better.
The following approach should also work, though it is somewhat rudimentary. It can serve as a reference for a more refined solution:
internal static void UsingItem(PlayerUsingItemEventArgs e)
{
if (e.UsableItem.Type == ItemType.SCP330)
Timing.RunCoroutine(UseCandy(e.Player, e.UsableItem));
}
internal static IEnumerator<float> UseCandy(Player player, UsableItem usableItem)
{
if (player is null || !(usableItem.Base is Scp330Bag scp330Bag))
yield break;
CandyKindID candyKindID = CandyKindID.None;
List<CandyKindID> originalCandies = new List<CandyKindID>(scp330Bag.Candies);
if (originalCandies is null || originalCandies.Count == 0)
yield break;
if (originalCandies.Count is 1)
{
candyKindID = originalCandies[0];
yield return Timing.WaitForSeconds(2);
goto UseCandy;
}
yield return Timing.WaitForSeconds(2);
if (player is null || !player.IsAlive || !(player.Items.FirstOrDefault(item => item.Type == ItemType.SCP330)?.Base is Scp330Bag scp330BagB)) yield break;
List<CandyKindID> currentCandies = new List<CandyKindID>(scp330BagB.Candies);
if (originalCandies.Count != currentCandies.Count + 1)
yield break;
foreach(var candy in currentCandies)
{
originalCandies.Remove(candy);
}
if (originalCandies.Count != 1)
yield break;
candyKindID = originalCandies.FirstOrDefault();
UseCandy:;
/*do something (candyKindID)*/
}
i would recommend just
patching it
[HarmonyPatch(typeof(Scp330Bag), nameof(Scp330Bag.ServerOnUsingCompleted))]
public static class EatingCandyEvent
{
public class AteCandyEventArgs(Player player, CandyKindID candy) : EventArgs
{
public Player Player { get; } = player;
public CandyKindID Candy { get; } = candy;
}
public static event LabEventHandler<AteCandyEventArgs>? AteCandy;
private static void Postfix(Scp330Bag __instance)
{
if (!__instance.IsCandySelected)
return;
if (!Scp330Candies.CandiesById.TryGetValue(__instance.Candies[__instance.SelectedCandyId], out ICandy candy))
return;
AteCandy?.Invoke(new AteCandyEventArgs(Player.Get(__instance.Owner), candy.Kind);
}
}
and then:
EatingCandyEvent.AteCandy += ev =>
{
if (ev.Candy == CandyKindID.Yellow)
ev.Player.Kill();
};
FOR REFERENCE: This is not functional and needs to be a prefix not postfix and you need to handle it differently
Patch also according to @fathom comet is not required (read down)
Does LabAPI have a new UsingCompleted event that could be used?
No clue, i just gave the answer that I think is the solution currently but yeah it might be simpler
The ICandy is an unnecessary lookup for some purposes
But if you want the ServerApplyEffects logic and the SpawnChanceWeight then you can do it
Thank's for the shoutout homeslice @lapis fern