123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290 |
- //---------------------------------------------------------------------------
- //
- // terrobj.cpp -- File contains the misc terrain object code
- //
- // MechCommander 2
- //
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //---------------------------------------------------------------------------
- // Include Files
- #ifndef MCLIB_H
- #include "mclib.h"
- #endif
- #ifndef TERROBJ_H
- #include "terrobj.h"
- #endif
- #ifndef GAMESOUND_H
- #include "gamesound.h"
- #endif
- #ifndef SOUNDS_H
- #include "sounds.h"
- #endif
- #ifndef MOVE_H
- #include "move.h"
- #endif
- #ifndef TEAM_H
- #include "team.h"
- #endif
- #ifndef COLLSN_H
- #include "collsn.h"
- #endif
- #ifndef MULTPLYR_H
- #include "multplyr.h"
- #endif
- #ifndef OBJMGR_H
- #include "objmgr.h"
- #endif
- #ifndef CARNAGE_H
- #include "carnage.h"
- #endif
- #ifndef DOBJNUM_H
- #include "dobjnum.h"
- #endif
- //#include "ObjectAppearance.h"
- extern unsigned long NextIdNumber;
- extern float worldUnitsPerMeter;
- extern bool drawExtents;
- extern bool somethingOnFire;
- extern bool useOldProject;
- extern bool MLRVertexLimitReached;
- inline float agsqrt( float _a, float _b )
- {
- return sqrt(_a*_a + _b*_b);
- }
- #define TREE_FALL_RATE 15.0f
- #define TREE_FALL_ACCEL 5.0f;
- char lastName[256];
- extern MidLevelRenderer::MLRClipper * theClipper;
- extern bool useNonWeaponEffects;
- //---------------------------------------------------------------------------
- // class TerrainObjectType
- //---------------------------------------------------------------------------
- GameObjectPtr TerrainObjectType::createInstance (void) {
- TerrainObjectPtr result = new TerrainObject;
- if (!result)
- return NULL;
- result->init(true, this);
- //result->setIdNumber(NextIdNumber++);
-
- return(result);
- }
- //---------------------------------------------------------------------------
- void TerrainObjectType::init (void) {
-
- objectTypeClass = TERRAINOBJECT_TYPE;
- objectClass = TERRAINOBJECT;
-
- subType = TERROBJ_NONE;
- damageLevel = 0.0;
- collisionOffsetX = 0;
- collisionOffsetY = 0;
- setImpassable = false;
- xImpasse = 0;
- yImpasse = 0;
- extentRadius = -1.0;
- explDmg = 0.0;
- explRad = 0.0;
- fireTypeHandle = -1;
- }
- //---------------------------------------------------------------------------
- void TerrainObjectType::destroy (void)
- {
- ObjectType::destroy();
- }
-
- //---------------------------------------------------------------------------
- void TerrainObjectType::initMiscTerrObj (long objTypeNum) {
- //---------------------------------------------------------------------
- // This function is here to maintain compatibility with MC1. The values
- // used for the various miscTerrainTypes are hardcoded, based on
- // MC1 ship values. If we need to modify 'em, then try adding new
- // object types to the packet file!
- explosionObject = 0xFFFFFFFF;
- destroyedObject = 0xFFFFFFFF;
- extentRadius = -1.0;
- keepMe = true;
- iconNumber = -1;
- teamId = -1;
- if (objTypeNum == ObjectTypeManager::bridgeTypeHandle) {
- subType = TERROBJ_BRIDGE;
- damageLevel = 100.0;
- }
- else if (objTypeNum == ObjectTypeManager::forestTypeHandle) {
- subType = TERROBJ_FOREST;
- damageLevel = 100.0;
- fireTypeHandle = 1;
- }
- else if (objTypeNum == ObjectTypeManager::wallHeavyTypeHandle) {
- subType = TERROBJ_WALL_HEAVY;
- damageLevel = 100.0;
- }
- else if (objTypeNum == ObjectTypeManager::wallMediumTypeHandle) {
- subType = TERROBJ_WALL_MEDIUM;
- damageLevel = 100.0;
- }
- else if (objTypeNum == ObjectTypeManager::wallLightTypeHandle) {
- subType = TERROBJ_WALL_LIGHT;
- damageLevel = 100.0;
- }
- else
- Fatal(objTypeNum, " TerrainObjectType.init: bad MiscTerrainObj num ");
- }
- //---------------------------------------------------------------------------
- long TerrainObjectType::init (FilePtr objFile, unsigned long fileSize) {
- long result = 0;
-
- FitIniFile bldgFile;
- result = bldgFile.open(objFile, fileSize);
- if (result != NO_ERR)
- return(result);
-
- //----------------------------------------------
- // Read in the data needed for the TerrainObject
- subType = TERROBJ_NONE;
- result = bldgFile.seekBlock("TerrainObjectData");
- if (result != NO_ERR) {
- result = bldgFile.seekBlock("TreeData");
- if (result != NO_ERR)
- return(result);
- subType = TERROBJ_TREE;
- objectClass = TREE;
- }
- unsigned long dmgLevel;
- result = bldgFile.readIdULong("DmgLevel",dmgLevel);
- if (result != NO_ERR)
- return(result);
- damageLevel = (float)dmgLevel;
-
- result = bldgFile.readIdLong("CollisionOffsetX",collisionOffsetX);
- if (result != NO_ERR)
- collisionOffsetX = 0;
-
- result = bldgFile.readIdLong("CollisionOffsetY",collisionOffsetY);
- if (result != NO_ERR)
- collisionOffsetY = 0;
- long setImpass;
- result = bldgFile.readIdLong("SetImpassable",setImpass);
- setImpassable = false;
- if (result == NO_ERR)
- setImpassable = setImpass ? true : false;
-
- result = bldgFile.readIdLong("XImpasse",xImpasse);
- if (result != NO_ERR)
- xImpasse = 0;
-
- result = bldgFile.readIdLong("YImpasse",yImpasse);
- if (result != NO_ERR)
- yImpasse = 0;
- float realExtent = 0.0;
- result = bldgFile.readIdFloat("ExtentRadius", realExtent);
- if (result != NO_ERR)
- realExtent = -1.0;
- result = bldgFile.readIdFloat("ExplosionRadius",explRad);
- //-----------------------------------------------------------------
- // if this fails, explosion radius is not set and no splash damage.
- if (result != NO_ERR)
- explRad = 0.0;
-
- result = bldgFile.readIdFloat("ExplosionDamage",explDmg);
- // if this fails, explosion damage is not set and no splash damage.
- if (result != NO_ERR)
- explDmg = 0.0;
- //-------------------------------------------------------
- // Initialize the base object Type from the current file.
- result = ObjectType::init(&bldgFile);
- extentRadius = realExtent;
- return(result);
- }
-
- //---------------------------------------------------------------------------
- bool TerrainObjectType::handleCollision (GameObjectPtr collidee, GameObjectPtr collider) {
- if (MPlayer && !MPlayer->isServer())
- return(true);
- switch (subType) {
- case TERROBJ_NONE:
- //-------------------------------------------------------
- // The Building ceases to exist when its effect is done.
- // always return FALSE or the collision will make it
- // go away! We may want to play a sound effect here.
- switch (collider->getObjectClass()) {
- case EXPLOSION:
- case BATTLEMECH:
- case GROUNDVEHICLE:
- if (!collider->isMover() || (collider->isMover() && ((MoverPtr)collider)->pathLocks))
- {
- WeaponShotInfo shot;
- shot.init(0, -1, collidee->getDamageLevel(), 0, 0);
- collidee->handleWeaponHit(&shot, (MPlayer != NULL));
- }
- break;
- }
- break;
- case TERROBJ_TREE:
- //-------------------------------------------------------
- // Trees are magical. If a mech hits one, it goes down
- // and is replaced by its last frame. In other words,
- // play the animation and stop on last frame.
- //
- // When a tree falls, we change its frame_of_ref to match
- // the direction it should fall in from the nominal world frame.
- //
- switch (collider->getObjectClass()) {
- case EXPLOSION:
- case BATTLEMECH:
- case GROUNDVEHICLE:
- if (!collider->isMover() || (collider->isMover() && ((MoverPtr)collider)->pathLocks))
- {
- TerrainObjectPtr tree = (TerrainObjectPtr)collidee;
- if (!tree->getFlag(OBJECT_FLAG_FALLEN) && !tree->getFlag(OBJECT_FLAG_FALLING)) {
- tree->setFlag(OBJECT_FLAG_FALLING, true);
-
- float fallAngle = collidee->relFacingTo(collider->getPosition());
- collidee->rotate(fallAngle,0.0f);
-
- //------------------------------------------------------
- // Tree has fallen. You may no longer collide with it.
- tree->setTangible(false);
- }
- }
- break;
- }
- break;
- case TERROBJ_BRIDGE:
- case TERROBJ_FOREST:
- case TERROBJ_WALL_HEAVY:
- case TERROBJ_WALL_MEDIUM:
- break;
- case TERROBJ_WALL_LIGHT:
- switch (collider->getObjectClass()) {
- case BATTLEMECH:
- case GROUNDVEHICLE: {
- WeaponShotInfo shotInfo;
- shotInfo.init(collider->getWatchID(), -1, 250.0, 0, 0);
- if (MPlayer) {
- if (MPlayer->isServer()) {
- collidee->handleWeaponHit(&shotInfo, true);
- }
- }
- else
- collidee->handleWeaponHit(&shotInfo);
- }
- break;
- }
- break;
- }
-
- return(true);
- }
- //---------------------------------------------------------------------------
- bool TerrainObjectType::handleDestruction (GameObjectPtr collidee, GameObjectPtr collider) {
- TerrainObjectPtr me = (TerrainObjectPtr)collidee;
- if (me->getObjectType()->getSubType() == TERROBJ_FOREST) {
- me->openSubAreas();
- }
- return(false);
- }
- //***************************************************************************
- // class TerrainObject
- //***************************************************************************
- void TerrainObject::rotate (float yaw, float pitch)
- {
- rotation = yaw;
- pitchAngle = pitch;
- }
- void TerrainObject::updateDebugWindow (GameDebugWindow* debugWindow) {
- debugWindow->clear();
- char s[128];
- //-------------------------------------------------------
- // For now, show the floating help text if we have one...
- if (((ObjectAppearance*)appearance)->objectNameId != -1) {
- char myName[255];
- cLoadString(((ObjectAppearance*)appearance)->objectNameId, myName, 254);
- debugWindow->print(myName);
- }
- else
- debugWindow->print("<no name>");
- sprintf(s, "team: %d, handle: %d, partID: %d %s", getTeamId(), getHandle(), getPartId(), getFlag(OBJECT_FLAG_CAPTURABLE) ? "[C]" : " ");
- debugWindow->print(s);
- sprintf(s, "objType: %d", getObjectType()->whatAmI());
- debugWindow->print(s);
- sprintf(s, "damage: %.2f/%.2f", getDamage(), getDamageLevel());
- debugWindow->print(s);
- sprintf(s, "pos: [%d, %d](area = %d)", cellPositionRow, cellPositionCol, GlobalMoveMap[0]->calcArea(cellPositionRow, cellPositionCol));
- debugWindow->print(s);
- sprintf(s, "footprint:[%d,%d]:[%d,%d]", cellFootprint[0], cellFootprint[1], cellFootprint[2], cellFootprint[3]);
- debugWindow->print(s);
- if (numSubAreas0 > 0) {
- sprintf(s, "subAreas:");
- for (long i = 0; i < numSubAreas0; i++) {
- char tempStr[15];
- sprintf(tempStr, " %d", subAreas0[i]);
- strcat(s, tempStr);
- }
- strcat(s, " *");
- for (i = 0; i < numSubAreas1; i++) {
- char tempStr[15];
- sprintf(tempStr, " %d", subAreas1[i]);
- strcat(s, tempStr);
- }
- debugWindow->print(s);
- }
- }
- //---------------------------------------------------------------------------
- bool TerrainObject::isVisible (void) {
- //----------------------------------------------------------------------
- // This function is the meat and potatoes of the object cull system.
- // Its job is to determine if the object is on screen or not.
- // It does this by transforming the position for each active camera to
- // its screen coords and saving them. It then checks each set of coords
- // to see if they are in the viewport of each camera. Returned value
- // is number of windows that object can be seen in.
- bool isVisible = false; //land->getVertexScreenPos(blockNumber, vertexNumber, screenPos);
- if (appearance)
- isVisible = appearance->recalcBounds();
-
- if (isVisible) {
- windowsVisible = turn;
- return(true);
- }
- return(false);
- }
- //---------------------------------------------------------------------------
- char* TerrainObject::getName (void) {
- /*
- static char* terrainObjectNames[NUM_TERROBJ_SUBTYPES] = {
- "Nothing",
- "Tree",
- "Bridge",
- "Forest",
- "Heavy Wall",
- "Medium Wall",
- "Light Wall"
- };
- TerrainObjectTypePtr type = (TerrainObjectTypePtr)getObjectType();
- return(terrainObjectNames[type->subType]);
- */
- if (((ObjectAppearance*)appearance)->objectNameId != -1) {
- cLoadString(((ObjectAppearance*)appearance)->objectNameId, lastName, 254);
- return(lastName);
- }
- return(NULL);
- }
- //---------------------------------------------------------------------------
- float TerrainObject::getStatusRating (void) {
- float curDamage = getDamage();
- float maxHealth = getDamageLevel();
- float rating = (maxHealth - curDamage) / maxHealth;
- if (rating < 0.0)
- rating = 0.0;
- return(rating);
- }
- //---------------------------------------------------------------------------
- #define BRIDGE_OFFSET 60
- long TerrainObject::update (void) {
- if (getFlag(OBJECT_FLAG_JUSTCREATED))
- {
- setFlag(OBJECT_FLAG_JUSTCREATED, false);
- setFlag(OBJECT_FLAG_TILECHANGED, false);
- TerrainObjectTypePtr type = (TerrainObjectTypePtr)ObjectManager->getObjectType(typeHandle);
- switch (type->subType) {
- case TERROBJ_NONE:
- case TERROBJ_TREE:
- {
- setTangible(true);
- }
- break;
-
- case TERROBJ_BRIDGE:
- if (!GameMap->getPassable(cellPositionRow, cellPositionCol)) {
- damage = type->getDamageLevel();
- setStatus(OBJECT_STATUS_DESTROYED);
- }
- break;
- case TERROBJ_FOREST:
- case TERROBJ_WALL_HEAVY:
- case TERROBJ_WALL_MEDIUM:
- case TERROBJ_WALL_LIGHT:
- if (GameMap->getPassable(cellPositionRow, cellPositionCol)) {
- damage = type->getDamageLevel();
- setStatus(OBJECT_STATUS_DESTROYED);
- }
- break;
- }
- }
- //-------------------------------------------
- // Handle power out.
- if (powerSupply && (ObjectManager->getByWatchID(powerSupply)->getStatus() == OBJECT_STATUS_DESTROYED))
- appearance->setLightsOut(true);
-
- if (appearance)
- {
- if (getFlag(OBJECT_FLAG_FALLING))
- {
- if (fallRate == 0.0f)
- {
- if (useSound && soundSystem)
- soundSystem->playDigitalSample(TREEFALL, getPosition(), true);
-
- fallRate = TREE_FALL_RATE;
- }
- else
- fallRate += TREE_FALL_ACCEL;
-
- pitchAngle -= (frameLength * fallRate);
- if (pitchAngle < -85.0f)
- {
- setFlag(OBJECT_FLAG_FALLEN,true);
- setFlag(OBJECT_FLAG_FALLING,false);
- }
- }
-
- appearance->setObjectParameters(position,rotation,FALSE,getTeamId(),Team::getRelation(getTeamId(), Team::home->getId()));
- appearance->setMoverParameters(pitchAngle);
- bool inView = appearance->recalcBounds();
- if (inView)
- {
- windowsVisible = turn;
- appearance->update();
- if (bldgDustPoofEffect && bldgDustPoofEffect->IsExecuted())
- {
- Stuff::Point3D actualPosition;
- Stuff::LinearMatrix4D shapeOrigin;
- Stuff::LinearMatrix4D localToWorld;
-
- actualPosition.x = -position.x;
- actualPosition.y = position.z;
- actualPosition.z = position.y;
-
- shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
- shapeOrigin.BuildTranslation(actualPosition);
-
- Stuff::OBB boundingBox;
- gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,&boundingBox);
-
- bool result = bldgDustPoofEffect->Execute(&info);
- if (!result)
- {
- bldgDustPoofEffect->Kill();
- delete bldgDustPoofEffect;
- bldgDustPoofEffect = NULL;
- }
- }
- }
- }
- return(1);
- }
- //---------------------------------------------------------------------------
- void TerrainObject::render (void) {
- if (!getFlag(OBJECT_FLAG_JUSTCREATED))
- {
- }
- if (appearance->canBeSeen())
- {
- if (getSelected())
- {
- TerrainObjectTypePtr type = (TerrainObjectTypePtr)getObjectType();
- float barStatus = 1.0;
- float totalDmgLvl = type->getDamageLevel();
- if (totalDmgLvl > 0.0)
- barStatus -= getDamage() / totalDmgLvl;
-
- if (barStatus < 0.0)
- barStatus = 0.0;
- DWORD color = 0xff7f7f7f;
-
- appearance->setBarColor(color);
- appearance->setBarStatus(barStatus);
- }
- //For debug purposes only. Will crash pause!! Sorry Heidi!
- // if (windowsVisible != turn)
- // STOP(("Rendering without an update!"));
- appearance->setVisibility(true,true);
- appearance->render();
-
- //------------------------------------------------
- // Render GOSFX
- gosFX::Effect::DrawInfo drawInfo;
- drawInfo.m_clipper = theClipper;
-
- MidLevelRenderer::MLRState mlrState;
- mlrState.SetDitherOn();
- mlrState.SetTextureCorrectionOn();
- mlrState.SetZBufferCompareOn();
- mlrState.SetZBufferWriteOn();
- drawInfo.m_state = mlrState;
- drawInfo.m_clippingFlags = 0x0;
-
- if (bldgDustPoofEffect && bldgDustPoofEffect->IsExecuted())
- {
- Stuff::Point3D actualPosition;
- Stuff::LinearMatrix4D shapeOrigin;
- Stuff::LinearMatrix4D localToWorld;
- actualPosition.x = -position.x;
- actualPosition.y = position.z;
- actualPosition.z = position.y;
-
- shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
- shapeOrigin.BuildTranslation(actualPosition);
-
- drawInfo.m_parentToWorld = &shapeOrigin;
-
- if (!MLRVertexLimitReached)
- bldgDustPoofEffect->Draw(&drawInfo);
- }
- }
-
- setSelected(false); //ALWAYS reset the selected flags. GUI needs this to work!
- setTargeted( false ); //ALWAYS do it here, too! Otherwise things may draw FUNNY!
- }
- //---------------------------------------------------------------------------
- void TerrainObject::renderShadows (void)
- {
- if (getFlag(OBJECT_FLAG_FALLING) || getFlag(OBJECT_FLAG_FALLEN))
- return; //No shadows on fallen trees.
-
- if (appearance->canBeSeen())
- {
- appearance->renderShadows();
- }
-
- setSelected(false); //ALWAYS reset the selected flags. GUI needs this to work!
- setTargeted( false ); //ALWAYS do it here, too! Otherwise things may draw FUNNY!
- }
- //---------------------------------------------------------------------------
- void TerrainObject::destroy (void)
- {
- if (cellsCovered)
- {
- numCellsCovered = 0;
- systemHeap->Free(cellsCovered);
- cellsCovered = NULL;
- }
- if (subAreas0)
- {
- ObjectTypeManager::objectCache->Free(subAreas0);
- subAreas0 = NULL;
- }
- if (subAreas1)
- {
- ObjectTypeManager::objectCache->Free(subAreas1);
- subAreas1 = NULL;
- }
- //-----------------------------------------------------
- // This will free any memory the Building is using.
- if (appearance)
- {
- delete appearance;
- appearance = NULL;
- }
- }
- //---------------------------------------------------------------------------
- void TerrainObject::setDamage (long newDamage) {
- damage = (float)newDamage;
- TerrainObjectTypePtr type = (TerrainObjectTypePtr)getObjectType();
- switch (type->subType)
- {
- case TERROBJ_TREE:
- case TERROBJ_NONE:
-
- break;
- }
- //---------------------------------------------
- // Code needs to go in here to fix appearance
- if (damage >= getDamageLevel())
- {
- setStatus(OBJECT_STATUS_DESTROYED);
- if (appearance)
- appearance->setObjStatus(OBJECT_STATUS_DESTROYED);
- }
- }
-
- //---------------------------------------------------------------------------
- void TerrainObject::init (bool create, ObjectTypePtr objType) {
- GameObject::init(true, objType);
- setFlag(OBJECT_FLAG_JUSTCREATED, true);
- if (((TerrainObjectTypePtr)objType)->subType == TERROBJ_TREE)
- {
- //-------------------------------------------------------------
- // The appearance is initialized here using data from the type
- // Need an MLR appearance class
- char *appearanceName = objType->getAppearanceTypeName();
- //--------------------------------------------------------------
- // New code!!!
- // We need to append the sprite type to the appearance num now.
- // The MechEdit tool does not assume a sprite type, nor should it.
- // MechCmdr2 features much simpler objects which only use 1 type of sprite!
- long appearanceType = (TREED_TYPE << 24);
- AppearanceTypePtr terrainObjectAppearanceType = appearanceTypeList->getAppearance(appearanceType,appearanceName);
- if (!terrainObjectAppearanceType)
- {
- //------------------------------------------------------
- // LOAD a dummy appearance until real ones are available
- // for this building!
- terrainObjectAppearanceType = appearanceTypeList->getAppearance(appearanceType,"TREE");
- gosASSERT(terrainObjectAppearanceType != NULL);
- }
-
- appearance = new TreeAppearance;
- gosASSERT(appearance != NULL);
- appearance->init((TreeAppearanceType*)terrainObjectAppearanceType, (GameObjectPtr)this);
- }
- else
- {
- //-------------------------------------------------------------
- // The appearance is initialized here using data from the type
- // Need an MLR appearance class
- char *appearanceName = objType->getAppearanceTypeName();
- //--------------------------------------------------------------
- // New code!!!
- // We need to append the sprite type to the appearance num now.
- // The MechEdit tool does not assume a sprite type, nor should it.
- // MechCmdr2 features much simpler objects which only use 1 type of sprite!
- long appearanceType = (BLDG_TYPE << 24);
- AppearanceTypePtr terrainObjectAppearanceType = appearanceTypeList->getAppearance(appearanceType,appearanceName);
- if (!terrainObjectAppearanceType)
- {
- //------------------------------------------------------
- // LOAD a dummy appearance until real ones are available
- // for this building!
- terrainObjectAppearanceType = appearanceTypeList->getAppearance(appearanceType,"TESTOBJ");
- }
-
- appearance = new BldgAppearance;
- gosASSERT(appearance != NULL);
- //--------------------------------------------------------------
- // The only appearance type for buildings is MLR_APPEARANCE.
- gosASSERT(terrainObjectAppearanceType->getAppearanceClass() == BLDG_TYPE);
-
- appearance->init((BldgAppearanceType*)terrainObjectAppearanceType, (GameObjectPtr)this);
- }
- if (objType->getExtentRadius() > 0.0)
- setTangible(true);
- objectClass = TERRAINOBJECT;
- switch (((TerrainObjectTypePtr)objType)->subType) {
- case TERROBJ_NONE:
- if (((TerrainObjectTypePtr)objType)->getDamageLevel() == 0.0) {
- //--------------------------------------------------------
- // We are already destroyed. Used for extraction Markers
- setTangible(false);
- setStatus(OBJECT_STATUS_DESTROYED);
- }
- break;
- case TERROBJ_TREE:
- objectClass = TREE;
- setFlag(OBJECT_FLAG_DAMAGED, false);
- break;
- case TERROBJ_BRIDGE:
- case TERROBJ_FOREST:
- case TERROBJ_WALL_HEAVY:
- case TERROBJ_WALL_MEDIUM:
- case TERROBJ_WALL_LIGHT:
- setTangible(false);
- objectClass = BRIDGE;
- break;
- }
- }
- //---------------------------------------------------------------------------
- void TerrainObject::killFire (void) {
- }
- //---------------------------------------------------------------------------
- void TerrainObject::lightOnFire (float timeToBurn)
- {
- }
- #define DUST_POOF_ID 32
- //---------------------------------------------------------------------------
- long TerrainObject::handleWeaponHit (WeaponShotInfoPtr shotInfo, bool addMultiplayChunk) {
- if (!shotInfo)
- return(NO_ERR);
- if (addMultiplayChunk)
- MPlayer->addWeaponHitChunk(this, shotInfo);
- if (!getFlag(OBJECT_FLAG_DAMAGED))
- {
- float curDamage = getDamage();
- TerrainObjectTypePtr type = (TerrainObjectTypePtr)getObjectType();
- switch (type->subType)
- {
- case TERROBJ_NONE:
- curDamage += shotInfo->damage;
- if (curDamage > type->getDamageLevel())
- curDamage = type->getDamageLevel();
- setDamage(curDamage);
-
- if (curDamage >= type->getDamageLevel())
- {
- setFlag(OBJECT_FLAG_DAMAGED, true);
- curDamage = type->getDamageLevel();
- setStatus(OBJECT_STATUS_DESTROYED);
- setTangible(false);
- appearance->markLOS(true);
- appearance->setObjStatus(OBJECT_STATUS_DESTROYED);
- appearance->setLightsOut(true);
- appearance->recalcBounds();
- appearance->update();
- appearance->markLOS();
-
- if (!shotInfo->attackerWID && (shotInfo->masterId == -1)) //Somebody stepped on me.
- {
- //--------------------------------------------
- //Play a Dust Poof.
- if (useNonWeaponEffects)
- {
- unsigned flags = gosFX::Effect::ExecuteFlag;
-
- Check_Object(gosFX::EffectLibrary::Instance);
- gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectName(DUST_POOF_ID));
-
- if (gosEffectSpec)
- {
- bldgDustPoofEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
- gosASSERT(bldgDustPoofEffect != NULL);
- }
-
- MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
- }
-
- if (bldgDustPoofEffect)
- {
- Stuff::Point3D actualPosition;
- Stuff::LinearMatrix4D shapeOrigin;
- Stuff::LinearMatrix4D localToWorld;
-
- actualPosition.x = -position.x;
- actualPosition.y = position.z;
- actualPosition.z = position.y;
-
- shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
- shapeOrigin.BuildTranslation(actualPosition);
-
- gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
- bldgDustPoofEffect->Start(&info);
- }
- }
- }
- break;
- case TERROBJ_TREE:
- setDamage(curDamage + 1.0);
-
- if (curDamage > type->getDamageLevel())
- {
- setFlag(OBJECT_FLAG_DAMAGED, true);
- curDamage = type->getDamageLevel();
- setStatus(OBJECT_STATUS_DESTROYED);
- appearance->markLOS(true);
- appearance->setObjStatus(OBJECT_STATUS_DESTROYED);
- appearance->setLightsOut(true);
- appearance->recalcBounds();
- appearance->update();
- appearance->markLOS();
- }
- break;
- case TERROBJ_FOREST:
- {
- curDamage += shotInfo->damage;
- if (curDamage >= type->getDamageLevel())
- {
- type->createExplosion(position, 0, 0);
- setStatus(OBJECT_STATUS_DESTROYED);
- openSubAreas();
- }
- setDamage(curDamage);
- }
- break;
- case TERROBJ_WALL_HEAVY:
- case TERROBJ_WALL_MEDIUM:
- case TERROBJ_WALL_LIGHT:
- curDamage += shotInfo->damage;
- if (curDamage >= type->getDamageLevel())
- {
- type->createExplosion(position, 0, 0);
- setStatus(OBJECT_STATUS_DESTROYED);
- if (type->subType == TERROBJ_WALL_LIGHT)
- soundSystem->playDigitalSample(BREAKINGFENCE, getPosition(), true);
- }
- setDamage(curDamage);
- break;
- }
- }
-
- return(NO_ERR);
- }
- //---------------------------------------------------------------------------
- void TerrainObject::setTerrainPosition (const Stuff::Vector3D& position, const Stuff::Vector2DOf<long>& numbers)
- {
- setPosition( position );
-
- vertexNumber = numbers.x;
- blockNumber = numbers.y;
- }
- void TerrainObject::setRotation( float rot )
- {
- rotation = rot;
- ((ObjectAppearance*)appearance)->rotation = rot;
- }
- //---------------------------------------------------------------------------
- void TerrainObject::calcCellFootprint (Stuff::Vector3D& pos) {
- short cellList[MAX_CELL_COORDS];
- cellList[0] = MAX_CELL_COORDS;
- long numCoords = appearance->calcCellsCovered(pos, cellList);
- long minRow = 10000;
- long minCol = 10000;
- long maxRow = 0;
- long maxCol = 0;
- long curCoord = 0;
- while (curCoord < numCoords) {
- if (cellList[curCoord] < minRow)
- minRow = cellList[curCoord];
- if (cellList[curCoord] > maxRow)
- maxRow = cellList[curCoord];
- curCoord++;
- if (cellList[curCoord] < minCol)
- minCol = cellList[curCoord];
- if (cellList[curCoord] > maxCol)
- maxCol = cellList[curCoord];
- curCoord++;
- }
-
- if (numCoords)
- {
- cellFootprint[0] = minRow;
- cellFootprint[1] = minCol;
- cellFootprint[2] = maxRow;
- cellFootprint[3] = maxCol;
- land->cellToWorld(cellFootprint[0], cellFootprint[1], vectorFootprint[0]);
- land->cellToWorld(cellFootprint[0], cellFootprint[3], vectorFootprint[1]);
- land->cellToWorld(cellFootprint[2], cellFootprint[3], vectorFootprint[2]);
- land->cellToWorld(cellFootprint[2], cellFootprint[1], vectorFootprint[3]);
- }
- else
- {
- cellFootprint[0] = 0;
- cellFootprint[1] = 0;
- cellFootprint[2] = 0;
- cellFootprint[3] = 0;
- vectorFootprint[0].Zero();
- vectorFootprint[1].Zero();
- vectorFootprint[2].Zero();
- vectorFootprint[3].Zero();
- }
- }
- //---------------------------------------------------------------------------
- long TerrainObject::getLineOfSightNodes (long eyeCellRow, long eyeCellCol, long* cells) {
- cells[0] = cellFootprint[0];
- cells[1] = cellFootprint[1];
- cells[2] = cellFootprint[0];
- cells[3] = cellFootprint[3];
- cells[4] = cellFootprint[2];
- cells[5] = cellFootprint[3];
- cells[6] = cellFootprint[2];
- cells[7] = cellFootprint[1];
- return(4);
- }
- //---------------------------------------------------------------------------
- void TerrainObject::calcSubAreas (long numCells, short cells[MAX_GAME_OBJECT_CELLS][2]) {
- numCellsCovered = numCells;
- if (numCellsCovered) {
- cellsCovered = (short*)systemHeap->Malloc(4 * numCellsCovered);
- if (cellsCovered) {
- short* curCoord = cellsCovered;
- for (long j = 0; j < numCellsCovered; j++) {
- *curCoord++ = cells[j][0];
- *curCoord++ = cells[j][1];
- }
- }
-
- numSubAreas0 = 0;
- short* curCoord = cellsCovered;
- for (long i = 0; i < numCellsCovered; i++)
- {
- long r = *curCoord++;
- long c = *curCoord++;
- long area = GlobalMoveMap[0]->calcArea(r, c);
- bool addIt = true;
- for (long j = 0; j < numSubAreas0; j++)
- if (subAreas0[j] == area)
- {
- addIt = false;
- break;
- }
- if (addIt)
- {
- if (!subAreas0)
- {
- subAreas0 = (short *)ObjectTypeManager::objectCache->Malloc(sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- memset(subAreas0,0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- }
- subAreas0[numSubAreas0++] = area;
- }
- }
- numSubAreas1 = 0;
- curCoord = cellsCovered;
- for (i = 0; i < numCellsCovered; i++)
- {
- long r = *curCoord++;
- long c = *curCoord++;
- long area = GlobalMoveMap[1]->calcArea(r, c);
- bool addIt = true;
- for (long j = 0; j < numSubAreas1; j++)
- if (subAreas1[j] == area)
- {
- addIt = false;
- break;
- }
- if (addIt)
- {
- if (!subAreas1)
- {
- subAreas1 = (short *)ObjectTypeManager::objectCache->Malloc(sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- memset(subAreas1,0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- }
- subAreas1[numSubAreas1++] = area;
- }
- }
- for (i = 0; i < numSubAreas0; i++)
- GlobalMoveMap[0]->setAreaOwnerWID(subAreas0[i], getWatchID());
- for (i = 0; i < numSubAreas1; i++)
- GlobalMoveMap[1]->setAreaOwnerWID(subAreas1[i], getWatchID());
- }
- }
- //---------------------------------------------------------------------------
- void TerrainObject::markMoveMap (bool passable) {
-
- short* curCoord = cellsCovered;
- for (long i = 0; i < numCellsCovered; i++) {
- long r = *curCoord++;
- long c = *curCoord++;
- GameMap->setPassable(r, c, passable);
- if (passable)
- GameMap->setLocalHeight(r, c, 0.0f);
- }
- }
- //---------------------------------------------------------------------------
- void TerrainObject::openSubAreas (void) {
- markMoveMap(true);
- for (long i = 0; i < numSubAreas0; i++)
- GlobalMoveMap[0]->openArea(subAreas0[i]);
- for (i = 0; i < numSubAreas1; i++)
- GlobalMoveMap[1]->openArea(subAreas1[i]);
- }
- //---------------------------------------------------------------------------
- void TerrainObject::closeSubAreas (void) {
- markMoveMap(false);
- for (long i = 0; i < numSubAreas0; i++)
- GlobalMoveMap[0]->closeArea(subAreas0[i]);
- for (i = 0; i < numSubAreas1; i++)
- GlobalMoveMap[1]->closeArea(subAreas1[i]);
- }
- //---------------------------------------------------------------------------
- void TerrainObject::setSubAreasTeamId (long id) {
- for (long i = 0; i < numSubAreas0; i++)
- GlobalMoveMap[0]->setAreaTeamID(subAreas0[i], id);
- for (i = 0; i < numSubAreas1; i++)
- GlobalMoveMap[1]->setAreaTeamID(subAreas1[i], id);
- }
- //---------------------------------------------------------------------------
- bool TerrainObject::calcAdjacentAreaCell (long moveLevel, long areaID, long& adjRow, long& adjCol) {
- if (areaID == -1) {
- short* curCoord = cellsCovered;
- for (long i = 0; i < numCellsCovered; i++) {
- long cellRow = *curCoord++;
- long cellCol = *curCoord++;
- long adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow - 1, cellCol);
- if (adjArea > -1) {
- adjRow = cellRow - 1;
- adjCol = cellCol;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow, cellCol + 1);
- if (adjArea > -1) {
- adjRow = cellRow;
- adjCol = cellCol + 1;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow + 1, cellCol);
- if (adjArea > -1) {
- adjRow = cellRow + 1;
- adjCol = cellCol;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow, cellCol - 1);
- if (adjArea > -1) {
- adjRow = cellRow;
- adjCol = cellCol - 1;
- return(true);
- }
- }
- }
- else {
- short* curCoord = cellsCovered;
- for (long i = 0; i < numCellsCovered; i++) {
- long cellRow = *curCoord++;
- long cellCol = *curCoord++;
- long adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow - 1, cellCol);
- if (adjArea == areaID) {
- adjRow = cellRow - 1;
- adjCol = cellCol;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow, cellCol + 1);
- if (adjArea == areaID) {
- adjRow = cellRow;
- adjCol = cellCol + 1;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow + 1, cellCol);
- if (adjArea == areaID) {
- adjRow = cellRow + 1;
- adjCol = cellCol;
- return(true);
- }
- adjArea = GlobalMoveMap[moveLevel]->calcArea(cellRow, cellCol - 1);
- if (adjArea == areaID) {
- adjRow = cellRow;
- adjCol = cellCol - 1;
- return(true);
- }
- }
- }
- return(false);
- }
- //***************************************************************************
- void TerrainObject::Save (PacketFilePtr file, long packetNum)
- {
- TerrainObjectData data;
- CopyTo(&data);
- //PacketNum incremented in ObjectManager!!
- file->writePacket(packetNum,(MemoryPtr)&data,sizeof(TerrainObjectData),STORAGE_TYPE_ZLIB);
- }
- //***************************************************************************
- void TerrainObject::CopyTo (TerrainObjectData *data)
- {
- data->damage = damage;
- data->vertexNumber = vertexNumber;
- data->blockNumber = blockNumber;
- data->pitchAngle = pitchAngle;
- data->fallRate = fallRate;
- data->powerSupply = powerSupply;
- memcpy(data->cellFootprint,cellFootprint,sizeof(short) * 4);
- memcpy(data->vectorFootprint,vectorFootprint,sizeof(Stuff::Vector3D) * 4);
- data->numSubAreas0 = numSubAreas0;
- data->numSubAreas1 = numSubAreas1;
- if (subAreas0)
- memcpy(data->subAreas0,subAreas0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- else
- memset(data->subAreas0,0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- if (subAreas1)
- memcpy(data->subAreas1,subAreas1,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- else
- memset(data->subAreas1,0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- data->listID = listID;
- data->numCellsCovered = numCellsCovered;
- if (numCellsCovered >= 162)
- STOP(("Object %d covers too many cells in Save/Load!!",getObjectType()->getObjTypeNum()));
- memcpy(data->cellsCovered,cellsCovered, sizeof(short) * numCellsCovered * 2);
- GameObject::CopyTo(dynamic_cast<GameObjectData *>(data));
- }
- //---------------------------------------------------------------------------
- void TerrainObject::Load (TerrainObjectData *data)
- {
- GameObject::Load(dynamic_cast<GameObjectData *>(data));
- damage = data->damage;
- vertexNumber = data->vertexNumber;
- blockNumber = data->blockNumber;
- pitchAngle = data->pitchAngle;
- fallRate = data->fallRate;
- powerSupply = data->powerSupply;
- memcpy(cellFootprint,data->cellFootprint,sizeof(short) * 4);
- memcpy(vectorFootprint,data->vectorFootprint,sizeof(Stuff::Vector3D) * 4);
- numSubAreas0 = data->numSubAreas0;
- numSubAreas1 = data->numSubAreas1;
- if (numSubAreas0)
- {
- subAreas0 = (short *)ObjectTypeManager::objectCache->Malloc(sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- memcpy(subAreas0,data->subAreas0,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- }
- if (numSubAreas1)
- {
- subAreas1 = (short *)ObjectTypeManager::objectCache->Malloc(sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- memcpy(subAreas1,data->subAreas1,sizeof(short) * MAX_SPECIAL_SUB_AREAS);
- }
- listID = data->listID;
- numCellsCovered = data->numCellsCovered;
- if (numCellsCovered)
- {
- cellsCovered = (short*)systemHeap->Malloc(sizeof(short) * numCellsCovered * 2);
- memcpy(cellsCovered, data->cellsCovered,sizeof(short) * numCellsCovered * 2);
- }
- }
- //***************************************************************************
|