Search the Community
Showing results for tags 'GUN HAND NPC XML C++'.
-
Placing a rifle to sit in the hands of an NPC can be a bit of a fiddle so I thought I'd post the code. The code relies on bones for accurate placement:- Trigger bone Gun Butt/Rest bone Trigger hand Butt hand I place config stuff like this in an XML file for easy editting, to read the XML I use a nice library tinyXML. Ignore the bullet code as this is a temp hack I will tidy later. Hope this helps. PS Thanks to Pixel Perfect for supplying gun model etc for my testing, without him I'd be "assetless". #include "gun/include/gun.h" #include "gun/include/bullet.h" #include "gamelib.h" //#define DEBUG_GUN_POS ActorGun::ActorGun( TScene *pScene, string pFile, TEntity par, TEntity spine, TEntity pTrig, TEntity pRest ): m_fireRate(300), m_range(50) { m_lastFireTime = AppTime(); m_scene = pScene; m_scene->framewerk.GetMain().SetWorld(); m_entity = LoadModel( (char *)pFile.c_str() ); m_spine = spine; m_parent = par; EntityType(m_entity, 5,1); EntityParent( m_entity, m_parent); m_handTrigger = pTrig; m_handRest = pRest; HookUpdateEvent(m_scene->updateEvent); #ifdef DEBUG_GUN_POS HookRenderEvent(m_scene->renderEvent); #endif } bool ActorGun::withinRange( float pDist ) { return (pDist <= m_range); } void ActorGun::Render( float gameLoopTime) { #ifdef DEBUG_GUN_POS TVec3 trigPos = EntityPosition( m_handTrigger, 1); TVec3 restPos = EntityPosition( m_handRest, 1); TVec3 trigBonePos = EntityPosition( m_triggerBone, 1); TVec3 restBonePos = EntityPosition( m_restBone, 1); SetColor( Vec4(1,0,0,1) ); // red tdDraw( m_scene->cam, trigPos, Vec3( trigPos.X, trigPos.Y + 0.1, trigPos.Z) ); SetColor( Vec4(0,0,1,1) ); // blue tdDraw( m_scene->cam, restPos, Vec3( restPos.X, restPos.Y + 0.1, restPos.Z) ); SetColor( Vec4(0,1,0,1) ); // green tdDraw( m_scene->cam, trigBonePos, Vec3( trigBonePos.X, trigBonePos.Y - 0.1, trigBonePos.Z) ); SetColor( Vec4(1,1,1,1) ); // white tdDraw( m_scene->cam, restBonePos, Vec3( restBonePos.X, restBonePos.Y - 0.1, restBonePos.Z) ); TVec3 pos = EntityPosition(m_muzzelBone,1); TVec3 pos1 = TFormVector( Vec3(0,0,-1), m_spine, NULL); pos1.X += pos.X; pos1.Y += pos.Y; pos1.Z += pos.Z; tdDraw( m_scene->cam, pos, pos1 ); #endif } // Position the gun in the actors hand void ActorGun::Update(float gameLoopTime) { TVec3 trigPos; TVec3 restPos = EntityPosition( m_handRest, 1); TVec3 handPos = EntityPosition( m_handTrigger, 1); float diffx = handPos.X - restPos.X; float diffy = handPos.Y - restPos.Y; float diffz = handPos.Z - restPos.Z; AlignToVector( m_entity, Vec3(diffx,diffy,diffz),3 ); TVec3 pos = EntityPosition(m_entity,1); trigPos = EntityPosition(m_triggerBone,1); diffx = pos.X - trigPos.X; diffy = pos.Y - trigPos.Y; diffz = pos.Z - trigPos.Z; trigPos = EntityPosition( m_handTrigger, 1); trigPos.X += diffx; trigPos.Y += diffy; trigPos.Z += diffz; PositionEntity(m_entity, trigPos, 1); list<Bullet*>::iterator bulletList; for(bulletList = m_bullets.begin(); bulletList != m_bullets.end(); ) { if ((*bulletList)->m_life == 0) { delete *bulletList; m_bullets.erase( bulletList++ ); } else ++bulletList; } } bool ActorGun::fireGun() { if (AppTime() < m_lastFireTime ) return false; m_lastFireTime = AppTime() + m_fireRate; Bullet *bullet; TVec3 pos; pos = EntityPosition(m_muzzelBone,1); //bullet = new Bullet( pos, TFormVector( Vec3(0,0,-1), m_muzzelBone, NULL), m_scene ); bullet = new Bullet( pos, TFormVector( Vec3(0,0,-1), m_spine, NULL), m_scene ); m_bullets.push_back( bullet ); return true; } TEntity gunPickSource; int _stdcall gunFilter( TEntity entity ) { if ( isParent(gunPickSource, entity) ) return 0; return 1; } bool ActorGun::canHit( TEntity target, TVec3 tagetPos) { gunPickSource = m_entity; TVec3 pos = EntityPosition(m_muzzelBone,1); TPick pick; if (LinePick( &pick, pos, tagetPos, 0, 0, (BP)gunFilter)) { if (isParent(target, pick.entity )) return true; } else return true; return false; } // Read in gun information from an XML file bool ActorGun::readGunFile( string pFile ) { string filename; string typeName; string bone; filename = AbstractPath( (str)pFile.c_str()); TiXmlDocument doc( filename.c_str() ); TiXmlElement* child = 0; TiXmlElement *bones = 0; doc.LoadFile( filename.c_str() ); bones = doc.FirstChildElement("bones"); if(bones) { child = bones->FirstChildElement(); while(child) { typeName = child->Attribute("type"); if(typeName == "trigger") { m_triggerBone = FindChild( m_entity, (str)child->Attribute("name") ); m_triggerPos = EntityPosition( m_triggerBone ); } typeName = child->Attribute("type"); if(typeName == "rest") { m_restBone = FindChild( m_entity, (str)child->Attribute("name") ); m_restPos = EntityPosition( m_restBone ); } if(typeName == "muzzel") { m_muzzelBone = FindChild( m_entity, (str)child->Attribute("name") ); } child = child->NextSiblingElement(); } } return true; } Include: - #ifndef GUN_H #define GUN_H #include "tinyxml.h" #include "gamelib/include/scene.h" #include "event/include/gameEvent.h" #include "gun/include/bullet.h" #include <list> class ActorGun : public GameObject { protected: TScene *m_scene; public: TEntity m_parent; TEntity m_entity; TEntity m_actor; TEntity m_handTrigger; TEntity m_handRest; TEntity m_triggerBone; TEntity m_restBone; TEntity m_muzzelBone; TEntity m_spine; TVec3 m_triggerPos; TVec3 m_restPos; list<Bullet*> m_bullets; float m_fireRate; float m_lastFireTime; float m_range; ActorGun( TScene *pScene, std::string pFile, TEntity par, TEntity spine, TEntity pTrig, TEntity pRest ); virtual void Update( float gameLoopTime); virtual void Render( float gameLoopTime); bool fireGun(); bool withinRange( float pDist ); bool canHit( TEntity target, TVec3 tagetPos); bool readGunFile( std::string pFile ); }; #endif