/** \file landscape.cpp * Landscape interface between the game and NeL */ /* Copyright, 2001 Nevrax Ltd. * * This file is part of NEVRAX SNOWBALLS. * NEVRAX SNOWBALLS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * NEVRAX SNOWBALLS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * You should have received a copy of the GNU General Public License * along with NEVRAX SNOWBALLS; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ // // Includes // #include "nel/misc/types_nl.h" #include #include #include #include "nel/misc/variable.h" #include "nel/misc/command.h" #include "nel/misc/variable.h" #include "nel/misc/debug.h" #include "nel/misc/path.h" #include "nel/misc/i18n.h" #include "nel/misc/config_file.h" #include #include #include #include #include #include #include #include #include #include #include #include "snowballs_client.h" #include "pacs.h" #include "commands.h" #include "mouse_listener.h" #include "physics.h" #include "configuration.h" #include "entities.h" // // Namespaces // using namespace std; using namespace NLMISC; using namespace NL3D; // // Variables // namespace SBCLIENT { /******************************************************************* * GLOBALS * *******************************************************************/ vector InstanceGroups; NLMISC::CVector SunDirection; /******************************************************************* * LANDSCAPE * *******************************************************************/ static UVisualCollisionEntity *_AimingEntity = NULL; static ULight *_Sun = NULL; // // Functions // void cbUpdateLandscape (CConfigFile::CVar &var) { // -- -- split this whole thing up, lol if (var.Name == "FogStart") Driver->setupFog (var.asFloat (), ConfigFile->getVar ("FogEnd").asFloat (), CRGBA(ConfigFile->getVar ("FogColor").asInt (0), ConfigFile->getVar ("FogColor").asInt (1), ConfigFile->getVar ("FogColor").asInt (2))); else if (var.Name == "FogEnd") Driver->setupFog (ConfigFile->getVar ("FogStart").asFloat (), var.asFloat (), CRGBA(ConfigFile->getVar ("FogColor").asInt (0), ConfigFile->getVar ("FogColor").asInt (1), ConfigFile->getVar ("FogColor").asInt (2))); else if (var.Name == "FogColor") Driver->setupFog( ConfigFile->getVar ("FogStart").asFloat (), ConfigFile->getVar ("FogEnd").asFloat (), CRGBA(var.asInt (0), var.asInt (1), var.asInt (2))); else if (var.Name == "FogEnable") { Driver->enableFog(var.asBool()); Driver->setupFog( ConfigFile->getVar("FogStart").asFloat(), ConfigFile->getVar("FogEnd").asFloat(), CRGBA(ConfigFile->getVar("FogColor").asInt(0), ConfigFile->getVar ("FogColor").asInt(1), ConfigFile->getVar ("FogColor").asInt(2))); } else if (var.Name == "SunAmbientColor") { _Sun->setAmbiant (CRGBA (var.asInt(0), var.asInt(1), var.asInt(2))); Driver->setLight (0, *_Sun); } else if (var.Name == "SunDiffuseColor") { _Sun->setDiffuse (CRGBA (var.asInt(0), var.asInt(1), var.asInt(2))); Driver->setLight (0, *_Sun); } else if (var.Name == "SunSpecularColor") { _Sun->setSpecular (CRGBA (var.asInt(0), var.asInt(1), var.asInt(2))); Driver->setLight (0, *_Sun); } else if (var.Name == "SunDirection") { SunDirection.set (var.asFloat(0), var.asFloat(1), var.asFloat(2)); _Sun->setDirection (SunDirection); Driver->setLight (0, *_Sun); } else nlwarning ("Unknown variable update %s", var.Name.c_str()); } static float _LandscapeVision; static float _LandscapeVisionInitial; static void cbMoreLandscapeStuff(CConfigFile::CVar &var) { if (var.Name == "LandscapeTileNear") Landscape->setTileNear(var.asFloat()); else if (var.Name == "LandscapeThreshold") Landscape->setThreshold(var.asFloat()); else if (var.Name == "LandscapeVision") _LandscapeVision = var.asFloat(); else if (var.Name == "LandscapeVisionInitial") _LandscapeVisionInitial = var.asFloat(); else if (var.Name == "LandscapeReceiveShadowMap") Landscape->enableReceiveShadowMap(var.asBool()); else nlwarning("Unknown variable update %s", var.Name.c_str()); } void initLight() { // -- -- sun or whatever light, simple use, doesn't need class yet _Sun = ULight::createLight(); nlassert(_Sun); _Sun->setMode(ULight::DirectionalLight); Driver->enableLight(0); ConfigFile->setCallback("SunAmbientColor", cbUpdateLandscape); ConfigFile->setCallback("SunDiffuseColor", cbUpdateLandscape); ConfigFile->setCallback("SunSpecularColor", cbUpdateLandscape); ConfigFile->setCallback("SunDirection", cbUpdateLandscape); cbUpdateLandscape(ConfigFile->getVar("SunAmbientColor")); cbUpdateLandscape(ConfigFile->getVar("SunDiffuseColor")); cbUpdateLandscape(ConfigFile->getVar("SunSpecularColor")); cbUpdateLandscape(ConfigFile->getVar("SunDirection")); } void releaseLight() { // -- -- just data ConfigFile->setCallback("SunAmbientColor", NULL); ConfigFile->setCallback("SunDiffuseColor", NULL); ConfigFile->setCallback("SunSpecularColor", NULL); ConfigFile->setCallback("SunDirection", NULL); delete _Sun; _Sun = NULL; } void initLandscape() { ConfigFile->setCallback ("FogStart", cbUpdateLandscape); ConfigFile->setCallback ("FogEnd", cbUpdateLandscape); ConfigFile->setCallback ("FogColor", cbUpdateLandscape); ConfigFile->setCallback ("FogEnable", cbUpdateLandscape); cbUpdateLandscape (ConfigFile->getVar ("FogStart")); cbUpdateLandscape (ConfigFile->getVar ("FogEnd")); cbUpdateLandscape (ConfigFile->getVar ("FogColor")); cbUpdateLandscape (ConfigFile->getVar ("FogEnable")); // -- -- start of init for "instance groups loaded from config" CConfigFile::CVar igv = ConfigFile->getVar("InstanceGroups"); for (uint32 i = 0; i < igv.size (); i++) { UInstanceGroup *inst = UInstanceGroup::createInstanceGroup (igv.asString (i)); if (inst == NULL) { nlwarning ("Instance group '%s' not found", igv.asString (i).c_str ()); } else { inst->addToScene (*Scene); InstanceGroups.push_back (inst); } } // -- -- start of init for "landscape around camera that gets data from config" // create the landscape nlassert(!Landscape); Landscape = Scene->createLandscape(); // load the bank files Landscape->loadBankFiles( CPath::lookup(ConfigFile->getVar("LandscapeBankName").asString()), CPath::lookup(ConfigFile->getVar("LandscapeFarBankName").asString())); Landscape->invalidateAllTiles(); // -- -- this doesn't do anything useful //// setup the zone path //Landscape->setZonePath(ConfigFile->getVar("DataPath").asString() + "zones/"); // -- -- do this when character appears or does far teleport //// and eventually, load the zones around the starting point. //Landscape->loadAllZonesAround (CVector(ConfigFile->getVar("StartPoint").asFloat(0), // ConfigFile->getVar("StartPoint").asFloat(1), // ConfigFile->getVar("StartPoint").asFloat(2)), // 1000.0f); // color of the landscape shadow CRGBA diffuse( ConfigFile->getVar("LandscapeDiffuseColor").asInt(0), ConfigFile->getVar("LandscapeDiffuseColor").asInt(1), ConfigFile->getVar("LandscapeDiffuseColor").asInt(2)); CRGBA ambient( ConfigFile->getVar("LandscapeAmbiantColor").asInt(0), ConfigFile->getVar("LandscapeAmbiantColor").asInt(1), ConfigFile->getVar("LandscapeAmbiantColor").asInt(2)); Landscape->setupStaticLight( diffuse, ambient, ConfigFile->getVar("LandscapeMultiplyFactor").asFloat()); CConfiguration::setAndCallback("LandscapeReceiveShadowMap", cbMoreLandscapeStuff); CConfiguration::setAndCallback("LandscapeTileNear", cbMoreLandscapeStuff); CConfiguration::setAndCallback("LandscapeThreshold", cbMoreLandscapeStuff); CConfiguration::setAndCallback("LandscapeVision", cbMoreLandscapeStuff); CConfiguration::setAndCallback("LandscapeVisionInitial", cbMoreLandscapeStuff); } void releaseLandscape() { CConfiguration::dropCallback("LandscapeReceiveShadowMap"); CConfiguration::dropCallback("LandscapeTileNear"); CConfiguration::dropCallback("LandscapeThreshold"); CConfiguration::dropCallback("LandscapeVision"); CConfiguration::dropCallback("LandscapeVisionInitial"); // release config'd instancegroups for (vector::iterator it(InstanceGroups.begin()), end(InstanceGroups.end()); it != end; ++it) { (*it)->removeFromScene(*Scene); delete (*it); } InstanceGroups.clear(); // -- -- release for cameralandscape Scene->deleteLandscape(Landscape); Landscape = NULL; ConfigFile->setCallback("FogStart", NULL); ConfigFile->setCallback("FogEnd", NULL); ConfigFile->setCallback("FogColor", NULL); ConfigFile->setCallback("FogEnable", NULL); } void initAiming() { // -- -- belongs in "camera that follows entity and can be used to aim" // -- -- random note: is an extension of "camera that follows entity" // Create an aiming entity _AimingEntity = VisualCollisionManager->createEntity(); _AimingEntity->setCeilMode(true); } void releaseAiming() { // -- -- belongs in CAimingEntityCamera VisualCollisionManager->deleteEntity(_AimingEntity); } // -- -- mix with following bit of code for higher accuracy //NLMISC::CVector CSceneryMouse::getLandscape() //{ // if (_LandscapeCached) return _LandscapeCache; // CViewport v = _Driver->getViewport(); // CVector pos, dir; -- -- random note: this code gets the landscape position where the mouse is pointing at // v.getRayWithPoint(_X * v.getWidth(), _Y * v.getHeight(), pos, dir, _Camera.getMatrix(), _Camera.getFrustum()); // dir.normalize(); // dir *= 50; // -- -- float rc = _Landscape->getRayCollision(pos, pos + dir); // -- -- _LandscapeCache = pos + (rc * dir); // _LandscapeCached = true; // return _LandscapeCache; //} // -- -- if higher than 50 or something, use code below CVector getTarget(const CVector &start, const CVector &step, uint numSteps) { CVector testPos = start; uint i; for (i=0; isnapToGround(snapped, normal) && (testPos.z-snapped.z)*normal.z < 0.0f) { testPos -= step*0.5f; break; } testPos += step; } return testPos; } CVector getTarget(CTrajectory &trajectory, TLocalTime dtSteps, uint numSteps) { TLocalTime t = trajectory.getStartTime(); CVector testPos; uint i; for (i=0; isnapToGround(snapped, normal) && (testPos.z-snapped.z)*normal.z < 0.0f) { t -= (dtSteps/2); testPos = trajectory.eval(t); break; } t += dtSteps; } return testPos; } void updateLandscape() { // -- -- update for CCameraLandscape // -- -- no need to go to snowballs mouse listener, can probly get this // from a NL3D::UCamera, NLPACS::UMovePrimitive or NL3D::UInstance too. // -- -- random note: make a CControllableMovePrimitiveEntityInstance or something // -- -- should get the player position and not the camera position, // most optimal for camera rotating around player. // load the zones around the viewpoint Landscape->refreshZonesAround( Scene->getCam().getMatrix().getPos(), _LandscapeVision); //_Landscape->refreshZonesAround(MouseListener->getViewMatrix().getPos(), 1000.0f); } void loadAllZonesAround() { /*Landscape->loadAllZonesAround( Scene->getCam().getMatrix().getPos(), _LandscapeVisionInitial);*/ Landscape->loadAllZonesAround(Self->Position, _LandscapeVisionInitial); } /* CVector getTarget(const CVector &start, const CVector &step, uint numSteps) { CVector testPos = start; uint i; for (i=0; isnapToGround(snapped, normal) && (testPos.z-snapped.z)*normal.z < 0.0f) { testPos -= step*0.5f; break; } testPos += step; } return testPos; } */ // -- -- snowballs specific commands, not for the landscape class itself, it assumes using // one landscape, and will get actual landscape from CSnowballsClient instance // -- -- random note: there will only be one instance of CSnowballsClient, // which is the class that takes care of what is currently done in client.cpp //NLMISC_DYNVARIABLE(float,tilenear,"landscape tile near") //{ // if (get) // *pointer = Landscape->getTileNear(); // else // Landscape->setTileNear(*pointer); //} // //NLMISC_DYNVARIABLE(float,threshold,"landscape threshold") //{ // if (get) // *pointer = Landscape->getThreshold(); // else // Landscape->setThreshold(*pointer); //} // //// boost to //NLMISC_COMMAND(boost,"switch landscape parameters between high speed and high quality","0|1") //{ // if (args.size() != 1 ) return false; // if ( args[0]=="1" ) // { // ICommand::execute( "tilenear 5", CommandsLog); // ICommand::execute( "threshold 1", CommandsLog); // } // else // { // ICommand::execute( "tilenear 100", CommandsLog); // ICommand::execute( "threshold 0.01", CommandsLog); // } // return true; //} NLMISC_COMMAND(add_ig, "add instance group", "name") { if (args.size() != 1 ) return false; UInstanceGroup *inst = UInstanceGroup::createInstanceGroup(args[0]); if (inst == NULL) nlwarning("Instance group '%s' not found", args[0].c_str()); else { inst->addToScene(*Scene); InstanceGroups.push_back(inst); } return true; } } /* namespace SBCLIENT */ /* end of file */