Skip to content

Commit

Permalink
Provide access to method that handles commands (tModLoader#608)
Browse files Browse the repository at this point in the history
* Provide access to method that handles commands
-Move startDedInputCallBack functionality to ExecuteCommand method
-Update startDedInputCallBack method to use ExecuteCommand
-Add ExecuteCommand method which takes a string and CommandCaller for allowing execution of commands from other areas

* Add support for ModSigns and provide ExampleCommandSign
-Remove hardcode check for sign types in Version1 load
-Move Sign checking to after loading ModTiles to ensure modded signs load appropriately
-Provide ExampleCommandSign tile and item which details how to create a ModSign and use ExecuteCommand method

* Add reviewer changes
-Remove extra whitespace from WorldFile class
-Remove accidental using from WorldFile class
-Shorten ExampleCommandSign method to two lines using StringOptions

* Undo Version1 read changes, add multiplayer support, shorten patch size for Version2 read
-Remove ReadWorld_Version1 patch
-Adjust ReadWorld_Version2 patch to be smaller
-Create new ValidateSigns method to WorldIO class that makes sure signs are active tiles (moved from ReadWorld_Version2)
-Use ValidateSigns method in TileIO.LoadTiles
-Adjust NetMessage to support and transmit sign data for sign tiles

* Adjust network sending to add support for "sign-sized" signs
-Adjust packet sending to also send mod sign data when processing signs

* Add override that sets initial text on sign when placed + one minor change
-Add PlaceInWorld override that sets text of sign
-Add parenthesis to condition statement for clarity of precedence

* Minor bugfixes

Co-authored-by: Chicken-Bones <mehvids@gmail.com>
  • Loading branch information
xNarnia and Chicken-Bones authored Mar 3, 2020
1 parent 7bba821 commit c31e56d
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 3 deletions.
37 changes: 37 additions & 0 deletions ExampleMod/Items/Placeable/ExampleCommandSign.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Terraria.ID;
using Terraria.ModLoader;

namespace ExampleMod.Items.Placeable
{
public class ExampleCommandSign : ModItem
{
public override void SetStaticDefaults()
{
Tooltip.SetDefault("This is a modded sign.");
}

public override void SetDefaults()
{
item.width = 26;
item.height = 22;
item.maxStack = 99;
item.useTurn = true;
item.autoReuse = true;
item.useAnimation = 15;
item.useTime = 10;
item.useStyle = 1;
item.consumable = true;
item.value = 500;
item.createTile = mod.TileType("ExampleCommandSign");
}

public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.AddIngredient(ItemID.Sign);
recipe.AddIngredient(mod.ItemType("ExampleBlock"), 6);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
}
Binary file added ExampleMod/Items/Placeable/ExampleCommandSign.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 110 additions & 0 deletions ExampleMod/Tiles/ExampleCommandSign.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.DataStructures;
using Terraria.Enums;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace ExampleMod.Tiles
{
public class ExampleCommandSign : ModTile
{
public override void SetDefaults()
{
// Credits to Dark;Light for finding this flag
// Keep in mind that the max amount of signs is 1000 (the size of the tileSign array)
// The Main.tileSign flag will do the following:
// *Automatically manages the sign for the specified tile
// -Adds a right-click to the tile to bring up an edit sign window
// -Allows editing of the sign text
// -Saves and loads sign data to world file
Main.tileSign[Type] = true;
Main.tileFrameImportant[Type] = true;
Main.tileLavaDeath[Type] = true;

// Allow hanging from ceilings
TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2);
TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile);
TileObjectData.newAlternate.StyleHorizontal = true;
TileObjectData.newAlternate.Origin = new Point16(0, 0);
TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide, 2, 0);
TileObjectData.newAlternate.AnchorBottom = AnchorData.Empty;
TileObjectData.addAlternate(1);

// Allow attaching to a solid object that is to the left of the sign
TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile);
TileObjectData.newAlternate.StyleHorizontal = true;
TileObjectData.newAlternate.Origin = new Point16(0, 0);
TileObjectData.newAlternate.AnchorLeft = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide, 2, 0);
TileObjectData.newAlternate.AnchorBottom = AnchorData.Empty;
TileObjectData.addAlternate(2);

// Allow attaching to a solid object that is to the right of the sign
TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile);
TileObjectData.newAlternate.StyleHorizontal = true;
TileObjectData.newAlternate.Origin = new Point16(0, 0);
TileObjectData.newAlternate.AnchorRight = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide, 2, 0);
TileObjectData.newAlternate.AnchorBottom = AnchorData.Empty;
TileObjectData.addAlternate(3);

// Allow attaching to a wall behind the sign
TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile);
TileObjectData.newAlternate.StyleHorizontal = true;
TileObjectData.newAlternate.Origin = new Point16(0, 0);
TileObjectData.newAlternate.AnchorWall = true;
TileObjectData.newAlternate.AnchorBottom = AnchorData.Empty;
TileObjectData.addAlternate(4);
TileObjectData.addTile(Type);
ModTranslation name = CreateMapEntryName();
name.SetDefault("Example Command Sign");
AddMapEntry(new Color(200, 200, 200), name);
dustType = mod.DustType("Sparkle");
disableSmartCursor = true;
adjTiles = new int[] { Type };
}

public override bool HasSmartInteract()
{
return true;
}

