Example #1
0
ObjArray *Chr::getWeapons(bool includeMagic) {
	ObjArray *list = new ObjArray;

	if (_weapon1)
		list->push_back(_weapon1);

	if (_weapon2)
		list->push_back(_weapon2);

	for (uint i = 0; i < _inventory.size(); i++)
		switch (_inventory[i]->_type) {
		case Obj::REGULAR_WEAPON:
		case Obj::THROW_WEAPON:
			list->push_back(_inventory[i]);
			break;
		case Obj::MAGICAL_OBJECT:
			if (includeMagic)
				list->push_back(_inventory[i]);
			break;
		default:
			break;
		}

	return list;
}
Example #2
0
BObjectImp* FileAccessExecutorModule::mf_ReadFile()
{
	const String* filename;
	if (!getStringParam( 0, filename ))
		return new BError( "Invalid parameter type" );

	const Package* outpkg;
	string path;
	if (!pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ))
		return new BError( "Error in filename descriptor" );

	if (path.find( ".." ) != string::npos)
		return new BError( "No parent path traversal please." );

	if (!HasReadAccess( exec.prog()->pkg, outpkg, path ))
		return new BError( "Access denied" );

	string filepath;
	if (outpkg == NULL)
		filepath = path;
	else
		filepath = outpkg->dir() + path;

	ifstream ifs( filepath.c_str() );
	if (!ifs.is_open())
		return new BError( "File not found: " + filepath );

	ObjArray* arr = new ObjArray();

	string line;
	while (getline(ifs, line))
		arr->addElement( new String( line ) );

	return arr;
}
LTBOOL SendTriggerMsgToObjects(LPBASECLASS pSender, const char* pName, const char* pMsg)
{
    if (!pMsg) return LTFALSE;

    // Process the message as a command if it is a valid command...

    if (g_pCmdMgr->IsValidCmd(pMsg))
    {
        return g_pCmdMgr->Process(pMsg);
    }

    if (!pName || pName[0] == '\0') return LTFALSE;

    ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    // ILTServer::FindNameObjects does not destroy pName so this is safe
    g_pLTServer->FindNamedObjects((char*)pName, objArray);

    int numObjects = objArray.NumObjects();
    if (!numObjects) return LTFALSE;

    for (int i = 0; i < numObjects; i++)
    {
        SendTriggerMsgToObject(pSender, objArray.GetObject(i), 0, pMsg);
    }

    return LTTRUE;
}
Example #4
0
void Camera::Update()
{
	LTVector vPos;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);

	ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    g_pLTServer->FindNamedObjects(DEFAULT_PLAYERNAME,objArray);

	int numObjects = objArray.NumObjects();

	for (int i = 0; i < numObjects; i++ )
	{
        CPlayerObj* pPlayer = (CPlayerObj*) g_pLTServer->HandleToObject(objArray.GetObject(i));
		if (pPlayer)
		{
			HCLIENT hClient = pPlayer->GetClient();
			if (hClient)
			{
                g_pLTServer->SetClientViewPos(hClient, &vPos);
			}
		}
	}

    if (m_fActiveTime > 0.0f && g_pLTServer->GetTime() > m_fTurnOffTime)
	{
		TurnOff();
	}
	else
	{
        SetNextUpdate(UPDATE_NEXT_FRAME);
	}
}
Example #5
0
void Spawner::HandleSpawnFromMsg( HOBJECT hSender, const CParsedMsg &crParsedMsg )
{
    LTVector	vPos;
    LTRotation	rRot;
    const char *pName = "";

    ObjArray<HOBJECT, 1> objArray;
    g_pLTServer->FindNamedObjects( const_cast<char*>(crParsedMsg.GetArg(1).c_str()), objArray );

    // Spawn the target object from the position of the specified object...
    if( objArray.NumObjects() == 1 )
    {
        g_pLTServer->GetObjectPos( objArray.GetObject(0), &vPos );
        g_pLTServer->GetObjectRotation( objArray.GetObject(0), &rRot );
    }
    else
    {
        g_pLTServer->GetObjectPos( m_hObject, &vPos );
        g_pLTServer->GetObjectRotation( m_hObject, &rRot );
    }

    // Rename the object if desired
    if( crParsedMsg.GetArgCount() > 2 )
    {
        pName = crParsedMsg.GetArg(2);
    }

    // Spawn using a target template...
    Spawn( m_sTarget.c_str(), pName, vPos, rRot );
}
Example #6
0
void Gui::regenWeaponsMenu() {
	if (_engine->_world->_weaponMenuDisabled)
		return;

	_menu->clearSubMenu(_weaponsMenuId);

	Chr *player = _engine->_world->_player;
	ObjArray *weapons = player->getWeapons(true);

	bool empty = true;

	for (uint i = 0; i < weapons->size(); i++) {
		Obj *obj = (*weapons)[i];
		if (obj->_type == Obj::REGULAR_WEAPON ||
			obj->_type == Obj::THROW_WEAPON ||
			obj->_type == Obj::MAGICAL_OBJECT) {
			Common::String command(obj->_operativeVerb);
			command += " ";
			command += obj->_name;

			_menu->addMenuSubItem(_weaponsMenuId, command.c_str(), kMenuActionCommand, 0, 0, true);

			empty = false;
		}
	}
	delete weapons;

	if (empty)
		_menu->addMenuSubItem(_weaponsMenuId, "You have no weapons", 0, 0, 0, false);
}
Example #7
0
LTRESULT FindNamedObject(const char* szName, ILTBaseClass *& pObject, bool bMultipleOkay)
{
	if ( !szName || !*szName ) return LT_NOTFOUND;

	pObject = NULL;
	ObjArray<HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    g_pLTServer->FindNamedObjects((char*)szName,objArray);

	switch ( objArray.NumObjects() )
	{
		case 1:
		{
			pObject = g_pLTServer->HandleToObject(objArray.GetObject(0));
			return LT_OK;
		}
		case 0:
		{
			return LT_NOTFOUND;
		}
		default:
		{
			if ( bMultipleOkay )
			{
				pObject = g_pLTServer->HandleToObject(objArray.GetObject(0));
				return LT_OK;
			}
			else
			{
                g_pLTServer->CPrint("Error, %d objects named \"%s\" present in level", objArray.NumObjects(), szName);
				return LT_ERROR;
			}
		}
	}
}
Example #8
0
BObjectImp* FileAccessExecutorModule::mf_ListDirectory()
{
	const String* dirname;
	const String* extension;
	short listdirs;
	if ((!getStringParam( 0, dirname )) ||
		(!getStringParam( 1, extension )) ||
		(!getParam( 2, listdirs )) )
		return new BError( "Invalid parameter type" );

	const Package* outpkg;
	string path;
	if (!pkgdef_split( dirname->value(), exec.prog()->pkg, &outpkg, &path ))
		return new BError( "Error in dirname descriptor" );
	if (path.find( ".." ) != string::npos)
		return new BError( "No parent path traversal please." );

	if (outpkg != NULL)
		path = outpkg->dir() + path;
	path = normalized_dir_form(path);
	if ( !IsDirectory( path.c_str() ) )
		return new BError( "Directory not found." );
	bool asterisk = false;
	bool nofiles = false;
	if ( extension->getStringRep().find('*',0) != string::npos)
		asterisk = true;
	else if ( extension->length() == 0 )
		nofiles = true;

	ObjArray* arr = new ObjArray;

	for( DirList dl( path.c_str() ); !dl.at_end(); dl.next() )
	{
		string name = dl.name();
		if (name[0] == '.')
			continue;

		if ( IsDirectory( (path+name).c_str() ) )
		{
			if ( listdirs == 0 )
				continue;
		}
		else if ( nofiles )
			continue;
		else if (!asterisk)
		{
			string::size_type extensionPointPos = name.rfind('.');
			if (extensionPointPos == string::npos)
				continue;
			if (name.substr(extensionPointPos + 1) != extension->value())
				continue;
		}
		
		arr->addElement( new String(name) );
	}

	return arr;
}
Example #9
0
void CDestructibleModel::CreateWorldModelDebris()
{
    ILTServer* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	const char* pName = GetObjectName(m_hObject);
	if (!pName || !pName[0]) return;


	// Find all the debris objects...

	int nNum = 0;

	char strKey[128]; memset(strKey, 0, 128);
	char strNum[18];  memset(strNum, 0, 18);

	HCLASS hWMDebris = pServerDE->GetClass("WorldModelDebris");

	while (1)
	{
		// Create the keyname string...

		sprintf(strKey, "%sDebris%d", pName, nNum);

		// Find any debris with that name...

		ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
		pServerDE->FindNamedObjects(strKey, objArray);

		int numObjects = objArray.NumObjects();
		if (!numObjects) return;

		for (int i = 0; i < numObjects; i++)
		{
			HOBJECT hObject = objArray.GetObject(i);

			if (pServerDE->IsKindOf(pServerDE->GetObjectClass(hObject), hWMDebris))
			{
				WorldModelDebris* pDebris = (WorldModelDebris*)pServerDE->HandleToObject(hObject);
				if (!pDebris) break;

				LTVector vVel, vRotPeriods;
				vVel.Init(GetRandom(-200.0f, 200.0f),
					GetRandom(100.0f, 300.0f), GetRandom(-200.0f, 200.0f));

				vRotPeriods.Init(GetRandom(-1.0f, 1.0f),
					GetRandom(-1.0f, 1.0f), GetRandom(-1.0f, 1.0f));

				pDebris->Start(&vRotPeriods, &vVel);
			}
		}

		// Increment the counter...

		nNum++;
	}
}
Example #10
0
ObjArray *Chr::getMagicalObjects() {
	ObjArray *list = new ObjArray;

	for (uint i = 0; i < _inventory.size(); i++)
		if (_inventory[i]->_type == Obj::MAGICAL_OBJECT)
			list->push_back(_inventory[i]);

	return list;
}
Example #11
0
void CDestructibleModel::DoExplosion(char* pTargetName)
{
	CWeapons weapons;
	weapons.Init(m_hObject);
	weapons.ObtainWeapon(m_nExplosionWeaponId);
	weapons.ChangeWeapon(m_nExplosionWeaponId);

	CWeapon* pWeapon = weapons.GetCurWeapon();
	if (!pWeapon) return;

	weapons.SetAmmo(pWeapon->GetAmmoId());

	pWeapon->SetDamageFactor(m_fDamageFactor);

	LTRotation rRot;
	g_pLTServer->GetObjectRotation(m_hObject, &rRot);

	LTVector vF, vPos;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);
	vF = rRot.Forward();

	// Just blow up in place if we're not supposed to fire along
	// forward vector and we don't have a target...

	if (!m_bFireAlongForward)
	{
		pWeapon->SetLifetime(0.0f);
		VEC_SET(vF, 0.0f, -1.0f, 0.0f);  // Fire down
	}

	// See if we have a target...If so, point at it.

	if (pTargetName)
	{
		ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
		g_pLTServer->FindNamedObjects(pTargetName, objArray);

		if (objArray.NumObjects())
		{
			LTVector vObjPos;
			g_pLTServer->GetObjectPos(objArray.GetObject(0), &vObjPos);
			vF = vObjPos - vPos;
			vF.Normalize();

			rRot = LTRotation(vF, LTVector(0.0f, 1.0f, 0.0f));
			g_pLTServer->SetObjectRotation(m_hObject, &rRot);
		}
	}

	WeaponFireInfo weaponFireInfo;
	weaponFireInfo.hFiredFrom	= m_hObject;
	weaponFireInfo.vPath		= vF;
	weaponFireInfo.vFirePos	= vPos;
	weaponFireInfo.vFlashPos	= vPos;

	pWeapon->Fire(weaponFireInfo);
}
BObjectImp* PolSystemExecutorModule::mf_Packages()
{
    ObjArray* arr = new ObjArray;
    for( unsigned i = 0; i < packages.size(); ++i )
    {
        PackageObjImp* imp = new PackageObjImp( PackagePtrHolder( packages[i] ) );
        arr->addElement( imp );
    }
    return arr;
}
Example #13
0
/// uo.em functions:
///  ListGuilds(); // returns an array of Guild objects
BObjectImp* GuildExecutorModule::mf_ListGuilds()
{
    ObjArray* result = new ObjArray;
    for( Guilds::iterator itr = guilds.begin(); itr != guilds.end(); ++itr )
    {
        Guild* guild = (*itr).second.get();
        result->addElement( new EGuildRefObjImp( GuildRef(guild )) );
    }
    return result;
}
Example #14
0
void ScreenShake::Update()
{
	if (--m_nNumShakes > 0)
	{
        SetNextUpdate(m_hObject, m_fFrequency);
	}

    LTVector vMyPos;
    g_pLTServer->GetObjectPos(m_hObject, &vMyPos);

	// Play sound...

	if (m_hstrSound)
	{
        char* pSound = g_pLTServer->GetStringData(m_hstrSound);
		g_pServerSoundMgr->PlaySoundFromPos(vMyPos, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_LOW);
	}

	// Time to shake.  Get all the players in the area of effect...

	ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    g_pLTServer->FindNamedObjects(DEFAULT_PLAYERNAME, objArray);
	int numObjects = objArray.NumObjects();

	if (!numObjects) return;

	for (int i = 0; i < numObjects; i++)
	{
		HOBJECT hObject = objArray.GetObject(i);

		if (hObject && IsPlayer(hObject))
		{
			// Make sure object is in area of effect...

            LTVector vPlayerPos;
            g_pLTServer->GetObjectPos(hObject, &vPlayerPos);

			if (m_fAreaOfEffect == c_fENTIRE_LEVEL ||
				VEC_DIST(vPlayerPos, vMyPos) <= m_fAreaOfEffect)
			{
                CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(hObject);
				if (pPlayer)
				{
					HCLIENT hClient = pPlayer->GetClient();
					if (hClient)
					{
                        HMESSAGEWRITE hMessage = g_pLTServer->StartMessage(hClient, MID_SHAKE_SCREEN);
                        g_pLTServer->WriteToMessageVector(hMessage, &m_vAmount);
                        g_pLTServer->EndMessage(hMessage);
					}
				}
			}
		}
	}
}
Example #15
0
void ClassInfo::iterate_tables(OopROMVisitor* visitor) {
  int index = 0;
  if (vtable_length() > 0) {
    visitor->do_comment("Virtual dispatch table");
    for (index = 0; index < vtable_length(); index++) {
      IndexableField field(index, true);
      visitor->do_oop(&field, vtable_offset_from_index(index), true);
    }
  }

  if (itable_length() > 0){
    visitor->do_comment("Interface dispatch table");
    for (index = 0; index < itable_length(); index++) {
      {
        InstanceClass ic = itable_interface_at(index);
        Symbol name = ic.name();
        char buffer[1024];
        jvm_sprintf(buffer, "interface klass_index ");
        name.string_copy(buffer + jvm_strlen(buffer), 
                         sizeof(buffer) - jvm_strlen(buffer));

        NamedField field(buffer, true);
        visitor->do_int(&field, itable_offset_from_index(index), true);
      }
      {
        NamedField field("offset", true);
        visitor->do_int(&field, 
                        itable_offset_from_index(index) + sizeof(jint),
                        true);
      }
    }
    for (index = 0; index < itable_length(); index++) {
      int offset = itable_offset_at(index);
      // Some ROM's interfaces that implement other interfaces set
      // offset=0, since this information is actually needed by
      // anyone.
      if (offset > 0) {
        InstanceClass ic = itable_interface_at(index);
        Symbol name = ic.name();
        ObjArray methods = ic.methods();
        const int buffer_size = 256;
        char buffer[256];
        jvm_sprintf(buffer, "Table for interface #%d: ", index);
        name.string_copy(buffer + jvm_strlen(buffer), buffer_size- jvm_strlen(buffer));
        visitor->do_comment(buffer);
        for (int i = 0; i < methods.length(); i ++) {
          IndexableField field(i, true);
          visitor->do_oop(&field, offset + i * sizeof(jobject), true);
        }
      }
    }
  }
}
HOBJECT CinematicTrigger::FindWhoPlaysDecision(uint8 byDecision)
{
	char* pCharName = DEFAULT_PLAYERNAME;

	if (byDecision > 0)
	{
		char* pMsg = g_pLTServer->GetStringData(m_hstrWhoPlaysDecisions[m_nCurMessage]);
		if (pMsg)
		{
	 		ConParse parse;
			parse.Init(pMsg);

			// Since the names will be seperated by semi-colons we need
			// to parse until we get to the correct name...

			LTBOOL bFound = LTTRUE;
			for (int i=1; i <= byDecision; i++)
			{
				if (g_pLTServer->Common()->Parse(&parse) != LT_OK)
				{
					bFound = LTFALSE;
					break;
				}
			}

			// Parse should be on the correct name now...

			if (bFound && parse.m_nArgs > 0)
			{
				if (parse.m_Args[0])
				{
					pCharName = parse.m_Args[0];
				}
			}
		}
	}

	ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    g_pLTServer->FindNamedObjects(pCharName, objArray);

	if (objArray.NumObjects())
	{
		return objArray.GetObject(0);
	}

	return LTNULL;
}
Example #17
0
void Controller::FirstUpdate()
{
	// Find target objects and make interlinks.

    for (uint32 i=0; i < MAX_CONTROLLER_TARGETS; i++)
	{
		ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;

        g_pLTServer->FindNamedObjects(m_Fades[i].m_ObjectName, objArray);

		if (objArray.NumObjects())
		{
			HOBJECT hObject = objArray.GetObject(0);

			m_Fades[i].m_hTarget = hObject;
		}
	}
}
Example #18
0
void WorldModel::HandleDetachMsg( const CParsedMsg &cMsg )
{
	if( cMsg.GetArgCount() >= 2 )
	{
		// Look for the specific objects we want to detach
		for( uint i = 1; i < cMsg.GetArgCount( ); i++ )
		{
			const char *pObjName = cMsg.GetArg(i).c_str();
			if( !pObjName )
				break;

			ObjArray<HOBJECT, 1> objArray;
			g_pLTServer->FindNamedObjects( const_cast<char *>(pObjName), objArray );

			if( objArray.NumObjects() )
			{
				DetachObject( objArray.GetObject( 0 ) );
			}
		}
	}
	else
	{
		// Remove an Object we attached using the AttachDir...

		if( m_hAttachDirObj )
		{
			DetachObject( m_hAttachDirObj );
			m_hAttachDirObj = NULL;
		}
		else
		{
			// Objects attached via ATTACH ....
			while( m_AttachMsgObjList.size( ))
			{
				ObjRefNotifierList::iterator msgiter = m_AttachMsgObjList.begin( );
				HOBJECT hObj = *msgiter;
				if( hObj )
					DetachObject( hObj );

				m_AttachMsgObjList.erase( msgiter );
			}
		}
	}
}
Example #19
0
bool SoundNonPoint::AllObjectsCreated()
{
	// resolve the object links. Basically, get the sound zone volumes
	// and collect their info into the non-point sound object that
	// gets created on the client.

	ObjArray <HOBJECT, 1> objArray;
	int32 i;

	m_SCS.m_nNumZones = 0;

	for (i=0; i < MAX_SOUND_VOLUMES; i++)
	{
		SoundZoneVolume* pSZV;

		if(!LTStrEmpty(m_sSoundZone[i].c_str()))
		{
			g_pLTServer->FindNamedObjects(m_sSoundZone[i].c_str(), objArray);
			if(objArray.NumObjects() > 0)
			{
				if (IsKindOf(objArray.GetObject(0), "SoundZoneVolume"))
				{
					HOBJECT hObj;

					hObj = objArray.GetObject(0);
					pSZV = (SoundZoneVolume*) g_pLTServer->HandleToObject(hObj);

					// do a type check before casting...

					if (pSZV)
					{
						g_pLTServer->GetObjectPos(hObj, &m_SCS.m_SoundZone[m_SCS.m_nNumZones].m_vPos);
						g_pLTServer->GetObjectRotation(hObj, &m_SCS.m_SoundZone[m_SCS.m_nNumZones].m_rRotation);
						m_SCS.m_SoundZone[m_SCS.m_nNumZones].m_vHalfDims = pSZV->GetHalfDims();

						m_SCS.m_nNumZones++;
					}
				}

			}
		}
	}
	return true;
}
Example #20
0
uint32 Door::OnAllObjectsCreated( )
{
	// Send to base class first...

	ActiveWorldModel::OnAllObjectsCreated( );

	// Create a link to our door link object if we have one...

	if( !m_sDoorLink.empty() )
	{
		ObjArray<HOBJECT, 1>	objArray;
		g_pLTServer->FindNamedObjects( m_sDoorLink.c_str(), objArray );

		if( objArray.NumObjects() > 0 )
		{
			m_hDoorLink = objArray.GetObject( 0 );
		}
	}

	return 1;
}
Example #21
0
void Menu::createWeaponsMenu(MenuItem *menu) {
	Chr *player = _gui->_engine->_world->_player;
	ObjArray *weapons = player->getWeapons(true);

	for (uint i = 0; i < weapons->size(); i++) {
		Obj *obj = (*weapons)[i];
		if (obj->_type == Obj::REGULAR_WEAPON ||
			obj->_type == Obj::THROW_WEAPON ||
			obj->_type == Obj::MAGICAL_OBJECT) {
			Common::String command(obj->_operativeVerb);
			command += " ";
			command += obj->_name;

			menu->subitems.push_back(new MenuSubItem(command.c_str(), kMenuActionCommand, 0, 0, true));
		}
	}
	delete weapons;

	if (menu->subitems.empty())
		menu->subitems.push_back(new MenuSubItem("You have no weapons", 0, 0, 0, false));
}
HOBJECT CinematicTrigger::PlayedBy(char *pszName)
{
    if (!g_pLTServer || m_nCurMessage >= MAX_CT_MESSAGES) return m_hObject;
    if (!pszName) return LTNULL;

	ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
    g_pLTServer->FindNamedObjects(pszName,objArray);

	int numObjects = objArray.NumObjects();

	for (int i = 0; i < numObjects; i++)
	{
		HOBJECT hObject = objArray.GetObject(i);

		if (IsActor(hObject))
		{
			return hObject;
		}
	}

    return LTNULL;
}
Example #23
0
void WorldModel::OnEveryObjectCreated( )
{
	// Save if we are currently set up to be activated...

	uint32 dwFlags;
	g_pCommonLT->GetObjectFlags( m_hObject, OFT_User, dwFlags );

	m_bCanActivate = !!(dwFlags & USRFLG_CAN_ACTIVATE);

	// Check for any objects to attach 

	if( !m_hstrAttachments ) return;

	const char *pAttachments = g_pLTServer->GetStringData( m_hstrAttachments );
	if( !pAttachments ) return;

	ConParse	parse( pAttachments );
		
	while( g_pCommonLT->Parse( &parse ) == LT_OK )
	{
		// We have an object we want to attach... find it

		if( parse.m_nArgs > 0 && parse.m_Args[0] )
		{
			ObjArray<HOBJECT, MAX_OBJECT_ARRAY_SIZE>	objArray;
			g_pLTServer->FindNamedObjects( parse.m_Args[0], objArray );

			for( uint i = 0; i < objArray.NumObjects(); i++ )
			{
				 AttachObject( objArray.GetObject( i ) );
			}
		}
	}

	// Once they are added free the string because we don't want to re-add the objects 
	// everytime this objects gets loaded.  Our attachment list will take care of everything.

	FREE_HSTRING( m_hstrAttachments );
}
Example #24
0
int main(int argc, char **argv)
{
	std::string filename;
	if (argc == 2)
		filename = argv[1];
	else
		filename = "image.bmp";

	ObjArray objects;
	
	////objects.push_back(new Sphere(vec3(0.0, 0, -20), 4, vec3(1.00, 0.32, 0.36), 1.0, 1.0));
	//objects.push_back(new Sphere(vec3(0.0, 0, -20), 4, vec3(0, 0, 0), 1.0, 0.8));
	//objects.push_back(new Sphere(vec3(5.0, -1, -15), 2, vec3(0.90, 0.76, 0.46), 1.0, 1));
	//objects.push_back(new Sphere(vec3(5.0, 0, -25), 3, vec3(0.35, 0.97, 0.37), 1.0, 1));
	//objects.push_back(new Sphere(vec3(-6, 0, -5), 3, vec3(0.9, 0.9, 0.9), 1.0, 1));	
	//objects.push_back(new Sphere(vec3(0, 5, -15), 1.0, vec3(0.2, 0.32, 0.9), 1.0, 1));

	objects.push_back(new Sphere(vec3(-6, 4, 0), 4, vec3(0.7, 0.2, 0.2), 1.0, 0.8));

	objects.push_back(new Sphere(vec3(6, 4, 0), 4, vec3(0.2, 0.7, 0.2), 1.0, 0.8));

	objects.push_back(new Sphere(vec3(0, 4, 6), 4, vec3(0.2, 0.2, 0.7), 1.0, 0.8));

	objects.push_back(new Disk(vec3(0, 0, 0), 40.0, glm::normalize(vec3(0, 1, 0)), vec3(0.2, 0.2, 0.25), 0.2, 1));

	lights.push_back(vec3(10, 10, 10));
	lights.push_back(vec3(-10, 10, 10));

	render(objects, filename.c_str());

	for (auto obj : objects)
	{
		delete obj;
	}

	return EXIT_SUCCESS;
}
void Intelligence::DoActivate(HOBJECT hSender)
{
	// BL 10/30/00 - fix multiple photographs of items in multiplayer
	{
		if ( g_pGameServerShell->GetGameType() != SINGLE )
		{
			uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
			if ( !(dwFlags & FLAG_VISIBLE) )
			{
				return;
			}
		}
	}

	HOBJECT hPlayer = hSender;

	if (!hSender || !IsPlayer(hSender))
	{
		// Find the player if the sender isn't one...

		ObjArray <HOBJECT, 1> objArray;
        g_pLTServer->FindNamedObjects(DEFAULT_PLAYERNAME, objArray);

		if (!objArray.NumObjects()) return;

		hPlayer = objArray.GetObject(0);
	}

	// Increment the player's intelligence count...
    CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(hPlayer);
	if (pPlayer)
	{
		if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && m_nPlayerTeamFilter)
		{
			if (pPlayer->GetTeamID() != m_nPlayerTeamFilter)
				return;
			uint8 nScore = (uint8)g_vtNetIntelScore.GetFloat();
			pPlayer->AddToScore(nScore);
			
			HCLIENT hClient = pPlayer->GetClient();
		    uint32 nPlayerID = g_pLTServer->GetClientID(hClient);

            HMESSAGEWRITE hWrite = g_pLTServer->StartMessage (LTNULL, MID_TEAM_SCORED);
            g_pLTServer->WriteToMessageDWord (hWrite, nPlayerID);
            g_pLTServer->WriteToMessageByte (hWrite, (uint8)pPlayer->GetTeamID());
            g_pLTServer->WriteToMessageByte (hWrite, nScore);
            g_pLTServer->EndMessage (hWrite);

		}


		CPlayerSummaryMgr* pPSMgr = pPlayer->GetPlayerSummaryMgr();
		if (pPSMgr)
		{
			pPSMgr->IncIntelligenceCount();
		}

		HCLIENT hClient = pPlayer->GetClient();
		if (hClient)
		{
            HMESSAGEWRITE hMessage = g_pLTServer->StartMessage(hClient, MID_PLAYER_INFOCHANGE);
            g_pLTServer->WriteToMessageByte(hMessage, IC_INTEL_PICKUP_ID);
            g_pLTServer->WriteToMessageByte(hMessage, 0);
            g_pLTServer->WriteToMessageByte(hMessage, 0);
            g_pLTServer->WriteToMessageFloat(hMessage, 0.0f);
            g_pLTServer->EndMessage(hMessage);
		}

		// Show the pop-up associated with the intelligence item, if
		// applicable...

		INTEL* pIntel = g_pIntelMgr->GetIntel(m_nIntelId);
		if (pIntel && m_bShowPopup)
		{
			char buf[255];
			sprintf(buf, "msg %s (popup %d", DEFAULT_PLAYERNAME, m_nInfoId);

			// Add the scale fx...

			for (int i=0; i < pIntel->nNumScaleFXNames; i++)
			{
				if (pIntel->szScaleFXNames[i])
				{
					strcat(buf, " ");
					strcat(buf, pIntel->szScaleFXNames[i]);
				}
			}

			strcat(buf, ")");

			if (g_pCmdMgr->IsValidCmd(buf))
			{
				g_pCmdMgr->Process(buf);
			}
		}


		// If we have a command, process it...

		if (m_hstrPickedUpCmd)
		{
            char* pCmd = g_pLTServer->GetStringData(m_hstrPickedUpCmd);

			if (pCmd && g_pCmdMgr->IsValidCmd(pCmd))
			{
				g_pCmdMgr->Process(pCmd);
			}
		}

		if (g_pGameServerShell->GetGameType() == SINGLE)
		{
			g_pLTServer->RemoveObject(m_hObject);
		}
		else
		{
			uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
			dwFlags &= (~FLAG_VISIBLE & ~FLAG_RAYHIT);
			g_pLTServer->SetObjectFlags(m_hObject, dwFlags);

			// Play pickup sound...

			LTVector vPos;
			g_pLTServer->GetObjectPos(m_hObject, &vPos);
			g_pServerSoundMgr->PlaySoundFromPos(vPos, INTEL_PICKUP_SOUND,
				600.0f, SOUNDPRIORITY_MISC_HIGH);
		}

	}
}
Example #26
0
BObjectRef EGuildRefObjImp::get_member_id( const int id ) //id test
{
    if (obj_->_disbanded)
        return BObjectRef( new BError( "Guild has disbanded" ) );
 
    ObjArray* arr;
    switch(id)
    {
    case MBR_MEMBERS:
        arr = new ObjArray;
        for( SerialSet::iterator itr = obj_->_member_serials.begin();
             itr != obj_->_member_serials.end();
             /* do this earlier */)
        {
            unsigned long mserial = (*itr);
            SerialSet::iterator last_itr = itr;
            ++itr;

            Character* chr = system_find_mobile( mserial );
            if (chr != NULL)
            {
                arr->addElement( new EOfflineCharacterRefObjImp( chr ) );
            }
            else
            {
                obj_->_member_serials.erase( last_itr );
            }
        }
        return BObjectRef( arr );

    case MBR_ALLYGUILDS:
        arr = new ObjArray;
        for( SerialSet::iterator itr = obj_->_allyguild_serials.begin();
             itr != obj_->_allyguild_serials.end();
             /* do this earlier */)
        {
            unsigned long gserial = (*itr);
            SerialSet::iterator last_itr = itr;
            ++itr;

            Guild* guild = FindGuild( gserial );

            if (guild != NULL)
            {
                arr->addElement( new EGuildRefObjImp( ref_ptr<Guild>(guild) ) );
            }
            else
            {
                obj_->_allyguild_serials.erase( last_itr );
            }
        }
        return BObjectRef( arr );

    case MBR_ENEMYGUILDS:
        arr = new ObjArray;
        for( SerialSet::iterator itr = obj_->_enemyguild_serials.begin();
             itr != obj_->_enemyguild_serials.end();
             /* do this earlier */)
        {
            unsigned long gserial = (*itr);
            SerialSet::iterator last_itr = itr;
            ++itr;

            Guild* guild = FindGuild( gserial );

            if (guild != NULL)
            {
                arr->addElement( new EGuildRefObjImp( ref_ptr<Guild>(guild) ) );
            }
            else
            {
                obj_->_enemyguild_serials.erase( last_itr );
            }
        }
        return BObjectRef( arr );

    case MBR_GUILDID:
        return BObjectRef( new BLong( obj_->_guildid ) );
    default:
        return BObjectRef( UninitObject::create() );
    }
}
Example #27
0
void Controller::HandleFadeCommand(const CParsedMsg &cMsg)
{
	static CParsedMsg::CToken s_cTok_Alpha("ALPHA");
	static CParsedMsg::CToken s_cTok_Color("COLOR");

	const char *pValue, *pDuration;
	ParamType paramType;
	ParamValue paramValue;
	WaveType waveType;
	float duration;
    uint32 i;


	if(cMsg.GetArgCount() < 4)
	{
		ShowTriggerError(cMsg);
		return;
	}

	const CParsedMsg::CToken &cParamType = cMsg.GetArg(1);
	pValue = cMsg.GetArg(2);
	pDuration = cMsg.GetArg(3);

	// Parse everything.. it doesn't do anything if there's an error.
	if(cParamType == s_cTok_Alpha)
	{
		paramType = Param_Alpha;
	}
	else if(cParamType == s_cTok_Color)
	{
		paramType = Param_Color;
	}
	else
	{
		ShowTriggerError(cMsg);
		return;
	}

	paramValue = ParseValue(paramType, pValue);
	duration = (float)atof(pDuration);
    duration = LTCLAMP(duration, 0.0f, 100000.0f);

	waveType = Wave_Sine;
	if(cMsg.GetArgCount() >= 5)
	{
		waveType = ParseWaveType(cMsg.GetArg(4));
	}

	// Ok, configure...
    m_fStartTime = g_pLTServer->GetTime() + g_pLTServer->GetFrameTime();
	m_fDuration = duration;
	m_ParamType = paramType;
	m_WaveType = waveType;
	m_DestValue = paramValue;

	ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;

	for(i=0; i < MAX_CONTROLLER_TARGETS; i++)
	{				
		g_pLTServer->FindNamedObjects(m_Fades[i].m_ObjectName, objArray);

		if (objArray.NumObjects())
		{
			HOBJECT hObject = objArray.GetObject(0);
			m_Fades[i].m_hTarget = hObject;
		}

		SetupCurrentValue(&m_Fades[i]);
	}

	m_State = CState_Fade;
    Activate();
}
Example #28
0
uint32 SpecialFX::EngineMessageFn(uint32 messageID, void *pData, float fData)
{
	switch (messageID)
	{
		case MID_PRECREATE :
		{
			uint32 dwRet = GameBase::EngineMessageFn(messageID, pData, fData);

			ObjectCreateStruct *pOcs = (ObjectCreateStruct *)pData;

			if ((uint32)fData == PRECREATE_WORLDFILE || (uint32)fData == PRECREATE_STRINGPROP)
			{
				// Read in object properties

				ReadProps(pOcs);
			}
			
			return dwRet;
		}
		break;
		
		case MID_INITIALUPDATE :
		{
			m_bFromSavedGame = ((uint32)fData == INITIALUPDATE_SAVEGAME);
			if ( !m_bFromSavedGame )
			{
				SetNextUpdate(UPDATE_NEVER);
			}
		}
		break;

		case MID_ALLOBJECTSCREATED :
		{
			if( !m_bFromSavedGame )
			{

				// See if we have a Target object...

				if( m_hstrTargetName )
				{
					ObjArray<HOBJECT, 1> objArray;
					g_pLTServer->FindNamedObjects( g_pLTServer->GetStringData( m_hstrTargetName ), objArray );

					if( objArray.NumObjects() > 0 )
					{
						m_hTargetObj = objArray.GetObject( 0 );
					}

					FREE_HSTRING( m_hstrTargetName );
				}

				if (m_bStartOn)
				{
					TurnON();
				}
			}
		}
		break;

		case MID_SAVEOBJECT :
		{			
			// Handle saving

			GameBase::EngineMessageFn(messageID, pData, fData);	
			OnSave((ILTMessage_Write*)pData, (uint32)fData);
			return LT_OK;
		}
		break;

		case MID_LOADOBJECT :
		{
			// Handle loading
			
			GameBase::EngineMessageFn(messageID, pData, fData);
			OnLoad((ILTMessage_Read*)pData, (uint32)fData);
			return LT_OK;
		}
		break;
	}

	return GameBase::EngineMessageFn(messageID, pData, fData);
}
Example #29
0
void WorldModel::HandleAttachMsg( const CParsedMsg &cMsg, const char *szClass )
{
	if( cMsg.GetArgCount() >= 2 && !szClass )
	{
		// Look for the specific objects we want to attach

		for( uint i = 1; i < cMsg.GetArgCount( ); i++ )
		{
			const char *pObjName = cMsg.GetArg(i).c_str();
			if( !pObjName )
				break;

			ObjArray<HOBJECT, 1> objArray;
			g_pLTServer->FindNamedObjects( const_cast<char*>(pObjName), objArray );

			if( objArray.NumObjects() )
			{
				AttachObject( objArray.GetObject( 0 ) );
			}
		}
	}
	else
	{
		if( m_vAttachDir.MagSqr() > 1.0f )
		{
			// Grab an object in the direction of the attach vector and attach it

			IntersectQuery	IQuery;
			IntersectInfo	IInfo;

			g_pLTServer->GetObjectPos( m_hObject, &IQuery.m_From );
			IQuery.m_To = IQuery.m_From + m_vAttachDir;

			IQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;

			if( g_pLTServer->IntersectSegment( &IQuery, &IInfo ) )
			{
				// Only attach objects of a specific class type...

				if( IInfo.m_hObject && IsKindOf( IInfo.m_hObject, szClass ))
				{
					if( m_hAttachDirObj )
						DetachObject( m_hAttachDirObj );

					m_hAttachDirObj = IInfo.m_hObject;
					AttachObject( m_hAttachDirObj );
				}
			}
		}
		else
		{
			LTVector	vPos;
			LTRotation	rRot;
			LTMatrix	mMat;

			g_pLTServer->GetObjectPos( m_hObject, &vPos );
			g_pLTServer->GetObjectRotation( m_hObject, &rRot );
			rRot.ConvertToMatrix( mMat );

			LTVector vMin, vMax, vDims;

			g_pPhysicsLT->GetObjectDims( m_hObject, &vDims );

			vMin = mMat * (vPos - vDims);
			vMax = mMat * (vPos + vDims);

			ObjectList *pObjList = g_pLTServer->GetBoxIntersecters( &vMin, &vMax );
			if( !pObjList )
				return;

			HOBJECT hObj;

			ObjectLink *pLink = pObjList->m_pFirstLink;
			while( pLink )
			{
				hObj = pLink->m_hObject;
				if( hObj && IsKindOf( hObj, szClass ))
				{
					AttachObject( hObj );

					// add it to our list of objects attached via the ATTACH message...
					LTObjRefNotifier ref( *this );
					ref = hObj;
					m_AttachMsgObjList.push_back( ref );
				}
				pLink = pLink->m_pNext;
			}

			g_pLTServer->RelinquishList( pObjList );
			pObjList = NULL;
		}
	}
}
Example #30
0
static void PrintPiecesThread(void* pv)
{
	CFrameWndEx* pFrame = (CFrameWndEx*)pv;
	CView* pView = pFrame->GetActiveView();
	CPrintDialog PD(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_NOSELECTION, pFrame);

	if (theApp.DoPrintDialog(&PD) != IDOK)
		return; 

	if (PD.m_pd.hDC == NULL)
		return;

	Project* project = lcGetActiveProject();
	ObjArray<lcPiecesUsedEntry> PiecesUsed;

	project->GetPiecesUsed(PiecesUsed);
	PiecesUsed.Sort(PiecesUsedSortFunc, NULL);

	// gather file to print to if print-to-file selected
	CString strOutput;
	if (PD.m_pd.Flags & PD_PRINTTOFILE)
	{
		CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
		CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
		CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
		CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
		CFileDialog dlg(FALSE, strDef, strPrintDef,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
		dlg.m_ofn.lpstrTitle = strCaption;
		if (dlg.DoModal() != IDOK)
			return;
		strOutput = dlg.GetPathName();
	}

	CString DocName;
	char* Ext = strrchr(project->m_strTitle, '.');
	DocName.Format("LeoCAD - %.*s BOM", Ext ? Ext - project->m_strTitle : strlen(project->m_strTitle), project->m_strTitle);
	DOCINFO docInfo;
	memset(&docInfo, 0, sizeof(DOCINFO));
	docInfo.cbSize = sizeof(DOCINFO);
	docInfo.lpszDocName = DocName;
	CString strPortName;

	int nFormatID;
	if (strOutput.IsEmpty())
	{
		docInfo.lpszOutput = NULL;
		strPortName = PD.GetPortName();
		nFormatID = AFX_IDS_PRINTONPORT;
	}
	else
	{
		docInfo.lpszOutput = strOutput;
		AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
		nFormatID = AFX_IDS_PRINTTOFILE;
	}

	SetAbortProc(PD.m_pd.hDC, _AfxAbortProc);
	pFrame->EnableWindow(FALSE);
	CPrintingDialog dlgPrintStatus(NULL);

	CString strTemp;
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, DocName);
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD.GetDeviceName());
	AfxFormatString1(strTemp, nFormatID, strPortName);
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp);
	dlgPrintStatus.ShowWindow(SW_SHOW);
	dlgPrintStatus.UpdateWindow();

	if (StartDoc(PD.m_pd.hDC, &docInfo) == SP_ERROR)
	{
		pFrame->EnableWindow(TRUE);
		dlgPrintStatus.DestroyWindow();
		AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
		return;
	}

	int ResX = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSX);
	int ResY = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSY);

	CRect RectDraw(0, 0, GetDeviceCaps(PD.m_pd.hDC, HORZRES), GetDeviceCaps(PD.m_pd.hDC, VERTRES));
	DPtoLP(PD.m_pd.hDC, (LPPOINT)(RECT*)&RectDraw, 2);
	RectDraw.DeflateRect((int)(ResX*(float)theApp.GetProfileInt("Default","Margin Left", 50)/100.0f),
	                     (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Top", 50)/100.0f),
	                     (int)(ResX*(float)theApp.GetProfileInt("Default","Margin Right", 50)/100.0f),
	                     (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Bottom", 50)/100.0f));

	CRect HeaderRect = RectDraw;
 	HeaderRect.top -= (int)(ResY*theApp.GetProfileInt("Default", "Margin Top", 50) / 200.0f);
	HeaderRect.bottom += (int)(ResY*theApp.GetProfileInt("Default", "Margin Bottom", 50) / 200.0f);

	int RowsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Rows", 10);
	int ColsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Columns", 3);
	int PicHeight = RectDraw.Height() / RowsPerPage;
	int PicWidth = RectDraw.Width() / ColsPerPage;
	int TotalRows = (PiecesUsed.GetSize() + ColsPerPage - 1) / ColsPerPage;
	int TotalPages = (TotalRows + RowsPerPage - 1) / RowsPerPage;
	int RowHeight = RectDraw.Height() / RowsPerPage;
	int ColWidth = RectDraw.Width() / ColsPerPage;

	PD.m_pd.nMinPage = 1;
	PD.m_pd.nMaxPage = TotalPages + 1;

	UINT EndPage = PD.m_pd.nToPage;
	UINT StartPage = PD.m_pd.nFromPage;
	if (PD.PrintAll())
	{
		EndPage = PD.m_pd.nMaxPage;
		StartPage = PD.m_pd.nMinPage;
	}

	lcClamp(EndPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage);
	lcClamp(StartPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage);
	int StepPage = (EndPage >= StartPage) ? 1 : -1;

	VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));

	// begin page printing loop
	BOOL bError = FALSE;

	// Creating Compatible Memory Device Context
	CDC *pMemDC = new CDC;
	if (!pMemDC->CreateCompatibleDC(pView->GetDC()))
		return;

	BITMAPINFO bi;
	ZeroMemory(&bi, sizeof(BITMAPINFO));
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = PicWidth;
	bi.bmiHeader.biHeight = PicHeight;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 24;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = PicWidth * PicHeight * 3;
	bi.bmiHeader.biXPelsPerMeter = 2925;
	bi.bmiHeader.biYPelsPerMeter = 2925;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;
	
	LPBITMAPINFOHEADER lpbi[1];

	HBITMAP hBm, hBmOld;
    hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0);
	if (!hBm)
		return;
	hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm);

	PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI,
			PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };
	int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd);
	DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
	SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd);
	HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc());
	wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc);

	GL_DisableVertexBufferObject();
	float Aspect = (float)PicWidth/(float)PicHeight;

	glViewport(0, 0, PicWidth, PicHeight);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(0.5f, 0.1f);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glClearColor(1, 1, 1, 1); 

	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	lf.lfHeight = -MulDiv(12, ResY, 72);
	lf.lfWeight = FW_REGULAR;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfQuality = PROOF_QUALITY;
	strcpy (lf.lfFaceName , "Arial");

	HFONT HeaderFont = CreateFontIndirect(&lf);
	HFONT OldFont = (HFONT)SelectObject(PD.m_pd.hDC, HeaderFont);
	SetBkMode(PD.m_pd.hDC, TRANSPARENT);
	SetTextColor(PD.m_pd.hDC, 0x000000);
	SetTextAlign(PD.m_pd.hDC, TA_CENTER|TA_NOUPDATECP);

	DWORD PrintOptions = AfxGetApp()->GetProfileInt("Settings", "Print", PRINT_NUMBERS | PRINT_BORDER/*|PRINT_NAMES*/);
	bool DrawNames = 1;//(PrintOptions & PRINT_NAMES) != 0;
	bool Horizontal = 1;//(PrintOptions & PRINT_HORIZONTAL) != 0;

	pMemDC->SetTextColor(0x000000);
	pMemDC->SetBkMode(TRANSPARENT);
