Show kmission.cpp syntax highlighted
/*
Copyright (C) 2003, 2004, 2005 by Luca Cappa
Written by Luca Cappa groton@users.sourceforge.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//?? -1 or NULL is for a not used mission parameter.
#include "cssysdef.h"
#include "csutil/sysfunc.h"
#include "csutil/cscolor.h"
#include "csutil/cmdhelp.h"
#include "csutil/cspmeter.h"
#include "csutil/csstring.h"
#include "csutil/scfstr.h"
#include "csutil/dirtyaccessarray.h"
#include "csutil/xmltiny.h"
#include "csutil/array.h"
#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "cstool/collider.h"
#include "iutil/vfs.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iutil/plugin.h"
#include "iutil/string.h"
#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "imesh/thing.h"
#include "imesh/object.h"
#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/natwin.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"
#include "igraphic/imageio.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/conout.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/collider.h"
#include "csgeom/quaterni.h"
#include "csgeom/transfrm.h"
#include "csgeom/math3d_d.h"
#include "csgeom/math3d.h"
#include "igeom/polymesh.h"
#include "igeom/objmodel.h"
#include "imap/loader.h"
#include "iaws/aws.h"
#include "iaws/awscnvs.h"
#include "korientation.h"
#include "kblock.h"
#include "kmap.h"
#include "kblockid.h"
#include "kflags.h"
#include "ksprite3d.h"
#include "kappstate.h"
#include "ske.h"
#include "klandmark.h"
#include "klandmarklist.h"
#include "kutil.h"
#include "kpath.h"
#include "kplayer.h"
#include "kxmlhelper.h"
#include "kmissiontype.h"
//Includes for this file.
#include "kmission.h"
#ifndef NEW_MISSION_DESIGN
//----------------------------------------------------
//KMission
//----------------------------------------------------
SCF_IMPLEMENT_IBASE(KMission)
SCF_IMPLEMENTS_INTERFACE(iKMission)
SCF_IMPLEMENT_IBASE_END
KMission::KMission (const char* p_name, KPosition* p_pos, KPlayer* p_player,
KMap* p_wM, KLandmarkList* p_lML, bool p_collectData) :
m_dataList (p_name), m_collectingData (p_collectData),
m_landmarks (p_lML), m_map (p_wM), m_player (p_player),
m_position (p_pos)
{
SCF_CONSTRUCT_IBASE (0);
CS_ASSERT (0 != p_name);
SetName (p_name);
}
KMission::KMission ()
{
SCF_CONSTRUCT_IBASE (0);
}
KMission::~KMission ()
{
SCF_DESTRUCT_IBASE ();
}
KPosition* KMission::GetInitPosition ()
{
return m_position;
}
void KMission::SetInitPosition (KPosition* p_pos)
{
m_position = p_pos;
}
const char* KMission::GetName ()
{
return m_name->GetData ();
}
void KMission::SetName (const char* p_name)
{
m_name.AttachNew (new scfString (p_name ));
}
KMap* KMission::GetMap ()
{
return m_map;
}
void KMission::SetMap (KMap* p_wM)
{
m_map = p_wM;
}
KLandmarkList* KMission::GetLandmarks ()
{
return m_landmarks;
}
void KMission::SetLandmarks (KLandmarkList* p_lms)
{
m_landmarks = p_lms;
}
KDataList* KMission::GetDataList ()
{
return &m_dataList;
}
bool KMission::GetCollectingData ()
{
return m_collectingData;
}
const KMissionType& KMission::GetMissionType ()
{
{csRef<iKFreeWalkingMission> l_tmp =
SCF_QUERY_INTERFACE (this, iKFreeWalkingMission);
if (0 != l_tmp)
return KMissionType::FREEWALKING;}
{csRef<iKTargetingMission> l_tmp =
SCF_QUERY_INTERFACE (this, iKTargetingMission);
if (l_tmp != NULL)
return KMissionType::TARGETING;}
{csRef<iKPointingTargetMission> l_tmp =
SCF_QUERY_INTERFACE (this, iKPointingTargetMission);
if (l_tmp != NULL)
return KMissionType::POINTINGTARGET;}
{csRef<iKNotFreeWalkingMission> l_tmp =
SCF_QUERY_INTERFACE (this, iKNotFreeWalkingMission);
if (l_tmp != NULL)
return KMissionType::NOTFREEWALKING;}
return KMissionType::INVALID;
}
float KMission::GetMinutes ()
{
if (m_dataList.GetCount () < 1)//if the datalist is empty.
return -1.0f;
return (m_dataList.GetLastSampleTimestamp () / 1000.0f) / 60.0f;//transform msecs to mins.
}
float KMission::GetMeters ()
{
if (m_dataList.GetCount () < 1)//if the datalist is empty.
return -1.0f;
csRef<KData> l_lastData = m_dataList.Get (m_dataList.GetCount () - 1);//get the last el.
return l_lastData->GetMeters ();
}
bool KMission::SaveMissionInfo (iDocumentNode* p_parent)
{
csRef<iDocumentNode> l_kmissionNode = p_parent->CreateNodeBefore
(CS_NODE_ELEMENT, NULL);
l_kmissionNode->SetValue ("Mission");
l_kmissionNode->SetAttribute ("name", GetName());
l_kmissionNode->SetAttribute ("missionType", GetMissionType ().GetName ());
l_kmissionNode->SetAttributeAsFloat ("minutes", GetMinutes ());
l_kmissionNode->SetAttributeAsFloat ("meters", GetMeters ());
//
//Save common info about the mission (Level, InitPos, Map)
m_landmarks->Write (l_kmissionNode);
m_map->Write (l_kmissionNode);
m_position->Write (l_kmissionNode);
//
//Save datas list.
m_dataList.WriteXML (l_kmissionNode);
return true;
}
bool KMission::LoadMissionInfo (iDocumentNode* p_parent)
{
const char* l_value = p_parent->GetValue ();
if (strcmp (l_value, "Mission"))
return false;
SetName (p_parent->GetAttributeValue ("name"));
//
//Load common info about the mission (Landmarks, Map, InitPos).
csRef<iDocumentNode> l_node =
KXMLHelper::FindNode (p_parent, "landmarks_list");
m_landmarks->Read (l_node);
l_node = KXMLHelper::FindNode (p_parent, "level");
m_map->Read (l_node);
l_node = KXMLHelper::FindNode (p_parent, "init_position");
m_position->Read (l_node);
//
//Load datas list.
l_node = KXMLHelper::FindNode (p_parent, "data_list");
m_dataList.ReadXML (l_node);
return true;
}
//??
struct Crap
{
void(*m_callback)(void *);
void* m_arg;
int m_interval;
};
static Crap s_crap;//??
void KMission::StopRecording ()
{
m_scheduler.RemoveCallback (s_crap.m_callback, s_crap.m_arg, s_crap.m_interval);
}
void KMission::StartRecording (int p_intervalMs)
{
m_currentTime = 0;
m_scheduler.AddRepeatCallback (MissionCallback, this, p_intervalMs);
s_crap.m_callback = MissionCallback;
s_crap.m_arg = this;
s_crap.m_interval = p_intervalMs;
//
//??? HACK
//This call below is needed, cause only in this way we register
//a KData with TimeStamp equal to 0 millisecs.
KMission::MissionCallback (this);
}
void KMission::Record (int p_elapsedTimeMs)
{
//dont collect data if not needed!
if (!m_collectingData)
return;
m_currentTime += p_elapsedTimeMs;
m_scheduler.TimePassed (p_elapsedTimeMs);
}
void KMission::MissionCallback (void* p_arg)
{
KMission* l_mission = (KMission*) p_arg;
csVector3 l_position = l_mission->m_player->GetPosition ();
KQuaternion l_hQ = l_mission->m_player->GetHeadAngles ();
KQuaternion l_bQ = l_mission->m_player->GetBodyAngle ();
float l_meters = 0;
if (l_mission->m_dataList.GetCount () > 1)
{
csRef<KData> l_data = l_mission->m_dataList.Get
(l_mission->m_dataList.GetCount () - 1);
l_meters = l_data->GetMeters ();
l_meters += ABS ((l_position - l_data->GetPosition ()).Norm ());
}//if
else
{
KPosition* l_iP = l_mission->GetInitPosition ();
l_meters += ABS ((l_position - l_iP->GetPosition ()).Norm ());
}//else
csVector3 l_vel = l_mission->m_player->m_mov3d.GetVelocity ();
csRef<KData> l_data;
l_data.AttachNew (new KData (l_position, l_bQ, l_hQ,
l_vel, l_meters, l_mission->m_currentTime));
l_mission->m_dataList.Add (l_data);
}
//----------------------------------------------------
//KFreeWalkingMission
//----------------------------------------------------
SCF_IMPLEMENT_IBASE_EXT (KFreeWalkingMission)
SCF_IMPLEMENTS_INTERFACE (iKFreeWalkingMission)
SCF_IMPLEMENT_IBASE_EXT_END
KFreeWalkingMission::KFreeWalkingMission (char* p_name,
KPosition* p_pos,
KPlayer* p_player,
float p_allowedMinutes, KMap* p_wM, KLandmarkList* p_lL,
bool p_collectingData) :
KMission (p_name, p_pos, p_player, p_wM, p_lL,
p_collectingData), m_allowedMinutes (p_allowedMinutes)
{
SCF_CONSTRUCT_IBASE(NULL);
}
KFreeWalkingMission::KFreeWalkingMission()
{
SCF_CONSTRUCT_IBASE(NULL);
}
KFreeWalkingMission::~KFreeWalkingMission()
{
}
float KFreeWalkingMission::GetAllowedMinutes ()
{
return m_allowedMinutes;
}
void KFreeWalkingMission::SetAllowedMinutes (float p_m)
{
m_allowedMinutes = p_m;
}
bool KFreeWalkingMission::WriteAdditionalInfo (iDocumentNode* p_parent)
{
csRef<iDocumentNode> l_kmissionNode = p_parent->CreateNodeBefore (CS_NODE_ELEMENT, NULL);
l_kmissionNode->SetValue ("FreeWalkingMission");
l_kmissionNode->SetAttribute ("name", GetName());
l_kmissionNode->SetAttributeAsFloat ("allowedMinutes", m_allowedMinutes);
return true;
}
bool KFreeWalkingMission::ReadAdditionalInfo (iDocumentNode* p_node)
{
SetName (p_node->GetAttributeValue ("name"));
SetAllowedMinutes (p_node->GetAttributeValueAsFloat ("allowedMinutes"));
return true;
}
//----------------------------------------------------
//KTargetingMission
//----------------------------------------------------
SCF_IMPLEMENT_IBASE_EXT (KTargetingMission)
SCF_IMPLEMENTS_INTERFACE (iKTargetingMission)
SCF_IMPLEMENT_IBASE_EXT_END
KTargetingMission::KTargetingMission (char const* p_name,
KPosition* p_pos,
KPlayer* p_player,
char const* p_targetName,
KPath* p_path, float p_allowedMinutes, KMap* p_wM,
KLandmarkList* p_lL, bool p_collectingData) :
KMission (p_name, p_pos, p_player, p_wM, p_lL,
p_collectingData), m_path (p_path),
m_allowedMinutes (p_allowedMinutes)
{
SCF_CONSTRUCT_IBASE(NULL);
SetTargetName (p_targetName);
//Create the collider for the target.
CreateTargetCollider ();
//
//If there is a path to follow, then build the "path follower".
if ((0 != m_path) && (!m_path->IsEmpty ()))
{
m_pathFollower = new KPathFollower (m_path,
m_player->GetPosition ());
m_pathFollower->SetMetersTolerance
(g_ske->mPathTolerance);
}//if
else
m_pathFollower = 0;
}
KTargetingMission::KTargetingMission ()
{
SCF_CONSTRUCT_IBASE (0);
m_path.AttachNew (new KPath ());
}
KTargetingMission::~KTargetingMission ()
{
}
void KTargetingMission::CreateTargetCollider ()
{
KLandmark* l_lm = g_ske->m_listLM->FindByName (m_targetName->GetData ());
l_lm->CreateColliders (g_ske->m_collisionDet, m_collidersList);
}
csRefArray<iCollider>* KTargetingMission::GetColliders ()
{
return &m_collidersList;
}
KLandmark* KTargetingMission::GetTarget ()
{
const char* l_name = GetTargetName ();
return m_landmarks->FindByName (l_name);
}
const char* KTargetingMission::GetTargetName ()
{
return m_targetName->GetData ();;
}
void KTargetingMission::SetTargetName (const char* p_name)
{
m_targetName.AttachNew (new scfString (p_name));
}
KPath* KTargetingMission::GetPath ()
{
return m_path;
}
void KTargetingMission::SetPath (KPath* p_path)
{
m_path.AttachNew (p_path);
}
KPathFollower* KTargetingMission::GetPathFollower ()
{
return m_pathFollower;
}
float KTargetingMission::GetAllowedMinutes ()
{
return m_allowedMinutes;
}
void KTargetingMission::SetAllowedMinutes (float p_t)
{
m_allowedMinutes = p_t;
}
bool KTargetingMission::WriteAdditionalInfo (iDocumentNode* p_parent)
{
csRef<iDocumentNode> l_kmissionNode =
p_parent->CreateNodeBefore (CS_NODE_ELEMENT, NULL);
l_kmissionNode->SetValue ("TargetingMission");
l_kmissionNode->SetAttribute ("name", GetName());
//Save target name
l_kmissionNode->SetAttribute ("targetName", m_targetName->GetData ());
//Save max allowed minutes.
l_kmissionNode->SetAttributeAsFloat ("allowedMinutes", GetAllowedMinutes ());
//
//Save the path (if any).
if (m_path)
m_path->Write (l_kmissionNode);
return true;
}
bool KTargetingMission::ReadAdditionalInfo (iDocumentNode* p_node)
{
const char* l_value = p_node->GetValue ();
if (stricmp (l_value, "TargetingMission"))
return false;
SetName (p_node->GetAttributeValue ("name"));
SetTargetName (p_node->GetAttributeValue ("targetName"));
SetAllowedMinutes (p_node->GetAttributeValueAsFloat ("allowedMinutes"));
if (0 != p_node->GetNode ("path"))//If there is a path.
{
m_path->Read (p_node->GetNode ("path"));
m_path->Init (0);//????????????
g_ske->m_path = m_path;//????????????
}
else
m_path = 0;
return true;
}
//----------------------------------------------------
//KNotFreeWalkingMission
//----------------------------------------------------
SCF_IMPLEMENT_IBASE_EXT (KNotFreeWalkingMission)
SCF_IMPLEMENTS_INTERFACE (iKNotFreeWalkingMission)
SCF_IMPLEMENT_IBASE_EXT_END
KNotFreeWalkingMission::KNotFreeWalkingMission (char* p_name,
KPosition* p_pos,
KPlayer* p_player,
KPath* p_path,
KMap* p_wM, KLandmarkList* p_lL, bool p_collectingData) :
KMission (p_name, p_pos, p_player, p_wM, p_lL,
p_collectingData), m_path (p_path)
{
CS_ASSERT (p_pos != NULL);
CS_ASSERT (p_player != NULL);
CS_ASSERT (p_path != NULL);
CS_ASSERT (p_wM != NULL);
CS_ASSERT (p_lL != NULL);
SCF_CONSTRUCT_IBASE(NULL);
}
KNotFreeWalkingMission::KNotFreeWalkingMission()
{
SCF_CONSTRUCT_IBASE(NULL);
m_path.AttachNew (new KPath ());
}
KNotFreeWalkingMission::~KNotFreeWalkingMission()
{
}
KPath* KNotFreeWalkingMission::GetPath ()
{
return m_path;
}
void KNotFreeWalkingMission::SetPath (KPath* p_path)
{
m_path = p_path;
}
bool KNotFreeWalkingMission::WriteAdditionalInfo (iDocumentNode* p_parent)
{
csRef<iDocumentNode> l_kmissionNode =
p_parent->CreateNodeBefore (CS_NODE_ELEMENT, NULL);
l_kmissionNode->SetValue ("NotFreeWalkingMission");
l_kmissionNode->SetAttribute ("name", GetName());
//write the <path> node.
m_path->Write (l_kmissionNode);
return true;
}
bool KNotFreeWalkingMission::ReadAdditionalInfo (iDocumentNode* p_node)
{
const char* l_value = p_node->GetValue ();
if (strcmp (l_value, "NotFreeWalkingMission"))
return false;
SetName (p_node->GetAttributeValue ("name"));
m_path->Read (p_node->GetNode ("path"));
m_path->Init (0);//????????????
g_ske->m_path = m_path;//????????????
return true;
}
//----------------------------------------------------
//KPointingTargetMission
//----------------------------------------------------
SCF_IMPLEMENT_IBASE_EXT (KPointingTargetMission)
SCF_IMPLEMENTS_INTERFACE (iKPointingTargetMission)
SCF_IMPLEMENT_IBASE_EXT_END
KPointingTargetMission::KPointingTargetMission (char* p_name,
KPosition* p_pos,
KPlayer* p_player,
char const* p_targetName,
KMap* p_wM, KLandmarkList* p_lL, bool p_collectingData) :
KMission (p_name, p_pos, p_player, p_wM, p_lL,
p_collectingData)
{
SCF_CONSTRUCT_IBASE (0);
CS_ASSERT (0 != p_targetName);
SetTargetName (p_targetName);
}
KPointingTargetMission::KPointingTargetMission ()
{
SCF_CONSTRUCT_IBASE (0);
}
KPointingTargetMission::~KPointingTargetMission ()
{
SCF_DESTRUCT_IBASE ();
}
void KPointingTargetMission::SetTargetName (const char* p_name)
{
m_targetName.AttachNew (new scfString (p_name));;
}
char* KPointingTargetMission::GetTargetName ()
{
return m_targetName->GetData ();;
}
KLandmark* KPointingTargetMission::GetTarget ()
{
char* l_name = GetTargetName ();
return m_landmarks->FindByName (l_name);
}
bool KPointingTargetMission::WriteAdditionalInfo (iDocumentNode* p_parent)
{
csRef<iDocumentNode> l_kmissionNode = p_parent->CreateNodeBefore (CS_NODE_ELEMENT, NULL);
l_kmissionNode->SetValue ("PointingTargetMission");
l_kmissionNode->SetAttribute ("name", GetName());
//
//Write target name.
l_kmissionNode->SetAttribute ("targetName", m_targetName->GetData ());
//
//Write the pointing angle.//????? THIS IS NOT USEFUL TO DO HERE: it will not be loaded
//indeed...
l_kmissionNode->SetAttributeAsFloat ("angle", this->CalculateAngle ());
return true;
}
bool KPointingTargetMission::ReadAdditionalInfo (iDocumentNode* p_node)
{
const char* l_value = p_node->GetValue ();
if (strcmp (l_value, "PointingTargetMission"))
return false;
SetName (p_node->GetAttributeValue ("name"));
//
//Read target name, target pos, player pos, player looking at, angle.
SetTargetName (p_node->GetAttributeValue ("targetName"));
return true;
}
float KPointingTargetMission::CalculateAngle ()
{
KData* l_data = m_dataList.Get (m_dataList.GetCount () - 1);
KQuaternion l_qH = l_data->GetBodyAngle ();
//l_z is the direction(vector) the player is looking to.
csVector3 l_z (0, 0, 1);
l_z = l_qH.Rotate (l_z);
//l_tP is the direction(vector) the target is in respect to player's position.
KLandmark* l_target = this->GetTarget ();
csVector3 l_targetPos = l_target->GetPosition ();
csVector3 l_tP (l_targetPos - this->GetInitPosition ()->GetPosition ());
float l_angle = ::CalculateAngle (l_z, l_tP);
return l_angle;
}
#else //NEW_MISSION_DESIGN
bool KMission::HandleEvent (iEvent& p_ev)
{
if (p_ev.Type != csevBroadcast || p_ev.Command.Code != cscmdPreProcess)
return false;
//Calling Test() on all iGeneralTester we have inthe csRefArray.
int i = 0;
for (i = 0; i < m_genTester.Length (); i++)
{
m_genTester[i]->Test ();
}//for
return true;
}
#endif //NEW_MISSION_DESIGN
See more files for this project here