public override void PlaceInWorld(int i, int j, Item item)
{
Main.sign[Sign.ReadSign(i, j, true)].text = "Type in a command, right-click sign to activate it!";
}

public override void RightClick(int i, int j)
{
// Uses the text from the sign to run a command
Main.ExecuteCommand(Main.sign[Sign.ReadSign(i, j, true)].text, new ExampleCommandCaller());
}

public override void NumDust(int i, int j, bool fail, ref int num)
{
num = fail ? 1 : 3;
}

public override void KillMultiTile(int i, int j, int frameX, int frameY)
{
Item.NewItem(i * 16, j * 16, 32, 32, mod.ItemType("ExampleCommandSign"));
Sign.KillSign(i, j);
}

// When a command is finished executing, it will return the output of the command
// via the Reply method. Console commands do not return output, only ModCommands
public class ExampleCommandCaller : CommandCaller
{
public CommandType CommandType => CommandType.Console;

public Player Player => null;

public void Reply(string text, Color color = default(Color))
{
foreach (string value in text.Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries))
Main.NewText(value);
}
}
}
}
Binary file added ExampleMod/Tiles/ExampleCommandSign.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions patches/tModLoader/Terraria.IO/WorldFile.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@
{
writer.Write(nPC2.active);
writer.Write(nPC2.netID);
@@ -2181,7 +_,7 @@
int num3 = reader.ReadInt32();
Tile tile = Main.tile[num2, num3];
Sign sign;
- if (tile.active() && Main.tileSign[(int)tile.type])
+ if (true) //if (tile.active() && Main.tileSign[(int)tile.type])
{
sign = new Sign();
sign.text = text;
@@ -2302,7 +_,7 @@
{
Stream baseStream = fileIO.BaseStream;
Expand Down
1 change: 1 addition & 0 deletions patches/tModLoader/Terraria.ModLoader.IO/TileIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ internal static void LoadTiles(TagCompound tag) {
using (var memoryStream = new MemoryStream(tag.GetByteArray("data")))
using (var reader = new BinaryReader(memoryStream))
ReadTileData(reader, tables);
WorldIO.ValidateSigns();
}

internal static void LoadLegacyTiles(BinaryReader reader) {
Expand Down
11 changes: 11 additions & 0 deletions patches/tModLoader/Terraria.ModLoader.IO/WorldIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,17 @@ public static void ReceiveModData(BinaryReader reader) {
}
}

public static void ValidateSigns() {
for (int i = 0; i < Main.sign.Length; i++) {
if (Main.sign[i] != null) {
Tile tile = Main.tile[Main.sign[i].x, Main.sign[i].y];
if (!(tile.active() && Main.tileSign[(int)tile.type])) {
Main.sign[i] = null;
}
}
}
}

private static void LoadLegacy(byte[] buffer) {
const int numByteFlags = 1;
using (MemoryStream stream = new MemoryStream(buffer)) {
Expand Down
30 changes: 27 additions & 3 deletions patches/tModLoader/Terraria/Main.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,23 @@
}
}

@@ -4375,8 +_,15 @@
{
while (!Netplay.disconnect)
{
+ string text = Console.ReadLine();
+ ExecuteCommand(text, new ConsoleCommandCaller());
+ }
+ }
+
+ public static void ExecuteCommand(string text, CommandCaller commandCaller)
+ {
+ {
Console.Write(": ");
- string text = Console.ReadLine();
string text2 = text;
text = text.ToLower();
try
@@ -4423,13 +_,23 @@
num = text3.Length;
}
Expand All @@ -674,7 +691,7 @@
+ foreach (var entry in modHelpList)
+ Console.WriteLine(entry.Item1 + new string('\t', num2 - entry.Item1.Length / 8) + entry.Item2);
+ }
+ else if (CommandManager.HandleCommand(text, new ConsoleCommandCaller())) {}
+ else if (CommandManager.HandleCommand(text, commandCaller)) {}
else if (text == Language.GetTextValue("CLI.Settle_Command"))
{
if (!Liquid.panicMode)
Expand All @@ -687,14 +704,21 @@
}
else
{
@@ -4556,6 +_,7 @@
@@ -4556,11 +_,12 @@
try
{
Console.Clear();
- continue;
+ Logging.ResetPastExceptions(); // "CLI.Clear_Command" above.
continue;
+ return;
}
catch
{
- continue;
+ return;
}
}
if (text == Language.GetTextValue("CLI.Playing_Command"))
@@ -4761,7 +_,7 @@
Main.instance = this;
#if CLIENT
Expand Down
9 changes: 9 additions & 0 deletions patches/tModLoader/Terraria/NetMessage.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@
{
short num8 = (short)Chest.FindChest(j, i);
if (num8 != -1)
@@ -1625,7 +_,7 @@
arg_240_0[(int)expr_238] = num10;
}
}
- if (tile2.type == 425 && tile2.frameX % 36 == 0 && tile2.frameY % 36 == 0)
+ if ((tile2.type == 425 || tile2.type >= TileID.Count && Main.tileSign[tile2.type]) && tile2.frameX % 36 == 0 && tile2.frameY % 36 == 0)
{
short num11 = (short)Sign.ReadSign(j, i, true);
if (num11 != -1)
@@ -1679,7 +_,17 @@
if (tile2.wall != 0)
{
Expand Down

0 comments on commit c31e56d

Please sign in to comment.