//returns true of door in unobjstructed (& thus can close) int is_door_free(segment *seg,int side) { int Connectside; segment *csegp; int objnum; csegp = &Segments[seg->children[side]]; Connectside = find_connect_side(seg, csegp); Assert(Connectside != -1); //go through each object in each of two segments, and see if //it pokes into the connecting seg for (objnum=seg->objects;objnum!=-1;objnum=Objects[objnum].next) if (Objects[objnum].type!=OBJ_WEAPON && Objects[objnum].type!=OBJ_FIREBALL && check_poke(objnum,seg-Segments,side)) return 0; //not free for (objnum=csegp->objects;objnum!=-1;objnum=Objects[objnum].next) if (Objects[objnum].type!=OBJ_WEAPON && Objects[objnum].type!=OBJ_FIREBALL && check_poke(objnum,csegp-Segments,Connectside)) return 0; //not free return 1; //doorway is free! }
//----------------------------------------------------------------- // Animates and processes the closing of a door. // Called from the game loop. void do_door_close(int door_num) { int p; active_door *d; wall *w; Assert(door_num != -1); //Trying to do_door_open on illegal door d = &ActiveDoors[door_num]; w = &Walls[d->front_wallnum[0]]; //check for objects in doorway before closing if (w->flags & WALL_DOOR_AUTO) for (p=0;p<d->n_parts;p++) { int Connectside, side; segment *csegp, *seg; int objnum; seg = &Segments[w->segnum]; side = w->sidenum; csegp = &Segments[seg->children[side]]; Connectside = find_connect_side(seg, csegp); Assert(Connectside != -1); //go through each object in each of two segments, and see if //it pokes into the connecting seg for (objnum=seg->objects;objnum!=-1;objnum=Objects[objnum].next) if (check_poke(objnum,seg-Segments,side)) return; //abort! for (objnum=csegp->objects;objnum!=-1;objnum=Objects[objnum].next) if (check_poke(objnum,csegp-Segments,Connectside)) return; //abort! } for (p=0;p<d->n_parts;p++) { wall *w; int Connectside, side; segment *csegp, *seg; fix time_elapsed, time_total, one_frame; int i, n; w = &Walls[d->front_wallnum[p]]; seg = &Segments[w->segnum]; side = w->sidenum; if (seg->sides[side].wall_num == -1) { return; } //if here, must be auto door Assert(Walls[seg->sides[side].wall_num].flags & WALL_DOOR_AUTO); // Otherwise, close it. csegp = &Segments[seg->children[side]]; Connectside = find_connect_side(seg, csegp); Assert(Connectside != -1); if ( Newdemo_state != ND_STATE_PLAYBACK ) // NOTE THE LINK TO ABOVE!! if (p==0) //only play one sound for linked doors if ( d->time==0 ) { //first time vms_vector cp; compute_center_point_on_side(&cp, seg, side ); if (WallAnims[w->clip_num].close_sound > -1 ) digi_link_sound_to_pos( WallAnims[Walls[seg->sides[side].wall_num].clip_num].close_sound, seg-Segments, side, &cp, 0, F1_0 ); } d->time += FrameTime; time_elapsed = d->time; n = WallAnims[w->clip_num].num_frames; time_total = WallAnims[w->clip_num].play_time; one_frame = time_total/n; i = n-time_elapsed/one_frame-1; if (i < n/2) { Walls[seg->sides[side].wall_num].flags &= ~WALL_DOOR_OPENED; Walls[csegp->sides[Connectside].wall_num].flags &= ~WALL_DOOR_OPENED; } // Animate door. if (i > 0) { wall_set_tmap_num(seg,side,csegp,Connectside,w->clip_num,i); Walls[seg->sides[side].wall_num].state = WALL_DOOR_CLOSING; Walls[csegp->sides[Connectside].wall_num].state = WALL_DOOR_CLOSING; ActiveDoors[Num_open_doors].time = 0; //counts up } else wall_close_door(door_num); } }