using Newtonsoft.Json; using Oxide.Core; using Oxide.Core.Configuration; using Oxide.Core.Libraries.Covalence; using Oxide.Core.Plugins; using System.Collections; using System.Collections.Generic; using System.Globalization; using System; using System.IO; using System.Linq; using UnityEngine; namespace Oxide.Plugins { [Info("Lights On", "mspeedie", "2.0.28")] [Description("Toggle lights on/off either as configured or by name.")] // big thank you to FastBurn for helping fix Fluid Splitters and adding Flashing Lights and Siren Lights // big thank you to Meeh for the help with the boomboxes public class LightsOn : CovalencePlugin //RustPlugin { [PluginReference] Plugin ZoneManager; const string perm_lightson = "lightson.allowed"; private bool NightToggleactive = false; private bool nightcross24 = false; private bool config_changed = false; private Timer Sweeptimer; private List zones_with_lights = new List(); readonly DynamicConfigFile zdataFile = Interface.Oxide.DataFileSystem.GetFile("LightsOn-Zones"); ItemDefinition fuel = ItemManager.FindItemDefinition("lowgradefuel"); private Dictionary IOPowerAmt = new Dictionary(); // strings to compare to check object names //const string autoturret_name = "autoturret"; const string bbq_name = "bbq"; const string bbq_camper_name = "bbq.campermodule"; const string boombox_name = "boombox"; const string campfire_name = "campfire"; const string cctv_name = "cctv"; const string ceilinglight_name = "ceilinglight"; const string chineselantern_name = "chineselantern"; const string cursedcauldron_name = "cursedcauldron"; const string deluxe_lightstring_name = "xmas.lightstring.advanced"; // it is not always consistent in name const string deluxe_lights2_name = "xmas.advanced.lights"; // it is not always consistent in name const string elevator_name = "elevatorioentity"; const string firepit_name = "skull_fire_pit"; const string fireplace_name = "fireplace"; const string flasherlight_name = "electric.flasherlight"; const string fluidswitch_name = "fluidswitch"; const string fogmachine_name = "fogmachine"; const string furnace_large_name = "furnace.large"; const string furnace_name = "furnace"; const string hatcandle_name = "hat.candle"; const string hatminer_name = "hat.miner"; const string heater_name = "electrical.heater"; const string hobobarrel_s_name = "hobobarrel_static"; const string hobobarrel_p_name = "hobobarrel"; const string industrial_wall_lamp_name = "industrial.wall.lamp"; const string industrial_wall_lamp_green_name = "industrial.wall.lamp.green"; const string industrial_wall_lamp_red_name = "industrial.wall.lamp.red"; const string igniter_name = "igniter"; const string jackolantern_angry_name = "jackolantern.angry"; const string jackolantern_happy_name = "jackolantern.happy"; const string lantern_name = "lantern"; const string large_candleset_name = "largecandleset"; const string laserdetector_name = "laserdetector"; const string laserlight_name = "laserlight"; //const string microphonestand_name = "microphonestand"; // this generates a signal and does not require power const string mining_pumpjack_name = "mining.pumpjack"; const string mining_pumpjack_static_name = "pumpjack"; const string mining_quarry_name = "mining_quarry"; const string mining_quarry_static_name = "miningquarry"; const string mixingtable_name = "mixingtable"; const string powered_water_purifier_name = "poweredwaterpurifier"; const string reactive_target_name = "reactivetarget"; const string refinery_small_name = "refinery_small"; // no clue why this one is inconsistent so we have it twice const string small_refinery_name = "small_refinery"; // no clue why this one is inconsistent so we have it twice const string rfbroadcaster_name = "rfbroadcaster"; const string rfreceiver_name = "rfreceiver"; const string sam_site_name = "sam_site_turret"; const string searchlight_name = "searchlight"; const string sign_name = "sign"; // we have a procedure to find all the specific sign names and below const string sign_neon_125x125_name = "sign.neon.125x125"; const string sign_neon_125x215_animated_name = "sign.neon.125x215.animated"; const string sign_neon_125x215_name = "sign.neon.125x215"; const string sign_neon_xl_animated_name = "sign.neon.xl.animated"; const string sign_neon_xl_name = "sign.neon.xl"; const string simplelight_name = "simplelight"; const string sirenlight_name = "electric.sirenlight"; const string small_candleset_name = "smallcandleset"; const string smart_alarm_name = "smartalarm"; const string smart_switch_name = "smartswitch"; const string snowmachine_name = "snowmachine"; const string spookyspeaker_name = "spookyspeaker"; const string storage_monitor_name = "storagemonitor"; const string strobelight_name = "strobelight"; const string telephone_name = "telephone"; const string teslacoil_name = "teslacoil"; const string tunalight_name = "tunalight"; const string vehiclelift_name = "electrical.modularcarlift"; const string water_purifier_name = "waterpurifier"; const string waterpump_name = "water.pump"; static readonly string [] cookable = new string[13] {"bearmeat", "can.beans.empty", "can.tuna.empty", "chicken.raw", "deermeat.raw", "fish.raw", "horsemeat.raw", "hq.metal.ore", "humanmeat.raw", "meat.boar", "metal.ore", "sulfur.ore", "wolfmeat.raw"}; #region Configuration private Configuration config; public class Configuration { [JsonProperty(PropertyName = "Hats do not use fuel (a-always d-day n-night i-ignore)")] public string Hats { get; set; } = "a"; //[JsonProperty(PropertyName = "Auto Turrets (a-always d-day n-night i-ignore)")] //public string AutoTurrets { get; set; } = "i"; [JsonProperty(PropertyName = "BBQs (a-always d-day n-night i-ignore)")] public string BBQs { get; set; } = "i"; [JsonProperty(PropertyName = "Boom Boxes (a-always d-day n-night i-ignore)")] public string BoomBoxes { get; set; } = "i"; [JsonProperty(PropertyName = "Campfires (a-always d-day n-night i-ignore)")] public string Campfires { get; set; } = "a"; [JsonProperty(PropertyName = "Candles (a-always d-day n-night i-ignore)")] public string Candles { get; set; } = "a"; [JsonProperty(PropertyName = "Cauldrons (a-always d-day n-night i-ignore)")] public string Cauldrons { get; set; } = "a"; [JsonProperty(PropertyName = "CCTVs (a-always d-day n-night i-ignore)")] public string CCTVs { get; set; } = "a"; [JsonProperty(PropertyName = "Ceiling Lights (a-always d-day n-night i-ignore)")] public string CeilingLights { get; set; } = "a"; [JsonProperty(PropertyName = "Deluxe Light Strings (a-always d-day n-night i-ignore)")] public string DeluxeLightstrings { get; set; } = "a"; [JsonProperty(PropertyName = "Elevators (a-always d-day n-night i-ignore)")] public string Elevators { get; set; } = "a"; [JsonProperty(PropertyName = "Fire Pits (a-always d-day n-night i-ignore)")] public string FirePits { get; set; } = "a"; [JsonProperty(PropertyName = "Fireplaces (a-always d-day n-night i-ignore)")] public string Fireplaces { get; set; } = "a"; [JsonProperty(PropertyName = "Flasher Lights (a-always d-day n-night i-ignore)")] public string FlasherLights { get; set; } = "i"; [JsonProperty(PropertyName = "FluidSwitches (a-always d-day n-night i-ignore)")] public string FluidSwitches { get; set; } = "a"; [JsonProperty(PropertyName = "Fog Machines (a-always d-day n-night i-ignore)")] public string FogMachines { get; set; } = "i"; [JsonProperty(PropertyName = "Furnaces (a-always d-day n-night i-ignore)")] public string Furnaces { get; set; } = "i"; [JsonProperty(PropertyName = "Hobo Barrels Static (a-always d-day n-night i-ignore)")] public string SHoboBarrels { get; set; } = "a"; [JsonProperty(PropertyName = "Player Hobo Barrels (a-always d-day n-night i-ignore)")] public string PHoboBarrels { get; set; } = "a"; [JsonProperty(PropertyName = "Heaters (a-always d-day n-night i-ignore)")] public string Heaters { get; set; } = "a"; [JsonProperty(PropertyName = "Industrial Wall Lamp (a-always d-day n-night i-ignore)")] public string IndustrialWallLamps { get; set; } = "a"; [JsonProperty(PropertyName = "Igniters (a-always d-day n-night i-ignore)")] public string Igniters { get; set; } = "i"; [JsonProperty(PropertyName = "Lanterns (a-always d-day n-night i-ignore)")] public string Lanterns { get; set; } = "a"; [JsonProperty(PropertyName = "LaserDetectors (a-always d-day n-night i-ignore)")] public string LaserDetectors { get; set; } = "i"; [JsonProperty(PropertyName = "LaserLights (a-always d-day n-night i-ignore)")] public string LaserLights { get; set; } = "i"; [JsonProperty(PropertyName = "Mining Quarries (a-always d-day n-night i-ignore)")] public string MiningQuarries { get; set; } = "a"; [JsonProperty(PropertyName = "Mixing Tables (a-always d-day n-night i-ignore)")] public string MixingTables { get; set; } = "a"; [JsonProperty(PropertyName = "Pump Jacks (a-always d-day n-night i-ignore)")] public string PumpJacks { get; set; } = "a"; [JsonProperty(PropertyName = "Reactive Targets (a-always d-day n-night i-ignore)")] public string ReactiveTargets { get; set; } = "a"; [JsonProperty(PropertyName = "RF Broadcasters (a-always d-day n-night i-ignore)")] public string RFBroadcasters { get; set; } = "a"; [JsonProperty(PropertyName = "RF Receivers (a-always d-day n-night i-ignore)")] public string RFReceivers { get; set; } = "a"; [JsonProperty(PropertyName = "Refineries (a-always d-day n-night i-ignore)")] public string Refineries { get; set; } = "i"; [JsonProperty(PropertyName = "SAM Sites (a-always d-day n-night i-ignore)")] public string SamSites { get; set; } = "a"; [JsonProperty(PropertyName = "Search Lights (a-always d-day n-night i-ignore)")] public string SearchLights { get; set; } = "a"; [JsonProperty(PropertyName = "Signs (a-always d-day n-night i-ignore)")] public string Signs { get; set; } = "a"; [JsonProperty(PropertyName = "Simple Lights (a-always d-day n-night i-ignore)")] public string SimpleLights { get; set; } = "a"; [JsonProperty(PropertyName = "Siren Lights (a-always d-day n-night i-ignore)")] public string SirenLights { get; set; } = "a"; [JsonProperty(PropertyName = "Smart Alarms (a-always d-day n-night i-ignore)")] public string SmartAlarms { get; set; } = "a"; [JsonProperty(PropertyName = "Smart Switches (a-always d-day n-night i-ignore)")] public string SmartSwitches { get; set; } = "a"; [JsonProperty(PropertyName = "SnowMachines (a-always d-day n-night i-ignore)")] public string SnowMachines { get; set; } = "a"; [JsonProperty(PropertyName = "SpookySpeakers (a-always d-day n-night i-ignore)")] public string Speakers { get; set; } = "i"; [JsonProperty(PropertyName = "Storage Monitor (a-always d-day n-night i-ignore)")] public string StorageMonitors { get; set; } = "a"; [JsonProperty(PropertyName = "Strobe Lights (a-always d-day n-night i-ignore)")] public string StrobeLights { get; set; } = "i"; [JsonProperty(PropertyName = "Telephones (a-always d-day n-night i-ignore)")] public string Telephones { get; set; } = "a"; [JsonProperty(PropertyName = "Tesla Coils (a-always d-day n-night i-ignore)")] public string TeslaCoils { get; set; } = "i"; [JsonProperty(PropertyName = "VehicleLifts (a-always d-day n-night i-ignore)")] public string VehicleLifts { get; set; } = "a"; [JsonProperty(PropertyName = "Water Pumps (a-always d-day n-night i-ignore)")] public string WaterPumps { get; set; } = "a"; [JsonProperty(PropertyName = "Water Purifiers (powered and unpowered) (a-always d-day n-night i-ignore)")] public string WaterPurifiers { get; set; } = "a"; [JsonProperty(PropertyName = "Protect BBQs (true/false)")] public bool ProtectBBQs { get; set; } = true; [JsonProperty(PropertyName = "Protect Campfires (true/false)")] public bool ProtectCampfires { get; set; } = false; [JsonProperty(PropertyName = "Protect Cauldrons (true/false)")] public bool ProtectCauldrons { get; set; } = false; [JsonProperty(PropertyName = "Protect Fire Pits (true/false)")] public bool ProtectFirePits { get; set; } = false; [JsonProperty(PropertyName = "Protect Fireplaces (true/false)")] public bool ProtectFireplaces { get; set; } = false; [JsonProperty(PropertyName = "Protect Furnaces (true/false)")] public bool ProtectFurnaces { get; set; } = true; [JsonProperty(PropertyName = "Protect Hobo Barrels (true/false)")] public bool ProtectHoboBarrels { get; set; } = false; [JsonProperty(PropertyName = "Protect Mixing Tables (true/false)")] public bool ProtectMixingTables { get; set; } = true; [JsonProperty(PropertyName = "Protect Refineries (true/false)")] public bool ProtectRefineries { get; set; } = true; [JsonProperty(PropertyName = "Keep running if more than one fuel present (true/false)")] public bool KeepRunningIfFuel { get; set; } = true; [JsonProperty(PropertyName = "Console Output (true/false)")] public bool ConsoleMsg { get; set; } = true; [JsonProperty(PropertyName = "Check Frequency (in seconds)")] public int CheckFrequency { get; set; } = 300; [JsonProperty(PropertyName = "Dusk Time (HH in a 24 hour clock)")] public float DuskTime { get; set; } = 17.5f; [JsonProperty(PropertyName = "Dawn Time (HH in a 24 hour clock)")] public float DawnTime { get; set; } = 09.0f; [JsonProperty(PropertyName = "Use Zone Manager Plugin")] public bool UseZoneManagerPlugin { get; set; } = false; [JsonProperty(PropertyName = "Alter Unowned Entities")] public bool AlterUnowned { get; set; } = false; [JsonProperty(PropertyName = "First Check After Initialization (in seconds)")] public int StartupDelay { get; set; } = 60; [JsonProperty(PropertyName = "BoomBox Power")] public int BoomBoxPower { get; set; } = 200; [JsonProperty(PropertyName = "Elevator Power")] public int ElevatorPower { get; set; } = 500; [JsonProperty(PropertyName = "Christmas Lights Power")] public int XmasLightsPower { get; set; } = 200; [JsonProperty(PropertyName = "Laser Detector Power")] public int LaserDetectorPower { get; set; } = 2; [JsonProperty(PropertyName = "Player Can Toggle non-lights (true/false)")] public bool PlayerToggleAll { get; set; } = false; [JsonProperty(PropertyName = "Furnace InstaCook (true/false)")] public bool FurnaceInstaCook { get; set; } = false; [JsonProperty(PropertyName = "Furnace NoFuelRequired (true/false)")] public bool FurnaceNoFuelRequired { get; set; } = false; [JsonProperty(PropertyName = "Furnace CookAnything (true/false)")] public bool FurnaceCookAnything { get; set; } = false; //[JsonProperty(PropertyName = "Microphone Stand Power")] //public int MicrophoneStandPower { get; set; } = 200; [JsonProperty(PropertyName = "Boom boxes On (true/false)")] public bool BoomBoxOn { get; set; } = true; public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } protected override void LoadDefaultConfig() => config = new Configuration(); protected override void LoadConfig() { // Set power amounts // If needed this can be moved to config //IOPowerAmt.Add("autoturret", 10); // we call clear incase LoadConfig gets called more than once or after load IOPowerAmt.Clear(); IOPowerAmt.Add("boombox", 200); IOPowerAmt.Add("cctv", 5); IOPowerAmt.Add("ceilinglight", 2); IOPowerAmt.Add("electric.flasherlight", 1); IOPowerAmt.Add("electric.sirenlight", 1); IOPowerAmt.Add("electrical.heater", 3); IOPowerAmt.Add("electrical.modularcarlift", 5); IOPowerAmt.Add("elevatorioentity", 500); IOPowerAmt.Add("fluidswitch", 1); IOPowerAmt.Add("fogmachine", 1); IOPowerAmt.Add("igniter", 2); IOPowerAmt.Add("laserlight", 1); IOPowerAmt.Add("poweredwaterpurifier", 5); IOPowerAmt.Add("reactivetarget", 1); IOPowerAmt.Add("rfbroadcaster", 1); IOPowerAmt.Add("rfreceiver", 1); IOPowerAmt.Add("sam_site_turret", 25); IOPowerAmt.Add("searchlight", 10); IOPowerAmt.Add("sign.neon.125x125", 4); IOPowerAmt.Add("sign.neon.125x215", 6); IOPowerAmt.Add("sign.neon.125x215.animated", 10); IOPowerAmt.Add("sign.neon.xl", 8); IOPowerAmt.Add("sign.neon.xl.animated", 15); IOPowerAmt.Add("industrial.wall.lamp", 2); IOPowerAmt.Add("industrial.wall.lamp.green", 2); IOPowerAmt.Add("industrial.wall.lamp.red", 2); IOPowerAmt.Add("simplelight", 2); IOPowerAmt.Add("smartalarm", 1); IOPowerAmt.Add("smartswitch", 1); IOPowerAmt.Add("snowmachine", 1); IOPowerAmt.Add("storagemonitor", 1); IOPowerAmt.Add("strobelight", 1); IOPowerAmt.Add("telephone", 2); IOPowerAmt.Add("teslacoil", 34); IOPowerAmt.Add("water.pump", 5); IOPowerAmt.Add("waterpurifier", 5); IOPowerAmt.Add("xmas.lightstring.advanced", 200); //IOPowerAmt.Add("microphonestand", 200); // added to deal with inconsistent names IOPowerAmt.Add("xmas.advanced.lights", 200); try { base.LoadConfig(); config = Config.ReadObject(); if (config == null) { throw new JsonException(); } if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) { LogWarning("Configuration appears to be outdated; updating and saving"); SaveConfig(); } } catch { LogWarning($"Configuration file {Name}.json is invalid; using defaults"); LoadDefaultConfig(); } // set the dictionary to be in synch IOPowerAmt["boombox"] = config.BoomBoxPower; IOPowerAmt["elevatorioentity"] = config.ElevatorPower; IOPowerAmt["xmas.lightstring.advanced"] = config.XmasLightsPower; IOPowerAmt["xmas.advanced.lights"] = config.XmasLightsPower; IOPowerAmt["laserdetector"] = config.LaserDetectorPower; //IOPowerAmt["microphonestand"] = config.MicrophoneStandPower; CheckConfig(); } protected override void SaveConfig() { LogWarning($"Configuration changes saved to {Name}.json"); Config.WriteObject(config, true); } #endregion Configuration string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args); protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["bad check frequency"] = "Check frequency must be between 10 and 600", ["bad check frequency2"] = "Check frequency must be between 60 and 6000", ["bad prefab"] = "Bad Prefab Name, not found: ", ["bad dusk time"] = "Dusk time must be between 0 and 24", ["bad dawn time"] = "Dawn time must be between 0 and 24", ["Coninstacook"] = "Cook anything only supported when InstaCook is true", ["dawn=dusk"] = "Dawn can't be the same value as dusk", ["dawn"] = "Lights going off. Next lights on at ", ["default"] = "Loading default config for LightsOn", ["dusk"] = "Lights coming on. Ending at ", ["Empty Zone"] = @"Empty Zone name in your oxide\data\LightsOn-Zones.json", ["Foninstacook"] = "No Fuel Requirement only supported when InstaCook is true", ["lights off"] = "Lights Off", ["lights on"] = "Lights On", ["lights check"] = "Lights processing based on settings", ["nopermission"] = "You do not have permission to use that command.", ["No Zone"] = @"Use Zone Manager set but no zones in oxide\data\LightsOn-Zones.json", ["invalid state"] = "Please select one (and only one of a, d, n, or i)[a-always d-day n-night i-ignore] for {0}", ["prefix"] = "LightsOn: ", ["state"] = "unknown state: please use on or off", ["syntax"] = @"syntax: Lights State (check/on/off) Optional: prefabshortname (part of the prefab name) to change their state, use all to force all lights' state", ["zone"] = "Zone Manager requested but not found loaded" }, this); } protected void CheckConfig() { // used to validate config settings List ValidConfigChoices = new List { "a","d","i","n" }; config_changed = false; // check data is ok because people can make mistakes if (config.DuskTime < 0f || config.DuskTime > 24f) { Puts(Lang("bad dusk time (outside of 0 to 24)")); config.DuskTime = 17f; config_changed = true; } if (config.DawnTime < 0f || config.DawnTime > 24f) { Puts(Lang("bad dawn time (outside of 0 to 24)")); config.DawnTime = 9f; config_changed = true; } if (config.DawnTime == config.DuskTime) { Puts(Lang("dawn can't be equal to dusk")); config.DawnTime = 9f; config.DuskTime = 17f; config_changed = true; } if (config.CheckFrequency < 30 || config.CheckFrequency > 3600) { Puts(Lang("bad check frequency (too small or too large)")); config.CheckFrequency = 300; config_changed = true; } if (config.StartupDelay < 30 || config.StartupDelay > 3600) { Puts(Lang("bad Startup Delay (too small or too large)")); config.StartupDelay = 60; config_changed = true; } // determine correct light timing logic if (config.DuskTime > config.DawnTime) nightcross24 = true; else nightcross24 = false; if (config.BBQs == null || config.BBQs.Length != 1 || !ValidConfigChoices.Contains(config.BBQs)) { Puts(Lang("invalid state",null,"BBQs")); config.BBQs = "a"; config_changed = true; } if (config.BoomBoxes == null || config.BoomBoxes.Length != 1 || !ValidConfigChoices.Contains(config.BoomBoxes)) { Puts(Lang("invalid state",null,"BoomBoxes")); config.BoomBoxes = "a"; config_changed = true; } //if (config.MicrophoneStands == null || config.MicrophoneStands.Length != 1 || !ValidConfigChoices.Contains(config.MicrophoneStands)) //{ // Puts(Lang("invalid state",null,"MicrophoneStands")); // config.MicrophoneStands = "a"; // config_changed = true; //} if (config.CCTVs == null || config.CCTVs.Length != 1 || !ValidConfigChoices.Contains(config.CCTVs)) { Puts(Lang("invalid state",null,"CCTVs")); config.CCTVs = "a"; config_changed = true; } if (config.Campfires == null || config.Campfires.Length != 1 || !ValidConfigChoices.Contains(config.Campfires)) { Puts(Lang("invalid state",null,"Campfires")); config.Campfires = "a"; config_changed = true; } if (config.Candles == null || config.Candles.Length != 1 || !ValidConfigChoices.Contains(config.Candles)) { Puts(Lang("invalid state",null,"Candles")); config.Candles = "a"; config_changed = true; } if (config.Cauldrons == null || config.Cauldrons.Length != 1 || !ValidConfigChoices.Contains(config.Cauldrons)) { Puts(Lang("invalid state",null,"Cauldrons")); config.Cauldrons = "a"; config_changed = true; } if (config.CeilingLights == null || config.CeilingLights.Length != 1 || !ValidConfigChoices.Contains(config.CeilingLights)) { Puts(Lang("invalid state",null,"CeilingLights")); config.CeilingLights = "a"; config_changed = true; } if (config.DeluxeLightstrings == null || config.DeluxeLightstrings.Length != 1 || !ValidConfigChoices.Contains(config.DeluxeLightstrings)) { Puts(Lang("invalid state",null,"DeluxeLightstrings")); config.DeluxeLightstrings = "a"; config_changed = true; } if (config.Elevators == null || config.Elevators.Length != 1 || !ValidConfigChoices.Contains(config.Elevators)) { Puts(Lang("invalid state",null,"Elevators")); config.Elevators = "a"; config_changed = true; } if (config.FirePits == null || config.FirePits.Length != 1 || !ValidConfigChoices.Contains(config.FirePits)) { Puts(Lang("invalid state",null,"FirePits")); config.FirePits = "a"; config_changed = true; } if (config.Fireplaces == null || config.Fireplaces.Length != 1 || !ValidConfigChoices.Contains(config.Fireplaces)) { Puts(Lang("invalid state",null,"Fireplaces")); config.Fireplaces = "a"; config_changed = true; } if (config.FlasherLights == null || config.FlasherLights.Length != 1 || !ValidConfigChoices.Contains(config.FlasherLights)) { Puts(Lang("invalid state",null,"FlasherLights")); config.FlasherLights = "a"; config_changed = true; } if (config.FluidSwitches == null || config.FluidSwitches.Length != 1 || !ValidConfigChoices.Contains(config.FluidSwitches)) { Puts(Lang("invalid state",null,"FluidSwitches")); config.FluidSwitches = "a"; config_changed = true; } if (config.FogMachines == null || config.FogMachines.Length != 1 || !ValidConfigChoices.Contains(config.FogMachines)) { Puts(Lang("invalid state",null,"FogMachines")); config.FogMachines = "a"; config_changed = true; } if (config.Furnaces == null || config.Furnaces.Length != 1 || !ValidConfigChoices.Contains(config.Furnaces)) { Puts(Lang("invalid state",null,"Furnaces")); config.Furnaces = "a"; config_changed = true; } if (config.Hats == null || config.Hats.Length != 1 || !ValidConfigChoices.Contains(config.Hats)) { Puts(Lang("invalid state",null,"Hats")); config.Hats = "a"; config_changed = true; } if (config.Heaters == null || config.Heaters.Length != 1 || !ValidConfigChoices.Contains(config.Heaters)) { Puts(Lang("invalid state",null,"Heaters")); config.Heaters = "a"; config_changed = true; } if (config.PHoboBarrels == null || config.PHoboBarrels.Length != 1 || !ValidConfigChoices.Contains(config.PHoboBarrels)) { Puts(Lang("invalid state",null,"Player HoboBarrels")); config.PHoboBarrels = "a"; config_changed = true; } if (config.SHoboBarrels == null || config.SHoboBarrels.Length != 1 || !ValidConfigChoices.Contains(config.SHoboBarrels)) { Puts(Lang("invalid state",null,"Static HoboBarrels")); config.SHoboBarrels = "a"; config_changed = true; } if (config.Igniters == null || config.Igniters.Length != 1 || !ValidConfigChoices.Contains(config.Igniters)) { Puts(Lang("invalid state",null,"Igniters")); config.Igniters = "a"; config_changed = true; } if (config.Lanterns == null || config.Lanterns.Length != 1 || !ValidConfigChoices.Contains(config.Lanterns)) { Puts(Lang("invalid state",null,"Lanterns")); config.Lanterns = "a"; config_changed = true; } if (config.LaserDetectors == null || config.LaserDetectors.Length != 1 || !ValidConfigChoices.Contains(config.LaserDetectors)) { Puts(Lang("invalid state",null,"LaserDetectors")); config.LaserDetectors = "i"; config_changed = true; } if (config.LaserLights == null || config.LaserLights.Length != 1 || !ValidConfigChoices.Contains(config.LaserLights)) { Puts(Lang("invalid state",null,"LaserLights")); config.LaserLights = "i"; config_changed = true; } if (config.MixingTables == null || config.MixingTables.Length != 1 || !ValidConfigChoices.Contains(config.MixingTables)) { Puts(Lang("invalid state",null,"MixingTables")); config.MixingTables = "a"; config_changed = true; } if (config.RFBroadcasters == null || config.RFBroadcasters.Length != 1 || !ValidConfigChoices.Contains(config.RFBroadcasters)) { Puts(Lang("invalid state",null,"RFBroadcasters")); config.RFBroadcasters = "a"; config_changed = true; } if (config.RFReceivers == null || config.RFReceivers.Length != 1 || !ValidConfigChoices.Contains(config.RFReceivers)) { Puts(Lang("invalid state",null,"RFReceivers")); config.RFReceivers = "a"; config_changed = true; } if (config.ReactiveTargets == null || config.ReactiveTargets.Length != 1 || !ValidConfigChoices.Contains(config.ReactiveTargets)) { Puts(Lang("invalid state",null,"ReactiveTargets")); config.ReactiveTargets = "a"; config_changed = true; } if (config.Refineries == null || config.Refineries.Length != 1 || !ValidConfigChoices.Contains(config.Refineries)) { Puts(Lang("invalid state",null,"Refineries")); config.Refineries = "a"; config_changed = true; } if (config.SamSites == null || config.SamSites.Length != 1 || !ValidConfigChoices.Contains(config.SamSites)) { Puts(Lang("invalid state",null,"SamSites")); config.SamSites = "a"; config_changed = true; } if (config.SearchLights == null || config.SearchLights.Length != 1 || !ValidConfigChoices.Contains(config.SearchLights)) { Puts(Lang("invalid state",null,"SearchLights")); config.SearchLights = "a"; config_changed = true; } if (config.MiningQuarries == null || config.MiningQuarries.Length != 1 || !ValidConfigChoices.Contains(config.MiningQuarries)) { Puts(Lang("invalid state",null,"MiningQuarries")); config.MiningQuarries = "a"; config_changed = true; } if (config.PumpJacks == null || config.PumpJacks.Length != 1 || !ValidConfigChoices.Contains(config.PumpJacks)) { Puts(Lang("invalid state",null,"PumpJacks")); config.PumpJacks = "a"; config_changed = true; } if (config.Signs == null || config.Signs.Length != 1 || !ValidConfigChoices.Contains(config.Signs)) { Puts(Lang("invalid state",null,"Signs")); config.Signs = "a"; config_changed = true; } if (config.IndustrialWallLamps == null || config.IndustrialWallLamps.Length != 1 || !ValidConfigChoices.Contains(config.IndustrialWallLamps)) { Puts(Lang("invalid state",null,"IndustrialWallLamps")); config.IndustrialWallLamps = "a"; config_changed = true; } if (config.SimpleLights == null || config.SimpleLights.Length != 1 || !ValidConfigChoices.Contains(config.SimpleLights)) { Puts(Lang("invalid state",null,"SimpleLights")); config.SimpleLights = "a"; config_changed = true; } if (config.SirenLights == null || config.SirenLights.Length != 1 || !ValidConfigChoices.Contains(config.SirenLights)) { Puts(Lang("invalid state",null,"SirenLights")); config.SirenLights = "i"; config_changed = true; } if (config.SmartAlarms == null || config.SmartAlarms.Length != 1 || !ValidConfigChoices.Contains(config.SmartAlarms)) { Puts(Lang("invalid state",null,"SmartAlarms")); config.SmartAlarms = "a"; config_changed = true; } if (config.SmartSwitches == null || config.SmartSwitches.Length != 1 || !ValidConfigChoices.Contains(config.SmartSwitches)) { Puts(Lang("invalid state",null,"SmartSwitches")); config.SmartSwitches = "a"; config_changed = true; } if (config.SnowMachines == null || config.SnowMachines.Length != 1 || !ValidConfigChoices.Contains(config.SnowMachines)) { Puts(Lang("invalid state",null,"SnowMachines")); config.SnowMachines = "a"; config_changed = true; } if (config.Speakers == null || config.Speakers.Length != 1 || !ValidConfigChoices.Contains(config.Speakers)) { Puts(Lang("invalid state",null,"Speakers")); config.Speakers = "i"; config_changed = true; } if (config.StorageMonitors == null || config.StorageMonitors.Length != 1 || !ValidConfigChoices.Contains(config.StorageMonitors)) { Puts(Lang("invalid state",null,"StorageMonitors")); config.StorageMonitors = "a"; config_changed = true; } if (config.StrobeLights == null || config.StrobeLights.Length != 1 || !ValidConfigChoices.Contains(config.StrobeLights)) { Puts(Lang("invalid state",null,"StrobeLights")); config.StrobeLights = "i"; config_changed = true; } if (config.Telephones == null || config.Telephones.Length != 1 || !ValidConfigChoices.Contains(config.Telephones)) { Puts(Lang("invalid state",null,"Telephones")); config.Telephones = "a"; config_changed = true; } if (config.VehicleLifts == null || config.VehicleLifts.Length != 1 || !ValidConfigChoices.Contains(config.VehicleLifts)) { Puts(Lang("invalid state",null,"VehicleLifts")); config.VehicleLifts = "a"; config_changed = true; } if (config.WaterPumps == null || config.WaterPumps.Length != 1 || !ValidConfigChoices.Contains(config.WaterPumps)) { Puts(Lang("invalid state",null,"WaterPumps")); config.WaterPumps = "a"; config_changed = true; } if (config.WaterPurifiers == null || config.WaterPurifiers.Length != 1 || !ValidConfigChoices.Contains(config.WaterPurifiers)) { Puts(Lang("invalid state",null,"WaterPurifiers")); config.WaterPurifiers = "a"; config_changed = true; } if (!config.FurnaceInstaCook && config.FurnaceNoFuelRequired) { Puts(Lang("Foninstacook",null,"FurnaceNoFuelRequired")); config.FurnaceNoFuelRequired = false; config_changed = true; } if (!config.FurnaceInstaCook && config.FurnaceCookAnything) { Puts(Lang("Coninstacook",null,"FurnaceCookAnything")); config.FurnaceCookAnything = false; config_changed = true; } if (config_changed) SaveConfig(); } private void OnServerInitialized() { // set up permission to run chat command if (!permission.PermissionExists(perm_lightson)) permission.RegisterPermission(perm_lightson,this); if (config.UseZoneManagerPlugin) { zones_with_lights = zdataFile.ReadObject>(); if (zones_with_lights.Count() == 0) Puts(Lang("No Zones for LightsOn Zone setting will be ignored")); else { foreach(string light_zone in zones_with_lights) { if (String.IsNullOrWhiteSpace(light_zone)) { Puts(Lang("Empty Zone found in LightsOn Config")); } //Puts(light_zone); // debug } //Puts(zones_with_lights.Count.ToString()); // debug } } // check if we are in day or night CheckNight(); // give the server time to spawn entities and kick off the process to sweep for what needs to be checked timer.Once(config.StartupDelay, () => {ChangePower(); TimerProcess(); return;}); } private string CleanedName(string prefabName) { if (string.IsNullOrEmpty(prefabName)) return ""; string CleanedString = prefabName.ToLower(); if (CleanedString.Contains("elevatorioentity")) return CleanedString; // special handling for elevators int clean_loc = CleanedString.IndexOf("deployed"); if (clean_loc > 1) CleanedString = CleanedString.Remove(clean_loc-1); clean_loc = CleanedString.IndexOf("static"); if (clean_loc > 1 && prefabName != hobobarrel_s_name) CleanedString = CleanedString.Remove(clean_loc-1); clean_loc = CleanedString.IndexOf("entity"); if (clean_loc > 1) CleanedString = CleanedString.Remove(clean_loc-1); return CleanedString; } private bool IsOvenPrefabName(string prefabName) { if (bbq_name.Contains(prefabName)) return true; else if (bbq_camper_name.Contains(prefabName)) return true; else if (campfire_name.Contains(prefabName)) return true; else if (chineselantern_name.Contains(prefabName)) return true; else if (cursedcauldron_name.Contains(prefabName)) return true; else if (firepit_name.Contains(prefabName)) return true; else if (fireplace_name.Contains(prefabName)) return true; else if (furnace_large_name.Contains(prefabName)) return true; else if (furnace_name.Contains(prefabName)) return true; else if (hobobarrel_s_name.Contains(prefabName)) return true; else if (hobobarrel_p_name.Contains(prefabName)) return true; else if (jackolantern_angry_name.Contains(prefabName)) return true; else if (jackolantern_happy_name.Contains(prefabName)) return true; else if (lantern_name.Contains(prefabName)) return true; else if (refinery_small_name.Contains(prefabName)) return true; else if (small_refinery_name.Contains(prefabName)) return true; // name is not consistent else if (tunalight_name.Contains(prefabName)) return true; else if (water_purifier_name.Contains(prefabName)) return true; else return false; } private bool IsLightPrefabName(string prefabName) // all ovens that just produce light { if (chineselantern_name.Contains(prefabName)) return true; else if (jackolantern_angry_name.Contains(prefabName)) return true; else if (jackolantern_happy_name.Contains(prefabName)) return true; else if (lantern_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_green_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_red_name.Contains(prefabName)) return true; else if (simplelight_name.Contains(prefabName)) return true; else if (tunalight_name.Contains(prefabName)) return true; else return false; } private bool IsHatPrefabName(string prefabName) { // this uses only internal names so do not need the Contains logic if (hatminer_name.Contains(prefabName)) return true; else if (hatcandle_name.Contains(prefabName)) return true; else return false; } private bool IsDevicePrefabName(string prefabName) { if (fogmachine_name.Contains(prefabName)) return true; else if (large_candleset_name.Contains(prefabName)) return true; else if (mining_pumpjack_static_name.Contains(prefabName)) return true; else if (mining_pumpjack_name.Contains(prefabName)) return true; else if (mining_quarry_name.Contains(prefabName)) return true; else if (mining_quarry_static_name.Contains(prefabName)) return true; else if (mixingtable_name.Contains(prefabName)) return true; else if (small_candleset_name.Contains(prefabName)) return true; else if (snowmachine_name.Contains(prefabName)) return true; else if (spookyspeaker_name.Contains(prefabName)) return true; else if (strobelight_name.Contains(prefabName)) return true; else if (waterpump_name.Contains(prefabName)) return true; //else if (autoturret_name.Contains(prefabName)) return true; else return false; } private bool IsElectricPrefabName(string prefabName) { if (cctv_name.Contains(prefabName)) return true; else if (boombox_name.Contains(prefabName)) return true; else if (ceilinglight_name.Contains(prefabName) ) return true; else if (deluxe_lights2_name.Contains(prefabName) ) return true; // name is not consistent else if (deluxe_lightstring_name.Contains(prefabName) ) return true; else if (elevator_name.Contains(prefabName)) return true; else if (flasherlight_name.Contains(prefabName)) return true; else if (fluidswitch_name.Contains(prefabName)) return true; else if (heater_name.Contains(prefabName)) return true; else if (igniter_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_green_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_name.Contains(prefabName)) return true; else if (industrial_wall_lamp_red_name.Contains(prefabName)) return true; else if (laserdetector_name.Contains(prefabName)) return true; else if (laserlight_name.Contains(prefabName)) return true; else if (powered_water_purifier_name.Contains(prefabName)) return true; else if (reactive_target_name.Contains(prefabName)) return true; else if (rfbroadcaster_name.Contains(prefabName)) return true; else if (rfreceiver_name.Contains(prefabName)) return true; else if (sam_site_name.Contains(prefabName)) return true; else if (searchlight_name.Contains(prefabName)) return true; else if (sign_name.Contains(prefabName)) return true; else if (sign_neon_125x125_name.Contains(prefabName)) return true; else if (sign_neon_125x215_animated_name.Contains(prefabName)) return true; else if (sign_neon_125x215_name.Contains(prefabName)) return true; else if (sign_neon_xl_animated_name.Contains(prefabName)) return true; else if (sign_neon_xl_name.Contains(prefabName)) return true; else if (simplelight_name.Contains(prefabName)) return true; else if (sirenlight_name.Contains(prefabName)) return true; else if (smart_alarm_name.Contains(prefabName)) return true; else if (smart_switch_name.Contains(prefabName)) return true; else if (storage_monitor_name.Contains(prefabName)) return true; else if (telephone_name.Contains(prefabName)) return true; else if (teslacoil_name.Contains(prefabName)) return true; else if (vehiclelift_name.Contains(prefabName)) return true; else if (waterpump_name.Contains(prefabName)) return true; else return false; } private bool IsSignShortPrefabName(string prefabName) { switch (CleanedName(prefabName)) { case sign_name: return true; case sign_neon_125x125_name: return true; case sign_neon_125x215_name: return true; case sign_neon_125x215_animated_name: return true; case sign_neon_xl_name: return true; case sign_neon_xl_animated_name: return true; default: return false; } } private static bool IsElectrical(IOEntity ioEntity) { if (ioEntity.ioType == IOEntity.IOType.Electric) return true; else { foreach (var input in ioEntity.inputs) { if (input.type == IOEntity.IOType.Electric) return true; } } return false; } private bool IsLightToggle(string prefabName) { if (lantern_name.Contains(prefabName)) return true; else if (tunalight_name.Contains(prefabName)) return true; else if (chineselantern_name.Contains(prefabName)) return true; else if (jackolantern_angry_name.Contains(prefabName)) return true; else if (jackolantern_happy_name.Contains(prefabName)) return true; //else if (large_candleset_name.Contains(prefabName)) // return true; //else if (small_candleset_name.Contains(prefabName)) // return true; else return false; } private bool CanCookShortPrefabName(string prefabName) { if (furnace_name.Contains(prefabName)) return true; else if (furnace_large_name.Contains(prefabName)) return true; else if (campfire_name.Contains(prefabName)) return true; else if (cursedcauldron_name.Contains(prefabName)) return true; else if (bbq_name.Contains(prefabName)) return true; else if (fireplace_name.Contains(prefabName)) return true; else if (hobobarrel_s_name.Contains(prefabName)) return true; else if (hobobarrel_p_name.Contains(prefabName)) return true; else if (refinery_small_name.Contains(prefabName)) return true; else if (small_refinery_name.Contains(prefabName)) return true; else if (firepit_name.Contains(prefabName)) return true; else return false; } private bool ProtectShortPrefabName(string prefabName) { switch (CleanedName(prefabName)) { case bbq_name: return config.ProtectBBQs; case campfire_name: return config.ProtectCampfires; case cursedcauldron_name: return config.ProtectCauldrons; case fireplace_name: return config.ProtectFireplaces; case furnace_name: return config.ProtectFurnaces; case furnace_large_name: return config.ProtectFurnaces; case hobobarrel_s_name: return config.ProtectHoboBarrels; case hobobarrel_p_name: return config.ProtectHoboBarrels; case refinery_small_name: return config.ProtectRefineries; case small_refinery_name: return config.ProtectRefineries; case firepit_name: return config.ProtectFirePits; case mixingtable_name: return config.ProtectMixingTables; case water_purifier_name: return config.ProtectCampfires; default: { return false; } } } private bool IsCookable(string prefabName) { return cookable.Contains(CleanedName(prefabName)); // CanMoveTo(ItemContainer newcontainer, int iTargetPos = -1); } private bool EntityInZone(BaseEntity entity) { if (!config.UseZoneManagerPlugin || ZoneManager == null || ZoneManager.IsLoaded != true || zones_with_lights.Count() == 0 || !entity.IsValid()) return true; bool in_zone = false; string[] entity_zones = (string[])ZoneManager?.Call("GetEntityZoneIDs", new object[] { entity }); //if (entity_zones.Count() > 0) Puts("EIZ: " + entity_zones.Count().ToString()); // debug if (entity_zones.Count() == 0) return false; // if no zones for entities we default to false foreach(string light_zone in zones_with_lights) { if (!String.IsNullOrWhiteSpace(light_zone)) { foreach(string entity_zone in entity_zones) { if (!String.IsNullOrWhiteSpace(entity_zone) && light_zone.Contains(entity_zone)) { in_zone = true; //Puts("EZ: " + entity_zone); // debug break; } } } //Puts(light_zone); // debug if (in_zone) break; } //if (in_zone) Puts("In Zone: "+ in_zone); // debug return in_zone; } private bool PlayerInZone(BasePlayer player) { if (!config.UseZoneManagerPlugin || ZoneManager == null || ZoneManager.IsLoaded != true || zones_with_lights.Count() == 0) return true; bool in_zone = false; string[] player_zones = (string[])ZoneManager?.Call("GetPlayerZoneIDs", new object[] { player }); //if (player_zones.Count() > 0) Puts("PIZ: " + player_zones.Count().ToString()); // debug if (player_zones.Count() == 0) return false; // if no zones for entities we default to false foreach(string light_zone in zones_with_lights) { if (!String.IsNullOrWhiteSpace(light_zone)) { foreach(string player_zone in player_zones) { if (!String.IsNullOrWhiteSpace(player_zone) && light_zone.Contains(player_zone)) { in_zone = true; // Puts("PZ: " + player_zone); // debug break; } } } if (in_zone) break; } //if (in_zone) Puts("In Zone: "+ in_zone); // debug return in_zone; } private bool BaseNetworkableInZone(BaseNetworkable baseNetworkable) { if (!config.UseZoneManagerPlugin || ZoneManager == null || ZoneManager.IsLoaded != true || zones_with_lights.Count() == 0) return true; if (!(baseNetworkable is BaseEntity)) return false; return EntityInZone(baseNetworkable as BaseEntity); } private string PrefabSetting(string prefabName) { string CleanName = CleanedName(prefabName); if (string.IsNullOrEmpty(CleanName) || (IsOvenPrefabName(CleanName) == false && IsHatPrefabName(CleanName) == false && IsDevicePrefabName(CleanName) == false && IsElectricPrefabName(CleanName) == false)) { //Puts("PrefabSetting bad prefab: " + prefabName + " Cleaned: " + CleanName); // debug return null; } switch (CleanName) { //case autoturret_name: return config.AutoTurrets; case teslacoil_name: return config.TeslaCoils; case bbq_name: return config.BBQs; case bbq_camper_name: return config.BBQs; case boombox_name: return config.BoomBoxes; case campfire_name: return config.Campfires; case cctv_name: return config.CCTVs; case ceilinglight_name: return config.CeilingLights; case chineselantern_name: return config.Lanterns; case cursedcauldron_name: return config.Cauldrons; case deluxe_lightstring_name: return config.DeluxeLightstrings; case deluxe_lights2_name: return config.DeluxeLightstrings; // No clue why this one is inconsistent so we have it twice case elevator_name: return config.Elevators; case firepit_name: return config.FirePits; case fireplace_name: return config.Fireplaces; case flasherlight_name: return config.FlasherLights; case fluidswitch_name: return config.FluidSwitches; case fogmachine_name: return config.FogMachines; case furnace_large_name: return config.Furnaces; case furnace_name: return config.Furnaces; case hatcandle_name: return config.Hats; case hatminer_name: return config.Hats; case heater_name: return config.Heaters; case hobobarrel_s_name: return config.SHoboBarrels; case hobobarrel_p_name: return config.PHoboBarrels; case igniter_name: return config.Igniters; case jackolantern_angry_name: return config.Lanterns; case jackolantern_happy_name: return config.Lanterns; case lantern_name: return config.Lanterns; case large_candleset_name: return config.Candles; case mining_quarry_name: return config.MiningQuarries; case mining_quarry_static_name: return config.MiningQuarries; case mining_pumpjack_name: return config.PumpJacks; case mining_pumpjack_static_name: return config.PumpJacks; case mixingtable_name: return config.MixingTables; case powered_water_purifier_name: return config.WaterPurifiers; case reactive_target_name: return config.ReactiveTargets; case refinery_small_name: return config.Refineries; // No clue why this one is inconsistent so we have it twice case rfbroadcaster_name: return config.RFBroadcasters; case rfreceiver_name: return config.RFReceivers; case sam_site_name: return config.SamSites; case searchlight_name: return config.SearchLights; case sign_name: return config.Signs; // We have a procedure to find all the specific sign names and below case sign_neon_125x125_name: return config.Signs; case sign_neon_125x215_animated_name: return config.Signs; case sign_neon_125x215_name: return config.Signs; case sign_neon_xl_animated_name: return config.Signs; case sign_neon_xl_name: return config.Signs; case industrial_wall_lamp_name: return config.IndustrialWallLamps; case industrial_wall_lamp_green_name: return config.IndustrialWallLamps; case industrial_wall_lamp_red_name: return config.IndustrialWallLamps; case simplelight_name: return config.SimpleLights; case sirenlight_name: return config.SirenLights; case small_candleset_name: return config.Candles; case small_refinery_name: return config.Refineries; // No clue why this one is inconsistent so we have it twice case smart_alarm_name: return config.SmartAlarms; case smart_switch_name: return config.SmartSwitches; case snowmachine_name: return config.SnowMachines; case spookyspeaker_name: return config.Speakers; case storage_monitor_name: return config.StorageMonitors; case strobelight_name: return config.StrobeLights; case telephone_name: return config.Telephones; case tunalight_name: return config.Lanterns; case vehiclelift_name: return config.VehicleLifts; case water_purifier_name: return config.WaterPurifiers; case waterpump_name: return config.WaterPumps; case laserdetector_name: return config.LaserDetectors; case laserlight_name: return config.LaserLights; //case microphonestand_name: return config.MicrophoneStands; default: { //Puts("PrefabSetting unknown prefab: " + CleanName); // debug return null; } } } private sbyte NewStateShortPrefabName(string prefabName, bool force = false, bool state = false) { // -1 = ignore, 0 = off, 1 = 0n string config_setting = PrefabSetting(prefabName); //Puts("NSSPN: " + prefabName + " : " + config_setting); // debug if (string.IsNullOrEmpty(config_setting)) return -1; else if (force == true) { if (state == true) return 1; else return 0; } else if (config_setting == "i") return -1; else if (config_setting == "a") return 1; else if (config_setting == "n") { if (NightToggleactive) return 1; else return 0; } else if (config_setting == "d") { if (NightToggleactive) return 0; else return 1; } else return -1; } bool SbyteToBool(sbyte state) { // we use sbyte instead of bool to allow -1 to skip processing since bool does not support null // note -1 converts to false so needs to be checked before converting to avoid logic failure! // i.e.: if (newstate = -1 || SbyteToBool(newstate) == oven.IsOn()) if (state > 0) return true; else return false; } private static bool IOBlocked(IOEntity ioEntity, int inputSlot, int amount) { object hookResult = Interface.CallHook("OnPowerlessInputUpdate", inputSlot, ioEntity, amount); return hookResult is bool && (bool)hookResult == false; } private void PowerIOEntity(IOEntity ioEntity, int powerAmount) { // Puts("POIE start "); // debug // if (!IsElectrical(ioEntity)) Puts (ioEntity.ShortPrefabName + " is Not Electrical."); else Puts (ioEntity.ShortPrefabName + " is Electrical!"); // debug if (ioEntity == null || !IsElectrical(ioEntity)) return; if (ioEntity.HasParent() && !(ioEntity is ElevatorIOEntity) && !(ioEntity is StorageMonitor)) return; if ((ioEntity is AutoTurret || ioEntity is SamSite) && ioEntity.children != null) // assume it is a modded entity return; if (ioEntity.inputs.Length == 0 || ioEntity.inputs[0].connectedTo.Get() != null) return; string prefabName = CleanedName(ioEntity.ShortPrefabName); if (string.IsNullOrEmpty(prefabName)) return; //Puts("POIE name: " + prefabName); // debug //Puts("POIE number of slots: " + ioEntity.inputs.Length.ToString()); // debug if ((!(deluxe_lightstring_name.Contains(prefabName) || deluxe_lights2_name.Contains(prefabName)) || config.AlterUnowned) && // name is not consistent (ioEntity.OwnerID == 0U || string.IsNullOrEmpty(ioEntity.OwnerID.ToString()))) return; if (IsDevicePrefabName(prefabName) == false && IsElectricPrefabName(prefabName) == false) return; int minslots = 1; // 2 //if (prefabName == "boombox" || prefabName == "microphonestand") // minslots = 1; // so it does not toggle it on for (int inputSlot = 0; inputSlot < Math.Min(minslots,ioEntity.inputs.Length); inputSlot++) { if (ioEntity.inputs[inputSlot].type != IOEntity.IOType.Electric) continue; //Puts(inputSlot.ToString() + " " + ioEntity.inputs[inputSlot].niceName); // debug if (ioEntity.inputs[inputSlot].connectedTo.Get() == null && !IOBlocked(ioEntity, inputSlot, powerAmount)) { //Puts("powering on: " + inputSlot.ToString()); // debug ioEntity.UpdateHasPower(powerAmount, inputSlot); ioEntity.UpdateFromInput(powerAmount, inputSlot); break; } } if (powerAmount > 0) { if (prefabName != "boombox" && config.BoomBoxOn) // && prefabName != "microphonestand") ioEntity.SetFlag(BaseEntity.Flags.On, true); ioEntity.SetFlag(BaseEntity.Flags.Reserved8, true); // has power ioEntity.SetFlag(IOEntity.Flag_HasPower, true); } else if (powerAmount == 0) { if (prefabName != "boombox" && config.BoomBoxOn) // && prefabName != "microphonestand") ioEntity.SetFlag(BaseEntity.Flags.On, false); ioEntity.SetFlag(BaseEntity.Flags.On, false); ioEntity.SetFlag(BaseEntity.Flags.Reserved8, false); // has no power ioEntity.SetFlag(IOEntity.Flag_HasPower, false); } ioEntity.SendNetworkUpdateImmediate(); } private void ProcessEntities(string prefabName, bool force = false, bool state = false) { CheckNight(); if (string.IsNullOrEmpty(prefabName)) return; string CleanName = CleanedName(prefabName); if (string.IsNullOrEmpty(CleanName)) return; if (prefabName != "all" && IsOvenPrefabName(CleanName) == false && IsHatPrefabName(CleanName) == false && IsDevicePrefabName(CleanName) == false && IsElectricPrefabName(CleanName) == false) { // Puts("ProcessEntities Bad Pref: " + prefabName); // debug return; } //if (prefabName == "all") // debug // Puts("all lights"); // debug //else // debug // if (state) // debug // Puts("turning on: " + prefabName + " " + CleanName); // debug // else // debug // Puts("turning off: " + prefabName + " " + CleanName); // debug if (CleanName == "all" || IsOvenPrefabName(CleanName)) { BaseOven[] ovens = BaseNetworkable.serverEntities.OfType().ToArray() as BaseOven[]; string oven_name = " "; foreach (BaseOven oven in ovens) { if (oven == null || oven.IsDestroyed || string.IsNullOrEmpty(oven.ShortPrefabName)) continue; if (force == false && !EntityInZone((BaseEntity) oven)) continue; oven_name = CleanedName(oven.ShortPrefabName); //Puts("turning on: " + oven.ShortPrefabName + " " + oven_name); if (CleanName != "all" && !oven_name.Contains(CleanName)) continue; else { //if (oven_name.Contains("fireplace")) //{ // if (ProtectShortPrefabName(oven_name)) Puts("Protect"); // if (oven.inventory.itemList.Count() > 0) Puts("Has stuff"); // if (config.KeepRunningIfFuel) Puts("config.KeepRunningIfFuel"); // if (NewStateShortPrefabName(oven_name, force, state) > 0) Puts("On"); else Puts("Off"); // if (force == false && ((ProtectShortPrefabName(oven_name) && oven.inventory.itemList.Count() > 0) || (config.KeepRunningIfFuel && oven.inventory.itemList.Count() > 1))) Puts("Don't process"); //} if (force == false && ((ProtectShortPrefabName(oven_name) && oven.inventory.itemList.Count() > 0) || (config.KeepRunningIfFuel && oven.inventory.itemList.Count() > 1))) continue; // protect if there is anything in it (do not change states) sbyte newstate = NewStateShortPrefabName(oven_name, force, state); // check what state is required based on time of day and config if (newstate < 0) continue; // it is set to be ignored bool newbool = SbyteToBool(newstate); if (newbool == oven.IsOn()) continue; // matching desired state so no need to process oven.SetFlag(BaseEntity.Flags.On, newbool); } } } if (CleanName == "all" || IsElectricPrefabName(CleanName)) { IOEntity[] ioEntities = BaseNetworkable.serverEntities.OfType().ToArray() as IOEntity[]; string io_name = " "; int poweramt = 0; foreach (IOEntity ioEntity in ioEntities) { if (ioEntity == null || ioEntity.IsDestroyed || string.IsNullOrEmpty(ioEntity.ShortPrefabName) || !IsElectrical(ioEntity)) continue; if (force == false && !EntityInZone((BaseEntity) ioEntity)) continue; io_name = CleanedName(ioEntity.ShortPrefabName); if (string.IsNullOrEmpty(io_name)) continue; //if (io_name.ToLower().Contains("laserd")) // debug //{ // Puts ("processing: " + io_name + " : " + CleanName); // debug // if (!io_name.Contains(CleanName)) Puts ("No Match"); // debug //} if (CleanName != "all" && !io_name.Contains(CleanName)) continue; if (IsDevicePrefabName(io_name) == false && IsElectricPrefabName(io_name) == false) continue; if ((!(deluxe_lightstring_name.Contains(io_name) || deluxe_lights2_name.Contains(io_name)) || config.AlterUnowned) && // name is not consistent (string.IsNullOrEmpty(ioEntity.OwnerID.ToString()) || ioEntity.OwnerID == 0U)) continue; sbyte newstate = NewStateShortPrefabName(io_name, force, state); // check what state is required based on time of day and config if (newstate < 0) continue; // it is set to be ignored bool newbool = SbyteToBool(newstate); TeslaCoil teslacoil = ioEntity as TeslaCoil; if (teslacoil != null) { teslacoil.maxDischargeSelfDamageSeconds = 0f; } try { poweramt = Math.Max(IOPowerAmt[io_name],1); } catch { Puts("Change Power errored: " + io_name + " : " + poweramt.ToString()); // debug } if (!newbool) poweramt = 0; PowerIOEntity(ioEntity, poweramt); } } if (CleanName == "all" || large_candleset_name.Contains(CleanName) || small_candleset_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(large_candleset_name, force, state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); Candle[] candles = BaseNetworkable.serverEntities.OfType().ToArray() as Candle[]; foreach (Candle candle in candles) { if (candle == null || candle.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) candle)) continue; if (newbool == candle.IsOn()) continue; // matching desired state so no need to process candle.SetFlag(BaseEntity.Flags.On, newbool); candle.lifeTimeSeconds = 999999f; candle.burnRate = 0.0f; candle.SendNetworkUpdateImmediate(); } } } if (CleanName == "all" || mixingtable_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(mixingtable_name, force, state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); MixingTable[] mixingtables = BaseNetworkable.serverEntities.OfType().ToArray() as MixingTable[]; foreach (MixingTable mixingtable in mixingtables) { if (mixingtable != null && !mixingtable.IsDestroyed) { if (force == false && !EntityInZone((BaseEntity) mixingtable)) continue; if (force == false && (ProtectShortPrefabName(mixingtable_name) || config.KeepRunningIfFuel) && mixingtable.inventory.itemList.Count() > 0) continue; // protect if there is anything in it (do not change states) if (newbool == true) { //Puts("ProcessDevices Mixing Table On"); mixingtable.RemainingMixTime = 999999f; mixingtable.TotalMixTime = 999999f; mixingtable.SetFlag(BaseEntity.Flags.On, true); mixingtable.SendNetworkUpdateImmediate(); } else { //Puts("ProcessDevices Mixing Table Off"); mixingtable.RemainingMixTime = 0f; mixingtable.TotalMixTime = 0f; mixingtable.SetFlag(BaseEntity.Flags.On, false); mixingtable.SendNetworkUpdateImmediate(); } } } } } if (CleanName == "all" || fogmachine_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(fogmachine_name, force, state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); FogMachine[] fogmachines = BaseNetworkable.serverEntities.OfType().ToArray() as FogMachine[]; foreach (FogMachine fog_machine in fogmachines) { if (force == false && !EntityInZone((BaseEntity) fog_machine)) continue; if (!(fog_machine == null || fog_machine.IsDestroyed)) { // there is bug with IsOn so force state if (newbool == true) // if (fogmachine.IsOn() != newbool) { //fog_machine.FinishFogging(); Item newItem = ItemManager.Create(fuel, 1); newItem.MoveToContainer(fog_machine.inventory); fog_machine.fuelPerSec = 0f; fog_machine.CancelInvoke(new Action(fog_machine.CheckTrigger)); fog_machine.SetFlag(BaseEntity.Flags.On, true, true, true); fog_machine.InvokeRepeating(new Action(fog_machine.StartFogging), 0, 60); fog_machine.nozzleBlastDuration = 60f; } else { fog_machine.FinishFogging(); fog_machine.SetFlag(BaseEntity.Flags.On, newbool); } fog_machine.SendNetworkUpdateImmediate(); } } } } //if (!string.IsNullOrEmpty(CleanName) && snowmachine_name.Contains(CleanName)) Puts ("Snow machine"); else Puts("Not snow: " + CleanName); // debug //if (config.SnowMachines) Puts("Snow is configure"); else Puts("Snow is not active"); // debug if (CleanName == "all" || snowmachine_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(snowmachine_name, force, state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); SnowMachine[] snowmachines = BaseNetworkable.serverEntities.OfType().ToArray() as SnowMachine[]; foreach (SnowMachine snow_machine in snowmachines) { if (!(snow_machine == null || snow_machine.IsDestroyed)) { if (force == false && !EntityInZone((BaseEntity) snow_machine)) continue; // there is bug with IsOn so force state if (newbool == true) // if (fogmachine.IsOn() != newbool) { //snow_machine.FinishFogging(); //snow_machine.SetFlag(BaseEntity.Flags.On, false); Item newItem = ItemManager.Create(fuel, 1); newItem.MoveToContainer(snow_machine.inventory); snow_machine.fuelPerSec = 0f; snow_machine.CancelInvoke(new Action(snow_machine.CheckTrigger)); snow_machine.SetFlag(BaseEntity.Flags.On, true, true, true); //snow_machine.EnableFogField(); snow_machine.InvokeRepeating(new Action(snow_machine.StartFogging), 0, 60); //snow_machine.nozzleBlastDuration = 60f; // Optional - Probably not a good idea. } else { snow_machine.FinishFogging(); snow_machine.SetFlag(BaseEntity.Flags.On, newbool); } snow_machine.SendNetworkUpdateImmediate(); } } } } if (CleanName == "all" || strobelight_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(strobelight_name, force, state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); StrobeLight[] strobelights = BaseNetworkable.serverEntities.OfType().ToArray() as StrobeLight[]; foreach (StrobeLight strobelight in strobelights) { if (strobelight == null || strobelight.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) strobelight)) continue; if (strobelight.IsOn() != newbool) { strobelight.SetFlag(BaseEntity.Flags.On, newbool); strobelight.burnRate = 0.0f; strobelight.SendNetworkUpdateImmediate(); } } } } if (CleanName == "all" || spookyspeaker_name.Contains(CleanName)) { sbyte newstate = NewStateShortPrefabName(spookyspeaker_name,force,state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); SpookySpeaker[] spookyspeakers = BaseNetworkable.serverEntities.OfType().ToArray() as SpookySpeaker[]; foreach (SpookySpeaker spookyspeaker in spookyspeakers) { if (spookyspeaker == null || spookyspeaker.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) spookyspeaker)) continue; spookyspeaker.SetFlag(BaseEntity.Flags.On, newbool); if (newbool == true) { spookyspeaker.SendPlaySound(); } spookyspeaker.SendNetworkUpdateImmediate(); } } } if (CleanName == "all" || mining_quarry_name.Contains(CleanName) || mining_quarry_static_name.Contains(CleanName) || mining_pumpjack_name.Contains(CleanName) || mining_pumpjack_static_name.Contains(CleanName)) { sbyte newstatemq = NewStateShortPrefabName(mining_quarry_name,force,state); // check what state is required based on time of day and config sbyte newstatepj = NewStateShortPrefabName(mining_pumpjack_name,force,state); // check what state is required based on time of day and config if (newstatemq >= 0 || newstatepj >= 0) // it is not set to be ignored { bool newboolmq = SbyteToBool(newstatemq); bool newboolpj = SbyteToBool(newstatepj); bool newbool = false; //if (newboolmq) Puts("newstatemq"); //if (newboolpj) Puts("newstatepj"); MiningQuarry[] miningquarries = BaseNetworkable.serverEntities.OfType().ToArray() as MiningQuarry[]; foreach (MiningQuarry mq in miningquarries) { //if (mq.isStatic) Puts(mq.ShortPrefabName + " Static"); else Puts(mq.ShortPrefabName + " not static"); if (mq == null || mq.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) mq)) continue; BaseEntity mqbe = mq as BaseEntity; if (!config.AlterUnowned && (mq.isStatic || mqbe.OwnerID == 0U || string.IsNullOrEmpty(mqbe.OwnerID.ToString()))) continue; BaseResourceExtractor pj = mq as BaseResourceExtractor; if (pj.canExtractLiquid) // Pumpjack { //Puts("PumpJack"); if (newstatepj < 0) continue; newbool = newboolpj; } else // mining quarry { //Puts("Mining Quarry"); if (newstatemq < 0) continue; newbool = newboolmq; } //mq.CancelInvoke(); //mq.SetOn(true); //BaseEntity hp = mq.hopperPrefab.instance as BaseEntity; //BaseEntity es = mq.engineSwitchPrefab.instance as BaseEntity; //hp.SetFlag(BaseEntity.Flags.On, newbool); //es.SetFlag(BaseEntity.Flags.On, newbool); mqbe.SetFlag(BaseEntity.Flags.On, newbool); //if (newbool) //mq.InvokeRepeating(() => mq.SetOn(true), 0, 10); mq.SendNetworkUpdateImmediate(); } } } if (CleanName == "all" || boombox_name.Contains(CleanName) && (force == true || config.BoomBoxOn == true )) { sbyte newstate = NewStateShortPrefabName(boombox_name,force,state); // check what state is required based on time of day and config if (newstate >= 0) // it is set to be ignored { bool newbool = SbyteToBool(newstate); // deployed boom boxes DeployableBoomBox[] boomboxes = BaseNetworkable.serverEntities.OfType().ToArray() as DeployableBoomBox[]; foreach (DeployableBoomBox boombox in boomboxes) { if (boombox == null || boombox.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) boombox)) continue; boombox.SetFlag(BaseEntity.Flags.On, newbool); } // Held boom boxes HeldBoomBox[] heldboomboxes = BaseNetworkable.serverEntities.OfType().ToArray() as HeldBoomBox[]; foreach (HeldBoomBox heldboombox in heldboomboxes) { if (heldboombox == null || heldboombox.IsDestroyed) continue; if (force == false && !EntityInZone((BaseEntity) heldboombox)) continue; heldboombox.SetFlag(BaseEntity.Flags.On, newbool); } } } } private object OnFindBurnable(BaseOven oven) { if (oven == null || string.IsNullOrEmpty(oven.ShortPrefabName)) return null; if (!config.AlterUnowned && (oven.OwnerID == 0U || string.IsNullOrEmpty(oven.OwnerID.ToString()))) return null; if (!IsLightPrefabName(oven.ShortPrefabName)) return null; if (!EntityInZone((BaseEntity) oven)) return null; if ((ProtectShortPrefabName(oven.ShortPrefabName) && oven.inventory.itemList.Count() > 0) || (config.KeepRunningIfFuel && oven.inventory.itemList.Count() > 1)) return null; // protect if there is anything in it (do not change states) sbyte newstate = NewStateShortPrefabName(oven.ShortPrefabName,false,false); // check what state is required based on time of day and config if (newstate < 0) return null; // it is set to be ignored bool newbool = SbyteToBool(newstate); if (newbool == true) { //Puts("OnFindBurnable: " + oven.ShortPrefabName + " : " + oven.cookingTemperature); // debug oven.StopCooking(); oven.allowByproductCreation = false; oven.SetFlag(BaseEntity.Flags.On, true); if (oven.fuelType != null) return ItemManager.CreateByItemID(oven.fuelType.itemid); } // catch all return null; } // for jack o laterns private void OnFuelConsume(BaseOven oven, Item fuel, ItemModBurnable burnable) { if (oven == null || string.IsNullOrEmpty(oven.ShortPrefabName)) return; if (!config.AlterUnowned && (oven.OwnerID == 0U || string.IsNullOrEmpty(oven.OwnerID.ToString()))) return; if (!IsLightPrefabName(oven.ShortPrefabName)) return; if (!EntityInZone((BaseEntity) oven)) return; //Puts("oven.ShortPrefabName: " + oven.ShortPrefabName); sbyte newstate = NewStateShortPrefabName(oven.ShortPrefabName,false,false); // check what state is required based on time of day and config if (newstate < 0) return; // it is set to be ignored bool newbool = SbyteToBool(newstate); if (newbool == true) { fuel.amount += 1; oven.StopCooking(); oven.allowByproductCreation = false; oven.SetFlag(BaseEntity.Flags.On, true); oven.SendNetworkUpdateImmediate(); } // catch all return; } // for hats private void OnItemUse(Item item, int amount) { if (config.Hats == "i") return; string ShortPrefabName = item?.parent?.parent?.info?.shortname ?? item?.GetRootContainer()?.entityOwner?.ShortPrefabName; BasePlayer player = null; if (string.IsNullOrEmpty(ShortPrefabName) || !IsHatPrefabName(ShortPrefabName)) return; //if (!EntityInZone((BaseEntity) item.BaseEntity)) return; sbyte newstate = NewStateShortPrefabName(ShortPrefabName,false,false); // check what state is required based on time of day and config if (newstate != 1) return; // it is set to be ignored or off try { player = item?.GetRootContainer()?.playerOwner; } catch { player = null; } if (player == null && string.IsNullOrEmpty(player.UserIDString)) { return; // no owner so no permission } item.amount += amount; return; } private object OnOvenToggle(BaseOven oven, BasePlayer player) { //CheckNight(); string cleanname = null; if (oven == null || string.IsNullOrEmpty(oven.ShortPrefabName) || (!config.AlterUnowned && (oven.OwnerID == 0U || string.IsNullOrEmpty(oven.OwnerID.ToString()))) ) return null; cleanname = CleanedName(oven?.ShortPrefabName); //Puts(oven.ShortPrefabName + " : " + cleanname + " : " + oven.IsOn() + " : " + oven.inventory.itemList.Count.ToString()); // debug // if there is stuff in the oven process it if (oven.inventory.itemList.Count == 0) // we only allow toggle on empty items { // pretty lights //if (IsLightToggle(cleanname)) Puts("Light"); //if (config.PlayerToggleAll) Puts("ToggleAll"); if (!IsLightToggle(cleanname) && !config.PlayerToggleAll) return null; // either it has to be a light or the toggle all has to be on //oven.StopCooking(); //oven.allowByproductCreation = false; if (!EntityInZone((BaseEntity) oven)) return null; //if ((ProtectShortPrefabName(oven.ShortPrefabName) && oven.inventory.itemList.Count() > 0) || (config.KeepRunningIfFuel && oven.inventory.itemList.Count() > 1)) return null; // protect if there is anything in it (do not change states) //sbyte newstate = NewStateShortPrefabName(cleanname,false,false); // check what state is required based on time of day and config //Puts("newstate: " + newstate.ToString()); //if (newstate < 1) return null; // it is set to be ignored or off //bool newbool = SbyteToBool(newstate); //if (newbool == false) return null; if (oven.IsOn()) { oven.StopCooking(); oven.SetFlag(BaseEntity.Flags.On, false); } else oven.SetFlag(BaseEntity.Flags.On, true); oven.SendNetworkUpdateImmediate(); } else { //Puts("Cooking time!"); if (config.FurnaceInstaCook) OvenCook(oven, player); else return null; } return null; } private object OvenCook(BaseOven oven, BasePlayer player) { //Puts(oven?.ShortPrefabName + " : " + oven.IsOn() + " : " + oven.inventory.itemList.Count.ToString()); // debug //if (oven.IsOn()) return null; Item Fuel = oven.FindBurnable(); //if (Fuel != null) Puts("Fuel: " + Fuel.amount.ToString()); //if (config.FurnaceNoFuelRequired) Puts("config.FurnaceNoFuelRequired"); if (!config.FurnaceNoFuelRequired && Fuel == null) return null; float FuelAmount = 0f; float Ratio = 1f; if (Fuel != null) { Ratio = (200f * Fuel.fuel) / oven.cookingTemperature; FuelAmount = Fuel.amount; Fuel.Remove(0f); ItemModBurnable Burnable = Fuel.info.GetComponent(); if (Burnable == null) return null; if (oven.allowByproductCreation && Burnable.byproductItem != null) { Item ByProduct = ItemManager.Create(Burnable.byproductItem, (int)(((1f - Burnable.byproductChance) * Burnable.byproductAmount * FuelAmount) + 0.5f), 0UL); if (ByProduct != null) { if (!ByProduct.MoveToContainer(Fuel.parent, Fuel.position, true, true)) if (!ByProduct.MoveToContainer(Fuel.parent, -1, true, true)) ByProduct.Drop(Fuel.parent.dropPosition, Fuel.parent.dropVelocity, default(Quaternion)); } } } for (int i = 0; i < oven.inventory.itemList.Count; i++) { Item Resource = oven.inventory.itemList[i]; if (!config.FurnaceNoFuelRequired && FuelAmount <= 0f) break; ItemModCookable Cookable = Resource.info.GetComponent(); if (Cookable == null || Cookable.becomeOnCooked == null || Cookable.becomeOnCooked.shortname.Contains("burn") || Cookable.becomeOnCooked.shortname.Contains("charcoal")) continue; if (!config.FurnaceCookAnything && (oven.cookingTemperature < (float)Cookable.lowTemp || oven.cookingTemperature > (float)Cookable.highTemp)) continue; int Amount = Resource.amount; if (!config.FurnaceNoFuelRequired) { float FuelNeeded = Amount * (1 / Ratio); if (FuelNeeded <= FuelAmount) { FuelAmount -= FuelNeeded; Resource.Remove(0f); } else { Amount = (int)(((FuelAmount * Ratio) / 1) + 0.5f); Resource.amount -= Amount; FuelAmount = 0f; } } else { Resource.amount = 0; Resource.Remove(0f); } Item Product = ItemManager.Create(Cookable.becomeOnCooked, (int)((Cookable.amountOfBecome * Amount) + 0.5f), 0UL); if (Product == null) continue; if (!Product.MoveToContainer(Resource.parent, Resource.position, true, true)) { if (!Product.MoveToContainer(Resource.parent, -1, true, true)) Product.Drop(Resource.parent.dropPosition, Resource.parent.dropVelocity, default(Quaternion)); } } return null; } private void ChangePower() { IOEntity[] ioEntities = BaseNetworkable.serverEntities.OfType().ToArray() as IOEntity[]; string io_name = " "; foreach (IOEntity ioEntity in ioEntities) { if (ioEntity == null || ioEntity.IsDestroyed || string.IsNullOrEmpty(ioEntity.ShortPrefabName) || !IsElectrical(ioEntity)) continue; if (!EntityInZone((BaseEntity) ioEntity)) continue; io_name = CleanedName(ioEntity.ShortPrefabName); //Puts(io_name); // debug sbyte newstate = NewStateShortPrefabName(io_name, false, false); // check what state is required based on time of day and config if (newstate < 0) continue; // it is set to be ignored bool newbool = SbyteToBool(newstate); int poweramt = 0; try { poweramt = Math.Max(IOPowerAmt[io_name],1); } catch { Puts("Change Power errored: " + io_name + " : " + poweramt.ToString()); // debug } if (poweramt <= 0) { Puts("Change Power failed: " + io_name + " : " + poweramt.ToString()); // debug } else { if (!newbool) poweramt = 0; PowerIOEntity(ioEntity, poweramt); } } } void ProcessNewEntity(BaseEntity entity) { if (entity == null || entity.IsDestroyed) return; string prefabName = CleanedName(entity.ShortPrefabName); Puts("PNE prefabName: " + prefabName); // debug if(string.IsNullOrEmpty(prefabName) || (IsOvenPrefabName(prefabName) == false && IsDevicePrefabName(prefabName) == false && IsElectricPrefabName(prefabName) == false)) return; //else Puts("PNE Processing: " + prefabName + " : " + NewStateShortPrefabName(prefabName,false,false).ToString()); // debug if (NewStateShortPrefabName(prefabName,false,false) < 1) return; // it is set to be ignored or off entity.SetFlag(BaseEntity.Flags.On, true); int poweramt = 0; if (entity is BaseOven) { BaseOven bo = entity as BaseOven; bo.SetFlag(BaseEntity.Flags.On, true); bo.SendNetworkUpdateImmediate(); } else if (entity is Candle) { Candle candle = entity as Candle; candle.lifeTimeSeconds = 999999f; candle.burnRate = 0.0f; candle.SetFlag(BaseEntity.Flags.On, true); candle.SendNetworkUpdateImmediate(); } else if (entity is MixingTable) { MixingTable mt = entity as MixingTable; mt.RemainingMixTime = 999999f; mt.TotalMixTime = 999999f; mt.SetFlag(BaseEntity.Flags.On, true); mt.SendNetworkUpdateImmediate(); } else if (entity is SnowMachine) { SnowMachine sm = entity as SnowMachine; Item newItem = ItemManager.Create(fuel, 1); newItem.MoveToContainer(sm.inventory); sm.fuelPerSec = 0f; sm.CancelInvoke(new Action(sm.CheckTrigger)); sm.SetFlag(BaseEntity.Flags.On, true, true, true); //sm.EnableFogField(); sm.InvokeRepeating(new Action(sm.StartFogging), 0, 60); //fm.nozzleBlastDuration = 60f; // Optional - Probably not a good idea. } else if (entity is FogMachine) { FogMachine fm = entity as FogMachine; fm.fuelPerSec = 0f; fm.CancelInvoke(new Action(fm.CheckTrigger)); fm.SetFlag(BaseEntity.Flags.On, true, true, true); fm.EnableFogField(); fm.InvokeRepeating(new Action(fm.StartFogging), 0, 60); } else if (entity is StrobeLight) { StrobeLight sl = entity as StrobeLight; sl.burnRate = 0.0f; sl.SetFlag(BaseEntity.Flags.On, true); sl.SendNetworkUpdateImmediate(); } else if (entity is SpookySpeaker) { SpookySpeaker ss = entity as SpookySpeaker; ss.SetFlag(BaseEntity.Flags.On, true); ss.SendPlaySound(); } else if (entity is MiningQuarry) { MiningQuarry mq = entity as MiningQuarry; entity.SetFlag(BaseEntity.Flags.On, true); } else if (entity is IOEntity && !(entity is SnowMachine)) { IOEntity IOE = entity as IOEntity; try { poweramt = Math.Max(IOPowerAmt[prefabName],1); } catch { Puts("PNE: " + prefabName + " : " + poweramt.ToString()); // debug } PowerIOEntity(IOE, poweramt); } //else // Puts("Process New Entity, unhandled entity, tell MalS: " + prefabName); debug } object CanMoveItem(Item item, PlayerInventory playerLoot, uint targetContainer, int targetSlot, int amount) { // if it is cookable, allow it to be put in if we are doing instacook if (config.FurnaceInstaCook == false) return null; ItemContainer container = playerLoot.FindContainer(targetContainer); if (container == null) return null; BaseOven targetOven = container?.entityOwner?.GetComponent(); if (targetOven == null || item == null) return false; string CleanName = CleanedName(targetOven.PrefabName); if (!IsOvenPrefabName(CleanName)) return null; Puts("A"); if (!item.info.GetComponent()) return null; Puts("B"); return ItemContainer.CanAcceptResult.CanAccept; } // not needed //object CanAcceptItem(ItemContainer container, Item item, int targetPos) //{ // // if it is cookable, allow it to be put in if we are doing instacook // if (config.FurnaceInstaCook == false) return null; // BaseEntity centity = container.entityOwner; // if (centity == null || centity.IsDestroyed) return null; // if (IsOvenPrefabName(CleanedName(centity.ShortPrefabName)) == false) return null; // Puts("1"); // if (!item.info.GetComponent()) return null; // Puts("2"); // return ItemContainer.CanAcceptResult.CanAccept; //} private void OnEntityBuilt(Planner plan, GameObject go) { BaseEntity goEntity = go.ToBaseEntity(); if (goEntity == null || goEntity.IsDestroyed || goEntity.OwnerID == null || !goEntity.OwnerID.IsSteamId()) return; //Puts("OnEntityBuilt: " + goEntity.ToString()); // debug try { BasePlayer player = BasePlayer.activePlayerList.Where(x=>x.userID == goEntity.OwnerID).First(); // .FirstOrDefault(); // I don't think we want default in this case if(player != null && !PlayerInZone(player)) return; // it is in a valid zone } catch {} ProcessNewEntity(goEntity); } private void OnEntitySpawned(BaseNetworkable bnentity) { BaseEntity entity = (BaseEntity) bnentity; if (entity == null || entity.IsDestroyed || entity.OwnerID == null || !entity.OwnerID.IsSteamId()) return; //Puts("OnEntitySpawn: " + entity.ToString()); // debug try { BasePlayer player = BasePlayer.activePlayerList.Where(x=>x.userID == entity.OwnerID).First(); // .FirstOrDefault(); // I don't think we want default in this case if(player != null && !PlayerInZone(player)) return; // it is in a valid zone } catch {} ProcessNewEntity(entity); } private void CheckNight() { // track when we cross the night boundary var gtime = TOD_Sky.Instance.Cycle.Hour; if ((nightcross24 == false && gtime >= config.DuskTime && gtime < config.DawnTime) || (nightcross24 && ((gtime >= config.DuskTime && gtime < 24) || gtime < config.DawnTime))) { NightToggleactive = true; } else if ((nightcross24 == false && gtime >= config.DawnTime) || (nightcross24 && (gtime < config.DuskTime && gtime >= config.DawnTime))) { NightToggleactive = false; } } private void TimerProcess() { //var startHour = TOD_Sky.Instance.Cycle.Hour; // debug //Puts("Processing lights from timer"); // debug // added this in case the time was manually changed CheckNight(); ProcessEntities("all",false,false); //var endHour = TOD_Sky.Instance.Cycle.Hour; // debug //var duration = 3600*(endHour - startHour); // debug //Puts("It took : " + duration.ToString()); // debug // submit for the next pass Sweeptimer = timer.Once(config.CheckFrequency, TimerProcess); } [Command("lights")] private void ChatCommandlo(IPlayer player, string cmd, string[] args) { if (!permission.UserHasPermission(player.Id, perm_lightson)) { player.Message(String.Concat(Lang("prefix", player.Id), Lang("nopermission", player.Id))); return; } else if (args == null || args.Length < 1) { player.Message(String.Concat(Lang("prefix", player.Id), Lang("syntax", player.Id))); return; } LoadConfig(); // load config in case there was a change the operator wants picked up bool state = false; bool force = true; string statestring = null; string prefabName = null; string forcestring = " "; // set the parameters statestring = args[0].ToLower(); // make sure we have something to process default to all on if (string.IsNullOrEmpty(statestring)) state = true; else if (statestring == "off" || statestring == "false" || statestring == "0" || statestring == "out") state = false; else if (statestring == "on" || statestring == "true" || statestring == "1" || statestring == "go") state = true; else if (statestring == "check") force = false; else { player.Message(String.Concat(Lang("prefix", player.Id), Lang("state", player.Id)) + " " + statestring); return; } // see if there is a prefabname specified and if so that it is valid if (args.Length > 1) { prefabName = CleanedName(args[1]); // Puts(prefabName); if(string.IsNullOrEmpty(prefabName)) prefabName = "all"; else if (prefabName != "all" && !IsOvenPrefabName(prefabName) && !IsElectricPrefabName(prefabName) && !IsDevicePrefabName(prefabName) ) { player.Message(String.Concat(Lang("prefix") , Lang("bad prefab", player.Id))+ " " + prefabName); return; } } else prefabName = "all"; //var startHour = TOD_Sky.Instance.Cycle.Hour; // debug //Puts("Processing lights from command"); // debug // added this in case the time was manually changed CheckNight(); ProcessEntities(prefabName, force, state); //var endHour = TOD_Sky.Instance.Cycle.Hour; // debug //var duration = 3600*(endHour - startHour); // debug //Puts("It took : " + duration.ToString()); // debug if (force) { if (state == true) player.Message(String.Concat(String.Concat(Lang("prefix") , Lang("lights on", player.Id)) , " " + prefabName + " " + forcestring)); else player.Message(String.Concat(String.Concat(Lang("prefix") , Lang("lights off", player.Id)) , " " + prefabName + " " + forcestring)); } else player.Message(String.Concat(String.Concat(Lang("prefix") , Lang("lights check", player.Id)) , " " + prefabName)); } } }