diff --git a/source/core/defparser.cpp b/source/core/defparser.cpp
index 7e61c31ed..bdc618d7b 100644
--- a/source/core/defparser.cpp
+++ b/source/core/defparser.cpp
@@ -2351,6 +2351,47 @@ static void parseTileFlags(FScanner& sc, FScriptPosition& pos)
 	sc.SetCMode(false);
 }
 
+static void parseBreakWall(FScanner& sc, FScriptPosition& pos)
+{
+	int basetile;
+	int breaktile;
+	FName sound;
+	VMFunction* handler = nullptr;
+
+	sc.SetCMode(true);
+	sc.MustGetString();
+	basetile = TileFiles.tileForName(sc.String);
+	sc.MustGetStringName(",");
+	sc.MustGetString();
+	breaktile = TileFiles.tileForName(sc.String);
+	sc.MustGetStringName(",");
+	sc.MustGetString();
+	sound = sc.String;
+	if (sc.CheckString(","))
+	{
+		sc.MustGetString();
+
+		size_t p = strcspn(sc.String, ".");
+		if (p == 0)
+		{
+			sc.ScriptMessage("Call to undefined function %s", sc.String);
+			return;
+		}
+
+		FString clsname(sc.String, p);
+		FString funcname = sc.String + p + 1;
+		handler = PClass::FindFunction(clsname, funcname);
+		if (handler == nullptr)
+			sc.ScriptMessage("Call to undefined function %s", sc.String);
+
+		// todo: validate the function's signature. Must be (walltype, TextureID, Sound, DukeActor)
+
+	}
+	breakWallMap.Insert(basetile, { breaktile, sound, handler });
+	sc.SetCMode(false);
+}
+
+
 //===========================================================================
 //
 // 
@@ -2445,6 +2486,7 @@ static const dispatch basetokens[] =
 
 	{ "spawnclasses",		parseSpawnClasses },
 	{ "tileflag",			parseTileFlags },
+	{ "breakwall",			parseBreakWall },
 	{ nullptr,           nullptr               },
 };
 
diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h
index 6fb3b910e..ffdbcf88a 100644
--- a/source/core/gamecontrol.h
+++ b/source/core/gamecontrol.h
@@ -294,3 +294,12 @@ struct SpawnRec
 };
 using SpawnMap = TMap<int, SpawnRec>;
 inline SpawnMap spawnMap;
+
+struct BreakWallRec
+{
+	int brokentex;
+	FName breaksound;
+	VMFunction* handler;
+};
+using BreakWallMap = TMap<int, BreakWallRec>;
+inline BreakWallMap breakWallMap;
diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp
index 3198205e1..61366ddbf 100644
--- a/source/core/vmexports.cpp
+++ b/source/core/vmexports.cpp
@@ -478,8 +478,9 @@ int sector_checktexture(sectortype* sec, int place, int intname)
 	if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
 
 	int tilenum = TileFiles.tileForName(FName(ENamedName(intname)).GetChars());
-	return tilenum == place ? sec->ceilingpicnum : sec->floorpicnum;
+	return tilenum == (place == 0 ? sec->ceilingpicnum : sec->floorpicnum);
 }
+
 DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, checktexture, sector_checktexture)
 {
 	PARAM_SELF_STRUCT_PROLOGUE(sectortype);
@@ -488,11 +489,26 @@ DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, checktexture, sector_checktexture)
 	ACTION_RETURN_BOOL(sector_checktexture(self, place, name));
 }
 
