inherit "/std/thing"; inherit "/std/living"; object debug; private mixed *states=({0}); mapping envmatch=([]); mapping matchbase=([]); string *output_queue=({}); void queue_texts(string *texts) { output_queue+=texts; set_heart_beat(1); } void heart_beat() { set_heart_beat(0); /* don't forget to add ::heart_beat() */ if(sizeof(output_queue)) { tell_room(environment(),output_queue[0],({this_object()})); /* we don't want to que to much, do we? */ output_queue=output_queue[1..25]; if(sizeof(output_queue)) set_heart_beat(1); } } /* replaces all occurances of repls[n] (n=even) with repls[n+1] in string */ string replace(string qstr, string *repls) { int e; if(!qstr || qstr=="") return qstr; for(e=0;e<sizeof(repls);e+=2) qstr=implode(explode(qstr+repls[e],repls[e]),repls[e+1]); return qstr; } varargs string treat_string( string str, string a1, string a2, string a3, string a4, string a5, string a6) { if(!a1) a1=""; if(!a2) a2=""; if(!a3) a3=""; if(!a4) a4=""; if(!a5) a5=""; if(!a6) a6=""; return replace(str,({ "#S1",a1,"#S2",a1,"#S3",a1,"#S4",a1,"#S5",a1,"#S6",a1, "#C1",capitalize(a1),"#C2",capitalize(a2),"#C3",capitalize(a3), "#C4",capitalize(a4),"#C5",capitalize(a5),"#C6",capitalize(a6), })); } void set_state(mixed state) { states[0]=state; } void clear_state(mixed state) { states[0]=({0}); } void push_state(mixed state) { states=({state})+states; } mixed query_state() { return states[0]; } void pop_state() { states=states[1..1000000]; if(!sizeof(states)) states=({0}); } void do_grejs(function f, mixed foo, string a, string b, string c, string d, string e, string f) { f(foo,a,b,c,d,e,f); } int matchmaker2(string str,mixed *c) { int e; string a1,a2,a3,a4,a5,a6; mixed tmp,t; if(!c) return 0; foreach(c,t) { if(random(100) >= t[0]) continue; if((!t[1] && t[2]==str) || t[1]==sscanf(str,t[2],a1,a2,a3,a4,a5,a6)) { tmp=t; break; } } if(!tmp) return 0; if(debug) tell_object(debug,query_name()+" match:"+tmp[2]+"\n"); foreach(tmp[3],t) { if(random(100)<t[0]) { if(!t[1]) { t[2](t[3],a1,a2,a3,a4,a5,a6); }else{ call_out(do_grejs,t[1],t[2],t[3],a1,a2,a3,a4,a5,a6); } } } return 1; } int matchmaker(string s,mapping m) { if(!stringp(s)) return; return matchmaker2(s,m[query_state()]) || matchmaker2(s,m["*"]); } void do_submatch(mapping data, string a, string b, string c, string d, string e, string f) { matchmaker(a+"\t"+b+"\t"+c+"\t"+d+"\t"+e+"\t"+f,data[query_state()]); } void do_answer_echo(string s, string a1, string a2, string a3, string a4, string a5, string a6) { enable_commands(); tell_room(environment(),treat_string(s+"\n",a1,a2,a3,a4,a5,a6)); } void do_answer_say(string s, string a1, string a2, string a3, string a4, string a5, string a6) { string t; enable_commands(); s=treat_string(s+"\n",a1,a2,a3,a4,a5,a6); t=query_name()+" says: "; queue_texts(explode(sprintf("%*s%-=*s",strlen(t),t,77-strlen(t),s),"\n")); } void do_answer_command(string s, string a1, string a2, string a3, string a4, string a5, string a6) { string q; q=treat_string(s,a1,a2,a3,a4,a5,a6); if(debug) tell_object(debug,query_name()+" doing: "+q+"\n"); command(q); } /*** configuration ****/ /* remember, this is just a pointer */ static mapping _tmp; private static mixed *current_match; void new_talk_match() { _tmp=matchbase=([]); } void continue_talk_match() { _tmp=matchbase; } void new_env_match() { _tmp=envmatch=([]); } void continue_env_match() { _tmp=envmatch; } static void stoppa_in_match(mixed *match,mixed stat) { mixed e; if(pointerp(stat)) { foreach(stat,e) { if(!_tmp[e]) _tmp[e]=({}); _tmp[e]+=({current_match}); } }else{ if(!_tmp[stat]) _tmp[stat]=({}); _tmp[stat]+=({current_match}); } } void add_match(int chance,string str,mixed stat) { current_match=({ chance,sizeof(explode(str,"%")),str, ({}) }); stoppa_in_match(current_match,stat); } void copy_match(int chance,string str,mixed stat) { current_match=({ chance,sizeof(explode(str,"%")),str, current_match[3] }); stoppa_in_match(current_match,stat); } void add_call(int chanse,function func,int delay,mixed arg) { current_match[3]+=({({ chanse,delay,func,arg })}); } void push_matches(int chanse,mixed state) { mapping tmp; tmp=([]); add_call(chanse,do_submatch,state,tmp); push_state(_tmp); _tmp=tmp; } void pop_matches() { _tmp=query_state(); pop_state(); } void add_echo(int chance,string str,int delay) { add_call(chance,do_answer_echo,delay,str); } void add_emote(int chance,string str,int delay) { add_echo(chance,query_name()+" "+str,delay); } void add_say(int chance,string str,int delay) { add_call(chance,do_answer_say,delay,str,this_object()); } void add_command(int chance,string com,int delay) { add_call(chance,do_answer_command,delay,com); } void add_set_state(int chance,string stat,int delay) { add_call(chance,set_state,delay,stat); } void add_push_state(int chance,string stat,int delay) { add_call(chance,push_state,delay,stat); } void add_pop_state(int chance,int delay) { add_call(chance,pop_state,delay,0); } void add_clear_state(int chance,int delay) { add_call(chance,clear_state,delay,0); } /* lfuns */ void catch_tell(string msg) { if(!stringp(msg)) return; if(debug) tell_object(debug,query_name()+" got: "+msg+"from:"+ file_name(previous_object())+"\n"); msg=lower_case(msg); matchmaker(msg,matchbase); } object get() { return 0; } void move_player(string how, mixed where) { ::move_player(how,where); matchmaker(hash_name(environment()),envmatch); } void set_name(string n) { full_name=capitalize(name=n); set_living_name(n); } int id(string id) { return living::id(id) || thing::id(id); }