Repository: evennia/evennia

Issue:
@tunnel doesn't support setting the exit typeclass
#### Brief summary of issue / Description of requested feature:
I was creating tunnel locations and would go and change the typeclass for the exit after the object was already created, this would break all the connetions from room to room. After looking further it appears the tunnel class doesn't have the ability to accept a typeclass for the exit

digstring = "@dig%s %s = %s;%s%s" % (telswitch, roomname,
                                             exitname, exitshort, backstring)
the dig string is passed from tunnel class into @dig this doesn't allow one to pass exit to and here typeclass on creation

@dig[/switches] <roomname>[;alias;alias...][:typeclass]
            [= <exit_to_there>[;alias][:typeclass]]
               [, <exit_to_here>[;alias][:typeclass]]

#### Steps to reproduce the issue / Reasons for adding feature:

1. @tunnel e = supply shop
2.  @typeclass e = typeclasses.exit.door.Door
3.  All room connections break

#### Error output / Expected result of feature
cant move from room to room

#### Extra information, such as Evennia revision/repo/branch, operating system and ideas for how to solve / implement:



Discussion:

Resolving patch:
diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py
--- a/evennia/commands/default/building.py
+++ b/evennia/commands/default/building.py
@@ -866,7 +866,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
     create new rooms in cardinal directions only
 
     Usage:
-      @tunnel[/switch] <direction> [= <roomname>[;alias;alias;...][:typeclass]]
+      @tunnel[/switch] <direction>[:typeclass] [= <roomname>[;alias;alias;...][:typeclass]]
 
     Switches:
       oneway - do not create an exit back to the current location
@@ -911,21 +911,34 @@ def func(self):
         """Implements the tunnel command"""
 
         if not self.args or not self.lhs:
-            string = "Usage: @tunnel[/switch] <direction> [= <roomname>" \
+            string = "Usage: @tunnel[/switch] <direction>[:typeclass] [= <roomname>" \
                      "[;alias;alias;...][:typeclass]]"
             self.caller.msg(string)
             return
-        if self.lhs not in self.directions:
+
+        # If we get a typeclass, we need to get just the exitname
+        exitshort = self.lhs.split(":")[0]
+
+        if exitshort not in self.directions:
             string = "@tunnel can only understand the following directions: %s." % ",".join(
                     sorted(self.directions.keys()))
             string += "\n(use @dig for more freedom)"
             self.caller.msg(string)
             return
+
         # retrieve all input and parse it
-        exitshort = self.lhs
         exitname, backshort = self.directions[exitshort]
         backname = self.directions[backshort][0]
 
+        # if we recieved a typeclass for the exit, add it to the alias(short name)
+        if ":" in self.lhs:
+            # limit to only the first : character
+            exit_typeclass = ":" + self.lhs.split(":", 1)[-1]
+            # exitshort and backshort are the last part of the exit strings,
+            # so we add our typeclass argument after
+            exitshort += exit_typeclass
+            backshort += exit_typeclass
+
         roomname = "Some place"
         if self.rhs:
             roomname = self.rhs  # this may include aliases; that's fine.


Test patch:
diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py
--- a/evennia/commands/default/tests.py
+++ b/evennia/commands/default/tests.py
@@ -266,6 +266,9 @@ def test_dig(self):
     def test_tunnel(self):
         self.call(building.CmdTunnel(), "n = TestRoom2;test2", "Created room TestRoom2")
 
+    def test_tunnel_exit_typeclass(self):
+        self.call(building.CmdTunnel(), "n:evennia.objects.objects.DefaultExit = TestRoom3", "Created room TestRoom3")
+
     def test_exit_commands(self):
         self.call(building.CmdOpen(), "TestExit1=Room2", "Created new Exit 'TestExit1' from Room to Room2")
         self.call(building.CmdLink(), "TestExit1=Room", "Link created TestExit1 > Room (one way).")