/* * psactionlocationinfo.cpp * * Copyright (C) 2005 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * Credits : * Michael Cummings * * This program 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 (version 2 * of the License). * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Creation Date: 1/20/2005 * Description : Container for the action_locations db table. * */ #include #include #include "imesh/object.h" #include #include "iengine/mesh.h" #include #include #include #include #include #include "util/psxmlparser.h" #include "util/log.h" #include "util/psstring.h" #include "pssectorinfo.h" #include "util/serverconsole.h" #include "../globals.h" #include "../psserver.h" #include "../cachemanager.h" #include "../gem.h" #include "psactionlocationinfo.h" // Definition of the itempool for psItemStats PoolAllocator psActionLocation::actionpool; void *psActionLocation::operator new(size_t allocSize) { CS_ASSERT( allocSize <= sizeof( psActionLocation ) ); return (void *)actionpool.CallFromNew(); } void psActionLocation::operator delete(void *releasePtr) { actionpool.CallFromDelete( (psActionLocation *)releasePtr ); } psActionLocation::psActionLocation() : gemAction( NULL ) { id = 0; master_id = 0; name = ""; sectorname = ""; meshname = ""; polygon.Format("%d", 0); position = csVector3(0.0F); radius = 0.0F; triggertype = ""; responsetype = ""; response = ""; isGameBoard = false; } psActionLocation::~psActionLocation() { } bool psActionLocation::Load(iResultRow& row) { id = row.GetInt( "id" ); master_id = row.GetInt( "master_id" ); name = row[ "name" ]; sectorname = row[ "sectorname" ]; meshname = row[ "meshname" ]; polygon.Format("%d",row.GetInt( "polygon" )); radius = row.GetFloat( "radius" ); float x = row.GetFloat( "pos_x" ); float y = row.GetFloat( "pos_y" ); float z = row.GetFloat( "pos_z" ); position = csVector3( x, y, z ); if ( !master_id ) { triggertype = row[ "triggertype" ]; responsetype = row[ "responsetype" ]; response = row[ "response" ]; } else { responsetype = row[ "master_triggertype" ]; responsetype = row[ "master_responsetype" ]; response = row[ "master_response" ]; } InitIsGameBoard(); return true; } bool psActionLocation::Load( csRef root ) { csRef topNode; csRef node; node = root->GetNode( "id" ); if ( node ) id = node->GetContentsValueAsInt(); node = root->GetNode( "masterid" ); if ( node ) master_id = node->GetContentsValueAsInt(); node = root->GetNode( "name" ); if ( node ) name = node->GetContentsValue(); node = root->GetNode( "sector" ); if ( node ) sectorname = node->GetContentsValue(); node = root->GetNode( "mesh" ); if ( node ) meshname = node->GetContentsValue(); node = root->GetNode( "polygon" ); if ( node ) polygon = node->GetContentsValue(); topNode = root->GetNode( "position" ); if ( topNode ) { float posx=0.0f, posy=0.0f, posz=0.0f; node = topNode->GetNode( "x" ); if ( node ) posx = node->GetContentsValueAsFloat(); node = topNode->GetNode( "y" ); if ( node ) posy = node->GetContentsValueAsFloat(); node = topNode->GetNode( "z" ); if ( node ) posz = node->GetContentsValueAsFloat(); position = csVector3( posx, posy, posz ); } node = root->GetNode( "radius" ); if ( node ) radius = node->GetContentsValueAsFloat(); node = root->GetNode( "triggertype" ); if ( node ) triggertype = node->GetContentsValue(); node = root->GetNode( "responsetype" ); if ( node ) responsetype = node->GetContentsValue(); node = root->GetNode( "response" ); if ( node ) response = node->GetContentsValue(); InitIsGameBoard(); return true; } bool psActionLocation::Save() { psStringArray fields; const char *fieldnames[]= { "master_id", "name", "sectorname", "meshname", "polygon", "pos_x", "pos_y", "pos_z", "radius", "triggertype", "responsetype", "response" }; fields.FormatPush( "%u", master_id ); fields.Push( name ); fields.Push( sectorname ); fields.Push( meshname ); fields.FormatPush( "%s", polygon.GetData() ); fields.FormatPush( "%f", position.x ); fields.FormatPush( "%f", position.y ); fields.FormatPush( "%f", position.z ); fields.FormatPush( "%f", radius ); //csString escpxml_response = EscpXML(response); if ( !master_id ) { fields.FormatPush( "%s", triggertype.GetData() ); fields.FormatPush( "%s", responsetype.GetData() ); fields.FormatPush( "%s", response.GetData() ); } if ( id == 0 ) // Insert New { size_t newid = Insert( "action_locations" , fieldnames, fields ); if (newid == 0) { Error2("Failed to create new action location. Error %s", db->GetLastError() ); return false; } id = newid; } else { csString idStr; idStr.Format( "%d", id ); if ( !UpdateByKey( "action_locations", "id", idStr, fieldnames, fields ) ) { Error3("Failed to update action location %u. Error %s", id, db->GetLastError() ); return false; } } return true; } bool psActionLocation::Delete() { csString id; csString key(""); key.Append( id ); if ( !DeleteByKey( "action_locations", "id", key.GetData() ) ) { Error3("Failed to delete action location %u. Error %s", id.GetData(), db->GetLastError() ); return false; } return true; } int psActionLocation::IsMatch( psActionLocation *compare ) { int result = 0; // match on sectorName and Mesh if ( ( compare->sectorname == sectorname ) && ( compare->meshname == meshname ) ) { result++; if ( polygon != "0" ) { if ( compare->polygon == polygon ) { result++; if ( !position.IsZero() ) { if ( csSquaredDist::PointPoint( compare->position, position ) < (radius * radius) ) { result++; } else // If position specified but does not match , no match { result = 0; } } } else // If polygon specified but does not match , no match { result = 0; } } } return result; } void psActionLocation::SetGemObject( gemActionLocation *gemAction ) { this->gemAction = gemAction; } gemActionLocation *psActionLocation::GetGemObject( void ) { return this->gemAction; } void psActionLocation::GetLocationInWorld(const char **sectorname, float &loc_x, float &loc_y, float &loc_z, float &loc_yrot) { *sectorname = this->sectorname.GetData(); loc_x = this->position.x; loc_y = this->position.y; loc_z = this->position.z; loc_yrot = 0; } void psActionLocation::Send( int clientnum) { this->gemAction->Send( clientnum ); } uint32 psActionLocation::GetInstanceIDOfContainer() { if ( response.StartsWith( "", false ) ) { // load response into XML doc csRef doc = ParseString( response ); if(!doc) { Error1("Parse error in action response"); return (uint32)-1; } csRef root = doc->GetRoot(); if(!root) { Error1("No XML root in action response"); return (uint32)-1; } csRef topNode = root->GetNode( "Examine" ); if(!topNode) { Error1("No tag in action response"); return (uint32)-1; } csRef containerNode, descriptionNode; containerNode = topNode->GetNode( "Container" ); if ( containerNode ) { uint32 instance_id = (uint32)containerNode->GetAttributeValueAsInt( "ID" ); return instance_id; } } return (uint32)-1; } void psActionLocation::InitIsGameBoard() { isGameBoard = false; if (response.StartsWith( "", false)) { csRef doc = ParseString(response); if (!doc) { Error1("Parse error in action response"); return; } csRef root = doc->GetRoot(); if (!root) { Error1("No XML root in action response"); return; } csRef topNode = root->GetNode("Examine"); if (!topNode) { Error1("No tag in action response"); return; } csRef boardNode; boardNode = topNode->GetNode("GameBoard"); isGameBoard = boardNode != NULL; } } csString psActionLocation::ToXML() const { csString xml; const char* formatXML = "%u%u%s%s%s%s%f%f%f%f%s%s%s"; csString escpxml_name = EscpXML(name); csString escpxml_sectorname = EscpXML(sectorname); csString escpxml_meshname = EscpXML(meshname); csString escpxml_polygon = EscpXML(polygon); csString escpxml_triggertype = EscpXML(triggertype); csString escpxml_responsetype = EscpXML(responsetype); csString escpxml_response = EscpXML(response); xml.Format( formatXML, id, master_id, escpxml_name.GetData(), escpxml_sectorname.GetData(), escpxml_meshname.GetData(), escpxml_polygon.GetData(), position.x, position.y, position.z, radius, escpxml_triggertype.GetData(), escpxml_responsetype.GetData(), escpxml_response.GetData() ); return xml; } // DB Helper Operations unsigned int psActionLocation::Insert( const char *table, const char **fieldnames, psStringArray& fieldvalues ) { csString command; int count = fieldvalues.Length(); int i; command = "INSERT INTO "; command.Append(table); command.Append(" ("); for (i=0;i0) command.Append(","); command.Append(fieldnames[i]); } command.Append(") VALUES ("); for (i=0;i0) command.Append(","); if (fieldvalues[i]!=NULL) { command.Append("'"); csString escape; db->Escape( escape, fieldvalues[i] ); command.Append(escape); command.Append("'"); } else { command.Append("NULL"); } } command.Append(")"); if (db->Command(command)!=1) return 0; return db->GetLastInsertID(); } bool psActionLocation::UpdateByKey( const char *table, const char *idname, const char *idvalue, const char **fieldnames, psStringArray& fieldvalues ) { int i; int count = fieldvalues.Length(); csString command; command.Append("UPDATE "); command.Append(table); command.Append(" SET "); for (i=0;i0) command.Append(","); command.Append(fieldnames[i]); if (fieldvalues[i]!=NULL) { command.Append("='"); csString escape; db->Escape(escape, fieldvalues[i]); command.Append(escape); command.Append("'"); } else { command.Append("=NULL"); } } command.Append(" where "); command.Append(idname); command.Append("='"); csString escape; db->Escape( escape, idvalue ); command.Append(escape); command.Append("'"); if (db->Command(command)==QUERY_FAILED) { return false; } return true; } bool psActionLocation::DeleteByKey( const char *table, const char *idname, const char *idvalue ) { csString command; command.Append("DELETE FROM "); command.Append(table); command.Append(" WHERE "); command.Append(idname); command.Append("='"); csString escape; db->Escape( escape, idvalue ); command.Append(escape); command.Append("'"); if (db->Command(command)==QUERY_FAILED) { return false; } return true; }