/* clearq.c */ #include "config.h" #include "object.h" #include "dbhandle.h" #include "construct.h" #include "interp.h" #include "cache.h" #include "globals.h" #include "edit.h" /* functions for clearing the queues */ void handle_destruct() { struct destq *curr_dest; struct object *prev_obj,*curr_obj,*next_obj; struct proto *prev_proto,*curr_proto; signed long num_globals,loop; struct ref_list *curr_ref; struct verb *next_verb,*curr_verb; struct cmdq *curr_cmd,*prev_cmd,*tmp_cmd; struct alarmq *curr_alarm,*prev_alarm; while (dest_list) { curr_dest=dest_list; dest_list=dest_list->next; curr_cmd=cmd_head; prev_cmd=NULL; if (curr_dest->obj->devnum!=(-1)) immediate_disconnect(curr_dest->obj->devnum); while (curr_cmd) { if (curr_cmd->obj==curr_dest->obj) { if (prev_cmd) prev_cmd->next=curr_cmd->next; if (cmd_head==curr_cmd) cmd_head=curr_cmd->next; if (cmd_tail==curr_cmd) cmd_tail=prev_cmd; tmp_cmd=curr_cmd; curr_cmd=curr_cmd->next; FREE(tmp_cmd); } else { prev_cmd=curr_cmd; curr_cmd=curr_cmd->next; } } curr_alarm=alarm_list; prev_alarm=NULL; while (curr_alarm) { if (curr_alarm->obj==curr_dest->obj) { if (prev_alarm) prev_alarm->next=curr_alarm->next; else alarm_list=curr_alarm->next; FREE(curr_alarm->funcname); FREE(curr_alarm); if (prev_alarm) curr_alarm=prev_alarm->next; else curr_alarm=alarm_list; } else { prev_alarm=curr_alarm; curr_alarm=curr_alarm->next; } } num_globals=curr_dest->obj->parent->funcs->num_globals; if (curr_dest->obj->flags & PROTOTYPE) { curr_obj=curr_dest->obj->next_child; while (curr_obj) { queue_for_destruct(curr_obj); curr_obj=curr_obj->next_child; } handle_destruct(); free_code(curr_dest->obj->parent->funcs); prev_proto=ref_to_obj(0)->parent; curr_proto=prev_proto->next_proto; while (curr_proto) { if (curr_proto==curr_dest->obj->parent) { prev_proto->next_proto=curr_proto->next_proto; break; } prev_proto=curr_proto; curr_proto=curr_proto->next_proto; } } else { prev_obj=curr_dest->obj->parent->proto_obj; curr_obj=prev_obj->next_child; while (curr_obj) { if (curr_obj==curr_dest->obj) { prev_obj->next_child=curr_dest->obj->next_child; break; } prev_obj=curr_obj; curr_obj=curr_obj->next_child; } } load_data(curr_dest->obj); loop=0; while (loop<num_globals) { clear_global_var(curr_dest->obj,loop); loop++; } curr_ref=curr_dest->obj->refd_by; while (curr_ref) { load_data(curr_ref->ref_obj); curr_ref->ref_obj->obj_state=DIRTY; curr_ref->ref_obj->globals[curr_ref->ref_num].type=INTEGER; curr_ref->ref_obj->globals[curr_ref->ref_num].value.integer=0; curr_ref=curr_ref->next; } unload_object(curr_dest->obj); if (curr_dest->obj->flags & PROTOTYPE) FREE(curr_dest->obj->parent); curr_obj=curr_dest->obj->contents; while (curr_obj) { curr_obj->location=curr_dest->obj->location; next_obj=curr_obj->next_object; if (curr_obj->location) { curr_obj->next_object=curr_obj->location->contents; curr_obj->location->contents=curr_obj; } else curr_obj->next_object=NULL; curr_obj=next_obj; } curr_dest->obj->contents=NULL; if (curr_dest->obj->location) { prev_obj=NULL; curr_obj=curr_dest->obj->location->contents; while (curr_obj) { if (curr_obj==curr_dest->obj) { if (prev_obj) prev_obj->next_object=curr_obj->next_object; else curr_dest->obj->location->contents=curr_obj->next_object; break; } prev_obj=curr_obj; curr_obj=curr_obj->next_object; } } curr_dest->obj->location=NULL; if (curr_dest->obj->flags & IN_EDITOR) remove_from_edit(curr_dest->obj); if (curr_dest->obj->flags & CONNECTED) disconnect_device(curr_dest->obj); curr_verb=curr_dest->obj->verb_list; while (curr_verb) { FREE(curr_verb->verb_name); FREE(curr_verb->function); next_verb=curr_verb->next; FREE(curr_verb); curr_verb=next_verb; } curr_dest->obj->devnum=-1; curr_dest->obj->flags=GARBAGE; curr_dest->obj->parent=NULL; curr_dest->obj->next_child=NULL; curr_dest->obj->location=NULL; curr_dest->obj->contents=NULL; curr_dest->obj->next_object=free_obj_list; curr_dest->obj->globals=NULL; curr_dest->obj->refd_by=NULL; curr_dest->obj->verb_list=NULL; free_obj_list=curr_dest->obj; FREE(curr_dest); } } void handle_alarm() { struct alarmq *curr_alarm; struct fns *func; struct var tmp; struct var_stack *rts; while (alarm_list) { if (alarm_list->delay>now_time) return; curr_alarm=alarm_list; alarm_list=alarm_list->next; func=find_fns(curr_alarm->funcname,curr_alarm->obj); #ifdef CYCLE_SOFT_MAX soft_cycles=0; #endif /* CYCLE_SOFT_MAX */ if (func) { rts=NULL; tmp.type=NUM_ARGS; tmp.value.num=0; push(&tmp,&rts); interp(NULL,curr_alarm->obj,NULL,&rts,func); free_stack(&rts); } FREE(curr_alarm->funcname); FREE(curr_alarm); handle_destruct(); } } struct verb *find_vname(struct object *obj, char *vname, int is_second_run) { struct verb *curr; if (is_second_run) curr=obj->parent->proto_obj->verb_list; else curr=obj->verb_list; while (curr) { if (!strcmp(curr->verb_name,vname)) return curr; curr=curr->next; } return NULL; } int find_verb(struct object *player, struct object *obj, char *vname, char *cmd, signed long disp) { struct verb *curr_verb; struct fns *func; struct var_stack *rts; struct var tmp; int is_match,is_second_run; char *string,*cvn; if (!obj) return 0; if ((obj->flags & INTERACTIVE) && player!=obj) return 0; curr_verb=obj->verb_list; is_second_run=0; if (!curr_verb) { curr_verb=obj->parent->proto_obj->verb_list; is_second_run=1; } while (curr_verb) { is_match=0; cvn=copy_string(curr_verb->verb_name); if (curr_verb->is_xverb) { if ((!strncmp(curr_verb->verb_name,cmd,strlen(curr_verb->verb_name))) || (!(*(curr_verb->verb_name)))) { rts=NULL; func=find_fns(curr_verb->function,obj); if (func) { tmp.type=STRING; tmp.value.string=&(cmd[strlen(curr_verb->verb_name)]); if ((*(tmp.value.string))=='\0') { tmp.type=INTEGER; tmp.value.integer=0; } push(&tmp,&rts); tmp.type=NUM_ARGS; tmp.value.num=1; push(&tmp,&rts); if (!interp(NULL,obj,player,&rts,func)) { if (!pop(&tmp,&rts,obj)) { if (tmp.type!=INTEGER || tmp.value.integer!=0) is_match=1; clear_var(&tmp); } } free_stack(&rts); } } } else { if (!strcmp(curr_verb->verb_name,vname)) { rts=NULL; func=find_fns(curr_verb->function,obj); if (func) { tmp.type=STRING; tmp.value.string=&(cmd[disp]); if ((*(tmp.value.string))=='\0') { tmp.type=INTEGER; tmp.value.integer=0; } push(&tmp,&rts); tmp.type=NUM_ARGS; tmp.value.num=1; push(&tmp,&rts); if (!interp(NULL,obj,player,&rts,func)) { if (!pop(&tmp,&rts,obj)) { if (tmp.type!=INTEGER || tmp.value.integer!=0) is_match=1; clear_var(&tmp); } } free_stack(&rts); } } } if (is_match) { FREE(cvn); return 1; } curr_verb=find_vname(obj,cvn,is_second_run); FREE(cvn); if (curr_verb) curr_verb=curr_verb->next; if (!curr_verb) if (!(obj->flags & PROTOTYPE) && !is_second_run) { is_second_run=1; curr_verb=obj->parent->proto_obj->verb_list; } } return 0; } void handle_command() { struct cmdq *curr; char *vname; signed long begin_char,count,loop; struct object *curr_obj; int done; while (cmd_head) { curr=cmd_head; cmd_head=curr->next; if (!cmd_head) cmd_tail=NULL; #ifdef CYCLE_SOFT_MAX soft_cycles=0; #endif /* CYCLE_SOFT_MAX */ done=0; begin_char=0; while (curr->cmd[begin_char]==' ') begin_char++; count=begin_char; while (curr->cmd[count]!='\0' && curr->cmd[count]!=' ') count++; vname=MALLOC(count-begin_char+1); loop=begin_char; while (loop<count) { vname[loop-begin_char]=curr->cmd[loop]; loop++; } vname[loop]='\0'; while (curr->cmd[count]==' ') count++; if (find_verb(curr->obj,curr->obj->location,vname,curr->cmd,count)) done=1; if (curr->obj->location) { curr_obj=curr->obj->location->contents; while (curr_obj && !done) { if (curr_obj!=curr->obj) if (find_verb(curr->obj,curr_obj,vname,curr->cmd,count)) done=1; curr_obj=curr_obj->next_object; } } curr_obj=curr->obj->contents; while (curr_obj && !done) { if (find_verb(curr->obj,curr_obj,vname,curr->cmd,count)) done=1; curr_obj=curr_obj->next_object; } if (!done) find_verb(curr->obj,curr->obj,vname,curr->cmd,count); FREE(vname); FREE(curr->cmd); FREE(curr); handle_destruct(); } }