C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using System;
using System.Linq;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using Oxide.Core.Libraries.Covalence;
using Rust;
using Rust.Ai;
using Network;
namespace Oxide.Plugins {
[Info("Payback2", "1928TOMMYGUN", "1.3.7")]
[Description("Special Admin Commands To Mess With Cheaters")]
class Payback2 : RustPlugin {
//| =============================================
//| CHANGELOG
//| =============================================
//| 1.3.7
//| - Added SPITROAST command
//| 1.3.6
//| - Updated for Jan 28 new year content
//| 1.3.5
//| - attempt to fix wounded NRE in hog
//| 1.3.4
//| - added INTERROGATE command
//| - hog now attempts to keep player's wearables in their inventory
[PluginReference]
Plugin Payback;
//| reference to the original payback plugin
[PluginReference]
private Plugin ImageLibrary;
//| Optional reference to ImageLibrary
//| Hello!
//| This is Payback 2! To make sure you can use this plugin on its own, it comes with some essential features from Payback 1!
//| If you want to have classic admin commands like ROCKETMAN, JAWS, and BSOD, please purchase Payback 1 at https://payback.fragmod.com
//| TUTORIAL:
//| admins require the permission payback.admin to use this plugin
//| this oxide command works for that: oxide.grant group admin payback.admin
//| put 'payback' in the F1 or server console to see the tutorial!
//| =========
//| ===================
//| ==============================================================================
//| TOMMYGUN'S EULA - BY USING THIS PLUGIN YOU AGREE TO THE FOLLOWING!
//| ==============================================================================
//|
//| Code contained in this file is not licensed to be copied, resold, or modified in any way.//| You must purchase another copy of the plugin for each server instance you would like to deploy on.Migration is allowed.//| Do not copy any portion of this document.//| Do not share this plugin with other server organizations, they much purchase their own licenses.//|
//| =======================================
//| ===================
//| =========
//| 1928TOMMYGUN
//MMMMMMMMMMMMMMMMMMMMMMMMWNO::loll::kKKXXXXXXXXXXKXXKx;o000000KKKKNWWWWWWWWWWWWWWWWWWMMMMMMWWXxkNNNNN
//MMMMMMMMMMMMMMMMMMMMMMMMKc,.....................................'',,,,,,,,,,,,,,,,,;;;;;;;;:..,'''.//MMMMMMMMMMMMMMMMMMMMMMMMXc',,;;;;;;;;;;;;;;;;;;;,.',''',;:::::::::::::clldxxxxxxxxxxooocccc
//MMMMMMMMMMMMMMNXK00KXKOdc;'',;:;,,;lxddl::,;::;'.',..''.kWNNNK:...',,........'oXMMMMMMMMMMMMMMMMM
//MMMMWNX0Oxol:;'.......:Oc.xMMMKc....','.;ool,...OMMMMNxcdO0KKo.lNMMMMMMMMMMMMMMMMMM
//Odlc;'...:,';xNMMWk.;xoxXXx'..cXMMMMMMMMMWO:.;OMMMMMMMMMMMMMMMMMMM
//.';:clodxO0XWMMMXo..:x000KK0Ol..xMMMMMMMW0:..:0WWMMMMMMMMMMMMMMMMMMM
//..,lONMMMMMMMMMMMMMX: ,0WMMMMMMMMx.cXMMMMMMMK, 'kNWMMMMMMMMMMMMMMMMMMMMMMMM
//'.;o0NMMMMMMMMMMMMMMMMk..oWMMMMMMMMMx..OMMMMMMMMNl ,OWMMMMMMMMMMMMMMMMMMMMMMM
//'.:xKWMMMMMMMMMMMMMMMMMMMNd..oNMMMMMMMMMMx..OMMMMMMMMMNkl::kWMMMMMMMMMMMMMMMMMMMMMMMM
//..,lkXMMMMMMMMMMMMMMMMMMMMMMMMMXOdxXMMMMMMMMMMMx..OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//..,lkKWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXOkkONMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//:.l0NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//| ==============================================================
//| Definitions
//| ==============================================================
public enum Card {
Pacifism = 0, //zeros all outgoing damage from target player
InstantKarma = 4, //reflects damage back to the player
Dud = 5, //prevents damage to non-player entities
Sit = 8, //force player to sit
HigherGround = 11, //target player is teleported 100m into the air
NoRest, // No Rest For The Wicked! Force the player to respawn!
ViewLoot, // View target entities loot
Hammer, // hammer - gives target player a hammer that will destroy all the entities owned by the hammer's target
Bag, // Bag - Print all players that have bagged target player in, and print all players that have been bagged.Include "discord" after the command to log the results to discord
//| Payback 2
Woods, // Woods - If you go down to the woods today, be ready for big surprise!
PotatoMode, // PotatoMode - Target's frame rate will decrease dramatically over time - Warning, this is designed to eventually crash Rust
Hogwild, // Hogwild - Ride the cheater around like a pig! REEE!
Interrogate, // Interrogate - Throw a hood over the cheater's head, force them to spill their secrets! They can't see anything unless they speak!!
Spitroast, // Spitroast - Stick 'em with the pointy end and feast on their tears.Roast the cheater roticery style over the fire!
}
Dictionary<Card, string> descriptions = new Dictionary<Card, string>() {
{
Card.Dud, "target player deals no damage to NON-PLAYER entities.Also prevents farming / tool use"
}
, {
Card.InstantKarma, "target player deals no damage to enemies and 35% of the damage is reflected back to them"
}
, {
Card.Pacifism, "target player deals no player damage to non-teammates; add 'silent' to not send a message about it to other players."
}
, {
Card.Sit, "spawns a chair in front of you and forces the cheater to sit.Doesn't let them get up and will place them back in if they die."
}
, {
Card.HigherGround, "target player is teleported 100m into the air"
}
, {
Card.NoRest, "No Rest For The Wicked! Force the player to respawn when they die!"
}
, {
Card.ViewLoot, "View target player's loot"
}
, {
Card.Hammer, "Gives admin a hammer that will destroy all the entities owned by the hammer's target.Add -noloot to also delete the loot"
}
, {
Card.Bag, "Print all players that have bagged target player in, and print all players that have been bagged.Include \"discord\" after the command to log the results to discord"
}
, //| Payback 2
{
Card.Woods, "Target will get attacked by a bear if he's farming wood or stone.Add 'landmine' to strap a bunch of landmines to the bear's face"
}
, {
Card.PotatoMode, "Target's frame rate will decrease dramatically over time.-- *Warning, this is designed to crash Rust*"
}
, {
Card.Hogwild, "Ride the cheater around like a pig! REEE!"
}
, {
Card.Interrogate, "Throw a hood over the cheater's head, force them to spill their secrets! They can't see anything unless they speak!! Supports spectate mode!"
}
, {
Card.Spitroast, "Stick 'em with the pointy end and feast on their tears.Roast the cheater roticery style over the fire!"
}
,
}
;
Dictionary<string, Card> cardAliases = new Dictionary<string, Card>() {
{
"dud", Card.Dud
}
, {
"in", Card.InstantKarma
}
, {
"pf", Card.Pacifism
}
, {
"hg", Card.HigherGround
}
, {
"nr", Card.NoRest
}
, {
"res", Card.NoRest
}
, {
"loot", Card.ViewLoot
}
, {
"ham", Card.Hammer
}
, {
"bg", Card.Bag
}
, //| Payback 2
{
"bear", Card.Woods
}
, {
"potato", Card.PotatoMode
}
, {
"hog", Card.Hogwild
}
, {
"sack", Card.Interrogate
}
, {
"roast", Card.Spitroast
}
,
}
;
//| ==============================================================
//| Giving
//| ==============================================================
public void GiveCard(ulong userID, Card card, string[] args = null, BasePlayer admin = null) {
HashSet<Card> cards;
if (!cardMap.TryGetValue(userID, out cards)) {
cards = new HashSet<Card>();
cardMap[userID] = cards;
}
cards.Add(card);
//Puts($"Payback card {card} given to {userID}");
BasePlayer player = BasePlayer.FindByID(userID);
if (player != null) {
if (card == Card.Sit) {
DoSitCommand(player, admin);
}
else if (card == Card.HigherGround) {
DoHigherGround(player);
}
else if (card == Card.Pacifism) {
silentPacifism = false;
if (args != null) {
if (args.Contains("silent")) {
silentPacifism = true;
}
}
}
else if (card == Card.NoRest) {
if (player.IsDead()) {
player.Respawn();
}
}
else if (card == Card.ViewLoot) {
ViewTargetPlayerInventory(player, admin);
TakeCard(player, Card.ViewLoot);
}
else if (card == Card.Hammer) {
GiveAdminHammer(player);
if (args.Contains("noloot")) {
flag_kill_no_loot = true;
PrintToPlayer(admin, $"Hammer set to remove loot!");
}
else {
flag_kill_no_loot = false;
}
}
else if (card == Card.Woods) {
if (args.Contains("landmine")) {
woodsHasLandmines.Add(player.userID);
}
else {
woodsHasLandmines.Remove(player.userID);
}
}
else if (card == Card.PotatoMode) {
DoPotato(player, admin, args);
}
else if (card == Card.Hogwild) {
DoHog(player, admin, args);
}
else if (card == Card.Interrogate) {
DoInterrogate(player, admin, args);
}
else if (card == Card.Spitroast) {
DoSpitroastCommand(player, admin);
}
}
}
bool silentPacifism = false;
//| ==============================================================
//| COMMAND Implementation
//| ==============================================================
public void Line(BasePlayer player, Vector3 from, Vector3 to, Color color, float duration) {
player.SendConsoleCommand("ddraw.line", duration, color, from, to);
}
#region Spitroast
public Dictionary<ulong, HashSet<BaseEntity>> roastEntities = new Dictionary<ulong, HashSet<BaseEntity>>();
void DoSpitroastCommand(BasePlayer targetPlayer, BasePlayer adminPlayer) {
if (targetPlayer == null) return;
//if (!HasCard(targetPlayer.userID, Card.Spitroast))
//{
// ResolveConflictingCommands(targetPlayer, adminPlayer);
//}
if (HasCard(targetPlayer.userID, Card.Spitroast)) {
if (adminPlayer == null) return;
if (targetPlayer.isMounted) {
targetPlayer.GetMounted().DismountPlayer(targetPlayer, true);
var car = targetPlayer.GetMountedVehicle();
if (car != null) {
car.Kill(BaseNetworkable.DestroyMode.Gib);
}
BaseEntity chair = null;
if (sitChairMap.TryGetValue(targetPlayer.userID, out chair)) {
chair?.Kill();
}
}
RaycastHit hitinfo;
if (Physics.Raycast(adminPlayer.eyes.HeadRay(), out hitinfo, 50)) {
Worker.StaticStartCoroutine(RoastCo(targetPlayer, adminPlayer, hitinfo));
}
}
else {
BaseEntity chair = null;
if (sitChairMap.TryGetValue(targetPlayer.userID, out chair)) {
if (chair != null) {
chair.Kill();
}
}
HashSet<BaseEntity> roasted = null;
if (roastEntities.TryGetValue(targetPlayer.userID, out roasted)) {
foreach (var r in roasted) {
r?.Kill();
}
roastEntities.Remove(targetPlayer.userID);
roasted.Clear();
}
}
}
IEnumerator RoastCo(BasePlayer targetPlayer, BasePlayer adminPlayer, RaycastHit hitinfo) {
HashSet<BaseEntity> roasted = null;
if (!roastEntities.TryGetValue(targetPlayer.userID, out roasted)) {
roasted = new HashSet<BaseEntity>();
roastEntities[targetPlayer.userID] = roasted;
}
Vector3 lookAtPosition = adminPlayer.transform.position;
targetPlayer.Teleport(hitinfo.point);
var chair = InvisibleSit(targetPlayer);
sitChairMap[targetPlayer.userID] = chair;
targetPlayer.EndSleeping();
GameObject.DestroyImmediate(chair.GetComponentInChildren<DestroyOnGroundMissing>());
GameObject.DestroyImmediate(chair.GetComponentInChildren<GroundWatch>());
lookAtPosition.y = chair.transform.position.y;
chair.transform.LookAt(lookAtPosition);
//| Stick em with the spear
var spearItem = ItemManager.CreateByName("spear.stone");
var droppedSpear = spearItem.Drop(targetPlayer.transform.position + Vector3.down * 0.25f, Vector3.zero) as DroppedItem;
droppedSpear.transform.position += chair.transform.forward * -0.05f;
droppedSpear.GetComponent<Rigidbody>().isKinematic = true;
droppedSpear.GetComponent<Rigidbody>().useGravity = false;
droppedSpear.GetComponent<Rigidbody>().velocity = Vector3.zero;
droppedSpear.allowPickup = false;
SetDespawnDuration(droppedSpear, 1000000);
roasted.Add(droppedSpear);
droppedSpear.transform.Rotate(droppedSpear.transform.right, 90);
//droppedSpear.transform.LookAt(droppedSpear.transform.position + Vector3.down);
Item muzzle = ItemManager.CreateByPartialName("muzzlebrake");
var droppedMuzzle = muzzle.Drop(targetPlayer.transform.position + Vector3.up * 0.75f, Vector2.zero);
DroppedItem droppedItem = droppedMuzzle as DroppedItem;
droppedItem.allowPickup = false;
droppedItem.GetComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
droppedItem.GetComponent<Rigidbody>().isKinematic = true;
droppedItem.GetComponent<Rigidbody>().useGravity = false;
if (droppedItem != null) {
SetDespawnDuration(droppedItem, float.MaxValue);
}
roasted.Add(droppedMuzzle);
//droppedMuzzle.transform.LookAt(lookAtPosition);
//droppedSpear.SetParent(chair, true, true);
chair.SetParent(droppedMuzzle, true, true);
droppedSpear.SetParent(droppedMuzzle, true, true);
droppedMuzzle.transform.Rotate(droppedMuzzle.transform.forward, 90);
//| come up off the ground a bit
droppedMuzzle.transform.position += Vector3.up * 0.3f;
//| spawn the campfire.var campfire = GameManager.server.CreateEntity("assets/prefabs/deployable/campfire/campfire.prefab", hitinfo.point);
campfire.Spawn();
roasted.Add(campfire);
//campfire.GetComponent<StabilityEntity>().grounded = true;
//var campfireContainer = campfire as StorageContainer;
campfire.SetFlag(BaseEntity.Flags.Locked, true, true, true);
var oven = campfire as BaseOven;
oven.StartCooking();
yield return null;
//| extra bits
var spearItem2 = ItemManager.CreateByName("spear.stone");
var droppedSpear2 = spearItem2.Drop(droppedSpear.transform.position + Vector3.down * 1.8f, Vector3.zero) as DroppedItem;
droppedSpear2.GetComponent<Rigidbody>().isKinematic = true;
droppedSpear2.GetComponent<Rigidbody>().useGravity = false;
droppedSpear2.GetComponent<Rigidbody>().velocity = Vector3.zero;
droppedSpear2.allowPickup = false;
SetDespawnDuration(droppedSpear2, 1000000);
roasted.Add(droppedSpear2);
droppedSpear2.transform.LookAt(droppedSpear2.transform.position + Vector3.down);
var spearItem3 = ItemManager.CreateByName("spear.stone");
var droppedSpear3 = spearItem3.Drop(droppedSpear.transform.position + Vector3.down * 1.8f + droppedSpear.transform.forward * -1.8f, Vector3.zero) as DroppedItem;
droppedSpear3.GetComponent<Rigidbody>().isKinematic = true;
droppedSpear3.GetComponent<Rigidbody>().useGravity = false;
droppedSpear3.GetComponent<Rigidbody>().velocity = Vector3.zero;
droppedSpear3.allowPickup = false;
SetDespawnDuration(droppedSpear3, 1000000);
roasted.Add(droppedSpear3);
droppedSpear3.transform.LookAt(droppedSpear3.transform.position + Vector3.down);
var target = droppedMuzzle;
float roastSpeed = 1.5f;
while (target != null && targetPlayer != null && HasCard(targetPlayer.userID, Card.Spitroast)) {
//Line(targetPlayer, target.transform.position, target.transform.position + chair.transform.forward, Color.red, Time.fixedDeltaTime);
//target.transform.Rotate(target.transform.right, roastSpeed);
//target.transform.Rotate(target.transform.up, roastSpeed);
//target.transform.Rotate(target.transform.forward, roastSpeed);
target.transform.Rotate(target.transform.up, roastSpeed, Space.World);
oven.StartCooking();
//target.SendNetworkUpdate();
yield return new WaitForFixedUpdate();
}
droppedSpear?.Kill();
chair?.Kill();
droppedSpear2?.Kill();
droppedSpear3?.Kill();
droppedMuzzle?.Kill();
campfire?.Kill();
if (targetPlayer != null) {
TakeCard(targetPlayer.userID, Card.Spitroast);
}
}
#endregion
#region Interrogate
string interrogate_open_url = "https://i.imgur.com/EBAoy53.png";
string interrogate_closed_url = "https://i.imgur.com/Dokk9TO.png";
string guid_interrogate = "guid_interrogate";
Dictionary<ulong, bool> interrogationState = new Dictionary<ulong, bool>();
Dictionary<ulong, Item> interrogationMasks = new Dictionary<ulong, Item>();
Dictionary<ulong, HashSet<ulong>> interrogationSpectators = new Dictionary<ulong, HashSet<ulong>>();
void DoInterrogate(BasePlayer player, BasePlayer admin = null, string[] args = null, bool removeCard = false, bool open = false) {
//| ===================================
//| BASE UI SETUP
//| ===================================
if (player.net.connection == null) return;
//| don't update image if we're in the correct state.bool existingState = GetInterrogationState(player.userID);
if (open && existingState == open && !removeCard) return;
interrogationState[player.userID] = open;
if (!open) {
bool existingMask = false;
foreach (var item in player.inventory.containerWear.itemList.ToArray()) {
if (item.info.itemid == ItemManager.FindItemDefinition("mask.balaclava").itemid && item.skin == 10139) {
existingMask = true;
interrogationMasks[player.userID] = item;
break;
}
var x = item.info.GetComponent<global : : ItemModWearable>();
bool headGear = x.ProtectsArea(HitArea.Head);
if (headGear) {
bool success = item.MoveToContainer(player.inventory.containerMain);
if (!success) {
item.Drop(player.transform.position + Vector3.up, Vector3.up);
}
}
}
if (!existingMask) {
var mask = ItemManager.CreateByName("mask.balaclava", 1, 10139);
GiveItemOrDrop(player, mask, false);
interrogationMasks[player.userID] = mask;
}
}
else {
if (interrogationMasks.ContainsKey(player.userID)) {
var mask = interrogationMasks[player.userID];
if (mask != null) {
mask.RemoveFromContainer();
mask.Remove();
interrogationMasks.Remove(player.userID);
}
}
}
if (removeCard) {
Unsubscribe("OnPlayerVoice");
interrogationState.Remove(player.userID);
if (interrogationMasks.ContainsKey(player.userID)) {
var mask = interrogationMasks[player.userID];
if (mask != null) {
mask.RemoveFromContainer();
mask.Remove();
interrogationMasks.Remove(player.userID);
}
}
}
else {
Subscribe("OnPlayerVoice");
}
UpdateInterrogateUI(player, open, removeCard);
var spectators = player.GetComponentsInChildren<BasePlayer>();
foreach (var spectator in spectators) {
if (spectator != player) {
UpdateInterrogateUI(spectator, open, removeCard);
}
}
}
bool GetInterrogationState(ulong userid) {
bool existingState;
interrogationState.TryGetValue(userid, out existingState);
return existingState;
}
void UpdateInterrogateUI(BasePlayer player, bool open, bool remove = false) {
Puts($"OnPlayerSpectate | UpdateInterrogateUI {player}");
string guid = guid_interrogate;
UI2.guids.Add(guid);
var elements = new CuiElementContainer();
CuiHelper.DestroyUi(player, guid);
if (remove) return;
//| ===================================
//| Bounds definitions
//| ===================================
float fade = 0.2f;
Vector4 mainBounds = UI2.vectorFullscreen;
UI2.CreatePanel(elements, "Overlay", guid, "1 1 1 0", mainBounds, null, false, 0, 0);
//| ===================================
//| Static elements
//| ===================================
string url = interrogate_closed_url;
if (open) {
url = interrogate_open_url;
}
if (ImageLibrary == null) {
UI2.CreatePanel(elements, guid, "bg", "1 1 1 1", UI2.vectorFullscreen, url, false, fade, fade, false, false);
}
else {
UI2.CreatePanel(elements, guid, "bg", "1 1 1 1", UI2.vectorFullscreen, GetImage(url), false, fade, fade, true, false);
}
//send the ui updates
if (elements.Count > 0) {
CuiHelper.AddUi(player, elements);
}
}
object OnPlayerSpectate(BasePlayer spectator, string targetDisplayName) {
Puts($"OnPlayerSpectate | {spectator.displayName} -> {targetDisplayName}");
var player = FindPlayer(targetDisplayName);
if (player != null) {
Puts($"OnPlayerSpectate 2 | {spectator.displayName} -> {targetDisplayName}");
BasePlayer targetplayer = player.Object as BasePlayer;
if (HasCard(targetplayer.userID, Card.Interrogate)) {
Puts($"OnPlayerSpectate 3 | {spectator.displayName} -> {targetDisplayName}");
bool existingState = GetInterrogationState(targetplayer.userID);
UpdateInterrogateUI(spectator, existingState, false);
}
}
return null;
}
//object CanSpectateTarget(BasePlayer spectator, string targetDisplayName) {
// return null;
//}
object OnPlayerSpectateEnd(BasePlayer spectator, string targetDisplayName) {
Puts($"OnPlayerSpectateEnd | {targetDisplayName}");
var player = FindPlayer(targetDisplayName);
if (player != null) {
BasePlayer targetplayer = player.Object as BasePlayer;
if (HasCard(targetplayer.userID, Card.Interrogate)) {
CuiHelper.DestroyUi(spectator, guid_interrogate);
}
}
return null;
}
object OnPlayerRecover(BasePlayer player) {
if (HasCard(player.userID, Card.Hogwild)) {
return false;
}
return null;
}
Dictionary<ulong, Coroutine> interrogationCooldowns = new Dictionary<ulong, Coroutine>();
object OnPlayerVoice(BasePlayer player, Byte[] data) {
//Unsubscribe("OnPlayerVoice");
//Subscribe("OnPlayerVoice");
//PrintToChat($"{player.displayName} is speaking");
//Puts($"{player.displayName} is speaking");
if (HasCard(player.userID, Card.Interrogate)) {
DoInterrogate(player, null, null, false, true);
Coroutine co = null;
if (interrogationCooldowns.TryGetValue(player.userID, out co)) {
Worker.GetSingleton().StopCoroutine(co);
}
co = Worker.StaticStartCoroutine(InterrogationCo(player));
interrogationCooldowns[player.userID] = co;
}
return null;
}
IEnumerator InterrogationCo(BasePlayer player) {
yield return new WaitForSeconds(0.45f);
if (HasCard(player.userID, Card.Interrogate)) {
DoInterrogate(player, null, null, false, false);
}
}
#endregion
#region HOG
object CanLootPlayer(BasePlayer target, BasePlayer looter) {
if (HasCard(target.userID, Card.Hogwild)) {
return false;
}
return null;
}
Dictionary<ulong, List<BaseEntity>> cowboynetworkables = new Dictionary<ulong, List<BaseEntity>>();
void DoHog(BasePlayer player, BasePlayer admin = null, string[] args = null, bool removeCard = false) {
if (removeCard) {
List<BaseEntity> existing;
if (cowboynetworkables.TryGetValue(player.userID, out existing)) {
if (existing != null) {
existing.ForEach(x => {
x.Kill();
}
);
existing.Clear();
}
cowboynetworkables.Remove(player.userID);
}
if (player != null) {
player.StopWounded();
}
return;
}
cowboynetworkables[player.userID] = new List<BaseEntity>() {
}
;
//down target player
//disabled for testing
player.BecomeWounded(new HitInfo());
player.ProlongWounding(100000000000);
ResolveConflictingCommands(player, admin);
//|====================================================
//| create the chair for the person to ride
var chair = GameManager.server.CreateEntity(invisibleChairPrefab, player.transform.position + Vector3.up * 0.2f);
var mount = chair as BaseMountable;
chair.Spawn();
GameObject.DestroyImmediate(chair.GetComponentInChildren<DestroyOnGroundMissing>());
GameObject.DestroyImmediate(chair.GetComponentInChildren<GroundWatch>());
var collider = chair.GetComponentInChildren<Collider>();
if (collider != null) {
collider.enabled = false;
}
cowboynetworkables[player.userID].Add(chair);
//| muzzlebreak
Item muzzle = ItemManager.CreateByPartialName("muzzlebrake");
var dropped = muzzle.Drop(player.transform.position, Vector2.zero);
DroppedItem droppedItem = dropped as DroppedItem;
droppedItem.allowPickup = false;
droppedItem.GetComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
droppedItem.GetComponent<Rigidbody>().isKinematic = true;
droppedItem.GetComponent<Rigidbody>().useGravity = false;
if (droppedItem != null) {
SetDespawnDuration(droppedItem, float.MaxValue);
}
Worker.StaticStartCoroutine(DropFollowPlayer(player, droppedItem));
cowboynetworkables[player.userID].Add(droppedItem);
//chair.SetParent(player, true, true);
chair.SetParent(droppedItem, true, true);
chair.transform.rotation = Quaternion.identity;
//| make it look like the seated player is above the target
Worker.StaticStartCoroutine(UpdateSeatedPlayerCo(chair as BaseMountable));
//| make sure the target doesn't clip into the chair collider
Worker.StaticStartCoroutine(AlwaysKill(chair, player));
//Worker.StaticStartCoroutine(AlwaysKill(admin, player));
//| make the dropped object follow the player without parenting (networking issues)
Worker.StaticStartCoroutine(ContinuousTP(player, chair));
//| make the chair face the players direction
Worker.StaticStartCoroutine(ChairFacingCo(player, droppedItem));
//| show the game tip about being ridden
Worker.StaticStartCoroutine(HogGameTipCo(player, chair as BaseMountable));
var boarEntity = GameManager.server.CreateEntity("assets/rust.ai/agents/boar/boar.prefab", player.transform.position);
boarEntity.Spawn();
cowboynetworkables[player.userID].Add(boarEntity);
Worker.StaticStartCoroutine(HogSFX(player, boarEntity));
//| look the part
foreach (var item in player.inventory.containerWear.itemList.ToArray()) {
bool success = item.MoveToContainer(player.inventory.containerMain);
if (!success) {
item.Drop(player.transform.position + Vector3.up, Vector3.zero);
}
}
//GiveItemOrDrop(player, ItemManager.CreateByName("attire.hide.skirt", 1, 793180528), false);
GiveItemOrDrop(player, ItemManager.CreateByName("mask.balaclava", 1, 10139), false);
}
IEnumerator HogSFX(BasePlayer player, BaseEntity boarEntity) {
float ts = float.NegativeInfinity;
var boar = boarEntity as Boar;
boar.enabled = false;
//boar.StopAllCoroutines();
boar.NavAgent.enabled = false;
while (player != null && HasCard(player.userID, Card.Hogwild) && boarEntity != null && !boarEntity.IsDestroyed) {
if (Time.realtimeSinceStartup - ts > 5f) {
boar.gameObject.SetActive(true);
boar.SignalBroadcast(BaseEntity.Signal.Attack);
ts = Time.realtimeSinceStartup;
boar.gameObject.SetActive(false);
PlayGesture(player, "hurry");
}
boar.transform.position = player.transform.position + Vector3.down * 3f;
yield return new WaitForFixedUpdate();
}
}
IEnumerator HogGameTipCo(BasePlayer player, BaseMountable mount) {
while (player != null && mount != null && !mount.IsDestroyed) {
if (mount.IsMounted()) {
CreateGameTip($"{mount.GetMounted().displayName} is riding you like a pig! REEE!!", player, 5, true);
//CreateGameTip($"{mount.GetMounted().displayName} is riding you like a pig!", mount.GetMounted(), 5, true);
yield return new WaitForSeconds(4.9f);
}
else {
yield return new WaitForSeconds(0.1f);
}
}
}
IEnumerator UpdateSeatedPlayerCo(BaseMountable mount) {
while (mount != null) {
if (mount.IsMounted()) {
//mount.GetMounted().Teleport(mount.transform.position + Vector3.up * 0.75f);
//mount.GetMounted().Teleport(mount.transform.position + Vector3.up * 0.8f);
mount.GetMounted().Teleport(mount.transform.position + Vector3.up * 0.95f);
}
yield return new WaitForFixedUpdate();
}
}
public void CreateGameTip(string text, BasePlayer player, float length = 30f, bool redColor = false) {
if (player == null) return;
if (redColor) {
player.SendConsoleCommand($"gametip.showtoast {1} \"{text}\" ");
}
else {
player.SendConsoleCommand("gametip.hidegametip");
player.SendConsoleCommand("gametip.showgametip", text + " ");
timer.Once(length, () => {
if (player != null) {
player.SendConsoleCommand("gametip.hidegametip");
}
}
);
}
}
IEnumerator DropFollowPlayer(BasePlayer player, DroppedItem item) {
while (player != null && item != null && !item.IsDestroyed) {
item.transform.position = player.transform.position + Vector3.down * 0.1f;
yield return new WaitForFixedUpdate();
}
}
IEnumerator ChairFacingCo(BasePlayer player, BaseEntity chair) {
while (player != null && chair != null && !chair.IsDestroyed) {
Vector3 facing = player.eyes.HeadForward();
facing.y = 0;
facing.Normalize();
chair.transform.LookAt(chair.transform.position + facing);
//chair.transform.Rotate(Vector3.up, 72);
chair.transform.Rotate(Vector3.up, 1);
chair.SendNetworkUpdate();
yield return new WaitForFixedUpdate();
}
}
IEnumerator ContinuousTP(BasePlayer player, BaseEntity entity) {
while (player != null && entity != null) {
if (player.isMounted) player.Teleport(entity.transform.position + Vector3.up * 1f) ;
yield return new WaitForSeconds(0.25f);
}
}
public void SendToPlayer(BasePlayer player, ulong netid, byte[] data) {
NetWrite write = Net.sv.StartWrite();
write.PacketID(Message.Type.VoiceData);
write.UInt64(netid);
write.BytesWithSize(data);
write.Send(new SendInfo(player.Connection) {
priority = Priority.Immediate
}
);
}
IEnumerator AlwaysKill(BaseEntity entity, BasePlayer player) {
List<Network.Connection> cons = new List<Network.Connection>(1);
while (entity != null && player != null && player.net != null && player.net.connection != null) {
cons.Clear();
cons.Add(player.net.connection);
cons.Clear();
cons.Add(player.net.connection);
NetWrite write = Net.sv.StartWrite();
write.PacketID(Message.Type.VoiceData);
write.UInt64(entity.net.ID.Value);
// write.BytesWithSize(data);
write.Send(new SendInfo(cons) {
priority = Priority.Immediate
}
);
//if (Network.Net.sv.write.Start())
//{
// Network.Net.sv.write.PacketID(Message.Type.EntityDestroy);
// Network.Net.sv.write.EntityID(entity.net.ID.Value);
// Network.Net.sv.write.UInt8((byte)BaseNetworkable.DestroyMode.None);
// Network.Net.sv.write.Send(new SendInfo(cons));
//}
yield return new WaitForSeconds(0.1f);
}
}
#endregion
#region POTATO
string guid_potato = "guid_potato";
Dictionary<ulong, int> currentFrameMap = new Dictionary<ulong, int>();
Dictionary<ulong, Coroutine> potatoCoRoutines = new Dictionary<ulong, Coroutine>();
void DoPotato(BasePlayer player, BasePlayer admin = null, string[] args = null, bool doRemove = false) {
Coroutine routine;
potatoCoRoutines.TryGetValue(player.userID, out routine);
if (doRemove) {
if (routine != null) {
Worker.GetSingleton().StopCoroutine(routine);
return;
}
//if (args.Contains("add")) {
// //| contiue to add to the lag
//} else
//{
// int existing = 0;
// currentFrameMap.TryGetValue(player.userID, out existing);
// for (int i = 0; i <= existing; i ++)
// {
// CuiHelper.DestroyUi(player, guid_BSOD + i);
// }
// currentFrameMap.Remove(player.userID);
// CuiHelper.DestroyUi(player, guid_BSOD);
// return;
//}
}
//if (!currentFrameMap.ContainsKey(player.userID))
//{
// UI2.guids.Add(guid_BSOD);
// var elements = new CuiElementContainer();
// UI2.CreatePanel(elements, "Under", guid_BSOD, "1 1 1 0", UI2.vectorFullscreen, null, false, 0, 0, false);
// CuiHelper.AddUi(player, elements);
//}
UI2.guids.Add(guid_potato);
var elements = new CuiElementContainer();
UI2.CreatePanel(elements, "Under", guid_potato, "1 1 1 0", UI2.vectorFullscreen, null, false, 0, 0, false);
CuiHelper.AddUi(player, elements);
routine = Worker.StaticStartCoroutine(DoPotatoCo(player, args));
potatoCoRoutines[player.userID] = routine;
}
IEnumerator DoPotatoCo(BasePlayer player, string[] args) {
int batch = 10;
//int totalFrames = 600;
int currentFrames = 0;
float rate = 100 / 1f;
//if (args.Contains("crash"))
//{
// intensity = 5;
// totalFrames = 5000;
//}
float ts = Time.realtimeSinceStartup;
float startTime = ts;
float elapsed;
float currentRate;
while (player != null && player.net != null && player.net.connection != null && player.net.connection.connected && HasCard(player.userID, Card.PotatoMode)) {
elapsed = Time.realtimeSinceStartup - startTime + Mathf.Epsilon;
currentRate = currentFrames / elapsed;
if (currentRate > rate) {
//Puts($"Paused: Current Frames: {currentFrames} rate {currentRate}");
yield return null;
}
else {
for (int j = 0; j < batch; j++) {
UI2.guids.Add(guid_potato + currentFrames);
var elements = new CuiElementContainer();
UI2.CreatePanel(elements, guid_potato, guid_potato + currentFrames, "1 1 1 0", UI2.vectorFullscreen, null, false, 0, 0, false);
CuiHelper.AddUi(player, elements);
currentFrames++;
}
}
//Puts($"Current Frames: {currentFrames} rate {currentRate}");
//| Ensure we take a break at least every 1/30s
if (Time.realtimeSinceStartup - ts > 1/30f) {
ts = Time.realtimeSinceStartup;
yield return null;
}
}
}
Dictionary<ulong, float> woodsTimestamps = new Dictionary<ulong, float>();
HashSet<ulong> woodsHasLandmines = new HashSet<ulong>();
void DoWoods(BasePlayer target) {
float ts = 0;
woodsTimestamps.TryGetValue(target.userID, out ts);
if (Time.realtimeSinceStartup - ts < 15) {
return;
}
woodsTimestamps[target.userID] = Time.realtimeSinceStartup;
//TakeCard(target, Card.Woods);
int layermask = 1 << 15 | 1 << 16 | 1 << 17 | 1 << 23 | 1 << 27 | 1 << 8 | 1 << 21 | 1 << 12 | 1 << 0 | 1 << 30;
bool foundSpot = false;
int iterations = 0;
while (!foundSpot && iterations < 100) {
var pos = target.transform.position + target.eyes.HeadRay().direction * -1 * 20;
pos += Vector3.up * 100;
var ray = new Ray(pos, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000, layermask)) {
//var hits = Physics.SphereCastAll(hit.point, 1, Vector3.up);
var collliders = Physics.OverlapSphere(hit.point, 1);
bool tooClose = false;
if (collliders != null) {
foreach (var c in collliders) {
var ent = c.gameObject.GetComponent<BaseEntity>();
if (ent != null) {
tooClose = true;
}
}
}
if (!tooClose) {
foundSpot = true;
if (woodsHasLandmines.Contains(target.userID)) {
Worker.StaticStartCoroutine(AnimalAttackCo(target, hit.point + Vector3.up, new string[] {
"bear", "landmine"
}
));
}
else {
Worker.StaticStartCoroutine(AnimalAttackCo(target, hit.point + Vector3.up, new string[] {
"bear"
}
));
}
}
}
iterations++;
}
}
HashSet<BaseEntity> animals = new HashSet<BaseEntity>();
HashSet<BaseEntity> noDamageEntities = new HashSet<BaseEntity>();
IEnumerator AnimalAttackCo(BasePlayer player, Vector3 spawnposition, string[] args) {
//Ray ray = new Ray(UnityEngine.Random.Range(-5f, 5f) * Vector3.forward + UnityEngine.Random.Range(-5f, 5f) * Vector3.left + spawnposition + Vector3.up * 20, Vector3.down);
//Ray ray = new Ray(UnityEngine.Random.Range(-5f, 5f) * Vector3.forward + UnityEngine.Random.Range(-5f, 5f) * Vector3.left + spawnposition + Vector3.up * 20, Vector3.down);
//if (Physics.Raycast(ray, out hit))
//{
string aiPrefab = "assets/rust.ai/agents/chicken/chicken.prefab";
if (args.Contains("bear")) {
aiPrefab = "assets/rust.ai/agents/bear/bear.prefab";
}
else if (args.Contains("boar")) {
aiPrefab = "assets/rust.ai/agents/boar/boar.prefab";
}
else if (args.Contains("wolf")) {
aiPrefab = "assets/rust.ai/agents/wolf/wolf.prefab";
}
else if (args.Contains("stag")) {
aiPrefab = "assets/rust.ai/agents/stag/stag.prefab";
}
//assets/rust.ai/agents/wolf/wolf.prefab
var entity = GameManager.server.CreateEntity(aiPrefab, spawnposition + Vector3.up * 0.2f);
//var entity = GameManager.server.CreateEntity("assets/rust.ai/agents/wolf/wolf.prefab", hit.point + Vector3.up * 0.2f);
//var entity = GameManager.server.CreateEntity("assets/rust.ai/agents/bear/bear.prefab", hit.point + Vector3.up * 0.2f);
BaseAnimalNPC npc = entity as BaseAnimalNPC;
entity.Spawn();
var stats = npc.Stats;
npc.AttackRange = 3;
HashSet<BaseEntity> forceNetworkUpdates = new HashSet<BaseEntity>();
if (args.Contains("landmine")) {
for (int i = 0; i < 5; i ++) {
var mine = GameManager.server.CreateEntity("assets/prefabs/deployable/landmine/landmine.prefab", npc.transform.position + Vector3.up * 0.6f + npc.transform.forward * (1.3f - 0.1f * i));
Landmine landmine = mine as
// ... [Code preview truncated due to length. Full source in attached file] ...