/* $Id: medwall.c,v 1.1.1.1 2006/03/17 19:58:48 zicodxx Exp $ */ /* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * * Created from version 1.11 of main\wall.c * */ #ifdef RCS static char rcsid[] = "$Id: medwall.c,v 1.1.1.1 2006/03/17 19:58:48 zicodxx Exp $"; #endif #ifdef HAVE_CONFIG_H #include "conf.h" #endif #include #include #include #include #include "editor/medwall.h" #include "inferno.h" #include "editor/editor.h" #include "segment.h" #include "error.h" #include "gameseg.h" #include "textures.h" #include "screens.h" #include "switch.h" #include "editor/eswitch.h" #include "texmerge.h" #include "medrobot.h" #include "timer.h" #include "mono.h" #include "cntrlcen.h" #include "key.h" #include "ehostage.h" #include "centers.h" #include "piggy.h" int wall_add_door_flag(sbyte flag); int wall_add_to_side(segment *segp, int side, sbyte type); int wall_remove_door_flag(sbyte flag); //------------------------------------------------------------------------- // Variables for this module... //------------------------------------------------------------------------- static UI_WINDOW *MainWindow = NULL; static UI_GADGET_USERBOX *WallViewBox; static UI_GADGET_BUTTON *QuitButton; static UI_GADGET_CHECKBOX *DoorFlag[4]; static UI_GADGET_RADIO *KeyFlag[4]; static int old_wall_num; static fix Time; static int framenum=0; static int Current_door_type=1; typedef struct count_wall { short wallnum; short segnum,sidenum; } count_wall; //--------------------------------------------------------------------- extern void create_removable_wall(segment *sp, int sidenum, int tmap_num); // Add a wall (removable 2 sided) int add_wall(segment *seg, short side) { int Connectside; segment *csegp; if (Num_walls < MAX_WALLS-2) if (IS_CHILD(seg->children[side])) { if (seg->sides[side].wall_num == -1) { seg->sides[side].wall_num = Num_walls; Num_walls++; } csegp = &Segments[seg->children[side]]; Connectside = find_connect_side(seg, csegp); if (csegp->sides[Connectside].wall_num == -1) { csegp->sides[Connectside].wall_num = Num_walls; Num_walls++; } create_removable_wall( seg, side, CurrentTexture ); create_removable_wall( csegp, Connectside, CurrentTexture ); return 1; } return 0; } int wall_assign_door(int door_type) { int Connectside; segment *csegp; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("Cannot assign door. No wall at Curside."); return 0; } if (Walls[Cursegp->sides[Curside].wall_num].type != WALL_DOOR && Walls[Cursegp->sides[Curside].wall_num].type != WALL_BLASTABLE) { editor_status("Cannot assign door. No door at Curside."); return 0; } Current_door_type = door_type; csegp = &Segments[Cursegp->children[Curside]]; Connectside = find_connect_side(Cursegp, csegp); Walls[Cursegp->sides[Curside].wall_num].clip_num = door_type; Walls[csegp->sides[Connectside].wall_num].clip_num = door_type; if (WallAnims[door_type].flags & WCF_TMAP1) { Cursegp->sides[Curside].tmap_num = WallAnims[door_type].frames[0]; csegp->sides[Connectside].tmap_num = WallAnims[door_type].frames[0]; Cursegp->sides[Curside].tmap_num2 = 0; csegp->sides[Connectside].tmap_num2 = 0; } else { Cursegp->sides[Curside].tmap_num2 = WallAnims[door_type].frames[0]; csegp->sides[Connectside].tmap_num2 = WallAnims[door_type].frames[0]; } Update_flags |= UF_WORLD_CHANGED; return 1; } int wall_add_blastable() { return wall_add_to_side(Cursegp, Curside, WALL_BLASTABLE); } int wall_add_door() { return wall_add_to_side(Cursegp, Curside, WALL_DOOR); } int wall_add_closed_wall() { return wall_add_to_side(Cursegp, Curside, WALL_CLOSED); } int wall_add_external_wall() { if (Cursegp->children[Curside] == -2) { editor_status( "Wall is already external!" ); return 1; } if (IS_CHILD(Cursegp->children[Curside])) { editor_status( "Cannot add external wall here - seg has children" ); return 0; } Cursegp->children[Curside] = -2; return 1; } int wall_add_illusion() { return wall_add_to_side(Cursegp, Curside, WALL_ILLUSION); } int wall_lock_door() { return wall_add_door_flag(WALL_DOOR_LOCKED); } int wall_unlock_door() { return wall_remove_door_flag(WALL_DOOR_LOCKED); } int wall_automate_door() { return wall_add_door_flag(WALL_DOOR_AUTO); } int wall_deautomate_door() { return wall_remove_door_flag(WALL_DOOR_AUTO); } int GotoPrevWall() { int current_wall; if (Cursegp->sides[Curside].wall_num < 0) current_wall = Num_walls; else current_wall = Cursegp->sides[Curside].wall_num; current_wall--; if (current_wall < 0) current_wall = Num_walls-1; if (current_wall >= Num_walls) current_wall = Num_walls-1; if (Walls[current_wall].segnum == -1) { mprintf((0, "Trying to goto wall at bogus segnum\n")); return 0; } if (Walls[current_wall].sidenum == -1) { mprintf((0, "Trying to goto wall at bogus sidenum\n")); return 0; } Cursegp = &Segments[Walls[current_wall].segnum]; Curside = Walls[current_wall].sidenum; return 1; } int GotoNextWall() { int current_wall; current_wall = Cursegp->sides[Curside].wall_num; // It's ok to be -1 because it will immediately become 0 current_wall++; if (current_wall >= Num_walls) current_wall = 0; if (current_wall < 0) current_wall = 0; if (Walls[current_wall].segnum == -1) { mprintf((0, "Trying to goto wall at bogus segnum\n")); return 0; } if (Walls[current_wall].sidenum == -1) { mprintf((0, "Trying to goto wall at bogus sidenum\n")); return 0; } Cursegp = &Segments[Walls[current_wall].segnum]; Curside = Walls[current_wall].sidenum; return 1; } int PrevWall() { int wall_type; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("Cannot assign new wall. No wall on curside."); return 0; } wall_type = Walls[Cursegp->sides[Curside].wall_num].clip_num; if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_DOOR) { do { wall_type--; if (wall_type < 0) wall_type = Num_wall_anims-1; if (wall_type == Walls[Cursegp->sides[Curside].wall_num].clip_num) Error("Cannot find clip for door."); } while (WallAnims[wall_type].num_frames == -1 || WallAnims[wall_type].flags & WCF_BLASTABLE); } else if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_BLASTABLE) { do { wall_type--; if (wall_type < 0) wall_type = Num_wall_anims-1; if (wall_type == Walls[Cursegp->sides[Curside].wall_num].clip_num) Error("Cannot find clip for blastable wall."); } while (WallAnims[wall_type].num_frames == -1 || !(WallAnims[wall_type].flags & WCF_BLASTABLE)); } wall_assign_door(wall_type); Update_flags |= UF_WORLD_CHANGED; return 1; } int NextWall() { int wall_type; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("Cannot assign new wall. No wall on curside."); return 0; } wall_type = Walls[Cursegp->sides[Curside].wall_num].clip_num; if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_DOOR) { do { wall_type++; if (wall_type >= Num_wall_anims) { wall_type = 0; if (Walls[Cursegp->sides[Curside].wall_num].clip_num==-1) Error("Cannot find clip for door."); } } while (WallAnims[wall_type].num_frames == -1 || WallAnims[wall_type].flags & WCF_BLASTABLE); } else if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_BLASTABLE) { do { wall_type++; if (wall_type >= Num_wall_anims) { wall_type = 0; if (Walls[Cursegp->sides[Curside].wall_num].clip_num==-1) Error("Cannot find clip for blastable wall."); } } while (WallAnims[wall_type].num_frames == -1 || !(WallAnims[wall_type].flags & WCF_BLASTABLE)); } wall_assign_door(wall_type); Update_flags |= UF_WORLD_CHANGED; return 1; } //------------------------------------------------------------------------- // Called from the editor... does one instance of the wall dialog box //------------------------------------------------------------------------- int do_wall_dialog() { int i; // Only open 1 instance of this window... if ( MainWindow != NULL ) return 0; // Close other windows. close_all_windows(); // Open a window with a quit button MainWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG ); QuitButton = ui_add_gadget_button( MainWindow, 20, 252, 48, 40, "Done", NULL ); // These are the checkboxes for each door flag. i = 80; DoorFlag[0] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Locked" ); i += 24; DoorFlag[1] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Auto" ); i += 24; DoorFlag[2] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion OFF" ); i += 24; KeyFlag[0] = ui_add_gadget_radio( MainWindow, 22, i, 16, 16, 0, "NONE" ); i += 24; KeyFlag[1] = ui_add_gadget_radio( MainWindow, 22, i, 16, 16, 0, "Blue" ); i += 24; KeyFlag[2] = ui_add_gadget_radio( MainWindow, 22, i, 16, 16, 0, "Red" ); i += 24; KeyFlag[3] = ui_add_gadget_radio( MainWindow, 22, i, 16, 16, 0, "Yellow" ); i += 24; // The little box the wall will appear in. WallViewBox = ui_add_gadget_userbox( MainWindow, 155, 5, 64, 64 ); // A bunch of buttons... i = 80; ui_add_gadget_button( MainWindow,155,i,70, 22, "<< Clip", PrevWall ); ui_add_gadget_button( MainWindow,155+70,i,70, 22, "Clip >>", NextWall );i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Add Blastable", wall_add_blastable ); i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Add Door", wall_add_door ); i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Add Illusory", wall_add_illusion); i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Add Closed Wall", wall_add_closed_wall ); i+=25; // ui_add_gadget_button( MainWindow,155,i,140, 22, "Restore All Walls", wall_restore_all ); i += 25; ui_add_gadget_button( MainWindow,155,i,70, 22, "<< Prev", GotoPrevWall ); ui_add_gadget_button( MainWindow,155+70,i,70, 22, "Next >>", GotoNextWall );i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Remove Wall", wall_remove ); i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Bind to Trigger", bind_wall_to_trigger ); i += 25; ui_add_gadget_button( MainWindow,155,i,140, 22, "Bind to Control", bind_wall_to_control_center ); i+=25; old_wall_num = -2; // Set to some dummy value so everything works ok on the first frame. return 1; } void close_wall_window() { if ( MainWindow!=NULL ) { ui_close_window( MainWindow ); MainWindow = NULL; } } void do_wall_window() { int i; sbyte type; fix DeltaTime, Temp; if ( MainWindow == NULL ) return; //------------------------------------------------------------ // Call the ui code.. //------------------------------------------------------------ ui_button_any_drawn = 0; ui_window_do_gadgets(MainWindow); //------------------------------------------------------------ // If we change walls, we need to reset the ui code for all // of the checkboxes that control the wall flags. //------------------------------------------------------------ if (old_wall_num != Cursegp->sides[Curside].wall_num) { if ( Cursegp->sides[Curside].wall_num != -1) { wall *w = &Walls[Cursegp->sides[Curside].wall_num]; ui_checkbox_check(DoorFlag[0], w->flags & WALL_DOOR_LOCKED); ui_checkbox_check(DoorFlag[1], w->flags & WALL_DOOR_AUTO); ui_checkbox_check(DoorFlag[2], w->flags & WALL_ILLUSION_OFF); if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_NONE) ui_radio_set_value(KeyFlag[0], 1); if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_BLUE) ui_radio_set_value(KeyFlag[1], 1); if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_RED) ui_radio_set_value(KeyFlag[2], 1); if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_GOLD) ui_radio_set_value(KeyFlag[3], 1); } } //------------------------------------------------------------ // If any of the checkboxes that control the wallflags are set, then // update the corresponding wall flag. //------------------------------------------------------------ if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_DOOR) { if ( DoorFlag[0]->flag == 1 ) Walls[Cursegp->sides[Curside].wall_num].flags |= WALL_DOOR_LOCKED; else Walls[Cursegp->sides[Curside].wall_num].flags &= ~WALL_DOOR_LOCKED; if ( DoorFlag[1]->flag == 1 ) Walls[Cursegp->sides[Curside].wall_num].flags |= WALL_DOOR_AUTO; else Walls[Cursegp->sides[Curside].wall_num].flags &= ~WALL_DOOR_AUTO; //------------------------------------------------------------ // If any of the radio buttons that control the mode are set, then // update the corresponding key. //------------------------------------------------------------ for ( i=0; i < 4; i++ ) { if ( KeyFlag[i]->flag == 1 ) { Walls[Cursegp->sides[Curside].wall_num].keys = 1<flag == 1 ) { KeyFlag[i]->flag = 0; KeyFlag[i]->status = 1; } } } if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_ILLUSION) { if ( DoorFlag[2]->flag == 1 ) Walls[Cursegp->sides[Curside].wall_num].flags |= WALL_ILLUSION_OFF; else Walls[Cursegp->sides[Curside].wall_num].flags &= ~WALL_ILLUSION_OFF; } else for ( i=2; i < 3; i++ ) if (DoorFlag[i]->flag == 1) { DoorFlag[i]->flag = 0; // Tells ui that this button isn't checked DoorFlag[i]->status = 1; // Tells ui to redraw button } //------------------------------------------------------------ // A simple frame time counter for animating the walls... //------------------------------------------------------------ Temp = timer_get_fixed_seconds(); DeltaTime = Temp - Time; //------------------------------------------------------------ // Draw the wall in the little 64x64 box //------------------------------------------------------------ gr_set_current_canvas( WallViewBox->canvas ); if (Cursegp->sides[Curside].wall_num != -1) { type = Walls[Cursegp->sides[Curside].wall_num].type; if ((type == WALL_DOOR) || (type == WALL_BLASTABLE)) { if (DeltaTime > ((F1_0*200)/1000)) { framenum++; Time = Temp; } if (framenum >= WallAnims[Walls[Cursegp->sides[Curside].wall_num].clip_num].num_frames) framenum=0; PIGGY_PAGE_IN(Textures[WallAnims[Walls[Cursegp->sides[Curside].wall_num].clip_num].frames[framenum]]); gr_ubitmap(0,0, &GameBitmaps[Textures[WallAnims[Walls[Cursegp->sides[Curside].wall_num].clip_num].frames[framenum]].index]); } else { if (type == WALL_OPEN) gr_clear_canvas( CBLACK ); else { if (Cursegp->sides[Curside].tmap_num2 > 0) gr_ubitmap(0,0, texmerge_get_cached_bitmap( Cursegp->sides[Curside].tmap_num, Cursegp->sides[Curside].tmap_num2)); else { PIGGY_PAGE_IN(Textures[Cursegp->sides[Curside].tmap_num]); gr_ubitmap(0,0, &GameBitmaps[Textures[Cursegp->sides[Curside].tmap_num].index]); } } } } else gr_clear_canvas( CGREY ); //------------------------------------------------------------ // If anything changes in the ui system, redraw all the text that // identifies this wall. //------------------------------------------------------------ if (ui_button_any_drawn || (old_wall_num != Cursegp->sides[Curside].wall_num) ) { if ( Cursegp->sides[Curside].wall_num > -1 ) { ui_wprintf_at( MainWindow, 12, 6, "Wall: %d ", Cursegp->sides[Curside].wall_num); switch (Walls[Cursegp->sides[Curside].wall_num].type) { case WALL_NORMAL: ui_wprintf_at( MainWindow, 12, 23, " Type: Normal " ); break; case WALL_BLASTABLE: ui_wprintf_at( MainWindow, 12, 23, " Type: Blastable" ); break; case WALL_DOOR: ui_wprintf_at( MainWindow, 12, 23, " Type: Door " ); ui_wprintf_at( MainWindow, 223, 6, "%s", WallAnims[Walls[Cursegp->sides[Curside].wall_num].clip_num].filename); break; case WALL_ILLUSION: ui_wprintf_at( MainWindow, 12, 23, " Type: Illusion " ); break; case WALL_OPEN: ui_wprintf_at( MainWindow, 12, 23, " Type: Open " ); break; case WALL_CLOSED: ui_wprintf_at( MainWindow, 12, 23, " Type: Closed " ); break; default: ui_wprintf_at( MainWindow, 12, 23, " Type: Unknown " ); break; } if (Walls[Cursegp->sides[Curside].wall_num].type != WALL_DOOR) ui_wprintf_at( MainWindow, 223, 6, " " ); ui_wprintf_at( MainWindow, 12, 40, " Clip: %d ", Walls[Cursegp->sides[Curside].wall_num].clip_num ); ui_wprintf_at( MainWindow, 12, 57, " Trigger: %d ", Walls[Cursegp->sides[Curside].wall_num].trigger ); } else { ui_wprintf_at( MainWindow, 12, 6, "Wall: none "); ui_wprintf_at( MainWindow, 12, 23, " Type: none "); ui_wprintf_at( MainWindow, 12, 40, " Clip: none "); ui_wprintf_at( MainWindow, 12, 57, " Trigger: none "); } Update_flags |= UF_WORLD_CHANGED; } if ( QuitButton->pressed || (last_keypress==KEY_ESC) ) { close_wall_window(); return; } old_wall_num = Cursegp->sides[Curside].wall_num; } //--------------------------------------------------------------------- extern void wall_close_door_num(int door_num); // Restore all walls to original status (closed doors, repaired walls) int wall_restore_all() { int i, j; int wall_num; for (i=0;i wall_num) Segments[seg].sides[side].wall_num--; mprintf((0,"BOGUS WALL DELETED!!!!\n")); return 1; } //--------------------------------------------------------------------- // Remove a specific side. int wall_remove_side(segment *seg, short side) { int Connectside; segment *csegp; int lower_wallnum; int w, s, t, l, t1; if (IS_CHILD(seg->children[side]) && IS_CHILD(seg->sides[side].wall_num)) { csegp = &Segments[seg->children[side]]; Connectside = find_connect_side(seg, csegp); remove_trigger(seg, side); remove_trigger(csegp, Connectside); // Remove walls 'wall_num' and connecting side 'wall_num' // from Walls array. lower_wallnum = seg->sides[side].wall_num; if (csegp->sides[Connectside].wall_num < lower_wallnum) lower_wallnum = csegp->sides[Connectside].wall_num; if (Walls[lower_wallnum].linked_wall != -1) Walls[Walls[lower_wallnum].linked_wall].linked_wall = -1; if (Walls[lower_wallnum+1].linked_wall != -1) Walls[Walls[lower_wallnum+1].linked_wall].linked_wall = -1; for (w=lower_wallnum;w lower_wallnum+1) Segments[s].sides[w].wall_num -= 2; // Destroy any links to the deleted wall. for (t=0;tsides[side].wall_num = -1; csegp->sides[Connectside].wall_num = -1; Update_flags |= UF_WORLD_CHANGED; return 1; } editor_status( "Can't remove wall. No wall present."); return 0; } //--------------------------------------------------------------------- // Remove a special wall. int wall_remove() { return wall_remove_side(Cursegp, Curside); } //--------------------------------------------------------------------- // Add a wall to curside int wall_add_to_side(segment *segp, int side, sbyte type) { int connectside; segment *csegp; if (add_wall(segp, side)) { csegp = &Segments[segp->children[side]]; connectside = find_connect_side(segp, csegp); Walls[segp->sides[side].wall_num].segnum = segp-Segments; Walls[csegp->sides[connectside].wall_num].segnum = csegp-Segments; Walls[segp->sides[side].wall_num].sidenum = side; Walls[csegp->sides[connectside].wall_num].sidenum = connectside; Walls[segp->sides[side].wall_num].flags = 0; Walls[csegp->sides[connectside].wall_num].flags = 0; Walls[segp->sides[side].wall_num].type = type; Walls[csegp->sides[connectside].wall_num].type = type; // Walls[segp->sides[side].wall_num].trigger = -1; // Walls[csegp->sides[connectside].wall_num].trigger = -1; Walls[segp->sides[side].wall_num].clip_num = -1; Walls[csegp->sides[connectside].wall_num].clip_num = -1; Walls[segp->sides[side].wall_num].keys = KEY_NONE; Walls[csegp->sides[connectside].wall_num].keys = KEY_NONE; if (type == WALL_BLASTABLE) { Walls[segp->sides[side].wall_num].hps = WALL_HPS; Walls[csegp->sides[connectside].wall_num].hps = WALL_HPS; //Walls[segp->sides[side].wall_num].clip_num = 0; //Walls[csegp->sides[connectside].wall_num].clip_num = 0; } if (type != WALL_DOOR) { segp->sides[side].tmap_num2 = 0; csegp->sides[connectside].tmap_num2 = 0; } if (type == WALL_DOOR) { Walls[segp->sides[side].wall_num].flags |= WALL_DOOR_AUTO; Walls[csegp->sides[connectside].wall_num].flags |= WALL_DOOR_AUTO; Walls[segp->sides[side].wall_num].clip_num = Current_door_type; Walls[csegp->sides[connectside].wall_num].clip_num = Current_door_type; } //Update_flags |= UF_WORLD_CHANGED; //return 1; // return NextWall(); //assign a clip num return wall_assign_door(Current_door_type); } else { editor_status( "Cannot add wall here, no children" ); return 0; } } //--------------------------------------------------------------------- // Add a wall to markedside int wall_add_to_markedside(sbyte type) { int Connectside; segment *csegp; if (add_wall(Markedsegp, Markedside)) { int wall_num, cwall_num; csegp = &Segments[Markedsegp->children[Markedside]]; Connectside = find_connect_side(Markedsegp, csegp); wall_num = Markedsegp->sides[Markedside].wall_num; cwall_num = csegp->sides[Connectside].wall_num; Walls[wall_num].segnum = Markedsegp-Segments; Walls[cwall_num].segnum = csegp-Segments; Walls[wall_num].sidenum = Markedside; Walls[cwall_num].sidenum = Connectside; Walls[wall_num].flags = 0; Walls[cwall_num].flags = 0; Walls[wall_num].type = type; Walls[cwall_num].type = type; Walls[wall_num].trigger = -1; Walls[cwall_num].trigger = -1; Walls[wall_num].clip_num = -1; Walls[cwall_num].clip_num = -1; Walls[wall_num].keys = KEY_NONE; Walls[cwall_num].keys = KEY_NONE; if (type == WALL_BLASTABLE) { Walls[wall_num].hps = WALL_HPS; Walls[cwall_num].hps = WALL_HPS; Walls[wall_num].clip_num = 0; Walls[cwall_num].clip_num = 0; } if (type != WALL_DOOR) { Markedsegp->sides[Markedside].tmap_num2 = 0; csegp->sides[Connectside].tmap_num2 = 0; } Update_flags |= UF_WORLD_CHANGED; return 1; } else { editor_status( "Cannot add wall here, no children" ); return 0; } } int wall_add_door_flag(sbyte flag) { int Connectside; segment *csegp; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("Cannot change flag. No wall at Curside."); return 0; } if (Walls[Cursegp->sides[Curside].wall_num].type != WALL_DOOR) { editor_status("Cannot change flag. No door at Curside."); return 0; } csegp = &Segments[Cursegp->children[Curside]]; Connectside = find_connect_side(Cursegp, csegp); Walls[Cursegp->sides[Curside].wall_num].flags |= flag; Walls[csegp->sides[Connectside].wall_num].flags |= flag; Update_flags |= UF_ED_STATE_CHANGED; return 1; } int wall_remove_door_flag(sbyte flag) { int Connectside; segment *csegp; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("Cannot change flag. No wall at Curside."); return 0; } if (Walls[Cursegp->sides[Curside].wall_num].type != WALL_DOOR) { editor_status("Cannot change flag. No door at Curside."); return 0; } csegp = &Segments[Cursegp->children[Curside]]; Connectside = find_connect_side(Cursegp, csegp); Walls[Cursegp->sides[Curside].wall_num].flags &= ~flag; Walls[csegp->sides[Connectside].wall_num].flags &= ~flag; Update_flags |= UF_ED_STATE_CHANGED; return 1; } int bind_wall_to_control_center() { int link_num; int i; if (Cursegp->sides[Curside].wall_num == -1) { editor_status("No wall at Curside."); return 0; } link_num = ControlCenterTriggers.num_links; for (i=0;isides[Curside].wall_num != -1) w1 = &Walls[Cursegp->sides[Curside].wall_num]; if (Markedsegp->sides[Markedside].wall_num != -1) w2 = &Walls[Markedsegp->sides[Markedside].wall_num]; if (!w1 || w1->type != WALL_DOOR) { editor_status("Curseg/curside is not a door"); return 0; } if (!w2 || w2->type != WALL_DOOR) { editor_status("Markedseg/markedside is not a door"); return 0; } if (w1->linked_wall != -1) editor_status("Curseg/curside is already linked"); if (w2->linked_wall != -1) editor_status("Markedseg/markedside is already linked"); w1->linked_wall = w2-Walls; w2->linked_wall = w1-Walls; return 1; } int wall_unlink_door() { wall *w1=NULL; if (Cursegp->sides[Curside].wall_num != -1) w1 = &Walls[Cursegp->sides[Curside].wall_num]; if (!w1 || w1->type != WALL_DOOR) { editor_status("Curseg/curside is not a door"); return 0; } if (w1->linked_wall == -1) editor_status("Curseg/curside is not linked"); Assert(Walls[w1->linked_wall].linked_wall == w1-Walls); Walls[w1->linked_wall].linked_wall = -1; w1->linked_wall = -1; return 1; } #define DIAGNOSTIC_MESSAGE_MAX 150 int check_walls() { int w, seg, side, wall_count, trigger_count; int w1, w2, t, l; count_wall CountedWalls[MAX_WALLS]; char Message[DIAGNOSTIC_MESSAGE_MAX]; int matcen_num; wall_count = 0; for (seg=0;seg<=Highest_segment_index;seg++) if (Segments[seg].segnum != -1) { // Check fuelcenters matcen_num = Segment2s[seg].matcen_num; if (matcen_num == 0) if (RobotCenters[0].segnum != seg) { mprintf((0,"Fixing Matcen 0\n")); Segment2s[seg].matcen_num = -1; } if (matcen_num > -1) if (RobotCenters[matcen_num].segnum != seg) { mprintf((0,"Matcen [%d] (seg %d) doesn't point back to correct segment %d\n", matcen_num, RobotCenters[matcen_num].segnum, seg)); mprintf((0,"Fixing....\n")); RobotCenters[matcen_num].segnum = seg; } for (side=0;side= Num_walls) mprintf((0,"wallnum %d in Segments exceeds Num_walls!\n", CountedWalls[w].wallnum)); if (Walls[w].segnum == -1) { mprintf((0, "Wall[%d] is BOGUS\n", w)); for (seg=0;seg<=Highest_segment_index;seg++) for (side=0;side