File: Exit.pm

package info (click to toggle)
perlmoo 0.045
  • links: PTS
  • area: main
  • in suites: slink
  • size: 404 kB
  • ctags: 242
  • sloc: perl: 5,211; makefile: 111; sh: 77
file content (125 lines) | stat: -rw-r--r-- 3,127 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# An exit is an object that sits in one room and provides a link to
# another room. They typically come in pairs (so you can go back).

package Exit;
use Utils;
use strict;
use vars qw(@ISA);
use Thing;
use UNIVERSAL qw(isa);
@ISA=qw{Thing};

sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $this  = Thing::new($class,@_);	
	bless ($this, $class);
	return $this;
}

# Move the calling object through to the room I'm linked to.
#
# As a special fetaure, you can type "go foo bar baz", and
# it will automatically run each of the go commands in sequence.
sub verb_go {
	my $this=shift;
	my $verbcall=shift;

	if (! isa($this->destination,"Room")) {
       		return "You can't go there."
	}

	$verbcall->caller->tell($this->message);
	$verbcall->caller->location->announce($verbcall->caller,$verbcall->caller->name." goes ".$this->name.".");
	$verbcall->caller->location->contents_remove($verbcall->caller);
	$this->destination->announce($verbcall->caller,$verbcall->caller->name." has arrived.");
	$verbcall->caller->location($this->destination);
	$verbcall->caller->location->contents_add($verbcall->caller);

	# If this is a compound go command, things get ugly.
	my ($v,@words)=$verbcall->words;
	shift(@words);
	if (@words && $words[0]) {
		$verbcall->words($v,@words);
		my $thing;
		foreach $thing (@{$verbcall->caller->location->exits}) {
			if ($thing && $thing->isalias($verbcall->word('direct_object'))) {
				$verbcall->direct_object($thing);
				$verbcall->object($thing);
				my $sub=$thing->getverbsub($verbcall);
				if (defined $sub) {
					return $thing->$sub($verbcall);
				}
			}
		}
		
		# Well that failed - call the go verb on the room we're in
		# as a last resort.
		return $verbcall->caller->location->verb_go($verbcall);
	}
	
	return;
}

# A bit of sanity checking on destination setting.
sub destination {
	my $this=shift;
	if (@_) {
		my $dest=shift;
		if (! isa($dest,"Room")) {
			Utils::Log("notice","Tried to link an exit to a non-room object.");
			return Error->new("Cannot link an exit to a non-room object.");
		}
		return Thing::destination($this,$dest);
	}
	else {
		return Thing::destination($this);
	}
}

# Override the name method, because when the name of an exit is 
# set, it sets a verb too.
sub name {
	my $this=shift;
	if (@_) {
		my $name=shift;
		if ($this->name ne undef) {
			$this->removeverb($this->name);
		}
		if ($name ne undef) {
		my @verbs=$this->listverbs;
			$this->addverb(Verb->new(sub => 'verb_go',command => $name));
		}
		return Thing::name($this,$name);
	}
	else {
		return Thing::name($this);
	}
}

# Override the alias method, because when the alias of an exit is set,
# it sets a verb too.
sub aliases {
	my $this=shift;
	if (@_) {
		my $value=shift;
		# Remove all old verbs.
		if (ref Thing::Aliases($this) eq 'ARRAY') {
			my $alias;
			foreach $alias (@{Thing::Aliases($this)}) {
				$this->removeverb($alias);
			}
		}

		# Set new aliases and verbs.
		foreach (@$value) {
			$this->addverb(Verb->new(sub => 'verb_go', command => $_));
		}
		return Thing::aliases($this,$value);
	}
	else {
		return Thing::aliases($this);
	}
}

1;