-void sector_settexture(sectortype* sec, int place, int intname)
+void sector_settexturename(sectortype* sec, int place, int intname)
 {
 	if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
 	int tilenum = TileFiles.tileForName(FName(ENamedName(intname)).GetChars());
-	(place ? sec->ceilingpicnum : sec->floorpicnum) = tilenum;
+	(place == 0 ? sec->ceilingpicnum : sec->floorpicnum) = tilenum;
+}
+DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, settexturename, sector_settexturename)
+{
+	PARAM_SELF_STRUCT_PROLOGUE(sectortype);
+	PARAM_INT(place);
+	PARAM_INT(name);
+	sector_settexturename(self, place, name);
+	return 0;
+}
+
+// This is declared as TextureID but for now receives a tilenum
+void sector_settexture(sectortype* sec, int place, int tilenum)
+{
+	if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
+	(place == 0 ? sec->ceilingpicnum : sec->floorpicnum) = tilenum;
 }
 DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, settexture, sector_settexture)
 {
@@ -701,6 +717,37 @@ DEFINE_ACTION_FUNCTION_NATIVE(_walltype, twosided, wall_twosided)
 	ACTION_RETURN_BOOL(self->twoSided());
 }
 
+void wall_settexturename(walltype* sec, int place, int intname)
+{
+	if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
+	int tilenum = TileFiles.tileForName(FName(ENamedName(intname)).GetChars());
+	(place ? sec->overpicnum : sec->picnum) = tilenum;
+}
+DEFINE_ACTION_FUNCTION_NATIVE(_walltype, settexturename, wall_settexturename)
+{
+	PARAM_SELF_STRUCT_PROLOGUE(walltype);
+	PARAM_INT(place);
+	PARAM_INT(name);
+	wall_settexturename(self, place, name);
+	return 0;
+}
+
+// This is declared as TextureID but for now receives a tilenum
+void wall_settexture(walltype* sec, int place, int tilenum)
+{
+	if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
+	(place ? sec->overpicnum : sec->picnum) = tilenum;
+}
+DEFINE_ACTION_FUNCTION_NATIVE(_walltype, settexture, wall_settexture)
+{
+	PARAM_SELF_STRUCT_PROLOGUE(walltype);
+	PARAM_INT(place);
+	PARAM_INT(name);
+	wall_settexture(self, place, name);
+	return 0;
+}
+
+
 //=============================================================================
 
 void tspritetype_setSpritePic(tspritetype* targ, DCoreActor* self, unsigned z)
diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp
index 4a0297968..493c08963 100644
--- a/source/games/duke/src/game.cpp
+++ b/source/games/duke/src/game.cpp
@@ -538,4 +538,18 @@ void CallStandingOn(DDukeActor* actor, player_struct* p)
 }
 
 
+CCMD(changewalltexture)
+{
+	if (argv.argc() < 2) return;
+	int tile = TileFiles.tileForName(argv[1]);
+	if (tile < 0) tile = (int)strtol(argv[1], nullptr, 10);
+	HitInfoBase hit;
+	hitscan(ps[0].actor->spr.pos, ps[0].cursector, DVector3(ps[0].actor->spr.Angles.Yaw.ToVector(), 0) * 1024, hit, CLIPMASK1);
+	if (hit.hitWall)
+	{
+		hit.hitWall->picnum = tile;
+	}
+}
+
+
 END_DUKE_NS
diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp
index 00db10530..411bea16d 100644
--- a/source/games/duke/src/player_r.cpp
+++ b/source/games/duke/src/player_r.cpp
@@ -316,7 +316,7 @@ static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int
 
 		if (hit.actor())
 		{
-			if (hit.actor()->spr.picnum == 1930)
+			if (hit.actor()->spr.picnum == TORNADO)
 				return;
 			fi.checkhitsprite(hit.actor(), spark);
 			if (hit.actor()->isPlayer() && (ud.coop != 1 || ud.ffire == 1))
@@ -459,7 +459,7 @@ static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int a
 		scount = 1;
 		if (atwith == SHITBALL)
 		{
-			if (actor->spr.picnum == 8705)
+			if (actor->spr.picnum == MAMA)
 				vel = 37.5;
 			else
 				vel = 25;
@@ -476,7 +476,7 @@ static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int a
 	{
 		vel = 52.5;
 		pos.Z -= 4;
-		if (actor->spr.picnum == 4649)
+		if (actor->spr.picnum == HULK)
 		{
 			pos += (actor->spr.Angles.Yaw + DAngle45).ToVector() * 16;
 			pos.Z += 12;
diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp
index ac9c2c215..50fa8e186 100644
--- a/source/games/duke/src/sectors_r.cpp
+++ b/source/games/duke/src/sectors_r.cpp
@@ -33,6 +33,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
 #include "mapinfo.h"
 #include "dukeactor.h"
 #include "secrets.h"
+#include "vm.h"
 
 // PRIMITIVE
 BEGIN_DUKE_NS
@@ -869,7 +870,21 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, const DVector3& pos, int atw
 				}
 				}
 
-	switch (wal->picnum)
+	auto data = breakWallMap.CheckKey(wal->picnum);
+	if (data)
+	{
+		if (!data->handler)
+		{
+			wal->picnum = data->brokentex;
+			S_PlayActorSound(S_FindSound(data->breaksound.GetChars()), spr);
+		}
+		else
+		{
+			VMValue args[4] = { wal, data->brokentex, S_FindSound(data->breaksound.GetChars()).index(), spr };
+			VMCall(data->handler, args, 4, nullptr, 0);
+		}
+	}
+	else switch (wal->picnum)
 	{
 	case IRONWHEELSWITCH:
 		if (isRRRA()) break;
@@ -901,139 +916,6 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, const DVector3& pos, int atw
 		}
 		return;
 	}
-	case RRTILE7555:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5015;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7441:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5016;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7559:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5017;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7433:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5018;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7557:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5019;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7553:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5020;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7552:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5021;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7568:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5022;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7540:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5023;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7558:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5024;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7554:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5025;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7579:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5026;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7561:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5027;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7580:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5037;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8227:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5070;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8503:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5079;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8567:
-	case RRTILE8568:
-	case RRTILE8569:
-	case RRTILE8570:
-	case RRTILE8571:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5082;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE7859:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5081;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8496:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5061;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8617:
-		if (!isRRRA()) break;
-		if (numplayers < 2)
-		{
-			wal->picnum = RRTILE8618;
-			S_PlayActorSound(47, spr);
-		}
-		return;
-	case RRTILE8620:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE8621;
-		S_PlayActorSound(47, spr);
-		return;
-	case RRTILE8622:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE8623;
-		S_PlayActorSound(495, spr);
-		return;
-	case WEAPONCABINET:
-		if (!isRRRA()) break;
-		wal->picnum = WEAPONCABINETBROKE;
-		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-		return;
-	case RRTILE8497:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5076;
-		S_PlayActorSound(495, spr);
-		return;
-	case RRTILE7533:
-		if (!isRRRA()) break;
-		wal->picnum = RRTILE5035;
-		S_PlayActorSound(495, spr);
-		return;
-
 	case COLAMACHINE:
 	case VENDMACHINE:
 		breakwall(wal->picnum + 2, spr, wal);
diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp
index f604f1c00..daf38ab4f 100644
--- a/source/games/duke/src/vmexports.cpp
+++ b/source/games/duke/src/vmexports.cpp
@@ -486,29 +486,31 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnweaponorammo, DukeActor_spawnweap
 	ACTION_RETURN_POINTER(DukeActor_spawnweaponorammo(self, type));
 }
 
-void DukeActor_Lotsofglass(DDukeActor* origin, int count)
+void DukeActor_Lotsofglass(DDukeActor* origin, int count, walltype* wal)
 {
-	lotsofglass(origin, nullptr, count);
+	lotsofglass(origin, wal, count);
 }
 
 DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, lotsofglass, DukeActor_Lotsofglass)
 {
 	PARAM_SELF_PROLOGUE(DDukeActor);
 	PARAM_INT(count);
-	DukeActor_Lotsofglass(self, count);
+	PARAM_POINTER(wall, walltype);
+	DukeActor_Lotsofglass(self, count, wall);
 	return 0;
 }
 
-void DukeActor_Lotsofcolourglass(DDukeActor* origin, int count)
+void DukeActor_Lotsofcolourglass(DDukeActor* origin, int count, walltype* wal)
 {
-	lotsofcolourglass(origin, nullptr, count);
+	lotsofcolourglass(origin, wal, count);
 }
 
 DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, lotsofcolourglass, DukeActor_Lotsofcolourglass)
 {
 	PARAM_SELF_PROLOGUE(DDukeActor);
 	PARAM_INT(count);
-	DukeActor_Lotsofcolourglass(self, count);
+	PARAM_POINTER(wall, walltype);
+	DukeActor_Lotsofcolourglass(self, count, wall);
 	return 0;
 }
 
diff --git a/wadsrc/static/filter/redneck.ridesagain/engine/engine.def b/wadsrc/static/filter/redneck.ridesagain/engine/engine.def
index ee0343546..f5dba6aa0 100644
--- a/wadsrc/static/filter/redneck.ridesagain/engine/engine.def
+++ b/wadsrc/static/filter/redneck.ridesagain/engine/engine.def
@@ -193,4 +193,35 @@ tileflag TFLAG_BLOCKDOOR {
 	RRTILE8565
 	RRTILE8605
 	}
-	
\ No newline at end of file
+	
+	breakwall RRTILE7555, RRTILE5015, GLASS_HEAVYBREAK
+	breakwall RRTILE7441, RRTILE5016, GLASS_HEAVYBREAK
+	breakwall RRTILE7559, RRTILE5017, GLASS_HEAVYBREAK
+	breakwall RRTILE7433, RRTILE5018, GLASS_HEAVYBREAK
+	breakwall RRTILE7557, RRTILE5019, GLASS_HEAVYBREAK
+	breakwall RRTILE7553, RRTILE5020, GLASS_HEAVYBREAK
+	breakwall RRTILE7552, RRTILE5021, GLASS_HEAVYBREAK
+	breakwall RRTILE7568, RRTILE5022, GLASS_HEAVYBREAK
+	breakwall RRTILE7540, RRTILE5023, GLASS_HEAVYBREAK
+	breakwall RRTILE7558, RRTILE5024, GLASS_HEAVYBREAK
+	breakwall RRTILE7554, RRTILE5025, GLASS_HEAVYBREAK
+	breakwall RRTILE7579, RRTILE5026, GLASS_HEAVYBREAK
+	breakwall RRTILE7561, RRTILE5027, GLASS_HEAVYBREAK
+	breakwall RRTILE7580, RRTILE5037, GLASS_HEAVYBREAK
+	breakwall RRTILE8227, RRTILE5070, GLASS_HEAVYBREAK
+	breakwall RRTILE8503, RRTILE5079, GLASS_HEAVYBREAK
+	breakwall RRTILE8567, RRTILE5082, GLASS_HEAVYBREAK
+	breakwall RRTILE8568, RRTILE5082, GLASS_HEAVYBREAK
+	breakwall RRTILE8569, RRTILE5082, GLASS_HEAVYBREAK
+	breakwall RRTILE8570, RRTILE5082, GLASS_HEAVYBREAK
+	breakwall RRTILE8571, RRTILE5082, GLASS_HEAVYBREAK
+	breakwall RRTILE7859, RRTILE5081, GLASS_HEAVYBREAK
+	breakwall RRTILE8496, RRTILE5061, GLASS_HEAVYBREAK
+	breakwall RRTILE8620, RRTILE8621, WOODBREK
+	breakwall RRTILE8622, RRTILE8623, SIGNHIT
+	breakwall WEAPONCABINET, WEAPONCABINETBROKE, GLASS_HEAVYBREAK
+	breakwall RRTILE8497, RRTILE5076, SIGNHIT
+	breakwall RRTILE7533, RRTILE5035, SIGNHIT
+	breakwall RRTILE8617, RRTILE8618, WOODBREK, "RedneckBreakwalls.SinglePlayerBreak"
+		
+
diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt
index ec58143a1..94e55e32f 100644
--- a/wadsrc/static/zscript.txt
+++ b/wadsrc/static/zscript.txt
@@ -115,6 +115,8 @@ version "4.10"
 #include "zscript/games/duke/actors/airplane.zs"
 #include "zscript/games/duke/actors/piano.zs"
 
+#include "zscript/games/duke/world/redneckbreak.zs"
+
 #include "zscript/games/blood/bloodgame.zs"
 #include "zscript/games/blood/ui/menu.zs"
 #include "zscript/games/blood/ui/sbar.zs"
