diff --git a/.gitignore b/.gitignore
index 50f9ec9..4dbc2d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -329,3 +329,4 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+/SRMP/_info.txt
diff --git a/Libs/Assembly-CSharp_publicized.dll b/Libs/Assembly-CSharp_publicized.dll
new file mode 100644
index 0000000..8486c97
Binary files /dev/null and b/Libs/Assembly-CSharp_publicized.dll differ
diff --git a/Libs/Newtonsoft.Json.dll b/Libs/Newtonsoft.Json.dll
new file mode 100644
index 0000000..4881a56
Binary files /dev/null and b/Libs/Newtonsoft.Json.dll differ
diff --git a/Libs/SRML.Editor.dll b/Libs/SRML.Editor.dll
new file mode 100644
index 0000000..ceca19f
Binary files /dev/null and b/Libs/SRML.Editor.dll differ
diff --git a/Libs/SRML.dll b/Libs/SRML.dll
new file mode 100644
index 0000000..7efefd3
Binary files /dev/null and b/Libs/SRML.dll differ
diff --git a/Libs/SRML.xml b/Libs/SRML.xml
new file mode 100644
index 0000000..6382d6c
--- /dev/null
+++ b/Libs/SRML.xml
@@ -0,0 +1,3810 @@
+
+
+
+ SRML
+
+
+
+
+ A command to add a user defined button to the command menu
+
+
+
+
+ A command to clear the console
+
+
+
+
+ A command that dumps stuff to dump files
+
+
+
+
+ A command to edit a user defined button
+
+
+
+
+ A command to display all commands
+
+
+
+
+ A command to display all mods
+
+
+
+
+ A command to reload the mods
+
+
+
+
+ A command to remove a user defined button from the command menu
+
+
+
+
+ Controls the in-game console
+
+
+
+
+ The event that triggers when the Reload Command is called
+
+
+
+
+ Initializes the console
+
+
+
+
+ Registers a new command into the console
+
+ Command to register
+ True if registered succesfully, false otherwise
+
+
+
+ Registers a new console button
+
+ The id of the button
+ Button to register
+ True if registered succesfully, false otherwise
+
+
+
+ Registers a new dump action for the dump command
+
+ The id to use for the dump command argument
+ The dump action to run
+ True if registered succesfully, false otherwise
+
+
+
+ Registers a command catcher which allows commands to be processed and their execution controlled by outside methods
+
+ The method to catch the commands
+
+
+
+ Logs a info message
+
+ Message to log
+ Should log to file?
+
+
+
+ Logs a success message
+
+ Message to log
+ Should log to file?
+
+
+
+ Logs a warning message
+
+ Message to log
+ Should log to file?
+
+
+
+ Logs an error message
+
+ Message to log
+ Should log to file?
+
+
+
+ Binds user commands to the console command menu
+
+
+
+
+ Reads all bindings
+
+
+
+
+ Registers a new bind
+
+ The id of the button
+ The text to show on the button
+ The command to execute
+
+
+
+ Removes a bind
+
+ The id of the bind to remove
+ True if the bind got removed, false otherwise
+
+
+
+ Removes all binds
+
+
+
+
+ Gets all the binds registered
+
+
+
+
+ A button for the console menu
+
+
+
+
+ Text to display on the button
+
+
+
+
+ Command to execute when the button is pressed
+
+
+
+
+ Creates a new console button button
+
+ Text to display on the button
+ Command to execute when the button is pressed
+
+
+
+ Base class for all console commands
+
+
+
+
+ The ID of this command (Always lowercase)
+
+
+
+
+ The usage info of this command
+
+
+
+
+ The description of this command
+
+
+
+
+ The extended description of this command, with a description of each argument to
+ display when you use help command on this command (Multiline is supported)
+
+
+
+
+ Executes the command
+
+ The arguments passed in the console (null if no arguments are provided)
+ True if it executed, false otherwise
+
+
+
+ Gets the auto complete list (word filter is done by the system)
+
+ The index of the argument in the command string
+ The text of the argument
+ The list of auto complete options
+
+
+
+ Gets the auto complete list (word filter is done by the system)
+
+ The index of the argument in the command string
+ A list of inputted arguments
+ The list of auto complete options
+
+
+
+ The arguments are out of bounds (either too many or too little)
+
+ Amount of arguments
+ Minimun amount
+ Maximun amount
+ True if arguments are out of bounds, false otherwise
+
+
+
+ Draws the window for the in-game console
+
+
+
+
+ Attachs the window to a scene
+
+
+
+
+ The logger for the log file
+
+
+
+
+ Initializes the file logger (run this before Console.Init)
+
+
+
+
+ Logs a info message
+
+ Message to log
+
+
+
+ Logs a warning message
+
+ Message to log
+
+
+
+ Logs an error message
+
+ Message to log
+
+
+
+ Allows adding values to any Enum
+
+
+
+
+ Add a new enum value to the given with the first free value
+
+ Type of enum to add the value to
+ Name of the new enum value
+ The new enum value
+
+
+
+ Add a new enum value to the given with the first free value
+
+ Type of enum to add the value to
+ Name of the new enum value
+ The new enum value
+
+
+
+ Add a new value to the given
+
+ Enum to add the new value to
+ Value to add to the enum
+ The name of the new value
+
+
+
+ Add a new value to the given
+
+ Enum to add the new value to
+ Value to add to the enum
+ The name of the new value
+
+
+
+ Get first undefined value in an enum
+
+
+ The first undefined enum value
+
+
+
+ Get first undefined value in an enum
+
+
+ The first undefined enum value
+
+
+
+ Serializable table that maps enum values from placeholder numerical values to their string counterparts
+ Used to assure that enum values map properly between game loads, even if registration order changes
+ Mapped values are always negative
+
+
+
+
+ Get the next free value for the given enumType
+
+ The enum type
+ The next free value
+
+
+
+ Generate a translation table for a list of enumValues
+
+ List of enum values to translate
+
+
+
+ Replace missing enum values with default values, or remove them all together
+
+
+
+
+ Translate an enum value
+
+ Original enum value
+ Translated integer
+
+
+
+ Register an EnumFixer that allows for objects of type to have their enum values processed by an enumtranslator
+
+
+
+
+
+
+ Fix enum values in an object using the registered EnumFixer
+
+ the to use for translating
+ Whether to translate TO or FROM the translated form
+ Object to fix
+
+
+
+ Class used to generate an error message
+
+
+
+
+ Checks if a path exists and creates it if it doesn't
+
+ Path to be checked
+ returns the original path argument
+
+
+
+ When called from a mod, gets the base path of that mod
+
+ The base path of the current executing mod
+
+
+
+ Gets a mods config path
+
+ The mod whose config path is needed
+ The config path
+
+
+
+ Gets the current mods config path
+
+ The config path
+
+
+
+ Utility class to help manage the main SRML harmony instance
+
+
+
+
+ Utilities for communication between mods
+
+
+
+
+ Called before GameContext.Awake()
+
+
+
+
+ Called before GameContext.Start()
+
+
+
+
+ Called after Load
+
+
+
+
+ Called before
+ Used to register things such as enum values, and to do Harmony patching
+
+
+
+
+ Called before
+ Used to register things that require a loaded GameContext
+
+
+
+
+ Called after every mod's Load has finished (not a registry step)
+ Used for editing existing assets in the game
+
+
+
+
+ Register a modded achievement into the registry.
+
+ The id of the achievement to register.
+ The tracker to track achievement progress.
+ The tier the achievement goes into.
+
+
+
+ Register an achievement tier into the registry.
+
+ The id of the tier.
+ The icon to be displayed in the achievement UI.
+
+
+
+ Check if an achievement is modded.
+
+ The id of the achievement to check.
+ True if achievement id belongs to a modded achievement, otherwise false.
+
+
+
+ Tiers for an achievement to be put into.
+
+
+
+
+ Register an ammo prefab to allow it to be put in a player's ammos (use )
+
+ to register the prefab to
+
+
+
+
+ Allow an to be put into a players inventory
+
+ Which inventory to allow the into
+ The to allow
+
+
+
+ Allow an Identifiable.Id to be put into a inventory
+
+
+
+
+
+
+ Allow an Identifiable to be put into the Refinery
+
+
+
+
+
+ Creates a and registers it into the enum
+
+
+
+
+
+
+
+
+ Creates a and registers it into the enum
+
+
+
+
+
+
+
+
+ Registers a
+
+
+
+
+
+ See if a is modded
+
+
+ True if given is from a mod
+
+
+
+ See if a is modded
+
+
+ True if given is from a mod
+
+
+
+ Registers an offset for a fashion.
+
+ The of the fashion to offset.
+ How far the fashion gets offset.
+ The condition that the fashion gets offset in.
+
+
+
+ Registers a slot for a fashion to be placed in.
+
+ The that belongs to the slot.
+ The hierarchal path to the bone.
+ The that the slot attaches to.
+
+
+
+ Adds an to a .
+
+ The to add to.
+ The to be added.
+
+
+
+ Registers a range of s into a .
+
+ The to add to.
+ The s to be added.
+
+
+
+ Registers a range of s into a .
+
+ The to add to.
+ The s to be added.
+
+
+
+ Registers a range of s into a .
+
+ The s to be added.
+
+
+
+ Registers a range of s into a .
+
+ The s to be added.
+
+
+
+ Removes an from a .
+
+ The to be removed from.
+ The to be removed.
+
+
+
+ Removes an from a .
+
+ The to be removed.
+ The to be removed from.
+
+
+
+ Adds an to a .
+
+ The to be added.
+ The to add to.
+
+
+
+ Automatically adds an to a .
+
+ The to be added.
+
+
+
+ Registers a rule for what to register a into.
+
+ The condition that the is registered into the
+ The to register an into.
+
+
+
+ Adds a rank into the 7Zee Rewards catalogue. If the rank already exists, then combine with the pre-existing one.
+
+ The level of the rank.
+ How much it costs to purchase the rank.
+ The rewards for the rank.
+ The banner to show behind the rank name. If null, then it will set to the highest rank's banner.
+
+
+
+ Adds a reward to a rank.
+
+ The rank to add a reward to.
+ The to add.
+
+
+
+ A special way to register rewards with a unique translation key.
+
+
+
+
+ Registers a region into the .
+
+ The of the region.
+ The bounds and values of the region.
+
+
+
+ Adds a zone into a region.
+
+ The to be added.
+ The of the region to add to.
+
+
+
+ Class for handling string ID's for the save system
+
+
+
+
+ Class allowing for the addition of arbitrary data to Actors, similar to Minecraft's NBT system
+
+
+
+
+ Instantiate an an Actor with the given data
+
+
+
+
+
+
+
+
+
+
+ A participant of the data system
+
+
+
+
+ A participant of the data system. When on a slime, if the slime transforms, it will copy to the resulting object.
+
+
+
+
+ Register a serializable
+
+ The actor model to register
+ The mod specific integer ID that the save system will use to refer to this
+
+
+
+ Register a serializable
+
+ Gadget model to register
+ The mod specific integer ID that the save system will use to refer to this
+
+
+
+ Register a serializable
+
+ LandPlot model to register
+ The mod specific integer ID that the save system will use to refer to this
+
+
+
+ Register a that will take part in the extended data system
+
+ Type of the participant to register
+
+
+
+ Allows an to go onto a gordo snare.
+
+ The to register.
+
+
+ if secret styles is installed, otherwise .
+
+
+
+ Register a secret style in a
+
+ Slime definition to register the secret style for
+ Secret style to register
+
+
+
+ Registers a targeter.
+
+ The condition in which the targeter is used.
+ A function getting the name of the targeted object, with the first bundle being the UI bundle, and the second being the pedia bundle.
+ A function getting the description of the targeted object, with the first bundle being the UI bundle, and the second being the pedia bundle.
+
+
+
+ Combines two keys' resulting translations.
+
+ The bundle containing the keys.
+ The key to be added to.
+ The key to be added.
+ The composed description.
+
+
+
+ Composes a type description translation.
+
+ The bundle containing the type key.
+ The key belonging to the type's translation.
+
+
+
+
+ Composes a diet description translation.
+
+ The bundle containing the diet key.
+ The key belonging to the diet's translation.
+
+
+
+ Create a new instance of an IdHandler
+
+
+
+
+
+
+
+ Register an as a drone target.
+
+
+
+
+
+ Registers a rancher.
+
+
+
+
+
+ Registers a rancher's id
+
+
+
+
+
+ Registers an offer id
+
+
+
+
+
+ Registers a category for exchange requests/rewards
+
+ The category to register
+ The ids in the category
+
+
+
+ Registers an item to be unlocked in a category
+
+ The to be unlocked.
+ The progress required to unlock it
+ The value used in the offer generator for count
+
+
+
+ Registers an item that's automatically unlocked in a category
+
+ The to be unlocked.
+ The value used in the offer generator for count
+
+
+
+ Checks if a rancher or offer ID is modded.
+
+ The ID to check.
+ True if the ID belongs to a mod, otherwise false.
+
+
+
+ Checks if a rancher is modded.
+
+ The rancher to check.
+ True if the rancher belongs to a mod, otherwise false.
+
+
+
+ Checks if a category is modded.
+
+ The category to check.
+ True if the category belongs to a mod, otherwise false.
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Check if a belongs to a modded gadget.
+
+ The to check.
+ True if belongs to a modded gadget, otherwise false.
+
+
+
+ Associates an with a
+
+ The to associate.
+ The to associate
+
+
+
+ Registers a locker for a blueprint.
+
+ The of the blueprint.
+ The locker for the blueprint.
+
+
+
+ Register a blueprint.
+
+ The of the blueprint.
+
+
+
+ Register a blueprint that's automatically available.
+
+ The of the blueprint.
+
+
+
+ Manually set the of the
+
+
+
+
+
+
+ Remove all instances of an from every class in
+
+
+
+
+
+ Puts a into one of the vanilla categories based on its name prefix (see )
+ WARNING: Will not categorize decorations properly!
+
+
+
+
+
+ Put an into one of the vanilla categories
+
+
+
+
+
+
+ Creates an .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Creates an .
+
+ What value is assigned to the .
+ The name of the .
+ If the should automatically be categorized into 's classes.
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Manually set the of the
+
+
+
+
+
+
+ Remove all instances of an from every class in
+
+
+
+
+
+
+ Check if an was registered by a mod
+
+
+ True if the was registered by a mod, otherwise false.
+
+
+
+ Gets every registered by a mod.
+
+ The ID of the mod to check.
+ All s reigstered by a mod.
+
+
+
+ Registers a rule for an id prefix to link to
+
+ The prefix for the id to check for.
+ The rule that the specified prefix links to.
+
+
+
+ Registers a rule for an id suffix to link to
+
+ The suffix for the id to check for.
+ The rule that the specified prefix links to.
+
+
+
+ Puts an into one of the vanilla categories based on its name (see )
+
+
+
+
+
+ Put an into one of the vanilla categories
+
+
+
+
+
+
+ Register a keybind into the options UI.
+
+ The action associated with the keybind.
+
+
+
+ Creates and registers a .
+
+ The name of the action.
+ The created action
+
+
+
+ Creates and registers a , then registers it into the options UI.
+
+ The name of the action.
+ The created action
+
+
+
+ Creates and registers a , adds it into the options UI, and adds a translation.
+
+ The name of the action.
+ The translated name of the action.
+ The created action
+
+
+
+ Check if an action is modded.
+
+ The action to check.
+ True if action belongs to a mod, otherwise false.
+
+
+
+ Register all 's in a Type
+
+ Type holding the 's
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Check if an was registered by a mod
+
+
+ True if the was registered by a mod, otherwise false.
+
+
+
+ Registers a land plot.
+
+ The land plot to register.
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Registers an land plot upgrade.
+
+ The type of land plot to register it to.
+ The upgrade to register.
+
+
+
+ Registers a to a land plot.
+
+ The to register.
+ The to register the to
+ Throws if the is already registered.
+
+
+
+ Sets the callback of the .
+
+ The callback
+
+
+
+
+ Sets the from translation.
+
+ The translated text.
+
+
+
+
+ Sets the body translation.
+
+ The translated text.
+
+
+
+ Sets the subject translation.
+
+ The translated text.
+
+
+
+ Registers a .
+
+ The to register.
+ The registered
+
+
+
+ Registers a .
+
+ The key of the to register.
+ The registered
+
+
+
+ Gets the default renderer for a Slimepedia entry.
+
+ The setting to get the renderer from.
+ The default renderer for the specified setting.
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Registers a tab for the Slimepedia.
+
+ The tab to register
+
+
+
+ Registers a into the Slimepedia.
+
+ The to register.
+
+
+
+ Creates and registers a .
+
+ The belonging to the entry.
+ The icon belonging to the entry.
+
+
+
+ Registers an entry renderer for the Slimepedia.
+
+ The assigned to the entry.
+ The renderer the Slimepedia entry should use.
+
+
+
+ Registers an entry to already be unlocked in a new game
+
+ The that belongs to the entry.
+
+
+
+ Creates a link between an and a .
+
+ The entry mapping both values.
+
+
+
+ Creates a link between an and a .
+
+ The to link.
+ The to link.
+
+
+
+ Sorts a Slimepedia category based on a rule.
+
+ The Slimepedia category to sort.
+ The rules to sort it.
+
+
+
+ Assigns a to a Slimepedia category.
+
+ The to assign.
+ The Slimepedia category to assign the to.
+
+
+
+ Registers an event to be run when a awakes.
+
+ The event to be ran.
+
+
+
+ Registers a link between a plant plot and an .
+
+ The entry of the link.
+
+
+
+ Registers a link between a plant plot and an , which only is used if a condition is met.
+
+ The condition that the link is established.
+ The entry of the link.
+
+
+
+ Predicate for choosing purchasable ui's
+
+ The type of the Purchasable UI
+ The UI instance
+
+
+
+
+ Creates purchasables on demand
+
+ The that the will be added to
+
+
+
+
+ Creates a purchasable on demand
+
+
+ The UI that the will be added to
+
+
+
+
+ Delegate for arbitarily manipulating a list of purchasables
+
+
+
+
+
+
+
+ Delegate for arbitarily manipulating a list of purchasables
+
+
+
+
+ Register a to all UI's pointed to by the
+
+ The prediate for filtering the Purchasable UI
+ The creator of the new purchasable
+
+
+
+ Register a compararer to sort a list of purchasables
+
+ Filter for PurchasableUI's
+ Comparer to use when sorting
+
+
+
+ Register a compararer to sort a list of purchasables
+
+ The type of the UI
+ Comparer used for sorting
+
+
+
+ Registers a plort entry into the Plort Market.
+
+ The plort's market entry.
+
+
+
+ Creates and registers a plort entry into the Plort Market.
+
+ The belonging to the plort.
+ The progress required to show the plort as unlocked.
+
+
+
+ Creates and registers a plort entry into the Plort Market that is automatically unlocked.
+
+ The belonging to the plort.
+
+
+
+ Registers an economy entry into the Plort Market.
+
+ The entry to register.
+
+
+
+ Creates and registers an economy entry into the Plort Market.
+
+ The belonging to the plort.
+ The base value of the plort.
+ How many plorts needed to saturate the market (cut the price in half).
+
+
+
+ Creates and registers an economy entry into the Plort Market.
+
+ The belonging to the plort.
+ The base value of the plort.
+ How many plorts needed to saturate the market (cut the price in half).
+ Throws if ran in PreLoad.
+
+
+
+ Creates and registers a plort entry, as well as an economy entry into the Plort Market.
+
+ The belonging to the plort.
+ The base value of the plort.
+ How many plorts needed to saturate the market (cut the price in half).
+
+
+
+ Register an Identifiable Prefab into the
+
+ The prefab to register.
+
+
+
+ Register an Identifiable Prefab into the
+
+ The belonging to the prefab to register.
+
+
+
+ Register into the
+
+
+
+
+
+ Register a landplot prefab into the
+
+ The prefab to register
+
+
+
+ Register a gadget entry to the
+
+
+
+
+
+ Register a vacuumable item into the
+
+ Id of the vacuumable item
+ Color of the background of the inventory slot
+ Icon that will be used for the item in inventory
+
+
+
+ Register into the
+
+ Upgrade Entry to register
+
+
+
+ Create and register an upgrade entry
+
+ Upgrade ID
+ Icon that will show up in the upgrade shop
+ The cost of the upgrade
+
+
+
+ Register a into the
+
+
+
+
+
+ Register a gordo prefab into the
+
+
+
+
+
+ Register into the
+
+ Liquid to register
+
+
+
+ Register into the
+
+ Entry to register
+
+
+
+ Register a toy (note: does not register the identifiable itself, only the toy, do that separately)
+
+ of the toy
+ Icon for the toy in the toy store
+ How much the toy costs in the toy store
+
+
+
+
+ Register a slime definition in the database
+
+ Slime definition to register
+
+
+
+ Register a slime definition in the database
+
+ Slime definition to register
+ Whether or not to refresh the EatMaps of the slime and its bases.
+
+
+
+ Registers a .
+
+ The that the is assigned to.
+ The to be registered.
+
+
+
+ Combines two s into a largo .
+
+ The base .
+ The addon .
+ The to register the into.
+ The properties controlling the way the s are combined.
+ The stripe shader to be used, if any.
+ The created .
+
+
+
+ Creates a largo from two base s.
+
+ The belonging to the resulting largo.
+ The belonging to the base slime.
+ The belonging to the addon slime.
+ The properties controlling the way the s are combined.
+ The created .
+
+
+
+ Combines the s of the bases of a into one .
+
+ The largo's .
+ The created .
+
+
+
+ Combines two slimes into a largo.
+
+ The belonging to the resulting largo.
+ The belonging to the base slime.
+ The belonging to the addon slime.
+ The properties controlling the way the slimes are combined.
+ The properties controlling the base Secret Style and the addon normal s are combined.
+ The properties controlling the base normal and the addon Secret Style s are combined.
+ The properties controlling the base Secret Style and the addon Secret Style s are combined.
+
+
+
+ Combines two slimes into a largo.
+
+ The belonging to the resulting largo.
+ The belonging to the base slime.
+ The belonging to the addon slime.
+ The properties controlling the way the slimes are combined.
+ The properties controlling the base Secret Style and the addon normal s are combined.
+ The properties controlling the base normal and the addon Secret Style s are combined.
+ The properties controlling the base Secret Style and the addon Secret Style s are combined.
+ The of the created largo.
+ The of the created largo.
+ The of the created largo.
+
+
+
+ Takes an and formats it into a largo name.
+
+ The belonging to the largo.
+ The resulting name.
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Represents a template game object, used to contain templates to turn into
+ Runtime Prefabs
+
+
+
+
+ A template to create new animals
+
+
+
+
+ Template to create new animals
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this animal
+ The model's mesh for this animal
+ The materials that compose this animal's model
+ The animator used by the animal
+ Is this animal a child?
+
+
+
+ Sets the reproduction objects (not needed for childs or males)
+
+ The male mate of this female
+ The resulting child
+
+
+
+ Sets the elder version of this (not needed for childs)
+
+ The elder version
+
+
+
+ Sets the movement component to a new one (Default is the Chicken Movement)
+
+ New component to use
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the reproduction infos (not needed for childs or males)
+
+ Min. Reproduction hours
+ Max. Reproduction hours
+
+
+
+ Sets the bones and skinned mesh of this animal (default are the ones from the Chicken/Hen)
+ The skinned mesh would be an object like mesh_body1 of the Hen's Prefab
+ The bones would be an object like root of the Hen's Prefab
+
+ The new skinned mesh to use for the animal
+ The new bones to use for the animal
+
+
+
+ Sets the child info (only needed for childs)
+
+ The number of hours before becoming an adult
+ The number of hours before hatching the egg
+ The egg object
+
+
+
+ Sets the translation for this animal's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new Craft Resources
+
+
+
+
+ Template to create new Craft Resources
+
+ The name of the object (prefixes are recommend, but not needed)
+ The Identifiable ID for this resource
+ The pedia ID for this resource
+ The model's mesh for this resource
+ The materials that compose this resource's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the transform values for the model
+
+ New values to set
+
+
+
+ Sets the collider radius for this craft resource (Use this to ajust the collider to the model)
+
+ The radius of the collider
+
+
+
+ Sets the scale for the Delaunch Trigger (do not change if you don't know what you are doing)
+
+ The new scale to set
+
+
+
+ Sets the translation for this resource's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new crates
+
+
+
+
+ Template to create new crates
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this crate
+ The materials that compose this crate's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the spawn options for the crate
+
+ List of options
+
+
+
+ Sets the info for spawning items
+
+ The min amount of things to spawn
+ The max amount of things to spawn
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new fashion attachments (the part that gets attached to the object)
+
+
+
+
+ Template to create new fashion attachments
+
+ The name of the object (prefixes are recommend, but not needed)
+ The Identifiable ID for this fashion attachment
+ The model's mesh for this fashion attachment
+ The materials that compose this fashion attachment's model
+
+
+
+ Sets the transform values for the model
+
+ New values to set
+
+
+
+ Adds a new layer
+
+ The mesh to add to the layer
+ The materials to add to the layer
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new fashions (the actual fashion not the pod)
+
+
+
+
+ Template to create new fashions
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this fashion
+ The prefab to attach to the target
+ The icon for this fashion
+ The slot it occupied when attached
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the translation for this fashion's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create floating decorations like ornaments or echos
+
+
+
+
+ Template to create floating decorations
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this decoration
+ The type of decoration
+ The model's mesh for this decoration
+ The materials that compose this decoration's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the clip (For the type ECHO_NOTE)
+
+ The number of clip to set
+
+
+
+ Sets the transform values
+
+ New values to set
+
+
+
+ Sets the color for the material (For the type ECHO or ECHO_NOTE) (only if you want to use the default material for echos and change the color)
+
+ New color to set
+
+
+
+ Sets the translation for this deco's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new foods
+
+
+
+
+ Template to create new foods
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this food
+ The pedia ID for this resource
+ The type of food
+ The model's mesh for this food
+ The materials that compose this food's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the info of the resource cycle
+
+ The number of game hours before the food is ready to collect
+ The number of game hours the food stays in place to be riped
+ The number of game hours the food can be eaten
+ The number of game hours the food takes to rot
+
+
+
+ Sets the rotten material
+
+ The rotten material
+
+
+
+ Sets the Audio Cues for the food (Only needed for type CUSTOM)
+
+ The cue triggered when the food is released from a farmable zone
+ The cue triggered when the food hits something
+
+
+
+ Sets the scale for the Delaunch Trigger (do not change if you don't know what you are doing)
+
+ The new scale to set
+
+
+
+ Sets the scale for the model, only needed if the default doesn't work
+
+ The new scale to set
+
+
+
+ Sets the option to eject the food when mature (only needed if the food is farmable)
+
+ The new state to set
+
+
+
+ Sets the translation for this slime's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new gordos
+
+
+
+
+ Template to create new gordos
+
+ The name of the object (prefixes are recommend, but not needed)
+ The identifiable ID for this gordo
+ The definition of the slime this gordo is based on
+ The materials to use on the model of this gordo
+
+
+
+ Adds a new behaviour to the slime
+
+ The component containing the new behaviour
+
+
+
+ Adds a new behaviour to the slime
+
+ The component containing the new behaviour
+ A list of components containing the new behaviour
+
+
+
+ Sets a new bone structure for the slime (Starting at the Vibrating part)
+
+ The new bone structure as a game object (to add to the prefab)
+
+
+
+ Sets the translation for this gordo's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new liquids
+
+
+
+
+ Template to create new liquids
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this liquid
+ The materials that compose this liquid's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the color for the material (only if you want to use the default material for water and change the color)
+ DO NOT USE THIS IF YOU SET A CUSTOM MATERIAL, THIS WILL OVERRIDE THAT MATERIAL
+
+ New color to set
+
+
+
+ Sets the translation for this slime's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new plorts
+
+
+
+
+ Template to create new plorts
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this plort
+ The materials that compose this plort's model
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the translation for this plort's name
+
+ The translated name
+
+
+
+ Sets the scale for the plort
+
+ The scale to set
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new slimes
+
+
+
+
+ Template to create new slimes
+
+ The name of the object (prefixes are recommend, but not needed)
+ The definition for this slime
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets the eat info
+
+ The min. drive required for the slime to eat
+ How much the drive is reduced once fed
+ How much the agitation is reduced once fed
+ How much the agitation is reduced once fed it's favorite
+
+
+
+ Sets the max. health of this slime
+
+ The max. health to set
+
+
+
+ Sets the possibility of having a feral state
+
+ Can the slime be afected by a feral state
+
+
+
+ Sets the possibility of turning into a glitch if spawned in the Slimeulation
+
+ Can the slime be turned into a glitch inside the Slimeulation
+
+
+
+ Sets the fear profile
+
+ The fear profile to set
+
+
+
+ Sets the starting emotions of this slime
+
+ The initial state for Hunger
+ The initial state for Agitation
+ The initial state for Fear
+
+
+
+ Sets the scale for the Delaunch Trigger (do not change if you don't know what you are doing)
+
+ The new scale to set
+
+
+
+ Adds a new behaviour to the slime
+
+ The component containing the new behaviour
+
+
+
+ Adds a new behaviour to the slime
+
+ The component containing the new behaviour
+ A list of components containing the new behaviour
+
+
+
+ Sets a new bone structure for the slime (Starting at the Appearance part)
+
+ The new bone structure as a game object (to add to the prefab)
+
+
+
+ Sets the translation for this slime's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Generates the largos for this slime (use this if you want the slime to be largoable)
+
+ Can the largos from the slime become tarr?
+ Use this to add extra behaviours to the largos
+ A list of all IDs made for the largos created
+
+
+
+ Generates a roaming Gordo Slime for this slime (use this if you want the slime to have a Gordo counter part)
+ Roaming gordos are normal slimes scaled as a gordo and contains almost no behaviours, also it doesnt eat. Use PrefabFunctions to give it
+ behaviours
+
+ The ID for the gordo
+ The slime template for the Roaming Gordo (YOU NEED TO CLASS .Create TO FINISH THE PROCESS)
+
+
+
+ Generates a Gordo Slime for this slime (use this if you want the slime to have a Gordo counter part)
+
+ The ID for the gordo
+ The gordo template for the static gordo (YOU NEED TO CLASS .Create TO FINISH THE PROCESS)
+
+
+
+ Builds the module for this slime
+
+
+
+
+ Builds the definition for this slime
+
+
+
+
+ A template to create new toys
+
+
+
+
+ Template to create new toys
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Identifiable ID for this toy
+ The model's mesh for this toy
+ The materials that compose this toy's model
+ The audio cue when this toy hits something
+
+
+
+ Sets the vacuumable size
+
+ The vac size to set
+
+
+
+ Sets what fashion is required to react with this toy
+
+ The ID of said fashion (NONE to remove the required fashion)
+
+
+
+ Sets the translation for this toy's name
+
+ The translated name
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template ti create new Tech Activators
+
+
+
+
+ Template to create new Tech Activators
+
+ The name of the object (prefixes are recommended, but not needed)
+ The prefab UI to display
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Interface used to make lists of Mod Prefabs (as lists can't have different generic constructs)
+
+
+
+
+ Simple prefab like class, used to make the structure for templates
+
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Adds a new start action to the pile
+
+ ID of the action (as registered in TemplateActions)
+
+
+
+ Adds a new awake action to the pile
+
+ ID of the action (as registered in TemplateActions)
+
+
+
+ Adds a prefab function (they are executed when ToPrefab is called)
+
+ Action to add to the pile
+
+
+
+ Adds a prefab function (they are executed when ToPrefab is called)
+
+ Actions to add to the pile
+
+
+
+ Sets the translation for the prefab, not all templates implement this, so it might do nothing.
+
+ The translated name
+
+
+
+ Turns this ModPrefab/Template into a runtime prefab
+
+
+
+
+ Returns this prefab as a template
+
+
+
+
+ Returns this prefab as a clone of the template
+
+
+
+
+ A template to create new bush plantables
+
+
+
+
+ Template to create new veggie plantables
+
+ The name of the object (prefixes are recommended, but not needed)
+ Is this plantable for the deluxe version of the garden?
+ The ID of the identifiable spawned by this plantable
+ The spawn resource id for this plantable
+ The list of things to spawn (null to get it from the ID provided)
+
+
+
+ Sets the bonus info
+
+ The min. amount selected from the bonus list
+ The change to select extras
+
+
+
+ Sets the list of bonus spawns
+
+ The list to set
+
+
+
+ Adds a new bonus spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a new bonus spawwn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the list of spawns
+
+ The list to set
+
+
+
+ Adds a spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a spawn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the tree to be used
+
+ The tree's mesh
+ The materials for that tree
+ The tree's mesh for the collider
+
+
+
+ Sets the tree to be used based on the SpawnResource ID (only works for those already in the game)
+
+ The ID to get the tree from
+
+
+
+ Sets the leaves to be used
+
+ The leaves's mesh
+ The materials for that leaves
+ The leaves's mesh for the collider
+
+
+
+ Sets the leaves to be used based on the SpawnResource ID (only works for those already in the game)
+
+ The ID to get the leaves from
+
+
+
+ Sets the position for the leaves (uses the same for normal and deluxe)
+
+ The new position to set
+
+
+
+ Sets the position for the leaves (uses different ones for normal and deluxe versions)
+
+ The new position to set for normal
+ The new position to set for deluxe
+
+
+
+ Sets the scale for the leaves (uses the same for normal and deluxe)
+
+ The new scale to set
+
+
+
+ Sets the scale for the leaves (uses different ones for normal and deluxe versions)
+
+ The new scale to set for normal
+ The new scale to set for deluxe
+
+
+
+ Sets the scale for the tree (uses the same for normal and deluxe)
+
+ The new scale to set
+
+
+
+ Sets the scale for the tree (uses different ones for normal and deluxe versions)
+
+ The new scale to set for normal
+ The new scale to set for deluxe
+
+
+
+ Sets the spawn info
+
+ Min. number of items to spawn
+ Max. number of items to spawn
+ Min. hours to be ready to spawn
+ Max. hours to be ready to spawn
+ Min. value of nutrients, related to growth rate
+ The number of hours the water lasts in the soil
+
+
+
+ Sets the model of the spawn points (used to display the growth of the items)
+
+ The mesh for the model
+ The materials for the model
+
+
+
+ Sets the spawn joints (the list needs to have 20 for non-deluxe and 34 for deluxe)
+
+ New spawn joints to set
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new fruit plantables
+
+
+
+
+ Template to create new veggie plantables
+
+ The name of the object (prefixes are recommended, but not needed)
+ Is this plantable for the deluxe version of the garden?
+ The ID of the identifiable spawned by this plantable
+ The spawn resource id for this plantable
+ The list of things to spawn (null to get it from the ID provided)
+
+
+
+ Sets the bonus info
+
+ The min. amount selected from the bonus list
+ The change to select extras
+
+
+
+ Sets the list of bonus spawns
+
+ The list to set
+
+
+
+ Adds a new bonus spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a new bonus spawwn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the list of spawns
+
+ The list to set
+
+
+
+ Adds a spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a spawn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the tree to be used
+
+ The tree's mesh
+ The materials for that tree
+ The tree's mesh for the collider
+
+
+
+ Sets the tree to be used based on the SpawnResource ID (only works for those already in the game)
+
+ The ID to get the tree from
+
+
+
+ Sets the leaves to be used
+
+ The leaves's mesh
+ The materials for that leaves
+ The leaves's mesh for the collider
+
+
+
+ Sets the leaves to be used based on the SpawnResource ID (only works for those already in the game)
+
+ The ID to get the leaves from
+
+
+
+ Sets the position for the leaves (uses the same for normal and deluxe)
+
+ The new position to set
+
+
+
+ Sets the position for the leaves (uses different ones for normal and deluxe versions)
+
+ The new position to set for normal
+ The new position to set for deluxe
+
+
+
+ Sets the scale for the leaves (uses the same for normal and deluxe)
+
+ The new scale to set
+
+
+
+ Sets the scale for the leaves (uses different ones for normal and deluxe versions)
+
+ The new scale to set for normal
+ The new scale to set for deluxe
+
+
+
+ Sets the scale for the tree (uses the same for normal and deluxe)
+
+ The new scale to set
+
+
+
+ Sets the scale for the tree (uses different ones for normal and deluxe versions)
+
+ The new scale to set for normal
+ The new scale to set for deluxe
+
+
+
+ Sets the spawn info
+
+ Min. number of items to spawn
+ Max. number of items to spawn
+ Min. hours to be ready to spawn
+ Max. hours to be ready to spawn
+ Min. value of nutrients, related to growth rate
+ The number of hours the water lasts in the soil
+
+
+
+ Sets the model of the spawn points (used to display the growth of the items)
+
+ The mesh for the model
+ The materials for the model
+
+
+
+ Sets the spawn joints (the list needs to have 20 for non-deluxe and 34 for deluxe)
+
+ New spawn joints to set
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new veggie plantables
+
+
+
+
+ Template to create new veggie plantables
+
+ The name of the object (prefixes are recommended, but not needed)
+ Is this plantable for the deluxe version of the garden?
+ The ID of the identifiable spawned by this plantable
+ The spawn resource id for this plantable
+ The list of things to spawn (null to get it from the ID provided)
+
+
+
+ Sets the bonus info
+
+ The min. amount selected from the bonus list
+ The change to select extras
+
+
+
+ Sets the list of bonus spawns
+
+ The list to set
+
+
+
+ Adds a new bonus spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a new bonus spawwn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the list of spawns
+
+ The list to set
+
+
+
+ Adds a spawn to the list
+
+ The ID for the spawnable
+
+
+
+ Adds a spawn to the list
+
+ The game object of the identifiable to spawn
+
+
+
+ Sets the sprout to be used (null can also be provided to use the default one)
+
+ The sprout's mesh
+ The material for that sprout
+
+
+
+ Sets the sprout to be used based on the SpawnResource ID (only works for those already in the game)
+
+ The ID to get the sprout from
+
+
+
+ Sets the spawn info
+
+ Min. number of items to spawn
+ Max. number of items to spawn
+ Min. hours to be ready to spawn
+ Max. hours to be ready to spawn
+ Min. value of nutrients, related to growth rate
+ The number of hours the water lasts in the soil
+
+
+
+ Sets the model of the spawn points (used to display the growth of the items)
+
+ The mesh for the model
+ The materials for the model
+
+
+
+ Sets the spawn joints (the list needs to have 20 for non-deluxe and 34 for deluxe)
+
+ New spawn joints to set
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create new plots
+
+
+
+
+ Template to create new plots
+
+ The name of the object (prefixes are recommended, but not needed)
+ The Plot ID for this plot
+
+
+
+ Sets the Activator Transform values
+
+ The position to set
+ The rotation to set
+ The scale to set
+
+
+
+ Sets the Activator Transform values
+
+ The values to set
+
+
+
+ Sets the game object for the UI of this plot
+
+ The game object to set
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ A template to create a plot frame (use this if you want to create a custom frame by adding prefab functions to it)
+
+
+
+
+ Template to create a plot frame
+
+ The name of the object
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Interface used to make lists of PlotUpgradeTemplate (as lists can't have different generic constructs)
+
+
+
+
+ A template to create a plot upgrade
+ This template is a bit more complex than the others, it's structure is entirely built by you. It only exists for covinience when adding to custom plots.
+
+
+
+
+ Template to create a plot upgrade
+
+ The name of the object
+ The upgrade for this land plot
+ The upgrader component to add to the main object
+ The action to setup the component after creation
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+ The action to construct the template
+
+
+
+ A template to create new activator UIs
+
+
+
+
+ Template to create new activator UIs
+
+ The name of the object (prefixes are recommended, but not needed)
+ The UI component to add
+
+
+
+ Creates the object of the template (To get the prefab version use .ToPrefab() after calling this)
+
+
+
+
+ Registers a toy into the first group of toys.
+
+ The belonging to the toy.
+
+
+
+ Registers a toy into the second group of toys.
+
+ The belonging to the toy.
+
+
+
+ Localization
+
+
+
+
+ Add a plaintext translation for a localization key
+
+ Key bundle the localization key is located in
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'pedia' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'actor' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'ui' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'achieve' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'exchange' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'global' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'mail' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for a localization key in the 'tutorial' bundle
+
+ The localization key
+ The plain text translation
+
+
+
+ Add a plaintext translation for localization for SRML error messages
+
+ The language to be translated to
+ The plain text translation for the text saying it's an error
+ The plain text translation for the text saying mod-loading is aborting
+
+
+
+ Creates a .
+
+ What value is assigned to the .
+ The name of the .
+ The created .
+ Throws if ran outside of PreLoad
+
+
+
+ Check if a belongs to a modded upgrade.
+
+ The to check.
+ True if belongs to a modded upgrade, otherwise false.
+
+
+
+ Registers a callback to be called when an upgrade is bought.
+
+ The that calls the callback.
+ The callback to be called.
+
+
+
+ Registers an upgrade locker.
+
+ The to be locked.
+ The locker locking the .
+
+
+
+ Registers an upgrade that's automatically unlocked.
+
+ The to be unlocked.
+
+
+
+ An utility class to help with Enums
+
+
+
+
+ Parses an enum in a easier way
+
+ Type of the enum
+ Value to parse
+ The parsed enum on success, null on failure.
+
+
+
+ Parses an enum in a easier way
+
+ Type of the enum
+ Value to parse
+ true to ignore case; false to regard case.
+ The parsed enum on success, null on failure.
+
+
+
+ Converts int to enum
+
+ Type of the enum
+ Int to convert to enum
+ The enum equal to the int
+
+
+
+ Gets all names in an enum
+
+ Type of the enum
+ The list of names in the enum
+
+
+
+ Gets all enum values in an enum
+
+ Type of the enum
+ The list of all values in the enum
+
+
+
+ Checks if an enum is defined.
+
+ Type of the enum
+ Value to check
+ true if defined, false if not.
+
+
+
+ Checks all names in an enum to see if what you need exists.
+
+ Type of the enum
+ Value to find
+ true if found, false if not.
+
+
+
+ Parses an enum in a easier way
+
+ Type of the enum
+ Value to parse
+ What to return if the parse fails.
+ The parsed enum on success, on failure.
+
+
+
+ Parses an enum in a easier way
+
+ Type of the enum
+ Value to parse
+ true to ignore case; false to regard case.
+ What to return if the parse fails.
+ The parsed enum on success, on failure.
+
+
+
+ Converts int to enum
+
+ Type of the enum
+ Int to convert to enum
+ The enum equal to the int
+
+
+
+ Gets all names in an enum
+
+ Type of the enum
+ The list of names in the enum
+
+
+
+ Gets all enum values in an enum
+
+ Type of the enum
+ What to return if the parse fails.
+ The list of all values in the enum
+
+
+
+ Checks if an enum is defined.
+
+ Type of the enum
+ Value to check
+ true if defined, false if not.
+
+
+
+ Checks all names in an enum to see if what you need exists.
+
+ Type of the enum
+ Value to find
+ true if found, false if not.
+
+
+
+ A basic mod data class that is safe to share between mods (no logic in it)
+
+
+
+
+ Data structure to simplify versioning and the comparing of versions
+
+
+
+
+ Actual internal implementation of a mod
+
+
+
+
+ Mods associated SRModInfo object
+
+
+
+
+ Path of the mod (usually the directory where the core modinfo.json is located)
+
+
+
+
+ Gets the current executing mod as an SRMod instance
+
+ The current executing mod
+
+
+
+ Forces a certain mod to be returned from
+
+ The mod to be forced
+
+
+
+ Clears the current mod context
+
+
+
+
+ Searches for valid mods and their assemblies, and decides the load order based on their settings
+
+
+
+
+ Check if corresponds with a valid mod
+
+ Mod ID to check
+ Whether or not the mod exists
+
+
+
+ Gets the associated for the associated
+
+ Relevant Mod ID
+ The associated ModInfo
+
+
+
+ Get an instance from a Mod ID
+
+ The ModID
+ The corresponding instance, or null
+
+
+
+ Utility class to help with the discovery and loading of mod assemblies
+
+
+
+
+ Class that represents a mod before it has been loaded or fully processed
+
+
+
+
+ Create a protomod from json info
+
+ Path of the json file
+ The parsed
+
+
+
+ Try to create a protomod from an embedded modinfo json in a DLL
+
+ Path to the DLL file to process
+ The parsed , or null
+ Whether the parsing was successful
+
+
+
+ Make sure fields are in the correct form and not null
+
+
+
+
+ Turn the protomod into a proper instance
+
+ Converted
+
+
+
+ Reverses the order of the elements in the entire .
+
+
+
+
+ Reverses a array
+
+
+
+
+ Swap two elements in array
+
+
+
+
+ Creates a from a .
+
+ A that contains elements from the input sequence except
+
+
+
+
+ Attempts to get a value from a collection.
+
+ True if an element in the collection matches the specified condition, otherwise false.
+
+
+
+ Returns new array without element at index
+
+
+
+
+ Returns new array with inserted empty element at index
+
+
+
+
+ Returns random element from collection
+
+
+
+
+ Returns random element from collection
+
+
+
+
+ Returns random element from collection
+
+
+
+
+ Is array null or empty
+
+
+
+
+ Is collection null or empty
+
+
+
+
+ Is enumerable null or empty. IEnumerable is relatively slow. Use Array or Collection implementation if possible
+
+
+
+
+ Get next index for circular array. i.e. -1 will result with last element index, Length + 1 is 0
+
+ Example (infinite loop first->last->first):
+ i = myArray.NextIndex(i++);
+ var nextItem = myArray[i];
+
+
+
+
+ Returns -1 if none found
+
+
+
+
+ Is Elements in two collections are the same
+
+
+
+
+ Is Keys in MyDictionary is the same as some collection
+
+
+
+
+ Is Values in MyDictionary is the same as some collection
+
+
+
+
+ Gets the value associated with the specified key if it exists, or
+ return the default value for the value type if it doesn't.
+
+
+
+
+ Gets the value associated with the specified key if it exists, or
+ generate a value for the new key if it doesn't.
+
+
+
+
+ Performs an action on each element of a collection.
+
+
+
+
+ Performs a function on each element of a collection.
+
+
+
+
+ Find the element of a collection that has the highest selected value.
+
+
+
+
+ Find the element of a collection that has the lowest selected value.
+
+
+
+
+ Returns new Color with Alpha set to a
+
+
+
+
+ Set Alpha of Renderer.Color
+
+
+
+
+ To string of "#b5ff4f" format
+
+
+
+
+ Returns a color lighter than the given color.
+
+
+
+
+
+
+ Returns a color darker than the given color.
+
+
+
+
+
+
+ Brightness offset with 1 is brightest and -1 is darkest
+
+
+
+
+ Converts unix timestamp to with high precision.
+
+ Unix timestamp.
+ DateTime object that represents the same moment in time as provided Unix time.
+
+
+
+ Converts to unix timestamp with high precision
+
+ DateTime date representation.
+ unix timestamp that represents the same moment in time as provided DateTime object.
+
+
+
+ Stop value from going above max or below min values.
+
+
+
+
+ Stop value from going above max or below min values.
+
+
+
+
+ Stop value from going above max or below min values.
+
+
+
+
+ Swap two reference values
+
+
+
+
+ Snap to grid of "round" size
+
+
+
+
+ Snap to grid of "round" size
+
+
+
+
+ Returns the sign 1/-1 evaluated at the given value.
+
+
+
+
+ Value is in [0, 1) range.
+
+
+
+
+ Value is in [closedLeft, openRight) range.
+
+
+
+
+ Value is in [closedLeft, closedRight] range, max-inclusive.
+
+
+
+
+ Clamp value to less than min or more than max
+
+
+
+
+ Clamp value to less than min or more than max
+
+
+
+
+ Return point A or B, closest to num
+
+
+
+
+ Contains extension methods for
+
+
+
+
+ Performs a TRUE null-check.
+
+ An object to check.
+ Returns if object is null, otherwise.
+
+
+
+ Performs a TRUE not-null-check.
+
+ An object to check.
+ Returns if object is null, otherwise.
+
+
+
+ Invokes a method
+
+ The object you are invoking the method in
+ The name of the method
+ parameters
+
+
+
+ Invokes a method
+
+ Type of return
+ The object you are invoking the method in
+ The name of the method
+ parameters
+
+
+
+ Sets the value of a field
+
+ The object to set the field value of
+ The name of the field
+ The value to set
+
+
+
+ Sets the value of a field
+
+ The object to set the field value of
+ The name of the field
+ The value to set
+ Type of value
+
+
+
+ Gets the value of a field
+
+ The object to get the value from
+ The name of the field
+
+
+
+ Gets the value of a field
+
+ The object to get the value from
+ The name of the field
+ Type of value
+
+
+
+ Sets the value of a property
+
+ The object to set the property value of
+ The name of the property
+ The value to set
+ Type of value
+
+
+
+ Sets the value of a property
+
+ The object to set the property value of
+ The name of the property
+ The value to set
+ Type of value
+
+
+
+ Gets the value of a property
+
+ The object to get the value from
+ The name of the property
+
+
+
+ Gets the value of a property
+
+ The object to get the value from
+ The name of the property
+ Type of value
+
+
+
+ Contains extension methods for
+
+
+
+
+ Clones the Scriptable Object
+
+
+
+ Indicates whether the specified string is or an empty string ("").
+ if the parameter is or an empty string (""); otherwise, .
+
+
+ Indicates whether a specified string is , empty, or consists only of white-space characters.
+ if the parameter is or , or if consists exclusively of white-space characters.
+
+
+
+ Returns a String array containing the substrings in this string that are delimited by elements of a specified
+ String array. A parameter specifies whether to return empty array elements.
+
+ The @this to act on.
+ A string that delimit the substrings in this string.
+
+ (Optional) Specify RemoveEmptyEntries to omit empty array elements from the array returned,
+ or None to include empty array elements in the array returned.
+
+
+ An array whose elements contain the substrings in this string that are delimited by the separator.
+
+
+
+
+ Reverses the string
+
+
+
+
+ Convert a string value to an Enum value.
+
+
+
+
+ Number presented in Roman numerals
+
+
+
+
+ Get the "message" string with the "surround" string at the both sides
+
+
+
+
+ Get the "message" string with the "start" at the beginning and "end" at the end of the string
+
+
+
+
+ Surround string with "color" tag
+
+
+
+
+ Surround string with "color" tag
+
+
+
+
+ Surround string with "size" tag
+
+
+
+
+ Surround string with "u" tag
+
+
+
+
+ Surround string with "b" tag
+
+
+
+
+ Surround string with "i" tag
+
+
+
+
+ Removes anything after the parameter
+
+ The string to seek
+ Whether to remove the
+
+
+
+ Removes anything after the parameter
+
+ The string to seek
+ Whether to remove the
+
+
+
+ Retrieves specified symbols amount from the end of the string.
+
+ Source string.
+ Amount of symbols
+ Specified symbols amount from the end of the string.
+
+
+
+ Removes specified symbols amount from the end of the string.
+
+ Source string.
+ Amount of symbols
+ Modified string.
+
+
+
+ Retrieves specified symbols amount from the beginning of the string.
+
+ Source string.
+ Amount of symbols
+ Specified symbols amount from the beginning of the string.
+
+
+
+ Method will return all the indexes for a matched string.
+
+ Source string.
+ String Value to look for.
+ Comparison Type.
+ Indexes for a matched string.
+
+
+
+
+ Removes all the leading occurrences of specified string from the current string.
+
+ Current string.
+ A string to remove.
+ The string that remains after all occurrences of trimString parameter are removed from the start of the current string.
+
+
+
+ Removes all the trailing occurrences of specified string from the current string.
+
+ Current string
+ A string to remove.
+ The string that remains after all occurrences of trimString parameter are removed from the end of the current string.
+
+
+
+ Represents list of supported by Unity Console color names
+
+
+
+
+ Create new sprite out of Texture
+
+ A texture to created sprite from.
+ New sprite instance.
+
+
+
+ Change texture size (and scale accordingly)
+
+
+
+
+ Crop texture to desired size.
+ Somehow cropped image seemed darker, brightness offset may fix this
+
+
+
+
+ Will texture with solid color
+
+
+
+
+ Convert png representation to base64 string.
+
+ Texture to convert.
+ Converted texture as base64 string
+
+
+
+ Loads texture content from base64 string.
+
+ Texture to load image content into.
+ Base64 string image representation.
+ Updated texture.
+
+
+
+ Resets `anchorMin`, `anchorMax`, `offsetMin`, `offsetMax` to `Vector2.zero`.
+
+ RectTransform to operate with.
+
+
+
+ Get's the screen rect of provided RectTransform.
+
+ RectTransform to operate with.
+ Screen rect.
+
+
+
+ Method to get Rect related to ScreenSpace, from given RectTransform.
+ This will give the real position of this Rect on screen.
+
+ Original RectTransform of some object
+ New Rect instance.
+
+
+
+ Sets value.
+
+ Transform component.
+ New lossyScale value.
+
+
+
+ Reset component position, scale and rotation.
+
+ Transform component.
+
+
+
+ Removes all transform children.
+
+ Transform component.
+ Will ignore disabled game-objects when set to true.
+
+
+
+
+ Find or create child with name.
+
+ Transform component.
+ Child name.
+ Child component instance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Set position to Vector3.zero.
+
+
+
+
+ Set sizeDelta to Vector2.Zero.
+
+
+
+
+ Snap to grid of snapValue
+
+
+
+
+ Snap to grid of snapValue
+
+
+
+
+ Snap to grid of snapValue
+
+
+
+
+ Snap position to grid of snapValue
+
+
+
+
+ Snap to one unit grid
+
+
+
+
+ Snap to one unit grid
+
+
+
+
+ Snap to one unit grid
+
+
+
+
+ Finds the position closest to the given one.
+
+ World position.
+ Other world positions.
+ Closest position.
+
+
+
+ Get vector between source and destination
+
+
+
+
+ Get vector between source and destination
+
+
+
+
+ Get vector between source and destination
+
+
+
+
+ Get vector between source and target
+
+
+
+
+ Get vector between source and target
+
+
+
+
+ Get vector between source and target
+
+
+
+
+ Get vector between source and target
+
+
+
+
+ Calculates a squared distance between current and given vectors.
+
+ The current vector.
+ The given vector.
+ Returns squared distance between current and given vectors.
+
+
+
+ Multiplies each element in Vector3 by the given scalar.
+
+ The current vector.
+ The given scalar.
+ Returns new Vector3 containing the multiplied components.
+
+
+
+ Multiplies each element in Vector3 a by the corresponding element of b.
+
+ The current vector.
+ The given vector.
+ Returns new Vector3 containing the multiplied components of the given vectors.
+
+
+
+ Smoothes a Vector3 that represents euler angles.
+
+ The current Vector3 value.
+ The target Vector3 value.
+ A refernce Vector3 used internally.
+ The time to smooth, in seconds.
+ The smoothed Vector3 value.
+
+
+
+ Calculates a squared distance between current and given vectors.
+
+ The current vector.
+ The given vector.
+ Returns squared distance between current and given vectors.
+
+
+
+ Multiplies each element in Vector2 by the given scalar.
+
+ The current vector.
+ The given scalar.
+ Returns new Vector2 containing the multiplied components.
+
+
+
+ Multiplies each element in Vector2 a by the corresponding element of b.
+
+ The current vector.
+ The given vector.
+ Returns new Vector2 containing the multiplied components of the given vectors.
+
+
+
+ Handles identification of Modded ID's
+
+
+
+
+ Adds more methods to to allow for more flexable addition
+
+
+
+
diff --git a/Libs/System.Runtime.Serialization.dll b/Libs/System.Runtime.Serialization.dll
new file mode 100644
index 0000000..0397ac5
Binary files /dev/null and b/Libs/System.Runtime.Serialization.dll differ
diff --git a/README.md b/README.md
index ffcd6d2..03db211 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,42 @@
# srmp-public
+This is the code for the Slime Rancher MultiPlayer Mod (SRMP) by SatyPardus.
-It's bad. It's really really bad.
+The user manual which includes information about compatability information, download and installation instructions and standard troubleshooting can be found [here](/manual.md).
-There is so much to clean up in this project, I would not even know where to begin.
-Kinda the reason why it's already uploaded. No idea where and how to clean it up.
-But this is the source code of my Slime Rancher Multiplayer mod.
-It went through many iterations and each new one had stuff copy pasted.
+## Bug Status
+Note: Bug list compiled from last known bug list of version 1488
-It's a mess within a mess.
-Oh god, forgive me.
+FIXED:
+- Multiplayer window doesn't show up on resolutions < 1920x1080
+- Exchange sometimes skips rewards if multiple players put items in at the same time
+- Exchange chest disappears without rewards
+-
+IN PROGRESS: N/A
----------------------------------------------------------------------------------
+Known Bugs:
+- Plort collectors don't work properly sometimes (Playing effect but not pulling anything)
+- Nutcracker doesn't spit out right amount, or spits out "babies"
+- Slimes sometimes appear "angry" for other players
+- Game stutters when placing/removing gadgets
+- First time using the mod can apparently break a lot of things (falling through world, slimes not eating) - Restarting the game fixes it
+- DLCs don't seem to be loaded correctly when leaving and joining
+- DLC are not initialized on game start, making the "You need following DLCs:" message pop up (Can be fixed by loading the "Manage DLCs" menu and trying again)
+- Gordos don't drop things sometimes
+- Slimes sometimes dont produce plorts
+- Drones get stuck in place sometimes
+- Chat sometimes empty for remote players
+- Upgrades sometimes does not get applied to All players
-But for real. Have fun digging through my unoptimized and undocumented code.
-I never thought I actually gonna release this, yet here we are.
-Would have dressed differently if I would have known.
-Don't judge me tho. It still .... "works".
-Just not as good as it could!
+## Current Status
+[@Twirlbug](https://github.com/Twirlbug)
+- Currently working on going through the code, adding notes and fixing some of the bugs in my free time.
+- I adore this mod and want to give both credit and a huge thank you to Saty for the origional creation of the mod.
+I am slowly working my way through the list of bugs as seen above.
+
+### Notation Status
+Files in the following folders still need more notation:
+- Networking
+- Packets
+- Patches
diff --git a/SRMP.sln b/SRMP.sln
index 285d74f..bf9122f 100644
--- a/SRMP.sln
+++ b/SRMP.sln
@@ -1,32 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.1267
+# Visual Studio Version 17
+VisualStudioVersion = 17.6.33815.320
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SRMP", "SRMP\SRMP.csproj", "{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{623884D3-E475-43F6-A6DF-64B8860E3EDD}"
+ ProjectSection(SolutionItems) = preProject
+ SRMP\_info.txt = SRMP\_info.txt
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
- SRML|Any CPU = SRML|Any CPU
SRML NoVer|Any CPU = SRML NoVer|Any CPU
- Standalone|Any CPU = Standalone|Any CPU
+ SRML|Any CPU = SRML|Any CPU
Standalone NoVer|Any CPU = Standalone NoVer|Any CPU
+ Standalone|Any CPU = Standalone|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Release|Any CPU.Build.0 = Release|Any CPU
- {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML|Any CPU.ActiveCfg = SRML|Any CPU
- {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML|Any CPU.Build.0 = SRML|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML NoVer|Any CPU.ActiveCfg = SRML NoVer|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML NoVer|Any CPU.Build.0 = SRML NoVer|Any CPU
- {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone|Any CPU.ActiveCfg = Standalone|Any CPU
- {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone|Any CPU.Build.0 = Standalone|Any CPU
+ {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML|Any CPU.ActiveCfg = SRML|Any CPU
+ {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.SRML|Any CPU.Build.0 = SRML|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone NoVer|Any CPU.ActiveCfg = Standalone NoVer|Any CPU
{E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone NoVer|Any CPU.Build.0 = Standalone NoVer|Any CPU
+ {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone|Any CPU.ActiveCfg = Standalone|Any CPU
+ {E1BF7CDA-F2AE-4042-A992-DCBF62E79238}.Standalone|Any CPU.Build.0 = Standalone|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/SRMP/Console/Console Commands.txt b/SRMP/Console/Console Commands.txt
new file mode 100644
index 0000000..b010d48
--- /dev/null
+++ b/SRMP/Console/Console Commands.txt
@@ -0,0 +1,27 @@
+The following console Commands work in the pop up console
+
+cheat money [amount]
+ Add or Remove the given amount from the curret money score
+
+cheat keys [amount]
+ Add or Remove the given amount of keys from the current amount
+
+cheat allgadgets
+ Unlocks all of the gagets in the game
+
+cheat spawn [id] ([amount])
+ spawns given item for the given ammount
+
+tp [(optional)TargetPlayer] [DestinationPlayer]
+ Teleports the player in spot 1 to player/destination entered
+ if spot 1 is empty the palayer that entered in the command in infered as the target
+listplayers
+ Prints the list of current players to the console
+
+sleep [Hours]
+ Sleep command followed by the time in in game hours to "sleep"". Fast forwards the game the alotted hours.
+
+console [enable/disable] [logtype]
+ Sets whether a specific log type should be displaying in the console.
+ All type default to enabled.
+ Log Types: Error, Assert, Warning, Log, Exception
\ No newline at end of file
diff --git a/SRMP/Console/ConsoleInput.cs b/SRMP/Console/ConsoleInput.cs
index cf52165..34076eb 100644
--- a/SRMP/Console/ConsoleInput.cs
+++ b/SRMP/Console/ConsoleInput.cs
@@ -1,4 +1,5 @@
-using System;
+using Microsoft.Win32;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,7 +10,46 @@ namespace SRMultiplayer
{
public string inputString = "";
public event Action OnInputText;
-
+
+ ///
+ /// Handle updates the console
+ /// This is to catch key presses and process them
+ ///
+ public void Update()
+ {
+ if (Console.KeyAvailable)
+ {
+ ConsoleKeyInfo consoleKeyInfo = Console.ReadKey();
+
+ switch (consoleKeyInfo.Key)
+ {
+ case ConsoleKey.Enter: this.OnEnter(); break;
+ case ConsoleKey.Backspace: this.OnBackspace(); break;
+ case ConsoleKey.Escape: this.OnEscape(); break;
+ case ConsoleKey.UpArrow: this.GetCommand(1); break;
+ case ConsoleKey.DownArrow: this.GetCommand(-1); break;
+ default:
+ //check if pressed key is a character
+ bool flag = consoleKeyInfo.KeyChar > '\0';
+ if (flag)
+ {
+ //if so at it tothe input line
+ this.inputString += consoleKeyInfo.KeyChar.ToString();
+ this.RedrawInputLine();
+ }
+ break;
+ }
+ }
+
+
+
+ }
+
+
+ #region Console Processors
+ ///
+ /// Clears out the current console line
+ ///
public void ClearLine()
{
Console.CursorLeft = 0;
@@ -17,7 +57,9 @@ namespace SRMultiplayer
Console.CursorTop--;
Console.CursorLeft = 0;
}
-
+ ///
+ /// Used to redraw the input line incase we had to hold for console write lines
+ ///
public void RedrawInputLine()
{
bool flag = Console.CursorLeft > 0;
@@ -29,7 +71,12 @@ namespace SRMultiplayer
Console.Write("> ");
Console.Write(this.inputString);
}
-
+ #endregion region
+
+ #region Key Press Events
+ ///
+ /// Process Backspace pressed
+ ///
internal void OnBackspace()
{
bool flag = this.inputString.Length <= 0;
@@ -39,7 +86,9 @@ namespace SRMultiplayer
this.RedrawInputLine();
}
}
-
+ ///
+ /// Process Escape pressed
+ ///
internal void OnEscape()
{
this.ClearLine();
@@ -47,6 +96,9 @@ namespace SRMultiplayer
this.RedrawInputLine();
}
+ ///
+ /// Process Enter pressed
+ ///
internal void OnEnter()
{
this.ClearLine();
@@ -57,47 +109,56 @@ namespace SRMultiplayer
bool flag = this.OnInputText != null;
if (flag)
{
+ //on text inputed reset the search loc and cycle the search tree
+ searchLoc = -1; //searchLoc set to -1 to always go to place 0 on first arrow
+ AddToCommandTree(obj);
+
this.OnInputText(obj);
}
}
-
- public void Update()
+
+ #endregion
+
+ #region Command History Retrieval
+ List cmdTree = new List();
+ int maxCommands = 10;
+ ///
+ /// Manages the Command tree for the up and down arrows
+ ///
+ ///
+ internal void AddToCommandTree(string cmdText)
{
- bool flag = !Console.KeyAvailable;
- if (!flag)
+ cmdTree.Insert(0, cmdText);
+
+ //if tree gets larger than 10 remove the 11th item
+ if (cmdTree.Count > maxCommands) { cmdTree.RemoveAt(10); };
+ }
+
+
+ //handle internal cycling of last 10 commands
+ int searchLoc = -1;
+ ///
+ /// Gets the command at the designaed slot from the current possition
+ ///
+ /// Possition from the current Command
+ internal void GetCommand(int diff)
+ {
+ if (cmdTree.Count > 0)
{
- ConsoleKeyInfo consoleKeyInfo = Console.ReadKey();
- bool flag2 = consoleKeyInfo.Key == ConsoleKey.Enter;
- if (flag2)
- {
- this.OnEnter();
- }
- else
- {
- bool flag3 = consoleKeyInfo.Key == ConsoleKey.Backspace;
- if (flag3)
- {
- this.OnBackspace();
- }
- else
- {
- bool flag4 = consoleKeyInfo.Key == ConsoleKey.Escape;
- if (flag4)
- {
- this.OnEscape();
- }
- else
- {
- bool flag5 = consoleKeyInfo.KeyChar > '\0';
- if (flag5)
- {
- this.inputString += consoleKeyInfo.KeyChar.ToString();
- this.RedrawInputLine();
- }
- }
- }
- }
+ searchLoc = searchLoc + diff;
+ //prevent below 0 or over max position
+ if (searchLoc > (cmdTree.Count - 1)) searchLoc = (cmdTree.Count - 1);
+ if (searchLoc < 0) searchLoc = 0;
+
+ //if a new location is found enter the search text in the input and redraw it.
+ this.inputString = cmdTree[searchLoc];
+ this.RedrawInputLine();
+ }
+ else
+ {
+ Console.WriteLine("cmdTree is empty");
}
}
+ #endregion
}
-}
+}
\ No newline at end of file
diff --git a/SRMP/Console/ConsoleWindow.cs b/SRMP/Console/ConsoleWindow.cs
index 0f4ff33..862784c 100644
--- a/SRMP/Console/ConsoleWindow.cs
+++ b/SRMP/Console/ConsoleWindow.cs
@@ -14,7 +14,9 @@ namespace SRMultiplayer
private TextWriter oldOutput;
private const int STD_OUTPUT_HANDLE = -11;
-
+ ///
+ /// Create the console window
+ ///
public void Initialize()
{
bool flag = !ConsoleWindow.AttachConsole(uint.MaxValue);
diff --git a/SRMP/Console/SRMPConsole.cs b/SRMP/Console/SRMPConsole.cs
new file mode 100644
index 0000000..d309f3a
--- /dev/null
+++ b/SRMP/Console/SRMPConsole.cs
@@ -0,0 +1,482 @@
+using JetBrains.Annotations;
+using MonomiPark.SlimeRancher.Regions;
+using SRMultiplayer.Networking;
+using SRMultiplayer.Packets;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Sockets;
+using UnityEngine;
+
+namespace SRMultiplayer
+{
+ enum LogItems
+ {
+ CLIENT,
+ SERVER,
+ PLAYERAMMO,
+ EXCHANGE
+ }
+
+
+ public class SRMPConsole : MonoBehaviour
+ {
+ ConsoleWindow console = new ConsoleWindow();
+ ConsoleInput input = new ConsoleInput();
+
+ //
+ // Create console window, register callbacks
+ //
+ void Awake()
+ {
+ DontDestroyOnLoad(gameObject);
+
+ console.Initialize();
+ console.SetTitle("Slime Rancher");
+
+ input.OnInputText += OnInputText;
+
+ Application.logMessageReceived += Application_logMessageReceived;
+
+ SRMP.Log("Console Started");
+ }
+
+ //used to prevent duplicate messages displaying and list what number duplicate it is
+ string LastMessage = "";
+ int duplicateCount = 0;
+
+ //types of console types that can be enabled/disabled
+ //server automatically starts with all active
+ List blockMessages = new List(); //keeps a list of message types that have been disabled
+ List blockLogs = new List(); //keeps a list of log message types that have been disabled
+ bool DisplayTrace = false;
+ private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
+ {
+ // We're half way through typing something, so clear this line ..
+ if (Console.CursorLeft != 0)
+ input.ClearLine();
+
+ //construct message
+ string message = condition;
+ if (!string.IsNullOrEmpty(stackTrace) && DisplayTrace)
+ {
+ //add stack strace if included
+ message += Environment.NewLine + stackTrace;
+ }
+
+ if (message == LastMessage)
+ {
+ //do not process duplicate marks if the last item was not written
+ if (duplicateCount > 0) duplicateCount++;
+ }
+ else
+ {
+ //add write line for duplicate notices if necessary
+ if (duplicateCount > 0)
+ {
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.WriteLine("Output Duplicated: " + duplicateCount);
+ }
+
+ //format color for message
+ if (type == LogType.Warning)
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ else if (type == LogType.Error)
+ Console.ForegroundColor = ConsoleColor.Red;
+ else
+ Console.ForegroundColor = ConsoleColor.White;
+
+ // mark new message
+ LastMessage = message;
+
+ bool displayLog = true;
+
+ //if log type is blocked turn off display
+ if (blockMessages.Contains(type)) displayLog = false;
+
+ //check data for specific inner types
+ string data = condition;
+
+ //remove the srmp tag and the time to check inner tags
+ if (type == LogType.Log && data.StartsWith("[SRMP]"))
+ {
+ data = data.Substring(17);
+
+ //if is still able to display make sure the log message blocker isnt blocking it
+ if (displayLog)
+ {
+ //try to pase the log message
+ if (Enum.TryParse(data.Split("]"[0])[0].Substring(1), true, out LogItems logMessage))
+ {
+ if (blockLogs.Contains(logMessage)) displayLog = false;
+ }
+ }
+ }
+
+
+ //always allow console reply to display
+ if (data.StartsWith("[Console]")) displayLog = true;
+
+ //only write the message type if its not blocked
+ if (displayLog)
+ {
+ //write the new line if not blocked
+ duplicateCount = 0;
+ Console.WriteLine(message);
+ }
+ else
+ {
+ //for testing log disabled display
+ //Console.ForegroundColor = ConsoleColor.Magenta;
+ Console.WriteLine(type.ToString() + " Dismissed");
+
+ //mark dupilcate count to -1
+ //prevent duplicate count for supressed messages from displaying
+ duplicateCount = -1;
+ }
+ }
+
+
+
+ // If we were typing something re-add it.
+ input.RedrawInputLine();
+ }
+
+ //create a log call that marks all console sent replys
+ void ConsoleLog(string message)
+ {
+ SRMP.Log(message, "Console");
+ }
+
+
+
+ //
+ // Text has been entered into the console
+ // Run it as a console command
+ //
+ void OnInputText(string obj)
+ {
+ var args = obj.Split(' ');
+ var cmd = args.FirstOrDefault();
+ args = args.Skip(1).ToArray();
+
+ switch (cmd.ToLower())
+ {
+ case "cheat":
+ {
+ if (args.Length > 0)
+ {
+ if (args[0].Equals("money"))
+ {
+ if (args.Length != 2 || !int.TryParse(args[1], out int money))
+ {
+ ConsoleLog("Usage: cheat money ");
+ }
+ else
+ {
+ if (money > 0)
+ SRSingleton.Instance.PlayerState.AddCurrency(money);
+ else
+ SRSingleton.Instance.PlayerState.SpendCurrency(money);
+ }
+ }
+ else if (args[0].Equals("enable"))
+ {
+ //TestUI.Instance.cheat = !TestUI.Instance.cheat;
+ }
+ else if (args[0].Equals("keys"))
+ {
+ if (args.Length != 2 || !int.TryParse(args[1], out int value))
+ {
+ ConsoleLog("Usage: cheat keys ");
+ }
+ else
+ {
+ SRSingleton.Instance.PlayerState.model.keys = value;
+ }
+ }
+ else if (args[0].Equals("allgadgets"))
+ {
+ foreach (var data in (Gadget.Id[])Enum.GetValues(typeof(Gadget.Id)))
+ {
+ SRSingleton.Instance.GadgetDirector.model.gadgets[data] = int.MaxValue;
+ }
+ foreach (var data in Identifiable.CRAFT_CLASS.Union(Identifiable.PLORT_CLASS))
+ {
+ SRSingleton.Instance.GadgetDirector.model.craftMatCounts[data] = int.MaxValue;
+ }
+ }
+ else if (args[0].Equals("spawn"))
+ {
+ if (args.Length == 2)
+ {
+ if (Enum.TryParse(args[1].ToUpper(), out Identifiable.Id id))
+ {
+ GameObject prefab = SRSingleton.Instance.LookupDirector.GetPrefab(id);
+ if (prefab != null)
+ {
+ SRBehaviour.InstantiateActor(prefab, SRSingleton.Instance.GameModel.player.currRegionSetId, SRSingleton.Instance.GameModel.player.GetPos() + new Vector3(0, 4, 0), Quaternion.identity, false);
+ }
+ else
+ {
+ ConsoleLog(id + " can not be spawned");
+ }
+ }
+ else
+ {
+ var data = Enum.GetNames(typeof(Identifiable.Id)).Where(n => n.ToLower().Contains(args[1].ToLower()));
+ SRMP.Log(args[1] + " not found. " + (data.Count() > 0 ? " Did you mean one of these?" : ""));
+ foreach (var name in data)
+ {
+ ConsoleLog(name);
+ }
+ }
+ }
+ else if (args.Length == 3 && int.TryParse(args[2], out int amount))
+ {
+ if (Enum.TryParse(args[1].ToUpper(), out Identifiable.Id id))
+ {
+ GameObject prefab = SRSingleton.Instance.LookupDirector.GetPrefab(id);
+ if (prefab != null)
+ {
+ for (int i = 0; i < amount; i++)
+ {
+ SRBehaviour.InstantiateActor(prefab, SRSingleton.Instance.GameModel.player.currRegionSetId, SRSingleton.Instance.GameModel.player.GetPos() + new Vector3(0, 4, 0), Quaternion.identity, false);
+ }
+ }
+ else
+ {
+ SRMP.Log(id + " can not be spawned");
+ }
+ }
+ else
+ {
+ var data = Enum.GetNames(typeof(Identifiable.Id)).Where(n => n.ToLower().Contains(args[1].ToLower()));
+ ConsoleLog(args[1] + " not found. " + (data.Count() > 0 ? " Did you mean one of these?" : ""));
+ foreach (var name in data)
+ {
+ ConsoleLog(name);
+ }
+ }
+ }
+ else
+ {
+ ConsoleLog("Usage: cheat spawn ()");
+ }
+ }
+ }
+ else
+ {
+ ConsoleLog("Available sub commands:");
+ ConsoleLog("cheat money ");
+ ConsoleLog("cheat keys ");
+ ConsoleLog("cheat spawn ()");
+ ConsoleLog("cheat allgadgets");
+ }
+ }
+ break;
+ case "tp":
+ {
+ if (args.Length < 1 || args.Length > 2)
+ {
+ ConsoleLog("Usage: tp <(optional)target:username> ");
+ return;
+ }
+
+ //mark target and destination seperately
+ string target = args.Length == 2 ? args[0] : "";
+ string destination = args.Length == 2 ? args[1] : args[0];
+
+ //mark target transform location
+ PacketPlayerPosition packet = null;
+ string destSummary = "";
+
+ //first check distination
+ switch (destination.ToLower())
+ {
+ case "home":
+
+ var home = SRSingleton.Instance.GetWakeUpDestination();
+ packet = new PacketPlayerPosition()
+ {
+ Position = home.transform.position,
+ Rotation = home.transform.eulerAngles.y,
+ RegionSet = (byte)home.GetRegionSetId()
+ };
+
+ destSummary = "Home";
+ break;
+ default: //check for a player name
+ var play = Globals.Players.Values.FirstOrDefault(p => p.Username.Equals(destination, StringComparison.CurrentCultureIgnoreCase));
+
+ if (play == null)
+ {
+ ConsoleLog("Destination not found");
+ return;
+ }
+ packet = new PacketPlayerPosition()
+ {
+ Position = play.transform.position,
+ Rotation = play.transform.eulerAngles.y,
+ RegionSet = (byte)play.CurrentRegionSet
+ };
+ destSummary = play.Username;
+ break;
+ }
+
+
+ if (packet != null)
+ {
+ //set as not load destination
+ packet.OnLoad = false;
+
+ NetworkPlayer targetPlayer = null;
+ if (target.Length > 0)
+ {
+ targetPlayer = Globals.Players.Values.FirstOrDefault(p => p.Username.Equals(target, StringComparison.CurrentCultureIgnoreCase));
+ }
+ else
+ {
+ targetPlayer = Globals.LocalPlayer;
+ }
+ //check if target is local user
+ if (targetPlayer == null)
+ {
+ ConsoleLog("Target Player not found");
+ return;
+ }
+
+ ConsoleLog("Teleporting " + targetPlayer.Username + " to " + destSummary);
+
+ if (!targetPlayer.IsLocal)
+ {
+ //if a target is located and is not the local player send the teleport command
+ packet.ID = targetPlayer.ID;
+ packet.WeaponY = targetPlayer.GetWeaponLocation();
+ packet.Send();
+ return;
+ }
+ else
+ {
+ //if we have have made it here the tp in question is for the instances player
+ //so move that player
+ SRSingleton.Instance.player.transform.position = packet.Position;
+ SRSingleton.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
+ SRSingleton.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
+ // play the teleport animation
+ SRSingleton.Instance.PlayTeleport();
+ }
+
+ }
+ else
+ {
+ ConsoleLog("Destination not found");
+ }
+
+ }
+ break;
+ case "listplayers":
+ {
+ ConsoleLog("Players:");
+ foreach (var player in Globals.Players.Values)
+ {
+ SRMP.Log(player.Username);
+ }
+ }
+ break;
+ case "sleep":
+ {
+ if (args.Length == 1)
+ {
+ SRSingleton.Instance.TimeDirector.FastForwardTo(SRSingleton.Instance.TimeDirector.HoursFromNow(float.Parse(args[0])));
+ ConsoleLog("Sleeoing for " + args[0] + " hours");
+ }
+ else
+ {
+ ConsoleLog("Usage: sleep ");
+ }
+ }
+ break;
+ case "console": //add toggle option for turning on and off logging types
+
+ if (args.Length > 1 && (args[0] == "enable" || args[0] == "disable"))
+ {
+ bool enable = args[0] == "enable";
+ //double check type
+ if (Enum.TryParse(args[1], true, out LogType logType)) //check for main log type
+ {
+ if (enable)
+ {
+ if (!blockMessages.Contains(logType)) blockMessages.Remove(logType);
+ ConsoleLog(logType.ToString() + " Messages Enabled");
+ }
+ else
+ {
+ if (blockMessages.Contains(logType)) blockMessages.Add(logType);
+ ConsoleLog("[Console] " + logType.ToString() + " Messages Disabled");
+ }
+ }
+ else if (Enum.TryParse(args[1], true, out LogItems logMessage)) //check for log message item types
+ {
+ if (enable)
+ {
+ if (!blockLogs.Contains(logMessage)) blockLogs.Remove(logMessage);
+ ConsoleLog(logMessage.ToString() + " Log Messages Enabled");
+ }
+ else
+ {
+ if (blockLogs.Contains(logMessage)) blockLogs.Add(logMessage);
+ ConsoleLog(logMessage.ToString() + " Log Messages Disabled");
+ }
+ }
+ else if (args[1].Equals("stacktrace", StringComparison.InvariantCultureIgnoreCase) || args[1].Equals("stack_trace", StringComparison.InvariantCultureIgnoreCase))
+ {
+ if (enable)
+ {
+ DisplayTrace = true;
+ ConsoleLog("Stack Trace Information Enabled");
+ }
+ else
+ {
+ DisplayTrace = false;
+ ConsoleLog("Stack Trace Information Disabled");
+ }
+ }
+ else
+ {
+ ConsoleLog("Invalid Feed back Type");
+ ConsoleLog("Valid Types: ");
+ ConsoleLog(string.Join(", ", Enum.GetValues(typeof(LogType))));
+ ConsoleLog(string.Join(", ", Enum.GetValues(typeof(LogItems))));
+ }
+ }
+ else
+ {
+ ConsoleLog("Usage: console ");
+ }
+ break;
+
+ }
+ }
+
+ //
+ // Update the input every frame
+ // This gets new key input and calls the OnInputText callback
+ //
+ void Update()
+ {
+ input.Update();
+ }
+
+ //
+ // It's important to call console.ShutDown in OnDestroy
+ // because compiling will error out in the editor if you don't
+ // because we redirected output. This sets it back to normal.
+ //
+ void OnDestroy()
+ {
+ console.Shutdown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/SRMP/ChatUI.cs b/SRMP/Custom UI/ChatUI.cs
similarity index 75%
rename from SRMP/ChatUI.cs
rename to SRMP/Custom UI/ChatUI.cs
index 9518920..7f10ffa 100644
--- a/SRMP/ChatUI.cs
+++ b/SRMP/Custom UI/ChatUI.cs
@@ -13,7 +13,11 @@ public class ChatUI : SRSingleton
private float fadeTime;
private List messages = new List();
private Vector2 chatScroll;
+ int maxWidth = 290;
+ ///
+ /// create a chat message to be displayed
+ ///
public class ChatMessage
{
public string Text;
@@ -27,52 +31,68 @@ public class ChatUI : SRSingleton
Time = DateTime.Now;
}
}
-
+ ///
+ /// On chat ui update triggered, handle it
+ ///
private void Update()
{
+ //only display chat if in multiplayer mode
if (!Globals.IsMultiplayer)
{
openChat = false;
message = "";
return;
}
-
+ //if enter is pressed start chat typing mode
if (Input.GetKeyUp(KeyCode.Return))
{
StartCoroutine(FocusChat());
}
}
-
+ ///
+ /// Crreate the Chat gui
+ ///
private void OnGUI()
{
+ //only mess with the gui in multiplayer mode
if (!Globals.IsMultiplayer) return;
if (openChat)
{
- GUILayout.BeginArea(new Rect(20, Screen.height / 2, 500, 300), GUI.skin.box);
+ //draw chat area
+ GUILayout.BeginArea(new Rect(20, Screen.height / 2, maxWidth + 10, 300), GUI.skin.box);
chatScroll = GUILayout.BeginScrollView(chatScroll);
var skin = GUI.skin.box;
skin.wordWrap = true;
skin.alignment = TextAnchor.MiddleLeft;
+
+ //add each mesage into the chat box scroller
foreach (var msg in messages)
{
- GUILayout.Label(wrapString(msg.Text, 490), skin, GUILayout.MaxWidth(490));
+ GUILayout.Label(wrapString(msg.Text, maxWidth), skin, GUILayout.MaxWidth(maxWidth));
}
GUILayout.EndScrollView();
+
+ //add display for text input area
GUI.SetNextControlName("ChatInput");
message = GUILayout.TextField(message);
GUILayout.EndArea();
+ //focus the input
GUI.FocusControl("ChatInput");
+ //watch for changes to the text input
Event e = Event.current;
if (e.rawType == EventType.KeyUp && e.keyCode == KeyCode.Return)
{
+ //on send close chat
openChat = !openChat;
if (!string.IsNullOrWhiteSpace(message))
{
+ //if server send message to all plauers
if (Globals.IsServer)
{
+ //if server send it to the server
AddChatMessage(Globals.Username + ": " + message);
new PacketPlayerChat()
{
@@ -81,6 +101,7 @@ public class ChatUI : SRSingleton
}
else
{
+ //if player send it to the server
new PacketPlayerChat()
{
message = message
@@ -90,13 +111,16 @@ public class ChatUI : SRSingleton
}
}
}
- else
+ else //if chat isnt open yet
{
- GUILayout.BeginArea(new Rect(20, Screen.height / 2, 500, 300));
+ //draw chat area
+ GUILayout.BeginArea(new Rect(20, Screen.height / 2, maxWidth+ 10, 300));
chatScroll = GUILayout.BeginScrollView(chatScroll);
var skin = GUI.skin.box;
skin.wordWrap = true;
skin.alignment = TextAnchor.MiddleLeft;
+
+ //add each mesage into the chat box scroller
foreach (var msg in messages)
{
if (msg.FadeTime > 0f)
@@ -105,26 +129,34 @@ public class ChatUI : SRSingleton
var c = GUI.color;
c.a = (msg.FadeTime / 5f);
GUI.color = c;
- GUILayout.Label(wrapString(msg.Text, 490), skin, GUILayout.MaxWidth(490));
+ GUILayout.Label(wrapString(msg.Text, maxWidth), skin, GUILayout.MaxWidth(maxWidth));
}
}
GUILayout.EndScrollView();
GUILayout.EndArea();
}
}
-
+ ///
+ /// Add a chat message to be displayed
+ ///
+ /// Message to display
public void AddChatMessage(string message)
{
fadeTime = 10f;
messages.Add(new ChatMessage(message));
chatScroll = new Vector2(0, 100000);
}
-
+ ///
+ /// Trigger a full clear of the chat
+ ///
public void Clear()
{
messages.Clear();
}
+ ///
+ /// Trigger focus on the chat box for when the uer hits enter
+ ///
private IEnumerator FocusChat()
{
yield return new WaitForEndOfFrame();
@@ -133,6 +165,12 @@ public class ChatUI : SRSingleton
GUI.FocusControl("ChatInput");
}
+ ///
+ /// Create the wrapped string to display in the chat box
+ ///
+ /// Message to display
+ /// Width of the chat box
+ ///
string wrapString(string msg, int width)
{
string[] words = msg.Split(" "[0]);
diff --git a/SRMP/MultiplayerUI.cs b/SRMP/Custom UI/MultiplayerUI.cs
similarity index 57%
rename from SRMP/MultiplayerUI.cs
rename to SRMP/Custom UI/MultiplayerUI.cs
index b48b521..a3940a4 100644
--- a/SRMP/MultiplayerUI.cs
+++ b/SRMP/Custom UI/MultiplayerUI.cs
@@ -8,18 +8,38 @@ using SRMultiplayer.Networking;
public class MultiplayerUI : SRSingleton
{
- private Rect windowRect = new Rect(Screen.width - 300, 20, 300, 500);
+ private Rect windowRect = new Rect(Screen.width - 300 - 20, 20, 300, 500);
private Vector2 playersScroll = Vector2.zero;
private string ipaddress = "localhost";
private string port = "16500";
private string servercode = "";
- private bool menuOpen;
+
+ //use internal name with getter and setter to allow the menu panel to remember the users last choice
+ private int _menuOpen;
+ private int menuOpen //menu open hold the current menu state (0 colapsed, 1 minimized, 2 open)
+ {
+ get
+ {
+ return _menuOpen;
+ }
+ set
+ {
+ _menuOpen = value;
+
+ //save users setting
+ PlayerPrefs.SetInt("SRMP_Menu", menuOpen);
+ }
+ }
+
+
private string username;
private float lastCodeUse;
private ConnectError error;
private ConnectHelp help;
private string errorMessage;
+
+
public enum ConnectError
{
None,
@@ -36,65 +56,228 @@ public class MultiplayerUI : SRSingleton
Hosting,
}
+ ///
+ /// Creation of gui with side panel is last display state
+ ///
public override void Awake()
{
base.Awake();
+ //set default ui location width adapting numbers for smaller resolutions
+ float width = 300;
+ if (Screen.width / 4 < width) width = Screen.width / 4;
+ windowRect = new Rect(Screen.width - width - 20, 20, width, 500);
+
Globals.Username = PlayerPrefs.GetString("SRMP_Username", "");
ipaddress = PlayerPrefs.GetString("SRMP_IP", "localhost");
port = PlayerPrefs.GetString("SRMP_Port", "16500");
- menuOpen = true;
+ menuOpen = PlayerPrefs.GetInt("SRMP_Menu", 2); ; //start panel open by default
+
username = Globals.Username;
}
+ ///
+ /// Update of panel display
+ ///
private void Update()
{
- if(lastCodeUse > 0f)
+ if (lastCodeUse > 0f)
{
var prevTime = lastCodeUse;
lastCodeUse -= Time.deltaTime;
- if(prevTime > 0f && lastCodeUse <= 0f)
+ if (prevTime > 0f && lastCodeUse <= 0f)
{
error = ConnectError.ServerCodeTimeout;
}
}
- if(Input.GetKeyDown(KeyCode.F4))
+
+ //this sets presskey senarios
+ if (Input.GetKeyDown(KeyCode.F4))
{
- menuOpen = !menuOpen;
+ //use the f4 key to swap between collapsed and minimized
+ menuOpen = menuOpen == 2 ? 0 : 2;
+ }
+ if (Input.GetKeyDown(KeyCode.F3))
+ {
+ //use the f3 key to set minimized or maximized
+ menuOpen = menuOpen < 2 ? 2 : 1;
}
}
-
+ ///
+ /// Handle draw event of the gui
+ ///
private void OnGUI()
{
- if (!menuOpen || (!Levels.isMainMenu() && !Globals.IsMultiplayer && Globals.PauseState != PauseState.Pause)) return;
+ //verify on a window that the menu can be drawn on
+ if ((!Levels.isMainMenu() && !Globals.IsMultiplayer && Globals.PauseState != PauseState.Pause)) return;
if (Globals.IsMultiplayer && Globals.PauseState != PauseState.Pause) return;
+ //if yes draw the window for the given state
if (SceneManager.GetActiveScene().buildIndex >= 2)
{
- windowRect = GUI.Window(1, windowRect, MultiplayerWindow, "SRMP v" + Globals.Version);
+ //check to make sure the panel is taking less than 25% of the screen if possible
+ float width = 300;
+ if(Screen.width/ 4 < width) width = Screen.width/4;
+ windowRect.width = width;
+
+ //check to see if the windows needs to move due to it being off the screen from size change
+ //also prevent the user from dragging it off the screen
+ if (windowRect.x + 20 + windowRect.width > Screen.width) windowRect.x = Screen.width - windowRect.width - 20;
+ if (windowRect.y + 20 + windowRect.height > Screen.height) windowRect.y = (Screen.height - windowRect.height - 20) >= 20 ? (Screen.height - windowRect.height - 20) : 20;
+ if (windowRect.x < 20) windowRect.x = 20;
+ if (windowRect.y < 20) windowRect.y = 20;
+
+
+
+ //drawn in the window
+ switch (menuOpen)
+ {
+ case 0: //collapsed
+ windowRect.height = 50;
+ windowRect = GUILayout.Window(1, windowRect, ClosedWindow, "SRMP v" + Globals.Version);
+ break;
+ case 1: //minimized
+ windowRect.height = 100;
+ windowRect = GUILayout.Window(1, windowRect, MiniWindow, "SRMP v" + Globals.Version);
+ break;
+ case 2: //open
+ windowRect.height = 500;
+ windowRect = GUILayout.Window(1, windowRect, MultiplayerWindow, "SRMP v" + Globals.Version);
+ break;
+ }
+
+
}
}
+ ///
+ /// display for the function keyps section of the gui
+ ///
+ private void FunctionKeys()
+ {
+ if (menuOpen != 0)
+ {
+ GUILayout.Label("Press Button or Key To Change Style");
+ }
+ GUILayout.BeginHorizontal();
+ if (GUILayout.Button(menuOpen == 1 ? "F3 - Full" : "F3 - Mini"))
+ {
+ menuOpen = menuOpen == 1 ? 2 : 1;
+ }
+ GUILayout.FlexibleSpace();
+ if (GUILayout.Button(menuOpen == 0 ? "F4 - Full" : "F4 - Colapsed"))
+ {
+ menuOpen = menuOpen == 0 ? 2 : 0;
+ }
+ GUILayout.EndHorizontal();
+ }
+ ///
+ /// Sets the window display for collapsed
+ /// Only activated if the id is the id for the window
+ ///
+ private void ClosedWindow(int id)
+ {
+ if (id != 1) return;
+ //display f3 and f4 commands
+ FunctionKeys();
+ GUI.DragWindow(new Rect(0, 0, 10000, 10000));
+ }
+ ///
+ /// Sets the window display for summary mode
+ /// Only activated if the id is the id for the window
+ ///
+ private void MiniWindow(int id)
+ {
+ if (id != 1) return;
+
+ //display f3 and f4 commands
+ FunctionKeys();
+
+ //show username and current connection status
+ GUIStyle standard = new GUIStyle(GUI.skin.label);
+ GUIStyle red = new GUIStyle(GUI.skin.label);
+ red.normal.textColor = Color.red;
+
+
+ if (string.IsNullOrWhiteSpace(Globals.Username))
+ {
+ GUILayout.Label("Username: Not Set", red);
+ }
+ else
+ {
+ GUILayout.Label("Username: " + Globals.Username);
+
+ if (Globals.IsServer)
+ {
+ GUILayout.Label("Status: Host");
+ }
+ else if (Globals.IsClient)
+ {
+
+ GUIStyle green = new GUIStyle(GUI.skin.label);
+ green.normal.textColor = Color.green;
+ GUILayout.Label("Status: Client", green);
+ }
+ else
+ {
+ bool canHost = true;
+ //check if user can host the session
+ if (!int.TryParse(port, out int numport) || numport < 1000 || numport > 65000)
+ {
+ canHost = false;
+ }
+
+ GUILayout.BeginHorizontal();
+ GUILayout.Label("Status: Disconnected", red);
+
+ GUILayout.FlexibleSpace();
+ if (canHost)
+ {
+ //only show host if not main menu
+ if (!Levels.isMainMenu())
+ {
+ if (GUILayout.Button("Host"))
+ {
+ NetworkServer.Instance.StartServer(numport);
+ SaveSettings();
+ }
+ }
+ }
+ GUILayout.EndHorizontal();
+ if (!canHost)
+ {
+ GUILayout.Label("Invalid Port Settings", red);
+ }
+ }
+
+ }
+ GUI.DragWindow(new Rect(0, 0, 10000, 10000));
+ }
+ ///
+ /// Sets the window display for full display mode
+ /// Only activated if the id is the id for the window
+ ///
private void MultiplayerWindow(int id)
{
if (id != 1) return;
- GUILayout.Label("You can close this menu with F4");
- GUILayout.Space(20);
+ //display f3 and f4 commands
+ FunctionKeys();
- if(string.IsNullOrWhiteSpace(Globals.Username))
+ //now display standard
+ if (string.IsNullOrWhiteSpace(Globals.Username))
{
UsernameGUI();
}
else
{
- if(Globals.IsServer)
+ if (Globals.IsServer)
{
ServerGUI();
}
- else if(Globals.IsClient)
+ else if (Globals.IsClient)
{
ClientGUI();
}
@@ -104,13 +287,13 @@ public class MultiplayerUI : SRSingleton
{
ErrorGUI();
}
- else if(help != ConnectHelp.None)
+ else if (help != ConnectHelp.None)
{
HelpGUI();
}
else
{
- if(lastCodeUse > 0f)
+ if (lastCodeUse > 0f)
{
GUILayout.Label("Trying to connect with server code...");
}
@@ -129,6 +312,9 @@ public class MultiplayerUI : SRSingleton
GUI.DragWindow(new Rect(0, 0, 10000, 10000));
}
+ ///
+ /// Display the active server info part of the gui
+ ///
private void ServerGUI()
{
GUILayout.Label("You are the server");
@@ -143,7 +329,7 @@ public class MultiplayerUI : SRSingleton
GUILayout.BeginHorizontal();
GUILayout.Label(player.Username);
- if(GUILayout.Button("Kick"))
+ if (GUILayout.Button("Kick"))
{
player.Connection.Disconnect("kicked");
}
@@ -151,7 +337,9 @@ public class MultiplayerUI : SRSingleton
}
GUILayout.EndScrollView();
}
-
+ ///
+ /// Display the client info part of the gui
+ ///
private void ClientGUI()
{
GUILayout.Label("You are a client");
@@ -169,7 +357,11 @@ public class MultiplayerUI : SRSingleton
}
GUILayout.EndScrollView();
}
-
+ ///
+ /// Display the connection information of the gui
+ /// this section includes user information,
+ /// how to and other imbedded sections for handling display
+ ///
private void ConnectGUI()
{
GUILayout.Label("Username: " + Globals.Username);
@@ -179,7 +371,7 @@ public class MultiplayerUI : SRSingleton
return;
}
GUILayout.Space(20);
- if(GUILayout.Button("How do I host a game?"))
+ if (GUILayout.Button("How do I host a game?"))
{
help = ConnectHelp.Hosting;
}
@@ -250,6 +442,9 @@ public class MultiplayerUI : SRSingleton
}
}
+ ///
+ /// Display the hosting info part of the gui
+ ///
private void HostGUI()
{
GUILayout.Label("Username: " + Globals.Username);
@@ -277,10 +472,12 @@ public class MultiplayerUI : SRSingleton
}
}
}
-
+ ///
+ /// Display the Help info part of the gui with instructions for hosting
+ ///
private void HelpGUI()
{
- switch(help)
+ switch (help)
{
case ConnectHelp.ServerCode:
{
@@ -301,10 +498,12 @@ public class MultiplayerUI : SRSingleton
break;
}
}
-
+ ///
+ /// Display the Error summaries in the gui
+ ///
private void ErrorGUI()
{
- switch(error)
+ switch (error)
{
case ConnectError.InvalidServerCode:
{
@@ -354,7 +553,9 @@ public class MultiplayerUI : SRSingleton
break;
}
}
-
+ ///
+ /// Display the Current user information
+ ///
private void UsernameGUI()
{
GUILayout.BeginHorizontal();
@@ -376,14 +577,18 @@ public class MultiplayerUI : SRSingleton
}
}
}
-
+ ///
+ /// Saves the gui settings for the user
+ ///
private void SaveSettings()
{
PlayerPrefs.SetString("SRMP_Username", Globals.Username);
PlayerPrefs.SetString("SRMP_IP", ipaddress);
PlayerPrefs.GetString("SRMP_Port", port);
}
-
+ ///
+ /// Handles connection resonces display when connection is lost from the server
+ ///
public void ConnectResponse(ConnectError connectError, string message = "")
{
lastCodeUse = 0f;
diff --git a/SRMP/TestUI.cs b/SRMP/Custom UI/TestUI.cs
similarity index 95%
rename from SRMP/TestUI.cs
rename to SRMP/Custom UI/TestUI.cs
index 98b7c0c..2998448 100644
--- a/SRMP/TestUI.cs
+++ b/SRMP/Custom UI/TestUI.cs
@@ -8,6 +8,24 @@
//using UnityEngine;
//using UnityEngine.SceneManagement;
+/*
+ * TestUi is a version of the multiplayer ui that adds the following information
+ * Added
+ Chat
+ Cheats
+
+
+ * More stats
+ Quick silver race is active
+ client status
+ server status
+ server code
+ send and recieve sizes
+ packet sizes
+ */
+
+
+
//namespace SRMultiplayer
//{
// class TestUI : SRSingleton
@@ -130,11 +148,11 @@
// {
// SRSingleton.Instance.PlayerState.AddCurrency(1000000);
// }
-// if(GUILayout.Button("Remove all actors"))
+// if (GUILayout.Button("Remove all actors"))
// {
-// foreach(var actor in SRSingleton.Instance.GameModel.AllActors().Values.ToList())
+// foreach (var actor in SRSingleton.Instance.GameModel.AllActors().Values.ToList())
// {
-// if(actor != null && actor.transform != null && actor.transform.gameObject.activeInHierarchy && !Identifiable.SCENE_OBJECTS.Contains(actor.ident))
+// if (actor != null && actor.transform != null && actor.transform.gameObject.activeInHierarchy && !Identifiable.SCENE_OBJECTS.Contains(actor.ident))
// {
// Destroyer.DestroyActor(actor.transform.gameObject, "Get.Removed");
// }
@@ -265,10 +283,10 @@
// {
// try
// {
-// if (GUILayout.Button("Clear " + ident.ToString()))
-// {
+// if (GUILayout.Button("Clear " + ident.ToString()))
+// {
// SRSingleton.Instance.ExchangeDirector.ClearOffer(ident);
-// }
+// }
// }
// catch { }
// }
@@ -535,10 +553,10 @@
// if (Globals.IsMultiplayer)
// {
// QuicksilverEnergyGenerator generator = null;
-// foreach(var region in Globals.LocalPlayer.Regions)
+// foreach (var region in Globals.LocalPlayer.Regions)
// {
// generator = region.GetComponent();
-// if(generator != null)
+// if (generator != null)
// {
// break;
// }
@@ -546,13 +564,13 @@
// GUILayout.Label("Is In Race: " + (generator != null ? generator.id : "None"));
// GUILayout.Label($"Client Status: {NetworkClient.Instance.Status}");
// GUILayout.Label($"Server Status: {NetworkServer.Instance.Status}");
-// if(!string.IsNullOrWhiteSpace(Globals.ServerCode))
+// if (!string.IsNullOrWhiteSpace(Globals.ServerCode))
// {
// GUILayout.Label($"Server Code: {Globals.ServerCode}");
// }
-// //GUILayout.Label("Received Messages: " + SRSingleton.Instance.Statistics.ReceivedMessages);
-// //GUILayout.Label("Send Messages: " + SRSingleton.Instance.Statistics.SentMessages);
+// GUILayout.Label("Received Messages: " + SRSingleton.Instance.Statistics.ReceivedMessages);
+// GUILayout.Label("Send Messages: " + SRSingleton.Instance.Statistics.SentMessages);
// if (NetworkServer.Instance != null && NetworkServer.Instance.Status == NetworkServer.ServerStatus.Running)
// {
@@ -567,7 +585,7 @@
// //GUILayout.Space(20);
// //GUILayout.Label("Chat");
// chatScroll = GUILayout.BeginScrollView(chatScroll, GUI.skin.box);
-// foreach(var sizes in Globals.PacketSize.OrderByDescending(c => c.Value))
+// foreach (var sizes in Globals.PacketSize.OrderByDescending(c => c.Value))
// {
// GUILayout.Label(sizes.Key + ": " + Utils.GetHumanReadableFileSize(sizes.Value));
// }
diff --git a/SRMP/Globals.cs b/SRMP/Globals.cs
index dac99cf..9010532 100644
--- a/SRMP/Globals.cs
+++ b/SRMP/Globals.cs
@@ -11,12 +11,12 @@ namespace SRMultiplayer
{
public static class Globals
{
+
+ //setup global objects for refrence usage
public static int Version;
public static UserData UserData;
public static GameObject BeatrixModel;
public static RuntimeAnimatorController BeatrixController;
- public static GameObject IngameMultiplayerMenuPrefab;
- public static GameObject MainMultiplayerMenuPrefab;
public static Dictionary Players = new Dictionary();
public static string Username;
public static string ServerCode;
@@ -53,6 +53,10 @@ namespace SRMultiplayer
public static List LemonTrees = new List();
public static Dictionary PacketSize = new Dictionary();
+ ///
+ /// get list of current installed mods
+ /// Excluding supporting files
+ ///
public static List Mods
{
get
diff --git a/SRMP/MainSRML.cs b/SRMP/MainSRML.cs
index d37551a..898d534 100644
--- a/SRMP/MainSRML.cs
+++ b/SRMP/MainSRML.cs
@@ -14,6 +14,10 @@ using UnityEngine;
namespace SRMultiplayer
{
+ ///
+ /// Handles mod being loaded from SRML
+ /// Takes the place of the Main Standalone file, but caters to the SRML
+ ///
public class MainSRML : ModEntryPoint
{
private static GameObject m_GameObject;
@@ -35,10 +39,12 @@ namespace SRMultiplayer
SRMP.Log("Loading SRMP SRML Version");
+ //create the mod directory in the install folder if needed
if (!Directory.Exists(SRMP.ModDataPath))
{
Directory.CreateDirectory(SRMP.ModDataPath);
}
+ //create the user data file if not created yet
if (!File.Exists(Path.Combine(SRMP.ModDataPath, "userdata.json")))
{
Globals.UserData = new UserData()
@@ -50,7 +56,7 @@ namespace SRMultiplayer
File.WriteAllText(Path.Combine(SRMP.ModDataPath, "userdata.json"), JsonConvert.SerializeObject(Globals.UserData));
SRMP.Log("Created userdata with UUID " + Globals.UserData.UUID);
}
- else
+ else //if alreayd created load in the data
{
Globals.UserData = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine(SRMP.ModDataPath, "userdata.json")));
if(Globals.UserData.IgnoredMods == null)
@@ -60,6 +66,7 @@ namespace SRMultiplayer
SRMP.Log("Loaded userdata with UUID " + Globals.UserData.UUID);
}
+ //create the mods main game objects and start connecting everything
string[] args = System.Environment.GetCommandLineArgs();
m_GameObject = new GameObject("SRMP");
@@ -71,12 +78,16 @@ namespace SRMultiplayer
m_GameObject.AddComponent();
m_GameObject.AddComponent();
+ //mark all mod objects and do not destroy
GameObject.DontDestroyOnLoad(m_GameObject);
+ //get current mod version
Globals.Version = Assembly.GetExecutingAssembly().GetName().Version.Revision;
+ //mark the mod as a background task
Application.runInBackground = true;
+ //initialize connect to the harmony patcher
HarmonyPatcher.GetInstance().PatchAll(Assembly.GetExecutingAssembly());
}
diff --git a/SRMP/MainStandalone.cs b/SRMP/MainStandalone.cs
index f769e4f..274ec8a 100644
--- a/SRMP/MainStandalone.cs
+++ b/SRMP/MainStandalone.cs
@@ -8,7 +8,9 @@ using UnityCoreMod;
using UnityEngine;
namespace SRMultiplayer
-{
+{ //
+ /// Handles mod being loaded from directly without the mod loader
+ ///
public class MainSaty : IUnityMod
{
private static GameObject m_GameObject;
@@ -19,10 +21,12 @@ namespace SRMultiplayer
SRMP.Log("Loading SRMP Standalone Version");
+ //create the mod directory in the install folder if needed
if (!Directory.Exists(SRMP.ModDataPath))
{
Directory.CreateDirectory(SRMP.ModDataPath);
}
+ //create the user data file if not created yet
if (!File.Exists(Path.Combine(SRMP.ModDataPath, "userdata.json")))
{
Globals.UserData = new UserData()
@@ -34,8 +38,9 @@ namespace SRMultiplayer
File.WriteAllText(Path.Combine(SRMP.ModDataPath, "userdata.json"), JsonConvert.SerializeObject(Globals.UserData));
SRMP.Log("Created userdata with UUID " + Globals.UserData.UUID);
}
- else
+ else //if alreayd created load in the data
{
+
Globals.UserData = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine(SRMP.ModDataPath, "userdata.json")));
if(Globals.UserData.IgnoredMods == null)
{
@@ -44,6 +49,7 @@ namespace SRMultiplayer
SRMP.Log("Loaded userdata with UUID " + Globals.UserData.UUID);
}
+ //create the mods main game objects and start connecting everything
string[] args = System.Environment.GetCommandLineArgs();
m_GameObject = new GameObject("SRMP");
@@ -55,13 +61,17 @@ namespace SRMultiplayer
m_GameObject.AddComponent();
m_GameObject.AddComponent();
+ //mark all mod objects and do not destroy
GameObject.DontDestroyOnLoad(m_GameObject);
+ //get current mod version
Globals.Version = Assembly.GetExecutingAssembly().GetName().Version.Revision;
+ //initialize harmony and init the patches
var harmony = new Harmony("saty.mod.srmp");
harmony.PatchAll(Assembly.GetExecutingAssembly());
+ //mark the mod as a background task
Application.runInBackground = true;
}
diff --git a/SRMP/Networking/NetworkClient.cs b/SRMP/Networking/Communication/NetworkClient.cs
similarity index 100%
rename from SRMP/Networking/NetworkClient.cs
rename to SRMP/Networking/Communication/NetworkClient.cs
diff --git a/SRMP/Networking/NetworkHandlerClient.cs b/SRMP/Networking/Communication/NetworkHandlerClient.cs
similarity index 92%
rename from SRMP/Networking/NetworkHandlerClient.cs
rename to SRMP/Networking/Communication/NetworkHandlerClient.cs
index ae0119f..29a5fa7 100644
--- a/SRMP/Networking/NetworkHandlerClient.cs
+++ b/SRMP/Networking/Communication/NetworkHandlerClient.cs
@@ -1,16 +1,12 @@
-using Assets.Script.Util.Extensions;
-using DG.Tweening;
+using DG.Tweening;
using Lidgren.Network;
using MonomiPark.SlimeRancher.DataModel;
-using MonomiPark.SlimeRancher.Persist;
using MonomiPark.SlimeRancher.Regions;
using SRMultiplayer.Packets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using UnityEngine;
namespace SRMultiplayer.Networking
@@ -24,22 +20,24 @@ namespace SRMultiplayer.Networking
Globals.PacketSize[type] += im.LengthBytes;
switch (type)
{
+ //Player amimations
+ case PacketType.PlayerAnimation: OnPlayerAnimation(new PacketPlayerAnimation(im)); break;
+
//Players
case PacketType.PlayerJoined: OnPlayerJoined(new PacketPlayerJoined(im)); break;
case PacketType.PlayerLeft: OnPlayerLeft(new PacketPlayerLeft(im)); break;
case PacketType.PlayerLoaded: OnPlayerLoaded(new PacketPlayerLoaded(im)); break;
case PacketType.PlayerPosition: OnPlayerPosition(new PacketPlayerPosition(im)); break;
- case PacketType.PlayerAnimationLayer: OnPlayerAnimationLayer(im); break;
- case PacketType.PlayerAnimationParameters: OnPlayerAnimationParameters(im); break;
- case PacketType.PlayerAnimationSpeed: OnPlayerAnimationSpeed(im); break;
case PacketType.PlayerFX: OnPlayerFX(new PacketPlayerFX(im)); break;
case PacketType.PlayerCurrency: OnPlayerCurrency(new PacketPlayerCurrency(im)); break;
case PacketType.PlayerCurrencyDisplay: OnPlayerCurrencyDisplay(new PacketPlayerCurrencyDisplay(im)); break;
case PacketType.PlayerUpgrade: OnPlayerUpgrade(new PacketPlayerUpgrade(im)); break;
case PacketType.PlayerUpgradeUnlock: OnPlayerUpgradeUnlock(new PacketPlayerUpgradeUnlock(im)); break;
case PacketType.PlayerChat: OnPlayerChat(new PacketPlayerChat(im)); break;
+
// Region
case PacketType.RegionOwner: OnRegionOwner(new PacketRegionOwner(im)); break;
+
//Actors
case PacketType.Actors: OnActors(new PacketActors(im)); break;
case PacketType.ActorSpawn: OnActorSpawn(new PacketActorSpawn(im)); break;
@@ -153,7 +151,7 @@ namespace SRMultiplayer.Networking
case PacketType.RaceTime: OnRaceTime(new PacketRaceTime(im)); break;
case PacketType.RaceTrigger: OnRaceTrigger(new PacketRaceTrigger(im)); break;
default:
- SRMP.Log($"Got unhandled packet: {type}");
+ SRMP.Log($"Got unhandled packet: {type} " + Enum.GetName(typeof(PacketType), type));
break;
}
}
@@ -274,7 +272,7 @@ namespace SRMultiplayer.Networking
private static void OnFireColumnActivate(PacketFireColumnActivate packet)
{
- if(Globals.FireColumns.TryGetValue(packet.ID, out NetworkFireColumn netColumn))
+ if (Globals.FireColumns.TryGetValue(packet.ID, out NetworkFireColumn netColumn))
{
netColumn.Column.ActivateFire();
}
@@ -321,9 +319,9 @@ namespace SRMultiplayer.Networking
private static void OnOasis(PacketOasis packet)
{
- foreach(var oasisData in packet.Oasis)
+ foreach (var oasisData in packet.Oasis)
{
- if(SRSingleton.Instance.GameModel.AllOases().TryGetValue(oasisData.ID, out OasisModel model))
+ if (SRSingleton.Instance.GameModel.AllOases().TryGetValue(oasisData.ID, out OasisModel model))
{
model.isLive = oasisData.Model.isLive;
@@ -337,30 +335,51 @@ namespace SRMultiplayer.Networking
#region Exchanges
private static void OnExchangeTryAccept(PacketExchangeTryAccept packet)
{
+ //get the exchange type
var type = (ExchangeDirector.OfferType)packet.Type;
+ //check if current scene (view) contains the item in question
if (SRSingleton.Instance.ExchangeDirector.worldModel.currOffers.ContainsKey(type))
{
+ //handle the scene changes for the given offer
var offer = SRSingleton.Instance.ExchangeDirector.worldModel.currOffers[type];
+ //cycle through requested items
foreach (ExchangeDirector.RequestedItemEntry requestedItemEntry in offer.requests)
{
+ //check if the item can be accespted
+ //is on the board and not already completed
if (requestedItemEntry.id == (Identifiable.Id)packet.ID && !requestedItemEntry.IsComplete())
{
+ //mark submit to log
SRMP.Log($"Exchange TryAccept for {(Identifiable.Id)packet.ID} ({(ExchangeDirector.OfferType)packet.Type}", "SERVER");
+ //mark progress
requestedItemEntry.progress++;
+
+ //if the given item completes the necesary quantity
if (offer.IsComplete())
{
- foreach(var rewarder in Resources.FindObjectsOfTypeAll())
+ foreach (var rewarder in Resources.FindObjectsOfTypeAll())
{
rewarder.AwardIfType(type);
}
- SRSingleton.Instance.ExchangeDirector.ClearOffer(type);
+
+ //trigger fireworks
+ //get ExchangeEjector
+ foreach (var eject in Resources.FindObjectsOfTypeAll())
+ {
+ //send off fireworks
+ SRBehaviour.InstantiateDynamic(eject.awardFX, eject.awardAt.position, eject.awardAt.rotation);
+ }
+
+ //dont clear out the offer yet, we arent done with it
+ //SRSingleton.Instance.ExchangeDirector.ClearOffer(type);
}
+
+ //trigger offer status changed
SRSingleton.Instance.ExchangeDirector.OfferDidChange();
}
}
}
}
-
private static void OnExchangePrepareDaily(PacketExchangePrepareDaily packet)
{
SRSingleton.Instance.ExchangeDirector.worldModel.pendingOfferRancherIds = packet.pendingOfferRancherIds;
@@ -414,7 +433,7 @@ namespace SRMultiplayer.Networking
private static void OnTreasurePods(PacketTreasurePods packet)
{
- foreach(var pod in packet.TreasurePods)
+ foreach (var pod in packet.TreasurePods)
{
if (SRSingleton.Instance.GameModel.AllPods().TryGetValue(pod.ID, out TreasurePodModel model))
{
@@ -446,7 +465,7 @@ namespace SRMultiplayer.Networking
if (model.HasAttached())
{
var netDrone = model.attached.transform.GetComponentInChildren(true);
- if(netDrone != null)
+ if (netDrone != null)
{
netDrone.PositionRotationUpdate(packet.Position, packet.Rotation, false);
}
@@ -675,7 +694,7 @@ namespace SRMultiplayer.Networking
extractor.nextProduceTime = packet.nextProduceTime;
extractor.queuedToProduce = packet.queuedToProduce;
- if(extractor.cyclesRemaining <= 0)
+ if (extractor.cyclesRemaining <= 0)
{
var extractorScript = extractor.transform.GetComponent();
if (extractorScript != null && extractorScript.gameObject.activeInHierarchy)
@@ -770,7 +789,7 @@ namespace SRMultiplayer.Networking
private static void OnGadgets(PacketGadgets packet)
{
List regions = new List();
- foreach(var gadgetData in packet.Gadgets)
+ foreach (var gadgetData in packet.Gadgets)
{
if (SRSingleton.Instance.GameModel.AllGadgetSites().TryGetValue(gadgetData.ID, out GadgetSiteModel model))
{
@@ -823,7 +842,7 @@ namespace SRMultiplayer.Networking
}
}
- foreach(var region in regions)
+ foreach (var region in regions)
{
if (Globals.Regions.TryGetValue(region, out NetworkRegion netRegion))
{
@@ -881,7 +900,7 @@ namespace SRMultiplayer.Networking
private static void OnPuzzleSlots(PacketPuzzleSlots packet)
{
- foreach(var puzzleSlotData in packet.PuzzleSlots)
+ foreach (var puzzleSlotData in packet.PuzzleSlots)
{
if (SRSingleton.Instance.GameModel.AllSlots().TryGetValue(puzzleSlotData.ID, out PuzzleSlotModel model))
{
@@ -919,7 +938,7 @@ namespace SRMultiplayer.Networking
private static void OnGordos(PacketGordos packet)
{
- foreach(var gordoData in packet.Gordos)
+ foreach (var gordoData in packet.Gordos)
{
if (SRSingleton.Instance.GameModel.AllGordos().TryGetValue(gordoData.ID, out GordoModel model))
{
@@ -959,7 +978,7 @@ namespace SRMultiplayer.Networking
private static void OnAccessDoors(PacketAccessDoors packet)
{
- foreach(var doorData in packet.Doors)
+ foreach (var doorData in packet.Doors)
{
if (SRSingleton.Instance.GameModel.AllDoors().TryGetValue(doorData.ID, out AccessDoorModel model))
{
@@ -1216,7 +1235,7 @@ namespace SRMultiplayer.Networking
}
var phaseSiteDirector = GameObject.FindObjectOfType();
- if(phaseSiteDirector != null)
+ if (phaseSiteDirector != null)
{
phaseSiteDirector.ResetAllSites();
foreach (PhaseSite phaseSite in new List(phaseSiteDirector.availablePhaseSites))
@@ -1295,7 +1314,7 @@ namespace SRMultiplayer.Networking
private static void OnLandPlotSiloAmmoAdd(PacketLandPlotSiloAmmoAdd packet)
{
- if(NetworkAmmo.All.TryGetValue(packet.ID, out NetworkAmmo ammo))
+ if (NetworkAmmo.All.TryGetValue(packet.ID, out NetworkAmmo ammo))
{
ammo.MaybeAddToSpecificSlot((Identifiable.Id)packet.Ident, null, packet.Slot, packet.Count, packet.Overflow);
SRMP.Log($"NetworkAmmo add slot {packet.Slot} (Type: {(Identifiable.Id)packet.Ident} - Count: {packet.Count}) for {packet.ID}", "CLIENT");
@@ -1488,7 +1507,7 @@ namespace SRMultiplayer.Networking
private static void OnLandPlots(PacketLandplots packet)
{
- foreach(var plotData in packet.LandPlots)
+ foreach (var plotData in packet.LandPlots)
{
if (SRSingleton.Instance.GameModel.AllLandPlots().TryGetValue(plotData.ID, out LandPlotModel model))
{
@@ -1538,7 +1557,7 @@ namespace SRMultiplayer.Networking
{
var type = (PacketActorFX.FXType)packet.Type;
var slimeEat = netActor.GetComponentInChildren();
- if(slimeEat != null)
+ if (slimeEat != null)
{
if (type == PacketActorFX.FXType.SlimeEatFavoriteFX)
{
@@ -1748,7 +1767,7 @@ namespace SRMultiplayer.Networking
private static void OnActors(PacketActors packet)
{
- foreach(var actorData in packet.Actors)
+ foreach (var actorData in packet.Actors)
{
if (!Globals.Actors.ContainsKey(actorData.ID))
{
@@ -1809,7 +1828,7 @@ namespace SRMultiplayer.Networking
Globals.Actors.Add(netActor.ID, netActor);
}
- catch(Exception ex)
+ catch (Exception ex)
{
SRMP.Log($"Could not create actor {actorData.ID}: {ex}");
}
@@ -1906,30 +1925,23 @@ namespace SRMultiplayer.Networking
}
}
- private static void OnPlayerAnimationSpeed(NetIncomingMessage im)
+ private static void OnPlayerAnimation(PacketPlayerAnimation packet)
{
- byte id = im.ReadByte();
- if (Globals.Players.TryGetValue(id, out NetworkPlayer player) && player.HasLoaded)
- {
- player.ReadAnimatorSpeed(im);
- }
- }
+ //handle character animation triggers
+ PacketPlayerAnimation.AnimationType type = (PacketPlayerAnimation.AnimationType)packet.Type;
- private static void OnPlayerAnimationParameters(NetIncomingMessage im)
- {
- byte id = im.ReadByte();
- if (Globals.Players.TryGetValue(id, out NetworkPlayer player) && player.HasLoaded)
- {
- player.ReadParameters(im);
- }
- }
- private static void OnPlayerAnimationLayer(NetIncomingMessage im)
- {
- byte id = im.ReadByte();
- if (Globals.Players.TryGetValue(id, out NetworkPlayer player) && player.HasLoaded)
+
+ if (Globals.Players.TryGetValue(packet.ID, out NetworkPlayer player) && player.HasLoaded)
{
- player.ReadAnimatorLayer(im);
+ if(type == PacketPlayerAnimation.AnimationType.Speed)
+ player.ReadAnimatorSpeed(packet.internalData);
+ else if (type == PacketPlayerAnimation.AnimationType.Parameters)
+ {
+ player.ReadParameters(packet.internalData);
+ }
+ else
+ player.ReadAnimatorLayer(packet.internalData);
}
}
@@ -1941,57 +1953,74 @@ namespace SRMultiplayer.Networking
{
if (player.IsLocal)
{
- var euler = SRSingleton.Instance.player.GetComponentInChildren().transform.eulerAngles;
- euler.x = packet.WeaponY;
- SRSingleton.Instance.player.GetComponentInChildren().transform.eulerAngles = euler;
- SRSingleton.Instance.player.transform.position = packet.Position;
- SRSingleton.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
- SRSingleton.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
-
- if (!Globals.IsServer)
+ if (packet.OnLoad)
{
- try
+
+ var euler = SRSingleton.Instance.player.GetComponentInChildren().transform.eulerAngles;
+ euler.x = packet.WeaponY;
+ SRSingleton.Instance.player.GetComponentInChildren().transform.eulerAngles = euler;
+ SRSingleton.Instance.player.transform.position = packet.Position;
+ SRSingleton.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
+ SRSingleton.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
+
+
+ //only reload inventory if this is a load up packet and NOT a tp packet
+ if (!Globals.IsServer)
{
- using (FileStream file = new FileStream(Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player"), FileMode.Open))
+ try
{
- using (BinaryReader reader = new BinaryReader(file))
+ using (FileStream file = new FileStream(Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player"), FileMode.Open))
{
- Debug.Log($"Loading {Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player")}");
- var ammoCount = reader.ReadInt32();
- for (int i = 0; i < ammoCount; i++)
+ using (BinaryReader reader = new BinaryReader(file))
{
- var state = (PlayerState.AmmoMode)reader.ReadByte();
- SRSingleton.Instance.PlayerState.model.ammoDict[state].usableSlots = reader.ReadInt32();
- var slotCount = reader.ReadInt32();
- SRSingleton.Instance.PlayerState.model.ammoDict[state].slots = new Ammo.Slot[slotCount];
- for (int j = 0; j < slotCount; j++)
+ Debug.Log($"Loading {Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player")}");
+ var ammoCount = reader.ReadInt32();
+ for (int i = 0; i < ammoCount; i++)
{
- if(reader.ReadBoolean())
+ var state = (PlayerState.AmmoMode)reader.ReadByte();
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].usableSlots = reader.ReadInt32();
+ var slotCount = reader.ReadInt32();
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].slots = new Ammo.Slot[slotCount];
+ for (int j = 0; j < slotCount; j++)
{
- SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j] = new Ammo.Slot((Identifiable.Id)reader.ReadUInt16(), reader.ReadInt32());
if (reader.ReadBoolean())
{
- SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j].emotions = new SlimeEmotionData();
- var emotionCount = reader.ReadInt32();
- for (int k = 0; k < emotionCount; k++)
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j] = new Ammo.Slot((Identifiable.Id)reader.ReadUInt16(), reader.ReadInt32());
+ if (reader.ReadBoolean())
{
- SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j].emotions.Add((SlimeEmotions.Emotion)reader.ReadUInt16(), reader.ReadSingle());
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j].emotions = new SlimeEmotionData();
+ var emotionCount = reader.ReadInt32();
+ for (int k = 0; k < emotionCount; k++)
+ {
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j].emotions.Add((SlimeEmotions.Emotion)reader.ReadUInt16(), reader.ReadSingle());
+ }
}
}
- }
- else
- {
- SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j] = null;
+ else
+ {
+ SRSingleton.Instance.PlayerState.model.ammoDict[state].slots[j] = null;
+ }
}
}
}
}
}
+ catch (Exception ex)
+ {
+ Debug.Log($"No savefile for {Globals.CurrentGameName}: {ex.Message}");
+ }
}
- catch (Exception ex)
- {
- Debug.Log($"No savefile for {Globals.CurrentGameName}: {ex.Message}");
- }
+ }
+ else
+ {
+ SRMP.Log("Player is being teleported", "CLIENT");
+
+ SRSingleton.Instance.player.transform.position = packet.Position;
+ SRSingleton.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
+ SRSingleton.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
+
+ SRSingleton.Instance.PlayTeleport();
+
}
}
else
diff --git a/SRMP/Networking/NetworkHandlerServer.cs b/SRMP/Networking/Communication/NetworkHandlerServer.cs
similarity index 94%
rename from SRMP/Networking/NetworkHandlerServer.cs
rename to SRMP/Networking/Communication/NetworkHandlerServer.cs
index ee0c1d0..f84f831 100644
--- a/SRMP/Networking/NetworkHandlerServer.cs
+++ b/SRMP/Networking/Communication/NetworkHandlerServer.cs
@@ -2,6 +2,7 @@
using Lidgren.Network;
using MonomiPark.SlimeRancher.DataModel;
using MonomiPark.SlimeRancher.Regions;
+using Newtonsoft.Json.Linq;
using SRMultiplayer.Packets;
using System;
using System.Collections.Generic;
@@ -19,14 +20,13 @@ namespace SRMultiplayer.Networking
if (!Globals.PacketSize.ContainsKey(type))
Globals.PacketSize.Add(type, 0);
Globals.PacketSize[type] += im.LengthBytes;
- switch(type)
+ switch (type)
{
+ //Player animation
+ case PacketType.PlayerAnimation: OnPlayerAnimation(new PacketPlayerAnimation(im), player); break;
//Player
case PacketType.PlayerLoaded: OnPlayerLoaded(new PacketPlayerLoaded(im), player); break;
case PacketType.PlayerPosition: OnPlayerPosition(new PacketPlayerPosition(im), player); break;
- case PacketType.PlayerAnimationLayer: OnPlayerAnimationLayer(im, player); break;
- case PacketType.PlayerAnimationParameters: OnPlayerAnimationParameters(im, player); break;
- case PacketType.PlayerAnimationSpeed: OnPlayerAnimationSpeed(im, player); break;
case PacketType.PlayerCurrency: OnPlayerCurrency(new PacketPlayerCurrency(im), player); break;
case PacketType.PlayerCurrencyDisplay: OnPlayerCurrencyDisplay(new PacketPlayerCurrencyDisplay(im), player); break;
case PacketType.PlayerUpgrade: OnPlayerUpgrade(new PacketPlayerUpgrade(im), player); break;
@@ -132,7 +132,7 @@ namespace SRMultiplayer.Networking
case PacketType.RaceTime: OnRaceTime(new PacketRaceTime(im), player); break;
case PacketType.RaceTrigger: OnRaceTrigger(new PacketRaceTrigger(im), player); break;
default:
- SRMP.Log($"Got unhandled packet from {player}: {type}");
+ SRMP.Log($"Got unhandled packet from {player}: {type}" + Enum.GetName(typeof(PacketType), type));
break;
}
}
@@ -140,7 +140,7 @@ namespace SRMultiplayer.Networking
#region Race
private static void OnRaceTrigger(PacketRaceTrigger packet, NetworkPlayer player)
{
- if(Globals.RaceTriggers.TryGetValue(packet.ID, out NetworkRaceTrigger trigger))
+ if (Globals.RaceTriggers.TryGetValue(packet.ID, out NetworkRaceTrigger trigger))
{
trigger.Activate();
}
@@ -172,7 +172,7 @@ namespace SRMultiplayer.Networking
var generator = QuicksilverEnergyGenerator.allGenerators.FirstOrDefault(g => g.id == packet.ID);
if (generator)
{
- if(Globals.LocalPlayer.CurrentGenerator.id == generator.id)
+ if (Globals.LocalPlayer.CurrentGenerator.id == generator.id)
{
generator.Activate();
}
@@ -242,9 +242,9 @@ namespace SRMultiplayer.Networking
oasis.SetLive(!model.gameObj.activeInHierarchy);
var oasisTriggers = GameObject.FindObjectsOfType();
- foreach(var trigger in oasisTriggers)
+ foreach (var trigger in oasisTriggers)
{
- if(trigger.oasisToScale == oasis && !trigger.hasAlreadyActivated)
+ if (trigger.oasisToScale == oasis && !trigger.hasAlreadyActivated)
{
if (trigger.scaleCue != null)
{
@@ -312,13 +312,23 @@ namespace SRMultiplayer.Networking
{
SRMP.Log($"Exchange TryAccept for {(Identifiable.Id)packet.ID} ({(ExchangeDirector.OfferType)packet.Type}", "SERVER");
requestedItemEntry.progress++;
- if(offer.IsComplete())
+ if (offer.IsComplete())
{
foreach (var rewarder in Resources.FindObjectsOfTypeAll())
{
rewarder.AwardIfType(type);
}
- SRSingleton.Instance.ExchangeDirector.ClearOffer(type);
+
+ //trigger fireworks
+ //get ExchangeEjector
+ foreach (var eject in Resources.FindObjectsOfTypeAll())
+ {
+ //send off fireworks
+ SRBehaviour.InstantiateDynamic(eject.awardFX, eject.awardAt.position, eject.awardAt.rotation);
+ }
+
+ //dont clear out the offer yet, we arent done with it
+ //SRSingleton.Instance.ExchangeDirector.ClearOffer(type);
}
SRSingleton.Instance.ExchangeDirector.OfferDidChange();
}
@@ -482,7 +492,7 @@ namespace SRMultiplayer.Networking
{
if (SRSingleton.Instance.GameModel.AllGadgetSites().TryGetValue(packet.ID, out GadgetSiteModel model))
{
- if(model.HasAttached())
+ if (model.HasAttached())
{
model.attached.transform.GetComponent().drone.ammo.MaybeAddToSpecificSlot((Identifiable.Id)packet.Ident, null, 0, 1);
}
@@ -497,7 +507,7 @@ namespace SRMultiplayer.Networking
if (Globals.GadgetSites.TryGetValue(packet.ID, out NetworkGadgetSite netSite))
{
var echoNet = netSite.Site.GetComponentInChildren(true);
- if(echoNet != null)
+ if (echoNet != null)
{
echoNet.ResetSpawnTime(echoNet.model);
}
@@ -510,7 +520,7 @@ namespace SRMultiplayer.Networking
if (Globals.GadgetSites.TryGetValue(packet.ID, out NetworkGadgetSite netSite))
{
var snare = netSite.Site.GetComponentInChildren(true);
- if(snare != null)
+ if (snare != null)
{
if (!snare.IsBaited() || snare.HasSnaredGordo())
{
@@ -579,7 +589,7 @@ namespace SRMultiplayer.Networking
{
Globals.GadgetSites.TryGetValue(packet.ID, out NetworkGadgetSite netSite);
bool didUnproxy = false;
- if(netSite != null)
+ if (netSite != null)
{
if (!netSite.Region.Region.root.activeSelf)
{
@@ -622,7 +632,7 @@ namespace SRMultiplayer.Networking
foreach (var data in packet.Amounts)
{
SRSingleton.Instance.GameModel.GetGadgetsModel().craftMatCounts[(Identifiable.Id)data.Key] -= data.Value;
- if(SRSingleton.Instance.GameModel.GetGadgetsModel().craftMatCounts[(Identifiable.Id)data.Key] < 0)
+ if (SRSingleton.Instance.GameModel.GetGadgetsModel().craftMatCounts[(Identifiable.Id)data.Key] < 0)
{
SRSingleton.Instance.GameModel.GetGadgetsModel().craftMatCounts[(Identifiable.Id)data.Key] = 0;
}
@@ -720,7 +730,7 @@ namespace SRMultiplayer.Networking
if (attachFashions != null)
{
var component = SRSingleton.Instance.LookupDirector.GetPrefab((Identifiable.Id)packet.Fashion)?.GetComponent();
- if(component != null)
+ if (component != null)
{
attachFashions.Attach(component, !attachFashions.gameObject.activeInHierarchy);
}
@@ -821,17 +831,17 @@ namespace SRMultiplayer.Networking
private static void OnWorldDecorizer(PacketWorldDecorizer packet, NetworkPlayer player)
{
- foreach(var c in packet.Contents)
+ foreach (var c in packet.Contents)
{
- for(int i = 0; i < c.Value; i++)
+ for (int i = 0; i < c.Value; i++)
{
SRSingleton.Instance.GameModel.decorizer.contents.Increment(c.Key);
}
}
- foreach(var setting in packet.Settings)
+ foreach (var setting in packet.Settings)
{
var storage = SRSingleton.Instance.GameModel.decorizer.participants.FirstOrDefault(c => ((DecorizerStorage)c).id == setting.Key);
- if(storage != null)
+ if (storage != null)
{
((DecorizerStorage)storage).selected = (Identifiable.Id)setting.Value;
}
@@ -952,7 +962,7 @@ namespace SRMultiplayer.Networking
if (SRSingleton.Instance.GameModel.AllLandPlots().TryGetValue(packet.ID, out LandPlotModel model))
{
var incinerate = model.gameObj.GetComponentInChildren();
- if(incinerate != null)
+ if (incinerate != null)
{
SRBehaviour.SpawnAndPlayFX(incinerate.ExplosionFX, packet.Position, packet.Rotation);
if (packet.Small)
@@ -976,7 +986,7 @@ namespace SRMultiplayer.Networking
private static void OnGlobalFX(PacketGlobalFX packet, NetworkPlayer player)
{
- if(Globals.FXPrefabs.TryGetValue(packet.Name, out GameObject prefabFX))
+ if (Globals.FXPrefabs.TryGetValue(packet.Name, out GameObject prefabFX))
{
SRBehaviour.SpawnAndPlayFX(prefabFX, packet.Position, Quaternion.identity);
}
@@ -1080,7 +1090,7 @@ namespace SRMultiplayer.Networking
if (SRSingleton.Instance.GameModel.AllLandPlots().TryGetValue(packet.ID, out LandPlotModel model))
{
var collector = model.gameObj.GetComponentInChildren();
- if(collector != null)
+ if (collector != null)
{
collector.StartCollection();
}
@@ -1268,14 +1278,14 @@ namespace SRMultiplayer.Networking
private static void OnRegionOwner(PacketRegionOwner packet, NetworkPlayer player)
{
- if(Globals.Regions.TryGetValue(packet.ID, out NetworkRegion netRegion))
+ if (Globals.Regions.TryGetValue(packet.ID, out NetworkRegion netRegion))
{
- if(packet.Owner == 0 && netRegion.Owner == player.ID)
+ if (packet.Owner == 0 && netRegion.Owner == player.ID)
{
netRegion.SetOwnership(0);
packet.SendToAll();
}
- else if(packet.Owner != 0 && netRegion.Owner == 0)
+ else if (packet.Owner != 0 && netRegion.Owner == 0)
{
netRegion.SetOwnership(packet.Owner);
packet.SendToAll();
@@ -1338,7 +1348,7 @@ namespace SRMultiplayer.Networking
var slimeFeral = netActor.GetComponentInChildren(true);
if (slimeFeral != null)
{
- if(packet.Feral)
+ if (packet.Feral)
{
slimeFeral.MakeFeral();
}
@@ -1384,7 +1394,7 @@ namespace SRMultiplayer.Networking
if (Globals.Actors.TryGetValue(packet.ID, out NetworkActor netActor))
{
var cycle = netActor.GetComponentInChildren(true);
- if(cycle != null)
+ if (cycle != null)
{
var state = (ResourceCycle.State)packet.State;
//SRMP.Log($"Resource state for {netActor.name} ({netActor.ID}): {state}", "SERVER");
@@ -1401,7 +1411,7 @@ namespace SRMultiplayer.Networking
}
TweenUtil.ScaleTo(cycle.gameObject, cycle.defaultScale, 4f, Ease.InOutQuad);
}
- else if(state == ResourceCycle.State.EDIBLE)
+ else if (state == ResourceCycle.State.EDIBLE)
{
cycle.MakeEdible();
cycle.additionalRipenessDelegate = null;
@@ -1427,7 +1437,7 @@ namespace SRMultiplayer.Networking
cycle.vacuumable.Pending = false;
}
}
- else if(state == ResourceCycle.State.ROTTEN)
+ else if (state == ResourceCycle.State.ROTTEN)
{
cycle.Rot();
cycle.SetRotten(!cycle.gameObject.activeInHierarchy);
@@ -1525,7 +1535,7 @@ namespace SRMultiplayer.Networking
netActor.KnownPlayers.AddRange(Globals.Players.Values.Where(p => p.HasLoaded));
var resourceCycle = actorObj.GetComponentInChildren(true);
- if(resourceCycle != null)
+ if (resourceCycle != null)
{
resourceCycle.SetInitState(ResourceCycle.State.UNRIPE, double.MaxValue);
}
@@ -1574,7 +1584,7 @@ namespace SRMultiplayer.Networking
private static void OnPlayerCurrencyDisplay(PacketPlayerCurrencyDisplay packet, NetworkPlayer player)
{
SRSingleton.Instance.PlayerState.SetCurrencyDisplay(packet.IsNull ? null : new int?(packet.Currency));
- if(packet.IsNull)
+ if (packet.IsNull)
{
SRSingleton.Instance.CreateCoinsPopup(packet.Currency, PlayerState.CoinsType.DRONE);
}
@@ -1629,58 +1639,56 @@ namespace SRMultiplayer.Networking
packet.SendToAllExcept(player);
}
- private static void OnPlayerAnimationSpeed(NetIncomingMessage im, NetworkPlayer player)
+ private static void OnPlayerAnimation(PacketPlayerAnimation packet, NetworkPlayer player)
{
if (player.HasLoaded)
{
- byte id = im.ReadByte();
- player.ReadAnimatorSpeed(im);
+ switch (packet.Type)
+ {
+ case (byte)PacketPlayerAnimation.AnimationType.Speed:
+ player.ReadAnimatorSpeed(packet.internalData);
+ break;
+ case (byte)PacketPlayerAnimation.AnimationType.Layer:
+ player.ReadAnimatorLayer(packet.internalData);
+ break;
+ case (byte)PacketPlayerAnimation.AnimationType.Parameters:
+ player.ReadParameters(packet.internalData);
+ break;
+ }
- NetOutgoingMessage om = NetworkServer.Instance.CreateMessage();
- om.Write(im);
- NetworkServer.Instance.SendToAll(om, player);
- }
- }
-
- private static void OnPlayerAnimationParameters(NetIncomingMessage im, NetworkPlayer player)
- {
- if (player.HasLoaded)
- {
- byte id = im.ReadByte();
- player.ReadParameters(im);
-
- NetOutgoingMessage om = NetworkServer.Instance.CreateMessage();
- om.Write(im);
- NetworkServer.Instance.SendToAll(om, player);
- }
- }
-
- private static void OnPlayerAnimationLayer(NetIncomingMessage im, NetworkPlayer player)
- {
- if(player.HasLoaded)
- {
- byte id = im.ReadByte();
- player.ReadAnimatorLayer(im);
-
- NetOutgoingMessage om = NetworkServer.Instance.CreateMessage();
- om.Write(im);
- NetworkServer.Instance.SendToAll(om, player);
- }
- }
-
- private static void OnPlayerPosition(PacketPlayerPosition packet, NetworkPlayer player)
- {
- if (player.HasLoaded)
- {
- player.PositionRotationUpdate(packet.Position, packet.Rotation, false);
- player.UpdateWeaponRotation(packet.WeaponY);
- player.CurrentRegionSet = (RegionRegistry.RegionSetId)packet.RegionSet;
-
- packet.ID = player.ID;
+ //make the incoming message an out going message
packet.SendToAllExcept(player, NetDeliveryMethod.Unreliable);
}
}
+ private static void OnPlayerPosition(PacketPlayerPosition packet, NetworkPlayer netPlayer)
+ {
+ //get player id from packet in case of a teleport
+ NetworkPlayer player = Globals.Players.Values.FirstOrDefault(p => p.ID.Equals(packet.ID));
+
+ if (player.HasLoaded)
+ {
+ if (player.IsLocal) //if the server player is the one being moved, teleport them
+ {
+ SRSingleton.Instance.player.transform.position = packet.Position;
+ SRSingleton.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
+ SRSingleton.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
+
+ SRSingleton.Instance.PlayTeleport();
+ }
+ else //else process player movement
+ {
+ player.PositionRotationUpdate(packet.Position, packet.Rotation, false);
+ player.UpdateWeaponRotation(packet.WeaponY);
+ player.CurrentRegionSet = (RegionRegistry.RegionSetId)packet.RegionSet;
+ packet.ID = player.ID;
+ packet.SendToAllExcept(netPlayer, NetDeliveryMethod.Unreliable);
+ }
+
+
+ }
+ }
+
private static void OnPlayerLoaded(PacketPlayerLoaded packet, NetworkPlayer player)
{
new PacketWorldData()
@@ -1707,7 +1715,7 @@ namespace SRMultiplayer.Networking
Contents = SRSingleton.Instance.GameModel.decorizer.contents.ToDictionary(c => c.Key, v => v.Value),
Settings = SRSingleton.Instance.GameModel.decorizer.settings.ToDictionary(s => s.Key, v => (ushort)v.Value.selected)
}.Send(player, NetDeliveryMethod.ReliableOrdered);
-
+
new PacketLandplots()
{
LandPlots = Globals.LandPlots.Values.Where(l => l.Plot.model != null).Select(l => new PacketLandplots.LandPlotData() { ID = l.Location.id, Model = l.Plot.model }).ToList()
diff --git a/SRMP/Networking/NetworkServer.cs b/SRMP/Networking/Communication/NetworkServer.cs
similarity index 99%
rename from SRMP/Networking/NetworkServer.cs
rename to SRMP/Networking/Communication/NetworkServer.cs
index b0ffa74..fac69fa 100644
--- a/SRMP/Networking/NetworkServer.cs
+++ b/SRMP/Networking/Communication/NetworkServer.cs
@@ -340,6 +340,7 @@ namespace SRMultiplayer.Networking
{
Globals.HandlePacket = true;
PacketType type = (PacketType)im.ReadUInt16();
+
var player = Globals.Players.Values.FirstOrDefault(p => p.Connection != null && p.Connection.RemoteUniqueIdentifier == im.SenderConnection.RemoteUniqueIdentifier);
if (player != null)
{
diff --git a/SRMP/Networking/NetworkActor.cs b/SRMP/Networking/NetworkActor.cs
index f0a2feb..dcf6c10 100644
--- a/SRMP/Networking/NetworkActor.cs
+++ b/SRMP/Networking/NetworkActor.cs
@@ -1,8 +1,10 @@
-using MonomiPark.SlimeRancher.Regions;
+using DG.Tweening;
+using MonomiPark.SlimeRancher.Regions;
using SRMultiplayer.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
@@ -52,7 +54,7 @@ namespace SRMultiplayer.Networking
private void OnEnable()
{
- if(Owner == 0)
+ if (Owner == 0)
{
TakeOwnership();
}
@@ -68,7 +70,7 @@ namespace SRMultiplayer.Networking
private void Update()
{
- if(IsLocal)
+ if (IsLocal)
{
m_MovementUpdateTimer -= Time.deltaTime;
if (m_MovementUpdateTimer <= 0)
@@ -92,7 +94,7 @@ namespace SRMultiplayer.Networking
}.Send(Lidgren.Network.NetDeliveryMethod.Unreliable);
}
- if(SlimeEat != null &&
+ if (SlimeEat != null &&
(!Utils.CloseEnoughForMe(SlimeEat.emotions.GetCurr(SlimeEmotions.Emotion.AGITATION), m_PreviousEmotions[SlimeEmotions.Emotion.AGITATION], 0.1f) ||
!Utils.CloseEnoughForMe(SlimeEat.emotions.GetCurr(SlimeEmotions.Emotion.FEAR), m_PreviousEmotions[SlimeEmotions.Emotion.FEAR], 0.1f) ||
!Utils.CloseEnoughForMe(SlimeEat.emotions.GetCurr(SlimeEmotions.Emotion.HUNGER), m_PreviousEmotions[SlimeEmotions.Emotion.HUNGER], 0.1f)))
@@ -113,7 +115,7 @@ namespace SRMultiplayer.Networking
}
else
{
- if(m_Rigidbody != null)
+ if (m_Rigidbody != null)
{
m_Rigidbody.velocity = Vector3.zero;
}
@@ -227,7 +229,7 @@ namespace SRMultiplayer.Networking
}
}
var destroyOnTouching = GetComponentInChildren();
- if(destroyOnTouching != null)
+ if (destroyOnTouching != null)
{
if (destroyOnTouching.destroyFX != null)
{
@@ -237,6 +239,7 @@ namespace SRMultiplayer.Networking
var exchangeBreakOnImpact = GetComponentInChildren();
if (exchangeBreakOnImpact != null)
{
+ SRMP.Log("Exchange Box Broke!", "ACTOR");
SRBehaviour.SpawnAndPlayFX(exchangeBreakOnImpact.breakFX, exchangeBreakOnImpact.gameObject.transform.position, exchangeBreakOnImpact.gameObject.transform.rotation);
}
var breakOnImpact = GetComponentInChildren();
@@ -245,7 +248,7 @@ namespace SRMultiplayer.Networking
SRBehaviour.SpawnAndPlayFX(breakOnImpact.breakFX, breakOnImpact.gameObject.transform.position, breakOnImpact.gameObject.transform.rotation);
}
var quicksilver = GetComponentInChildren();
- if(quicksilver != null)
+ if (quicksilver != null)
{
if (quicksilver.destroyFX != null)
{
diff --git a/SRMP/Networking/NetworkGordo.cs b/SRMP/Networking/NetworkGordo.cs
index 94685f0..9ddc3db 100644
--- a/SRMP/Networking/NetworkGordo.cs
+++ b/SRMP/Networking/NetworkGordo.cs
@@ -10,7 +10,7 @@ namespace SRMultiplayer.Networking
{
public class NetworkGordo : MonoBehaviour
{
- public string ID { get { return Gordo.id == null ? Gordo.GetComponentInParent(true).id : Gordo.id; } }
+ public string ID { get { return Gordo.id == null ? Gordo.GetComponentInParent(true).id : Gordo.id; } }
public GordoEat Gordo;
public NetworkRegion Region;
@@ -33,36 +33,51 @@ namespace SRMultiplayer.Networking
public void Burst()
{
+ //if object is in active mark the reach target
if (gameObject.activeInHierarchy)
{
StartCoroutine(ReachedTarget());
}
else
{
+ //if not just dismiss the gordo completely
Gordo.gameObject.SetActive(false);
Gordo.SetEatenCount(-1);
}
}
+ //process the gordo burst reaction
private IEnumerator ReachedTarget()
{
+ //start the burst and begin sounds and animations
Gordo.WillStartBurst();
Gordo.GetComponent().SetTrigger("Strain");
SECTR_AudioSystem.Play(Gordo.strainCue, Gordo.transform.position, false);
+ //wait for amination/sounds to finish
yield return new WaitForSeconds(2f);
SECTR_AudioSystem.Play(Gordo.burstCue, Gordo.transform.position, false);
+
+ //if the gordo has a destroy effect process it
if (Gordo.destroyFX != null)
{
+ //play the spawn behavior for destroy events for the gordo that is bursting
GameObject gameObject = SRBehaviour.SpawnAndPlayFX(Gordo.destroyFX, Gordo.transform.position + Vector3.up * 2f, Gordo.transform.rotation);
+ //get the gordo slime type
Identifiable component = Gordo.gameObject.GetComponent();
+ //get the color of the current gordo
Color[] colors = SlimeUtil.GetColors(Gordo.gameObject, (component != null) ? component.id : Identifiable.Id.NONE, true);
+ //get the slime children spawned by the gordo
RecolorSlimeMaterial[] componentsInChildren = gameObject.GetComponentsInChildren();
for (int i = 0; i < componentsInChildren.Length; i++)
{
+ //foreach slime in the count spawned by the gordo, set their coloring
componentsInChildren[i].SetColors(colors[0], colors[1], colors[2]);
}
}
+ //trigger the burst completed event
Gordo.DidCompleteBurst();
+
+ //despawn the bursted gordo from game
Gordo.gameObject.SetActive(false);
Gordo.SetEatenCount(-1);
yield break;
diff --git a/SRMP/Networking/NetworkPlayer.Animation.cs b/SRMP/Networking/NetworkPlayer.Animation.cs
index 469f01a..0ea4470 100644
--- a/SRMP/Networking/NetworkPlayer.Animation.cs
+++ b/SRMP/Networking/NetworkPlayer.Animation.cs
@@ -1,12 +1,10 @@
using Lidgren.Network;
using SRMultiplayer.Packets;
-using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using UnityEngine;
+using static SRMultiplayer.Packets.PacketPlayerAnimation;
namespace SRMultiplayer.Networking
{
@@ -62,33 +60,42 @@ namespace SRMultiplayer.Networking
continue;
}
- NetOutgoingMessage writer = CreateMessage();
- writer.Write((ushort)PacketType.PlayerAnimationLayer);
- writer.Write(Globals.LocalID);
- WriteAnimatorLayer(writer, stateHash, normalizedTime, i, layerWeight[i]);
- Send(writer);
+ //NetOutgoingMessage writer = CreateMessage();
+
+ //add the object to the writer but dont send it yet
+ var packet = new PacketPlayerAnimation()
+ {
+ Type = (byte)PacketPlayerAnimation.AnimationType.Layer,
+ ID = Globals.LocalID
+ };
+
+ //add extra parameters
+ WriteAnimatorLayer(packet, stateHash, normalizedTime, i, layerWeight[i]);
+
+ //send the changes
+ packet.Send();
}
CheckSpeed();
}
- void WriteAnimatorLayer(NetOutgoingMessage writer, int stateHash, float normalizedTime, int layerNumber, float layerWeight)
+ void WriteAnimatorLayer(PacketPlayerAnimation writer, int stateHash, float normalizedTime, int layerNumber, float layerWeight)
{
- writer.Write(stateHash);
- writer.Write(normalizedTime);
- writer.Write(layerNumber);
- writer.Write(layerWeight);
+ writer.Add(stateHash);
+ writer.Add(normalizedTime);
+ writer.Add(layerNumber);
+ writer.Add(layerWeight);
WriteParameters(writer);
}
- public void ReadAnimatorLayer(NetIncomingMessage im)
+ public void ReadAnimatorLayer(Queue im)
{
if (m_Animator == null) return;
- int stateHash = im.ReadInt32();
- float normalizedTime = im.ReadFloat();
- int layerNumber = im.ReadInt32();
- float layerWeight = im.ReadFloat();
+ int stateHash = im.Dequeue().iData.Value;
+ float normalizedTime = im.Dequeue().fData.Value;
+ int layerNumber = im.Dequeue().iData.Value;
+ float layerWeight = im.Dequeue().fData.Value;
if (stateHash != 0 && m_Animator.enabled)
{
@@ -106,24 +113,33 @@ namespace SRMultiplayer.Networking
if (Mathf.Abs(previousSpeed - newSpeed) > 0.001f)
{
previousSpeed = newSpeed;
- NetOutgoingMessage writer = CreateMessage();
- writer.Write((ushort)PacketType.PlayerAnimationSpeed);
- writer.Write(Globals.LocalID);
- WriteAnimatorSpeed(writer, newSpeed);
- Send(writer);
+ //NetOutgoingMessage writer = CreateMessage();
+
+ //add the object to the writer but dont send it yet
+ var packet = new PacketPlayerAnimation()
+ {
+ Type = (byte)PacketPlayerAnimation.AnimationType.Speed,
+ ID = Globals.LocalID
+ };
+
+ //add extra parameters
+ WriteAnimatorSpeed(packet, newSpeed);
+
+ //send the speed change
+ packet.Send();
}
}
- void WriteAnimatorSpeed(NetOutgoingMessage writer, float newSpeed)
+ void WriteAnimatorSpeed(PacketPlayerAnimation writer, float newSpeed)
{
- writer.Write(newSpeed);
+ writer.Add(newSpeed);
}
- public void ReadAnimatorSpeed(NetIncomingMessage im)
+ public void ReadAnimatorSpeed(Queue im)
{
if (m_Animator == null) return;
- var newSpeed = im.ReadFloat();
+ var newSpeed = im.Dequeue().fData.Value;
// set m_Animator
m_Animator.speed = newSpeed;
m_AnimatorSpeed = newSpeed;
@@ -179,12 +195,17 @@ namespace SRMultiplayer.Networking
{
nextSendTime = now + syncInterval;
- NetOutgoingMessage writer = CreateMessage();
- writer.Write((ushort)PacketType.PlayerAnimationParameters);
- writer.Write(Globals.LocalID);
- if (WriteParameters(writer))
+ //add the object to the writer but dont send it yet
+ var packet = new PacketPlayerAnimation()
{
- Send(writer);
+ Type = (byte)PacketPlayerAnimation.AnimationType.Parameters,
+ ID = Globals.LocalID
+ };
+
+ //add extra parameters
+ if (WriteParameters(packet))
+ {
+ packet.Send();
}
}
}
@@ -226,10 +247,10 @@ namespace SRMultiplayer.Networking
return dirtyBits;
}
- bool WriteParameters(NetOutgoingMessage writer, bool forceAll = false)
+ bool WriteParameters(PacketPlayerAnimation writer, bool forceAll = false)
{
ulong dirtyBits = forceAll ? (~0ul) : NextDirtyBits();
- writer.Write(dirtyBits);
+ writer.Add(dirtyBits);
for (int i = 0; i < parameters.Length; i++)
{
if ((dirtyBits & (1ul << i)) == 0)
@@ -239,53 +260,55 @@ namespace SRMultiplayer.Networking
if (par.type == AnimatorControllerParameterType.Int)
{
int newIntValue = m_Animator.GetInteger(par.nameHash);
- writer.Write(newIntValue);
+ writer.Add(newIntValue);
}
else if (par.type == AnimatorControllerParameterType.Float)
{
float newFloatValue = m_Animator.GetFloat(par.nameHash);
- writer.Write(newFloatValue);
+ writer.Add(newFloatValue);
}
else if (par.type == AnimatorControllerParameterType.Bool)
{
bool newBoolValue = m_Animator.GetBool(par.nameHash);
- writer.Write(newBoolValue);
+ writer.Add(newBoolValue);
}
}
return dirtyBits != 0;
}
- public void ReadParameters(NetIncomingMessage reader)
- {
+ public void ReadParameters(Queue im)
+ { //make sure
if (m_Animator == null) return;
bool m_AnimatorEnabled = m_Animator.enabled;
- // need to read values from NetworkReader even if m_Animator is disabled
- ulong dirtyBits = reader.ReadUInt64();
+ // need to read values from NetworkReader even if m_Animator is disabled
+ ulong dirtyBits = im.Dequeue().uData.Value;
for (int i = 0; i < parameters.Length; i++)
{
if ((dirtyBits & (1ul << i)) == 0)
continue;
+
AnimatorControllerParameter par = parameters[i];
+
if (par.type == AnimatorControllerParameterType.Int)
{
- int newIntValue = reader.ReadInt32();
+ int? newIntValue = im.Dequeue().iData;
if (m_AnimatorEnabled)
- m_Animator.SetInteger(par.nameHash, newIntValue);
+ m_Animator.SetInteger(par.nameHash, newIntValue.Value);
}
else if (par.type == AnimatorControllerParameterType.Float)
{
- float newFloatValue = reader.ReadSingle();
+ float? newFloatValue = im.Dequeue().fData;
if (m_AnimatorEnabled)
- m_Animator.SetFloat(par.nameHash, newFloatValue);
+ m_Animator.SetFloat(par.nameHash, newFloatValue.Value);
}
else if (par.type == AnimatorControllerParameterType.Bool)
{
- bool newBoolValue = reader.ReadBoolean();
+ bool? newBoolValue = im.Dequeue().bData;
if (m_AnimatorEnabled)
- m_Animator.SetBool(par.nameHash, newBoolValue);
+ m_Animator.SetBool(par.nameHash, newBoolValue.Value);
}
}
}
diff --git a/SRMP/Networking/NetworkPlayer.cs b/SRMP/Networking/NetworkPlayer.cs
index aa4ff56..fb71921 100644
--- a/SRMP/Networking/NetworkPlayer.cs
+++ b/SRMP/Networking/NetworkPlayer.cs
@@ -150,6 +150,11 @@ namespace SRMultiplayer.Networking
}
}
+ public float GetWeaponLocation()
+ {
+ return m_ActualWeaponY;
+ }
+
private void OnAnimatorIK()
{
if(m_Animator != null && m_LeftHandTarget != null)
diff --git a/SRMP/Packets/Actors/PacketPlayerAnimation.cs b/SRMP/Packets/Actors/PacketPlayerAnimation.cs
new file mode 100644
index 0000000..35f18f9
--- /dev/null
+++ b/SRMP/Packets/Actors/PacketPlayerAnimation.cs
@@ -0,0 +1,133 @@
+using Lidgren.Network;
+using MonomiPark.SlimeRancher.DataModel;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static SRMultiplayer.Packets.PacketAccessDoors;
+
+namespace SRMultiplayer.Packets
+{
+ [Packet(PacketType.PlayerAnimation)]
+ public class PacketPlayerAnimation : Packet
+ {
+ public enum AnimationType : int
+ {
+ Layer,
+ Speed,
+ Parameters
+
+ }
+
+ public byte ID;
+ public byte Type;
+ public struct animateData
+ {
+ public byte type
+ {
+ get
+ {
+ if (fData.HasValue) return 0;
+ if (bData.HasValue) return 1;
+ if (iData.HasValue) return 2;
+ if (uData.HasValue) return 3;
+ return 8;
+ }
+ }
+ public float? fData;
+ public bool? bData;
+ public int? iData;
+ public ulong? uData;
+ }
+
+ public Queue internalData { get; set; } = new Queue();
+
+ public void Add(T obj)
+ {
+ switch (obj)
+ {
+ case float itm:
+ internalData.Enqueue(new animateData() { fData = itm });
+ break;
+ case bool itm:
+ internalData.Enqueue(new animateData() { bData = itm });
+ break;
+ case int itm:
+ internalData.Enqueue(new animateData() { iData = itm });
+ break;
+ case ulong itm:
+ internalData.Enqueue(new animateData() { uData = itm });
+ break;
+ }
+ }
+
+ ///
+ /// mark construction inheritance incase we need it
+ ///
+ public PacketPlayerAnimation() : base() { }
+ ///
+ /// mark construction inheritance so the deserialization automatically happens for is
+ /// since the base decalres this
+ ///
+ public PacketPlayerAnimation(NetIncomingMessage im) : base(im) { }
+
+ public override void Serialize(NetOutgoingMessage om)
+ {
+ base.Serialize(om);
+
+ om.Write(internalData.Count);
+ foreach (var data in internalData)
+ {
+ om.Write(data.type);
+ switch (data.type)
+ {
+ case 0:
+ om.Write(data.fData.Value);
+ break;
+ case 1:
+ om.Write(data.bData.Value);
+ break;
+ case 2:
+ om.Write(data.iData.Value);
+ break;
+ case 3:
+ om.Write(data.uData.Value);
+ break;
+ }
+ }
+ }
+
+ public override void Deserialize(NetIncomingMessage im)
+ {
+ base.Deserialize(im);
+
+ internalData = new Queue();
+ int Count = im.ReadInt32();
+ for (int i = 0; i < Count; i++)
+ {
+ var data = new animateData();
+ byte type = im.ReadByte();
+ switch (type)
+ {
+ case 0:
+ data.fData = im.ReadFloat();
+ break;
+ case 1:
+ data.bData = im.ReadBoolean();
+ break;
+ case 2:
+ data.iData = im.ReadInt32();
+ break;
+ case 3:
+ data.uData = im.ReadUInt64();
+ break;
+ }
+
+ internalData.Enqueue(data);
+ }
+ }
+ }
+
+}
diff --git a/SRMP/Packets/Players/PacketPlayerPosition.cs b/SRMP/Packets/Players/PacketPlayerPosition.cs
index 18398e4..0a4597e 100644
--- a/SRMP/Packets/Players/PacketPlayerPosition.cs
+++ b/SRMP/Packets/Players/PacketPlayerPosition.cs
@@ -15,6 +15,7 @@ namespace SRMultiplayer.Packets
public float Rotation;
public float WeaponY;
public byte RegionSet;
+ public bool OnLoad = true;
public PacketPlayerPosition() { }
public PacketPlayerPosition(NetIncomingMessage im) { Deserialize(im); }
diff --git a/SRMP/Packets/_Classes/IPacket.cs b/SRMP/Packets/_Classes/IPacket.cs
index 6b1c3ed..3236699 100644
--- a/SRMP/Packets/_Classes/IPacket.cs
+++ b/SRMP/Packets/_Classes/IPacket.cs
@@ -1,4 +1,5 @@
using Lidgren.Network;
+using SRMultiplayer.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,7 +10,15 @@ namespace SRMultiplayer.Packets
public interface IPacket
{
PacketType GetPacketType();
+ ///
+ /// Searilizes the given packet item
+ ///
+ /// Outgoing Message that the packet should be added to
void Serialize(NetOutgoingMessage om);
- void Deserialize(NetIncomingMessage im);
+ ///
+ /// Deserializes the given packet item
+ ///
+ /// Incoming Message that the packet should be deserialized from
+ void Deserialize(NetIncomingMessage im);
}
}
diff --git a/SRMP/Packets/_Classes/Packet.cs b/SRMP/Packets/_Classes/Packet.cs
index 8b10008..9f77617 100644
--- a/SRMP/Packets/_Classes/Packet.cs
+++ b/SRMP/Packets/_Classes/Packet.cs
@@ -9,16 +9,42 @@ namespace SRMultiplayer.Packets
{
public abstract class Packet : IPacket
{
+ ///
+ /// Parameterless constructor to be used through inheritance
+ ///
+ public Packet() { }
+
+ ///
+ /// Incoming message based construtor that deserielizes the item for the message
+ ///
+ public Packet(NetIncomingMessage im) { Deserialize(im); }
+
+
+ ///
+ /// Searilizes the given packet item
+ ///
+ /// Outgoing Message that the packet should be added to
+ public virtual void Serialize(NetOutgoingMessage om)
+ {
+ om.Write((ushort)GetPacketType());
+ //writes the object type using the gettype name
+ //this allows the object to assume its object packet type
+ //om.Write(this.GetType().AssemblyQualifiedName);
+ //
+
+ om.WriteAllFields(this, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+ }
+
+ ///
+ /// Deserializes the given packet item
+ ///
+ /// Incoming Message that the packet should be deserialized from
public virtual void Deserialize(NetIncomingMessage im)
{
im.ReadAllFields(this, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
}
- public virtual void Serialize(NetOutgoingMessage om)
- {
- om.Write((ushort)GetPacketType());
- om.WriteAllFields(this, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
- }
+
public PacketType GetPacketType()
{
diff --git a/SRMP/Packets/_Classes/PacketType.cs b/SRMP/Packets/_Classes/PacketType.cs
index a6ca38d..1f22782 100644
--- a/SRMP/Packets/_Classes/PacketType.cs
+++ b/SRMP/Packets/_Classes/PacketType.cs
@@ -7,9 +7,7 @@
PlayerLeft,
PlayerPosition,
PlayerLoaded,
- PlayerAnimationLayer,
- PlayerAnimationSpeed,
- PlayerAnimationParameters,
+ PlayerAnimation,
PlayerFX,
PlayAudio,
ActorSpawn,
@@ -97,6 +95,7 @@
ExchangeTryAccept,
ExchangeClear,
ExchangeOffers,
+ ExchangeBreak,
GordoEat,
Oasis,
OasisLive,
diff --git a/SRMP/Patches/Patch_ExchangeBreakOnImpact.cs b/SRMP/Patches/Patch_ExchangeBreakOnImpact.cs
index 219a384..1e29af0 100644
--- a/SRMP/Patches/Patch_ExchangeBreakOnImpact.cs
+++ b/SRMP/Patches/Patch_ExchangeBreakOnImpact.cs
@@ -1,9 +1,13 @@
using HarmonyLib;
+using MonomiPark.SlimeRancher.Regions;
using SRMultiplayer.Networking;
+using SRMultiplayer.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
+using UnityEngine;
namespace SRMultiplayer.Patches
{
@@ -11,11 +15,19 @@ namespace SRMultiplayer.Patches
[HarmonyPatch("BreakOpen")]
class ExchangeBreakOnImpact_BreakOpen
{
+
static bool Prefix(ExchangeBreakOnImpact __instance)
{
- if (!Globals.IsMultiplayer) return true;
+ //if multiplayer, only the server can trigger the impact
+ if (!Globals.IsMultiplayer) return true;
+
+
var entity = __instance.GetComponent();
+
+ SRMP.Log("Exchange Box Break: " + (entity != null && entity.IsLocal), "EXCHANGE");
+
+ //if the box exists and the entity is local process the break
return (entity != null && entity.IsLocal);
}
}
diff --git a/SRMP/Patches/Patch_Identifiable.cs b/SRMP/Patches/Patch_Identifiable.cs
index d9bcd3c..ba109e3 100644
--- a/SRMP/Patches/Patch_Identifiable.cs
+++ b/SRMP/Patches/Patch_Identifiable.cs
@@ -22,7 +22,18 @@ namespace SRMultiplayer.Patches
{
if (Globals.Actors.ContainsKey(netActor.ID))
{
+ //check if this is an exchange box
+ var exchangeBreakOnImpact = netActor.GetComponentInChildren();
+ if (exchangeBreakOnImpact != null)
+ {
+ //exchange box was found processing it with the ondestroy command instead of just removing it!
+ //netActor.OnDestroyEffect();
+ //Destroyer.DestroyActor(netActor.gameObject, "NetworkHandlerServer.OnActorDestroy");
+ }
+
+ //make sure the actor still gets cleaned up
Globals.Actors.Remove(netActor.ID);
+
new PacketActorDestroy()
{
ID = netActor.ID
diff --git a/SRMP/Patches/Patch_PauseMenu.cs b/SRMP/Patches/Patch_PauseMenu.cs
index 2003929..d34d87b 100644
--- a/SRMP/Patches/Patch_PauseMenu.cs
+++ b/SRMP/Patches/Patch_PauseMenu.cs
@@ -17,7 +17,9 @@ namespace SRMultiplayer.Patches
{
if (!Globals.IsMultiplayer) return;
+ //only handle the client if the client is the one disconnecting
NetworkClient.Instance.Disconnect();
+ //if server ahndle the shutdown
NetworkServer.Instance.Disconnect();
}
}
diff --git a/SRMP/PauseState.cs b/SRMP/PauseState.cs
deleted file mode 100644
index 416e527..0000000
--- a/SRMP/PauseState.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace SRMultiplayer
-{
- public enum PauseState
- {
- Pause,
- Playing
- }
-}
diff --git a/SRMP/Properties/AssemblyInfo.cs b/SRMP/Properties/AssemblyInfo.cs
index 4800f7c..00d781b 100644
--- a/SRMP/Properties/AssemblyInfo.cs
+++ b/SRMP/Properties/AssemblyInfo.cs
@@ -15,7 +15,7 @@ using System.Resources;
[assembly: AssemblyCulture("")]
// Version informationr(
-[assembly: AssemblyVersion("0.0.0.1488")]
-[assembly: AssemblyFileVersion("0.0.0.1488")]
+[assembly: AssemblyVersion("0.0.0.1510")]
+[assembly: AssemblyFileVersion("0.0.0.1510")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
diff --git a/SRMP/SRMP.cs b/SRMP/SRMP.cs
index b474b26..7cb7b5c 100644
--- a/SRMP/SRMP.cs
+++ b/SRMP/SRMP.cs
@@ -20,26 +20,41 @@ namespace SRMultiplayer
private float m_LastTimeSync;
+ ///
+ /// Acts as the initializer for the Mod
+ ///
public override void Awake()
{
base.Awake();
+ //attach scene manager to trigger event when in a menu or loading up a game
SceneManager.activeSceneChanged += SceneManager_activeSceneChanged;
+ //attach log messager to log all game errors and exceptions into the SRMP Logs
Application.logMessageReceived += Application_logMessageReceived;
+ //load up mod specific resources
var myLoadedAssetBundle = AssetBundle.LoadFromMemory(Utils.ExtractResource("SRMultiplayer.srmultiplayer.dat"));
if (myLoadedAssetBundle == null)
{
SRMP.Log("Failed to load AssetBundle!");
return;
}
+ //load up the Player moment animator for the Beatrix model
Globals.BeatrixController = myLoadedAssetBundle.LoadAsset("Controller");
- Globals.IngameMultiplayerMenuPrefab = myLoadedAssetBundle.LoadAsset("IngameMultiplayerMenu");
- Globals.MainMultiplayerMenuPrefab = myLoadedAssetBundle.LoadAsset("MainMultiplayerMenu");
- }
+ //unused prefab menus, these menus functions are handled in the floating gui
+ //Globals.IngameMultiplayerMenuPrefab = myLoadedAssetBundle.LoadAsset("IngameMultiplayerMenu");
+ //Globals.MainMultiplayerMenuPrefab = myLoadedAssetBundle.LoadAsset("MainMultiplayerMenu");
+ }
+ ///
+ /// Subscriber to the Applicaiton log and process it on to the Mods console
+ ///
+ /// Log condition
+ /// Stack trace of log strigger (if applicable)
+ /// Log Type
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
+ //if Error or Exception hand the error of to the Mods log/console to display
if(type == LogType.Error || type == LogType.Exception)
{
SRMP.Log(condition);
@@ -54,6 +69,10 @@ namespace SRMultiplayer
//menuObj.AddComponent();
}
+ ///
+ /// After triggering base destroy
+ /// trigger disconnect and shut down the server
+ ///
public override void OnDestroy()
{
base.OnDestroy();
@@ -62,18 +81,25 @@ namespace SRMultiplayer
NetworkServer.Instance.Disconnect();
}
+ ///
+ /// On Game quit trigger disconnect and shut down the server
+ ///
private void OnApplicationQuit()
{
NetworkClient.Instance.Disconnect();
NetworkServer.Instance.Disconnect();
}
+ ///
+ /// On Update triggered sync up game time
+ ///
private void Update()
{
if(Globals.GameLoaded)
{
if(Globals.IsServer)
{
+ //every 30 seconds send a time updater out to all clients
if(Time.time - m_LastTimeSync > 30)
{
m_LastTimeSync = Time.time;
@@ -98,17 +124,28 @@ namespace SRMultiplayer
}
}
+ ///
+ /// Handle scene changed events triggered by the game
+ ///
+ /// Scene previously
+ /// New Scene
private void SceneManager_activeSceneChanged(Scene from, Scene to)
{
+ //trigger handlers for returning or going to the main menu
if (to.buildIndex == 2) OnMainMenuLoaded();
- if (to.buildIndex == 3) OnGameLoaded();
+ //trigger handlers for loading the game
+ else if (to.buildIndex == 3) OnGameLoaded();
}
+ ///
+ /// Handle user changing to the main menu, whether it is start up or from saving/ being kicked out of the game
+ ///
private void OnMainMenuLoaded()
{
//var menuObj = Instantiate(Globals.MainMultiplayerMenuPrefab, null, false);
//menuObj.AddComponent();
+ //innitialize all necessary global variables
Globals.LocalID = 0;
Globals.DisableAchievements = false;
Globals.GameLoaded = false;
@@ -135,6 +172,8 @@ namespace SRMultiplayer
Globals.Nutcrackers.Clear();
Globals.RaceTriggers.Clear();
NetworkAmmo.All.Clear();
+
+ //clean up any lingering players in the global list
foreach (var player in Globals.Players.Values.ToList())
{
if(player != null && player.gameObject != null)
@@ -144,9 +183,14 @@ namespace SRMultiplayer
}
Globals.Players.Clear();
+
+ //reset the chat
ChatUI.Instance.Clear();
}
+ ///
+ /// Handle the user loading into the multiplayer game
+ ///
private void OnGameLoaded()
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
@@ -365,6 +409,12 @@ namespace SRMultiplayer
private static FileStream m_LogFileStream;
private static StreamWriter m_LogWriter;
+ ///
+ /// Custom message logging of a given message
+ ///
+ /// Main message to be logged
+ /// Prefix to be displayed before the message. Prefix will be after time marker and before the message
+ /// It will also be incapsulated in []
public static void Log(string msg, string prefix = null)
{
if(m_LogFileStream == null)
diff --git a/SRMP/SRMP.csproj b/SRMP/SRMP.csproj
index d8f208f..677c9da 100644
--- a/SRMP/SRMP.csproj
+++ b/SRMP/SRMP.csproj
@@ -9,14 +9,14 @@
Properties
SRMultiplayer
SRMP
- v4.5
+ v4.7.2
512
true
true
- full
+ portable
false
..\Builds\SRMP\
__CONSTRAINED__;Standalone
@@ -74,24 +74,25 @@
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\0Harmony.dll
+ .\0Harmony.dll
+ False
..\Libs\Assembly-CSharp_publicized.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\DOTween.dll
+ .\DOTween.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\InControl.dll
+ .\InControl.dll
+ False
-
+
False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\Newtonsoft.Json.dll
-
-
- False
- ..\Libs\SRML.dll
+ ..\Libs\Newtonsoft.Json.dll
+ False
@@ -103,54 +104,73 @@
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\Unity.TextMeshPro.dll
+ .\Unity.TextMeshPro.dll
+ False
False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityCoreMod.dll
+ .\UnityCoreMod.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.dll
+ .\UnityEngine.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.AnimationModule.dll
+ .\UnityEngine.AnimationModule.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.AssetBundleModule.dll
+ .\UnityEngine.AssetBundleModule.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.CoreModule.dll
+ .\UnityEngine.CoreModule.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.IMGUIModule.dll
+ .\UnityEngine.IMGUIModule.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.InputLegacyModule.dll
+ .\UnityEngine.InputLegacyModule.dll
+ False
+
+
+ .\UnityEngine.InputModule.dll
+
+
+ .\UnityEngine.JSONSerializeModule.dll
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.PhysicsModule.dll
+ .\UnityEngine.PhysicsModule.dll
+ False
False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.TextCoreModule.dll
+ .\UnityEngine.TextCoreModule.dll
+ False
False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.TextRenderingModule.dll
+ .\UnityEngine.TextRenderingModule.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.UI.dll
+ .\UnityEngine.UI.dll
+ False
- C:\Program Files (x86)\Steam\steamapps\common\Slime Rancher\SlimeRancher_Data\Managed\UnityEngine.UIModule.dll
+ .\UnityEngine.UIModule.dll
+ False
-
-
-
+
+
+
@@ -228,11 +248,13 @@
-
+
+
+
+
-
@@ -241,8 +263,6 @@
-
-
@@ -256,11 +276,11 @@
-
+
@@ -462,19 +482,20 @@
-
True
True
AssemblyInfo.tt
-
-
-
-
+
+
+
+
+
+
TextTemplatingFileGenerator
modinfo.json
@@ -487,6 +508,11 @@
+
+
+ ..\Libs\SRML.dll
+
+
True
diff --git a/SRMP/SRMPConsole.cs b/SRMP/SRMPConsole.cs
deleted file mode 100644
index ea5d6d1..0000000
--- a/SRMP/SRMPConsole.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-using MonomiPark.SlimeRancher.Regions;
-using SRMultiplayer.Networking;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using UnityEngine;
-
-namespace SRMultiplayer
-{
- public class SRMPConsole : MonoBehaviour
- {
- ConsoleWindow console = new ConsoleWindow();
- ConsoleInput input = new ConsoleInput();
-
- //
- // Create console window, register callbacks
- //
- void Awake()
- {
- DontDestroyOnLoad(gameObject);
-
- console.Initialize();
- console.SetTitle("Slime Rancher");
-
- input.OnInputText += OnInputText;
-
- Application.logMessageReceived += Application_logMessageReceived;
-
- SRMP.Log("Console Started");
- }
-
- private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
- {
- if (type == LogType.Warning)
- Console.ForegroundColor = ConsoleColor.Yellow;
- else if (type == LogType.Error)
- Console.ForegroundColor = ConsoleColor.Red;
- else
- Console.ForegroundColor = ConsoleColor.White;
-
- // We're half way through typing something, so clear this line ..
- if (Console.CursorLeft != 0)
- input.ClearLine();
-
- Console.WriteLine(condition);
- if (!string.IsNullOrEmpty(stackTrace))
- Console.WriteLine(stackTrace);
-
- // If we were typing something re-add it.
- input.RedrawInputLine();
- }
-
- //
- // Text has been entered into the console
- // Run it as a console command
- //
- void OnInputText(string obj)
- {
- var args = obj.Split(' ');
- var cmd = args.FirstOrDefault();
- args = args.Skip(1).ToArray();
-
- switch (cmd.ToLower())
- {
- case "cheat":
- {
- if (args.Length > 0)
- {
- if (args[0].Equals("money"))
- {
- if (args.Length != 2 || !int.TryParse(args[1], out int money))
- {
- SRMP.Log("Usage: cheat money ");
- }
- else
- {
- if(money > 0)
- SRSingleton.Instance.PlayerState.AddCurrency(money);
- else
- SRSingleton.Instance.PlayerState.SpendCurrency(money);
- }
- }
- else if(args[0].Equals("enable"))
- {
- //TestUI.Instance.cheat = !TestUI.Instance.cheat;
- }
- else if (args[0].Equals("keys"))
- {
- if (args.Length != 2 || !int.TryParse(args[1], out int value))
- {
- SRMP.Log("Usage: cheat keys ");
- }
- else
- {
- SRSingleton.Instance.PlayerState.model.keys = value;
- }
- }
- else if (args[0].Equals("allgadgets"))
- {
- foreach (var data in (Gadget.Id[])Enum.GetValues(typeof(Gadget.Id)))
- {
- SRSingleton.Instance.GadgetDirector.model.gadgets[data] = int.MaxValue;
- }
- foreach (var data in Identifiable.CRAFT_CLASS.Union(Identifiable.PLORT_CLASS))
- {
- SRSingleton.Instance.GadgetDirector.model.craftMatCounts[data] = int.MaxValue;
- }
- }
- else if (args[0].Equals("spawn"))
- {
- if (args.Length == 2)
- {
- if (Enum.TryParse(args[1].ToUpper(), out Identifiable.Id id))
- {
- GameObject prefab = SRSingleton.Instance.LookupDirector.GetPrefab(id);
- if (prefab != null)
- {
- SRBehaviour.InstantiateActor(prefab, SRSingleton.Instance.GameModel.player.currRegionSetId, SRSingleton.Instance.GameModel.player.GetPos() + new Vector3(0, 4, 0), Quaternion.identity, false);
- }
- else
- {
- SRMP.Log(id + " can not be spawned");
- }
- }
- else
- {
- var data = Enum.GetNames(typeof(Identifiable.Id)).Where(n => n.ToLower().Contains(args[1].ToLower()));
- SRMP.Log(args[1] + " not found. " + (data.Count() > 0 ? " Did you mean one of these?" : ""));
- foreach (var name in data)
- {
- SRMP.Log(name);
- }
- }
- }
- else if (args.Length == 3 && int.TryParse(args[2], out int amount))
- {
- if (Enum.TryParse(args[1].ToUpper(), out Identifiable.Id id))
- {
- GameObject prefab = SRSingleton.Instance.LookupDirector.GetPrefab(id);
- if (prefab != null)
- {
- for (int i = 0; i < amount; i++)
- {
- SRBehaviour.InstantiateActor(prefab, SRSingleton.Instance.GameModel.player.currRegionSetId, SRSingleton.Instance.GameModel.player.GetPos() + new Vector3(0, 4, 0), Quaternion.identity, false);
- }
- }
- else
- {
- SRMP.Log(id + " can not be spawned");
- }
- }
- else
- {
- var data = Enum.GetNames(typeof(Identifiable.Id)).Where(n => n.ToLower().Contains(args[1].ToLower()));
- SRMP.Log(args[1] + " not found. " + (data.Count() > 0 ? " Did you mean one of these?" : ""));
- foreach (var name in data)
- {
- SRMP.Log(name);
- }
- }
- }
- else
- {
- SRMP.Log("Usage: cheat spawn ()");
- }
- }
- }
- else
- {
- SRMP.Log("Available sub commands:");
- SRMP.Log("cheat money ");
- SRMP.Log("cheat keys ");
- SRMP.Log("cheat spawn ()");
- SRMP.Log("cheat allgadgets");
- }
- }
- break;
- case "tp":
- {
- if (args.Length == 1)
- {
- var player = Globals.Players.Values.FirstOrDefault(p => p.Username.Equals(args[0], StringComparison.CurrentCultureIgnoreCase));
- if (player != null)
- {
- SRSingleton.Instance.player.transform.position = player.transform.position;
- }
- else
- {
- SRMP.Log("Player not found");
- }
- }
- else
- {
- SRMP.Log("Usage: tp ");
- }
- }
- break;
- case "listplayers":
- {
- SRMP.Log("Players:");
- foreach (var player in Globals.Players.Values)
- {
- SRMP.Log(player.Username);
- }
- }
- break;
- case "sleep":
- {
- if (args.Length == 1)
- {
- SRSingleton.Instance.TimeDirector.FastForwardTo(SRSingleton.Instance.TimeDirector.HoursFromNow(float.Parse(args[0])));
- }
- }
- break;
- }
- }
-
- //
- // Update the input every frame
- // This gets new key input and calls the OnInputText callback
- //
- void Update()
- {
- input.Update();
- }
-
- //
- // It's important to call console.ShutDown in OnDestroy
- // because compiling will error out in the editor if you don't
- // because we redirected output. This sets it back to normal.
- //
- void OnDestroy()
- {
- console.Shutdown();
- }
- }
-}
\ No newline at end of file
diff --git a/SRMP/UserData.cs b/SRMP/UserData.cs
deleted file mode 100644
index c4f8959..0000000
--- a/SRMP/UserData.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace SRMultiplayer
-{
- [Serializable]
- public struct UserData
- {
- public Guid UUID;
- public bool CheckDLC;
- public List IgnoredMods;
- }
-}
diff --git a/SRMP/Compression.cs b/SRMP/Utils/Compression.cs
similarity index 100%
rename from SRMP/Compression.cs
rename to SRMP/Utils/Compression.cs
diff --git a/SRMP/Extensions.cs b/SRMP/Utils/Extensions.cs
similarity index 96%
rename from SRMP/Extensions.cs
rename to SRMP/Utils/Extensions.cs
index 0dce3e1..b67946f 100644
--- a/SRMP/Extensions.cs
+++ b/SRMP/Utils/Extensions.cs
@@ -10,6 +10,10 @@ using UnityEngine;
namespace SRMultiplayer
{
+ ///
+ /// Extends multiple objects to add extras functionality
+ ///
+ ///
public static class Extensions
{
public static void Rebuild(this RefineryUI ui)
@@ -40,6 +44,7 @@ namespace SRMultiplayer
}
}
+ #region Ammo Slot Extensions
public static void WriteAmmoSlot(this NetOutgoingMessage om, Ammo.Slot slot)
{
om.Write(slot != null);
@@ -78,7 +83,9 @@ namespace SRMultiplayer
}
return null;
}
+ #endregion
+ #region Packet Handling Extensions
public static void Send(this Packet packet, NetDeliveryMethod method = NetDeliveryMethod.ReliableOrdered, int sequence = 0)
{
if(!Globals.IsClient)
@@ -160,6 +167,10 @@ namespace SRMultiplayer
NetworkServer.Instance.SendTo(packet, cons, method, sequence);
}
+ #endregion
+
+ #region Component Handling Extensions
+
public static T CopyComponent(this T original, GameObject destination) where T : Component
{
System.Type type = original.GetType();
@@ -245,5 +256,6 @@ namespace SRMultiplayer
}
return null;
}
+ #endregion
}
}
diff --git a/SRMP/Utils/Objects.cs b/SRMP/Utils/Objects.cs
new file mode 100644
index 0000000..3c32ef3
--- /dev/null
+++ b/SRMP/Utils/Objects.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SRMultiplayer
+{
+ ///
+ /// Used marking the game time movement status
+ ///
+ public enum PauseState
+ {
+ Pause,
+ Playing
+ }
+
+ ///
+ /// Handles basic user data to be used for connection communication
+ /// Uesr ID, mod count and dlc checkers
+ ///
+ [Serializable]
+ public struct UserData
+ {
+ public Guid UUID;
+ public bool CheckDLC;
+ public List IgnoredMods;
+ }
+}
diff --git a/SRMP/Utils.cs b/SRMP/Utils/Utils.cs
similarity index 81%
rename from SRMP/Utils.cs
rename to SRMP/Utils/Utils.cs
index dc4f061..27d17ba 100644
--- a/SRMP/Utils.cs
+++ b/SRMP/Utils/Utils.cs
@@ -11,6 +11,11 @@ namespace SRMultiplayer
{
public static class Utils
{
+ ///
+ /// Loads up any resources embedded in the mod
+ ///
+ /// Name of resource
+ /// Contents of resource
public static byte[] ExtractResource(String filename)
{
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
@@ -22,7 +27,9 @@ namespace SRMultiplayer
return ba;
}
}
-
+ ///
+ /// Sets what layer the given item is at
+ ///
public static void SetLayer(GameObject obj, int layer)
{
obj.layer = layer;
@@ -31,18 +38,27 @@ namespace SRMultiplayer
SetLayer(child.gameObject, layer);
}
}
-
+ ///
+ /// Check to see if the provided values are close enough to be the same
+ ///
public static bool CloseEnoughForMe(double value1, double value2, double acceptableDifference)
{
return Math.Abs(value1 - value2) <= acceptableDifference;
}
-
+ ///
+ /// Check to see if the provided values are close enough to be the same
+ ///
public static bool CloseEnoughForMe(float value1, float value2, float acceptableDifference)
{
return Mathf.Abs(value1 - value2) <= acceptableDifference;
}
private static System.Random m_Random = new System.Random();
+
+ ///
+ /// Gets a new random actor id for netowork actors
+ ///
+ /// Random integer between in Min and int max that is not in the current sessions of NetworkActors
public static int GetRandomActorID()
{
int id = m_Random.Next(int.MinValue, int.MaxValue);
@@ -55,6 +71,11 @@ namespace SRMultiplayer
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
const long byteConversion = 1000;
+ ///
+ /// Takes a count of bytes and turns it into a human readable version
+ ///
+ /// Count of Bytes as a long
+ /// String statement of the bytes
public static string GetHumanReadableFileSize(long value)
{
diff --git a/SRMP/modinfo.json b/SRMP/modinfo.json
index b836b8c..4ff9176 100644
--- a/SRMP/modinfo.json
+++ b/SRMP/modinfo.json
@@ -1,11 +1,9 @@
-
{
"id": "srmp",
"name": "Slime Rancher Multiplayer",
- "version": "0.0.1488",
+ "version": "0.0.1510",
"author": "SatyPardus",
"dependencies": [
]
-}
-
+}