S013010C_Aaron_Smith_Steering::S013010C_Aaron_Smith_Steering(S013010C_Aaron_Smith_Tank* tank,bool demoTank) { mTank = tank; mIsArriving = false; mIsPursuing = false; mIsEvading = false; mIsFleeing = false; mIsWandering = false; mIsSeeking = false; mIsPursuing = false; mIsObstacleAvoiding = true; mIsWallAvoided = true; //add walls walls = vector<Walls>(); Walls leftWall = Walls(Vector2D(0, 0), Vector2D(0, kScreenHeight)); Walls rightWall = Walls(Vector2D(kScreenWidth, 0), Vector2D(kScreenWidth, kScreenHeight)); Walls bottomWall = Walls(Vector2D(0, kScreenHeight), Vector2D(kScreenWidth, kScreenHeight)); Walls topWall = Walls(Vector2D(0, 0), Vector2D(kScreenWidth, 0)); walls.push_back(leftWall); walls.push_back(rightWall); walls.push_back(bottomWall); walls.push_back(topWall); }
INT16 CMine::FindTriggerWall (INT16 trignum) { CDWall *wall = Walls (); int wallnum; for (wallnum = GameInfo ().walls.count; wallnum; wallnum--, wall++) if (wall->trigger == trignum) return wall - Walls (); return GameInfo ().walls.count; }
INT16 CMine::FindTriggerWall (INT16 *trignum, INT16 segnum, INT16 sidenum) { GetCurrent (segnum, sidenum); CDWall *wall = Walls (); int wallnum; for (wallnum = GameInfo ().walls.count; wallnum; wallnum--, wall++) { if ((wall->segnum == segnum) && (wall->sidenum == sidenum)) { *trignum = wall->trigger; return wall - Walls (); } } *trignum = NO_TRIGGER; return GameInfo ().walls.count; }
bool CMine::VisibleWall (UINT16 nWall) { if (nWall == NO_WALL) return false; CDWall *wallP = Walls (nWall); return (wallP->type != WALL_OPEN); }
TEST (MazeReader, LoadMazeFromFile) { char fileName[] = "mazefiles/empty.maz"; ReadRealWallsFromFile (fileName); UpdateEntireMazeFromRealWalls (); EXPECT_EQ (ALL_SEEN + WEST_WALL + SOUTH_WALL + EAST_WALL, Walls (Home())); }
TEST (MazeReader, LoadMazeFromInvalidFile) { char fileName[] = "mazefiles/aaaaaa.maz"; ReadRealWallsFromFile (fileName); UpdateEntireMazeFromRealWalls (); EXPECT_EQ (ALL_SEEN + NO_WALLS, Walls (Home())); }
void CMine::SetSegmentChildNum (CDSegment *pRoot, INT16 segnum,INT16 recursion_level) { INT16 sidenum, child, nImprove = 0; UINT16 nWall; CDSegment *seg = Segments () + segnum; CDSegment *prevSeg = NULL; bool bMarkChildren = false; // mark each child if child number is lower for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) { // Skip if this is a door nWall = seg->sides [sidenum].nWall; // .. if there is a wall and its a door if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR)) continue; // mark segment if it has a child child = seg->children [sidenum]; if ((child > -1) && (child < SegCount ()) && (recursion_level > seg->seg_number)) { if (seg->seg_number >= 0) ++nImprove; /* if (pRoot) { UnlinkSeg (seg, pRoot); LinkSeg (seg, pRoot); } */ seg->seg_number = recursion_level; bMarkChildren = true; break; } } //return if segment has no children or max recursion depth is reached if (!bMarkChildren || (recursion_level == 1)) return; // check each side of this segment for more children for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) { // skip if there is a wall and its a door nWall = seg->sides [sidenum].nWall; if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR)) continue; // check child child = seg->children [sidenum]; if ((child > -1) && (child < SegCount ())) SetSegmentChildNum (pRoot, child, recursion_level - 1); } }
void CMine::DeleteTrigger (INT16 nTrigger) { INT16 i, nSegment, nSide, nWall; if (nTrigger < 0) { nWall = CurrSeg ()->sides [Current ()->side].nWall; if (nWall >= GameInfo ().walls.count) return; nTrigger = Walls (nWall)->trigger; } if (nTrigger >= GameInfo ().triggers.count) return; // update all Walls () who point to Triggers () higher than this one // and unlink all Walls () who point to deleted trigger (should be only one wall) theApp.SetModified (TRUE); theApp.LockUndo (); CDWall *wallP = Walls (); for (i = GameInfo ().walls.count; i; i--, wallP++) if ((wallP->trigger != NO_TRIGGER) && (wallP->trigger > nTrigger)) wallP->trigger--; else if (wallP->trigger == nTrigger) { wallP->trigger = NO_TRIGGER; nSegment = wallP->segnum; nSide = wallP->sidenum; } // remove trigger from array //for (i=nTrigger;i<GameInfo ().triggers.count-1;i++) // update number of Triggers () CDTrigger *trigP = Triggers (); for (i = NumTriggers (); i; i--, trigP++) if (trigP->type >= TT_MASTER) DeleteTriggerTarget (trigP, nSegment, nSide, false); if (nTrigger < --GameInfo ().triggers.count) memcpy(Triggers (nTrigger), Triggers (nTrigger + 1), (GameInfo ().triggers.count - nTrigger) * sizeof(CDTrigger)); theApp.UnlockUndo (); theApp.MineView ()->Refresh (); AutoLinkExitToReactor(); }
int main() { std::cout << "Ready to play Pong?" << "\n"; system("pause"); sfw::initContext(width, height, "Pong"); // then we need to update our buffers, poll for input, etc. while (sfw::stepContext()) { Walls(); Player1(); Player2(); Ball(); if (player1score > 4) { std::cout << "Player 1 wins" << "\n" <<"Player 1 Score:" << player1score << "\n" << "Player 2 Score:" << player2score << "\n"; sfw::termContext(); system("pause"); } if (player2score > 4) { std::cout << "Player 2 wins" << "\n" << "Player 2 Score:" << player2score << "\n" << "Player 1 Score:" << player1score << "\n"; sfw::termContext(); system("pause"); } } //395 405 250 350 sfw::termContext(); return 0; }
// // Action - Updates control center Triggers () so that exit door opens // when the reactor blows up. Removes any invalid cube/sides // from control_center_triggers if they exist. //------------------------------------------------------------------------ void auto_link_exit_to_reactor() { INT16 linknum,control,num_links,segnum,sidenum; UINT16 wallnum; UINT8 trignum; bool found; control = 0; // only 0 used by the game Descent // remove items from list that do not point to a wall for (linknum=0;linknum<control_center_triggers[control].num_links;linknum++) { num_links = control_center_triggers[control].num_links; segnum = control_center_triggers[control].seg[linknum]; sidenum = control_center_triggers[control].side[linknum]; // search for Walls () that have a exit of type trigger found = FALSE; for (wallnum=0;wallnum<GameInfo ().walls_howmany;wallnum++) { if (Walls (wallnum)->segnum == segnum && Walls ()[wallnum].sidenum == sidenum) { found = TRUE; break; } } // trignum = Walls (wallnum)->trigger; // if (trignum >= 0 && trignum <GameInfo ().triggers_howmany) { // if (Triggers ()[trignum].flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT)) { // found = TRUE; // break; // } // } // } // } if (!found) { if (num_links > 0) { // just in case // move last link into this deleted link's spot control_center_triggers[control].seg [linknum] = control_center_triggers[control].seg[num_links-1]; control_center_triggers[control].side[linknum] = control_center_triggers[control].side[num_links-1]; control_center_triggers[control].seg [num_links-1] = 0; control_center_triggers[control].side[num_links-1] = 0; control_center_triggers[control].num_links--; } } } // add exit to list if not already in list // search for walls that have a exit of type trigger num_links = control_center_triggers[control].num_links; for (wallnum=0;wallnum<GameInfo ().walls_howmany;wallnum++) { trignum = Walls (wallnum)->trigger; if (trignum >= 0 && trignum <GameInfo ().triggers_howmany) { if ( file_type == RDL_FILE && Triggers ()[trignum].flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT) || file_type != RDL_FILE && (Triggers ()[trignum].type == TT_EXIT || Triggers ()[trignum].type == TT_SECRET_EXIT) ) { // see if cube,side is already on the list segnum = (INT16)Walls (wallnum)->segnum; sidenum =(INT16)Walls (wallnum)->sidenum; found = FALSE; for (linknum=0;linknum<num_links;linknum++) { if (segnum == control_center_triggers[control].seg[linknum] && sidenum == control_center_triggers[control].side[linknum]) { found = TRUE; break; } } // if not already on the list, add it if (!found) { linknum = control_center_triggers[control].num_links; control_center_triggers[control].seg[linknum] = segnum; control_center_triggers[control].side[linknum] = sidenum; control_center_triggers[control].num_links++; } } } } }
bool CMine::CalcDeltaLights (double fLightScale, int force, int recursion_depth) { // initialize totals CDSegment *srcseg, *childseg; int source_segnum, child_segnum; double effect[4]; GameInfo ().delta_lights.count = 0; GameInfo ().dl_indices.count = 0; bool bWall, bD2XLights = (level_version >= 15) && (GameInfo ().fileinfo_version >= 34); fLightScale = 1.0; ///= 100.0; for (source_segnum = 0, srcseg = Segments (); source_segnum < SegCount (); source_segnum++, srcseg++) { // skip if not marked unless we are automatically saving if (!(srcseg->wall_bitmask & MARKED_MASK) && !force) continue; // loop on all sides int source_sidenum; for (source_sidenum = 0; source_sidenum < 6; source_sidenum++) { INT16 tmapnum = srcseg->sides [source_sidenum].nBaseTex & 0x3fff; INT16 tmapnum2 = srcseg->sides [source_sidenum].nOvlTex & 0x3fff; INT16 trignum; bool bl1 = (bool) (IsLight (tmapnum) != -1); bool bl2 = (bool) (IsLight (tmapnum2) != -1); if (!(bl1 || bl2)) continue; // no lights on this side bool bCalcDeltas = false; // if the current side is a wall and has a light and is the target of a trigger // than can make the wall appear/disappear, calculate delta lights for it if ((bWall = (FindWall (source_segnum, source_sidenum) != NULL)) && ((trignum = FindTriggerTarget (0, source_segnum, source_sidenum)) >= 0)) { INT8 trigtype = Triggers (trignum)->type; bCalcDeltas = (trigtype == TT_ILLUSION_OFF) || (trigtype == TT_ILLUSION_ON) || (trigtype == TT_CLOSE_WALL) || (trigtype == TT_OPEN_WALL) || (trigtype == TT_LIGHT_OFF) || (trigtype == TT_LIGHT_ON); } if (!bCalcDeltas) bCalcDeltas = IsFlickeringLight (source_segnum, source_sidenum); if (!bCalcDeltas) { bool bb1 = IsBlastableLight (tmapnum); bool bb2 = IsBlastableLight (tmapnum2); if (bb1 == bb2) bCalcDeltas = bb1; // both lights blastable or not else if (!(bb1 ? bl2 : bl1)) // i.e. one light blastable and the other texture not a non-blastable light bCalcDeltas = true; } if (!bCalcDeltas) { //check if light is target of a "light on/off" trigger int trignum = FindTriggerTarget (0, source_segnum, source_sidenum); if ((trignum >= 0) && (Triggers (trignum)->type >= TT_LIGHT_OFF)) bCalcDeltas = true; } if (!bCalcDeltas) continue; // only set lights for textures which have a nOvlTex //if (tmapnum2 == 0) // continue; INT16 srcwall = srcseg->sides [source_sidenum].nWall; if ((srcseg->children [source_sidenum] != -1) && ((srcwall >= GameInfo ().walls.count) || (Walls (srcwall)->type == WALL_OPEN))) continue; // if ((IsLight (tmapnum) == -1) && (IsLight (tmapnum2) == -1)) // continue; if (GameInfo ().dl_indices.count >= MAX_DL_INDICES) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } vms_vector A,source_center; // get index number and increment total number of dl_indices int dl_index_num = (int)GameInfo ().dl_indices.count++; dl_index *pdli = DLIndex (dl_index_num); if (bD2XLights) { pdli->d2x.segnum = source_segnum; pdli->d2x.sidenum = source_sidenum; pdli->d2x.count = 0; // will be incremented below } else { pdli->d2.segnum = source_segnum; pdli->d2.sidenum = source_sidenum; pdli->d2.count = 0; // will be incremented below } pdli->d2.index = (INT16)GameInfo ().delta_lights.count; // find orthogonal angle of source segment CalcOrthoVector(A,source_segnum,source_sidenum); // remember to flip the sign since we want it to point inward A.x = -A.x; A.y = -A.y; A.z = -A.z; // calculate the center of the source segment CalcCenter(source_center,source_segnum,source_sidenum); // mark those Segments () within N children of current cube //(note: this is done once per light instead of once per segment // even though some Segments () have multiple lights. // This actually reduces the number of calls since most // Segments () do not have lights) int h; for (h = 0; h < SegCount (); h++) Segments (h)->seg_number = -1; SetSegmentChildNum (srcseg, source_segnum, recursion_depth); srcseg->seg_number = recursion_depth; // setup source corner vertex for length calculation later vms_vector source_corner[4]; int j; for (j = 0; j < 4; j++) { UINT8 vertnum = side_vert[source_sidenum][j]; int h = srcseg->verts[vertnum]; source_corner[j].x = Vertices (h)->x; source_corner[j].y = Vertices (h)->y; source_corner[j].z = Vertices (h)->z; } // loop on child Segments () for (child_segnum = 0, childseg = Segments (); child_segnum < SegCount (); child_segnum++, childseg++) { if (childseg->seg_number < 0) continue; // loop on child sides int child_sidenum; for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) { // if texture has a child.. #ifdef _DEBUG CBRK (source_segnum == 6 && source_sidenum == 2 && child_segnum == 10 && child_sidenum == 1); #endif if (childseg->children[child_sidenum] >= 0) { UINT16 nWall = childseg->sides[child_sidenum].nWall; // .. if there is no wall .. if (nWall >= GameInfo ().walls.count) continue; // .. or its not a door .. if (Walls (nWall)->type == WALL_OPEN) continue; // don't put light because there is no texture here } // don't affect non-flickering light emitting textures (e.g. lava) tmapnum = childseg->sides [child_sidenum].nBaseTex; tmapnum2 = childseg->sides [child_sidenum].nOvlTex & 0x3fff; if (m_nNoLightDeltas == 1) { if (((IsLight (tmapnum) >= 0) || (IsLight (tmapnum2) >= 0)) && !IsFlickeringLight (child_segnum, child_sidenum)) continue; } else if ((m_nNoLightDeltas == 2) && (IsLava (tmapnum) || IsLava (tmapnum2))) continue; // if the child side is the same as the source side, then set light and continue if (child_sidenum == source_sidenum && child_segnum == source_segnum) { if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++); dl->segnum = child_segnum; dl->sidenum = child_sidenum; dl->dummy = 0; dl->vert_light [0] = dl->vert_light [1] = dl->vert_light [2] = dl->vert_light [3] = (UINT8) min (32, 32 * fLightScale); if (bD2XLights) pdli->d2x.count++; else pdli->d2.count++; continue; } // calculate vector between center of source segment and center of child #ifdef _DEBUG CBRK (child_segnum == qqq1 && child_sidenum == qqq2); #endif if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) { theApp.SetModified (TRUE); if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++); dl->segnum = child_segnum; dl->sidenum = child_sidenum; dl->dummy = 0; int iCorner; for (iCorner = 0; iCorner < 4; iCorner++) dl->vert_light [iCorner] = (UINT8) min(32, effect [iCorner]); if (bD2XLights) pdli->d2x.count++; else pdli->d2.count++; } } } // } } } return true; }
void CMine::Illuminate ( INT16 source_segnum, INT16 source_sidenum, UINT32 brightness, double fLightScale, bool bAll, bool bCopyTexLights) { CDSegment *seg = Segments (); CDSegment *child_seg; double effect[4]; // find orthogonal angle of source segment vms_vector A; //fLightScale /= 100.0; CalcOrthoVector (A,source_segnum,source_sidenum); // remember to flip the sign since we want it to point inward A.x = -A.x; A.y = -A.y; A.z = -A.z; // calculate the center of the source segment vms_vector source_center; CalcCenter (source_center,source_segnum,source_sidenum); if ((source_segnum == 911) && (source_sidenum == 3)) A = A; // mark those Segments () within N children of current cube // set child numbers //Segments ()[source_segnum].seg_number = m_lightRenderDepth; int i; for (i = SegCount (); i; i--, seg++) seg->seg_number = -1; SetSegmentChildNum (NULL, source_segnum, m_lightRenderDepth); CDColor *plc = LightColor (source_segnum, source_sidenum); if (!plc->index) { plc->index = 255; plc->color.r = plc->color.g = plc->color.b = 1.0; } if (UseTexColors () && bCopyTexLights) { CDColor *psc = LightColor (source_segnum, source_sidenum, false); *psc = *plc; } seg = Segments (source_segnum); seg->seg_number = m_lightRenderDepth; bool bWall = false; //FindWall (source_segnum, source_sidenum) != NULL; // loop on child Segments () int child_segnum; for (child_segnum=0, child_seg = Segments ();child_segnum<SegCount ();child_segnum++, child_seg++) { // skip if this is not viewable if (child_seg->seg_number < 0) continue; // skip if not marked // if (!(bAll || (child_seg->wall_bitmask & MARKED_MASK))) // continue; // setup source corner vertex for length calculation later vms_vector source_corner[4]; int j; for (j = 0; j < 4; j++) { int vertnum = side_vert [source_sidenum][j]; int h = seg->verts [vertnum]; source_corner[j].x = Vertices (h)->x; source_corner[j].y = Vertices (h)->y; source_corner[j].z = Vertices (h)->z; } // loop on child sides int child_sidenum; for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) { // if side has a child.. if (!(bAll || SideIsMarked (child_segnum, child_sidenum))) continue; if (child_seg->children[child_sidenum] >= 0) { UINT16 nWall = child_seg->sides[child_sidenum].nWall; // .. but there is no wall .. if (nWall >= GameInfo ().walls.count) continue; // .. or its not a door .. if (Walls (nWall)->type == WALL_OPEN) continue; } // CBRK (psc->index > 0); // if the child side is the same as the source side, then set light and continue #ifdef _DEBUG CBRK (child_segnum == qqq1 && child_sidenum == qqq2); #endif if (child_sidenum == source_sidenum && child_segnum == source_segnum) { uvl *uvlP = child_seg->sides [child_sidenum].uvls; UINT32 vBr, lBr; theApp.SetModified (TRUE); int j; for (j = 0; j < 4; j++, uvlP++) { CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]); vBr = (UINT16) uvlP->l; lBr = (UINT32) (brightness * fLightScale); BlendColors (plc, pvc, lBr, vBr); vBr += lBr; vBr = min (0x8000, vBr); uvlP->l = (UINT16) vBr; } continue; } // calculate vector between center of source segment and center of child // CBRK (child_segnum == 1 && child_sidenum == 2); if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) { UINT32 vBr, lBr; //vertex brightness, light brightness uvl *uvlP = child_seg->sides [child_sidenum].uvls; theApp.SetModified (TRUE); int j; for (j = 0; j < 4; j++, uvlP++) { CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]); if (child_seg->verts [side_vert [child_sidenum][j]] == 2368) j = j; vBr = (UINT16) uvlP->l; lBr = (UINT16) (brightness * effect [j] / 32); BlendColors (plc, pvc, lBr, vBr); vBr += lBr; vBr = min (0x8000, vBr); uvlP->l = (UINT16) vBr; } } } } }
CDTrigger *CMine::AddTrigger (UINT16 wallnum, INT16 type, BOOL bAutoAddWall) { INT16 flags; INT16 segnum, sidenum, trignum; static INT16 defWallTypes [NUM_TRIGGER_TYPES] = { WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION, WALL_OPEN, WALL_OPEN }; static INT16 defWallTextures [NUM_TRIGGER_TYPES] = { 0, 0, 0, 0, 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, 0 }; // check if there's already a trigger on the current side wallnum = FindTriggerWall (&trignum); if (trignum != NO_TRIGGER) { ErrorMsg ("There is already a trigger on this side"); return NULL; } if (GameInfo ().triggers.count >= MAX_TRIGGERS) { ErrorMsg ("The maximum number of triggers has been reached."); return NULL; } // if no wall at current side, try to add a wall of proper type bool bUndo = theApp.SetModified (TRUE); theApp.LockUndo (); if (CurrSide ()->nWall >= GameInfo ().walls.count) { if (bAutoAddWall) { if (GameInfo ().walls.count >= MAX_WALLS) { ErrorMsg ("Cannot add a wall to this side,\nsince the maximum number of walls is already reached."); return NULL; } segnum = sidenum = -1; GetCurrent (segnum, sidenum); if (!AddWall (-1, -1, (Segments (segnum)->children [sidenum] < 0) ? WALL_OVERLAY : defWallTypes [type], 0, 0, -1, defWallTextures [type])) { ErrorMsg ("Cannot add a wall for this trigger."); theApp.ResetModified (bUndo); return NULL; } } else { ErrorMsg ("You must add a wall to this side before you can add a trigger."); return NULL; } } // if D1, then convert type to flag value if (file_type == RDL_FILE) { switch(type) { case TT_OPEN_DOOR: flags = TRIGGER_CONTROL_DOORS; break; case TT_MATCEN: flags = TRIGGER_MATCEN; break; case TT_EXIT: flags = TRIGGER_EXIT; break; case TT_SECRET_EXIT: flags = TRIGGER_SECRET_EXIT; break; case TT_ILLUSION_OFF: flags = TRIGGER_ILLUSION_OFF; break; case TT_ILLUSION_ON: flags = TRIGGER_ILLUSION_ON; break; case TT_ENERGY_DRAIN: flags = TRIGGER_ENERGY_DRAIN; break; case TT_SHIELD_DAMAGE: flags = TRIGGER_SHIELD_DAMAGE; break; default: flags = 0; } type = 0; } else flags = 0; trignum = (UINT16) GameInfo ().triggers.count; // set new trigger data InitTrigger (Triggers (trignum), type, flags); // link trigger to the wall Walls (wallnum)->trigger = (UINT8) trignum; // update number of Triggers () GameInfo ().triggers.count++; AutoLinkExitToReactor(); theApp.UnlockUndo (); theApp.MineView ()->Refresh (); return Triggers (trignum); }
void CMine::AutoLinkExitToReactor () { INT16 linknum,control,num_links,segnum,sidenum; UINT16 wallnum; INT8 trignum; bool found; control = 0; // only 0 used by the game Descent control_center_trigger *ccTrigger = CCTriggers (control); theApp.SetModified (TRUE); theApp.LockUndo (); // remove items from list that do not point to a wall for (linknum = 0; linknum < ccTrigger->num_links; linknum++) { num_links = ccTrigger->num_links; segnum = ccTrigger->seg [linknum]; sidenum = ccTrigger->side [linknum]; // search for Walls () that have a exit of type trigger found = FALSE; for (wallnum=0;wallnum<GameInfo ().walls.count;wallnum++) { if (Walls (wallnum)->segnum == segnum && Walls (wallnum)->sidenum == sidenum) { found = TRUE; break; } } if (!found) { if (num_links > 0) { // just in case // move last link into this deleted link's spot ccTrigger->seg [linknum] = ccTrigger->seg [num_links-1]; ccTrigger->side [linknum] = ccTrigger->side [num_links-1]; ccTrigger->seg [num_links-1] = 0; ccTrigger->side [num_links-1] = 0; ccTrigger->num_links--; } } } // add exit to list if not already in list // search for Walls () that have a exit of type trigger num_links = ccTrigger->num_links; for (wallnum = 0; wallnum < GameInfo ().walls.count; wallnum++) { trignum = Walls (wallnum)->trigger; if (trignum >= 0 && trignum <GameInfo ().triggers.count) { if ((file_type == RDL_FILE) ? Triggers (trignum)->flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT) : Triggers (trignum)->type == TT_EXIT || Triggers (trignum)->type == TT_SECRET_EXIT) { // see if cube,side is already on the list segnum = (INT16)Walls (wallnum)->segnum; sidenum =(INT16)Walls (wallnum)->sidenum; found = FALSE; for (linknum = 0; linknum < num_links; linknum++) { if (segnum == ccTrigger->seg [linknum] && sidenum == ccTrigger->side [linknum]) { found = TRUE; break; } } // if not already on the list, add it if (!found) { linknum = ccTrigger->num_links; ccTrigger->seg [linknum] = segnum; ccTrigger->side [linknum] = sidenum; ccTrigger->num_links++; } } } } theApp.UnlockUndo (); }
bool Visited (location_t location) { return (Walls (location) & VISITED) == VISITED; }
bool HasExit (location_t location, direction_t direction) { walls_t walls = Walls (location); return !WallExists (walls, direction); }