12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931 |
- /************************************************************************************************
- *
- * RM_Mission.cpp
- *
- * implements the CRMMission class. The CRMMission class loads and manages an arioche mission
- *
- ************************************************************************************************/
- #include "../server/exe_headers.h"
- #include "rm_headers.h"
- #define ARIOCHE_CLIPBRUSH_SIZE 300
- #define CVAR_OBJECTIVE 0
- /************************************************************************************************
- * CRMMission::CRMMission
- * constructor
- *
- * inputs:
- * none
- *
- * return:
- * none
- *
- ************************************************************************************************/
- CRMMission::CRMMission ( CRandomTerrain* landscape )
- {
- mCurrentObjective = NULL;
- mValidPaths = false;
- mValidRivers = false;
- mValidNodes = false;
- mValidWeapons = false;
- mValidAmmo = false;
- mValidObjectives = false;
- mValidInstances = false;
- mTimeLimit = 0;
- mMaxInstancePosition = 1;
- mAccuracyMultiplier = 1.0f;
- mHealthMultiplier = 1.0f;
- mPickupHealth = 1.0f;
- mPickupArmor = 1.0f;
- mPickupAmmo = 1.0f;
- mPickupWeapon = 1.0f;
- mPickupEquipment = 1.0f;
-
- mDefaultPadding = 0;
- mSymmetric = SYMMETRY_NONE;
- // mCheckedEnts.clear();
- mLandScape = landscape;
- // cut down the possible area that is 'legal' for area manager to use by 20%
- vec3_t land_min, land_max;
- land_min[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * 0.1f;
- land_min[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * 0.1f;
- land_min[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * 0.1f;
- land_max[0] = mLandScape->GetBounds ( )[1][0] - (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * 0.1f;
- land_max[1] = mLandScape->GetBounds ( )[1][1] - (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * 0.1f;
- land_max[2] = mLandScape->GetBounds ( )[1][2] - (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * 0.1f;
- // Create a new area manager for the landscape
- mAreaManager = new CRMAreaManager ( land_min,
- land_max );
- // Create a new path manager
- mPathManager = new CRMPathManager ( mLandScape );
- }
- /************************************************************************************************
- * CRMMission::~CRMMission
- * destructor
- *
- * inputs:
- * none
- *
- * return:
- * none
- *
- ************************************************************************************************/
- CRMMission::~CRMMission ( )
- {
- rmObjectiveIter_t oit;
- rmInstanceIter_t iit;
- // mCheckedEnts.clear();
- // Cleanup the objectives
- for (oit = mObjectives.begin(); oit != mObjectives.end(); oit++)
- {
- delete (*oit);
- }
- // Cleanup the instances
- for (iit = mInstances.begin(); iit != mInstances.end(); iit++)
- {
- delete (*iit);
- }
- if (mPathManager)
- {
- delete mPathManager;
- mPathManager = 0;
- }
- if (mAreaManager)
- {
- delete mAreaManager;
- mAreaManager = 0;
- }
- }
- /************************************************************************************************
- * CRMMission::FindObjective
- * searches through the missions objectives for the one with the given name
- *
- * inputs:
- * name: name of objective to find
- *
- * return:
- * objective: objective matching the given name or NULL if it couldnt be found
- *
- ************************************************************************************************/
- CRMObjective* CRMMission::FindObjective ( const char* name )
- {
- rmObjectiveIter_t it;
- for (it = mObjectives.begin(); it != mObjectives.end(); it++)
- {
- // Does it match?
- if (!stricmp ((*it)->GetName(), name ))
- {
- return (*it);
- }
- }
- // Not found
- return NULL;
- }
- void CRMMission::MirrorPos(vec3_t pos)
- {
- pos[0] = 1.0f - pos[0];
- pos[1] = 1.0f - pos[1];
- }
- /************************************************************************************************
- * CRMMission::ParseOrigin
- * parses an origin block which includes linking to a node and absolute origins
- *
- * inputs:
- * group: parser group containing the node or origin
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseOrigin ( CGPGroup* originGroup, vec3_t origin, vec3_t lookat, int* flattenHeight )
- {
- const char* szNodeName;
- vec3_t mins;
- vec3_t maxs;
- if ( flattenHeight )
- {
- *flattenHeight = 66;
- }
-
- // If no group was given then use 0,0,0
- if ( NULL == originGroup )
- {
- VectorCopy ( vec3_origin, origin );
- return false;
- }
- // See if attaching to a named node
- szNodeName = originGroup->FindPairValue ( "node", "" );
- if ( *szNodeName )
- {
- CRMNode* node;
- // Find the node being attached to
- node = mPathManager->FindNodeByName ( szNodeName );
- if ( node )
- {
- if ( flattenHeight )
- {
- if ( node->GetFlattenHeight ( ) == -1 )
- {
- node->SetFlattenHeight ( 40 + mLandScape->irand(0,40) );
- }
- *flattenHeight = node->GetFlattenHeight ( );
- }
- VectorCopy(node->GetPos(), origin);
- VectorCopy ( origin, lookat );
- int dir;
- int rnd_offset = mLandScape->irand(0, DIR_MAX-1);
- for (dir=0; dir<DIR_MAX; dir++)
- {
- int d = (dir + rnd_offset) % DIR_MAX;
- if (node->PathExist(d))
- {
- vec4_t tmp_pt, tmp_dir;
- int pathID = node->GetPath(d);
- mLandScape->GetPathInfo(pathID, 0.1f, tmp_pt, tmp_dir );
- lookat[0] = tmp_pt[0];
- lookat[1] = tmp_pt[1];
- lookat[2] = 0;
- return true;
- }
- }
- return true;
- }
- }
- mins[0] = atof( originGroup->FindPairValue ( "left", ".1" ) );
- mins[1] = atof( originGroup->FindPairValue ( "top", ".1" ) );
- maxs[0] = atof( originGroup->FindPairValue ( "right", ".9" ) );
- maxs[1] = atof( originGroup->FindPairValue ( "bottom", ".9" ) );
- lookat[0] = origin[0] = mLandScape->flrand(mins[0],maxs[0]);
- lookat[1] = origin[1] = mLandScape->flrand(mins[1],maxs[1]);
- lookat[2] = origin[2] = 0;
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseNodes
- * parses all the named nodes in the file
- *
- * inputs:
- * group: parser group containing the named nodes
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseNodes ( CGPGroup* group )
- {
- // If NULL that means this particular difficulty level has no named nodes
- if ( NULL == group || mValidNodes)
- {
- return true;
- }
- // how many nodes spaced over map?
- int x_cells;
- int y_cells;
- x_cells = atoi ( group->FindPairValue ( "x_cells", "3" ) );
- y_cells = atoi ( group->FindPairValue ( "y_cells", "3" ) );
- mPathManager->CreateArray(x_cells, y_cells);
- // Loop through all the nodes and generate each as specified
- for ( group = group->GetSubGroups();
- group;
- group=group->GetNext() )
- {
- int min_depth = atof( group->FindPairValue ( "min_depth", "0" ) );
- int max_depth = atof( group->FindPairValue ( "max_depth", "5" ) );
- int min_paths = atoi( group->FindPairValue ( "min_paths", "1" ) );
- int max_paths = atoi( group->FindPairValue ( "max_paths", "1" ) );
- mPathManager->CreateLocation( group->GetName(), min_depth, max_depth, min_paths, max_paths );
- }
- mValidNodes = true;
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParsePaths
- * parses all path styles in the file and then generates paths
- *
- * inputs:
- * group: parser group containing the list of path styles
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParsePaths ( CGPGroup* group )
- {
- // If NULL that means this particular difficulty level has no paths
- if ( NULL == group || mValidPaths)
- {
- return true;
- }
- // path style info
- float depth;
- float deviation;
- float breadth;
- float minwidth;
- float maxwidth;
- int points;
- points = atoi ( group->FindPairValue ( "points", "10" ) );
- depth = atof ( group->FindPairValue ( "depth", ".31" ) );
- deviation = atof ( group->FindPairValue ( "deviation", ".025" ) );
- breadth = atof ( group->FindPairValue ( "breadth", "5" ) );
- minwidth = atof ( group->FindPairValue ( "minwidth", ".03" ) );
- maxwidth = atof ( group->FindPairValue ( "maxwidth", ".05" ) );
- mPathManager->SetPathStyle( points, minwidth, maxwidth, depth, deviation, breadth);
- if (!mValidPaths)
- { // we must create paths
- mPathManager->GeneratePaths( mSymmetric );
- mValidPaths = true;
- }
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseRivers
- * parses all river styles in the file and then generates rivers
- *
- * inputs:
- * group: parser group containing the list of path styles
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseRivers ( CGPGroup* group )
- {
- // If NULL that means this particular difficulty level has no rivers
- if ( NULL == group || mValidRivers)
- {
- return true;
- }
- // river style info
- int maxdepth;
- float beddepth;
- float deviation;
- float breadth;
- float minwidth;
- float maxwidth;
- int points;
- string bridge_name;
- maxdepth = atoi ( group->FindPairValue ( "maxpathdepth", "5" ) );
- points = atoi ( group->FindPairValue ( "points", "10" ) );
- beddepth = atof ( group->FindPairValue ( "depth", "1" ) );
- deviation = atof ( group->FindPairValue ( "deviation", ".03" ) );
- breadth = atof ( group->FindPairValue ( "breadth", "7" ) );
- minwidth = atof ( group->FindPairValue ( "minwidth", ".01" ) );
- maxwidth = atof ( group->FindPairValue ( "maxwidth", ".03" ) );
- bridge_name= group->FindPairValue ( "bridge", "" ) ;
- mPathManager->SetRiverStyle( maxdepth, points, minwidth, maxwidth, beddepth, deviation, breadth, bridge_name);
- if (!mValidRivers &&
- beddepth < 1) // use a depth of 1 if we don't want any rivers
- { // we must create rivers
- mPathManager->GenerateRivers();
- mValidRivers = true;
- }
- return true;
- }
- void CRMMission::PlaceBridges()
- {
- if (!mValidRivers || strlen(mPathManager->GetBridgeName()) < 1)
- return;
- int max_bridges = 0;
- int path;
- float t;
- float river_depth = mLandScape->GetLandScape()->GetWaterHeight();
- vec3_t pos, lastpos;
- vec3pair_t bounds;
- VectorSet(bounds[0], 0,0,0);
- VectorSet(bounds[1], 0,0,0);
- // walk along paths looking for dips
- for (path = 0; path < mPathManager->GetPathCount(); path++)
- {
- vec4_t tmp_pt, tmp_dir;
- bool new_water = true;
- mLandScape->GetPathInfo(path, 0, tmp_pt, tmp_dir );
- lastpos[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * tmp_pt[0];
- lastpos[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * tmp_pt[1];
- lastpos[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * tmp_pt[2];
- mLandScape->GetLandScape()->GetWorldHeight ( lastpos, bounds, true );
- const float delta = 0.05f;
- for (t= delta; t < 1.0f; t += delta)
- {
- mLandScape->GetPathInfo(path, t, tmp_pt, tmp_dir );
- pos[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * tmp_pt[0];
- pos[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * tmp_pt[1];
- pos[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * tmp_pt[2];
- mLandScape->GetLandScape()->GetWorldHeight ( pos, bounds, true );
- if (new_water &&
- lastpos[2] < river_depth &&
- pos[2] < river_depth &&
- pos[2] > lastpos[2])
- { // add a bridge
- if (max_bridges < 3)
- {
- CRMArea* area;
- CRMInstance* instance;
- max_bridges++;
- // create a single bridge
- lastpos[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * mPathManager->GetPathDepth();
- instance = mInstanceFile.CreateInstance ( mPathManager->GetBridgeName() );
- if ( NULL != instance )
- { // Set the area
- vec3_t zerodvec;
- VectorClear(zerodvec);
- area = mAreaManager->CreateArea ( lastpos, instance->GetSpacingRadius(), instance->GetSpacingLine(), GetDefaultPadding(), 0, zerodvec, pos, instance->GetFlattenRadius()?true:false, false, instance->GetLockOrigin() );
- area->EnableLookAt(false);
- instance->SetArea ( mAreaManager, area );
- mInstances.push_back ( instance );
- new_water = false;
- }
- }
- }
- else if (pos[2] > river_depth)
- { // hit land again
- new_water = true;
- }
- VectorCopy ( pos, lastpos );
- }
- }
- }
- void CRMMission::PlaceWallInstance(CRMInstance* instance, float xpos, float ypos, float zpos, int x, int y, float angle)
- {
- if (NULL == instance)
- return;
- float spacing = instance->GetSpacingRadius();
- CRMArea* area;
- vec3_t origin;
- vec3_t zerodvec;
- VectorClear(zerodvec);
- origin[0] = xpos + spacing * x;
- origin[1] = ypos + spacing * y;
- origin[2] = zpos;
- // Set the area of position
- area = mAreaManager->CreateArea ( origin, (spacing / 2.1f), 0, GetDefaultPadding(), 0, zerodvec, origin, instance->GetFlattenRadius()?true:false, false, instance->GetLockOrigin() );
- area->EnableLookAt(false);
- area->SetAngle(angle);
- instance->SetArea ( mAreaManager, area );
- mInstances.push_back ( instance );
- }
- /************************************************************************************************
- * CRMMission::ParseWallRect
- * creates instances for walled rectangle at this node (fence)
- *
- * inputs:
- * group: parser group containing the wall rect info
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseWallRect(CGPGroup* group , int side)
- {
- #ifndef PRE_RELEASE_DEMO
- CGPGroup* wallGroup = group->FindSubGroup ( "wallrect" ) ;
- // If NULL that means this particular instance has no wall rect
- if ( NULL == group || NULL == wallGroup)
- {
- return true;
- }
- const char* wallName = wallGroup->FindPairValue ( "wall_instance", "" );
- const char* cornerName = wallGroup->FindPairValue ( "corner_instance", "" );
- const char* towerName = wallGroup->FindPairValue ( "tower_instance", "" );
- const char* gateName = wallGroup->FindPairValue ( "gate_instance", "" );
- const char* ripName = wallGroup->FindPairValue ( "rip_instance", "" );
- if ( NULL != wallName )
- {
- int xcount = atoi( wallGroup->FindPairValue ( "xcount", "0" ) );
- int ycount = atoi( wallGroup->FindPairValue ( "ycount", "0" ) );
- int gateCount = atoi( wallGroup->FindPairValue ( "gate_count", "1" ) );
- int gateMin = atoi( wallGroup->FindPairValue ( "gate_min", "0" ) );
- int gateMax = atoi( wallGroup->FindPairValue ( "gate_max", "0" ) );
- int ripCount = atoi( wallGroup->FindPairValue ( "rip_count", "0" ) );
- int ripMin = atoi( wallGroup->FindPairValue ( "rip_min", "0" ) );
- int ripMax = atoi( wallGroup->FindPairValue ( "rip_max", "0" ) );
- int towerCount = atoi( wallGroup->FindPairValue ( "tower_count", "0" ) );
- int towerMin = atoi( wallGroup->FindPairValue ( "tower_min", "0" ) );
- int towerMax = atoi( wallGroup->FindPairValue ( "tower_max", "0" ) );
- if (gateMin != gateMax)
- gateCount = mLandScape->irand(gateMin,gateMax);
- if (ripMin != ripMax)
- ripCount = mLandScape->irand(ripMin,ripMax);
- if (towerMin != towerMax)
- towerCount = mLandScape->irand(towerMin,towerMax);
- if (NULL == gateName)
- gateCount = 0;
- if (NULL == towerName)
- towerCount = 0;
- if (NULL == ripName)
- ripCount = 0;
- const char* nodename;
- CGPGroup* originGroup = group->FindSubGroup ( "origin" );
- if (originGroup)
- {
- nodename = originGroup->FindPairValue ( "node", "" );
- if (*nodename)
- {
- CRMNode* node;
- // Find the node being attached to
- node = mPathManager->FindNodeByName ( nodename );
- if ( node )
- {
- CRMInstance* instance;
- int x,y;
- int halfx = xcount/2;
- int halfy = ycount/2;
- float xpos = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * node->GetPos()[0];
- float ypos = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * node->GetPos()[1];
- float zpos = mLandScape->GetBounds ( )[1][2] + 100;
- float angle = 0;
- int lastGate = 0;
- int lastRip = 0;
- // corners
- x = -halfx;
- y = -halfy;
- if (towerCount > 3 ||
- (towerCount > 0 && mLandScape->irand(1,2) == 1) )
- {
- towerCount--;
- instance = mInstanceFile.CreateInstance ( towerName );
- }
- else
- instance = mInstanceFile.CreateInstance ( cornerName );
- angle = (float)DEG2RAD(90);
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, y, angle);
- x = halfx;
- y = -halfy;
- if (towerCount > 3 ||
- (towerCount > 0 && mLandScape->irand(1,2) == 1) )
- {
- towerCount--;
- instance = mInstanceFile.CreateInstance ( towerName );
- }
- else
- instance = mInstanceFile.CreateInstance ( cornerName );
- angle = (float)DEG2RAD(180);
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, y, angle);
- x = halfx;
- y = halfy;
- if (towerCount > 3 ||
- (towerCount > 0 && mLandScape->irand(1,2) == 1) )
- {
- towerCount--;
- instance = mInstanceFile.CreateInstance ( towerName );
- }
- else
- instance = mInstanceFile.CreateInstance ( cornerName );
- angle = (float)DEG2RAD(270);
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, y, angle);
- x = -halfx;
- y = halfy;
- if (towerCount > 3 ||
- (towerCount > 0 && mLandScape->irand(1,2) == 1) )
- {
- towerCount--;
- instance = mInstanceFile.CreateInstance ( towerName );
- }
- else
- instance = mInstanceFile.CreateInstance ( cornerName );
- angle = DEG2RAD(0);
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, y, angle);
- // walls
- angle = DEG2RAD(0);
- for (x = -halfx+1; x <= halfx-1; x++)
- {
- if (lastGate<1 && gateCount > 0 && mLandScape->irand(1,(halfx+halfy)/gateCount) == 1)
- { // gate
- gateCount--;
- lastGate = 3;
- instance = mInstanceFile.CreateInstance ( gateName );
- }
- else if (lastRip<1 && ripCount > 0 && mLandScape->irand(1,(halfx+halfy)/ripCount) == 1)
- { // damaged fence
- ripCount--;
- lastRip = 3;
- instance = mInstanceFile.CreateInstance ( ripName );
- }
- else
- { // just a wall
- instance = mInstanceFile.CreateInstance ( wallName );
- lastRip--;
- lastGate--;
- }
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, -halfy, angle);
- }
- for (x = -halfx+1; x <= halfx-1; x++)
- {
- if (lastGate<1 && gateCount > 0 && mLandScape->irand(1,(halfx+halfy)/gateCount) == 1)
- { // gate
- gateCount--;
- lastGate = 3;
- instance = mInstanceFile.CreateInstance ( gateName );
- }
- else if (lastRip<1 && ripCount > 0 && mLandScape->irand(1,(halfx+halfy)/ripCount) == 1)
- { // damaged fence
- ripCount--;
- lastRip = 3;
- instance = mInstanceFile.CreateInstance ( ripName );
- }
- else
- { // just a wall
- instance = mInstanceFile.CreateInstance ( wallName );
- lastRip--;
- lastGate--;
- }
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, x, halfy, angle);
- }
- angle = (float)DEG2RAD(90);
- for (y = -halfy+1; y <= halfy-1; y++)
- {
- if (lastGate<1 && gateCount > 0 && mLandScape->irand(1,(halfx+halfy)/gateCount) == 1)
- { // gate
- gateCount--;
- lastGate = 3;
- instance = mInstanceFile.CreateInstance ( gateName );
- }
- else if (lastRip<1 && ripCount > 0 && mLandScape->irand(1,(halfx+halfy)/ripCount) == 1)
- { // damaged fence
- ripCount--;
- lastRip = 3;
- instance = mInstanceFile.CreateInstance ( ripName );
- }
- else
- { // just a wall
- instance = mInstanceFile.CreateInstance ( wallName );
- lastRip--;
- lastGate--;
- }
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, -halfx, y, angle);
- }
- for (y = -halfy+1; y <= halfy-1; y++)
- {
- if (lastGate<1 && gateCount > 0 && mLandScape->irand(1,(halfx+halfy)/gateCount) == 1)
- { // gate
- gateCount--;
- lastGate = 3;
- instance = mInstanceFile.CreateInstance ( gateName );
- }
- else if (lastRip<1 && ripCount > 0 && mLandScape->irand(1,(halfx+halfy)/ripCount) == 1)
- { // damaged fence
- ripCount--;
- lastRip = 3;
- instance = mInstanceFile.CreateInstance ( ripName );
- }
- else
- { // just a wall
- instance = mInstanceFile.CreateInstance ( wallName );
- lastRip--;
- lastGate--;
- }
- instance->SetSide(side);
- PlaceWallInstance(instance, xpos, ypos, zpos, halfx, y, angle);
- }
- }
- }
- }
- }
- else
- return false;
- #endif // #ifndef PRE_RELEASE_DEMO
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseInstancesOnPath
- * creates instances on path between nodes
- *
- * inputs:
- * group: parser group containing the defenses, other instances on the path between nodes
- *
- * return:
- * true: parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseInstancesOnPath ( CGPGroup* group )
- {
- #ifndef PRE_RELEASE_DEMO
- CGPGroup* defenseGroup;
- for ( defenseGroup = group->GetSubGroups();
- defenseGroup;
- defenseGroup=defenseGroup->GetNext() )
- if (stricmp ( defenseGroup->GetName ( ), "defenses" )==0 ||
- stricmp ( defenseGroup->GetName(), "instanceonpath")==0)
- {
- const char* defName = defenseGroup->FindPairValue ( "instance", "" );
- if ( *defName )
- {
- float minpos;
- float maxpos;
- int mincount;
- int maxcount;
- // how far along path does this get placed?
- minpos = atof( defenseGroup->FindPairValue ( "minposition", "0.5" ) );
- maxpos = atof( defenseGroup->FindPairValue ( "maxposition", "0.5" ) );
- mincount = atoi( defenseGroup->FindPairValue ( "mincount", "1" ) );
- maxcount = atoi( defenseGroup->FindPairValue ( "maxcount", "1" ) );
- const char* nodename;
- CGPGroup* originGroup = group->FindSubGroup ( "origin" );
- if (originGroup)
- {
- nodename = originGroup->FindPairValue ( "node", "" );
- if (*nodename)
- {
- CRMNode* node;
- // Find the node being attached to
- node = mPathManager->FindNodeByName ( nodename );
- if ( node )
- {
- int dir;
- // look at each connection from this node to others, if there is a path, create a defense
- for (dir=0; dir<DIR_MAX; dir++)
- {
- if (node->PathExist(dir))
- { // path leads out of this node
- CRMArea* area;
- CRMInstance* instance;
- float spacing;
- vec3_t origin;
- vec3_t lookat;
- vec4_t tmp_pt, tmp_dir;
- int n,num_insts = mLandScape->irand(mincount,maxcount);
- int pathID = node->GetPath(dir);
- if (0 == num_insts)
- continue;
- float posdelta = (maxpos - minpos) / num_insts;
- for (n=0; n<num_insts; n++)
- {
- instance = mInstanceFile.CreateInstance ( defName );
- // Failed to create, not good
- if ( NULL == instance )
- {
- continue;
- }
- // If a spacing radius was specified then override the one thats
- // in the instance
- spacing = atof( defenseGroup->FindPairValue ( "spacing", "0" ) );
- if ( spacing )
- {
- instance->SetSpacingRadius ( spacing );
- }
- instance->SetFilter(group->FindPairValue("filter", ""));
- instance->SetTeamFilter(group->FindPairValue("teamfilter", ""));
- if (strstr(instance->GetTeamFilter(),"red"))
- instance->SetSide(SIDE_RED);
- else if (strstr(instance->GetTeamFilter(),"blue"))
- instance->SetSide(SIDE_BLUE);
- float pos_along_path = mLandScape->flrand(minpos + posdelta*n, minpos + posdelta*(n+1));
- float look_along_path = atof( defenseGroup->FindPairValue ( "pathalign", "1" ) ) ;
- mLandScape->GetPathInfo (pathID, pos_along_path, tmp_pt, tmp_dir );
- origin[0] = tmp_pt[0];
- origin[1] = tmp_pt[1];
- mLandScape->GetPathInfo (pathID, look_along_path, tmp_dir, tmp_pt );
- lookat[0] = tmp_pt[0];
- lookat[1] = tmp_pt[1];
- origin[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * origin[0];
- origin[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * origin[1];
- origin[2] = mLandScape->GetBounds ( )[0][2] ;
- // look at a point along the path at this location
- lookat[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * lookat[0];
- lookat[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * lookat[1];
- lookat[2] = 0;
- // Fixed height? (used for bridges)
- if ( !atoi(group->FindPairValue ( "nodrop", "0" )) )
- {
- origin[2] = mLandScape->GetBounds ( )[1][2] + 100;
- }
-
- // Set the area of position
- area = mAreaManager->CreateArea ( origin, instance->GetSpacingRadius(), instance->GetSpacingLine(), GetDefaultPadding(), 0, origin, lookat, instance->GetFlattenRadius()?true:false, true, instance->GetLockOrigin(), mSymmetric );
- area->EnableLookAt(false);
- if ( node->GetFlattenHeight ( ) == -1 )
- {
- node->SetFlattenHeight ( 66 + mLandScape->irand(0,40) );
- }
- instance->SetFlattenHeight ( node->GetFlattenHeight ( ) );
- instance->SetArea ( mAreaManager, area );
- mInstances.push_back ( instance );
- }
- }
- }
- }
- }
- }
- else
- return false;
- }
- else
- return false;
- }
- #endif // #ifndef PRE_RELEASE_DEMO
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseInstance
- * Parses an individual instance
- *
- * inputs:
- * group: parser group containing the list of instances
- *
- * return:
- * true: instances parsed successfully
- * false: instances failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseInstance ( CGPGroup* group )
- {
- CRMArea* area;
- CRMInstance* instance;
- float spacing;
- vec3_t origin;
- vec3_t lookat;
- int flattenHeight;
- vec3_t zerodvec;
- VectorClear(zerodvec);
- // create fences / walls
- // Create the instance using the instance file helper class
- instance = mInstanceFile.CreateInstance ( group->GetName ( ) );
- // Failed to create, not good
- if ( NULL == instance )
- {
- return false;
- }
- // If a spacing radius was specified then override the one thats
- // in the instance
- spacing = atof( group->FindPairValue ( "spacing", "0" ) );
- if ( spacing )
- {
- instance->SetSpacingRadius ( spacing );
- }
- instance->SetFilter(group->FindPairValue("filter", ""));
- instance->SetTeamFilter(group->FindPairValue("teamfilter", ""));
- if (strstr(instance->GetTeamFilter(),"red"))
- instance->SetSide( SIDE_RED);
- else if (strstr(instance->GetTeamFilter(),"blue"))
- instance->SetSide( SIDE_BLUE );
- // ParseWallRect(group, instance->GetSide());
- // Get its origin now
- ParseOrigin ( group->FindSubGroup ( "origin" ), origin, lookat, &flattenHeight );
- origin[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * origin[0];
- origin[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * origin[1];
- origin[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * origin[2];
- lookat[0] = mLandScape->GetBounds ( )[0][0] + (mLandScape->GetBounds ( )[1][0]-mLandScape->GetBounds ( )[0][0]) * lookat[0];
- lookat[1] = mLandScape->GetBounds ( )[0][1] + (mLandScape->GetBounds ( )[1][1]-mLandScape->GetBounds ( )[0][1]) * lookat[1];
- lookat[2] = mLandScape->GetBounds ( )[0][2] + (mLandScape->GetBounds ( )[1][2]-mLandScape->GetBounds ( )[0][2]) * lookat[2];
- // Fixed height? (used for bridges)
- if ( !atoi(group->FindPairValue ( "nodrop", "0" )) )
- {
- origin[2] = mLandScape->GetBounds ( )[1][2] + 100;
- }
- // Set the area of position
- area = mAreaManager->CreateArea ( origin, instance->GetSpacingRadius(), instance->GetSpacingLine(), GetDefaultPadding(), 0, zerodvec, lookat, instance->GetFlattenRadius()?true:false, true, instance->GetLockOrigin(), mSymmetric );
- instance->SetArea ( mAreaManager, area );
- instance->SetFlattenHeight ( flattenHeight );
- mInstances.push_back ( instance );
- // create defenses?
- ParseInstancesOnPath(group );
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseInstances
- * parses all instances within the mission and populates the instance list
- *
- * inputs:
- * group: parser group containing the list of instances
- *
- * return:
- * true: instances parsed successfully
- * false: instances failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseInstances ( CGPGroup* group )
- {
- #ifndef PRE_RELEASE_DEMO
- // If NULL that means this particular difficulty level has no instances
- if ( NULL == group )
- {
- return true;
- }
- // Loop through all the instances in the mission and add each
- // to the master list of instances
- for ( group = group->GetSubGroups();
- group;
- group=group->GetNext() )
- {
- ParseInstance ( group );
- }
- #endif // #ifndef PRE_RELEASE_DEMO
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseObjectives
- * parses all objectives within the mission and populates the objective list
- *
- * inputs:
- * group: parser group containing the list of objectives
- *
- * return:
- * true: objectives parsed successfully
- * false: objectives failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseObjectives ( CGPGroup* group )
- {
- // If NULL that means this particular difficulty level has no objectives
- if ( NULL == group )
- {
- return true;
- }
- // Loop through all the objectives in the mission and add each
- // to the master list of objectives
- for ( group = group->GetSubGroups();
- group;
- group=group->GetNext() )
- {
- CRMObjective* objective;
- // Create the new objective
- objective = new CRMObjective ( group );
- mObjectives.push_back ( objective );
- }
- mValidObjectives = true;
-
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseAmmo
- * parses the given ammo list and sets the necessary ammo cvars to grant those
- * weapons to the players
- *
- * inputs:
- * ammos: parser group containing the ammo list
- *
- * return:
- * true: ammo parsed successfully
- * false: ammo failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseAmmo ( CGPGroup* ammos )
- {
- /* CGPValue* ammo;
- // No weapons, no success
- if ( NULL == ammos )
- {
- return false;
- }
- if (0 == gi.Cvar_VariableIntegerValue("ar_wpnselect"))
- {
- // Make sure the ammo cvars are all reset so ammo from the last map or
- // another difficulty level wont carry over
- CWeaponSystem::ClearAmmoCvars (TheWpnSysHelper());
- ammo = ammos->GetPairs ( );
- // Loop through the weapons listed and grant them to the player
- while ( ammo )
- {
- // Grab the weapons ID
- AmmoID id = CWeaponSystem::GetAmmoID ( ammo->GetName ( ) );
- // Now set the weapon cvar with the given data
- TheWpnSysHelper().CvarSet ( CWeaponSystem::GetAmmoCvar ( id ), ammo->GetTopValue ( ), CVAR_AMMO );
- // Move on to the next weapon
- ammo = (CGPValue*)ammo->GetNext();
- }
- }
- */
- mValidAmmo = true;
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseWeapons
- * parses the given weapon list and sets the necessary weapon cvars to grant those
- * weapons to the players
- *
- * inputs:
- * weapons: parser group containing the weapons list
- *
- * return:
- * true: weapons parsed successfully
- * false: weapons failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseWeapons ( CGPGroup* weapons )
- {
- /* CGPValue* weapon;
- WpnID id;
- // No weapons, no success
- if ( NULL == weapons )
- {
- return false;
- }
- if (0 == gi.Cvar_VariableIntegerValue("ar_wpnselect"))
- {
- // Make sure the weapon cvars are all reset so weapons from the last map or
- // another difficulty level wont carry over
- CWeaponSystem::ClearWpnCvars (TheWpnSysHelper());
- id = NULL_WpnID;
- weapon = weapons->GetPairs ( );
- // Loop through the weapons listed and grant them to the player
- while ( weapon )
- {
- // Grab the weapons ID
- id = CWeaponSystem::GetWpnID ( weapon->GetName ( ) );
- // Now set the weapon cvar with the given data
- TheWpnSysHelper().CvarSet ( CWeaponSystem::GetWpnCvar ( id ), weapon->GetTopValue ( ) );
- // Move on to the next weapon
- weapon = (CGPValue*)weapon->GetNext();
- }
- // If we found at least one weapon then ready the last one in the list
- if ( NULL_WpnID != id )
- {
- TheWpnSysHelper().CvarSet("wp_righthand", va("%i/%i/0/0",id,CWeaponSystem::GetClipSize ( id )), CVAR_MISC );
- }
- }
- */
- mValidWeapons = true;
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseOutfit
- * parses the outfit (weapons and ammo)
- *
- * inputs:
- * outfit: parser group containing the outfit
- *
- * return:
- * true: weapons and ammo parsed successfully
- * false: failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseOutfit ( CGPGroup* outfit )
- {
- if ( NULL == outfit )
- {
- return false;
- }
- /* // Its ok to fail parsing weapons as long as weapons have
- // already been parsed at some point
- if ( !ParseWeapons ( ParseRandom ( outfit->FindSubGroup ( "weapons" ) ) ) )
- {
- if ( !mValidWeapons )
- {
- return false;
- }
- }
- // Its ok to fail parsing ammo as long as ammo have
- // already been parsed at some point
- if ( !ParseAmmo ( ParseRandom ( outfit->FindSubGroup ( "ammo" ) ) ) )
- {
- if ( !mValidAmmo)
- {
- return false;
- }
- }
- */
- return true;
- }
- /************************************************************************************************
- * CRMMission::ParseRandom
- * selects a random sub group with from all within this one
- *
- * inputs:
- * random: parser group containing the various subgroups
- *
- * return:
- * true: parsed successfuly
- * false: failed to parse
- *
- ************************************************************************************************/
- CGPGroup* CRMMission::ParseRandom ( CGPGroup* randomGroup )
- {
- if (NULL == randomGroup)
- return NULL;
- CGPGroup* group;
- CGPGroup* groups[MAX_RANDOM_CHOICES];
- int numGroups;
- // Build a list of the groups one can be chosen
- for ( numGroups = 0, group = randomGroup->GetSubGroups ( );
- group;
- group = group->GetNext ( ) )
- {
- if ( stricmp ( group->GetName ( ), "random_choice" ) )
- {
- continue;
- }
- int weight = atoi ( group->FindPairValue ( "random_weight", "1" ) );
- while (weight-- > 0)
- groups[numGroups++] = group;
- assert (numGroups <= MAX_RANDOM_CHOICES);
- }
- // No groups!
- if ( !numGroups )
- {
- return randomGroup;
- }
- // Now choose a group to parse
- return groups[mLandScape->irand(0,numGroups-1)];
- }
- /************************************************************************************************
- * CRMMission::ParseDifficulty
- * parses the given difficulty and populates the mission with its data
- *
- * inputs:
- * difficulty: parser group containing the difficulties info
- *
- * return:
- * true: difficulty parsed successfully
- * false: difficulty failed to parse
- *
- ************************************************************************************************/
- bool CRMMission::ParseDifficulty ( CGPGroup* difficulty, CGPGroup *parent )
- {
- // If a null difficulty then stop the recursion. Make sure to
- // return true here so the parsing doesnt fail
- if ( NULL == difficulty )
- {
- return true;
- }
- if (difficulty->GetParent())
- {
- parent = difficulty->GetParent();
- }
- // is map supposed to be symmetric?
- mSymmetric = (symmetry_t)atoi(parent->FindPairValue ( "symmetric", "0" ));
- mBackUpPath = atoi(parent->FindPairValue ( "backuppath", "0" ));
- if( mSymmetric )
- {// pick between the 2 starting corners -- yes this is a hack
- mSymmetric = SYMMETRY_TOPLEFT;
- if( TheRandomMissionManager->GetLandScape()->irand(0, 1) )
- {
- mSymmetric = SYMMETRY_BOTTOMRIGHT;
- }
- }
-
- mDefaultPadding = atoi(parent->FindPairValue ( "padding", "0" ));
-
- // Parse the nodes
- if ( !ParseNodes ( ParseRandom ( difficulty->FindSubGroup ( "nodes" ) ) ) )
- {
- return false;
- }
- // Parse the paths
- if ( !ParsePaths ( ParseRandom ( difficulty->FindSubGroup ( "paths" ) ) ) )
- {
- return false;
- }
- // Parse the rivers
- if ( !ParseRivers ( ParseRandom ( difficulty->FindSubGroup ( "rivers" ) ) ) )
- {
- return false;
- }
- // Handle inherited properties
- if ( !ParseDifficulty ( parent->FindSubGroup ( difficulty->FindPairValue ( "inherit", "" ) ), parent ) )
- {
- return false;
- }
- // parse the player's outfit (weapons and ammo)
- if ( !ParseOutfit( ParseRandom ( difficulty->FindSubGroup ( "outfit" ) ) ) )
- {
- // Its ok to fail parsing weapons as long as weapons have
- // already been parsed at some point
- if ( !ParseWeapons ( ParseRandom ( difficulty->FindSubGroup ( "weapons" ) ) ) )
- {
- if ( !mValidWeapons )
- {
- return false;
- }
- }
- // Its ok to fail parsing ammo as long as ammo have
- // already been parsed at some point
- if ( !ParseAmmo ( ParseRandom ( difficulty->FindSubGroup ( "ammo" ) ) ) )
- {
- if ( !mValidAmmo)
- {
- return false;
- }
- }
- }
- // Its ok to fail parsing objectives as long as objectives have
- // already been parsed at some point
- if ( !ParseObjectives ( ParseRandom ( difficulty->FindSubGroup ( "objectives" ) ) ) )
- {
- if ( !mValidObjectives )
- {
- return false;
- }
- }
- // Set the cvars with the available values
- Cvar_Set ( "mi_health", difficulty->FindPairValue ( "health", "100" ) );
- Cvar_Set ( "mi_armor", difficulty->FindPairValue ( "armor", "0" ) );
- // Parse out the timelimit
- mTimeLimit = atol(difficulty->FindPairValue("timelimit", "0"));
- // NPC multipliers
- mAccuracyMultiplier = atof(difficulty->FindPairValue("npcaccuracy", "1"));
- mHealthMultiplier = atof(difficulty->FindPairValue("npchealth", "1"));
- // keep only some of RMG pickups 1 = 100%
- mPickupHealth = atof(difficulty->FindPairValue("pickup_health", "1"));
- mPickupArmor = atof(difficulty->FindPairValue("pickup_armor", "1"));
- mPickupAmmo = atof(difficulty->FindPairValue("pickup_ammo", "1"));
- mPickupWeapon = atof(difficulty->FindPairValue("pickup_weapon", "1"));
- mPickupEquipment = atof(difficulty->FindPairValue("pickup_equipment", "1"));
- // Its ok to fail parsing instances as long as instances have
- // already been parsed at some point
- if ( !ParseInstances ( ParseRandom ( difficulty->FindSubGroup ( "instances" ) ) ) )
- {
- if ( !mValidInstances )
- {
- return false;
- }
- }
- return true;
- }
- /************************************************************************************************
- * CRMMission::Load
- * Loads the given mission using the given difficulty level
- *
- * inputs:
- * name: Name of the mission to load (should only be the name rather than the full path)
- * difficulty: difficulty level to load
- *
- * return:
- * true: mission successfully loaded
- * false: mission failed to load
- *
- ************************************************************************************************/
- bool CRMMission::Load ( const char* mission, const char* instances, const char* difficulty )
- {
- CGenericParser2 parser;
- CGPGroup* root;
- // Create the parser for the mission file
- if(!Com_ParseTextFile(va("ext_data/rmg/%s.mission", mission), parser))
- {
- if(!Com_ParseTextFile(va("ext_data/arioche/%s.mission", mission), parser))
- {
- Com_Printf("ERROR: Failed to open mission file '%s'\n", mission);
- return false;
- }
- }
-
- // Grab the root parser groop and make sure its mission, otherwise this
- // isnt a valid mission file
- root = parser.GetBaseParseGroup()->GetSubGroups();
- if(stricmp(root->GetName(), "mission"))
- {
- Com_Printf("ERROR: '%s' is not a valid mission file\n", mission );
- parser.Clean();
- return false;
- }
-
- // Grab the mission description and set the cvar for it
- mDescription = root->FindPairValue ( "description", "<MISSION DESCRIPTION MISSING>" );
- // Cvar_Set("ar_obj_main0",mDescription.c_str(), CVAR_OBJECTIVE);
- // Cvar_Set("ar_obj_maincom0", "&OBJECTIVES_INPROGRESS&", CVAR_OBJECTIVE);
- // Cvar_SetValue ("ar_cur_objective", 0, CVAR_OBJECTIVE);
- string mInfo = root->FindPairValue ( "info", "<MISSION ADDITIONAL INFO MISSING>" );
- // Cvar_Set("ar_obj_info0",mInfo.c_str(), CVAR_OBJECTIVE);
- mExitScreen = root->FindPairValue ( "exitScreen", "<EXIT SCREEN MISSING>" );
- mTimeExpiredScreen = root->FindPairValue ( "TimeExpiredScreen", "<TIME EXPIRED SCREEN MISSING>" );
-
- // Open the instance file for the specified instances
- if ( !mInstanceFile.Open ( instances) )
- {
- Com_Printf ( "ERROR: Could not open instance file '%s'\n", instances );
- return false;
- }
- // Start at one and readjust each time we see and instance
- // with a higher value
- mMaxInstancePosition = 1;
- // Now parse the specified difficulty level
- CGPGroup* parserdif = root->FindSubGroup ( difficulty );
- CGPGroup* parserpar = parserdif->GetParent();
- if (!parserpar)
- { //rww - expected to have a parent, but sometime doesn't get set.
- //I take it JK2's generic parser is not quite the same as SOF2's. Or is out of date.
- parserpar = root;
- }
- if ( !ParseDifficulty ( parserdif, parserpar ) )
- {
- return false;
- }
- // Generate the terrain now
- mLandScape->Generate(mSymmetric);
- // Cleanup
- parser.Clean();
- return true;
- }
- /************************************************************************************************
- * CRMMission::Spawn
- * Spawns all of the instances for the entire mission onto the given landscape
- *
- * inputs:
- * landscape: landscape to spawn instances on
- *
- * return:
- * true: instances spawned successfully
- * false: instances failed to spawn
- *
- ************************************************************************************************/
- bool CRMMission::Spawn ( CRandomTerrain* terrain, qboolean IsServer )
- {
- #ifndef PRE_RELEASE_DEMO
- rmInstanceIter_t it;
- int areaIndex;
- CRMArea* area;
- // Prespawn all instances, this is mainly for flattening
- for(it = mInstances.begin(); it != mInstances.end(); it++)
- {
- CRMInstance* instance = *it;
- // Pre-Spawn
- instance->PreSpawn ( terrain, IsServer );
- if (mSymmetric)
- {
- instance->SetMirror(1);
- instance->PreSpawn ( terrain, IsServer );
- instance->SetMirror(0);
- }
- }
- mLandScape->Smooth ( );
- // place bridges
- PlaceBridges();
- // create automap
- // if (!com_dedicated->integer)
- {
- #ifndef DEDICATED
- CM_TM_Create(mLandScape->GetLandScape());
- #endif
- }
- mLandScape->GetLandScape()->UpdatePatches();
- // Spawn all instances
- for(it = mInstances.begin(); it != mInstances.end(); it++)
- {
- CRMInstance* instance = *it;
- // Spawn
- instance->Spawn ( terrain, IsServer );
- instance->PostSpawn ( terrain, IsServer );
- if (mSymmetric)
- { // spawn the mirror version
- instance->SetMirror(1);
- instance->Spawn ( terrain, IsServer );
- instance->PostSpawn ( terrain, IsServer );
- instance->SetMirror(0);
- }
- }
- #ifndef FINAL_BUILD
- // make sure to write out after the mirror happens so red side is displayed on map
- if (1 == Cvar_VariableIntegerValue("rmg_saveautomap"))
- { // write out automap for test purposes
- char seed[MAX_QPATH];
- char terrainName[MAX_QPATH];
- char missionName[MAX_QPATH];
- Cvar_VariableStringBuffer("RMG_seed", seed, MAX_QPATH);
- Cvar_VariableStringBuffer("RMG_terrain", terrainName, MAX_QPATH);
- Cvar_VariableStringBuffer("RMG_mission", missionName, MAX_QPATH);
- #ifndef DEDICATED
- for(it = mInstances.begin(); it != mInstances.end(); it++)
- {
- (*it)->DrawAutomapSymbol();
- }
- //gi.CM_TM_SaveImageToDisk(terrainName, missionName, seed);
- CM_TM_SaveImageToDisk(terrainName, missionName, seed);
- #endif
- Com_Error (ERR_DROP, "RMG Automap written.");
- return false;
- }
- #endif
- // // draw player start on automap
- // CEntity *spot = NULL;
- // spot = entitySystem->GetEntityFromClassname( spot, "info_player_start");
- // if (spot)
- // {
- // gi.CM_TM_AddStart(spot->GetOrigin()[0], spot->GetOrigin()[1]);
- // }
- // Spawn NPC triggers now
- // SpawnNPCTriggers ( mLandScape );
- // Restory all the NPC's accuracies to the template accuracies times the
- // multiplier
- // INPCEnt::RestoreTemplate ( mAccuracyMultiplier, mHealthMultiplier );
- // Little trick to set the current objective to the first in the list
- CompleteObjective ( NULL );
- // Iterate through the areas and add each to the landscapes list, this is sorta hacky
- // but bridges the game / common gap
- for ( areaIndex = 0; NULL != (area = mAreaManager->EnumArea ( areaIndex )); areaIndex ++ )
- {
- // Dont bother adding it to the list if collision isnt enabled
- if ( !area->IsCollisionEnabled() )
- {
- continue;
- }
- CArea* newarea = new CArea ( );
- newarea->Init ( area->GetOrigin(), area->GetSpacingRadius (), 0, area->IsFlattened()?AT_FLAT:AT_NONE );
- mLandScape->GetLandScape()->SaveArea( newarea );
- if (mSymmetric)
- {
- CArea* newarea = new CArea ( );
- newarea->Init ( area->GetOrigin(), area->GetSpacingRadius (), 0, area->IsFlattened()?AT_FLAT:AT_NONE );
- newarea->GetPosition()[0] = mLandScape->GetBounds ( )[0][0]+mLandScape->GetBounds ( )[1][0]-newarea->GetPosition()[0];
- newarea->GetPosition()[1] = mLandScape->GetBounds ( )[0][1]+mLandScape->GetBounds ( )[1][1]-newarea->GetPosition()[1];
- mLandScape->GetLandScape()->SaveArea( newarea );
- }
- }
- mInstanceFile.Close ( );
- #endif // PRE_RELEASE_DEMO
- return true;
- }
- /************************************************************************************************
- * CRMMission::CompleteMission
- * Pauses the game, plays an end screen after a brief delay, which then returns the player to
- * the RMG menu.
- * *
- * Input *
- * <Variable>: <Description> *
- * Output / Return *
- * <Variable>: <Description> *
- ************************************************************************************************/
- void CRMMission::CompleteMission(void)
- {
- Cvar_Set ("cl_paused", "1");
- // AddText(va("killserver; menu %s\n", mExitScreen.c_str()));
- return;
- }
- /************************************************************************************************
- * CRMMission::FailedMission
- * Pauses the game, plays an end screen after a brief delay, which then returns the player to
- * the RMG menu.
- * *
- * Input *
- * TimeExpired: indicates if the reason failed was because of time
- * Output / Return *
- * <Variable>: <Description> *
- ************************************************************************************************/
- void CRMMission::FailedMission(bool TimeExpired)
- {
- Cvar_Set ("cl_paused", "1");
- if (TimeExpired)
- {
- // AddText(va("killserver; menu %s\n", mTimeExpiredScreen.c_str()));
- }
- return;
- }
- /************************************************************************************************
- * CRMMission::CompleteObjective
- * Completes the given objective and advances the current objective accordingly
- *
- * inputs:
- * objective: the objetive to mark complete
- *
- * return:
- * none
- *
- ************************************************************************************************/
- void CRMMission::CompleteObjective ( CRMObjective* objective )
- {
- rmObjectiveIter_t it;
- // Set the object as completed
- if ( objective )
- {
- objective->Complete ( true );
- // Set the completed text for the objective
- // gi.Cvar_Set( va("ar_obj_subcom0_%i", objective->GetOrderIndex ( )), "&OBJECTIVES_COMPLETE&", CVAR_OBJECTIVE) ;
- /* CEntity *tent = G_TempEntity( vec3_origin, EV_SUB_PRINT );
- tent->s.time2 = gi.SP_GetStringID ( objective->GetMessage ( ) );
- tent->r.svFlags |= SVF_BROADCAST;
- G_AddTempEntity(tent);
- if (objective->CompleteSoundID())
- G_SoundBroadcast( tent, objective->CompleteSoundID());
- */
- }
- mCurrentObjective = NULL;
- // Find the next objective
- for (it = mObjectives.begin(); it != mObjectives.end(); it++)
- {
- objective = (*it);
- // Skip completed objectives
- if ( objective->IsCompleted ( ) )
- {
- continue;
- }
- // Find the objective with the lowest priority
- if ( mCurrentObjective && objective->GetPriority ( ) > mCurrentObjective->GetPriority ( ) )
- {
- continue;
- }
- // Found one
- mCurrentObjective = objective;
- }
- if ( NULL != mCurrentObjective )
- {
- // Cvar_SetValue ("ar_cur_objective", mCurrentObjective->GetOrderIndex ( ), CVAR_OBJECTIVE);
- mCurrentObjective->Activate ( );
- }
- else
- {
- // Set the completed text for the objective
- // Cvar_Set( "ar_obj_maincom0", "&OBJECTIVES_COMPLETE&", CVAR_OBJECTIVE) ;
- }
- }
- /************************************************************************************************
- * CRMMission::Preview
- * Previews the instances within the mission
- *
- * inputs:
- * from: the origin which the mission is being previewed from
- *
- * return:
- * none
- *
- ************************************************************************************************/
- void CRMMission::Preview ( const vec3_t from )
- {
- rmInstanceIter_t it;
- // Look for settlements close to the player and put up some debug stuff
- for(it = mInstances.begin(); it != mInstances.end(); it++)
- {
- CRMInstance* instance = *it;
- vec3_t a;
- vec3_t b;
- VectorCopy ( from, a );
- VectorCopy ( instance->GetOrigin(), b );
- a[2] = 0;
- b[2] = 0;
- // Skip stuff thats too far away
- if ( Distance ( a, b) > 2000 )
- {
- continue;
- }
- instance->Preview ( from );
- }
- }
- /************************************************************************************************
- * CRMMission::PurgeTrigger
- * Purge the trigger and all its targets
- *
- * inputs:
- * trigger: trigger to purge
- *
- * return:
- * none
- *
- ************************************************************************************************/
- /*void CRMMission::PurgeTrigger ( CEntity* trigger )
- {
- CEntity* target;
-
- // Purge all targets
- target = entitySystem->GetEntityFromTargetName ( NULL, trigger->GetTarget ( ) );
- while ( target )
- {
- PurgeTrigger ( target );
- target = entitySystem->GetEntityFromTargetName ( target, trigger->GetTarget ( ) );
- }
- // Get rid of the purge trigger
- entitySystem->RemoveEntityWithServer ( trigger );
- entitySystem->RemoveEntity ( trigger );
- }
- */
- /************************************************************************************************
- * CRMMission::PurgeUnlinkedTriggers
- * Searches the entitySystem form a random arioche trigger that matches the objective name
- *
- * inputs:
- * none
- *
- * return:
- * trigger: a random trigger or NULL if one couldnt be found
- *
- ************************************************************************************************/
- /*void CRMMission::PurgeUnlinkedTriggers ( )
- {
- CTriggerAriocheObjective* search;
- // Start at the first match of the classname
- search = (CTriggerAriocheObjective*) entitySystem->GetEntityFromClassname ( NULL, "trigger_arioche_objective" );
- // Continue on as long as there are triggers
- while ( search )
- {
- CTriggerAriocheObjective* purge = search;
- // move on to the next trigger before deleting the entity
- // just in case there are some state issues with the search
- search = (CTriggerAriocheObjective*) entitySystem->GetEntityFromClassname ( search, "trigger_arioche_objective" );
- // Dont purge linked triggers
- if ( purge->GetObjective ( ) )
- {
- continue;
- }
- // Purge the trigger and all its targets
- PurgeTrigger ( purge );
- }
- }
- */
- /************************************************************************************************
- * CRMMission::SpawnNPCTriggers
- * Spawn triggers across the map which will activate sleeping NPCs
- *
- * inputs:
- * landscape: landscape to spawn the triggers relative to
- *
- * return:
- * trigger: a random trigger or NULL if one couldnt be found
- *
- ************************************************************************************************/
- /*void CRMMission::SpawnNPCTriggers ( CCMLandScape* landscape )
- {
- CEntity* ent;
- int i;
- int count;
- float section;
- // Determine how many NPC sections there are in the map
- count = (landscape->GetBounds()[1][0] - landscape->GetBounds()[0][0]) / 5000.0f;
- section = (landscape->GetBounds()[1][0] - landscape->GetBounds()[0][0]) / count;
- // Drop a trigger down at each NPC section interval except for the first and last.
- for ( i = 1; i < count - 1; i ++ )
- {
- vec3_t mins;
- vec3_t maxs;
- vec3_t origin;
- VectorCopy ( landscape->GetBounds()[0], mins );
- VectorCopy ( landscape->GetBounds()[1], maxs );
- // Set up the mins and maxs for the trigger
- mins[0] = mins[0] + (section * i) - 100;
- maxs[0] = mins[0] + 100;
- maxs[2] = maxs[2] + 100;
- mins[2] = mins[2] - 100;
- origin[0] = (maxs[0]-mins[0])/2 + mins[0];
- origin[1] = (maxs[1]-mins[1])/2 + mins[1];
- origin[2] = (maxs[2]-mins[2])/2 + mins[2];
- spawnSystem->ClearSpawnFields();
- spawnSystem->AddSpawnField("classname", "trigger_arioche_npcspawner" );
- spawnSystem->AddSpawnField("origin", va("%f %f %f",origin[0],origin[1],origin[2]) );
- spawnSystem->AddSpawnField("target", va("rmg_npc_%i", i + 1) );
- // Spawn the inhabitant, if it fails then fail
- ent = entitySystem->SpawnItem("trigger_arioche_npcspawner");
- if ( !ent )
- {
- continue;
- }
- // Fail if we cant register the entity
- if ( -1 == entitySystem->RegisterEntityWithServer( ent ) )
- {
- entitySystem->RemoveEntity ( ent );
- continue;
- }
- // Normalize the mins and maxs for the X axis since they arent
- // absolute mins and maxs
- mins[0] = -100;
- maxs[0] = 100;
- // Adjust the absmin and absmax for the trigger now
- VectorCopy ( mins, ent->r.mins[0] );
- VectorCopy ( maxs, ent->r.maxs[0] );
- Com_DPrintf( "NPC Trigger spawned at '%f %f %f' for targets 'rmg_npc_%i'\n", origin[0], origin[1], origin[2], i + 1 );
- // Set the "ONLY_ONCE" spawn flag
- ent->AddSpawnflags ( 2 );
- #ifdef _GAME
- // initial linking
- gi.SV_LinkEntity( ent );
- #endif
- }
- AttachNPCTriggers ( landscape );
- }
- */
- /************************************************************************************************
- * CRMMission::AttachNPCTriggers
- * Attaches npc triggers to all unattached npcs
- *
- * inputs:
- * landscape: landscape triggers were spawned on
- *
- * return:
- * trigger: a random trigger or NULL if one couldnt be found
- *
- ************************************************************************************************/
- /*void CRMMission::AttachNPCTriggers ( CCMLandScape* landscape )
- {
- TNPCList npcList;
- TNPCFinder npcFinder;
- CNPC* theNPC = 0;
- int npcsegment;
- GetCharacterManager().GetCharacterList(npcList);
- // Loop through all npcs and reset their accuracy
- for( npcFinder = npcList.begin(); npcFinder != npcList.end(); npcFinder++)
- {
- theNPC = (CNPC*) INPCEnt::GetEntity(*npcFinder);
- if(!theNPC)
- {
- continue;
- }
- npcsegment = (theNPC->r.currentOrigin[0] - landscape->GetMins()[0]) / 5000.0f;
- // All npcs in segment 0 and 1 are immediately spawned, all others wait for the
- // trigger
- if ( npcsegment > 1 )
- {
- entitySystem->RemoveFromTargetNameMap(theNPC);
- theNPC->SetTargetName ( va("rmg_npc_%i", npcsegment ) );
- entitySystem->AddToTargetNameMap(theNPC);
- // Start the NPC in the off position
- theNPC->SetSpawnflags(1);
- theNPC->r.contents = 0;
- theNPC->r.svFlags |= SVF_NOCLIENT;
- theNPC->s.eFlags |= EF_NODRAW;
- }
- }
- }
- */
|