/* 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. */ /* * $Source: /cvsroot/dxx-rebirth/d1x-rebirth/editor/medwall.c,v $ * $Revision: 1.1.1.1 $ * $Author: zicodxx $ * $Date: 2006/03/17 19:45:52 $ * * Created from version 1.11 of main\wall.c * * $Log: medwall.c,v $ * Revision 1.1.1.1 2006/03/17 19:45:52 zicodxx * initial import * * Revision 1.1.1.1 1999/06/14 22:04:04 donut * Import of d1x 1.37 source. * * Revision 2.0 1995/02/27 11:35:47 john * Version 2.0! No anonymous unions, Watcom 10.0, with no need * for bitmaps.tbl. * * Revision 1.71 1995/02/01 16:30:03 yuan * Stabilizing triggers and matcens. * * Revision 1.70 1995/01/28 15:28:08 yuan * Return proper bug description. * * Revision 1.69 1995/01/14 19:18:07 john * First version of object paging. * * Revision 1.68 1995/01/12 12:10:44 yuan * Added delete trigger function * * Revision 1.67 1994/11/29 16:51:53 yuan * Fixed false bogus trigger info. * * Revision 1.66 1994/11/27 23:17:29 matt * Made changes for new mprintf calling convention * * Revision 1.65 1994/11/15 11:59:42 john * Changed timing for door to use fixed seconds instead of milliseconds. * * Revision 1.64 1994/11/03 10:41:17 yuan * Made walls add whichever the previous type was. * * Revision 1.63 1994/10/13 13:14:59 yuan * Fixed trigger removal bug. * * Revision 1.62 1994/10/07 17:43:39 yuan * Make validate walls default to 1. * * Revision 1.61 1994/10/03 23:40:20 mike * Fix hosedness in walls in group copying. * * Revision 1.60 1994/09/29 00:20:36 matt * Took out reference to unused external wall type * * Revision 1.59 1994/09/28 17:32:24 mike * Functions to copy walls withing groups. * * Revision 1.58 1994/09/28 13:40:46 yuan * Fixed control center trigger bug. * * Revision 1.57 1994/09/24 12:41:52 matt * Took out references to obsolete constants * * Revision 1.56 1994/09/23 18:03:55 yuan * Finished wall checking code. * * Revision 1.55 1994/09/22 14:35:25 matt * Made blastable walls work again * * Revision 1.54 1994/09/21 16:46:07 yuan * Fixed bug that reset wall slot which was just deleted. * * Revision 1.53 1994/09/20 18:31:21 yuan * Output right Wallnum * * Revision 1.52 1994/09/20 18:23:24 yuan * Killed the BOGIFYING WALL DRAGON... * * There was a problem with triggers being created that had bogus * pointers back to their segments. * * Revision 1.51 1994/09/20 11:13:11 yuan * Delete all bogus walls when checking walls. * * Revision 1.50 1994/09/19 23:31:14 yuan * Adding wall checking stuff. * * Revision 1.49 1994/09/13 21:11:20 matt * Added wclips that use tmap1 instead of tmap2, saving lots of merging * * Revision 1.48 1994/09/10 13:32:08 matt * Made exploding walls a type of blastable walls. * Cleaned up blastable walls, making them tmap2 bitmaps. * * Revision 1.47 1994/09/10 09:47:47 yuan * Added wall checking function. * * Revision 1.46 1994/08/26 14:14:56 yuan * Fixed wall clip being set to -2 bug. * * Revision 1.45 1994/08/25 21:56:26 mike * IS_CHILD stuff. * * Revision 1.44 1994/08/19 19:30:27 matt * Added informative message if wall is already external when making it so. * * Revision 1.43 1994/08/17 11:13:46 matt * Changed way external walls work * * Revision 1.42 1994/08/15 17:47:29 yuan * Added external walls * * Revision 1.41 1994/08/05 21:18:09 matt * Allow two doors to be linked together * * Revision 1.40 1994/08/02 14:18:06 mike * Clean up dialog boxes. * * Revision 1.39 1994/08/01 11:04:33 yuan * New materialization centers. * * Revision 1.38 1994/07/22 17:19:11 yuan * Working on dialog box for refuel/repair/material/control centers. * * Revision 1.37 1994/07/20 17:35:33 yuan * Added new gold key. * * Revision 1.36 1994/07/19 14:31:44 yuan * Fixed keys bug. * * Revision 1.35 1994/07/18 15:58:31 yuan * Hopefully prevent any "Adam door bombouts" * * Revision 1.34 1994/07/18 15:48:40 yuan * Made minor cosmetic change. * * Revision 1.33 1994/07/15 16:09:22 yuan * Error checking * * Revision 1.32 1994/07/14 16:47:05 yuan * Fixed wall dialog for selected dooranims. * * Revision 1.31 1994/07/11 15:09:16 yuan * Wall anim filenames stored in wclip structure. * * Revision 1.30 1994/07/06 10:56:01 john * New structures for hostages. * * Revision 1.29 1994/07/01 16:35:54 yuan * Added key system * * Revision 1.28 1994/06/21 18:50:12 john * Made ESC key exit dialog. * * Revision 1.27 1994/06/20 22:29:59 yuan * Fixed crazy runaway trigger bug that Adam found * * Revision 1.26 1994/06/01 15:50:25 yuan * Added one more door... Needs to be set by bm.c in the future. * * Revision 1.25 1994/05/30 20:22:34 yuan * New triggers. * * Revision 1.24 1994/05/27 10:34:31 yuan * Added new Dialog boxes for Walls and Triggers. * * Revision 1.23 1994/05/25 18:08:45 yuan * Revamping walls and triggers interface. * Wall interface complete, but triggers are still in progress. * * Revision 1.22 1994/05/18 18:21:56 yuan * Fixed delete segment and walls bug. * * Revision 1.21 1994/05/11 18:24:29 yuan * Oops.. trigger not triggers.. * * Revision 1.20 1994/05/11 18:23:53 yuan * Fixed trigger not set to -1 bug. * */ #ifdef RCS static char rcsid[] = "$Id: medwall.c,v 1.1.1.1 2006/03/17 19:45:52 zicodxx Exp $"; #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 "fuelcen.h" #include "key.h" #include "ehostage.h" #include "centers.h" #include "piggy.h" int wall_add_door_flag(byte flag); int wall_add_to_side(segment *segp, int side, byte type); int wall_remove_door_flag(byte 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; //--------------------------------------------------------------------- // 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; byte 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) { for ( i=0; i < 3; i++ ) { DoorFlag[i]->flag = 0; // Tells ui that this button isn't checked DoorFlag[i]->status = 1; // Tells ui to redraw button } for ( i=0; i < 4; i++ ) { KeyFlag[i]->flag = 0; // Tells ui that this button isn't checked KeyFlag[i]->status = 1; // Tells ui to redraw button } if ( Cursegp->sides[Curside].wall_num != -1) { if (Walls[Cursegp->sides[Curside].wall_num].flags & WALL_DOOR_LOCKED) DoorFlag[0]->flag = 1; // Mark this button as checked if (Walls[Cursegp->sides[Curside].wall_num].flags & WALL_DOOR_AUTO) DoorFlag[1]->flag = 1; // Mark this button as checked if (Walls[Cursegp->sides[Curside].wall_num].flags & WALL_ILLUSION_OFF) DoorFlag[2]->flag = 1; // Mark this button as checked if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_NONE) KeyFlag[0]->flag = 1; if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_BLUE) KeyFlag[1]->flag = 1; if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_RED) KeyFlag[2]->flag = 1; if (Walls[Cursegp->sides[Curside].wall_num].keys & KEY_GOLD) KeyFlag[3]->flag = 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) { DoorFlag[i]->flag = 0; // Tells ui that this button isn't checked DoorFlag[i]->status = 1; // Tells ui to redraw button } for ( i=0; i < 4; i++ ) { if ( KeyFlag[i]->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; } //--------------------------------------------------------------------- // 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, byte 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(byte 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(byte 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(byte 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 = Segments[seg].matcen_num; if (matcen_num == 0) if (RobotCenters[0].segnum != seg) { mprintf((0,"Fixing Matcen 0\n")); Segments[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