📄 aas_map.c
字号:
Error ("MAX_MAPFILE_BRUSHSIDES");
side = brush->original_sides + n;
newside = newbrush->original_sides + n;
newside->original = NULL;
newside->winding = NULL;
newside->contents = side->contents;
newside->flags = side->flags;
newside->surf = side->surf;
newside->planenum = side->planenum;
newside->texinfo = side->texinfo;
nummapbrushsides++;
} //end for
//
nummapbrushes++;
mapent->numbrushes++;
return newbrush;
} //end of the function AAS_CopyMapBrush
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int mark_entities[MAX_MAP_ENTITIES];
int AAS_AlwaysTriggered_r(char *targetname)
{
int i;
if (!strlen(targetname)) {
return false;
}
//
for (i = 0; i < num_entities; i++) {
// if the entity will activate the given targetname
if ( !strcmp(targetname, ValueForKey(&entities[i], "target")) ) {
// if this activator is present in deathmatch
if (!(atoi(ValueForKey(&entities[i], "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH)) {
// if it is a trigger_always entity
if (!strcmp("trigger_always", ValueForKey(&entities[i], "classname"))) {
return true;
}
// check for possible trigger_always entities activating this entity
if ( mark_entities[i] ) {
Warning( "entity %d, classname %s has recursive targetname %s\n", i,
ValueForKey(&entities[i], "classname"), targetname );
return false;
}
mark_entities[i] = true;
if ( AAS_AlwaysTriggered_r(ValueForKey(&entities[i], "targetname")) ) {
return true;
}
}
}
}
return false;
}
int AAS_AlwaysTriggered(char *targetname) {
memset( mark_entities, 0, sizeof(mark_entities) );
return AAS_AlwaysTriggered_r( targetname );
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_ValidEntity(entity_t *mapent)
{
int i;
char target[1024];
//all world brushes are used for AAS
if (mapent == &entities[0])
{
return true;
} //end if
//some of the func_wall brushes are also used for AAS
else if (!strcmp("func_wall", ValueForKey(mapent, "classname")))
{
//Log_Print("found func_wall entity %d\n", mapent - entities);
//if the func wall is used in deathmatch
if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
{
//Log_Print("func_wall USED in deathmatch mode %d\n", atoi(ValueForKey(mapent, "spawnflags")));
return true;
} //end if
} //end else if
else if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
{
//if the func_door_rotating is present in deathmatch
if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
{
//if the func_door_rotating is always activated in deathmatch
if (AAS_AlwaysTriggered(ValueForKey(mapent, "targetname")))
{
//Log_Print("found func_door_rotating in deathmatch\ntargetname %s\n", ValueForKey(mapent, "targetname"));
return true;
} //end if
} //end if
} //end else if
else if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
{
//"dmg" is the damage, for instance: "dmg" "666"
return true;
} //end else if
else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
{
return true;
} //end else if
else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
{
//find out if the trigger_multiple is pointing to a target_teleporter
strcpy(target, ValueForKey(mapent, "target"));
for (i = 0; i < num_entities; i++)
{
//if the entity will activate the given targetname
if (!strcmp(target, ValueForKey(&entities[i], "targetname")))
{
if (!strcmp("target_teleporter", ValueForKey(&entities[i], "classname")))
{
return true;
} //end if
} //end if
} //end for
} //end else if
else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
{
return true;
} //end else if
else if (!strcmp("func_static", ValueForKey(mapent, "classname")))
{
//FIXME: easy/medium/hard/deathmatch specific?
return true;
} //end else if
else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
{
return true;
} //end else if
return false;
} //end of the function AAS_ValidEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TransformPlane(int planenum, vec3_t origin, vec3_t angles)
{
float newdist, matrix[3][3];
vec3_t normal;
//rotate the node plane
VectorCopy(mapplanes[planenum].normal, normal);
CreateRotationMatrix(angles, matrix);
RotatePoint(normal, matrix);
newdist = mapplanes[planenum].dist + DotProduct(normal, origin);
return FindFloatPlane(normal, newdist);
} //end of the function AAS_TransformPlane
//===========================================================================
// this function sets the func_rotating_door in it's final position
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PositionFuncRotatingBrush(entity_t *mapent, mapbrush_t *brush)
{
int spawnflags, i;
float distance;
vec3_t movedir, angles, pos1, pos2;
side_t *s;
spawnflags = FloatForKey(mapent, "spawnflags");
VectorClear(movedir);
if (spawnflags & DOOR_X_AXIS)
movedir[2] = 1.0; //roll
else if (spawnflags & DOOR_Y_AXIS)
movedir[0] = 1.0; //pitch
else // Z_AXIS
movedir[1] = 1.0; //yaw
// check for reverse rotation
if (spawnflags & DOOR_REVERSE)
VectorInverse(movedir);
distance = FloatForKey(mapent, "distance");
if (!distance) distance = 90;
GetVectorForKey(mapent, "angles", angles);
VectorCopy(angles, pos1);
VectorMA(angles, -distance, movedir, pos2);
// if it starts open, switch the positions
if (spawnflags & DOOR_START_OPEN)
{
VectorCopy(pos2, angles);
VectorCopy(pos1, pos2);
VectorCopy(angles, pos1);
VectorInverse(movedir);
} //end if
//
for (i = 0; i < brush->numsides; i++)
{
s = &brush->original_sides[i];
s->planenum = AAS_TransformPlane(s->planenum, mapent->origin, pos2);
} //end for
//
FreeBrushWindings(brush);
AAS_MakeBrushWindings(brush);
AddBrushBevels(brush);
FreeBrushWindings(brush);
} //end of the function AAS_PositionFuncRotatingBrush
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PositionBrush(entity_t *mapent, mapbrush_t *brush)
{
side_t *s;
float newdist;
int i, notteam;
char *model;
if (!strcmp(ValueForKey(mapent, "classname"), "func_door_rotating"))
{
AAS_PositionFuncRotatingBrush(mapent, brush);
} //end if
else
{
if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
{
for (i = 0; i < brush->numsides; i++)
{
s = &brush->original_sides[i];
newdist = mapplanes[s->planenum].dist +
DotProduct(mapplanes[s->planenum].normal, mapent->origin);
s->planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
} //end for
} //end if
//if it's a trigger hurt
if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
{
notteam = FloatForKey(mapent, "bot_notteam");
if ( notteam == 1 ) {
brush->contents |= CONTENTS_NOTTEAM1;
}
else if ( notteam == 2 ) {
brush->contents |= CONTENTS_NOTTEAM2;
}
else {
// always avoid so set lava contents
brush->contents |= CONTENTS_LAVA;
}
} //end if
//
else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
{
//set the jumppad contents
brush->contents = CONTENTS_JUMPPAD;
//Log_Print("found trigger_push brush\n");
} //end if
//
else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
{
//set teleporter contents
brush->contents = CONTENTS_TELEPORTER;
//Log_Print("found trigger_multiple teleporter brush\n");
} //end if
//
else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
{
//set teleporter contents
brush->contents = CONTENTS_TELEPORTER;
//Log_Print("found trigger_teleport teleporter brush\n");
} //end if
else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
{
//set mover contents
brush->contents = CONTENTS_MOVER;
//get the model number
model = ValueForKey(mapent, "model");
brush->modelnum = atoi(model+1);
} //end if
} //end else
} //end of the function AAS_PositionBrush
//===========================================================================
// uses the global cfg_t cfg
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels)
{
int i;
//side_t *s;
mapbrush_t *bboxbrushes[16];
//if the brushes are not from an entity used for AAS
if (!AAS_ValidEntity(mapent))
{
nummapbrushsides -= brush->numsides;
brush->numsides = 0;
return;
} //end if
//
AAS_PositionBrush(mapent, brush);
//from all normal solid brushes only the textured brush sides will
//be used as bsp splitters, so set the right texinfo reference here
AAS_SetTexinfo(brush);
//remove contents detail flag, otherwise player clip contents won't be
//bsped correctly for AAS!
brush->contents &= ~CONTENTS_DETAIL;
//if the brush has contents area portal it should be the only contents
if (brush->contents & (CONTENTS_AREAPORTAL|CONTENTS_CLUSTERPORTAL))
{
brush->contents = CONTENTS_CLUSTERPORTAL;
brush->leafnum = -1;
} //end if
//window and playerclip are used for player clipping, make them solid
if (brush->contents & (CONTENTS_WINDOW | CONTENTS_PLAYERCLIP))
{
//
brush->contents &= ~(CONTENTS_WINDOW | CONTENTS_PLAYERCLIP);
brush->contents |= CONTENTS_SOLID;
brush->leafnum = -1;
} //end if
//
if (brush->contents & CONTENTS_BOTCLIP)
{
brush->contents = CONTENTS_SOLID;
brush->leafnum = -1;
} //end if
//
//Log_Write("brush %d contents = ", brush->brushnum);
//PrintContents(brush->contents);
//Log_Write("\r\n");
//if not one of the following brushes then the brush is NOT used for AAS
if (!(brush->contents & (CONTENTS_SOLID
| CONTENTS_LADDER
| CONTENTS_CLUSTERPORTAL
| CONTENTS_DONOTENTER
| CONTENTS_TELEPORTER
| CONTENTS_JUMPPAD
| CONTENTS_WATER
| CONTENTS_LAVA
| CONTENTS_SLIME
| CONTENTS_MOVER
)))
{
nummapbrushsides -= brush->numsides;
brush->numsides = 0;
return;
} //end if
//fix the map brush
//AAS_FixMapBrush(brush);
//if brush bevels should be added (for real map brushes, not bsp map brushes)
if (addbevels)
{
//NOTE: we first have to get the mins and maxs of the brush before
// creating the brush bevels... the mins and maxs are used to
// create them. so we call MakeBrushWindings to get the mins
// and maxs and then after creating the bevels we free the
// windings because they are created for all sides (including
// bevels) a little later
AAS_MakeBrushWindings(brush);
AddBrushBevels(brush);
FreeBrushWindings(brush);
} //end if
//NOTE: add the brush to the WORLD entity!!!
mapent = &entities[0];
//there's at least one new brush for now
nummapbrushes++;
mapent->numbrushes++;
//liquid brushes are expanded for the maximum possible bounding box
if (brush->contents & (CONTENTS_WATER
| CONTENTS_LAVA
| CONTENTS_SLIME
| CONTENTS_TELEPORTER
| CONTENTS_JUMPPAD
| CONTENTS_DONOTENTER
| CONTENTS_MOVER
))
{
brush->expansionbbox = 0;
//NOTE: the first bounding box is the max
//FIXME: use max bounding box created from all bboxes
AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
AAS_MakeBrushWindings(brush);
} //end if
//area portal brushes are NOT expanded
else if (brush->contents & CONTENTS_CLUSTERPORTAL)
{
brush->expansionbbox = 0;
//NOTE: the first bounding box is the max
//FIXME: use max bounding box created from all bboxes
AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
AAS_MakeBrushWindings(brush);
} //end if
//all solid brushes are expanded for all bounding boxes
else if (brush->contents & (CONTENTS_SOLID
| CONTENTS_LADDER
))
{
//brush for the first bounding box
bboxbrushes[0] = brush;
//make a copy for the other bounding boxes
for (i = 1; i < cfg.numbboxes; i++)
{
bboxbrushes[i] = AAS_CopyMapBrush(brush, mapent);
} //end for
//expand every brush for it's bounding box and create windings
for (i = 0; i < cfg.numbboxes; i++)
{
AAS_ExpandMapBrush(bboxbrushes[i], cfg.bboxes[i].mins, cfg.bboxes[i].maxs);
bboxbrushes[i]->expansionbbox = cfg.bboxes[i].presencetype;
AAS_MakeBrushWindings(bboxbrushes[i]);
} //end for
} //end else
} //end of the function AAS_CreateMapBrushes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -