sub update{
#$time=time;
my $time=$lastupdate;
until($time>time) {
if (defined($do{$time})){
# print "aaaa!\n";
while (@{$do{$time}}){
print "@{$do{$time}[0]{args}}\n";
&{$do{$time}[0]{sub}}(@{$do{$time}[0]{args}});
shift @{$do{$time}};
}
}
$time++;
}
if (time-$mediumupdate>30){
print ".";
$mediumupdate=time;
&mediumupdate;
}
if (time-$longupdate>300){
print "-";
$longupdate=time;
&longupdate;
}
foreach $a (keys %outbuffer) {
if (defined($user{$a}{monster})){
local $incoming;
$incoming=$outbuffer{$a};
delete $outbuffer{$a};
local $client=$a;
if (defined(&{$monster[$user{$a}{monster}]{script}})){
&{$monster[$user{$a}{"monster"}]{script}};
}
}
}
foreach $a (keys %user){
if ($user{$a}{round}){
$user{$a}{round}--;
}
if ($user{$a}{stun}){
$user{$a}{stun}--;
}
if($user{$a}{dead}){
if (time-$user{$a}{dead}>10){
if (defined($user{$a}{monster})){
#monster is dead
print "monster $user{$a}{name} should decay\n";
say("the dead body of $user{$a}{name} decays into nothingness.",$user{$a}{room});
monsterdecay($a);
next;
}
else {
print "player $user{$a}{name} should pass away\n";
playerdecay($a);
#player is dead
next;
}
}
}
foreach $b (keys %{$user{$a}{exp}}){
foreach $c (keys %{$user{$a}{exp}{$b}}){
if ($user{$a}{exp}{$b}{$c}{pool}>0){
# print "c\n";
my $increase=0;
if ($user{$a}{exp}{$b}{$c}{pool}>($user{$a}{disc}*100)){
$increase=int($user{$a}{wis}/5);
}
elsif ($user{$a}{exp}{$b}{$c}{pool}>300){
# print "e\n";
$increase=$user{$a}{wis}+(int(($user{$a}{exp}{$b}{$c}{pool}-300)/300)*3);
}
else {
# print "x\n";
$increase=int($user{$a}{wis}/5);
}
# print "increase=$increase\n\n";
if ($user{$a}{exp}{$b}{$c}{pool}>=$increase){
$user{$a}{exp}{$b}{$c}{pool}-=$increase;
$user{$a}{exp}{$b}{$c}{expcur}+=$increase;
}
else {
$user{$a}{exp}{$b}{$c}{expcur}+=$user{$a}{exp}{$b}{$c}{pool};
$user{$a}{exp}{$b}{$c}{pool}=0;
}
my $ranks=0;
while ($user{$a}{exp}{$b}{$c}{expcur}>=$user{$a}{exp}{$b}{$c}{expneeded}){
print "cur=$user{$a}{exp}{$b}{$c}{expcur}\n$c\n$b\n";
print keys %{$user{$a}{exp}{$b}{$c}};
my $d=$user{$a}{exp}{$b}{$c}{expcur}-$user{$a}{exp}{$b}{$c}{expneeded};
$user{$a}{exp}{$b}{$c}{ranks}+=1;
$ranks++; $user{$a}{exp}{$b}{$c}{expneeded}=($user{$a}{exp}{$b}{$c}{ranks}*$user{$a}{exp}{$b}{$c}{ranks})*100;
$user{$a}{exp}{$b}{$c}{expcur}=$d;
}
if ($ranks==1){
$outbuffer{$a}.="\r\nYou earn a rank of $c \r\n$prompt";
}
elsif ($ranks>1){
$outbuffer{$a}.="\r\nYou earn $ranks ranks of $c\r\n$prompt";
}
}
}
}
}
}
sub mediumupdate {
print ".";
foreach $a (keys %user){
unless (defined ($user{$a}{vitality})){
next;
}
$user{$a}{vitality}+=$user{$a}{con};
if ($user{$a}{vitality}>$user{$a}{vitalitymax}){
$user{$a}{vitality}=$user{$a}{vitalitymax}
}
foreach $b (keys %{$user{$a}{health}}){
if (defined($user{$a}{health}{$b}{requires})){
my $c=$user{$a}{health}{$b}{requires};
if ($user{$a}{health}{$c}{hp}<=0){
next;
}
}
if ($user{$a}{health}{$b}{bleeding}){
# print "doing $user{$a}{health}{$b}{bleeding} bleeding damage from $user{$a}{vitality}\n";
$user{$a}{vitality}-=$user{$a}{health}{$b}{bleeding}
}
if ($user{$a}{health}{$b}{intbleeding}){
# print "doing $user{$a}{health}{$b}{intbleeding} intbleeding damage from $user{$a}{vitality}\n";
$user{$a}{vitality}-=$user{$a}{health}{$b}{intbleeding}
}
#print "$b-$user{$a}{health}{$b}{bleeding}-$user{$a}{health}{$b}{intbleeding}--";
}
if ($user{$a}{vitality}<=0 and (!$user{$a}{dead})){
#print "$user{$a}{vitality}\n";
died($a);
}
}
}
sub longupdate {
foreach $node (@node){
$a=rand(10);
if (${$node}{max}>${$node}{maxused}){
if ($a<${$node}{prob}){
#print"a\n";
${$node}{maxused}++;
my $d=int(rand(@{${$node}{monsters}}));
#print "d=$d\n";
createmonster(${$node}{monsters}[$d],${$node}{room},$node);
}
}
}
foreach $a ($select->handles){
#only checking actual people, monsters can't be inactive after all.
unless (defined($user{$a})){
#don't ask me why but there is one in here thats not a person. so we skip it.
next;
}
unless (defined($user{$a}{name})){
next;
}
if (defined($last{$a}) and (time-$last{$a}>500)){
$outbuffer{$a}.="You have been inactive for too long.\r\n$prompt";
}
if (defined($last{$a}) and (time-$last{$a}>600)){
print "removing $a for inactivity\n";
&delete($a);
next;
}
}
}
sub createmonster {
$mon=shift;
$room=shift;
$node=shift;
unless(defined($monster[$mon])){
return;
}
print "creating a $monster[$mon]{name} monster\n";
local $client="monster".$monstertotal++;
unless (loadplayer($monster[$mon]{name}, $client, "monsters")){
print "Error\r\n";
}
my $z=int(rand(@{$monster[$mon]{adjectives}}));
$user{$client}{monster}=$mon;
$user{$client}{node}=$node;
$user{$client}{room}=$room;
$user{$client}{desc}=$monster[$mon]{desc};
$outbuffer{$client}.="Welcome to the world.\n";
$user{$client}{name}=$monster[$mon]{adjectives}[$z]." $monster[$mon]{name}";
$user{$client}{pre}=$monster[$mon]{pre};
$room[$user{$client}{room}]{in}{$client}=$user{$client}{name};
if (defined($monster[$mon]{birthline})){
my $a=$monster[$mon]{birthline};
$a=~s/\[(.*?)\]/$user{$client}{$1}/isg;
say("$a");
}
else {
say("$user{$client}{name} suddenly spawns before your eyes.");
}
my $time=time;
if (defined($monster[$mon]{scriptbirth})){
&{$monster[$mon]{scriptbirth}};
}
#push (@{$do{$time+10}},{sub=>"say", args=>["hello","$user{$client}{room}"]})
}
sub addexp {
my $skill=shift;
my $skilltype=shift;
my $amount=shift;
my $client=(shift or $client);
unless($client){
my $client=shift;
}
unless ($skilltype and $amount and $skill){
return;
}
unless ($user{$client}){
print "error with adding exp, no user{client}\n\n";
return;
}
unless (defined($user{$client}{exp}{$skilltype})){
#print "zzz\n";
$user{$client}{exp}{$skilltype}={total=>0};
}
unless(defined($user{$client}{exp}{$skilltype}{$skill})){
print "AZXCD\n";
$user{$client}{exp}{$skilltype}{$skill}={pool=>0,ranks=>0,expcur=>0,expneeded=>50};
}
my $maxpool=$user{$client}{disc}*100;
if ($user{$client}{exp}{$skilltype}{$skill}{pool}>=$maxpool){
$outbuffer{$client}.="Your head aches from absorbing $skill and you learn very little\r\n$prompt";
$user{$client}{exp}{$skilltype}{$skill}{pool}+=$amount/100;
return 0;
}
$user{$client}{exp}{$skilltype}{$skill}{pool}+=$amount;
if ($user{$client}{exp}{$skilltype}{$skill}{pool}>=$maxpool){
$outbuffer{$client}.="Your head begins to hurt from absorbing $skill and you learn very little\r\n$prompt";
}
}
sub died {
my $dead=shift;
print "$user{$dead}{name} has died!!!\n";
say2("$user{$dead}{name} falls dead",$user{$dead}{room},"You fall to the ground dead",$dead);
$user{$dead}{dead}=time;
$user{$dead}{position}="lying";
$user{$dead}{roomdesc}="the dead body of $user{$dead}{name} lies here";
$type{$dead}="dead";
}
sub say {
$message=shift;
my $room=(shift or $user{$client}{room});
foreach $a (keys %{$room[$room]{in}}){
$outbuffer{$a}.="$message\r\n$prompt";
}
}
sub say2 {
$message=shift;
$room=shift;
$message2=shift;
$ignore=shift;
foreach $a (keys %{$room[$room]{in}}){
#print "$a\n";
if ($a eq "$ignore"){
if ($message2){
$outbuffer{$a}.="$message2\r\n$prompt";
}
}
else {
$outbuffer{$a}.="$message\r\n$prompt";
}
}
}
sub look{
if (defined($user{$client}{brief})){
$outbuffer{$client}.="$room[$user{$client}{room}]{shortdesc}\r\n";
}
else{
$outbuffer{$client}.="$room[$user{$client}{room}]{longdesc}\r\n";
}
local $b=0;
foreach $a (keys %{$room[$user{$client}{room}]{in}}){
if (defined($user{$a}{hiding})){
next;
}
unless ($room[$user{$client}{room}]{in}{$a} eq "$user{$client}{name}"){
unless($b==1){
$b=1;
if ($user{$a}{roomdesc}){
$outbuffer{$client}.= "Also here is : $user{$a}{roomdesc}";
}
else {
$outbuffer{$client}.= "Also here is : $user{$a}{pre}$room[$user{$client}{room}]{in}{$a}";
}
}
else {
if ($user{$a}{roomdesc}){
$outbuffer{$client}.=", $user{$a}{roomdesc}";
}
else {
$outbuffer{$client}.= ", $room[$user{$client}{room}]{in}{$a}";
}
}
}
}
if ($b){
$outbuffer{$client}.="\r\n";
}
local $b=0;
foreach $a (keys %{$room[$user{$client}{room}]{items}}){
if (defined($item{$a}{noshow})){
next;
}
unless($b==1){
$b=1;
if ($item{$a}{roomdesc}){
$outbuffer{$client}.= "Lying here is : $item{$a}{roomdesc}";
}
else {
$outbuffer{$client}.= "Lying here is : $item{$a}{name}";
}
}
else {
if ($item{$a}{roomdesc}){
$outbuffer{$client}.=", $item{$a}{roomdesc}";
}
else {
$outbuffer{$client}.= ", $item{$a}{name}";
}
}
}
if ($b){
$outbuffer{$client}.="\r\n";
}
$outbuffer{$client}.= "Obvious exits: $room[$user{$client}{room}]{obvious}";
$outbuffer{$client}.= "\r\n$prompt";
}
sub move {
my $dest=shift;
my $message=shift;
my $message2=shift;
unless($client){
my $client=shift;
}
if(roundcheck()){
return;
}
#print "AAA\n";
if ($user{$client}{position} and $user{$client}{position} ne "stand"){
$outbuffer{$client}.="You'll have to stand to do that\r\n$prompt";
return;
}
removefromroom($client);
$user{$client}{hiding}=undef;
say("$message",$user{$client}{room});
say("$message2",$dest);
addtoroom($dest,$client);
look();
}
sub removefromroom {
my $e=shift;
unless ($e){
print "something very strange is going on\n";
return;
}
unless ($user{$e}){
print "major error here\n";
}
unless ($user{$e}{room}){
print "bigger errror here\n";
}
delete($room[$user{$e}{room}]{in}{$e});
}
sub addtoroom {
my $room=shift;
my $person=shift;
$user{$person}{room}=$room;
$room[$room]{in}{$client}=$user{$client}{name};
#print "moving $person to $room\n";
}
sub additemtoroom {
my $room=shift;
my $item=shift;
$room[$room]{items}{$item}=$item{$item}{name};
}
sub removeitemfromroom {
my $room=shift;
my $item=shift;
print "removing $item from $room\n";
delete $room[$room]{items}{$item};
return 1;
}
sub makeitem {
my $item=shift;
unless ($itemtemplate{$item}){
print "tried to create bad item $item\r\n";
return 0;
}
$itemtotal++;
$item{$itemtotal}=$itemtemplate{$item};
&savemuddata;
return $itemtotal;
}
sub delete {
$a=shift;
save($a);
say("$user{$a}{name} has left the universe.",$user{$a}{room});
removefromroom($a);
delete $inbuffer{$a};
delete $outbuffer{$a};
delete $ready{$a};
delete $user{$a};
delete $last{$a};
delete $type{$a};
$select ->remove($a);
unless (close($a)){
print "error $!\n";
}
print "$a has been hung up on\n";
}
sub locateitemfloor {
my $room=shift;
my $item=shift;
my $skip=shift;
chomp ($item);
foreach $a (keys %{$room[$room]{items}}){
# print "looking for $item in $a\r\n";
if ($item{$a}{name}=~/$item/i){
if ($skip){
$skip--;
}
else {
return $a;
}
}
}
return 0;
}
sub locateitem{
$room=shift;
$item=shift;
if ($a=locateitemfloor($room,$item)){
return $a;
}
return 0;
}
sub monsterdecay {
$a=shift;
removefromroom($a);
#$node[$user{$a}{monster}{node}]{maxused}--;
#print "$user{$a}{node}";
${$user{$a}{node}}{maxused}--;
#print "${$user{$a}{node}}{maxused}\n";
delete $user{$a};
delete $outbuffer{$a};
delete $inbuffer{$a};
delete $ready{$a};
delete $type{$a};
if (defined($user{$a})){
print "nope, it's not going boom\n";
die;
}
}
sub playerdecay {
$a=shift;
say2("$user{$a}{name} is magicaly reborn!", $user{$a}{room}, "The gods smile upon you and you are returned to life!", $a);
$type{$a}="normal";
$user{$a}{vitality}=$user{$a}{vitalitymax};
$user{$a}{roomdesc}="$user{$a}{name} is lying around";
$node{$user{$a}{node}}{maxused}--;
delete $user{$a}{dead};
}
sub descend {
my $str=shift;
my $key=shift;
if (ref($str) eq "HASH"){
#is a refrence need to descend
$string.="<$key>\n";
foreach $a (keys %{$str}){
descend(${$str}{$a},$a);
}
$string.="</$key>\n";
}
elsif (ref($str) eq "ARRAY"){
return;
}
else {
#is a plain value, save it.
$string.="<$key=$str>\n";
}
}
sub save {
if (&saveplayer){
$outbuffer{$client}.="You have been saved\r\n$prompt";
}
else {
$outbuffer{$client}.="You have NOT been saved, something went wrong\r\n";
}
}
sub saveplayer {
my $client=(shift or $client);
local $string;
foreach $a (keys %{$user{$client}}){
descend($user{$client}{$a},$a);
}
unless (open (PLAYER, ">players/$user{$client}{name}")){
$outbuffer{$client}.="$!";
return 0;
}
print PLAYER $string;
close PLAYER;
foreach $a (%{$user{$client}{health}}){
foreach $b (%{$user{$client}{health}{$a}{wear}}) {
if ($user{$client}{health}{$a}{wear}{$b}){
print "wearing save, $a $b\n";
&saverealitem($user{$client}{health}{$a}{wear}{$b});
}
}
if ($user{$client}{health}{$a}{hold}){
print "holding save $user{$client}{health}{$a}{hold}\n";
&saverealitem($user{$client}{health}{$a}{hold});
}
}
return 1;
}
return 1;