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;