tModLoader v0.11.8.9
A mod to make and play Terraria mods
WallLoader.cs
Go to the documentation of this file.
1using Microsoft.Xna.Framework.Graphics;
2using System;
3using System.Collections.Generic;
4using System.IO;
5using Terraria.ID;
6
7namespace Terraria.ModLoader
8{
9 //todo: further documentation
13 public static class WallLoader
14 {
15 private static int nextWall = WallID.Count;
16 internal static readonly IList<ModWall> walls = new List<ModWall>();
17 internal static readonly IList<GlobalWall> globalWalls = new List<GlobalWall>();
18 private static bool loaded = false;
19
20 private static Func<int, int, int, bool>[] HookKillSound;
21 private delegate void DelegateNumDust(int i, int j, int type, bool fail, ref int num);
22 private static DelegateNumDust[] HookNumDust;
23 private delegate bool DelegateCreateDust(int i, int j, int type, ref int dustType);
25 private delegate bool DelegateDrop(int i, int j, int type, ref int dropType);
26 private static DelegateDrop[] HookDrop;
27 private delegate void DelegateKillWall(int i, int j, int type, ref bool fail);
29 private static Func<int, int, int, bool>[] HookCanExplode;
30 private delegate void DelegateModifyLight(int i, int j, int type, ref float r, ref float g, ref float b);
32 private static Action<int, int, int>[] HookRandomUpdate;
33 private static Func<int, int, int, SpriteBatch, bool>[] HookPreDraw;
34 private static Action<int, int, int, SpriteBatch>[] HookPostDraw;
35 private static Action<int, int, int, Item>[] HookPlaceInWorld;
36
37 internal static int ReserveWallID() {
38 if (ModNet.AllowVanillaClients) throw new Exception("Adding walls breaks vanilla client compatibility");
39
40 int reserveID = nextWall;
41 nextWall++;
42 return reserveID;
43 }
44
45 public static int WallCount => nextWall;
46
50 public static ModWall GetWall(int type) {
51 return type >= WallID.Count && type < WallCount ? walls[type - WallID.Count] : null;
52 }
53
54 private static void Resize2DArray<T>(ref T[,] array, int newSize) {
55 int dim1 = array.GetLength(0);
56 int dim2 = array.GetLength(1);
57 T[,] newArray = new T[newSize, dim2];
58 for (int j = 0; j < newSize && j < dim1; j++) {
59 for (int k = 0; k < dim2; k++) {
60 newArray[j, k] = array[j, k];
61 }
62 }
63 array = newArray;
64 }
65
66 internal static void ResizeArrays(bool unloading = false) {
67 Array.Resize(ref Main.wallLoaded, nextWall);
68 for (int k = WallID.Count; k < nextWall; k++) {
69 Main.wallLoaded[k] = true;
70 }
71 Resize2DArray(ref Main.wallAltTexture, nextWall);
72 Resize2DArray(ref Main.wallAltTextureInit, nextWall);
73 Resize2DArray(ref Main.wallAltTextureDrawn, nextWall);
74 Array.Resize(ref Main.wallTexture, nextWall);
75 Array.Resize(ref Main.wallHouse, nextWall);
76 Array.Resize(ref Main.wallDungeon, nextWall);
77 Array.Resize(ref Main.wallLight, nextWall);
78 Array.Resize(ref Main.wallBlend, nextWall);
79 Array.Resize(ref Main.wallLargeFrames, nextWall);
80 Array.Resize(ref Main.wallFrame, nextWall);
81 Array.Resize(ref Main.wallFrameCounter, nextWall);
82 Array.Resize(ref WallID.Sets.Conversion.Grass, nextWall);
83 Array.Resize(ref WallID.Sets.Conversion.Stone, nextWall);
84 Array.Resize(ref WallID.Sets.Conversion.Sandstone, nextWall);
85 Array.Resize(ref WallID.Sets.Conversion.HardenedSand, nextWall);
86 Array.Resize(ref WallID.Sets.Transparent, nextWall);
87 Array.Resize(ref WallID.Sets.Corrupt, nextWall);
88 Array.Resize(ref WallID.Sets.Crimson, nextWall);
89 Array.Resize(ref WallID.Sets.Hallow, nextWall);
90
91 ModLoader.BuildGlobalHook(ref HookKillSound, globalWalls, g => g.KillSound);
92 ModLoader.BuildGlobalHook(ref HookNumDust, globalWalls, g => g.NumDust);
93 ModLoader.BuildGlobalHook(ref HookCreateDust, globalWalls, g => g.CreateDust);
94 ModLoader.BuildGlobalHook(ref HookDrop, globalWalls, g => g.Drop);
95 ModLoader.BuildGlobalHook(ref HookKillWall, globalWalls, g => g.KillWall);
96 ModLoader.BuildGlobalHook(ref HookCanExplode, globalWalls, g => g.CanExplode);
97 ModLoader.BuildGlobalHook(ref HookModifyLight, globalWalls, g => g.ModifyLight);
98 ModLoader.BuildGlobalHook(ref HookRandomUpdate, globalWalls, g => g.RandomUpdate);
99 ModLoader.BuildGlobalHook(ref HookPreDraw, globalWalls, g => g.PreDraw);
100 ModLoader.BuildGlobalHook(ref HookPostDraw, globalWalls, g => g.PostDraw);
101 ModLoader.BuildGlobalHook(ref HookPlaceInWorld, globalWalls, g => g.PlaceInWorld);
102
103 if (!unloading) {
104 loaded = true;
105 }
106 }
107
108 internal static void Unload() {
109 loaded = false;
110 walls.Clear();
111 nextWall = WallID.Count;
112 globalWalls.Clear();
113 }
114
115 //change type of Terraria.Tile.wall to ushort and fix associated compile errors
116 //in Terraria.IO.WorldFile.SaveWorldTiles increase length of array by 1 from 13 to 14
117 //in Terraria.IO.WorldFile.SaveWorldTiles inside block if (tile.wall != 0) after incrementing num2
118 // call WallLoader.WriteType(tile.wall, array, ref num2, ref b3);
119 internal static void WriteType(ushort wall, byte[] data, ref int index, ref byte flags) {
120 if (wall > 255) {
121 data[index] = (byte)(wall >> 8);
122 index++;
123 flags |= 32;
124 }
125 }
126 //in Terraria.IO.WorldFile.LoadWorldTiles after setting tile.wall call
127 // WallLoader.ReadType(ref tile.wall, reader, b, modWalls);
128 //in Terraria.IO.WorldFile.ValidateWorld before if ((b2 & 16) == 16)
129 // replace fileIO.ReadByte(); with ushort wall = fileIO.ReadByte();
130 // ushort _ = 0; WallLoader.ReadType(ref wall, fileIO, b2, new Dictionary<int, int>());
131 internal static void ReadType(ref ushort wall, BinaryReader reader, byte flags, IDictionary<int, int> wallTable) {
132 if ((flags & 32) == 32) {
133 wall |= (ushort)(reader.ReadByte() << 8);
134 }
135 if (wallTable.ContainsKey(wall)) {
136 wall = (ushort)wallTable[wall];
137 }
138 }
139 //in Terraria.WorldGen.KillWall add if(!WallLoader.KillSound(i, j, tile.wall)) { } to beginning of
140 // if/else chain for playing sounds, and turn first if into else if
141 public static bool KillSound(int i, int j, int type) {
142 foreach (var hook in HookKillSound) {
143 if (!hook(i, j, type)) {
144 return false;
145 }
146 }
147 ModWall modWall = GetWall(type);
148 if (modWall != null) {
149 if (!modWall.KillSound(i, j)) {
150 return false;
151 }
152 Main.PlaySound(modWall.soundType, i * 16, j * 16, modWall.soundStyle);
153 return false;
154 }
155 return true;
156 }
157 //in Terraria.WorldGen.KillWall after if statement setting num to 3 add
158 // WallLoader.NumDust(i, j, tile.wall, fail, ref num);
159 public static void NumDust(int i, int j, int type, bool fail, ref int numDust) {
160 GetWall(type)?.NumDust(i, j, fail, ref numDust);
161
162 foreach (var hook in HookNumDust) {
163 hook(i, j, type, fail, ref numDust);
164 }
165 }
166 //in Terraria.WorldGen.KillWall before if statements creating dust add
167 // if(!WallLoader.CreateDust(i, j, tile.wall, ref int num2)) { continue; }
168 public static bool CreateDust(int i, int j, int type, ref int dustType) {
169 foreach (var hook in HookCreateDust) {
170 if (!hook(i, j, type, ref dustType)) {
171 return false;
172 }
173 }
174 return GetWall(type)?.CreateDust(i, j, ref dustType) ?? true;
175 }
176 //in Terraria.WorldGen.KillWall replace if (num4 > 0) with
177 // if (WallLoader.Drop(i, j, tile.wall, ref num4) && num4 > 0)
178 public static bool Drop(int i, int j, int type, ref int dropType) {
179 foreach (var hook in HookDrop) {
180 if (!hook(i, j, type, ref dropType)) {
181 return false;
182 }
183 }
184 return GetWall(type)?.Drop(i, j, ref dropType) ?? true;
185 }
186 //in Terraria.WorldGen.KillWall after if statements setting fail to true call
187 // WallLoader.KillWall(i, j, tile.wall, ref fail);
188 public static void KillWall(int i, int j, int type, ref bool fail) {
189 GetWall(type)?.KillWall(i, j, ref fail);
190
191 foreach (var hook in HookKillWall) {
192 hook(i, j, type, ref fail);
193 }
194 }
195
196 public static bool CanExplode(int i, int j, int type) {
197 foreach (var hook in HookCanExplode) {
198 if (!hook(i, j, type)) {
199 return false;
200 }
201 }
202 return GetWall(type)?.CanExplode(i, j) ?? true;
203 }
204 //in Terraria.Lighting.PreRenderPhase after wall modifies light call
205 // WallLoader.ModifyLight(n, num17, wall, ref num18, ref num19, ref num20);
206 public static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b) {
207 GetWall(type)?.ModifyLight(i, j, ref r, ref g, ref b);
208
209 foreach (var hook in HookModifyLight) {
210 hook(i, j, type, ref r, ref g, ref b);
211 }
212 }
213 //in Terraria.WorldGen.UpdateWorld after each call to TileLoader.RandomUpdate call
214 // WallLoader.RandomUpdate(num7, num8, Main.tile[num7, num8].wall);
215 // WallLoader.RandomUpdate(num64, num65, Main.tile[num64, num65].wall);
216 public static void RandomUpdate(int i, int j, int type) {
217 GetWall(type)?.RandomUpdate(i, j);
218
219 foreach (var hook in HookRandomUpdate) {
220 hook(i, j, type);
221 }
222 }
223 //in Terraria.Main.Update after vanilla wall animations call WallLoader.AnimateWalls();
224 public static void AnimateWalls() {
225 if (loaded) {
226 for (int i = 0; i < walls.Count; i++) {
227 ModWall modWall = walls[i];
228 modWall.AnimateWall(ref Main.wallFrame[modWall.Type], ref Main.wallFrameCounter[modWall.Type]);
229 }
230 }
231 }
232 //in Terraria.Main.DrawWalls before if statements that do the drawing add
233 // if(!WallLoader.PreDraw(j, i, wall, Main.spriteBatch))
234 // { WallLoader.PostDraw(j, i, wall, Main.spriteBatch); continue; }
235 public static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch) {
236 foreach (var hook in HookPreDraw) {
237 if (!hook(i, j, type, spriteBatch)) {
238 return false;
239 }
240 }
241 return GetWall(type)?.PreDraw(i, j, spriteBatch) ?? true;
242 }
243 //in Terraria.Main.DrawWalls after wall outlines are drawn call
244 // WallLoader.PostDraw(j, i, wall, Main.spriteBatch);
245 public static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) {
246 GetWall(type)?.PostDraw(i, j, spriteBatch);
247
248 foreach (var hook in HookPostDraw) {
249 hook(i, j, type, spriteBatch);
250 }
251 }
252
253 public static void PlaceInWorld(int i, int j, Item item) {
254 int type = item.createWall;
255 if (type < 0)
256 return;
257
258 foreach (var hook in HookPlaceInWorld) {
259 hook(i, j, type, item);
260 }
261
262 GetWall(type)?.PlaceInWorld(i, j, item);
263 }
264 }
265}
static bool AllowVanillaClients
Definition: ModNet.cs:53
This class represents a type of wall that can be added by a mod. Only one instance of this class will...
Definition: ModWall.cs:13
virtual void NumDust(int i, int j, bool fail, ref int num)
Allows you to change how many dust particles are created when the wall at the given coordinates is hi...
Definition: ModWall.cs:143
virtual bool PreDraw(int i, int j, SpriteBatch spriteBatch)
Allows you to draw things behind the wall at the given coordinates. Return false to stop the game fro...
Definition: ModWall.cs:203
virtual bool CanExplode(int i, int j)
Whether or not the wall at the given coordinates can be killed by an explosion (ie....
Definition: ModWall.cs:171
virtual void AnimateWall(ref byte frame, ref byte frameCounter)
Allows you to animate your wall. Use frameCounter to keep track of how long the current frame has bee...
Definition: ModWall.cs:197
virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
Allows you to determine how much light this wall emits. This can also let you light up the block in f...
Definition: ModWall.cs:185
virtual void RandomUpdate(int i, int j)
Called whenever the world randomly decides to update the tile containing this wall in a given tick....
Definition: ModWall.cs:191
virtual void KillWall(int i, int j, ref bool fail)
Allows you to determine what happens when the tile at the given coordinates is killed or hit with a h...
Definition: ModWall.cs:165
int soundType
The default type of sound made when this wall is hit. Defaults to 0.
Definition: ModWall.cs:42
virtual bool KillSound(int i, int j)
Allows you to customize which sound you want to play when the wall at the given coordinates is hit....
Definition: ModWall.cs:136
virtual void PlaceInWorld(int i, int j, Item item)
Called after this wall is placed in the world by way of the item provided.
Definition: ModWall.cs:216
virtual bool CreateDust(int i, int j, ref int type)
Allows you to modify the default type of dust created when the wall at the given coordinates is hit....
Definition: ModWall.cs:149
ushort Type
The internal ID of this type of wall.
Definition: ModWall.cs:33
int soundStyle
The default style of sound made when this wall is hit. Defaults to 1.
Definition: ModWall.cs:46
virtual void PostDraw(int i, int j, SpriteBatch spriteBatch)
Allows you to draw things in front of the wall at the given coordinates.
Definition: ModWall.cs:210
virtual bool Drop(int i, int j, ref int type)
Allows you to customize which items the wall at the given coordinates drops. Return false to stop the...
Definition: ModWall.cs:157
This serves as the central class from which wall-related functions are supported and carried out.
Definition: WallLoader.cs:14
static DelegateDrop[] HookDrop
Definition: WallLoader.cs:26
static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: WallLoader.cs:235
static bool CreateDust(int i, int j, int type, ref int dustType)
Definition: WallLoader.cs:168
delegate bool DelegateDrop(int i, int j, int type, ref int dropType)
static void PlaceInWorld(int i, int j, Item item)
Definition: WallLoader.cs:253
static Func< int, int, int, bool >[] HookCanExplode
Definition: WallLoader.cs:29
static DelegateKillWall[] HookKillWall
Definition: WallLoader.cs:28
static ModWall GetWall(int type)
Gets the ModWall instance with the given type. If no ModWall with the given type exists,...
Definition: WallLoader.cs:50
static Func< int, int, int, SpriteBatch, bool >[] HookPreDraw
Definition: WallLoader.cs:33
static void KillWall(int i, int j, int type, ref bool fail)
Definition: WallLoader.cs:188
static DelegateModifyLight[] HookModifyLight
Definition: WallLoader.cs:31
static Action< int, int, int, SpriteBatch >[] HookPostDraw
Definition: WallLoader.cs:34
static void NumDust(int i, int j, int type, bool fail, ref int numDust)
Definition: WallLoader.cs:159
static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: WallLoader.cs:245
static Action< int, int, int, Item >[] HookPlaceInWorld
Definition: WallLoader.cs:35
delegate void DelegateNumDust(int i, int j, int type, bool fail, ref int num)
delegate void DelegateKillWall(int i, int j, int type, ref bool fail)
static Action< int, int, int >[] HookRandomUpdate
Definition: WallLoader.cs:32
static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
Definition: WallLoader.cs:206
static DelegateNumDust[] HookNumDust
Definition: WallLoader.cs:22
static bool Drop(int i, int j, int type, ref int dropType)
Definition: WallLoader.cs:178
delegate bool DelegateCreateDust(int i, int j, int type, ref int dustType)
static void Resize2DArray< T >(ref T[,] array, int newSize)
Definition: WallLoader.cs:54
static DelegateCreateDust[] HookCreateDust
Definition: WallLoader.cs:24
static bool CanExplode(int i, int j, int type)
Definition: WallLoader.cs:196
static bool KillSound(int i, int j, int type)
Definition: WallLoader.cs:141
static void RandomUpdate(int i, int j, int type)
Definition: WallLoader.cs:216
delegate void DelegateModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
static Func< int, int, int, bool >[] HookKillSound
Definition: WallLoader.cs:20