C#:
using System;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Libraries;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Facepunch;
using Rust.Ai.HTN;
using Rust.Ai.Gen2;
#region Changelogs and ToDo
/**********************************************************************
*
* API // Pre definition trigger on Alpha/Omega animal kill (before the animal type is defined)
void OnAlphaAnimalKilled(BaseAnimalNPC animal, HitInfo info);
void OmegaAnimalKilled(BaseAnimalNPC animal, HitInfo info);
// Alpha animal kills
void OnAlphaBearKilled(BaseAnimalNPC animal, HitInfo info);
void OnAlphaPolarbearKilled(BaseAnimalNPC animal, HitInfo info);
void OnAlphaWolfKilled(BaseAnimalNPC animal, HitInfo info);
void OnAlphaCrocodileKilled(BaseAnimalNPC animal, HitInfo info);
void OnAlphaPantherKilled(BaseAnimalNPC animal, HitInfo info);
void OnAlphaTigerKilled(BaseAnimalNPC animal, HitInfo info);
// Omega animal kills
void OnOmegaBearKilled(BaseAnimalNPC animal, HitInfo info);
void OnOmegaPolarbearKilled(BaseAnimalNPC animal, HitInfo info);
void OnOmegaWolfKilled(BaseAnimalNPC animal, HitInfo info);
// Omega animal spawns
void OnOmegaBearSpawned(BaseAnimalNPC animal);
void OnOmegaPolarbearSpawned(BaseAnimalNPC animal);
void OnOmegaWolfSpawned(BaseAnimalNPC animal);
*
**********************************************************************/
#endregion
namespace Oxide.Plugins
{
[Info("AlphaAnimals" , "Krungh Crow" , "1.3.2")]
[Description("Alpha Animal events")]
class AlphaAnimals : RustPlugin
{
#region PluginReference
[PluginReference]
private Plugin Economics, ServerRewards;
#endregion
#region Variables
public static AlphaAnimals instance;
ulong chaticon = 0;
string prefix;
bool Debug = false;
bool UseEconomics;
bool UseSR;
string _Wolf = "assets/rust.ai/agents/wolf/wolf.prefab";
string _Bear = "assets/rust.ai/agents/bear/bear.prefab";
string _PBear = "assets/rust.ai/agents/bear/polarbear.prefab";
string _WolfHowl = "assets/bundled/prefabs/fx/player/howl.prefab";
string _WaterSplash = "assets/bundled/prefabs/fx/explosions/water_bomb.prefab";
string _AnimalType;
int _Packsize;
const string TipSimple = "alphaanimals.tipsimple";
const string TipFull = "alphaanimals.tipfull";
const string Eco_Perm = "alphaanimals.economics";
const string SR_Perm = "alphaanimals.serverrewards";
#endregion
#region MonoBehaviour
private class Animals : MonoBehaviour
{
private Vector3 home;
private BaseNpc npc;
private float distance;
private float time;
public static List<Animals> OmegaAnimals = new List<Animals>();
private void Awake()
{
npc = GetComponent<BaseAnimalNPC>();
if (npc == null)
{
instance.Puts("BaseAnimalNPC component is missing from this GameObject.");
return;
}
home = npc.transform.position;
distance = 10f;
enabled = false;
InvokeRepeating("CheckDistance" , 1f , 2f);
InvokeRepeating("CheckBehaviour" , 1f , 2f);
npc.SetFact(BaseNpc.Facts.Speed , (byte)BaseNpc.SpeedEnum.Walk , true , true);
}
private void CheckBehaviour()
{
if (npc == null || npc.IsDestroyed) return;
npc.SetFact(BaseNpc.Facts.IsAfraid , 1 , true , true);
}
private void CheckDistance()
{
if (npc == null || npc.IsDestroyed)
{
instance?.Puts("npc is null or destroyed in CheckDistance.");
return;
}
Vector3 npcPosition = npc.transform.position;
string npcName = npc.name;
float distanceFromHome = Vector3.Distance(home , npcPosition);
if (distanceFromHome < 2)
{
npc.CurrentBehaviour = BaseNpc.Behaviour.Idle;
npc.StopMoving();
instance?.Puts($"{npcName} is at home spawn point {home}");
return;
}
if (distanceFromHome > distance)
{
npc.UpdateDestination(home);
npc.CurrentBehaviour = BaseNpc.Behaviour.Wander;
npc.SetFact(BaseNpc.Facts.Speed , (byte)BaseNpc.SpeedEnum.Walk , true , true);
instance?.Puts($"Sending {npcName} home {home}");
}
}
public void DoDestroy()
{
if (npc != null)
{
npc.Kill();
}
}
private void OnDestroy()
{
CancelInvoke("CheckDistance");
CancelInvoke("CheckBehaviour");
if (OmegaAnimals != null && OmegaAnimals.Contains(this))
{
OmegaAnimals.Remove(this);
}
}
}
#endregion
private bool IsScientist2(BaseNPC2 npc)
{
return npc != null && npc.Categorize() == "Scientist2";
}
#region Configuration
void Init()
{
if (!LoadConfigVariables())
{
Puts("Config file issue detected. Please delete file, or check syntax and fix.");
return;
}
Debug = configData.PlugCFG.Debug;
UseEconomics = configData.Rewards.UseEco;
UseSR = configData.RewardsSR.UseSR;
prefix = configData.PlugCFG.Prefix;
chaticon = configData.PlugCFG.Chaticon;
permission.RegisterPermission(TipSimple , this);
permission.RegisterPermission(TipFull , this);
permission.RegisterPermission(Eco_Perm , this);
permission.RegisterPermission(SR_Perm , this);
if (Debug) Puts($"[Debug] trigger for Debug is true");
}
private ConfigData configData;
class ConfigData
{
[JsonProperty(PropertyName = "Plugin")]
public SettingsPlugin PlugCFG = new SettingsPlugin();
[JsonProperty(PropertyName = "Economics")]
public RewardingsEco Rewards = new RewardingsEco();
[JsonProperty(PropertyName = "ServerRewards")]
public RewardingsSR RewardsSR = new RewardingsSR();
[JsonProperty(PropertyName = "Animals")]
public AnimalData Animals = new AnimalData();
}
class RewardingsSR
{
[JsonProperty(PropertyName = "Use ServerRewards")]
public bool UseSR = false;
[JsonProperty(PropertyName = "Alpha Bear points")]
public int BearPoints = 300;
[JsonProperty(PropertyName = "Omega Bear points")]
public int OBearPoints = 100;
[JsonProperty(PropertyName = "Alpha Polarbear points")]
public int PBearPoints = 400;
[JsonProperty(PropertyName = "Omega Polarbear points")]
public int OPBearPoints = 150;
[JsonProperty(PropertyName = "Alpha Wolf points")]
public int WolfPoints = 200;
[JsonProperty(PropertyName = "Omega Wolf points")]
public int OWolfPoints = 50;
[JsonProperty(PropertyName = "Alpha Crocodile points")]
public int CrocPoints = 500;
[JsonProperty(PropertyName = "Alpha Panther points")]
public int PantherPoints = 200;
[JsonProperty(PropertyName = "Alpha Tiger points")]
public int TigerPoints = 200;
}
class RewardingsEco
{
[JsonProperty(PropertyName = "Use Economics")]
public bool UseEco = false;
[JsonProperty(PropertyName = "Alpha Bear points")]
public double BearPoints = 300;
[JsonProperty(PropertyName = "Omega Bear points")]
public double OBearPoints = 100;
[JsonProperty(PropertyName = "Alpha Polarbear points")]
public double PBearPoints = 400;
[JsonProperty(PropertyName = "Omega Polarbear points")]
public double OPBearPoints = 150;
[JsonProperty(PropertyName = "Alpha Wolf points")]
public double WolfPoints = 200;
[JsonProperty(PropertyName = "Omega Wolf points")]
public double OWolfPoints = 50;
[JsonProperty(PropertyName = "Alpha Crocodile points")]
public int CrocPoints = 500;
[JsonProperty(PropertyName = "Alpha Panther points")]
public int PantherPoints = 200;
[JsonProperty(PropertyName = "Alpha Tiger points")]
public int TigerPoints = 200;
}
class AnimalData
{
[JsonProperty(PropertyName = "Life Duration (minutes)")]
public float Lifetime = 5f;
[JsonProperty(PropertyName = "Spawn Radius")]
public int Radius = 12;
[JsonProperty(PropertyName = "Bear Packsize")]
public int PacksizeB = 2;
[JsonProperty(PropertyName = "Bear settings")]
public OmegaSettings OmegaB = new OmegaSettings();
[JsonProperty(PropertyName = "Polarbear Packsize")]
public int PacksizePB = 2;
[JsonProperty(PropertyName = "Polarbear settings")]
public OmegaSettings OmegaPB = new OmegaSettings();
[JsonProperty(PropertyName = "Wolf Packsize")]
public int PacksizeW = 5;
[JsonProperty(PropertyName = "Wolf settings")]
public OmegaSettings OmegaW = new OmegaSettings();
[JsonProperty(PropertyName = "Use Random Skins")]
public bool RandomSkins = false;
[JsonProperty(PropertyName = "Loot settings (Alphas)")]
public LootSettings Loots = new LootSettings();
}
class OmegaSettings
{
[JsonProperty(PropertyName = "Min HP")]
public float MinHP = 350f;
[JsonProperty(PropertyName = "Max HP")]
public float MaxHP = 600f;
}
class SettingsPlugin
{
[JsonProperty(PropertyName = "Debug")]
public bool Debug = false;
[JsonProperty(PropertyName = "Chat Steam64ID")]
public ulong Chaticon = 0;
[JsonProperty(PropertyName = "Chat Prefix")]
public string Prefix = "[<color=orange>AlphaAnimals</color>] ";
[JsonProperty(PropertyName = "Anounce Alpha spawns")]
public bool Anounce = true;
}
class LootSettings
{
[JsonProperty(PropertyName = "Spawn Min Amount Items")]
public int MinAmount = 1;
[JsonProperty(PropertyName = "Spawn Max Amount Items")]
public int MaxAmount = 3;
[JsonProperty(PropertyName = "Loot Table" , ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<LootItems> Loot { get; set; } = DefaultLoot;
}
private bool LoadConfigVariables()
{
try
{
configData = Config.ReadObject<ConfigData>();
}
catch
{
return false;
}
SaveConf();
return true;
}
protected override void LoadDefaultConfig()
{
Puts("Fresh install detected Creating a new config file.");
configData = new ConfigData();
SaveConf();
}
void SaveConf() => Config.WriteObject(configData , true);
#endregion
#region LanguageAPI
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string , string>
{
["AlphaAnnounce"] = "A <color=yellow>{animal}</color> was located around <color=orange>Grid {location}</color>" ,
["EngageSimple"] = "<color=yellow>carefull This is a {animal}</color>" ,
["EngageFull"] = "<color=yellow>carefull This is a {animal} {health} HP</color>" ,
["EngageSimpleKill"] = "<color=yellow>You killed the {animal}</color>" ,
["EngageFullKill"] = "<color=yellow>You got points killing the {animal}</color>" ,
["KillAlpha"] = "You Killed a <color=green>{animal}</color> and <color=green>{packsize} Omega's</color> are summoned" ,
["KillAlphaAll"] = "{player} Killed a <color=green>{animal}</color> and <color=green>{packsize} Omega's</color> are summoned" ,
["KillOmega"] = "You Killed the <color=green>{animal}</color>" ,
} , this);
}
#endregion
#region Oxide Hooks
private void Unload()
{
RemoveOmegas();
}
void OnEntityDeath(BaseEntity entity , HitInfo info)
{
if (entity is BaseAnimalNPC animal)
{
BasePlayer attacker = info?.InitiatorPlayer;
if (attacker == null) return;
double Reward = 0;
int SRReward = 0;
int _Packsize = 0;
float MinHealth = 100.0f;
float MaxHealth = 300.0f;
string AnimalPrefab = null;
if (animal.name.Contains("Alpha"))
{
Interface.CallHook("OnAlphaAnimalKilled" , animal , info);
Reward = GetEcoRewardForAnimal(animal);
SRReward = GetSRRewardForAnimal(animal);
switch (animal)
{
case Bear _:
Interface.CallHook("OnAlphaBearKilled" , animal , info);
SpawnRadLoot(animal.transform.position + new Vector3(0f , 0.5f , 0f) , animal.transform.rotation , "Alpha Bear");
AnimalPrefab = _Bear;
_Packsize = configData.Animals.PacksizeB;
MinHealth = configData.Animals.OmegaB.MinHP;
MaxHealth = configData.Animals.OmegaB.MaxHP;
break;
case Polarbear _:
Interface.CallHook("OnAlphaPolarbearKilled" , animal , info);
SpawnRadLoot(animal.transform.position + new Vector3(0f , 0.5f , 0f) , animal.transform.rotation , "Alpha Polarbear");
AnimalPrefab = _PBear;
_Packsize = configData.Animals.PacksizePB;
MinHealth = configData.Animals.OmegaPB.MinHP;
MaxHealth = configData.Animals.OmegaPB.MaxHP;
break;
}
for (int i = 0; i < _Packsize; i++)
{
SpawnAnimal(attacker.transform.position , AnimalPrefab , MinHealth , MaxHealth);
}
Player.Message(attacker , msg("KillAlpha").Replace("{animal}" , animal.name).Replace("{packsize}" , _Packsize.ToString()) , chaticon);
Effect.server.Run(_WaterSplash , animal.transform.position);
}
if (IsOmegaAnimal(animal))
{
Interface.CallHook("OnOmegaAnimalKilled" , animal , info);
switch (animal)
{
case Bear _:
Interface.CallHook("OnOmegaBearKilled" , animal , info);
break;
case Polarbear _:
Interface.CallHook("OnOmegaPolarBearKilled" , animal , info);
break;
}
Reward = GetEcoRewardForAnimal(animal);
SRReward = GetSRRewardForAnimal(animal);
Effect.server.Run(_WaterSplash , animal.transform.position);
}
if (UseEconomics && Economics != null && HasPerm(attacker , Eco_Perm) && Reward != 0)
{
Economics.Call("Deposit" , attacker.userID , Reward);
if (Debug) Puts($"{attacker.displayName} killed a {animal.name} and got {Reward} Economic points");
}
if (UseSR && ServerRewards != null && HasPerm(attacker , SR_Perm) && SRReward != 0)
{
ServerRewards.Call("AddPoints" , attacker.userID , SRReward);
if (Debug) Puts($"{attacker.displayName} killed a {animal.name} and got {SRReward} ServerRewards points");
}
if (Debug) Puts($"Target : {animal} Event : {animal.name} killed by {attacker.displayName}");
if (IsAlphaOrOmega(animal.name))
{
if (HasPerm(attacker , TipFull) && (HasPerm(attacker , Eco_Perm) || HasPerm(attacker , SR_Perm)))
{
TIP(attacker , Info("EngageFullKill").Replace("{animal}" , animal.name) , 16 , "white" , 0f);
}
else if (HasPerm(attacker , TipSimple))
{
TIP(attacker , Info("EngageSimpleKill").Replace("{animal}" , animal.name) , 16 , "white" , 0f);
}
}
return;
}
if (entity is BaseNPC2 npc)
{
if (IsScientist2(npc))
return;
BasePlayer attacker = info?.InitiatorPlayer;
if (attacker == null) return;
double Reward = 0;
int SRReward = 0;
int _Packsize = 0;
float MinHealth = 100.0f;
float MaxHealth = 300.0f;
string AnimalPrefab = null;
if (npc.name.Contains("Alpha"))
{
Interface.CallHook("OnAlphaAnimalKilled" , npc , info);
Reward = GetEcoRewardForAnimal(npc);
SRReward = GetSRRewardForAnimal(npc);
switch (npc)
{
case Wolf2 _:
Interface.CallHook("OnAlphaWolf2Killed" , npc , info);
SpawnRadLoot(npc.transform.position + new Vector3(0f , 0.5f , 0f) , npc.transform.rotation , "Alpha Wolf2");
Effect.server.Run(_WolfHowl , npc.transform.position);
AnimalPrefab = _Wolf;
_Packsize = configData.Animals.PacksizeW;
MinHealth = configData.Animals.OmegaW.MinHP;
MaxHealth = configData.Animals.OmegaW.MaxHP;
break;
case Panther _:
Interface.CallHook("OnAlphaPantherKilled" , npc , info);
SpawnRadLoot(npc.transform.position + new Vector3(0f , 0.5f , 0f) , npc.transform.rotation , "Alpha Panther");
Effect.server.Run(_WolfHowl , npc.transform.position);
break;
case Tiger _:
Interface.CallHook("OnAlphaTigerKilled" , npc , info);
SpawnRadLoot(npc.transform.position + new Vector3(0f , 0.5f , 0f) , npc.transform.rotation , "Alpha Tiger");
Effect.server.Run(_WolfHowl , npc.transform.position);
break;
case Crocodile _:
Interface.CallHook("OnAlphaCrocodileKilled" , npc , info);
SpawnRadLoot(npc.transform.position + new Vector3(0f , 0.5f , 0f) , npc.transform.rotation , "Alpha Tiger");
Effect.server.Run(_WolfHowl , npc.transform.position);
break;
}
for (int i = 0; i < _Packsize; i++)
{
SpawnAnimal(attacker.transform.position , AnimalPrefab , MinHealth , MaxHealth);
}
Player.Message(attacker , msg("KillAlpha").Replace("{animal}" , npc.name).Replace("{packsize}" , _Packsize.ToString()) , chaticon);
Effect.server.Run(_WaterSplash , npc.transform.position);
}
if (IsOmegaAnimal(npc))
{
Interface.CallHook("OnOmegaAnimalKilled" , npc , info);
switch (npc)
{
case Wolf2 _:
Interface.CallHook("OnOmegaWolf2Killed" , npc , info);
Effect.server.Run(_WolfHowl , npc.transform.position);
break;
}
Reward = GetEcoRewardForAnimal(npc);
SRReward = GetSRRewardForAnimal(npc);
Effect.server.Run(_WaterSplash , npc.transform.position);
}
if (UseEconomics && Economics != null && HasPerm(attacker , Eco_Perm) && Reward != 0)
{
Economics.Call("Deposit" , attacker.userID , Reward);
if (Debug) Puts($"{attacker.displayName} killed a {npc.name} and got {Reward} Economic points");
}
if (UseSR && ServerRewards != null && HasPerm(attacker , SR_Perm) && SRReward != 0)
{
ServerRewards.Call("AddPoints" , attacker.userID , SRReward);
if (Debug) Puts($"{attacker.displayName} killed a {npc.name} and got {SRReward} ServerRewards points");
}
if (Debug) Puts($"Target : {npc} Event : {npc.name} killed by {attacker.displayName}");
if (IsAlphaOrOmega(npc.name))
{
if (HasPerm(attacker , TipFull) && (HasPerm(attacker , Eco_Perm) || HasPerm(attacker , SR_Perm)))
{
TIP(attacker , Info("EngageFullKill").Replace("{animal}" , npc.name) , 16 , "white" , 0f);
}
else if (HasPerm(attacker , TipSimple))
{
TIP(attacker , Info("EngageSimpleKill").Replace("{animal}" , npc.name) , 16 , "white" , 0f);
}
}
}
}
void OnEntitySpawned(BaseEntity entity)
{
if (entity is BaseAnimalNPC animal)
{
var animalEntity = animal;
timer.Once(1f , () =>
{
if (animalEntity != null && animalEntity.transform != null && (animalEntity.name.Contains("Alpha") || animalEntity.name.Contains("Omega")))
{
if (animalEntity.name.Contains("Alpha") && configData.PlugCFG.Anounce)
{
foreach (var player in BasePlayer.activePlayerList)
{
if (player != null && player.IsConnected)
{
Player.Message(player , msg("AlphaAnnounce")
.Replace("{animal}" , animalEntity.name)
.Replace("{location}" , GetGrid(animalEntity.transform.position)) , chaticon);
}
}
}
}
});
return;
}
if (entity is BaseNPC2 npc)
{
if (IsScientist2(npc))
return;
var npcEntity = npc;
timer.Once(1f , () =>
{
if (npcEntity != null && npcEntity.transform != null && (npcEntity.name.Contains("Alpha") || npcEntity.name.Contains("Omega")))
{
if (Debug) Puts($"Target : {npcEntity} ({(int)npcEntity.health}HP) Event : {npcEntity.name} Spawned");
if (npcEntity.name.Contains("Alpha") && configData.PlugCFG.Anounce)
{
foreach (var player in BasePlayer.activePlayerList)
{
Player.Message(player , msg("AlphaAnnounce")
.Replace("{animal}" , npcEntity.name)
.Replace("{location}" , GetGrid(npcEntity.transform.position)) , chaticon);
}
}
}
});
}
}
void OnEntityTakeDamage(BaseEntity entity , HitInfo info)
{
if (entity is BaseAnimalNPC animalEntity)
{
HandleAnimalDamage(animalEntity , info);
return;
}
if (entity is BaseNPC2 npcEntity)
{
if (IsScientist2(npcEntity))
return;
HandleNpcDamage(npcEntity , info);
}
}
void HandleAnimalDamage(BaseAnimalNPC animalEntity , HitInfo info)
{
if (animalEntity == null || info?.InitiatorPlayer == null) return;
BasePlayer player = info.InitiatorPlayer;
if (animalEntity.name.Contains("Alpha") || animalEntity.name.Contains("Omega"))
{
var Type = animalEntity.name;
if (HasPerm(player , TipFull))
{
var Health = Convert.ToInt32(animalEntity.health);
var MaxHealth = Convert.ToInt32(animalEntity._maxHealth);
string FullHealth = $"{Health}/{MaxHealth}";
WARNING(player , Info("EngageFull").Replace("{animal}" , Type).Replace("{health}" , FullHealth) , 16 , "blue" , 0f);
}
else if (HasPerm(player , TipSimple))
{
WARNING(player , Info("EngageSimple").Replace("{animal}" , Type) , 16 , "blue" , 0f);
}
}
}
void HandleNpcDamage(BaseNPC2 npcEntity , HitInfo info)
{
if (npcEntity == null || info?.InitiatorPlayer == null) return;
if (IsScientist2(npcEntity)) return;
BasePlayer player = info.InitiatorPlayer;
if (npcEntity.name.Contains("Alpha") || npcEntity.name.Contains("Omega"))
{
var Type = npcEntity.name;
if (HasPerm(player , TipFull))
{
var Health = Convert.ToInt32(npcEntity.health);
var MaxHealth = Convert.ToInt32(npcEntity._maxHealth);
string FullHealth = $"{Health}/{MaxHealth}";
WARNING(player , Info("EngageFull").Replace("{animal}" , Type).Replace("{health}" , FullHealth) , 16 , "blue" , 0f);
}
else if (HasPerm(player , TipSimple))
{
WARNING(player , Info("EngageSimple").Replace("{animal}" , Type) , 16 , "blue" , 0f);
}
}
}
#endregion
#region Helpers
bool IsAlphaOrOmega(string animalName)
{
return animalName.Contains("Alpha") || animalName.Contains("Omega");
}
double GetEcoRewardForAnimal(BaseEntity entity)
{
var npc = entity as BaseNPC2;
if (npc != null && IsScientist2(npc))
return 0;
bool isAlpha = entity.name.Contains("Alpha");
bool isOmega = entity.name.Contains("Omega");
switch (entity)
{
case BaseAnimalNPC animal when animal is Bear _ && isAlpha:
return configData.Rewards.BearPoints;
case BaseAnimalNPC animal when animal is Bear _ && isOmega:
return configData.Rewards.OBearPoints;
case BaseAnimalNPC animal when animal is Polarbear _ && isAlpha:
return configData.Rewards.PBearPoints;
case BaseAnimalNPC animal when animal is Polarbear _ && isOmega:
return configData.Rewards.OPBearPoints;
case BaseNPC2 n when n is Wolf2 _ && isAlpha:
return configData.Rewards.WolfPoints;
case BaseNPC2 n when n is Wolf2 _ && isOmega:
return configData.Rewards.OWolfPoints;
case BaseNPC2 n when n is Crocodile _ && isAlpha:
return configData.Rewards.CrocPoints;
case BaseNPC2 n when n is Panther _ && isAlpha:
return configData.Rewards.PantherPoints;
default:
return 0;
}
}
int GetSRRewardForAnimal(BaseEntity entity)
{
var npc = entity as BaseNPC2;
if (npc != null && IsScientist2(npc))
return 0;
bool isAlpha = entity.name.Contains("Alpha");
bool isOmega = entity.name.Contains("Omega");
switch (entity)
{
case BaseAnimalNPC animal when animal is Bear _ && isAlpha:
return configData.RewardsSR.BearPoints;
case BaseAnimalNPC animal when animal is Bear _ && isOmega:
return configData.RewardsSR.OBearPoints;
case BaseAnimalNPC animal when animal is Polarbear _ && isAlpha:
return configData.RewardsSR.PBearPoints;
case BaseAnimalNPC animal when animal is Polarbear _ && isOmega:
return configData.RewardsSR.OPBearPoints;
case BaseNPC2 n when n is Wolf2 _ && isAlpha:
return configData.RewardsSR.WolfPoints;
case BaseNPC2 n when n is Wolf2 _ && isOmega:
return configData.RewardsSR.OWolfPoints;
case BaseNPC2 n when n is Crocodile _ && isAlpha:
return configData.RewardsSR.CrocPoints;
case BaseNPC2 n when n is Panther _ && isAlpha:
return configData.RewardsSR.PantherPoints;
case BaseNPC2 n when n is Tiger _ && isAlpha:
return configData.RewardsSR.TigerPoints;
default:
return 0;
}
}
private static string GetGrid(Vector3 position) => MapHelper.PositionToString(position);
bool HasPerm(BasePlayer player , string perm)
{
return permission.UserHasPermission(player.UserIDString , perm);
}
private void RemoveOmegas()
{
var omegasToRemove = new List<Animals>(Animals.OmegaAnimals);
foreach (var animal in omegasToRemove)
{
Puts($"removed {animal.name}");
animal.DoDestroy();
}
}
private void SpawnAnimal(Vector3 position , string Type , float MinHealth , float MaxHealth)
{
var RandomHealth = UnityEngine.Random.Range(MinHealth , MaxHealth);
int radius = configData.Animals.Radius;
Vector3 pos = position + UnityEngine.Random.onUnitSphere * radius;
pos.y = TerrainMeta.HeightMap.GetHeight(pos);
BaseAnimalNPC animal = (BaseAnimalNPC)GameManager.server.CreateEntity(Type , pos , new Quaternion() , true);
if (!animal)
{
return;
}
if (animal is Bear)
{
Interface.CallHook("OnOmegaBearSpawned" , animal);
}
else if (animal is Polarbear)
{
Interface.CallHook("OnOmegaPolarbearSpawned" , animal);
}
else if (animal is Wolf2)
{
Interface.CallHook("OnOmegaWolfSpawned" , animal);
}
animal.Spawn();
var animalComponent = animal.gameObject.AddComponent<Animals>();
Animals.OmegaAnimals.Add(animalComponent);
timer.Once(1f , () => { animal.InitializeHealth(RandomHealth , RandomHealth); });
animal.name = $"Omega {animal.ShortPrefabName}";
animal.SendNetworkUpdate();
timer.Once(configData.Animals.Lifetime * 60 , () =>
{
if (animal != null && !animal.IsDestroyed && animal.transform != null)
{
Effect.server.Run(_WolfHowl , animal.transform.position);
Effect.server.Run(_WaterSplash , animal.transform.position);
animal.Kill();
}
});
}
#endregion
#region Message helper
private string msg(string key , string id = null) => prefix + lang.GetMessage(key , this , id);
private string Info(string key , string id = null) => lang.GetMessage(key , this , id);
void TIP(BasePlayer player , string message , int textsize , string textcolor , float dur)
{
if (player == null) return;
string msg = Info(message);
if (textsize == 0) textsize = 14;
string newmsg = $"<color={textcolor}><size={textsize}>{msg}</size></color>";
try
{
player.SendConsoleCommand("gametip.showtoast_translated" , 1 , "" , newmsg);
if (dur != 0) timer.Once(dur , () => player?.SendConsoleCommand("gametip.hidegametip"));
}
catch
{
Puts("catched the gametip");
}
}
void WARNING(BasePlayer player , string message , int textsize , string textcolor , float dur)
{
if (player == null) return;
string msg = Info(message);
if (textsize == 0) textsize = 14;
string newmsg = $"<color={textcolor}><size={textsize}>{msg}</size></color>";
try
{
player.SendConsoleCommand("gametip.showtoast_translated" , 1f , null , newmsg);
player.SendConsoleCommand("gametip.showtoast_translated" , 1 , "" , newmsg);
}
catch
{
Puts("catched the toast");
}
}
#endregion
#region Loot
private Dictionary<string , List<ulong>> Skins { get; set; } = new Dictionary<string , List<ulong>>();
private static List<LootItems> DefaultLoot
{
get
{
return new List<LootItems>
{
new LootItems { shortname = "ammo.pistol", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.pistol.fire", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.pistol.hv", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.rifle", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.rifle.explosive", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.rifle.hv", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.rifle.incendiary", name = "", amount = 5, skin = 0, amountMin = 5, AlwaysInclude = false },
new LootItems { shortname = "ammo.rocket.basic.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = true },
new LootItems { shortname = "ammo.rocket.fire.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = true },
new LootItems { shortname = "ammo.rocket.hv.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "ammo.shotgun", name = "", amount = 12, skin = 0, amountMin = 8, AlwaysInclude = false },
new LootItems { shortname = "explosive.timed", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "explosives", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "pistol.m92", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "rifle.ak.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "rifle.bolt.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "shotgun.spas12", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "smg.2.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "smg.thompson.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.8x.scope.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.flashlight.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.holosight.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.lasersight.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.silencer.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "weapon.mod.small.scope.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "grenade.f1.bp", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "pickaxe", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "hatchet", name = "", amount = 1, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "can.beans", name = "", amount = 3, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "can.tuna", name = "", amount = 3, skin = 0, amountMin = 1, AlwaysInclude = false },
new LootItems { shortname = "black.raspberries", name = "", amount = 5, skin = 0, amountMin = 3, AlwaysInclude = false },
};
}
}
public class LootItems
{
[JsonProperty(PropertyName = "Item shortname")]
public string shortname { get; set; }
[JsonProperty(PropertyName = "Custom name")]
public string name { get; set; }
[JsonProperty(PropertyName = "Skin ID")]
public ulong skin { get; set; }
[JsonProperty(PropertyName = "Amount min")]
public int amountMin { get; set; }
[JsonProperty(PropertyName = "Amount max")]
public int amount { get; set; }
[JsonProperty(PropertyName = "Always add")]
public bool AlwaysInclude { get; set; }
}
private void SpawnRadLoot(Vector3 pos , Quaternion rot , string animalType)
{
var backpack = GameManager.server.CreateEntity(StringPool.Get(545786656) , pos , rot , true) as DroppedItemContainer;
if (backpack == null)
{
if (Debug) Puts("Failed to create backpack entity.");
return;
}
backpack.inventory = new ItemContainer();
backpack.inventory.ServerInitialize(null , 36);
backpack.inventory.GiveUID();
backpack.inventory.entityOwner = backpack;
backpack.inventory.SetFlag(ItemContainer.Flag.NoItemInput , true);
backpack.Spawn();
if (Debug) Puts($"Spawned backpack at {pos} with rotation {rot}");
switch (animalType)
{
case "Alpha Wolf":
case "Alpha Wolf2":
case "Alpha Bear":
case "Alpha Polarbear":
case "Alpha Panther":
case "Alpha Tiger":
case "Alpha Crocodile":
SpawnLoot(backpack.inventory , configData.Animals.Loots.Loot , animalType);
break;
case "Omega Wolf":
case "Omega Bear":
case "Omega Polarbear":
break;
default:
break;
}
}
private void SpawnLoot(ItemContainer container , IList<LootItems> loot , string AnimalType)
{
var alwaysIncludeItems = new List<LootItems>();
var randomLoot = new List<LootItems>();
for (int i = 0; i < loot.Count; i++)
{
var item = loot[i];
if (item == null) continue;
if (item.AlwaysInclude) alwaysIncludeItems.Add(item);
else randomLoot.Add(item);
}
int totalPool = alwaysIncludeItems.Count + randomLoot.Count;
int min = configData.Animals.Loots.MinAmount;
int max = configData.Animals.Loots.MaxAmount;
if (totalPool < min) min = totalPool;
if (totalPool < max) max = totalPool;
if (max < 0) max = 0;
if (min < 0) min = 0;
if (max < min) max = min;
int totalItems = UnityEngine.Random.Range(min , max + 1);
if (Debug) Puts($"{AnimalType} total items: {totalItems}");
if (totalItems <= 0) return;
container.capacity = totalItems;
for (int i = 0; i < alwaysIncludeItems.Count; i++)
{
if (totalItems <= 0) break;
AddLootItem(container , alwaysIncludeItems[i]);
totalItems--;
}
for (int i = 0; i < totalItems; i++)
{
if (randomLoot.Count == 0) break;
int idx = UnityEngine.Random.Range(0 , randomLoot.Count);
var lootItem = randomLoot[idx];
randomLoot.RemoveAt(idx);
if (lootItem == null) continue;
if (lootItem.amount <= 0) continue;
AddLootItem(container , lootItem);
}
}
private void AddLootItem(ItemContainer container , LootItems lootItem)
{
string shortname = lootItem.shortname;
bool isBlueprint = shortname.EndsWith(".bp");
if (isBlueprint) shortname = shortname.Replace(".bp" , string.Empty);
ItemDefinition def = ItemManager.FindItemDefinition(shortname);
if (def == null)
{
Puts($"Invalid shortname: {lootItem.shortname}");
return;
}
ulong skin = lootItem.skin;
if (configData.Animals.RandomSkins && skin == 0)
{
List<ulong> skins = GetItemSkins(def);
if (skins.Count > 0) skin = skins.GetRandom();
}
int amount = lootItem.amount;
if (lootItem.amountMin > 0 && lootItem.amountMin < lootItem.amount)
{
amount = UnityEngine.Random.Range(lootItem.amountMin , lootItem.amount);
}
Item item;
if (isBlueprint)
{
item = ItemManager.CreateByItemID(-996920608 , 1 , 0);
if (item == null) return;
item.blueprintTarget = def.itemid;
item.amount = amount;
}
else
{
item = ItemManager.Create(def , amount , skin);
}
if (!string.IsNullOrEmpty(lootItem.name))
{
item.name = lootItem.name;
}
if (!item.MoveToContainer(container , -1 , false)) item.Remove();
}
private List<ulong> GetItemSkins(ItemDefinition def)
{
List<ulong> skins;
if (!Skins.TryGetValue(def.shortname , out skins))
{
Skins[def.shortname] = skins = ExtractItemSkins(def , skins);
}
return skins;
}
private List<ulong> ExtractItemSkins(ItemDefinition def , List<ulong> skins)
{
skins = new List<ulong>();
foreach (var skin in def.skins)
{
skins.Add(Convert.ToUInt64(skin.id));
}
foreach (var asi in Rust.Workshop.Approved.All.Values)
{
if (!string.IsNullOrEmpty(asi.Skinnable.ItemName) && asi.Skinnable.ItemName == def.shortname)
{
skins.Remove(Convert.ToUInt64(asi.WorkshopdId));
}
}
return skins;
}
#endregion
#region API
public bool IsOmegaAnimal(BaseEntity entity)
{
if (entity == null)
{
return false;
}
Animals animalComponent = entity.GetComponent<Animals>();
return animalComponent != null && Animals.OmegaAnimals.Contains(animalComponent);
}
#endregion
}
}