//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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 of the License, or // (at your option) any later version. // // Scorched3D 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 Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include static inline float approx_distance(float dx, float dy) { float approx = (dx * dx) + (dy * dy); return approx; } LandscapeObjects::LandscapeObjects() { } LandscapeObjects::~LandscapeObjects() { } void LandscapeObjects::clearGroups() { // Groups std::map::iterator itor; for (itor = groups_.begin(); itor != groups_.end(); itor++) { LandscapeObjectsGroupEntry *entry = (*itor).second; delete entry; } groups_.clear(); } LandscapeObjectsGroupEntry *LandscapeObjects::getGroup( const char *name, HeightMap *create) { std::map::iterator findItor = groups_.find(name); if (findItor != groups_.end()) { return (*findItor).second; } if (create) { LandscapeObjectsGroupEntry *entry = new LandscapeObjectsGroupEntry(*create); groups_[name] = entry; return entry; } return 0; } void LandscapeObjects::draw(bool shadowView) { unsigned int wantedState = GLState::BLEND_ON | GLState::DEPTH_ON; if (!shadowView) { wantedState |= GLState::TEXTURE_ON; bool vertexLighting = OptionsDisplay::instance()->getNoModelLighting(); if (!vertexLighting) { wantedState |= GLState::NORMALIZE_ON | GLState::LIGHTING_ON | GLState::LIGHT1_ON; } } GLState state(wantedState); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.00f); Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos(); std::multimap::iterator itor = entries_.begin(); std::multimap::iterator enditor = entries_.end(); for (; itor != enditor; itor++) { LandscapeObjectsEntry *entry = (*itor).second; float distance = approx_distance( cameraPos[0] - entry->position[0], cameraPos[1] - entry->position[1]); entry->render(distance); } glDisable(GL_ALPHA_TEST); } void LandscapeObjects::simulate(float frameTime) { std::multimap::iterator itor = entries_.begin(); std::multimap::iterator enditor = entries_.end(); for (; itor != enditor; itor++) { LandscapeObjectsEntry *entry = (*itor).second; entry->simulate(frameTime); } } static inline unsigned int pointToUInt(unsigned int x, unsigned int y) { return (x << 16) | (y & 0xffff); } void LandscapeObjects::generate(RandomGenerator &generator, LandscapePlace &place, ScorchedContext &context, unsigned int &playerId, ProgressCounter *counter) { if (counter) counter->setNewOp("Populating Landscape"); // Generate all the objects using the objects definitions for (unsigned int i=0; icreateObjects(context, generator, playerId, counter); } } void LandscapeObjects::addObject(unsigned int x, unsigned int y, LandscapeObjectsEntry *entry) { // Add the entry unsigned int point = pointToUInt(x, y); entries_.insert( std::pair(point, entry)); } void LandscapeObjects::removeAllObjects() { // Clear any current objects std::multimap::iterator itor = entries_.begin(); std::multimap::iterator enditor = entries_.end(); for (; itor != enditor; itor++) { LandscapeObjectsEntry *entry = (*itor).second; delete entry; } entries_.clear(); // Make sure all groups are cleared clearGroups(); getShadows().clear(); } void LandscapeObjects::removeObjects( ScorchedContext &context, unsigned int x, unsigned int y, unsigned int r, unsigned int playerId) { for (unsigned int a=x-r; a<=x+r; a++) { for (unsigned int b=y-r; b<=y+r; b++) { unsigned int point = pointToUInt(a, b); std::multimap::iterator lower = entries_.lower_bound(point); std::multimap::iterator upper = entries_.upper_bound(point); std::multimap::iterator iter; for (iter = lower; iter != upper; iter++) { LandscapeObjectsEntry *entry = (*iter).second; if (playerId != 0 && entry->removeaction.c_str()[0] && 0 != strcmp(entry->removeaction.c_str(), "none")) { Accessory *accessory = context.accessoryStore->findByPrimaryAccessoryName( entry->removeaction.c_str()); if (accessory && accessory->getAction()->getType() == AccessoryPart::AccessoryWeapon) { Weapon *weapon = (Weapon *) accessory->getAction(); weapon->fireWeapon(context, playerId, entry->position, Vector::nullVector); } } removeFromGroups(entry); delete entry; } entries_.erase(lower, upper); } } } void LandscapeObjects::burnObjects( ScorchedContext &context, unsigned int x, unsigned int y, unsigned int playerId) { unsigned int point = pointToUInt((unsigned int)x, (unsigned int)y); std::multimap::iterator lower = entries_.lower_bound(point); std::multimap::iterator upper = entries_.upper_bound(point); std::multimap::iterator iter; for (iter = lower; iter != upper; iter++) { LandscapeObjectsEntry *entry = (*iter).second; if (!entry->burnt) { entry->burnt = true; if (playerId != 0 && entry->burnaction.c_str()[0] && 0 != strcmp(entry->burnaction.c_str(), "none")) { Accessory *accessory = context.accessoryStore->findByPrimaryAccessoryName( entry->burnaction.c_str()); if (accessory && accessory->getAction()->getType() == AccessoryPart::AccessoryWeapon) { Weapon *weapon = (Weapon *) accessory->getAction(); weapon->fireWeapon(context, playerId, entry->position, Vector::nullVector); } } } } } void LandscapeObjects::removeFromGroups(LandscapeObjectEntryBase *obj) { if (obj->groups.empty()) return; std::vector::iterator itor; for (itor = obj->groups.begin(); itor != obj->groups.end(); itor++) { LandscapeObjectsGroupEntry *entry = (*itor); entry->removeObject(obj); } }