dxx-rebirth/editor/medrobot.c
2006-03-20 16:43:15 +00:00

942 lines
27 KiB
C
Executable file

/*
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/medrobot.c,v $
* $Revision: 1.1.1.1 $
* $Author: zicodxx $
* $Date: 2006/03/17 19:45:16 $
*
* Dialog box to edit robot properties.
*
* $Log: medrobot.c,v $
* Revision 1.1.1.1 2006/03/17 19:45:16 zicodxx
* initial import
*
* Revision 1.1.1.1 1999/06/14 22:03:56 donut
* Import of d1x 1.37 source.
*
* Revision 2.0 1995/02/27 11:35:59 john
* Version 2.0! No anonymous unions, Watcom 10.0, with no need
* for bitmaps.tbl.
*
* Revision 1.46 1995/02/22 15:22:03 allender
* remove anonyous unions from object structure
*
* Revision 1.45 1994/11/27 23:17:32 matt
* Made changes for new mprintf calling convention
*
* Revision 1.44 1994/11/14 11:39:57 mike
* fix default robot behavior
*
* Revision 1.43 1994/11/02 16:18:47 matt
* Moved draw_model_picture() out of editor, and cleaned up code
*
* Revision 1.42 1994/10/10 17:23:23 mike
* Verify that not placing too many player objects.
*
* Revision 1.41 1994/10/09 22:04:38 mike
* Maybe improve, maybe not, robot selection in shift-R menu.
*
* Revision 1.40 1994/09/30 21:49:01 mike
* Fix stupid shift-R dialog bug which caused lots of mprintf and selecting of object and frustration.
*
* Revision 1.39 1994/09/30 11:51:33 mike
* Fix boolean logic on an error trap.
*
* Revision 1.38 1994/09/20 14:36:32 mike
* Clean up Robot dialog.
*
* Revision 1.37 1994/09/12 19:11:56 mike
* Fix stupid bugs in selecting objects.
*
* Revision 1.36 1994/09/01 17:05:51 matt
* Don't force redraw if object select fails
*
* Revision 1.35 1994/08/31 19:24:40 mike
* Fix hang bug when only objects in mine are not robots.
*
* Revision 1.34 1994/08/25 21:56:38 mike
* IS_CHILD stuff.
*
* Revision 1.33 1994/08/23 16:39:29 mike
* mode replaced by behavior in ai_info.
*
* Revision 1.32 1994/08/15 23:47:16 mike
* fix bugs.
*
* Revision 1.31 1994/08/13 17:32:45 mike
* set to still function.
*
* Revision 1.30 1994/08/09 16:06:02 john
* Added the ability to place players. Made old
* Player variable be ConsoleObject.
*
* Revision 1.29 1994/08/02 16:22:48 matt
* Finished object editor dialog
*
*/
#ifdef RCS
static char rcsid[] = "$Id: medrobot.c,v 1.1.1.1 2006/03/17 19:45:16 zicodxx Exp $";
#endif
#include <stdlib.h>
#include <stdio.h>
#ifndef __LINUX__
#include <conio.h>
#include <direct.h>
#include <dos.h>
#endif
#include <math.h>
#include <string.h>
#include "screens.h"
#include "inferno.h"
#include "segment.h"
#include "editor.h"
#include "timer.h"
#include "objpage.h"
#include "fix.h"
#include "mono.h"
#include "error.h"
#include "kdefs.h"
#include "object.h"
#include "polyobj.h"
#include "game.h"
#include "powerup.h"
#include "ai.h"
#include "hostage.h"
#include "eobject.h"
#include "medwall.h"
#include "eswitch.h"
#include "ehostage.h"
#include "key.h"
#include "centers.h"
#include "bm.h"
#define NUM_BOXES 6 // Number of boxes, AI modes
int GoodyNextID();
int GoodyPrevID();
void robot_close_window();
//-------------------------------------------------------------------------
// Variables for this module...
//-------------------------------------------------------------------------
static UI_WINDOW *MainWindow = NULL;
static UI_GADGET_USERBOX *RobotViewBox;
static UI_GADGET_USERBOX *ContainsViewBox;
static UI_GADGET_BUTTON *QuitButton;
static UI_GADGET_RADIO *InitialMode[NUM_BOXES];
static int old_object;
static fix Time;
static vms_angvec angles={0,0,0}, goody_angles={0,0,0};
//-------------------------------------------------------------------------
// Given a pointer to an object, returns a number that cooresponds to the
// object id as used in the objpage stuff.
//-------------------------------------------------------------------------
int get_object_id( object * obj )
{
int i;
int goal_type;
switch( obj->type ) {
case OBJ_PLAYER: goal_type=OL_PLAYER; break;
case OBJ_ROBOT: goal_type=OL_ROBOT; break;
case OBJ_POWERUP: goal_type=OL_POWERUP; break;
case OBJ_CNTRLCEN: goal_type=OL_CONTROL_CENTER; break;
case OBJ_HOSTAGE: goal_type=OL_HOSTAGE; break;
case OBJ_CLUTTER: goal_type=OL_CLUTTER; break;
default:
Int3(); // Invalid object type
return -1;
}
// Find first object with the same type as this
// one and then add the object id to that to find
// the offset into the list.
for (i=0; i< Num_total_object_types; i++ ) {
if ( ObjType[i]==goal_type)
return obj->id + i;
}
return -1;
}
void call_init_ai_object(object *objp, int behavior)
{
int hide_segment;
if (behavior == AIB_STATION)
hide_segment = Cursegp-Segments;
else {
if (Markedsegp != NULL)
hide_segment = Markedsegp-Segments;
else
hide_segment = Cursegp-Segments;
}
mprintf((0, "Initializing AI object with hide segment = %i\n", hide_segment));
init_ai_object(objp-Objects, behavior, hide_segment);
if (behavior == AIB_STATION) {
int cseg, mseg;
cseg = 0;
mseg = 0;
if (Cursegp != NULL)
cseg = Cursegp-Segments;
if (Markedsegp != NULL) {
mseg = Markedsegp-Segments;
}
objp->ctype.ai_info.follow_path_start_seg = Cursegp-Segments;
objp->ctype.ai_info.follow_path_end_seg = Markedsegp-Segments;
}
}
//-------------------------------------------------------------------------
// Called when user presses "Next Type" button. This only works for polygon
// objects and it just selects the next polygon model for the current object.
//-------------------------------------------------------------------------
int RobotNextType()
{
if (Cur_object_index > -1 ) {
if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
object * obj = &Objects[Cur_object_index];
obj->id++;
if (obj->id >= N_robot_types )
obj->id = 0;
//Set polygon-object-specific data
obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
obj->rtype.pobj_info.subobj_flags = 0;
//set Physics info
obj->mtype.phys_info.flags |= (PF_LEVELLING);
obj->shields = Robot_info[obj->id].strength;
call_init_ai_object(obj, AIB_NORMAL);
Cur_robot_type = obj->id;
}
}
Update_flags |= UF_WORLD_CHANGED;
return 1;
}
//-------------------------------------------------------------------------
// Called when user presses "Prev Type" button. This only works for polygon
// objects and it just selects the prev polygon model for the current object.
//-------------------------------------------------------------------------
int RobotPrevType()
{
if (Cur_object_index > -1 ) {
if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
object * obj = &Objects[Cur_object_index];
if (obj->id == 0 )
obj->id = N_robot_types-1;
else
obj->id--;
//Set polygon-object-specific data
obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
obj->rtype.pobj_info.subobj_flags = 0;
//set Physics info
obj->mtype.phys_info.flags |= (PF_LEVELLING);
obj->shields = Robot_info[obj->id].strength;
call_init_ai_object(obj, AIB_NORMAL);
Cur_robot_type = obj->id;
}
}
Update_flags |= UF_WORLD_CHANGED;
return 1;
}
//-------------------------------------------------------------------------
// Dummy function for Mike to write.
//-------------------------------------------------------------------------
int med_set_ai_path()
{
mprintf( (0, "med-set-ai-path called -- it does nothing, paths automatically set!\n" ));
return 1;
}
// #define OBJ_NONE 255 //unused object
// #define OBJ_WALL 0 //A wall... not really an object, but used for collisions
// #define OBJ_FIREBALL 1 //a fireball, part of an explosion
// #define OBJ_ROBOT 2 //an evil enemy
// #define OBJ_HOSTAGE 3 //a hostage you need to rescue
// #define OBJ_PLAYER 4 //the player on the console
// #define OBJ_WEAPON 5 //a laser, missile, etc
// #define OBJ_CAMERA 6 //a camera to slew around with
// #define OBJ_POWERUP 7 //a powerup you can pick up
// #define OBJ_DEBRIS 8 //a piece of robot
// #define OBJ_CNTRLCEN 9 //the control center
// #define OBJ_FLARE 10 //the control center
// #define MAX_OBJECT_TYPES 11
#define GOODY_TYPE_MAX MAX_OBJECT_TYPES
#define GOODY_X 6
#define GOODY_Y 132
//#define GOODY_ID_MAX_ROBOT 6
//#define GOODY_ID_MAX_POWERUP 9
#define GOODY_COUNT_MAX 4
int Cur_goody_type = OBJ_POWERUP;
int Cur_goody_id = 0;
int Cur_goody_count = 0;
void update_goody_info(void)
{
if (Cur_object_index > -1 ) {
if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
object * obj = &Objects[Cur_object_index];
obj->contains_type = Cur_goody_type;
obj->contains_id = Cur_goody_id;
obj->contains_count = Cur_goody_count;
}
}
}
// #define OBJ_WALL 0 //A wall... not really an object, but used for collisions
// #define OBJ_FIREBALL 1 //a fireball, part of an explosion
// #define OBJ_ROBOT 2 //an evil enemy
// #define OBJ_HOSTAGE 3 //a hostage you need to rescue
// #define OBJ_PLAYER 4 //the player on the console
// #define OBJ_WEAPON 5 //a laser, missile, etc
// #define OBJ_CAMERA 6 //a camera to slew around with
// #define OBJ_POWERUP 7 //a powerup you can pick up
// #define OBJ_DEBRIS 8 //a piece of robot
// #define OBJ_CNTRLCEN 9 //the control center
// #define OBJ_FLARE 10 //the control center
// #define MAX_OBJECT_TYPES 11
int GoodyNextType()
{
Cur_goody_type++;
while (!((Cur_goody_type == OBJ_ROBOT) || (Cur_goody_type == OBJ_POWERUP))) {
if (Cur_goody_type > GOODY_TYPE_MAX)
Cur_goody_type=0;
else
Cur_goody_type++;
}
GoodyNextID();
GoodyPrevID();
update_goody_info();
return 1;
}
int GoodyPrevType()
{
Cur_goody_type--;
while (!((Cur_goody_type == OBJ_ROBOT) || (Cur_goody_type == OBJ_POWERUP))) {
if (Cur_goody_type < 0)
Cur_goody_type = GOODY_TYPE_MAX;
else
Cur_goody_type--;
}
GoodyNextID();
GoodyPrevID();
update_goody_info();
return 1;
}
int GoodyNextID()
{
Cur_goody_id++;
if (Cur_goody_type == OBJ_ROBOT) {
if (Cur_goody_id >= N_robot_types)
Cur_goody_id=0;
} else {
if (Cur_goody_id >= N_powerup_types)
Cur_goody_id=0;
}
update_goody_info();
return 1;
}
int GoodyPrevID()
{
Cur_goody_id--;
if (Cur_goody_type == OBJ_ROBOT) {
if (Cur_goody_id < 0)
Cur_goody_id = N_robot_types-1;
} else {
if (Cur_goody_id < 0)
Cur_goody_id = N_powerup_types-1;
}
update_goody_info();
return 1;
}
int GoodyNextCount()
{
Cur_goody_count++;
if (Cur_goody_count > GOODY_COUNT_MAX)
Cur_goody_count=0;
update_goody_info();
return 1;
}
int GoodyPrevCount()
{
Cur_goody_count--;
if (Cur_goody_count < 0)
Cur_goody_count=GOODY_COUNT_MAX;
update_goody_info();
return 1;
}
int is_legal_type(int the_type)
{
return (the_type == OBJ_ROBOT) || (the_type == OBJ_CLUTTER);
}
int is_legal_type_for_this_window(int objnum)
{
if (objnum == -1)
return 1;
else
return is_legal_type(Objects[objnum].type);
}
int LocalObjectSelectNextinSegment(void)
{
int rval, first_obj;
rval = ObjectSelectNextinSegment();
first_obj = Cur_object_index;
if (Cur_object_index != -1) {
while (!is_legal_type_for_this_window(Cur_object_index)) {
//mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
rval = ObjectSelectNextinSegment();
if (first_obj == Cur_object_index)
break;
}
Cur_goody_type = Objects[Cur_object_index].contains_type;
Cur_goody_id = Objects[Cur_object_index].contains_id;
if (Objects[Cur_object_index].contains_count < 0)
Objects[Cur_object_index].contains_count = 0;
Cur_goody_count = Objects[Cur_object_index].contains_count;
}
if (Cur_object_index != first_obj)
set_view_target_from_segment(Cursegp);
return rval;
}
int LocalObjectSelectNextinMine(void)
{
int rval, first_obj;
rval = ObjectSelectNextInMine();
first_obj = Cur_object_index;
if (Cur_object_index != -1) {
while (!is_legal_type_for_this_window(Cur_object_index)) {
//mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
ObjectSelectNextInMine();
if (Cur_object_index == first_obj)
break;
}
Cur_goody_type = Objects[Cur_object_index].contains_type;
Cur_goody_id = Objects[Cur_object_index].contains_id;
if (Objects[Cur_object_index].contains_count < 0)
Objects[Cur_object_index].contains_count = 0;
Cur_goody_count = Objects[Cur_object_index].contains_count;
}
if (Cur_object_index != first_obj)
set_view_target_from_segment(Cursegp);
return rval;
}
int LocalObjectSelectPrevinMine(void)
{
int rval, first_obj;
rval = ObjectSelectPrevInMine();
first_obj = Cur_object_index;
if (Cur_object_index != -1) {
while (!is_legal_type_for_this_window(Cur_object_index)) {
//mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
ObjectSelectPrevInMine();
if (first_obj == Cur_object_index)
break;
}
Cur_goody_type = Objects[Cur_object_index].contains_type;
Cur_goody_id = Objects[Cur_object_index].contains_id;
if (Objects[Cur_object_index].contains_count < 0)
Objects[Cur_object_index].contains_count = 0;
Cur_goody_count = Objects[Cur_object_index].contains_count;
}
if (Cur_object_index != first_obj)
set_view_target_from_segment(Cursegp);
return rval;
}
int LocalObjectDelete(void)
{
int rval;
rval = ObjectDelete();
if (Cur_object_index != -1) {
Cur_goody_type = Objects[Cur_object_index].contains_type;
Cur_goody_id = Objects[Cur_object_index].contains_id;
Cur_goody_count = Objects[Cur_object_index].contains_count;
}
set_view_target_from_segment(Cursegp);
return rval;
}
int LocalObjectPlaceObject(void)
{
int rval;
Cur_goody_count = 0;
while (ObjType[Cur_robot_type] != OL_ROBOT) { // && (ObjType[Cur_robot_type] != OL_POWERUP)) {
Cur_robot_type++;
if (Cur_robot_type >= N_robot_types)
Cur_robot_type = 0;
}
rval = ObjectPlaceObject();
if (rval == -1)
return -1;
Objects[Cur_object_index].contains_type = Cur_goody_type;
Objects[Cur_object_index].contains_id = Cur_goody_id;
Objects[Cur_object_index].contains_count = Cur_goody_count;
set_view_target_from_segment(Cursegp);
return rval;
}
void close_all_windows(void)
{
close_trigger_window();
close_wall_window();
close_centers_window();
hostage_close_window();
robot_close_window();
}
//-------------------------------------------------------------------------
// Called from the editor... does one instance of the robot dialog box
//-------------------------------------------------------------------------
int do_robot_dialog()
{
int i;
// Only open 1 instance of this window...
if ( MainWindow != NULL ) return 0;
// Close other windows
close_all_windows();
Cur_goody_count = 0;
// 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, 286, 40, 32, "Done", NULL );
ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y-3, 25, 22, "<<", GoodyPrevType );
ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y-3, 25, 22, ">>", GoodyNextType );
ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y+21, 25, 22, "<<", GoodyPrevID );
ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y+21, 25, 22, ">>", GoodyNextID );
ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y+45, 25, 22, "<<", GoodyPrevCount );
ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y+45, 25, 22, ">>", GoodyNextCount );
InitialMode[0] = ui_add_gadget_radio( MainWindow, 6, 58, 16, 16, 0, "Hover" );
InitialMode[1] = ui_add_gadget_radio( MainWindow, 76, 58, 16, 16, 0, "Normal" );
InitialMode[2] = ui_add_gadget_radio( MainWindow, 6, 78, 16, 16, 0, "(hide)" );
InitialMode[3] = ui_add_gadget_radio( MainWindow, 76, 78, 16, 16, 0, "Avoid" );
InitialMode[4] = ui_add_gadget_radio( MainWindow, 6, 98, 16, 16, 0, "Follow" );
InitialMode[5] = ui_add_gadget_radio( MainWindow, 76, 98, 16, 16, 0, "Station" );
// The little box the robots will spin in.
RobotViewBox = ui_add_gadget_userbox( MainWindow,155, 5, 150, 125 );
// The little box the robots will spin in.
ContainsViewBox = ui_add_gadget_userbox( MainWindow,10, 202, 100, 80 );
// A bunch of buttons...
i = 135;
ui_add_gadget_button( MainWindow,190,i,53, 26, "<<Typ", RobotPrevType );
ui_add_gadget_button( MainWindow,247,i,53, 26, "Typ>>", RobotNextType ); i += 29;
ui_add_gadget_button( MainWindow,190,i,110, 26, "Next in Seg", LocalObjectSelectNextinSegment ); i += 29;
ui_add_gadget_button( MainWindow,190,i,53, 26, "<<Obj", LocalObjectSelectPrevinMine );
ui_add_gadget_button( MainWindow,247,i,53, 26, ">>Obj", LocalObjectSelectNextinMine ); i += 29;
ui_add_gadget_button( MainWindow,190,i,110, 26, "Delete", LocalObjectDelete ); i += 29;
ui_add_gadget_button( MainWindow,190,i,110, 26, "Create New", LocalObjectPlaceObject ); i += 29;
ui_add_gadget_button( MainWindow,190,i,110, 26, "Set Path", med_set_ai_path );
Time = timer_get_fixed_seconds();
old_object = -2; // Set to some dummy value so everything works ok on the first frame.
if ( Cur_object_index == -1 )
LocalObjectSelectNextinMine();
return 1;
}
void robot_close_window()
{
if ( MainWindow!=NULL ) {
ui_close_window( MainWindow );
MainWindow = NULL;
}
}
#define STRING_LENGTH 8
void do_robot_window()
{
int i;
fix DeltaTime, Temp;
int first_object_index;
if ( MainWindow == NULL ) return;
first_object_index = Cur_object_index;
while (!is_legal_type_for_this_window(Cur_object_index)) {
LocalObjectSelectNextinMine();
if (first_object_index == Cur_object_index) {
break;
}
}
//------------------------------------------------------------
// Call the ui code..
//------------------------------------------------------------
ui_button_any_drawn = 0;
ui_window_do_gadgets(MainWindow);
//------------------------------------------------------------
// If we change objects, we need to reset the ui code for all
// of the radio buttons that control the ai mode. Also makes
// the current AI mode button be flagged as pressed down.
//------------------------------------------------------------
if (old_object != Cur_object_index ) {
for ( i=0; i < NUM_BOXES; i++ ) {
InitialMode[i]->flag = 0; // Tells ui that this button isn't checked
InitialMode[i]->status = 1; // Tells ui to redraw button
}
if ( Cur_object_index > -1 ) {
int behavior = Objects[Cur_object_index].ctype.ai_info.behavior;
if ( !((behavior >= MIN_BEHAVIOR) && (behavior <= MAX_BEHAVIOR))) {
mprintf((0, "Object #%i behavior id (%i) out of bounds, setting to AIB_NORMAL.\n", Cur_object_index, behavior));
Objects[Cur_object_index].ctype.ai_info.behavior = AIB_NORMAL;
behavior = AIB_NORMAL;
}
InitialMode[behavior - MIN_BEHAVIOR]->flag = 1; // Mark this button as checked
}
}
//------------------------------------------------------------
// If any of the radio buttons that control the mode are set, then
// update the cooresponding AI state.
//------------------------------------------------------------
for ( i=0; i < NUM_BOXES; i++ ) {
if ( InitialMode[i]->flag == 1 )
if (Objects[Cur_object_index].ctype.ai_info.behavior != MIN_BEHAVIOR+i) {
Objects[Cur_object_index].ctype.ai_info.behavior = MIN_BEHAVIOR+i; // Set the ai_state to the cooresponding radio button
call_init_ai_object(&Objects[Cur_object_index], MIN_BEHAVIOR+i);
}
}
//------------------------------------------------------------
// A simple frame time counter for spinning the objects...
//------------------------------------------------------------
Temp = timer_get_fixed_seconds();
DeltaTime = Temp - Time;
Time = Temp;
//------------------------------------------------------------
// Redraw the object in the little 64x64 box
//------------------------------------------------------------
if (Cur_object_index > -1 ) {
int id;
gr_set_current_canvas( RobotViewBox->canvas );
id = get_object_id(&Objects[Cur_object_index]);
if ( id > -1 )
draw_robot_picture(id, &angles, -1 );
else
gr_clear_canvas( CGREY );
angles.h += fixmul(0x1000, DeltaTime );
} else {
// no object, so just blank out
gr_set_current_canvas( RobotViewBox->canvas );
gr_clear_canvas( CGREY );
// LocalObjectSelectNextInMine();
}
//------------------------------------------------------------
// Redraw the contained object in the other little box
//------------------------------------------------------------
if ((Cur_object_index > -1 ) && (Cur_goody_count > 0)) {
int id;
gr_set_current_canvas( ContainsViewBox->canvas );
id = Cur_goody_id;
if ( id > -1 ) {
int ol_type=0;
if (Cur_goody_type == OBJ_ROBOT)
ol_type = OL_ROBOT;
else if (Cur_goody_type == OBJ_POWERUP)
ol_type = OL_POWERUP;
else
Int3(); // Error? Unknown goody type!
draw_robot_picture(id, &goody_angles, ol_type );
} else
gr_clear_canvas( CGREY );
goody_angles.h += fixmul(0x1000, DeltaTime );
} else {
// no object, so just blank out
gr_set_current_canvas( ContainsViewBox->canvas );
gr_clear_canvas( CGREY );
// LocalObjectSelectNextInMine();
}
//------------------------------------------------------------
// If anything changes in the ui system, redraw all the text that
// identifies this robot.
//------------------------------------------------------------
if (ui_button_any_drawn || (old_object != Cur_object_index) ) {
int i;
char type_text[STRING_LENGTH+1],id_text[STRING_LENGTH+1];
if (Cur_object_index != -1) {
Cur_goody_type = Objects[Cur_object_index].contains_type;
Cur_goody_id = Objects[Cur_object_index].contains_id;
if (Objects[Cur_object_index].contains_count < 0)
Objects[Cur_object_index].contains_count = 0;
Cur_goody_count = Objects[Cur_object_index].contains_count;
}
ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y, " Type:");
ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+24, " ID:");
ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+48, "Count:");
for (i=0; i<STRING_LENGTH; i++)
id_text[i] = ' ';
id_text[i] = 0;
switch (Cur_goody_type) {
case OBJ_ROBOT:
strcpy(type_text, "Robot ");
strncpy(id_text, Robot_names[Cur_goody_id], strlen(Robot_names[Cur_goody_id]));
break;
case OBJ_POWERUP:
strcpy(type_text, "Powerup");
strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
break;
default:
editor_status("Illegal contained object type (%i), changing to powerup.", Cur_goody_type);
Cur_goody_type = OBJ_POWERUP;
Cur_goody_id = 0;
strcpy(type_text, "Powerup");
strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
break;
}
ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y, type_text);
ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+24, id_text);
ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+48, "%i", Cur_goody_count);
if ( Cur_object_index > -1 ) {
int id = Objects[Cur_object_index].id;
char id_text[12];
int i;
for (i=0; i<STRING_LENGTH; i++)
id_text[i] = ' ';
id_text[i] = 0;
strncpy(id_text, Robot_names[id], strlen(Robot_names[id]));
ui_wprintf_at( MainWindow, 12, 6, "Robot: %3d ", Cur_object_index );
ui_wprintf_at( MainWindow, 12, 22, " Id: %3d", id);
ui_wprintf_at( MainWindow, 12, 38, " Name: %8s", id_text);
} else {
ui_wprintf_at( MainWindow, 12, 6, "Robot: none" );
ui_wprintf_at( MainWindow, 12, 22, " Type: ? " );
ui_wprintf_at( MainWindow, 12, 38, " Name: ________" );
}
Update_flags |= UF_WORLD_CHANGED;
}
if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
robot_close_window();
return;
}
old_object = Cur_object_index;
}
// --------------------------------------------------------------------------------------------------------------------------
#define NUM_MATT_THINGS 2
#define MATT_LEN 20
static UI_WINDOW *MattWindow = NULL;
void object_close_window()
{
if ( MattWindow!=NULL ) {
ui_close_window( MattWindow );
MattWindow = NULL;
}
}
UI_GADGET_INPUTBOX *Xtext, *Ytext, *Ztext;
//-------------------------------------------------------------------------
// Called from the editor... does one instance of the object dialog box
//-------------------------------------------------------------------------
int do_object_dialog()
{
char Xmessage[MATT_LEN], Ymessage[MATT_LEN], Zmessage[MATT_LEN];
object *obj=&Objects[Cur_object_index];
if (obj->type == OBJ_ROBOT) //don't do this for robots
return 0;
// Only open 1 instance of this window...
if ( MattWindow != NULL )
return 0;
Cur_goody_count = 0;
// Open a window with a quit button
MattWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
QuitButton = ui_add_gadget_button( MattWindow, 20, 286, 40, 32, "Done", NULL );
QuitButton->hotkey = KEY_ENTER;
// These are the radio buttons for each mode
InitialMode[0] = ui_add_gadget_radio( MattWindow, 10, 50, 16, 16, 0, "None" );
InitialMode[1] = ui_add_gadget_radio( MattWindow, 80, 50, 16, 16, 0, "Spinning" );
InitialMode[obj->movement_type == MT_SPINNING?1:0]->flag = 1;
sprintf(Xmessage,"%.2f",f2fl(obj->mtype.spin_rate.x));
sprintf(Ymessage,"%.2f",f2fl(obj->mtype.spin_rate.y));
sprintf(Zmessage,"%.2f",f2fl(obj->mtype.spin_rate.z));
ui_wprintf_at( MattWindow, 10, 132,"&X:" );
Xtext = ui_add_gadget_inputbox( MattWindow, 30, 132, MATT_LEN, MATT_LEN, Xmessage );
ui_wprintf_at( MattWindow, 10, 162,"&Y:" );
Ytext = ui_add_gadget_inputbox( MattWindow, 30, 162, MATT_LEN, MATT_LEN, Ymessage );
ui_wprintf_at( MattWindow, 10, 192,"&Z:" );
Ztext = ui_add_gadget_inputbox( MattWindow, 30, 192, MATT_LEN, MATT_LEN, Zmessage );
ui_gadget_calc_keys(MattWindow);
MattWindow->keyboard_focus_gadget = (UI_GADGET *) InitialMode[0];
mprintf((0, "X = %08x, Y = %08x, Z = %08x\n", atoi(Xmessage), atoi(Ymessage), atoi(Zmessage)));
return 1;
}
void do_object_window()
{
object *obj=&Objects[Cur_object_index];
if ( MattWindow == NULL ) return;
//------------------------------------------------------------
// Call the ui code..
//------------------------------------------------------------
ui_button_any_drawn = 0;
ui_window_do_gadgets(MattWindow);
if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
if (InitialMode[0]->flag) obj->movement_type = MT_NONE;
if (InitialMode[1]->flag) obj->movement_type = MT_SPINNING;
obj->mtype.spin_rate.x = fl2f(atof(Xtext->text));
obj->mtype.spin_rate.y = fl2f(atof(Ytext->text));
obj->mtype.spin_rate.z = fl2f(atof(Ztext->text));
object_close_window();
return;
}
old_object = Cur_object_index;
}
void set_all_modes_to_hover(void)
{
int i;
for (i=0; i<=Highest_object_index; i++)
if (Objects[i].control_type == CT_AI)
Objects[i].ctype.ai_info.behavior = AIB_STILL;
}