C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using System;
using UnityEngine;
using Oxide.Core.Plugins;
using Oxide.Core;
using Oxide.Core.Configuration;
using System.Linq;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins {
[Info("Kill Streaks", "Default", "0.1.8")]
[Description("Adds redeemable kilstreak rewards")]
class KillStreaks : RustPlugin {
[PluginReference]
private Plugin Airstrike, Clans, Economics, EventManager, Friends, Kits, ServerRewards, AdvAirstrike, FancyDrop, ZoneManager;
private Dictionary<ulong, int> cachedData = new Dictionary<ulong, int>();
readonly DynamicConfigFile zdataFile = Interface.Oxide.DataFileSystem.GetFile("KillStreaks-Zones");
private List<BaseHelicopter> activeHelis = new List<BaseHelicopter>();
private List<ulong> aasGren = new List<ulong>();
private List<ulong> sqGren = new List<ulong>();
private List<ulong> naGren = new List<ulong>();
private List<ulong> nuGren = new List<ulong>();
private List<ulong> spGren = new List<ulong>();
private List<ulong> asGren = new List<ulong>();
private List<ulong> ssGren = new List<ulong>();
private List<ulong> arGren = new List<ulong>();
private List<ulong> heGren = new List<ulong>();
private List<ulong> mrtdm = new List<ulong>();
private List<ulong> turret = new List<ulong>();
private List<AutoTurret> TurretList = new List<AutoTurret>();
private List<string> zones = new List<string>();
private Dictionary<ulong, StreakType> activeGrenades = new Dictionary<ulong, StreakType>();
private Dictionary<int, StreakType> streakTypes = new Dictionary<int, StreakType>() {
{
0, StreakType.None
}
, {
1, StreakType.Airstrike
}
, {
2, StreakType.SquadStrike
}
, {
3, StreakType.Artillery
}
, {
4, StreakType.Helicopter
}
, {
5, StreakType.SupplyDrop
}
, {
6, StreakType.AirstrikeGrenade
}
, {
7, StreakType.SquadStrikeGrenade
}
, {
8, StreakType.ArtilleryGrenade
}
, {
9, StreakType.HelicopterGrenade
}
, {
10, StreakType.Martyrdom
}
, {
11, StreakType.TurretDrop
}
, {
12, StreakType.Coins
}
, {
13, StreakType.RP
}
, {
14, StreakType.AdvAirstrike
}
, {
15, StreakType.AdvAirstrikeGrenade
}
, {
16, StreakType.SupplySignal
}
, {
17, StreakType.AdvAirstrikeSquad
}
, {
18, StreakType.AdvAirstrikeNapalm
}
, {
19, StreakType.AdvAirstrikeNuke
}
, {
20, StreakType.AdvAirstrikeSpectre
}
, {
21, StreakType.AdvAirstrikeSquadGrenade
}
, {
22, StreakType.AdvAirstrikeNapalmGrenade
}
, {
23, StreakType.AdvAirstrikeNukeGrenade
}
, {
24, StreakType.AdvAirstrikeSpectreGrenade
}
, {
25, StreakType.KitOnly
}
}
;
DataStorage data;
Player_DataStorage pdata;
private DynamicConfigFile KSData;
private DynamicConfigFile KSPData;
private static Vector2 warningPos = new Vector2(0.25f, 0.13f);
private static Vector2 warningDim = new Vector2(0.5f, 0.12f);
private readonly int triggerMask = LayerMask.GetMask("Trigger");
private const string supplydrop_prefab = "assets/prefabs/misc/supply drop/supply_drop.prefab";
private const string KillStreakPermission = "killstreaks.allowed";
#region oxide hooks
void OnServerInitialized() {
RegisterMessages();
KSData = Interface.Oxide.DataFileSystem.GetFile("killstreak_data");
KSPData = Interface.Oxide.DataFileSystem.GetFile("killstreak_player_data");
LoadData();
LoadVariables();
CheckDependencies();
permission.RegisterPermission(KillStreakPermission , this);
SaveStreakData();
}
private void CheckDependencies() {
if (Friends == null) {
if (useFriendsAPI) {
PrintWarning($"FriendsAPI is not found! Disabling friends feature.");
useFriendsAPI = false;
}
}
if (Clans == null) {
if (useClans) {
PrintWarning($"Clans is not found! Disabling clans feature.");
useClans = false;
}
}
if (Airstrike == null) {
if (useAirstrike) {
PrintWarning($"Airstrike is not found! Disabling airstrike feature.");
useAirstrike = false;
}
}
if (AdvAirstrike == null) {
if (useAdvAirstrike) {
PrintWarning($"Advanced Airstrike is not found! Disabling advanced airstrike feature.");
useAirstrike = false;
}
}
if (Economics == null) {
PrintWarning("Economics is not found! Unable to issue Economics rewards.");
}
if (ServerRewards == null) {
PrintWarning("ServerRewards is not found! Unable to issue RP rewards.");
}
if (PVPOnly && PeopleOnly) {
PrintWarning("You can have either PVP Only or People Only, not Both, setting to People Only (That includes players and NPCs)");
PVPOnly = false;
PeopleOnly = true;
}
}
protected override void LoadDefaultConfig() {
Puts("Creating a new config file");
Config.Clear();
LoadVariables();
}
void OnEntityDeath(BaseEntity entity, HitInfo hitinfo) {
if (entity == null || hitinfo == null || hitinfo?.Initiator == null) return;
if (entity is BasePlayer && !((entity as BasePlayer).IsNpc)) ProcessDeath((BasePlayer)entity, hitinfo);
BasePlayer killer = hitinfo?.Initiator?.ToPlayer();
if (killer == null || killer?.UserIDString == null) return;
if ((usePermissions && !permission.UserHasPermission(killer?.UserIDString, KillStreakPermission))) return;
// only zone check if set, there is a zone entry and ZoneManagers is loaded
if (useZoneManager && zones.Count > 0 && ZoneManager != null) {
bool inZone = false;
//Puts("count zones: " + zones.Count);
foreach(string zs in zones) {
if (String.IsNullOrWhiteSpace(zs)) Puts("Empty Zone Multiplier name please check your json");
else if ((bool)ZoneManager?.Call("isPlayerInZone", zs, killer)) {
inZone = true;
// Puts(zs);
break;
}
}
if (!inZone) return;
// not in a valid zone so no reward
}
if (entity is BaseHelicopter && activeHelis.Contains((BaseHelicopter)entity)) activeHelis.Remove((BaseHelicopter)entity);
if (!(hitinfo.Initiator is BasePlayer) || (hitinfo.Initiator as BasePlayer).IsNpc) return;
// NPC do not get killstreaks
if (entity is BasePlayer && hitinfo.Initiator is BasePlayer && (entity as BasePlayer).UserIDString == (hitinfo.Initiator as BasePlayer).UserIDString) // no credit for killing yourself
return;
if (PVPOnly && (!(entity is BasePlayer) || (entity as BasePlayer).IsNpc)) return;
// If it is PVP and you kill is not an actual player it does not count
if (entity is BasePlayer && !((entity as BasePlayer).IsNpc)) // process kill of player
ProcessKill((BasePlayer)hitinfo.Initiator, (BasePlayer)entity);
if (PeopleOnly && entity is BasePlayer && ((entity as BasePlayer).IsNpc)) // process kill of NPC
ProcessKill((BasePlayer)hitinfo.Initiator, (BasePlayer)null);
else if (!PVPOnly && !PeopleOnly) // PVE process kill of non-players (NPC, Animals, Heli, CH47 and Bradley)
{
if ((entity is BasePlayer && (entity as BasePlayer).IsNpc) || // NPC
entity is BaseNpc || (!String.IsNullOrWhiteSpace(entity.name) && entity.name.Contains("assets/rust.ai/")) || // Animals
entity is BaseHelicopter || entity is CH47HelicopterAIController || entity is BradleyAPC // hard to kill entities
) ProcessKill((BasePlayer)hitinfo.Initiator, (BasePlayer)null);
}
}
void OnPlayerDisconnected(BasePlayer player) => ProcessDeath(player, null, true);
void OnExplosiveThrown(BasePlayer player, BaseEntity entity) {
if (!entity.name.Contains("grenade.smoke")) return;
if ((player.UserIDString == null) || (usePermissions && !permission.UserHasPermission(player.UserIDString, KillStreakPermission))) return;
if (activeGrenades.ContainsKey(player.userID)) {
//entity.CancelInvoke((entity as SupplySignal).Explode);
entity.Invoke(entity.KillMessage, 10f);
timer.Once(3, () => {
//Effect.server.Run("assets/bundled/prefabs/fx/smoke_signal.prefab", entity, 0, new Vector3(), new Vector3());
Vector3 pos = entity.transform.position;
if (pos == null) pos = player.transform.position;
switch (activeGrenades[player.userID]) {
case StreakType.AdvAirstrikeGrenade : CallAdvAirstrike(pos, activeGrenades[player.userID]);
break;
case StreakType.AdvAirstrikeSquadGrenade : CallAdvAirstrike(pos, activeGrenades[player.userID]);
break;
case StreakType.AdvAirstrikeNapalmGrenade : CallAdvAirstrike(pos, activeGrenades[player.userID]);
break;
case StreakType.AdvAirstrikeNukeGrenade : CallAdvAirstrike(pos, activeGrenades[player.userID]);
break;
case StreakType.AdvAirstrikeSpectreGrenade : CallAdvAirstrike(pos, activeGrenades[player.userID]);
break;
case StreakType.AirstrikeGrenade : CallAirstrike(pos);
break;
case StreakType.SquadStrikeGrenade : CallAirstrike(pos, false);
break;
case StreakType.ArtilleryGrenade : LaunchArtillery(pos);
break;
case StreakType.HelicopterGrenade : CallHeli(pos, cachedData[player.userID], true);
break;
case StreakType.TurretDrop : DropTurret(pos, player);
break;
default : return;
}
activeGrenades.Remove(player.userID);
}
);
}
}
void Unload() {
SaveData();
KillHeli();
KillTurret();
}
#endregion
#region functions
private bool HasPriv(BasePlayer player) {
var hit = Physics.OverlapSphere(player.transform.position, 2f, triggerMask);
foreach (var entity in hit) {
BuildingPrivlidge privs = entity.GetComponentInParent<BuildingPrivlidge>();
if (privs != null) if (privs.IsAuthed(player)) return true;
}
return false;
}
private void ProcessKill(BasePlayer player, BasePlayer victim) {
if (ignoreBuildPriv && HasPriv(player)) return;
if (useClans && victim != null && IsClanmate(player.UserIDString, victim.UserIDString)) return;
if (useFriendsAPI && victim != null && IsFriend(player.userID, victim.userID)) return;
if (EventManager) {
object isPlaying = EventManager?.Call("isPlaying", new object[] {
player
}
);
if (isPlaying is bool) if ((bool)isPlaying) return;
}
if (!pdata.killStreakData.ContainsKey(player.userID)) pdata.killStreakData.Add(player.userID, new KSPDATA() {
Name = player.displayName, highestKS = 0
}
);
if (!cachedData.ContainsKey(player.userID)) cachedData.Add(player.userID, 0);
cachedData[player.userID]++;
if (cachedData[player.userID] > pdata.killStreakData[player.userID].highestKS) pdata.killStreakData[player.userID].highestKS = cachedData[player.userID];
Deal(player, victim);
}
private void ProcessDeath(BasePlayer player, HitInfo info, bool disconnected = false) {
if (cachedData.ContainsKey(player.userID)) {
if (!disconnected) if (mrtdm.Contains(player.userID)) ChooseRandomExp(player.transform.position);
ClearPlayerRewards(player);
string deathType = lang.GetMessage("suic", this, player.UserIDString);
if (disconnected) {
if (NoDisconnect) return;
else deathType = lang.GetMessage("disconnected", this, player.UserIDString);
}
else if (info != null) deathType = GetDeathType(info.Initiator);
if (broadcastEnd) BroadcastToAll(lang.GetMessage("endstreak", this, player.UserIDString) + deathType, player.displayName);
}
}
private void ClearPlayerRewards(BasePlayer player) {
ulong ID = player.userID;
if (aasGren.Contains(ID)) aasGren.Remove(ID);
if (sqGren.Contains(ID)) sqGren.Remove(ID);
if (naGren.Contains(ID)) naGren.Remove(ID);
if (nuGren.Contains(ID)) nuGren.Remove(ID);
if (spGren.Contains(ID)) spGren.Remove(ID);
if (asGren.Contains(ID)) asGren.Remove(ID);
if (ssGren.Contains(ID)) ssGren.Remove(ID);
if (arGren.Contains(ID)) arGren.Remove(ID);
if (heGren.Contains(ID)) heGren.Remove(ID);
if (mrtdm.Contains(ID)) mrtdm.Remove(ID);
if (turret.Contains(ID)) turret.Remove(ID);
cachedData.Remove(ID);
}
public string GetDeathType(BaseEntity entity) {
string deathtype = "";
if (entity == null) return null;
else if (entity.ToPlayer() != null) deathtype = entity.ToPlayer().displayName;
else if (entity.name.Contains("patrolhelicopter.pr")) deathtype = lang.GetMessage("aheli", this);
else if (entity.name.Contains("animals/")) deathtype = lang.GetMessage("aanim", this);
else if (entity.name.Contains("beartrap.prefab")) deathtype = lang.GetMessage("abt", this);
else if (entity.name.Contains("landmine.prefab")) deathtype = lang.GetMessage("aldm", this);
else if (entity.name.Contains("spikes.floor.prefab")) deathtype = lang.GetMessage("flrsp", this);
else if (entity.name.Contains("autoturret_deployed.prefab")) deathtype = lang.GetMessage("aturr", this);
else if (entity.name.Contains("deployable/barricades") || entity.name.Contains("wall.external.high")) deathtype = lang.GetMessage("awall", this);
return deathtype;
}
private void BroadcastToAll(string msg, string keyword) => PrintToChat(fontColor1 + keyword + " </color>" + fontColor2 + msg + "</color>");
private void BroadcastToPlayer(BasePlayer player, string msg, string keyword) => SendReply(player, fontColor1 + keyword + " </color>" + fontColor2 + msg + "</color>");
private void GUIToPlayer(BasePlayer player, string msg, string keyword) => KSUI.GetPlayer(player).UseUI(fontColor1 + keyword + " </color>" + fontColor2 + msg + "</color>", warningPos, warningDim, 20);
private bool IsClanmate(string playerId, string friendId) {
if (!Clans || !useClans) return false;
if ((bool)Clans?.Call("IsMemberOrAlly", playerId, friendId)) return true;
return false;
}
private List<BasePlayer> FindNearbyFriends(BasePlayer player) {
List<BaseEntity> nearbyPlayers = new List<BaseEntity>();
List<BasePlayer> nearbyFriends = new List<BasePlayer>();
Vis.Entities(player.transform.position, nearbyRadius, nearbyPlayers);
foreach (var entry in nearbyPlayers) if (entry is BasePlayer) if (entry != null) if (IsClanmate(entry.ToPlayer().UserIDString, player.UserIDString) || IsFriend(entry.ToPlayer().userID, player.userID)) nearbyFriends.Add(entry.ToPlayer());
if (nearbyFriends.Count > 0) return nearbyFriends;
return null;
}
private bool IsFriend(ulong playerID, ulong friendID) {
if (!Friends || !useFriendsAPI) return false;
bool isFriend = (bool)Friends?.Call("IsFriend", playerID, friendID);
return isFriend;
}
private Item GiveSmokeSignal() {
var definition = ItemManager.FindItemDefinition("grenade.smoke");
if (definition != null) {
Item item = ItemManager.CreateByItemID((int)definition.itemid, 1);
return item;
}
return null;
}
private Item GiveSupplySignal() {
var definition = ItemManager.FindItemDefinition("supply.signal");
if (definition != null) {
Item item = ItemManager.CreateByItemID((int)definition.itemid, 1);
return item;
}
return null;
}
#endregion
#region punishments/prizes
private void Deal(BasePlayer player, BasePlayer victim) {
var count = cachedData[player.userID];
if (data.killStreaks.ContainsKey(count)) {
string vict_name = victim?.displayName;
string langKey = data.killStreaks[count].Message;
if (broadcastMsg) {
if (showVictim && !string.IsNullOrEmpty(vict_name)) BroadcastToAll(langKey + string.Format(lang.GetMessage("kill_mess_victim", this), count, vict_name), player.displayName);
else BroadcastToAll(langKey + string.Format(lang.GetMessage("kill_message", this), count), player.displayName);
}
else {
if (showVictim && !string.IsNullOrEmpty(vict_name)) BroadcastToPlayer(player, player.displayName + langKey, string.Format(lang.GetMessage("kill_mess_victim", this, player.UserIDString), count, vict_name));
else BroadcastToPlayer(player, player.displayName + langKey, string.Format(lang.GetMessage("kill_message", this, player.UserIDString), count));
}
string message = lang.GetMessage("attract", this);
if (data.killStreaks[count].StreakType != StreakType.None) {
var streakType = data.killStreaks[count].StreakType;
var pos = player.transform.position;
string kitname = data.killStreaks[count].KitName;
if (!string.IsNullOrEmpty(kitname) && kitname != "null" && Kits) {
message = GiveKit(player, kitname, count);
GUIToPlayer(player, message, lang.GetMessage("warning", this));
}
if (streakType != StreakType.KitOnly) {
switch (streakType) {
case StreakType.Airstrike : if (!Airstrike) return;
CallAirstrike(pos);
message = lang.GetMessage("asLaunch", this, player.UserIDString);
break;
case StreakType.SquadStrike : if (!Airstrike) return;
CallAirstrike(pos, false);
message = lang.GetMessage("ssLaunch", this, player.UserIDString);
break;
case StreakType.Artillery : LaunchArtillery(pos);
message = lang.GetMessage("arLaunch", this, player.UserIDString);
break;
case StreakType.Helicopter : CallHeli(player.transform.position, count, false, player);
message = lang.GetMessage("asLaunch", this, player.UserIDString);
break;
case StreakType.SupplyDrop : SendSupplyDrop(player, count);
message = lang.GetMessage("sdLaunch", this, player.UserIDString);
break;
case StreakType.Martyrdom : SetMartyrdom(player);
message = lang.GetMessage("mrtdmActive", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeGrenade : GiveRewardGrenade(player, StreakType.AdvAirstrikeGrenade);
message = lang.GetMessage("aasGrenade", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeSquadGrenade : GiveRewardGrenade(player, StreakType.AdvAirstrikeSquadGrenade);
message = lang.GetMessage("sqGrenade", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeNapalmGrenade : GiveRewardGrenade(player, StreakType.AdvAirstrikeNapalmGrenade);
message = lang.GetMessage("naGrenade", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeNukeGrenade : GiveRewardGrenade(player, StreakType.AdvAirstrikeNukeGrenade);
message = lang.GetMessage("nuGrenade", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeSpectreGrenade : GiveRewardGrenade(player, StreakType.AdvAirstrikeSpectreGrenade);
message = lang.GetMessage("spGrenade", this, player.UserIDString);
break;
case StreakType.AirstrikeGrenade : GiveRewardGrenade(player, StreakType.AirstrikeGrenade);
message = lang.GetMessage("asGrenade", this, player.UserIDString);
break;
case StreakType.SquadStrikeGrenade : GiveRewardGrenade(player, StreakType.SquadStrikeGrenade);
message = lang.GetMessage("ssGrenade", this, player.UserIDString);
break;
case StreakType.ArtilleryGrenade : GiveRewardGrenade(player, StreakType.ArtilleryGrenade);
message = lang.GetMessage("arGrenade", this, player.UserIDString);
break;
case StreakType.HelicopterGrenade : GiveRewardGrenade(player, StreakType.HelicopterGrenade);
message = lang.GetMessage("heGrenade", this, player.UserIDString);
break;
case StreakType.TurretDrop : GiveRewardGrenade(player, StreakType.TurretDrop);
message = lang.GetMessage("tuGrenade", this, player.UserIDString);
break;
case StreakType.Coins : if (!Economics) return;
message = GiveEconomics(player, count);
break;
case StreakType.RP : if (!ServerRewards) return;
message = GiveRP(player, count);
break;
case StreakType.AdvAirstrike : CallAdvAirstrike(pos, streakType);
message = lang.GetMessage("aasLaunch", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeSquad : CallAdvAirstrike(pos, streakType);
message = lang.GetMessage("sqLaunch", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeNapalm : CallAdvAirstrike(pos, streakType);
message = lang.GetMessage("naLaunch", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeNuke : CallAdvAirstrike(pos, streakType);
message = lang.GetMessage("nuLaunch", this, player.UserIDString);
break;
case StreakType.AdvAirstrikeSpectre : CallAdvAirstrike(pos, streakType);
message = lang.GetMessage("spLaunce", this, player.UserIDString);
break;
case StreakType.SupplySignal : player.inventory.GiveItem(GiveSupplySignal());
message = lang.GetMessage("sdSignal", this, player.UserIDString);
break;
}
GUIToPlayer(player, message, lang.GetMessage("warning", this));
}
Effect.server.Run("assets/prefabs/npc/autoturret/effects/targetacquired.prefab", player.transform.position);
}
}
}
private void GiveRewardGrenade(BasePlayer player, StreakType type) {
List<ulong> list = new List<ulong>();
if (type == StreakType.ArtilleryGrenade) list = arGren;
else if (type == StreakType.AdvAirstrikeGrenade) list = aasGren;
else if (type == StreakType.AdvAirstrikeSquadGrenade) list = sqGren;
else if (type == StreakType.AdvAirstrikeNapalmGrenade) list = naGren;
else if (type == StreakType.AdvAirstrikeNukeGrenade) list = nuGren;
else if (type == StreakType.AdvAirstrikeSpectreGrenade) list = spGren;
else if (type == StreakType.AirstrikeGrenade) list = asGren;
else if (type == StreakType.SquadStrikeGrenade) list = ssGren;
else if (type == StreakType.HelicopterGrenade) list = heGren;
else if (type == StreakType.TurretDrop) list = turret;
player.inventory.GiveItem(GiveSmokeSignal());
if (list != null) list.Add(player.userID);
}
#region airstrike
private void CallAirstrike(Vector3 target, bool type = true) {
if (Airstrike) {
if (type) Airstrike?.Call("CallStrike", target);
else Airstrike?.Call("CallSquad", target);
}
else Puts(lang.GetMessage("noAirstrike", this));
}
#endregion
#region advairstrike
private void CallAdvAirstrike(Vector3 target, StreakType type) {
if (AdvAirstrike) {
if (type == StreakType.AdvAirstrike ) AdvAirstrike?.Call("CallStrike", target);
else if (type == StreakType.AdvAirstrikeSquad ) AdvAirstrike?.Call("CallSquad", target);
else if (type == StreakType.AdvAirstrikeNapalm ) AdvAirstrike?.Call("CallNapalm", target);
else if (type == StreakType.AdvAirstrikeNuke ) AdvAirstrike?.Call("CallNuke", target);
else if (type == StreakType.AdvAirstrikeSpectre ) AdvAirstrike?.Call("CallSpectre", target);
else Puts(lang.GetMessage("noAdvAirstrikeType", this));
}
else Puts(lang.GetMessage("noAdvAirstrike", this));
}
#endregion
#region artillery
private void LaunchArtillery(Vector3 target) {
timer.Repeat(rocketInterval, rocketAmount, () => RocketSpread(target));
}
private void RocketSpread(Vector3 targetPos) {
targetPos = Quaternion.Euler(UnityEngine.Random.Range((float)(-rocketSpread * 0.2), rocketSpread * 0.2f), UnityEngine.Random.Range((float)(-rocketSpread * 0.2), rocketSpread * 0.2f), UnityEngine.Random.Range((float)(-rocketSpread * 0.2), rocketSpread * 0.2f)) * targetPos;
CreateRocket(targetPos);
}
private BaseEntity CreateRocket(Vector3 targetPos) {
string fireRocket = "ammo.rocket.fire";
string rocketType = "ammo.rocket.basic";
var rocket = rocketType;
int rand = UnityEngine.Random.Range(1, 7);
if (rand == 1) rocket = fireRocket;
var launchPos = targetPos + new Vector3(0, 200, 0);
ItemDefinition projectileItem = ItemManager.FindItemDefinition(rocket);
ItemModProjectile component = projectileItem.GetComponent<ItemModProjectile>();
BaseEntity entity = GameManager.server.CreateEntity(component.projectileObject.resourcePath, launchPos, new Quaternion(), true);
TimedExplosive rocketExplosion = entity.GetComponent<TimedExplosive>();
ServerProjectile rocketProjectile = entity.GetComponent<ServerProjectile>();
rocketExplosion.timerAmountMin = 60;
rocketExplosion.timerAmountMax = 60;
Vector3 newDirection = (targetPos - launchPos);
entity.SendMessage("InitializeVelocity", (newDirection));
entity.Spawn();
return null;
}
#endregion
#region helicopters
private int HeliDistance = 50;
private static LayerMask GROUND_MASKS = LayerMask.GetMask("Terrain", "World", "Construction");
private void CallHeli(Vector3 pos, int streaknum, bool onSmoke = false, BasePlayer player = null) {
int amount = data.killStreaks[streaknum].Amount;
int i = 0;
while (i < amount) {
BaseEntity entity = CreateHeli(pos);
MoveEntity(entity, pos);
if (!onSmoke) if (player != null) CheckDistance(entity, player);
i++;
}
}
private BaseEntity CreateHeli(Vector3 pos) {
BaseEntity entity = GameManager.server.CreateEntity("assets/prefabs/npc/patrol helicopter/patrolhelicopter.prefab", new Vector3(), new Quaternion(), true);
if (!entity) return null;
((BaseCombatEntity)entity).startHealth = HeliHealth;
var weakspots = ((BaseHelicopter)entity).weakspots;
weakspots[0].maxHealth = MainRotorHealth;
weakspots[0].health = MainRotorHealth;
weakspots[1].maxHealth = TailRotorHealth;
weakspots[1].health = TailRotorHealth;
entity.GetComponent<BaseHelicopter>().maxCratesToSpawn = 2;
entity.Spawn();
activeHelis.Add((BaseHelicopter)entity);
ConVar.PatrolHelicopter.bulletAccuracy = HeliAccuracy;
entity.GetComponent<PatrolHelicopterAI>().State_Move_Enter(pos + new Vector3(0.0f, 10f, 0.0f));
return entity;
}
private Vector3 calculateSpawnPos(Vector3 arenaPos) {
Vector3 spawnPos = new Vector3(0, 0, 0);
float randX = RandomRange(SpawnDistance);
float randZ = RandomRange(SpawnDistance);
spawnPos.x = arenaPos.x - randX;
spawnPos.z = arenaPos.z - randZ;
var ang = UnityEngine.Random.Range(1, 360);
Vector3 finalPos = GetGroundPosition(spawnPos);
finalPos.y = finalPos.y + 30;
finalPos.x = spawnPos.x + SpawnDistance * Mathf.Sin(ang * Mathf.Deg2Rad);
finalPos.z = spawnPos.z + SpawnDistance * Mathf.Cos(ang * Mathf.Deg2Rad);
return finalPos;
}
private float RandomRange(float distance, float difference = 50) {
float rand = UnityEngine.Random.Range(distance - difference, distance + difference);
return rand;
}
private void MoveEntity(BaseEntity entity, Vector3 pos) {
Vector3 spawnPos = calculateSpawnPos(pos);
entity.transform.position = spawnPos;
}
private void CheckDistance(BaseEntity entity, BasePlayer player) {
if (entity == null || player == null) return;
if (cachedData.ContainsKey(player.userID)) {
var currentPos = entity.transform.position;
var targetPos = player.transform.position;
if (targetPos != null) {
if (Vector3.Distance(currentPos, targetPos) < (currentPos.y + HeliDistance)) {
PatrolHelicopterAI heliAI = entity.GetComponent<PatrolHelicopterAI>();
heliAI.State_Orbit_Enter(50);
heliAI.maxSpeed = HeliSpeed;
}
else entity.GetComponent<PatrolHelicopterAI>().State_Move_Enter(targetPos + new Vector3(0.0f, 10f, 0.0f));
}
timer.Once(7, () => CheckDistance(entity, player));
}
}
static Vector3 GetGroundPosition(Vector3 sourcePos) // credit Wulf & Nogrod
{
RaycastHit hitInfo;
if (Physics.Raycast(sourcePos, Vector3.down, out hitInfo, GROUND_MASKS)) {
sourcePos.y = hitInfo.point.y;
}
sourcePos.y = Mathf.Max(sourcePos.y, TerrainMeta.HeightMap.GetHeight(sourcePos));
return sourcePos;
}
private void KillHeli() {
int i = 0;
foreach (var heli in activeHelis) {
heli.KillMessage();
i++;
}
if (i > 0) Puts("Destroyed {0} KillStreak Helicopters", i);
}
private void KillTurret() {
int i = 0;
foreach (var turret in TurretList) {
if (turret == null || turret.IsDead()) continue;
turret.DieInstantly();
i++;
}
if (i > 0) Puts("Destroyed {0} KillStreak Turrets", i);
}
#endregion
#region martyrdom
private void SetMartyrdom(BasePlayer player) => mrtdm.Add(player.userID);
private void ChooseRandomExp(Vector3 pos) {
int num = UnityEngine.Random.Range(1, 6);
if (num == 1 || num == 2 || num == 3) dropGrenade(pos);
else if (num == 4 || num == 5) dropBeancan(pos);
else if (num == 6) dropExplosive(pos);
}
private void dropGrenade(Vector3 deathPos) {
timer.Once(0.1f, () => Effect.server.Run("assets/prefabs/weapons/f1 grenade/effects/bounce.prefab", deathPos));
timer.Once(4f, () => {
Effect.server.Run("assets/prefabs/weapons/f1 grenade/effects/f1grenade_explosion.prefab", deathPos);
dealDamage(deathPos, grenadeDamage, grenadeRadius);
}
);
}
private void dropBeancan(Vector3 deathPos) {
timer.Once(0.1f, () => Effect.server.Run("assets/prefabs/weapons/beancan grenade/effects/bounce.prefab", deathPos));
timer.Once(4f, () => {
Effect.server.Run("assets/prefabs/weapons/beancan grenade/effects/beancan_grenade_explosion.prefab", deathPos);
dealDamage(deathPos, beancanDamage, beancanRadius);
}
);
}
private void dropExplosive(Vector3 deathPos) {
timer.Once(0.1f, () => Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.updated.prefab", deathPos));
timer.Once(2f, () => Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.updated.prefab.prefab", deathPos));
timer.Once(4f, () => Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.updated.prefab.prefab", deathPos));
timer.Once(6f, () => Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.updated.prefab.prefab", deathPos));
timer.Once(8f, () => {
Effect.server.Run("assets/prefabs/tools/c4/effects/c4_explosion.prefab", deathPos);
dealDamage(deathPos, explosiveDamage, explosiveRadius);
}
);
}
#endregion
#region supplydrop
private void SendSupplyDrop(BasePlayer player, int streaknum) {
if (player == null) return;
int amount = data.killStreaks[streaknum].Amount;
int i = 0;
while (i < amount) {
SpawnSignal(player);
i++;
}
}
private void SpawnSignal(BasePlayer player) {
if (FancyDrop) rust.RunServerCommand("ad.dropplayer " + player.UserIDString);
else {
var pos = player.transform.position;
Vector3 setPos = pos + new Vector3(RandomRange(10, 5), 200, RandomRange(10, 5));
BaseEntity drop = GameManager.server.CreateEntity(supplydrop_prefab, setPos);
drop.globalBroadcast = true;
drop.Spawn();
}
}
#endregion
#region turret drop
private void DropTurret(Vector3 pos, BasePlayer player) {
AutoTurret turret = CreateTurret(pos);
// safety check if the turret was unable to spawn
if (turret != null || !turret.IsDead()) {
TurretList.Add(turret);
AssignTurretAuth(player, turret);
player.SendNetworkUpdateImmediate();
// set timer to remove it after 30 minutes
timer.Once(1800, () => {
if (turret != null && !turret.IsDead()) turret.DieInstantly();
}
);
}
}
private AutoTurret CreateTurret(Vector3 targetPos) {
BaseEntity turret = GameManager.server.CreateEntity("assets/prefabs/npc/autoturret/autoturret_deployed.prefab", targetPos, new Quaternion(), true);
turret.Spawn();
return (AutoTurret)turret;
}
private void AssignTurretAuth(BasePlayer player, AutoTurret turret) {
var nearbyFriends = FindNearbyFriends(player);
if (nearbyFriends != null) {
foreach (var entry in nearbyFriends) if (entry != null) turret.authorizedPlayers.Add(new ProtoBuf.PlayerNameID() {
userid = entry.userID, username = entry.displayName
}
);
}
// Item weapon = ItemManager.CreateByItemID(1545779598); // m249
Item weapon = ItemManager.CreateByItemID(28201841);
// m39
weapon.MoveToContainer(turret.inventory, 0, false);
turret.UpdateAttachedWeapon();
turret.inventory.AddItem(ItemManager.FindItemDefinition(turretAmmoTypeName), turretAmmoCount);
turret.InitiateStartup();
turret.SendNetworkUpdateImmediate();
}
#endregion
#region payment
private string GiveEconomics(BasePlayer player, int streaknum) {
double amount = data.killStreaks[streaknum].Amount;
Economics?.Call("Deposit", player.userID, amount);
return string.Format(lang.GetMessage("coinsActive", this, player.UserIDString), amount);
}
private string GiveRP(BasePlayer player, int streaknum) {
int amount = data.killStreaks[streaknum].Amount;
ServerRewards?.Call("AddPoints", player.userID, amount);
return string.Format(lang.GetMessage("rpActive", this, player.UserIDString), amount);
}
private string GiveKit(BasePlayer player, string kitname, int streaknum) {
if (string.IsNullOrEmpty(kitname) || kitname == "null") return string.Format(lang.GetMessage("noKit", this, player.UserIDString));
else {
Kits?.Call("GiveKit", new object[] {
player, kitname
}
);
return string.Format(lang.GetMessage("kitActive", this, player.UserIDString), kitname);
}
}
#endregion
#region damage
private void dealDamage(Vector3 deathPos, float damage, float radius) {
List<BaseCombatEntity> entitiesClose = new List<BaseCombatEntity>();
List<BaseCombatEntity> entitiesNear = new List<BaseCombatEntity>();
List<BaseCombatEntity> entitiesFar = new List<BaseCombatEntity>();
Vis.Entities<BaseCombatEntity>(deathPos, radius / 3, entitiesClose);
Vis.Entities<BaseCombatEntity>(deathPos, radius / 2, entitiesNear);
Vis.Entities<BaseCombatEntity>(deathPos, radius, entitiesFar);
foreach (BaseCombatEntity entity in entitiesClose) {
entity.Hurt(damage, Rust.DamageType.Explosion, null, true);
}
foreach (BaseCombatEntity entity in entitiesNear) {
if (entitiesClose.Contains(entity)) return;
entity.Hurt(damage / 2, Rust.DamageType.Explosion, null, true);
}
foreach (BaseCombatEntity entity in entitiesFar) {
if (entitiesClose.Contains(entity) || entitiesNear.Contains(entity)) return;
entity.Hurt(damage / 4, Rust.DamageType.Explosion, null, true);
}
}
#endregion
#endregion
#region chat commands
//[ChatCommand("a")]
//void asd(BasePlayer player, string command, string[] args)
//{
// if (!pdata.killStreakData.ContainsKey(player.userID))
// pdata.killStreakData.Add(player.userID, new KSPDATA() { Name = player.displayName, highestKS = 0 });
// if (!cachedData.ContainsKey(player.userID))
// cachedData.Add(player.userID, 0);
// cachedData[player.userID]++;
// if (cachedData[player.userID] > pdata.killStreakData[player.userID].highestKS)
// pdata.killStreakData[player.userID].highestKS = cachedData[player.userID];
// Deal(player);
//}
[ChatCommand("ks")]
void cmdTarget(BasePlayer player, string command, string[] args) {
if (args == null || args.Length == 0) {
SendReply(player, fontColor1 + lang.GetMessage("title", this, player.UserIDString) + "</color>");
BroadcastToPlayer(player, lang.GetMessage("kstop2", this, player.UserIDString), lang.GetMessage("kstop", this, player.UserIDString));
BroadcastToPlayer(player, lang.GetMessage("kspb2", this, player.UserIDString), lang.GetMessage("kspb", this, player.UserIDString));
if (isAuth(player)) {
BroadcastToPlayer(player, lang.GetMessage("ksAdd1", this, player.UserIDString), lang.GetMessage("ksAdd", this, player.UserIDString));
BroadcastToPlayer(player, lang.GetMessage("ksRem1", this, player.UserIDString), lang.GetMessage("ksRem", this, player.UserIDString));
BroadcastToPlayer(player, lang.GetMessage("ksList1", this, player.UserIDString), lang.GetMessage("ksList", this, player.UserIDString));
BroadcastToPlayer(player, lang.GetMessage("ksListNum1", this, player.UserIDString), lang.GetMessage("ksListNum", this, player.UserIDString));
BroadcastToPlayer(player, lang.GetMessage("kswipe2", this, player.UserIDString), lang.GetMessage("kswipe", this, player.UserIDString));
}
return;
}
var ID = player.userID;
// write data since it might be references
KSPData.WriteObject(pdata);
switch (args[0].ToLower()) {
case "top" : if (args.Length >= 1) {
int amount = 5;
if (args.Length >= 2) if (!int.TryParse(args[1], out amount)) amount = 5;
Dictionary<string, int> top5 = pdata.killStreakData.OrderByDescending(pair => pair.Value.highestKS).Take(amount).ToDictionary(pair => pair.Value.Name, pair => pair.Value.highestKS);
if (top5.Count > 0) {
SendReply(player, fontColor1 + lang.GetMessage("title", this, player.UserIDString) + "</color>" + fontColor2 + lang.GetMessage("bestHits", this, player.UserIDString) + "</color>");
foreach (var name in top5) {
SendReply(player, string.Format(fontColor2 + lang.GetMessage("topList", this, player.UserIDString) + "</color>", name.Key, name.Value));
}
}
}
return;
case "wipe" : if (isAuth(player)) {
foreach (BasePlayer onlinePlayer in BasePlayer.activePlayerList) {
ClearPlayerRewards(onlinePlayer);
}
pdata.killStreakData.Clear();
KSPData.WriteObject(pdata);
SendReply(player, lang.GetMessage("wipedata", this, player.UserIDString));
}
return;
case "pb" : if (pdata.killStreakData.ContainsKey(ID)) BroadcastToPlayer(player, pdata.killStreakData[ID].highestKS.ToString(), lang.GetMessage("pb", this, player.UserIDString));
else BroadcastToPlayer(player, "0", lang.GetMessage("pb", this, player.UserIDString));
return;
case "list" : if (isAuth(player)) {
if (args.Length >= 2) {
int i = -1;
int.TryParse(args[1], out i);
if (i <= 0) {
BroadcastToPlayer(player, lang.GetMessage("invKsNum", this, player.UserIDString), lang.GetMessage("ksListNum", this, player.UserIDString));
return;
}
if (!data.killStreaks.ContainsKey(i)) {
SendReply(player, string.Format(fontColor1 + lang.GetMessage("invKey", this, player.UserIDString) + "</color>", i));
return;
}
BroadcastToPlayer(player, i.ToString(), lang.GetMessage("kills", this, player.UserIDString));
BroadcastToPlayer(player, data.killStreaks[i].StreakType.ToString(), lang.GetMessage("type", this, player.UserIDString));
BroadcastToPlayer(player, data.killStreaks[i].Amount.ToString(), lang.GetMessage("amount", this, player.UserIDString));
// ... [Code preview truncated due to length. Full source in attached file] ...