//	lf.lfHeight = -MulDiv(40, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72);
//	lf.lfWeight = FW_BOLD;
	HFONT CatalogFont = CreateFontIndirect(&lf);
	lf.lfHeight = -MulDiv(80, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72);
	HFONT CountFont = CreateFontIndirect(&lf);
	HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont);
	HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC, GetStockObject(BLACK_PEN));

	for (UINT CurPage = StartPage; CurPage != EndPage; CurPage += StepPage)
	{
		TCHAR szBuf[80];
		wsprintf(szBuf, strTemp, CurPage);
		dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf);
		if (::StartPage(PD.m_pd.hDC) < 0)
		{
			bError = TRUE;
			break;
		}

		// Draw header and footer.
		SelectObject(PD.m_pd.hDC, HeaderFont);

		CString Header;
		UINT Align;

		FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Header", ""), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages);
		Align |= DT_TOP|DT_SINGLELINE;

		DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align);

		FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Footer", "Page &P"), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages);
		Align |= DT_BOTTOM|DT_SINGLELINE;

		DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align);

		int StartPiece = (CurPage - 1) * RowsPerPage * ColsPerPage;
		int EndPiece = lcMin(StartPiece + RowsPerPage * ColsPerPage, PiecesUsed.GetSize());

		for (int CurPiece = StartPiece; CurPiece < EndPiece; CurPiece++)
		{
			FillRect(pMemDC->m_hDC, CRect(0, PicHeight, PicWidth, 0), (HBRUSH)GetStockObject(WHITE_BRUSH));
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			PieceInfo* pInfo = PiecesUsed[CurPiece].Info;
			pInfo->ZoomExtents(30.0f, Aspect);

			pInfo->RenderPiece(PiecesUsed[CurPiece].ColorIndex);
			glFinish();

			// Draw description text at the bottom.
			CRect TextRect(0, 0, PicWidth, PicHeight);
	
			if (DrawNames)
			{
				SelectObject(pMemDC->m_hDC, CatalogFont);
				pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_CALCRECT | DT_WORDBREAK);

				TextRect.OffsetRect(0, PicHeight - TextRect.Height() - 5);
				pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_WORDBREAK);
			}

			// Draw count.
			SelectObject(pMemDC->m_hDC, CountFont);
			TextRect = CRect(0, 0, PicWidth, TextRect.top);
			TextRect.DeflateRect(5, 5);

			char CountStr[16];
			sprintf(CountStr, "%dx", PiecesUsed[CurPiece].Count);
			pMemDC->DrawText(CountStr, strlen(CountStr), TextRect, DT_BOTTOM | DT_LEFT | DT_SINGLELINE);

			LPBITMAPINFOHEADER lpbi[1];
			lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24));
			BITMAPINFO bi;
			ZeroMemory(&bi, sizeof(BITMAPINFO));
			memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER));
			SetStretchBltMode(PD.m_pd.hDC, COLORONCOLOR);

			int CurRow, CurCol;

			if (Horizontal)
			{
				CurRow = (CurPiece - StartPiece) / ColsPerPage;
				CurCol = (CurPiece - StartPiece) % ColsPerPage;
			}
			else
			{
				CurRow = (CurPiece - StartPiece) % RowsPerPage;
				CurCol = (CurPiece - StartPiece) / RowsPerPage;
			}
			
			int Left = RectDraw.left + ColWidth * CurCol + (ColWidth - PicWidth) / 2;
			int Top = RectDraw.top + RowHeight * CurRow + (RowHeight - PicHeight) / 2;

			StretchDIBits(PD.m_pd.hDC, Left, Top, PicWidth, PicHeight, 0, 0, PicWidth, PicHeight, 
			              (LPBYTE)lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY);
			if (lpbi[0])
				GlobalFreePtr(lpbi[0]);
		}

		if (::EndPage(PD.m_pd.hDC) < 0 || !_AfxAbortProc(PD.m_pd.hDC, 0))
		{
			bError = TRUE;
			break;
		}
	}

	SelectObject(pMemDC->m_hDC, hpOld);
	SelectObject(PD.m_pd.hDC, OldFont);
	DeleteObject(HeaderFont);
	SelectObject(pMemDC->m_hDC, OldMemFont);
	DeleteObject(CatalogFont);
	DeleteObject(CountFont);

	GL_EnableVertexBufferObject();
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hmemrc);
	SelectObject(pMemDC->GetSafeHdc(), hBmOld);
	DeleteObject(hBm);
	delete pMemDC;

	if (!bError)
		EndDoc(PD.m_pd.hDC);
	else
		AbortDoc(PD.m_pd.hDC);

	pFrame->EnableWindow();
	dlgPrintStatus.DestroyWindow();

	if (PD.m_pd.hDC != NULL)
    {
		::DeleteDC(PD.m_pd.hDC);
		PD.m_pd.hDC = NULL;
    }
}