#!/usr/bin/perl
# The way this works for now is that whoever the whisper is
# directed to hears it with 90% accuracy. Others in the room either
# don't notice it (10%), notice it, but don't hear anything specific 
# (50%), or hear parts of it, with between 5 and 50% accuracy.
#
# Of course, if there was info about the size of room, locations of
# people in it, etc, the numbers could be more meaningful.

#use Mooix::Thing;
#use Mooix::Root;

my $animate=$Mooix::Root->abstract->animate;
my $container=$Mooix::Root->concrete->container;

my @mumbles=qw{mumble mumble mutter mutter};

sub distort {
	my $word=shift;
	my $prob=shift;

	if (rand > $prob) {
		return @mumbles[rand @mumbles];
	}
	else {
		return $word;
	}
}

sub gentext {
        my $quote=shift;
        my $accuracy=shift;

	$quote =~ s/(\w+)/distort($1, $accuracy)/eg;
	return $quote;
}

sub tellavatars {
	my $this=shift;
	my $container=shift;
	%_=@_;
	my $recipient=$_{direct_object};

	foreach my $obj ($container->contents->list) {
		if ($obj->isa($animate) && $obj->aware &&
		    $obj != $this && $obj != $recipient) {
			my $r=rand();
			if ($r <= 0.5 || ! $recipient) {
				$this->msg(($recipient ? 'directed_whisper' : 'whisper'), onlyto => $obj, %_);
			}
			elsif ($r <= 0.9) {
				$this->msg('overhear', onlyto => $obj, %_,
					quote => gentext($_{quote}, (0.05 + rand(0.45))));
			}
		}
		elsif ($obj->isa($container)) {
			tellavatars($this, $obj, %_);
		}
	}
}

run sub {
	my $this=shift;
	%_=@_;
	my $avatar=$_{avatar};
	my $recipient=$_{direct_object};
	
	# Make sure that this command is not spoofed, just in case.
        if ($_{avatar} != $this) {
		fail "No!"; 
	}
	
	$this->msg('whisperto', onlyto => $recipient, %_, 
				quote => gentext($_{quote}, 0.9))
		if $recipient && $recipient != $avatar;
				
	# First, find the topmost container.
	my $room=$this->location;
	$room=$room->location while ref $room->location;
	
	# Recurse through containers, telling the message to some avatars only.
	tellavatars($this, $room, %_);

	$this->msg(($recipient ? 'directed_whisper' : 'whisper'), %_, onlyto => $this);
}
