cTrigger::cTrigger and
cTrigger::~cTrigger
Just as does every C++ class,
cTrigger has a constructor and a destructor that set up
and free the data contained within the class. The only data tracked by the
trigger
class that is not contained with the linked list is the number of triggers
currently
held in the linked list and a pointer to that linked list. The constructor and
destructor ensure that the class is prepared for using those two variables to
free
the class's data when destroyed (by calling the free function).
cTrigger::load and cTrigger::save
You typically design maps with
a set of triggers all in their proper locations.
Loading a list of those triggers is the main priority of the trigger class. Once
a list
of triggers is created or loaded, you also have the option to save that list of
triggers
(to save the game state, for example).
The load function opens a text
file and repeatedly reads in lines of text that define
the type, identification, location, and special properties of each trigger (as
described
in the earlier section “Creating a Trigger Class”). When the end of file is
reached,
the load function returns. Take a look at the load function code to see just
what I’m
talking about:
bool cTrigger::load(const char* filename)
{
free();
FILE* fp = fopen(filename, "rb");
if(fp == NULL)
return false;
// start looping, reading in until EOF reached.
for(;;)
{
long id = get_next_long_2(fp);
if(id == -1)
break;
long type = get_next_long_2(fp);
bool enabled = get_next_long_2(fp) ? true : false;
float x1, y1, z1, x2, y2, z2, x3, z3, radius;
// read in rest depending on type
switch(type)
{
case TRIGGER_SPHERE:
x1 = get_next_float_2(fp);
y1 = get_next_float_2(fp);
z1 = get_next_float_2(fp);
radius = get_next_float_2(fp);
add_sphere(id, enabled, x1, y1, z1, radius);
break;
case TRIGGER_BOX:
x1 = get_next_float_2(fp);
y1 = get_next_float_2(fp);
z1 = get_next_float_2(fp);
x2 = get_next_float_2(fp);
y2 = get_next_float_2(fp);
z2 = get_next_float_2(fp);
add_box(id, enabled, x1, y1, z1, x2, y2, z2);
break;
case TRIGGER_CYLINDER:
x1 = get_next_float_2(fp);
y1 = get_next_float_2(fp);
z1 = get_next_float_2(fp);
radius = get_next_float_2(fp);
y2 = get_next_float_2(fp);
add_cylinder(id, enabled, x1, y1, z1, radius, y2);
break;
case TRIGGER_TRIANGLE:
x1 = get_next_float_2(fp);
z1 = get_next_float_2(fp);
x2 = get_next_float_2(fp);
z2 = get_next_float_2(fp);
x3 = get_next_float_2(fp);
z3 = get_next_float_2(fp);
y1 = get_next_float_2(fp);
y2 = get_next_float_2(fp);
add_triangle(id, enabled, x1, z1, x2, z2, x3, z3, y1, y2);
break;
default: // some error occurred
fclose(fp);
free();
return false;
}
}
fclose(fp);
return true;
}
At this point, the trigger data
file is open and ready to begin reading in a list of
trigger definitions. For each trigger, remember that the text line uses the
following
order: the trigger identification number, the type (0=sphere, 1=box, and so on),
the
default enabled status (0=trigger disabled, 1=enabled), and the specific data
based on
the type of trigger being read.
Once past reading in the
identification number, type, and enabled flag of each trigger,
a single switch...case code block takes care of loading in each trigger type’s
data.
As each trigger’s data is read in, a separate function is called (based on the
trigger’s
type) to insert the trigger into the linked list. Those functions are add_sphere,
add_box,
add_cylinder, and add_triangle.
Moving past the load function,
you see the save function, which scans the linked list
of triggers and saves each trigger’s data to a file, using the same format for
each
line of text that defines a trigger. Take a look:
bool cTrigger::save(const char* filename)
{
if(m_num_triggers == 0)
return false;
FILE* fp = fopen(filename, "wb");
if(fp == NULL)
return false;
// write out all triggers
for(sTrigger* trigger = m_root_trigger; trigger != NULL; trigger = trigger->next)
{
int enabled = trigger->enabled ? 1 : 0;
switch(trigger->type)
{
case TRIGGER_SPHERE:
fprintf(fp, "%lu %lu %lu %lf %lf %lf %lf\r\n",
trigger->id, trigger->type, enabled,
trigger->x1, trigger->y1, trigger->z1,
trigger->radius);
break;
case TRIGGER_BOX:
fprintf(fp, "%lu %lu %lu %lf %lf %lf %lf %lf %lf\r\n",
trigger->id, trigger->type, enabled,
trigger->x1, trigger->y1, trigger->z1,
trigger->x2, trigger->y2, trigger->z2);
break;
case TRIGGER_CYLINDER:
fprintf(fp, "%lu %lu %lu %lf %lf %lf %lf %lf\r\n",
trigger->id, trigger->type, enabled,
trigger->x1, trigger->y1, trigger->z1,
trigger->radius, trigger->y2);
break;
case TRIGGER_TRIANGLE:
fprintf(fp, "%lu %lu %lu %lf %lf %lf %lf %lf %lf %lf %lf\r\n",
trigger->id, trigger->type, enabled,
trigger->x1, trigger->z1,
trigger->x2, trigger->z2,
trigger->x3, trigger->z3,
trigger->y1, trigger->y2);
break;
}
}
fclose(fp);
return true;
}