diff --git a/wadsrc/static/zscript/games/duke/actors/destructibles.zs b/wadsrc/static/zscript/games/duke/actors/destructibles.zs
index 91d626b33..d40283e34 100644
--- a/wadsrc/static/zscript/games/duke/actors/destructibles.zs
+++ b/wadsrc/static/zscript/games/duke/actors/destructibles.zs
@@ -129,7 +129,7 @@ class DukeFanSprite : DukeActor
 			self.setSpriteSetImage(1);
 			self.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
 			if (self.sector.CheckTexture(sectortype.floor, "FANSHADOW"))
-				self.sector.SetTexture(sectortype.floor, "FANSHADOWBROKE");
+				self.sector.SetTextureName(sectortype.floor, "FANSHADOWBROKE");
 
 			self.PlayActorSound("GLASS_HEAVYBREAK");
 			for (int j = 0; j < 16; j++) self.RANDOMSCRAP();
diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs
index 4209a9da0..e0fd9bd1c 100644
--- a/wadsrc/static/zscript/games/duke/dukeactor.zs
+++ b/wadsrc/static/zscript/games/duke/dukeactor.zs
@@ -171,8 +171,8 @@ class DukeActor : CoreActor native
 	native DukeActor spawn(Name type);
 	native DukeActor spawnsprite(int type);	// for cases where the map has a picnum stored. Avoid when possible.
 	native DukeActor spawnweaponorammo(int type);
-	native void lotsofglass(int count);
-	native void lotsofcolourglass(int count);
+	native void lotsofglass(int count, walltype wal = null);
+	native void lotsofcolourglass(int count, walltype wal = null);
 	native void makeitfall();
 	native void detonate(name type);
 	native void checkhitdefault(DukeActor proj);
diff --git a/wadsrc/static/zscript/games/duke/world/redneckbreak.zs b/wadsrc/static/zscript/games/duke/world/redneckbreak.zs
new file mode 100644
index 000000000..3f4e72090
--- /dev/null
+++ b/wadsrc/static/zscript/games/duke/world/redneckbreak.zs
@@ -0,0 +1,22 @@
+// Container for handler functions that handle walls with breakable textures
+struct RedneckBreakWalls
+{
+
+	static void breakwall(TextureID newpn, DukeActor spr, walltype wal)
+	{
+		wal.SetTexture(walltype.main, newpn);
+		spr.PlayActorSound("VENT_BUST");
+		spr.PlayActorSound("GLASS_HEAVYBREAK");
+		spr.lotsofglass(10, wal);
+	}
+
+	static void SinglePlayerBreak(walltype wal, TextureID newtex, Sound snd, DukeActor hitter)
+	{
+		if (ud.multimode < 2)
+		{
+			wal.SetTexture(walltype.main, newtex);
+			hitter.PlayActorSound(snd);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/wadsrc/static/zscript/maptypes.zs b/wadsrc/static/zscript/maptypes.zs
index 2bee29735..ec6187da9 100644
--- a/wadsrc/static/zscript/maptypes.zs
+++ b/wadsrc/static/zscript/maptypes.zs
@@ -241,7 +241,8 @@ struct sectortype native
 	native double, double getslopes(Vector2 pos);
 	native sectortype nextsectorneighborz(double refz, int find);
 	native bool CheckTexture(int place, Name tex);
-	native void SetTexture(int place, Name tex);
+	native void SetTextureName(int place, Name tex);
+	native void SetTexture(int place, TextureID tex);
 
 }
 
@@ -253,6 +254,11 @@ struct sectortype native
 
 struct walltype native
 {
+	enum EPlane
+	{
+		main = 0,
+		over = 1,
+	}
 	native readonly Vector2 pos;
 
 	native readonly int point2;
@@ -296,6 +302,8 @@ struct walltype native
 	native double Length();
 	native void move(Vector2 vec);
 	native void dragpoint(Vector2 vec);
+	native void SetTextureName(int place, Name tex);
+	native void SetTexture(int place, TextureID tex);
 }
 
 //=============================================================================