////////////////////////////////////////////////////////////////////// // // Crytek Source code // Copyright (c) Crytek 2001-2004 // // // ScriptObjectGame.cpp: implementation of the CScriptObjectGame class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #if defined LINUX #include #else #include #endif #include "Game.h" #include "XServer.h" #include "ScriptObjectGame.h" #include "UIHud.h" #include "ScriptObjectRenderer.h" #include "PlayerSystem.h" #include "Xplayer.h" #include "Spectator.h" #include "IngameDialog.h" #include "XSystemBase.h" #include "Flock.h" #include #include "ScriptObjectVector.h" #include "ScriptTimerMgr.h" #include #include "WeaponClass.h" #include "WeaponSystemEx.h" // for the definition of AIObjectPlayer #include #include #include #include "GameMods.h" #if !defined(LINUX) # include # pragma comment (lib, "version.lib") #else #include #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// _DECLARE_SCRIPTABLEEX(CScriptObjectGame) CScriptObjectGame::CScriptObjectGame() { m_pGame=NULL; } CScriptObjectGame::~CScriptObjectGame() { while(!m_vRenderersObjs.empty()) { CScriptObjectRenderer *p=m_vRenderersObjs.back(); m_vRenderersObjs.pop_back(); delete p; } if(m_psoNavigationPoint) m_psoNavigationPoint->Release(); if(m_psoVector) m_psoVector->Release(); //! Release players pool. for (unsigned int i = 0; i < m_pPlayersPool.size(); i++) { if (m_pPlayersPool[i]) m_pPlayersPool[i]->Release(); } } void CScriptObjectGame::Init(IScriptSystem *pScriptSystem,CXGame *pGame) { m_pGame=pGame; m_pSystem=pGame->GetSystem(); m_pConsole=m_pSystem->GetIConsole(); m_pRenderer=m_pSystem->GetIRenderer(); m_p3DEngine=m_pSystem->GetI3DEngine(); m_pEntitySystem=m_pSystem->GetIEntitySystem(); m_pPhysicalWorld=m_pSystem->GetIPhysicalWorld(); m_pInput=m_pSystem->GetIInput(); InitGlobal(pScriptSystem,"Game",this); m_psoNavigationPoint=pScriptSystem->CreateObject(); m_psoVector=pScriptSystem->CreateObject(); m_pScriptSystem->SetGlobalValue("PICK_SELONLY", PICK_SELONLY); m_pScriptSystem->SetGlobalValue("PICK_SELADD", PICK_SELADD); m_pScriptSystem->SetGlobalValue("PICK_SELSUB", PICK_SELSUB); m_pScriptSystem->SetGlobalValue("VF_REQUIRE_NET_SYNC", VF_REQUIRE_NET_SYNC); // player's vehicle states m_pScriptSystem->SetGlobalValue("PVS_OUT", CPlayer::PVS_OUT ); m_pScriptSystem->SetGlobalValue("PVS_DRIVER", CPlayer::PVS_DRIVER ); m_pScriptSystem->SetGlobalValue("PVS_GUNNER", CPlayer::PVS_GUNNER ); m_pScriptSystem->SetGlobalValue("PVS_PASSENGER", CPlayer::PVS_PASSENGER ); // entity classes m_pScriptSystem->SetGlobalValue("SPECTATOR_CLASS_ID",SPECTATOR_CLASS_ID); m_pScriptSystem->SetGlobalValue("ADVCAMSYSTEM_CLASS_ID",ADVCAMSYSTEM_CLASS_ID); m_pScriptSystem->SetGlobalValue("PLAYER_CLASS_ID",PLAYER_CLASS_ID); m_pScriptSystem->SetGlobalValue("SYNCHED2DTABLE_CLASS_ID",SYNCHED2DTABLE_CLASS_ID); m_pGetTagPoint.Create( pScriptSystem ); } void CScriptObjectGame::Reset() { if(m_vRenderersObjs.size()) { while(!m_vRenderersObjs.empty()) { CScriptObjectRenderer *p=m_vRenderersObjs.back(); m_vRenderersObjs.pop_back(); delete p; } } } //------------------------------------------------------------------------------------------------- void CScriptObjectGame::OnNETServerFound(CIPAddress &ip, SXServerInfos &pServerInfo) { _SmartScriptObject pServer(m_pScriptSystem); pServer->SetValue("Name", pServerInfo.strName.c_str()); pServer->SetValue("Map", pServerInfo.strMap.c_str()); pServer->SetValue("Players", (int)pServerInfo.nPlayers); pServer->SetValue("MaxPlayers", (int)pServerInfo.nMaxPlayers); pServer->SetValue("GameType", pServerInfo.strGameType.c_str()); pServer->SetValue("Mod", pServerInfo.strMod.c_str()); pServer->SetValue("Ping", (int)pServerInfo.nPing); pServer->SetValue("IP", pServerInfo.IP.GetAsString(true)); pServer->SetValue("Password", (int)((pServerInfo.nServerFlags&SXServerInfos::FLAG_PASSWORD) ? 1 : 0)); pServer->SetValue("CheatsEnabled", (int)((pServerInfo.nServerFlags&SXServerInfos::FLAG_CHEATS) ? 1 : 0)); char str[80]; pServerInfo.VersionInfo.ToString(str); pServer->SetValue("GameVersion", str); pServer->SetValue("InternetServer", (int)((pServerInfo.nServerFlags&SXServerInfos::FLAG_NET) ? 1 : 0)); pServer->SetValue("ComputerType", (int)pServerInfo.nComputerType); pServer->SetValue("PunkBuster", (int)((pServerInfo.nServerFlags & SXServerInfos::FLAG_PUNKBUSTER) ? 1 : 0) ); HSCRIPTFUNCTION pfOnNETServerFound = 0; if (m_pScriptThis->GetValue("OnNETServerFound", pfOnNETServerFound)) { m_pScriptSystem->BeginCall(pfOnNETServerFound); m_pScriptSystem->PushFuncParam(GetScriptObject()); m_pScriptSystem->PushFuncParam(pServer); m_pScriptSystem->EndCall(); } m_pScriptSystem->ReleaseFunc(pfOnNETServerFound); } //------------------------------------------------------------------------------------------------- void CScriptObjectGame::OnNETServerTimeout(CIPAddress &ip) { _SmartScriptObject pServer(m_pScriptSystem); pServer->SetValue("Name", ""); pServer->SetValue("Map", ""); pServer->SetValue("Players", 0); pServer->SetValue("MaxPlayers", 0); pServer->SetValue("GameType", ""); pServer->SetValue("Mod", ""); pServer->SetValue("Ping", 0); pServer->SetValue("IP", ip.GetAsString(true)); pServer->SetValue("Password", 0); pServer->SetValue("CheatsEnabled", 0); pServer->SetValue("GameVersion", ""); pServer->SetValue("InternetServer", 0); pServer->SetValue("ComputerType", 0); pServer->SetValue("PunkBuster", 0); HSCRIPTFUNCTION pfOnNETServerTimeout = 0; if (m_pScriptThis->GetValue("OnNETServerTimeout", pfOnNETServerTimeout)) { m_pScriptSystem->BeginCall(pfOnNETServerTimeout); m_pScriptSystem->PushFuncParam(GetScriptObject()); m_pScriptSystem->PushFuncParam(pServer); m_pScriptSystem->EndCall(); } m_pScriptSystem->ReleaseFunc(pfOnNETServerTimeout); } //------------------------------------------------------------------------------------------------- void CScriptObjectGame::InitializeTemplate(IScriptSystem *pSS) { _ScriptableEx::InitializeTemplate(pSS); REG_FUNC(CScriptObjectGame,GetCDPath); REG_FUNC(CScriptObjectGame,GetUserName); REG_FUNC(CScriptObjectGame,Load); REG_FUNC(CScriptObjectGame,GetPlayers); REG_FUNC(CScriptObjectGame,SetHUDFont);//<> move to Client REG_FUNC(CScriptObjectGame,WriteHudNumber);//<> move to Client REG_FUNC(CScriptObjectGame,WriteHudString);//<> move to Client REG_FUNC(CScriptObjectGame,WriteHudStringFixed);//<> move to Client REG_FUNC(CScriptObjectGame,GetHudStringSize);//<> move to Client REG_FUNC(CScriptObjectGame,GetServerList); REG_FUNC(CScriptObjectGame,GetMaterialIDByName); REG_FUNC(CScriptObjectGame,ReloadMaterialPhysics); REG_FUNC(CScriptObjectGame,GetActions); REG_FUNC(CScriptObjectGame,IsPlayer); REG_FUNC(CScriptObjectGame,GetEntitiesScreenSpace); REG_FUNC(CScriptObjectGame,GetPlayerEntitiesInRadius); REG_FUNC(CScriptObjectGame,DrawRadar); REG_FUNC(CScriptObjectGame,DrawHalfCircleGauge); REG_FUNC(CScriptObjectGame,ShowIngameDialog); REG_FUNC(CScriptObjectGame,HideIngameDialog); REG_FUNC(CScriptObjectGame,EnableUIOverlay); REG_FUNC(CScriptObjectGame,IsUIOverlay); REG_FUNC(CScriptObjectGame,GetEntityTeam); REG_FUNC(CScriptObjectGame,GetTeamScore); REG_FUNC(CScriptObjectGame,GetTeamFlags); REG_FUNC(CScriptObjectGame,Connect); REG_FUNC(CScriptObjectGame,Reconnect); REG_FUNC(CScriptObjectGame,Disconnect); REG_FUNC(CScriptObjectGame,GetLevelList); REG_FUNC(CScriptObjectGame,LoadLevel); REG_FUNC(CScriptObjectGame,GetLevelName); REG_FUNC(CScriptObjectGame,LoadLevelListen); REG_FUNC(CScriptObjectGame,LoadLevelMPServer); REG_FUNC(CScriptObjectGame,GetVersion); REG_FUNC(CScriptObjectGame,GetVersionString); REG_FUNC(CScriptObjectGame,CreateVariable); REG_FUNC(CScriptObjectGame,RemoveVariable); REG_FUNC(CScriptObjectGame,SetVariable); REG_FUNC(CScriptObjectGame,GetVariable); REG_FUNC(CScriptObjectGame,Save); REG_FUNC(CScriptObjectGame,Quit); REG_FUNC(CScriptObjectGame,IsPointInWater); REG_FUNC(CScriptObjectGame,GetWaterHeight); REG_FUNC(CScriptObjectGame,RefreshServerList);//<> move to Client REG_FUNC(CScriptObjectGame,ClearServerInfo); REG_FUNC(CScriptObjectGame,GetServerInfo); REG_FUNC(CScriptObjectGame,GetServerListInfo); REG_FUNC(CScriptObjectGame,ExecuteRConCommand); REG_FUNC(CScriptObjectGame,IsServer); REG_FUNC(CScriptObjectGame,IsClient); REG_FUNC(CScriptObjectGame,IsMultiplayer); REG_FUNC(CScriptObjectGame,SetTimer); REG_FUNC(CScriptObjectGame,KillTimer); REG_FUNC(CScriptObjectGame,StartRecord); REG_FUNC(CScriptObjectGame,StopRecord); REG_FUNC(CScriptObjectGame,StartDemoPlay); REG_FUNC(CScriptObjectGame,StopDemoPlay); REG_FUNC(CScriptObjectGame,DisplayNetworkStats); REG_FUNC(CScriptObjectGame,ForceScoreBoard); REG_FUNC(CScriptObjectGame,ReloadMaterials); REG_FUNC(CScriptObjectGame,GetTagPoint); REG_FUNC(CScriptObjectGame,GetMaterialBySurfaceID); REG_FUNC(CScriptObjectGame,ReloadWeaponScripts); REG_FUNC(CScriptObjectGame,AddWeapon); REG_FUNC(CScriptObjectGame,GetWeaponClassIDByName); REG_FUNC(CScriptObjectGame,SetThirdPerson); REG_FUNC(CScriptObjectGame,SetViewAngles); REG_FUNC(CScriptObjectGame,DumpEntities); REG_FUNC(CScriptObjectGame,TouchCheckPoint); REG_FUNC(CScriptObjectGame,LoadLatestCheckPoint); REG_FUNC(CScriptObjectGame,ShowSaveGameMenu); REG_FUNC(CScriptObjectGame,GetSaveGameList); REG_FUNC(CScriptObjectGame,ToggleMenu); REG_FUNC(CScriptObjectGame,ShowMenu); REG_FUNC(CScriptObjectGame,HideMenu); REG_FUNC(CScriptObjectGame,IsInMenu); // REG_FUNC(CScriptObjectGame,TraceGrenade); REG_FUNC(CScriptObjectGame,SendMessage); REG_FUNC(CScriptObjectGame,GetEntityClassIDByClassName); REG_FUNC(CScriptObjectGame,SetCameraFov); REG_FUNC(CScriptObjectGame,GetCameraFov); REG_FUNC(CScriptObjectGame,ApplyStormToEnvironment); REG_FUNC(CScriptObjectGame,CreateExplosion); REG_FUNC(CScriptObjectGame,DrawLabel); REG_FUNC(CScriptObjectGame,GetInstantHit); REG_FUNC(CScriptObjectGame,GetMeleeHit); REG_FUNC(CScriptObjectGame,SaveConfiguration); REG_FUNC(CScriptObjectGame,LoadConfiguration); REG_FUNC(CScriptObjectGame,LoadConfigurationEx); REG_FUNC(CScriptObjectGame,RemoveConfiguration); REG_FUNC(CScriptObjectGame,DrawHealthBar); REG_FUNC(CScriptObjectGame,__RespawnEntity); REG_FUNC(CScriptObjectGame,ListPlayers); REG_FUNC(CScriptObjectGame,LoadScript); REG_FUNC(CScriptObjectGame,ForceEntitiesToSleep); REG_FUNC(CScriptObjectGame,CreateRenderer); REG_FUNC(CScriptObjectGame,SoundEvent); REG_FUNC(CScriptObjectGame,CheckMap); REG_FUNC(CScriptObjectGame,GetMapDefaultMission); REG_FUNC(CScriptObjectGame,CleanUpLevel); REG_FUNC(CScriptObjectGame,SavePlayerPos); REG_FUNC(CScriptObjectGame,LoadPlayerPos); REG_FUNC(CScriptObjectGame,PlaySubtitle); //REG_FUNC(CScriptObjectGame,SetListener); REG_FUNC(CScriptObjectGame,GetModsList); REG_FUNC(CScriptObjectGame,LoadMOD); REG_FUNC(CScriptObjectGame,GetCurrentModName); REG_FUNC(CScriptObjectGame,AddCommand); REG_FUNC(CScriptObjectGame,EnableQuicksave); } int CScriptObjectGame::GetCDPath(IFunctionHandler *pH) { string szCDPath; if (m_pGame->GetCDPath(szCDPath)) { return pH->EndFunction(szCDPath.c_str()); } return pH->EndFunctionNull(); } int CScriptObjectGame::GetUserName(IFunctionHandler *pH) { CHECK_PARAMETERS(0); return pH->EndFunction(m_pSystem->GetUserName()); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::ForceEntitiesToSleep(IFunctionHandler *pH) { if (!m_pGame->IsDevModeEnable()) return (pH->EndFunction()); IEntity *pLocal=m_pGame->GetMyPlayer(); IEntityItPtr pEntities=m_pSystem->GetIEntitySystem()->GetEntityIterator(); pEntities->MoveFirst(); IEntity *pEnt=NULL; while((pEnt=pEntities->Next())!=NULL) { //EntityClass *pClass=pECR->GetByClass(pEnt->GetEntityClassName()); if (pEnt==pLocal) continue; // do not put to sleep ourselves IAIObject *pAI=pEnt->GetAI(); if (!pAI || (pAI->GetType()==AIOBJECT_PLAYER)) continue; pAI->Event(AIEVENT_SLEEP,0); pEnt->SetSleep(true); //Vec3 pos = pEnt->GetPos(); //m_pSystem->GetILog()->Log("ENTITY class=%s/%d ent=%s/%d pos=(%.1f,%.1f,%.1f)", pClass->strClassName.c_str(), pClass->cTypeID, pEnt->GetName(), pEnt->GetId(), pos.x, pos.y, pos.z); } return (pH->EndFunction()); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::__RespawnEntity(IFunctionHandler *pH) { int id=0; pH->GetParam(1,id); if(id) { IEntity *pEnt=m_pEntitySystem->GetEntity(id); if(pEnt){ CEntityDesc ed; pEnt->GetEntityDesc(ed); m_pEntitySystem->RemoveEntity(id,true); m_pEntitySystem->SpawnEntity(ed); } } return pH->EndFunction(); } int CScriptObjectGame::ListPlayers(IFunctionHandler *pH) { if (!m_pGame->GetXSystem() || !m_pGame->m_pServer) { return pH->EndFunctionNull(); } CXServer::XSlotMap &Slots = m_pGame->m_pServer->GetSlotsMap(); m_pConsole->PrintLine("\tid name"); for(CXServer::XSlotMap::iterator it = Slots.begin(); it != Slots.end(); ++it) { CXServerSlot *Slot = it->second; if(Slot->GetPlayerId() != INVALID_WID) { char szLine[512] = {0}; sprintf(szLine, "\t%d %s", Slot->GetID(), Slot->GetName()); m_pConsole->PrintLine(szLine); }; } return pH->EndFunction(); } //! ReloadWeaponScripts int CScriptObjectGame::ReloadWeaponScripts(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pGame->ReloadWeaponScripts(); return pH->EndFunction(); } //! Make sure the weapon is loaded int CScriptObjectGame::AddWeapon(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *pszDesc; pH->GetParam(1, pszDesc); if(pszDesc) { m_pGame->GetWeaponSystemEx()->AddWeapon(pszDesc); } else m_pScriptSystem->RaiseError("Game:AddWeapon parameter is invalid"); return pH->EndFunction(); } //! ReloadWeaponScripts int CScriptObjectGame::GetWeaponClassIDByName(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *name; pH->GetParam(1, name); if(name) { int val = m_pGame->GetWeaponSystemEx()->GetWeaponClassIDByName(name); if (val >= 0) return pH->EndFunction(val); else return pH->EndFunctionNull(); } m_pScriptSystem->RaiseError("Game:GetWeaponClassIDByName parameter is invalid"); return pH->EndFunctionNull(); } int CScriptObjectGame::ReloadMaterials(IFunctionHandler *pH) { m_pGame->m_XSurfaceMgr.LoadMaterials("scripts/materials",true); return pH->EndFunction(); } /*! set a timer callback @param table the object that will receive the OnEvent with ScriptEvent_Timer as eventid @param fMilliseconds duration on the timer @param pParam optional table that will be passed back by the callback @return the timer id */ int CScriptObjectGame::SetTimer(IFunctionHandler *pH) { if(pH->GetParamCount()<2) { m_pScriptSystem->RaiseError("Game.SetTimer wrong number of arguments"); return pH->EndFunctionNull(); } float fMilliseconds; IScriptObject *pParam=m_pScriptSystem->CreateEmptyObject(); IScriptObject *pTable=m_pScriptSystem->CreateEmptyObject(); pH->GetParam(1,pTable); pH->GetParam(2,fMilliseconds); if(!pH->GetParam(3,pParam)) { pParam->Release(); pParam=NULL; } ITimer *pTimer=m_pGame->GetSystem()->GetITimer(); return pH->EndFunction(m_pGame->m_pScriptTimerMgr->AddTimer(pTable,(unsigned int)(pTimer->GetCurrTime()*1000),(unsigned int)(fMilliseconds),pParam,true)); } /*! snooze a timer event @param nTimerID the timer id returned by Game.SetTimer */ int CScriptObjectGame::KillTimer(IFunctionHandler *pH) { CHECK_PARAMETERS(1); int nTimerID; pH->GetParam(1,nTimerID); m_pGame->m_pScriptTimerMgr->RemoveTimer(nTimerID); return pH->EndFunction(); } //!refresh the server list from the LAN network int CScriptObjectGame::RefreshServerList(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pGame->RefreshServerList(); return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::ClearServerInfo(IFunctionHandler *pH) { CHECK_PARAMETERS(0); INETServerSnooper *pSnooper = m_pGame->GetNETSnooper(); assert(pSnooper); pSnooper->ClearList(); return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::GetServerInfo(IFunctionHandler *pH) { CHECK_PARAMETERS(2); INETServerSnooper *pSnooper = m_pGame->GetNETSnooper(); assert(pSnooper); int iPort; char *szIP = 0; if (!pH->GetParam(1, szIP) || !pH->GetParam(2, iPort)) return pH->EndFunctionNull(); CIPAddress ip(iPort, szIP); pSnooper->AddServer(ip); return pH->EndFunction(1); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::ExecuteRConCommand(IFunctionHandler *pH) { CHECK_PARAMETERS(1); IRConSystem *pRCon = m_pGame->GetIRConSystem(); assert(pRCon); char *szCommand = 0; if(!pH->GetParam(1, szCommand)) return pH->EndFunctionNull(); pRCon->ExecuteRConCommand(szCommand); return pH->EndFunction(1); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::GetServerListInfo(IFunctionHandler *pH) { CHECK_PARAMETERS(1); INETServerSnooper *pSnooper = m_pGame->GetNETSnooper(); assert(pSnooper); if (pH->GetParamType(1) != svtObject) return pH->EndFunctionNull(); std::vector vIP; IScriptObject *pServerList = m_pScriptSystem->CreateEmptyObject(); pH->GetParam(1, pServerList); pServerList->BeginIteration(); while(pServerList->MoveNext()) { int iPort = 0; char *szIP = 0; IScriptObject *pServer = m_pScriptSystem->CreateEmptyObject(); pServer->GetValue("IP", (const char* &)szIP); pServer->GetValue("Port", iPort); pSnooper->Release(); if (!szIP || !iPort) { continue; } vIP.push_back(CIPAddress(iPort, szIP)); } pServerList->EndIteration(); pServerList->Release(); pSnooper->AddServerList(vIP); return pH->EndFunction(1); } /*!return all player entity in game @return table filled with all player entity in game */ int CScriptObjectGame::GetPlayers(IFunctionHandler *pH) { CHECK_PARAMETERS(0); _SmartScriptObject pObj(m_pScriptSystem); if(!m_pGame->GetXSystem()) { // no multiplayer system return pH->EndFunction(*pObj); } IEntityItPtr pItor = m_pGame->GetXSystem()->GetEntities(); IEntity *pEntity = 0; int k = 1; while (pEntity = pItor->Next()) { if (m_pGame->GetXSystem()->GetEntityTeam(pEntity->GetId()) < 0) { continue; } pObj->SetAt(k, pEntity->GetScriptObject()); k++; } pObj->SetNullAt(k); return pH->EndFunction(*pObj); } /*! set the font used by the functions WriteHudStrings and WriteHudNumber @param fontname string enumeration the font name @param effectname string enumerationg the font shader */ int CScriptObjectGame::SetHUDFont(IFunctionHandler *pH) { CHECK_PARAMETERS(2); CUIHud *pHud = m_pGame->GetHud(); const char *pFontname; const char *pEffectname; pH->GetParam(1,pFontname); pH->GetParam(2,pEffectname); pHud->SetFont(pFontname, pEffectname); IFFont *pFont = pHud->Getfont(); if (pFont) { pFont->Reset(); } return pH->EndFunction(); } void SetFont(char *pszFontName, char *pszEffectName); int CScriptObjectGame::GetHudStringSize(IFunctionHandler *pH) { float xsize = 10.0f, ysize = 10.0f, fWrapWidth=0; pH->GetParam(2,xsize); pH->GetParam(3,ysize); if (pH->GetParamCount() > 3) { pH->GetParam(4, fWrapWidth); } wstring swString; const char *sStringKey = 0; if (pH->GetParam(1,sStringKey)) { m_pGame->m_StringTableMgr.Localize( sStringKey, swString ); } IFFont *pFont = m_pGame->GetHud()->Getfont(); assert(pFont); pFont->Reset(); pFont->SetSize(vector2f(xsize, ysize)); vector2f l; if (fWrapWidth > 0) { l = pFont->GetWrappedTextSizeW(swString.c_str(), fWrapWidth); } else { l = pFont->GetTextSizeW(swString.c_str()); } float x = l.x/m_pRenderer->ScaleCoordX(1); float y = l.y/m_pRenderer->ScaleCoordY(1); return pH->EndFunction(x,y); //Timur Old not efficient way. //_SmartScriptObject vec(m_pScriptSystem); //vec->SetValue("x", x); //vec->SetValue("y", y); //return pH->EndFunction(vec); } /*! print a string into the Hud @param px x coordinate into the screen(the screen is always normalized to 800x600) @param py y coordinate into the screen(the screen is always normalized to 800x600) @param number number to print @param r red component of the color used to print the number @param g green component of the color used to print the number @param b blue component of the color used to print the number @param bxsize witdh of a single character @param ysize height of a single character */ int CScriptObjectGame::WriteHudNumber(IFunctionHandler *pH) { CHECK_PARAMETERS(9); CUIHud *pHud = m_pGame->GetHud(); int px,py,number; float r,g,b,a,bxsize,ysize; pH->GetParam(1,px); pH->GetParam(2,py); pH->GetParam(3,number); pH->GetParam(4,r); pH->GetParam(5,g); pH->GetParam(6,b); pH->GetParam(7,a); pH->GetParam(8,bxsize); pH->GetParam(9,ysize); pHud->WriteNumber(px,py,number,r,g,b,a,bxsize,ysize); return pH->EndFunction(); } /*! print a string into the Hud with variable size fonts(a letter 'm' is wider than 'i') @param px x coordinate into the screen(the screen is always normalized to 800x600) @param py y coordinate into the screen(the screen is always normalized to 800x600) @param string string to print @param r red component of the color used to print the number @param g green component of the color used to print the number @param b blue component of the color used to print the number @param a alpha component of the color used to print the number @param bxsize witdh of a single character @param ysize height of a single character @param bCenter center the message on screen (returns the starting pos if center was true) */ int CScriptObjectGame::WriteHudString(IFunctionHandler *pH) { //CHECK_PARAMETERS(8); if(pH->GetParamCount()<9) { m_pScriptSystem->RaiseError("CScriptObjectGame::WriteHudString wrong number of arguments"); return pH->EndFunction(); } CUIHud *pHud = m_pGame->GetHud(); int px,py; float r,g,b,a,bxsize,ysize; //const char *pszStr; bool bCenter=false; float fWrapWidth=0; pH->GetParam(1,px); pH->GetParam(2,py); wstring swString; //pH->GetParam(3,pszStr); //m_pGame->m_StringTableMgr.GetString(pH,3,sString,swString); const char *sStringKey = 0; if (pH->GetParam(3,sStringKey)) { m_pGame->m_StringTableMgr.Localize( sStringKey,swString ); } pH->GetParam(4,r); pH->GetParam(5,g); pH->GetParam(6,b); pH->GetParam(7,a); pH->GetParam(8,bxsize); pH->GetParam(9,ysize); IFFont *pFont=pHud->Getfont(); pFont->Reset(); if(pH->GetParamCount()>=10) { pH->GetParam(10,bCenter); if (pH->GetParamCount() >= 11) { pH->GetParam(11, fWrapWidth); } if (bCenter) { vector2f vLen; if (fWrapWidth > 0) { vLen=pFont->GetWrappedTextSizeW(swString.c_str(), fWrapWidth); } else { vLen=pFont->GetTextSizeW(swString.c_str()); } vLen.x*=(m_pSystem->GetIRenderer()->GetWidth()/800.0f); px=800/2-(int)(vLen.x/2); } } pHud->WriteString(px,py,swString.c_str(),r,g,b,a,bxsize,ysize, fWrapWidth); return pH->EndFunction(px); } ////////////////////////////////////////////////////////////////////// /*! print a string into the Hud with fixed size(both letter 'm' and 'i' have the same width) @param px x coordinate into the screen(the screen is always normalized to 800x600) @param py y coordinate into the screen(the screen is always normalized to 800x600) @param string string to print @param r red component of the color used to print the number @param g green component of the color used to print the number @param b blue component of the color used to print the number @param bxsize witdh of a single character @param ysize height of a single character */ int CScriptObjectGame::WriteHudStringFixed(IFunctionHandler *pH) { //#ifdef _XBOX // CHECK_PARAMETERS(9); //#else CHECK_PARAMETERS(10); //#endif CUIHud *pHud = m_pGame->GetHud(); int px,py; float r,g,b,a,bxsize,ysize,fWidthScale; //const char *pszStr; /* #ifdef _XBOX pH->GetParam(1,px); pH->GetParam(2,py); pH->GetParam(3,pszStr); pH->GetParam(4,r); pH->GetParam(5,g); pH->GetParam(6,b); pH->GetParam(7,bxsize); pH->GetParam(8,ysize); pH->GetParam(9,fWidthScale); pHud->WriteStringFixed(px,py,(char*)pszStr,r,g,b,1.0,bxsize,ysize,fWidthScale); #else */ pH->GetParam(1,px); pH->GetParam(2,py); wstring swString; //pH->GetParam(3,pszStr); //m_pGame->m_StringTableMgr.GetString(pH,3,sString,swString); const char *sStringKey = 0; if (pH->GetParam(3,sStringKey)) { m_pGame->m_StringTableMgr.Localize( sStringKey,swString ); } IFFont *pFont=pHud->Getfont(); pFont->Reset(); pH->GetParam(4,r); pH->GetParam(5,g); pH->GetParam(6,b); pH->GetParam(7,a); pH->GetParam(8,bxsize); pH->GetParam(9,ysize); pH->GetParam(10,fWidthScale); pHud->WriteStringFixed(px,py,swString.c_str(),r,g,b,a,bxsize,ysize,fWidthScale); //#endif return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////// /*!under development ...right now doesn't do anything */ int CScriptObjectGame::DisplayNetworkStats(IFunctionHandler *pH) { CHECK_PARAMETERS(0); IFFont *pFont=pFont=m_pSystem->GetICryFont()->GetFont("Default"); pFont->SetCharWidthScale(1.0f); vector2f hsize (16,16); pFont->SetSize(hsize); pFont->SetSameSize(false); color4f hcolor(1,1,1,1.0f); pFont->SetColor(hcolor); pFont->DrawString(10,100,"Network stats"); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////// /*!Get the list of server on the network with related infos @return a table with the server infos */ int CScriptObjectGame::GetServerList(IFunctionHandler *pH) { CHECK_PARAMETERS(0); _SmartScriptObject pObj(m_pScriptSystem); int k=1; for (ServerInfosVecItor i=m_pGame->m_ServersInfos.begin();i!=m_pGame->m_ServersInfos.end();i++) { SXServerInfos tServInfo=(*i).second; _SmartScriptObject pInner(m_pScriptSystem); pInner->SetValue("Name", tServInfo.strName.c_str()); pInner->SetValue("Map", tServInfo.strMap.c_str()); pInner->SetValue("Players", (int)tServInfo.nPlayers); pInner->SetValue("MaxPlayers", (int)tServInfo.nMaxPlayers); pInner->SetValue("Mod", tServInfo.strMod.c_str()); pInner->SetValue("GameType", tServInfo.strGameType.c_str()); pInner->SetValue("Ping", (int)tServInfo.nPing); pInner->SetValue("IP", tServInfo.IP.GetAsString(true)); pInner->SetValue("Password", (int)((tServInfo.nServerFlags&SXServerInfos::FLAG_PASSWORD) ? 1 : 0)); pInner->SetValue("CheatsEnabled", (int)((tServInfo.nServerFlags&SXServerInfos::FLAG_CHEATS) ? 1 : 0)); char str[80]; tServInfo.VersionInfo.ToString(str); pInner->SetValue("GameVersion", str); pInner->SetValue("InternetServer", (int)((tServInfo.nServerFlags&SXServerInfos::FLAG_NET) ? 1 : 0)); pInner->SetValue("ComputerType", (int)tServInfo.nComputerType); pInner->SetValue("PunkBuster", (int)((tServInfo.nServerFlags&SXServerInfos::FLAG_PUNKBUSTER) ? 1 : 0) ); pObj->SetAt(k, *pInner);k++; } //i return pH->EndFunction(*pObj); } /*!create a local client and connect it to a server @param sServer string containing the server name or ip number @param bShowConsole (optional, default true) */ int CScriptObjectGame::Connect(IFunctionHandler *pH) { bool bDoLateSwitch=false, bDoCDAuthorization=false; //if a local server exist shutdown it //m_pGame->ShutdownServer(); const char *sServer=NULL; if(pH->GetParamCount()!=0) pH->GetParam(1,sServer); if(pH->GetParamCount()>1) pH->GetParam(2,bDoLateSwitch); if(pH->GetParamCount()>2) pH->GetParam(3,bDoCDAuthorization); m_pGame->ShutdownClient(); m_pGame->ShutdownServer(); if(sServer==NULL) { if(!m_pGame->m_pServer) return pH->EndFunction(); sServer = "127.0.0.1"; } bool bReturn = true; if (!m_pGame->m_bEditor) { HSCRIPTFUNCTION pfnOnConnectBegin = m_pScriptSystem->GetFunctionPtr("Game", "OnConnectBegin"); if (pfnOnConnectBegin) { m_pScriptSystem->BeginCall(pfnOnConnectBegin); m_pScriptSystem->PushFuncParam(m_pGame->GetScriptObject()); m_pScriptSystem->PushFuncParam(sServer); m_pScriptSystem->EndCall(bReturn); m_pScriptSystem->ReleaseFunc(pfnOnConnectBegin); } } if (!bReturn) { return pH->EndFunctionNull(); } m_pGame->StartupClient(); // if bDoLateSwitch is true then it does the 3 lines below but after the connection is completed. m_pGame->m_pClient->XConnect((char *)sServer, bDoLateSwitch, bDoCDAuthorization); return pH->EndFunction(); } /*!create a local client and reconnect to the last server @param sServer string containing the server name or ip number @param bShowConsole (optional, default true) */ int CScriptObjectGame::Reconnect(IFunctionHandler *pH) { CHECK_PARAMETERS(0); if (!m_pGame->m_szLastAddress.empty()) { m_pScriptSystem->BeginCall("Game", "Connect"); m_pScriptSystem->PushFuncParam(this->GetScriptObject()); m_pScriptSystem->PushFuncParam(m_pGame->m_szLastAddress.c_str()); m_pScriptSystem->PushFuncParam((int)(m_pGame->m_bLastDoLateSwitch ? 1 : 0)); m_pScriptSystem->PushFuncParam((int)(m_pGame->m_bLastCDAuthentication ? 1 : 0)); m_pScriptSystem->EndCall(); } else { m_pConsole->PrintLine("No previous connect command."); } return pH->EndFunction(); } /*!disconnect the current connection to a remote server @param sCause string describing the cause of the disconnection[optional] */ int CScriptObjectGame::Disconnect(IFunctionHandler *pH) { int iCount=pH->GetParamCount(); if(iCount>1) { m_pScriptSystem->RaiseError("Game.Disconnect too many parameters"); return pH->EndFunction(); } const char *sCause=0; if(iCount>0) pH->GetParam(1,sCause); // sCause might get 0 when LUA passed a nil value if(!sCause) sCause="@UserDisconnected"; // if(m_pGame->m_pClient) // m_pGame->m_pClient->XDisconnect(sCause); m_pGame->ShutdownClient(); m_pGame->ShutdownServer(); return pH->EndFunction(); } // Scans the given vector of strings for presence of szString // case-insensitive // returns true when the string is present in the array bool HasStringI (const std::vector &arrStrings, const char* szString) { for (std::vector::const_iterator it = arrStrings.begin(); it != arrStrings.end(); ++it) if (!stricmp(it->c_str(), szString)) return true; return false; } ////////////////////////////////////////////////////////////////////////// // Returns the table - list of levels with the given mission in them int CScriptObjectGame::GetLevelList (IFunctionHandler* pH) { // the first and only parameter is the name of the mission // empty name means all levels will be returned const char* pszMissionFilter = NULL; if (pH->GetParamCount()>=1 && !pH->GetParam(1,pszMissionFilter)) { m_pScriptSystem->RaiseError ( "CScriptObjectGame::GetLevelList : 1st (%s) of %d arguments couldn't be resolved as mission name string.", ScriptVarTypeAsCStr(pH->GetParamType(1)), pH->GetParamCount()); return pH->EndFunctionNull(); } _SmartScriptObject pObj(m_pScriptSystem); int nLevel = 1; string sLevelsFolder = m_pGame->GetLevelsFolder(); //struct __finddata64_t fd; //intptr_t hFind; struct _finddata_t c_file; intptr_t hFile; ICryPak *pIPak = m_pSystem->GetIPak(); if ((hFile = pIPak->FindFirst((sLevelsFolder+string("/*.*")).c_str(),&c_file)) == -1L ) return (pH->EndFunction(*pObj)); //if ((hFind = _findfirst64( (sLevelsFolder+"/*.*").c_str(), &fd )) == -1L) //return (pH->EndFunction(*pObj)); // warning: this should be empty here std::vector arrMissions; do { arrMissions.clear(); if ((strncmp(c_file.name, ".",1)!=0) && (c_file.attrib & _A_SUBDIR) && m_pGame->GetLevelMissions( (sLevelsFolder + "/" +c_file.name).c_str(), arrMissions) && (!pszMissionFilter || HasStringI(arrMissions, pszMissionFilter))) { _SmartScriptObject pLevelObj(m_pScriptSystem); pLevelObj->SetValue("Name", c_file.name); _SmartScriptObject pMissionObj(m_pScriptSystem); for(int i = 0; i < (int)arrMissions.size(); i++) { static char szIndex[4]; pMissionObj->SetValue(itoa(i+1, szIndex, 10), arrMissions[i].c_str()); } pLevelObj->SetValue("MissionList", pMissionObj); // we found a level pObj->SetAt (nLevel, pLevelObj); ++nLevel; } //} while(_findnext64(hFind, &fd)==0); //_findclose(hFind); } while(pIPak->FindNext( hFile, &c_file ) == 0); pIPak->FindClose( hFile ); return pH->EndFunction(*pObj); } /*!Load a level ,start a local client and connect it to the local server, no external connections (sp game) @param sMapName the name of the map to load @param sMissionName the name of the mission[optional] */ int CScriptObjectGame::LoadLevel(IFunctionHandler *pH) { const char *szMapName; const char *szMissionName = ""; if(m_pGame->m_bDedicatedServer) return pH->EndFunction(); pH->GetParam(1,szMapName); if(pH->GetParamCount()==2) pH->GetParam(2,szMissionName); ICVar* pVar = m_pSystem->GetIConsole()->GetCVar("g_GameType"); pVar->Set("Default"); m_pGame->m_tPlayerPersistentData.m_bDataSaved=false; m_pGame->LoadLevelCS(false, szMapName, szMissionName, false); return pH->EndFunction(); } /*!Load a level, start a local client and connect it to the local server, and allow external connections @param sMapName the name of the map to load @param sMissionName the name of the mission[optional] */ int CScriptObjectGame::LoadLevelListen(IFunctionHandler *pH) { const char *szMapName; const char *szMissionName = ""; pH->GetParam(1,szMapName); if(pH->GetParamCount()==2) pH->GetParam(2,szMissionName); m_pGame->LoadLevelCS(false, szMapName, szMissionName, true); return pH->EndFunction(); } /*!Load a level on a mp server, keeping the current clients connected to the current server @param sMapName the name of the map to load @param sMissionName the name of the mission[optional] */ int CScriptObjectGame::LoadLevelMPServer(IFunctionHandler *pH) { const char *szMapName; const char *szMissionName = ""; pH->GetParam(1,szMapName); if(pH->GetParamCount()==2) pH->GetParam(2,szMissionName); m_pGame->LoadLevelCS(true, szMapName, szMissionName, true); return pH->EndFunction(); } /*! Get the game version as a string */ int CScriptObjectGame::GetVersion(IFunctionHandler *pH) { unsigned int dwVersion = GAME_VERSION; unsigned char bPrimary = (GAME_VERSION & 0xff000000) >> 24; unsigned char bSecond = (GAME_VERSION & 0xff0000) >> 16; unsigned short wBuild = (GAME_VERSION & 0xffff); char szVersionString[128] = {0}; if (pH->GetParamCount() > 0) { char *szFormat = 0; pH->GetParam(1, szFormat); if (szFormat) { sprintf(szVersionString, szFormat, bPrimary, bSecond, wBuild); return pH->EndFunction(szVersionString); } } sprintf(szVersionString, "%d.%02d.%03d", bPrimary, bSecond, wBuild); return pH->EndFunction(szVersionString); } int CScriptObjectGame::GetVersionString(IFunctionHandler *pH) { #if !defined(LINUX) char szDate[128] = __DATE__; char *szMonth = szDate; char *szDay = szDate + 4; char *szYear = szDate + 9; unsigned int dwMonth = 0; switch(*((int *)szMonth)) { case ' naJ': dwMonth = 1; break; case ' beF': dwMonth = 2; break; case ' raM': dwMonth = 3; break; case ' rpA': dwMonth = 4; break; case ' yaM': dwMonth = 5; break; case ' nuJ': dwMonth = 6; break; case ' luJ': dwMonth = 7; break; case ' guA': dwMonth = 8; break; case ' peS': dwMonth = 9; break; case ' tcO': dwMonth = 10; break; case ' voN': dwMonth = 11; break; case ' ceD': dwMonth = 12; break; default: assert(0); } szDay[2] = 0; int iBuild = 0; m_pSystem->GetFileVersion(); // get the .exe file name char *szLocalCmdLine = GetCommandLine(); char *p = szLocalCmdLine+1; while (*p && *p != '"') ++p; string szFileName(szLocalCmdLine+1, p); unsigned int dwVersionSize = GetFileVersionInfoSize((char *)szFileName.c_str(), 0); if (dwVersionSize) { unsigned char *pData = new unsigned char [dwVersionSize+1]; if (!pData) { assert(0); } else { char szQueryInfoString[256] = {0}; char *szFileVersionInfo = 0; unsigned int dwSize; PUINT pVersionBuffer = NULL; if (GetFileVersionInfo((char *)szFileName.c_str(), 0, dwVersionSize, pData)) { strcpy(szQueryInfoString, "\\VarFileInfo\\Translation"); if (VerQueryValue(pData, szQueryInfoString, (LPVOID*)&pVersionBuffer, &dwSize) && dwSize == 4) { UINT dwLang = *pVersionBuffer; sprintf(szQueryInfoString, "\\StringFileInfo\\%02X%02X%02X%02X\\FileVersion", (dwLang & 0xff00) >> 8, dwLang & 0xff,(dwLang & 0xff000000) >> 24, (dwLang & 0xff0000) >> 16); } else { sprintf(szQueryInfoString, "\\StringFileInfo\\%04X04B0\\FileVersion", GetUserDefaultLangID()); } if (VerQueryValue(pData, szQueryInfoString, (void **)&szFileVersionInfo, &dwSize) && szFileVersionInfo) { char *szTok = strtok(szFileVersionInfo, "."); szTok = strtok(0, "."); if (szTok) { szTok = strtok(0, "."); if (szTok) { szTok = strtok(0, "."); if (szTok) { iBuild = atoi(szTok); } } } else { char *szTok = strtok(szFileVersionInfo, ","); szTok = strtok(0, ","); if (szTok) { szTok = strtok(0, ","); if (szTok) { szTok = strtok(0, ","); if (szTok) { iBuild = atoi(szTok); } } } } } } delete[] pData; } } char szVersionString[128]; sprintf(szVersionString, "FC%s%d%s%s%d", szDay, dwMonth, szYear, GAME_VERSION_SUFIX, iBuild); #else char szVersionString[ 128 ]; sprintf( szVersionString, "FC %s %d (LINUX)", __DATE__, GAME_VERSION_SUFIX); #endif return pH->EndFunction(szVersionString); } /*!create a console variable @param sName name of the console variable @param sDefault the default value[optional] */ int CScriptObjectGame::CreateVariable(IFunctionHandler *pH) { //CHECK_PARAMETERS(1); int nPCount=pH->GetParamCount(); const char *sName; const char *sDefault; const char *sflags; int iflags=0; pH->GetParam(1,sName); if(nPCount>1) { pH->GetParam(2,sDefault); if (nPCount>2) { switch(pH->GetParamType(3)) { case svtString: if (pH->GetParam(3,sflags)) { if (strcmp(sflags, "NetSynch")==0) iflags=VF_REQUIRE_NET_SYNC; } else m_pSystem->GetILog()->LogWarning("Game:CreateVariable can't get the 3rd parameter (string)"); break; case svtNumber: if (pH->GetParam(3, iflags)) { // do nothing, the flags must be the VF_* flags } else m_pSystem->GetILog()->LogWarning("Game:CreateVariable can't get the 3rd parameter (number)"); break; default: m_pSystem->GetILog()->LogWarning("Game:CreateVariable unexpected 3rd (flags) parameter type (%s)", ScriptVarTypeAsCStr(pH->GetParamType(3))); break; } } } else { sDefault="0"; } m_pConsole->CreateVariable( sName,sDefault,iflags); // TRACE("CreateVariable %s=%s flags=0x%x",sName,sDefault,iflags); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::AddCommand(IFunctionHandler *pH) { int nPCount=pH->GetParamCount(); const char *sName; const char *sCommand; const char *sHelp=NULL; int iflags=0; pH->GetParam(1,sName); if (nPCount>1) { pH->GetParam(2,sCommand); if (nPCount>2) { if (!pH->GetParam(3,sHelp)) sHelp=NULL; } if (sHelp) m_pConsole->AddCommand(sName,sCommand,0,sHelp); else m_pConsole->AddCommand(sName,sCommand,VF_NOHELP,""); } return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::GetLevelName(IFunctionHandler *pH) { CHECK_PARAMETERS(0); return pH->EndFunction(m_pGame->GetLevelName()); } int CScriptObjectGame::GetVariable(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sName; if (!pH->GetParam(1,sName)) { m_pScriptSystem->RaiseError ("GetVariable invalid parameter type %s, string expected", ScriptVarTypeAsCStr(pH->GetParamType(1))); return pH->EndFunctionNull(); } ICVar* pVar = m_pSystem->GetIConsole()->GetCVar(sName); if (!pVar) { m_pScriptSystem->RaiseError("GetVariable invalid variable name \"%s\": no such variable found", sName); return pH->EndFunctionNull(); } switch (pVar->GetType()) { case CVAR_INT: return pH->EndFunction(pVar->GetIVal()); case CVAR_FLOAT: return pH->EndFunction(pVar->GetFVal()); case CVAR_STRING: return pH->EndFunction(pVar->GetString()); default: return pH->EndFunctionNull(); } } int CScriptObjectGame::SetVariable(IFunctionHandler *pH) { CHECK_PARAMETERS(2); const char *sName; if (!pH->GetParam(1,sName)) { m_pScriptSystem->RaiseError ("SetVariable invalid parameter type %s, string expected", ScriptVarTypeAsCStr(pH->GetParamType(1))); return pH->EndFunctionNull(); } ICVar* pVar = m_pSystem->GetIConsole()->GetCVar(sName); if (!pVar) { m_pScriptSystem->RaiseError("SetVariable invalid variable name \"%s\": no such variable found", sName); return pH->EndFunctionNull(); } if ((pVar->GetFlags() & VF_CHEAT) && (!m_pGame->IsDevModeEnable())) { // [martin] hide this message because we don't want to help hacking // m_pSystem->GetILog()->LogWarning ("\001 Variable %s is cheat protected.", sName); return pH->EndFunctionNull(); } switch (pH->GetParamType(2)) { case svtNull: pVar->Set(""); break; case svtString: { const char *pVal; if (!pH->GetParam(2, pVal)) { m_pScriptSystem->RaiseError("SetVariable cannot retrieve the variable %s string value", sName); return pH->EndFunctionNull(); } pVar->Set(pVal); } break; case svtNumber: { int nVal; float fVal; if (pH->GetParam(2, fVal)) pVar->Set(fVal); else if (pH->GetParam(2, nVal)) pVar->Set(nVal); else { m_pScriptSystem->RaiseError("SetVariable cannot retrieve the variable %s numeric value", sName); return pH->EndFunctionNull(); } } break; default: m_pScriptSystem->RaiseError ("SetVariable cannot set the variable %s value: unsupported type %s", sName, ScriptVarTypeAsCStr(pH->GetParamType(2))); break; } return pH->EndFunction(); } /*!save the game on a file @param sFileName the name of the target file[optional] the default "is farcry_save.sav" */ int CScriptObjectGame::Save(IFunctionHandler *pH) { const char *sFileName=""; if(pH->GetParamCount()) pH->GetParam(1,sFileName); m_pGame->Save(sFileName, NULL, NULL); return pH->EndFunction(); } /*!load the game from a file @param sFileName the name of the target file[optional] the default "is farcry_save.sav" */ int CScriptObjectGame::Load(IFunctionHandler *pH) { const char *sFileName=""; if(pH->GetParamCount()) pH->GetParam(1,sFileName); m_pGame->Load(sFileName); return pH->EndFunction(); } int CScriptObjectGame::ShowSaveGameMenu(IFunctionHandler *pH) { return pH->EndFunction(!m_pGame->m_bEditor && !m_pGame->m_strLastSaveGame.empty() && !m_pGame->m_bMenuOverlay); } int CScriptObjectGame::LoadLatestCheckPoint(IFunctionHandler *pH) { m_pGame->LoadLatest(); return pH->EndFunction(); } // call with the number of the checkpoint to cause a game to be saved for it int CScriptObjectGame::TouchCheckPoint(IFunctionHandler *pH) { CHECK_PARAMETERS(3); int cp = 0; _VERIFY(pH->GetParam(1, cp)); _SmartScriptObject tpos(m_pScriptSystem, true); _VERIFY(pH->GetParam(2, tpos)); _SmartScriptObject tangles(m_pScriptSystem, true); _VERIFY(pH->GetParam(3, tangles)); float x, y, z, xa, ya, za; _VERIFY(tpos->GetValue("x", x)); _VERIFY(tpos->GetValue("y", y)); _VERIFY(tpos->GetValue("z", z)); _VERIFY(tangles->GetValue("x", xa)); _VERIFY(tangles->GetValue("y", ya)); _VERIFY(tangles->GetValue("z", za)); Vec3 pos(x, y, z); Vec3 angles(xa, ya, za); char buf[1024]; if (m_pGame->m_pServer) { //[kirill] //this is moved here from bool CXGame::LoadFromStream(CStream &stm, bool isdemo) //instedad of overriding player's health on loading let's save desired value //this change needen for quickload to use restore health int playerCurHealth; IEntity *pLocalEnt=m_pGame->GetMyPlayer(); CPlayer *pPlayer=NULL; IEntityContainer *pLocalCnt=pLocalEnt->GetContainer(); if (pLocalCnt && pLocalCnt->QueryContainerInterface(CIT_IPLAYER, (void **)&pPlayer)) { playerCurHealth = pPlayer->m_stats.health; if(m_pGame->p_restorehalfhealth->GetIVal()) { pPlayer->m_stats.health = 255; // [marco] danger! this should be set by // gamerules but it gets overwritten by the save checkpoint // [kirill] // this was requested by UBI. It's expected here that current health value is the maximum //Everytime Jack dies he should respawn with half of his hit points instead of full health. //Same mechanics for Val, she should get half her hit points everytime Jack respawns. pPlayer->m_stats.health/=2; } if (pPlayer->m_stats.health<128) pPlayer->m_stats.health = 128; } //this is moved is over sprintf(buf, "checkpoint_%s_%s_%d", m_pGame->g_LevelName->GetString(), m_pGame->m_pServer->m_GameContext.strMission.c_str(), cp); m_pGame->Save(buf, &pos, &angles); //[kirill] //restore player's health to current value (used some forced value for "checkpointRestoreHealth" trick) if( pPlayer ) pPlayer->m_stats.health = playerCurHealth; } return pH->EndFunction(); } /*!remove a console variable @param sName the name of the variable */ int CScriptObjectGame::RemoveVariable(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sName; pH->GetParam(1,sName); m_pConsole->UnregisterVariable(sName,true); return pH->EndFunction(); } /*!quit the game */ int CScriptObjectGame::Quit(IFunctionHandler *pH) { CHECK_PARAMETERS(0); //m_pConsole->Exit(NULL); m_pSystem->Quit(); return pH->EndFunction(); } /*!return !=nil if the specified coordinate is under the water level @param vPosition a table with the x,y,z fields containing the position that has to be tested @return !=nil(true) nil(false) */ int CScriptObjectGame::IsPointInWater(IFunctionHandler *pH) { CScriptObjectVector vPosition(m_pScriptSystem,true); CHECK_PARAMETERS(1); pH->GetParam(1, *vPosition); if (m_pSystem->GetI3DEngine()->IsPointInWater(vPosition.Get())) return pH->EndFunction(true); else return pH->EndFunction(false); } /*!return the height of the water level @return the z value of the water level */ int CScriptObjectGame::GetWaterHeight(IFunctionHandler *pH) { //CHECK_PARAMETERS(0); if (pH->GetParamCount()>0) { CScriptObjectVector vPosition(m_pScriptSystem,true); pH->GetParam(1, *vPosition); return pH->EndFunction(m_pSystem->GetI3DEngine()->GetWaterLevel(&vPosition.Get())); } return pH->EndFunction(m_pSystem->GetI3DEngine()->GetWaterLevel()); } /*! */ int CScriptObjectGame::GetActions(IFunctionHandler *pH) { CHECK_PARAMETERS(0); _SmartScriptObject pObj(m_pScriptSystem); ActionsEnumMap &ActionsMap=m_pGame->GetActionsEnumMap(); ActionsEnumMapItor It=ActionsMap.begin(); int i=1; while (It!=ActionsMap.end()) { _SmartScriptObject pVal(m_pScriptSystem); _SmartScriptObject pStrTbl(m_pScriptSystem); pVal->SetValue("name", It->first.c_str()); pVal->SetValue("id", It->second.nId); pVal->SetValue("desc", It->second.sDesc.c_str()); pVal->SetValue("configurable", It->second.bConfigurable); switch(It->second.nType) { case ACTIONTYPE_MOVEMENT: pVal->SetValue("type", "movement"); break; case ACTIONTYPE_COMBAT: pVal->SetValue("type", "combat"); break; case ACTIONTYPE_GAME: pVal->SetValue("type", "game"); break; case ACTIONTYPE_MULTIPLAYER: pVal->SetValue("type", "multiplayer"); break; case ACTIONTYPE_DEBUG: pVal->SetValue("type", "debug"); break; default: pVal->SetValue("type", "misc"); } int j=1; for (Vec2StrIt StrIt=It->second.vecSetToActionMap.begin();StrIt!=It->second.vecSetToActionMap.end();++StrIt) { pStrTbl->SetAt(j, (*StrIt).c_str()); j++; } pVal->SetValue("actionmaps", pStrTbl); pObj->SetAt(i, pVal); i++; ++It; } return pH->EndFunction(pObj); } /*!return true if a certain entity is a player @param the entity id @return !=nil(true) nil(false) */ int CScriptObjectGame::IsPlayer(IFunctionHandler *pH) { CHECK_PARAMETERS(1); int nEntityId; pH->GetParam(1, nEntityId); IEntity *pEnt=m_pSystem->GetIEntitySystem()->GetEntity(nEntityId); if (!pEnt) return pH->EndFunctionNull(); return pH->EndFunction(m_pGame->GetPlayerSystem()->IsPlayerClass(pEnt->GetClassId())); } /*!return true if the local host is a server @return !=nil(true) nil(false) */ int CScriptObjectGame::IsServer(IFunctionHandler *pH) { CHECK_PARAMETERS(0); return pH->EndFunction(m_pGame->IsServer()); } /*!return true if the local host is a client @return !=nil(true) nil(false) */ int CScriptObjectGame::IsClient(IFunctionHandler *pH) { CHECK_PARAMETERS(0); return pH->EndFunction(m_pGame->IsClient()); } /*!return true if we are in multiplayer mode (being either a server or a client) @return !=nil(true) nil(false) */ int CScriptObjectGame::IsMultiplayer(IFunctionHandler *pH) { CHECK_PARAMETERS(0); return pH->EndFunction(m_pGame->IsMultiplayer()); } int CScriptObjectGame::GetEntitiesScreenSpace(IFunctionHandler *pH) { const char *pszBoneName=NULL; if (pH->GetParamCount()>=1) pH->GetParam(1, pszBoneName); _SmartScriptObject pTable(m_pScriptSystem); IEntityItPtr It=m_pSystem->GetIEntitySystem()->GetEntityInFrustrumIterator(); CCamera Cam=m_pSystem->GetViewCamera(); Vec3 CamVec=Cam.GetAngles(); CamVec=ConvertToRadAngles(CamVec); int i=1; IEntity *pEnt; ray_hit RayHit; IEntity *pLocal=m_pGame->GetMyPlayer(); while (pEnt=It->Next()) { if (pEnt==pLocal) continue; if (!pEnt->IsTrackable()) continue; IPhysicalEntity *pPE=pEnt->GetPhysics(); if (!pPE) continue; CPlayer *pPlayer; IEntityContainer *pCnt=pEnt->GetContainer(); if (!pCnt) continue; if (!pCnt->QueryContainerInterface(CIT_IPLAYER, (void **)&pPlayer)) continue; if (!pPlayer->IsAlive() || !pPlayer->IsVisible()) // tiago: make sure only visible stuff is processed continue; pe_status_dynamics dynStats; Vec3 Min, Max; pEnt->GetBBox(Min, Max); Vec3 Center=(Max-Min)/2+Min; Vec3 Position; Vec3 Velocity; _SmartScriptObject pEntity(m_pScriptSystem); CScriptObjectVector pPosition(m_pScriptSystem); CScriptObjectVector pVelocity(m_pScriptSystem); float px, py, pz; float x, y, z; if (!pPE->GetStatus(&dynStats)) { dynStats.v.Set(0,0,0); } else { if (pszBoneName) // if we want a bone instead of bbox-center lets do so... { IEntityCharacter *pIChar=pEnt->GetCharInterface(); if (pIChar) { ICryCharInstance *cmodel=pIChar->GetCharacter(0); if (cmodel) { ICryBone *pBone = cmodel->GetBoneByName(pszBoneName); if (pBone) { Center=pBone->GetBonePosition(); Matrix44 m; m.SetIdentity(); m=GetTranslationMat(pEnt->GetPos())*m; m=Matrix44::CreateRotationZYX(-pEnt->GetAngles()*gf_DEGTORAD)*m; //NOTE: angles in radians and negated Center=m.TransformPointOLD(Center); } } } } } Vec3 diff(Center-Cam.GetPos()); if(GetLengthSquared(diff)>700*700) continue; if (m_pSystem->GetIPhysicalWorld()->RayWorldIntersection(vectorf(Cam.GetPos()), diff, ent_terrain|ent_static,0, &RayHit, 1,pPE)) continue; m_pSystem->GetIRenderer()->ProjectToScreen(Center.x, Center.y, Center.z, &px, &py, &pz); Position.x=(float)px*8.0f; Position.y=(float)py*6.0f; Position.z=(float)pz; if ((Position.x>=0.0f) && (Position.y>=0.0f) && (Position.x<=800.0f) && (Position.y<=600.0f) && (Position.z>0.0f)) { Vec3 PrevPos=Center-(Vec3)dynStats.v; m_pSystem->GetIRenderer()->ProjectToScreen(PrevPos.x, PrevPos.y, PrevPos.z, &x, &y, &z); Velocity.x=(x-px)/100.0f; Velocity.y=(y-py)/100.0f; Velocity.z=CamVec*(Vec3)dynStats.v; pEntity->SetValue("pEntity", pEnt->GetScriptObject()); pPosition=Position; pEntity->SetValue("Position", *pPosition); pVelocity=Velocity; pEntity->SetValue("Velocity", *pVelocity); float fVelLen=cry_sqrtf(Velocity.x*Velocity.x+Velocity.y*Velocity.y); pEntity->SetValue("VelLen", fVelLen); Vec3 pos2d=Position; pos2d.z=0; Vec3 screenCenter(400,300,0); pEntity->SetValue("DistFromCenter",GetDistance(screenCenter,pos2d)); pTable->SetAt(i, *pEntity); i++; } } return pH->EndFunction(*pTable); } int CScriptObjectGame::GetPlayerEntitiesInRadius(IFunctionHandler *pH) { //CHECK_PARAMETERS(3); if(pH->GetParamCount()<3) { m_pScriptSystem->RaiseError("CScriptObjectGame::GetPlayerEntitiesInRadius wrong number of arguments"); return pH->EndFunction(); } ASSERT(m_pGame); ASSERT(m_pEntitySystem); _SmartScriptObject pVec(m_pScriptSystem, true); Vec3 Center; pH->GetParam(1, *pVec); pVec->GetValue("x", Center.x); pVec->GetValue("y", Center.y); pVec->GetValue("z", Center.z); float fRadius; pH->GetParam(2, fRadius); fRadius*=fRadius; // square radius for faster check if(!m_pGame->IsClient()) { return pH->EndFunctionNull(); } // Get output table from script. _SmartScriptObject pTable(m_pScriptSystem,true); pH->GetParam(3, pTable); int iEntityMask=-1; if(pH->GetParamCount()>3) { // 0 = return alive and trackable only, 1= return all pH->GetParam(4, iEntityMask); } EntitiesSet *psetPlayers=NULL; if (m_pGame->IsServer()) { CXServer *pServer=m_pGame->GetServer(); ASSERT(pServer); ASSERT(pServer->m_pISystem); psetPlayers=&(pServer->m_pISystem->GetPlayerEntities()); } else { CXClient *pClient=m_pGame->GetClient(); ASSERT(pClient); ASSERT(pClient->m_pISystem) psetPlayers=&(pClient->m_pISystem->GetPlayerEntities()); } IEntityContainer *pCnt; CPlayer *pPlayer; int nCount=1; unsigned int playerIndex = 0; if (psetPlayers->empty()) { return pH->EndFunctionNull(); } bool bEmpty=true; for (EntitiesSetItor It=psetPlayers->begin();It!=psetPlayers->end();) { EntityId Id=(*It); IEntity *pEntity=m_pEntitySystem->GetEntity(Id); // remove entity from list if not valid if((!pEntity) || ((pCnt=pEntity->GetContainer())==NULL) || (!pCnt->QueryContainerInterface(CIT_IPLAYER, (void **)&pPlayer))) { EntitiesSetItor next = It; next++; psetPlayers->erase(It); It = next; continue; } // skip not needed entities bool bEntityState=1; if(iEntityMask==0 || iEntityMask==-1) { bEntityState= !pEntity->IsTrackable() || !pPlayer->IsAlive(); } if(iEntityMask==1) { bEntityState= !pEntity->IsTrackable(); } if(bEntityState) { ++It; continue; } float fDist2=GetSquaredDistance(pEntity->GetPos(), Center); if (fDist2<=fRadius) { IScriptObject *pEntitySO = 0; if (playerIndex >= m_pPlayersPool.size()) { // Makes new pool object. pEntitySO = m_pScriptSystem->CreateObject(); m_pPlayersPool.push_back( pEntitySO ); } else { // Takes object from pool. pEntitySO = m_pPlayersPool[playerIndex]; } bEmpty=false; pEntitySO->SetValue("nId", pEntity->GetId()); // removed- not being used anywhere pEntitySO->SetValue("pEntity", pEntity->GetScriptObject()); pEntitySO->SetValue("fDistance2", fDist2); pTable->SetAt(nCount++, pEntitySO); playerIndex++; } ++It; } if(!bEmpty) { return pH->EndFunction(); } return pH->EndFunction(); } #define NUM_RADAR_TEXTURES 7 ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::DrawRadar(IFunctionHandler *pH) { CHECK_PARAMETERS(14); ASSERT(m_pEntitySystem); float x, y, w, h, fRange; char *pRadarObjective; int nCookie=0; _SmartScriptObject pEntities(m_pScriptSystem, true); pH->GetParam(1, x); pH->GetParam(2, y); pH->GetParam(3, w); pH->GetParam(4, h); pH->GetParam(5, fRange); // get radar textures id INT_PTR pRadarTextures[NUM_RADAR_TEXTURES]; memset(pRadarTextures, 0, NUM_RADAR_TEXTURES*sizeof(INT_PTR)); for (int k=0;kGetParamUDVal(k+6, pRadarTextures[k], nCookie) && (nCookie==USER_DATA_TEXTURE))) return pH->EndFunction(); } //k pH->GetParam(6+NUM_RADAR_TEXTURES, *pEntities); pH->GetParam(6+NUM_RADAR_TEXTURES+1, pRadarObjective); m_pGame->DrawRadar(x, y, w, h, fRange, pRadarTextures, &pEntities, pRadarObjective); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::DrawHalfCircleGauge(IFunctionHandler *pH) { if (pH->GetParamCount()<10) CHECK_PARAMETERS(10); if (!m_pRenderer) return pH->EndFunctionNull(); // no renderer int nCookie=0; float x, y, w, h; // size of gauge float u, v, uw, vh; // tex-coords float r=1.0f, g=1.0f, b=1.0f, a=1.0f; INT_PTR nTid; // texture float fValue; // 0<=value<=100 pH->GetParam(1, x); pH->GetParam(2, y); pH->GetParam(3, w); pH->GetParam(4, h); pH->GetParam(5, u); pH->GetParam(6, v); pH->GetParam(7, uw); pH->GetParam(8, vh); if (!(pH->GetParamUDVal(9, nTid, nCookie) && (nCookie==USER_DATA_TEXTURE))) { return pH->EndFunctionNull(); // invalid texture handle } pH->GetParam(10, fValue); if (pH->GetParamCount()>=14) { pH->GetParam(11, r); pH->GetParam(12, g); pH->GetParam(13, b); pH->GetParam(14, a); } if (fValue<0.0f) fValue=0.0f; if (fValue>100.0f) fValue=100.0f; struct _vtx_ { float x,y,z; unsigned int c; float u,v; }; unsigned int dwColor=((unsigned int)(a*255.0f)<<24) | ((unsigned int)(b*255.0f)<<16) | ((unsigned int)(g*255.0f)<<8) | (unsigned int)(r*255.0f); const _vtx_ vtxpos[6]={ {x+1 , y , 0.0f, dwColor, u , v }, {x+1 , y+h, 0.0f, dwColor, u , v+vh}, {x+w*0.5f, y , 0.0f, dwColor, u+uw*0.5f, v }, {x+w*0.5f, y+h, 0.0f, dwColor, u+uw*0.5f, v+vh}, {x+w-1 , y , 0.0f, dwColor, u+uw , v }, {x+w-1 , y+h, 0.0f, dwColor, u+uw , v+vh} }; m_pRenderer->Set2DMode(true, 800, 600); m_pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); m_pRenderer->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); m_pRenderer->SetTexture(nTid); m_pRenderer->SetTexClampMode(true); m_pRenderer->SetCullMode(R_CULL_DISABLE); float w2=w*0.5f; float uw2=uw*0.5f; if (fValue>75.0f) { const int nVerts=7; _vtx_ vtx[nVerts]; vtx[0]=vtxpos[5]; vtx[1]=vtxpos[4]; vtx[2]=vtxpos[3]; vtx[3]=vtxpos[2]; vtx[4]=vtxpos[3]; vtx[5]=vtxpos[0]; vtx[6]=vtxpos[1]; _vtx_ &pt=vtx[0]; float fMult=(100.0f-fValue); pt.y=pt.y-(( h/25.0f)*fMult); pt.v=pt.v-((vh/25.0f)*fMult); CVertexBuffer vb(&vtx, VERTEX_FORMAT_P3F_COL4UB_TEX2F, nVerts); m_pRenderer->DrawTriStrip(&vb, nVerts); }else if (fValue>50.0f) { const int nVerts=7; _vtx_ vtx[nVerts]; vtx[0]=vtxpos[4]; vtx[1]=vtxpos[4]; vtx[2]=vtxpos[3]; vtx[3]=vtxpos[2]; vtx[4]=vtxpos[3]; vtx[5]=vtxpos[0]; vtx[6]=vtxpos[1]; _vtx_ &pt=vtx[0]; float fMult=(75.0f-fValue); pt.x=pt.x-(( w2/25.0f)*fMult); pt.u=pt.u-((uw2/25.0f)*fMult); vtx[1]=vtx[0]; CVertexBuffer vb(&vtx, VERTEX_FORMAT_P3F_COL4UB_TEX2F, nVerts); m_pRenderer->DrawTriStrip(&vb, nVerts); }else if (fValue>25.0f) { const int nVerts=5; _vtx_ vtx[nVerts]; vtx[0]=vtxpos[2]; vtx[1]=vtxpos[2]; vtx[2]=vtxpos[3]; vtx[3]=vtxpos[0]; vtx[4]=vtxpos[1]; _vtx_ &pt=vtx[0]; float fMult=(50.0f-fValue); pt.x=pt.x-(( w2/25.0f)*fMult); pt.u=pt.u-((uw2/25.0f)*fMult); vtx[1]=vtx[0]; CVertexBuffer vb(&vtx, VERTEX_FORMAT_P3F_COL4UB_TEX2F, nVerts); m_pRenderer->DrawTriStrip(&vb, nVerts); }else { const int nVerts=3; _vtx_ vtx[nVerts]; vtx[0]=vtxpos[3]; vtx[1]=vtxpos[0]; vtx[2]=vtxpos[1]; _vtx_ &pt=vtx[1]; float fMult=(25.0f-fValue); pt.y=pt.y+(( h/25.0f)*fMult); pt.v=pt.v+((vh/25.0f)*fMult); CVertexBuffer vb(&vtx, VERTEX_FORMAT_P3F_COL4UB_TEX2F, nVerts); m_pRenderer->DrawTriStrip(&vb, nVerts); } m_pRenderer->SetState(GS_DEPTHWRITE); m_pRenderer->SetTexClampMode(false); m_pRenderer->Set2DMode(false, 0, 0); return pH->EndFunction(1); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::ShowIngameDialog(IFunctionHandler *pH) { if (pH->GetParamCount()<5) return (pH->EndFunctionNull()); int nId=-1; int nFillId; int nSize; const char *pszFontName; const char *pszEffectName; //const char *pszText=NULL; // read params pH->GetParam(1,nFillId); pH->GetParam(2,pszFontName); pH->GetParam(3,pszEffectName); pH->GetParam(4,nSize); // pH->GetParam(5,pszText); string sStr; wstring swStr; const char *sStringKey = 0; if (pH->GetParam(5,sStringKey)) { m_pGame->m_StringTableMgr.Localize( sStringKey,swStr ); } float fTimeout=0.0f; if (pH->GetParamCount()>=6) pH->GetParam(6,fTimeout); if (m_pGame && (!sStr.empty() || !swStr.empty())) { CIngameDialogMgr *pMgr=m_pGame->GetIngameDialogManager(); if (pMgr) { nId=pMgr->AddDialog(m_pSystem, nFillId, pszFontName, pszEffectName, nSize, sStr,swStr, fTimeout); } } return (pH->EndFunction(nId)); } int CScriptObjectGame::HideIngameDialog(IFunctionHandler *pH) { CHECK_PARAMETERS(1); int nId; // read params pH->GetParam(1,nId); if (m_pGame) { CIngameDialogMgr *pMgr=m_pGame->GetIngameDialogManager(); if (pMgr) { pMgr->RemoveDialog(nId); } } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::EnableUIOverlay(IFunctionHandler *pH) { CHECK_PARAMETERS(2); int iEnable = 0; int iExclusiveInput = 0; if (pH->GetParamType(1) == svtNumber) { pH->GetParam(1, iEnable); } if (pH->GetParamType(2) == svtNumber) { pH->GetParam(2, iExclusiveInput); } m_pGame->EnableUIOverlay(iEnable != 0, iExclusiveInput != 0); return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::IsUIOverlay(IFunctionHandler *pH) { CHECK_PARAMETERS(0); if (m_pGame->IsUIOverlay()) { return pH->EndFunction(1); } return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- /*!return the team name of a certain entity @param the entity id @return the team name or nil if the entity is not in a team */ int CScriptObjectGame::GetEntityTeam(IFunctionHandler *pH) { CHECK_PARAMETERS(1); int id=0; if (pH->GetParam(1, id)) { IXSystem *pSys=m_pGame->GetXSystem(); int nTID =pSys->GetEntityTeam(id); if (nTID==-1) { // TRACE("Team is NULL"); return pH->EndFunctionNull(); } //TRACE("Team is %s", pTeam->GetName().c_str()); //m_pGame->GetTeamManager()->DumpEnts(); char sTeamName[256]; pSys->GetTeamName(nTID,sTeamName); return pH->EndFunction(sTeamName); }else return pH->EndFunctionNull(); } /*!return the material id by the material name @param sMaterialName the material name @return the material id or nil if the material doesn't exist or is not loaded in the current map */ int CScriptObjectGame::GetMaterialIDByName(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sMaterialName; int nMaterialID; if(pH->GetParam(1,sMaterialName)) { nMaterialID=m_pGame->m_XSurfaceMgr.GetSurfaceIDByMaterialName(sMaterialName); return pH->EndFunction(nMaterialID); } return pH->EndFunctionNull(); } int CScriptObjectGame::ReloadMaterialPhysics(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sMaterialName; if(pH->GetParam(1,sMaterialName)) m_pGame->m_XSurfaceMgr.ReloadMaterialPhysics(sMaterialName); return pH->EndFunctionNull(); } /*!return the material table passing is id @param the id of the material @return the material table or nil if the specified id is not related to any loaded material */ int CScriptObjectGame::GetMaterialBySurfaceID(IFunctionHandler *pH) { CHECK_PARAMETERS(1); //int nMaterialID; int surfaceID; if(pH->GetParam(1,surfaceID)) { IScriptObject *pSO=m_pGame->m_XSurfaceMgr.GetMaterialBySurfaceID(surfaceID); if(pSO) { return pH->EndFunction(pSO); } else { TRACE("[GetMaterialBySurfaceID] Warning MATERIAL IS NULL"); return pH->EndFunctionNull(); } } return pH->EndFunctionNull(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::StartDemoPlay(IFunctionHandler *pH) { const char *sFileName = "timedemo"; if(pH->GetParamCount()==1) { pH->GetParam(1,sFileName); } if (sFileName) m_pGame->StartDemoPlay(sFileName); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::StopDemoPlay(IFunctionHandler *pH) { m_pGame->StopDemoPlay(); return pH->EndFunction(); } int CScriptObjectGame::StartRecord(IFunctionHandler *pH) { const char *sFileName = "timedemo"; if(pH->GetParamCount()==1) { pH->GetParam(1,sFileName); } if (sFileName) m_pGame->StartRecording(sFileName); return pH->EndFunction(); } int CScriptObjectGame::StopRecord(IFunctionHandler *pH) { m_pGame->StopRecording(); return pH->EndFunction(); } /*! get the score of a cetain team @param sTeamName the team name @return the current team score or nil if the specified team doesn't exist */ int CScriptObjectGame::GetTeamScore(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sTeamName; if(pH->GetParam(1,sTeamName)) { IXSystem *pSys=m_pGame->GetXSystem(); int nTID=pSys->GetTeamId(sTeamName); if(nTID!=-1) return pH->EndFunction(pSys->GetTeamScore(nTID)); } else { assert(0); // don't pass nil as team name } return pH->EndFunction(); } /*! get the score of a cetain team @param sTeamName the team name @return the current team score or nil if the specified team doesn't exist */ int CScriptObjectGame::GetTeamFlags(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sTeamName; if(pH->GetParam(1,sTeamName)) { IXSystem *pSys=m_pGame->GetXSystem(); int nTID=pSys->GetTeamId(sTeamName); if(nTID!=-1) { return pH->EndFunction(pSys->GetTeamFlags(nTID)); } } // } return pH->EndFunction(); } /*! set/remove the scoreboard to a certain client connected to this srever @param reqid id of the player entity associated if this parameter is 0 brodcast the command to all clients @param isshown if !=nil activate the scoreboard if nil decativate it @return the current team score or nil if the specified team doesn't exist */ int CScriptObjectGame::ForceScoreBoard(IFunctionHandler *pH) { CHECK_PARAMETERS(2); int reqid; bool isshown = false; pH->GetParam(1, reqid); pH->GetParam(2, isshown); CXServer *server = m_pGame->m_pServer; CXServer::XSlotMap &slots = server->GetSlotsMap(); for(CXServer::XSlotMap::iterator i = slots.begin(); i != slots.end(); ++i) { CXServerSlot *slot = i->second; EntityId id = slot->GetPlayerId(); if(id!=INVALID_WID) { IEntity *ent = server->m_pISystem->GetEntity(id); if(ent && ent->GetContainer()) { CPlayer *pPlayer=0; CSpectator *pSpec=0; ent->GetContainer()->QueryContainerInterface(CIT_IPLAYER,(void**) &pPlayer); ent->GetContainer()->QueryContainerInterface(CIT_ISPECTATOR,(void**) &pSpec); if ((pPlayer || pSpec) && (!reqid || reqid==id)) { slot->m_bForceScoreBoard = isshown; } } } } return pH->EndFunction(); } int CScriptObjectGame::GetTagPoint(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sTPName; ITagPoint *pTP=NULL; Vec3 vec(0,0,0); if(pH->GetParam(1,sTPName)) { pTP=m_pGame->GetTagPoint(sTPName); if(!pTP) return pH->EndFunctionNull(); pTP->GetPos(vec); } m_pGetTagPoint.Set(vec); return pH->EndFunction(m_pGetTagPoint); } int CScriptObjectGame::SetThirdPerson(IFunctionHandler * pH) { CHECK_PARAMETERS(1); bool bThirdPerson; pH->GetParam(1,bThirdPerson); //[kirill] this check is done in m_pGame->SetViewMode // if (m_pGame->IsDevModeEnable()) m_pGame->SetViewMode(bThirdPerson); return pH->EndFunction(); } int CScriptObjectGame::SetViewAngles(IFunctionHandler * pH) { CHECK_PARAMETERS(1); CScriptObjectVector oAng(m_pScriptSystem,true); if(pH->GetParam(1,oAng)) { m_pGame->SetViewAngles(oAng.Get()); } return pH->EndFunction(); } int CScriptObjectGame::DumpEntities(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pSystem->GetILog()->Log("------------------------------------------------------------------------------------------"); IEntityClassRegistry *pECR=m_pGame->GetClassRegistry(); IEntityItPtr pEntities=m_pSystem->GetIEntitySystem()->GetEntityIterator(); pEntities->MoveFirst(); IEntity *pEnt=NULL; while((pEnt=pEntities->Next())!=NULL) { EntityClass *pClass=pECR->GetByClass(pEnt->GetEntityClassName()); //if(m_pGame->GetWeaponSystem()->IsWeaponClass(pClass->cTypeID)) continue; if(m_pGame->GetWeaponSystemEx()->IsProjectileClass(pClass->ClassId)) continue; Vec3 pos = pEnt->GetPos(); m_pSystem->GetILog()->Log("ENTITY class=%s/%d ent=%s/%d pos=(%.1f,%.1f,%.1f)", pClass->strClassName.c_str(), (int)pClass->ClassId, pEnt->GetName(), pEnt->GetId(), pos.x, pos.y, pos.z); } m_pSystem->GetILog()->Log("------------------------------------------------------------------------------------------"); return pH->EndFunction(); } // FIXME: tim, refactor these functions struct SFoundSaveGame { string szFileName, szLevel, szMission; int iHour, iMinute, iSecond, iYear, iMonth, iDay; }; bool SortSaveGame(const SFoundSaveGame &a, const SFoundSaveGame &b) { /* // Sort by save number. int len1 = a.szFileName.find('.'); while (len1 > 0 && isdigit(a.szFileName[len1-1])) len1--; int len2 = b.szFileName.find('.'); while (len2 > 0 && isdigit(b.szFileName[len2-1])) len2--; int num1 = atoi(a.szFileName.substr(len1).c_str()); int num2 = atoi(b.szFileName.substr(len2).c_str()); return num1 < num2; */ // Sort by time. if (a.iYear > b.iYear) { return 0; } else if (a.iYear < b.iYear) { return 1; } else if (a.iMonth > b.iMonth) { return 0; } else if (a.iMonth < b.iMonth) { return 1; } else if (a.iDay > b.iDay) { return 0; } else if (a.iDay < b.iDay) { return 1; } else if (a.iHour > b.iHour) { return 0; } else if (a.iHour < b.iHour) { return 1; } else if (a.iMinute > b.iMinute) { return 0; } else if (a.iMinute < b.iMinute) { return 1; } else if (a.iSecond > b.iSecond) { return 0; } else if (a.iSecond < b.iSecond) { return 1; } return 0; } int CScriptObjectGame::GetSaveGameList(IFunctionHandler *pH) { intptr_t hEnumFile = -1L; __finddata64_t sFindData; _SmartScriptObject cList(m_pSystem->GetIScriptSystem(), false); std::vector vSaveList; CHECK_PARAMETERS(1); char *szProfileName; pH->GetParam(1, szProfileName); string szSaveGameDir = "Profiles/player/"; szSaveGameDir+= szProfileName; szSaveGameDir += "/Savegames/"; //m_pSystem->GetILog()->Log("SEARCHING FOR SAVEGAMES (PROFILE: %s)!", szProfileName); string pattern = szSaveGameDir + "*.sav"; if ((hEnumFile = _findfirst64(pattern.c_str(), &sFindData)) == -1L) { _findclose(hEnumFile); hEnumFile = -1L; return pH->EndFunction(cList); } do { if(sFindData.attrib&_A_SUBDIR) continue; string szSaveFilename = szSaveGameDir + sFindData.name; CDefaultStreamAllocator sa; CStream stm(300, &sa); int bitslen = m_pSystem->GetCompressedFileSize((char *)szSaveFilename.c_str()); if (bitslen) { stm.Resize(bitslen); int bitsread = m_pSystem->ReadCompressedFile((char *)szSaveFilename.c_str(), stm.GetPtr(), stm.GetAllocatedSize()); if (bitsread) { stm.SetSize(bitsread); string szMagic; int iVersion; stm.Read(szMagic); stm.Read(iVersion); if ((szMagic == SAVEMAGIC)) { m_pSystem->GetILog()->Log("\tfound savegame: %s", sFindData.name); string szLevelName; string szMissionName; stm.Read(szLevelName); stm.Read(szMissionName); unsigned char bHour, bMinute, bSecond, bDay, bMonth; unsigned short wYear; stm.Read(bHour); // hour stm.Read(bMinute); // minute stm.Read(bSecond); // minute stm.Read(bDay); // day stm.Read(bMonth); // month stm.Read(wYear); // year SFoundSaveGame Save; Save.iYear = (int)wYear; Save.iMonth = (int)bMonth; Save.iDay = (int)bDay; Save.iHour = (int)bHour; Save.iMinute = (int)bMinute; Save.iSecond = (int)bSecond; Save.szFileName = sFindData.name; Save.szLevel = szLevelName; Save.szMission = szMissionName; vSaveList.push_back(Save); } else { m_pSystem->GetILog()->Log("\tfound savegame: %s $4wrong version", sFindData.name); } } else { m_pSystem->GetILog()->Log("\tfound savegame: %s $4failed to read", sFindData.name); } } else { m_pSystem->GetILog()->Log("\tfound savegame: %s $4zero length", sFindData.name); } } while (_findnext64(hEnumFile, &sFindData) != -1); _findclose(hEnumFile); hEnumFile = 0; std::sort(vSaveList.begin(), vSaveList.end(), SortSaveGame); for (std::vector::iterator it = vSaveList.begin(); it != vSaveList.end(); ++it) { _SmartScriptObject pCheckpoint(m_pSystem->GetIScriptSystem(), false); pCheckpoint->SetValue("Hour", it->iHour); pCheckpoint->SetValue("Minute", it->iMinute); pCheckpoint->SetValue("Second", it->iSecond); pCheckpoint->SetValue("Day", it->iDay); pCheckpoint->SetValue("Month", it->iMonth); pCheckpoint->SetValue("Year", it->iYear); pCheckpoint->SetValue("Filename", it->szFileName.c_str()); pCheckpoint->SetValue("Level", it->szLevel.c_str()); pCheckpoint->SetValue("Mission", it->szMission.c_str()); cList->SetAt(cList->Count()+1, pCheckpoint); } //m_pSystem->GetILog()->Log("END OF SAVEGAMES (PROFILE: %s)!", szProfileName); return pH->EndFunction(cList); } int CScriptObjectGame::ToggleMenu(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pGame->SendMessage("Switch"); // m_pGame->Update(); // m_pGame->m_pSystem->GetIProcess()->SetPMessage("Switch"); // m_pGame->Update(); // m_pGame->m_pSystem->GetIProcess()->SetPMessage("Switch"); // m_pGame->Update(); return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::ShowMenu(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pGame->GotoMenu(); return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::HideMenu(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pGame->GotoGame(); return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CScriptObjectGame::IsInMenu(IFunctionHandler *pH) { CHECK_PARAMETERS(0); if (m_pGame->IsInMenu()) return pH->EndFunction(1); return pH->EndFunctionNull(); } /* // calculates aproximate point of lending for granade on terrain, // Returns "hit probability" [0,1]. // 1-granade lands at target location // 0-granade lands more than explosion_radius from target // firePos - start point // fireAngl - fireing angles // target - target location // name - name of the grenade // example: // Game:TraceGrenade( firePos, fireAngl, ttarget:GetPos(), "ProjFlashbangGrenade" ); int CScriptObjectGame::TraceGrenade(IFunctionHandler *pH) { CHECK_PARAMETERS(4); const char * sGrenadeName; float timeStep = .03f; float timeLimit = 30.0f; Vec3 firePos; Vec3 curPos; Vec3 dir; Vec3 target; float time = 0.0f; float vel; // initial velocity Vec3 gravity; float z; float radius; CScriptObjectVector oVec(m_pScriptSystem,true); _SmartScriptObject obj(m_pScriptSystem); _SmartScriptObject explPar(m_pScriptSystem); _SmartScriptObject param(m_pScriptSystem); pH->GetParam(1,*oVec); firePos=oVec.Get(); pH->GetParam(2,*oVec); dir=oVec.Get(); pH->GetParam(3,*oVec); target=oVec.Get(); pH->GetParam(4,sGrenadeName); dir=ConvertToRadAngles(dir); if( !m_pScriptSystem->GetGlobalValue(sGrenadeName, obj)) { return (pH->EndFunction( 0 )); } obj->GetValue("ExplosionParams", explPar); obj->GetValue("PhysParams", param); explPar->GetValue("radius", radius); param->GetValue("initial_velocity", vel); param->GetValue("gravity", oVec); gravity=oVec.Get(); curPos = firePos; if( curPos.z<=m_pSystem->GetI3DEngine()->GetTerrainElevation(curPos.x, curPos.y) ) curPos.z = m_pSystem->GetI3DEngine()->GetTerrainElevation(curPos.x, curPos.y) + .01f; while( curPos.z > (z=m_pSystem->GetI3DEngine()->GetTerrainElevation(curPos.x, curPos.y)) && timeGetIRenderer()->DrawLabel(curPos, 1, "O"); time += timeStep; } curPos.z = z; //m_pSystem->GetIRenderer()->DrawLabel(curPos, 3, "O"); float dist = (curPos-target).Length(); if( dist == 0 ) dist = 1; else if( dist >= radius ) dist = 0; else dist = 1.0f - dist/radius; return (pH->EndFunction( dist )); } */ ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// //NEW STUFF int CScriptObjectGame::SendMessage(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *pszMsg; pH->GetParam(1, pszMsg); if(pszMsg) m_pGame->SendMessage(pszMsg); else m_pScriptSystem->RaiseError("SendMessage() parameter is nil"); return pH->EndFunction(); } int CScriptObjectGame::GetEntityClassIDByClassName(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sClassName; if(!pH->GetParam(1,sClassName)) return pH->EndFunctionNull(); IEntityClassRegistry *pECR=m_pGame->GetClassRegistry(); EntityClass *pEC=pECR->GetByClass(sClassName); if(!pEC) return pH->EndFunctionNull(); return pH->EndFunction((int)pEC->ClassId); } ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// /*!sets the camera field of view @param fFOV the field of view angle */ int CScriptObjectGame::SetCameraFov(IFunctionHandler *pH) { CHECK_PARAMETERS(1); float fFOV; pH->GetParam(1,fFOV); IEntity *pEntity;; CXClient *pClient=m_pGame->GetClient(); pEntity=pClient->m_pISystem->GetLocalPlayer(); if(pEntity) { if(pEntity->GetCamera()) { IEntityCamera *pCamera=pEntity->GetCamera(); if (pCamera && (fabs(fFOV-pCamera->GetFov())>0.001f)) { pCamera->SetFov(fFOV,m_pRenderer->GetWidth(),m_pRenderer->GetHeight()); pCamera->GetCamera().Init(m_pRenderer->GetWidth(),m_pRenderer->GetHeight(),fFOV); pCamera->GetCamera().Update(); } } } return pH->EndFunction(); } int CScriptObjectGame::GetCameraFov(IFunctionHandler *pH) { CHECK_PARAMETERS(0); IEntity *pEntity; CXClient *pClient=m_pGame->GetClient(); pEntity=pClient->m_pISystem->GetLocalPlayer(); if(pEntity) { if(pEntity->GetCamera()) { IEntityCamera *pCamera=pEntity->GetCamera(); return pH->EndFunction(pCamera->GetFov()); } } return pH->EndFunctionNull(); } int CScriptObjectGame::ApplyStormToEnvironment(IFunctionHandler * pH) { //CHECK_PARAMETERS(3); CScriptObjectVector pVecOrigin(m_pScriptSystem,false); CScriptObjectVector pVecWindDirection(m_pScriptSystem,false); Vec3 vOrigin,vWind; float fRainAmount; pH->GetParam(1,pVecWindDirection); vWind=pVecWindDirection.Get(); pH->GetParam(2,fRainAmount); // all these effects are client-side only IEntity *pEntity=NULL; CXClient *pClient=m_pGame->GetClient(); if (pClient) pEntity=pClient->m_pISystem->GetLocalPlayer(); if (pEntity) { if (pEntity->GetCamera()) { IEntityCamera *pCamera=pEntity->GetCamera(); Vec3 vPos=pEntity->GetCamera()->GetPos(); if (m_p3DEngine->GetVisAreaFromPos(vPos)==NULL) { // enable rain only when the client is outdoor m_p3DEngine->SetRainAmount(fRainAmount); m_p3DEngine->SetWindForce(vWind); } } } return pH->EndFunctionNull(); } int CScriptObjectGame::CreateExplosion(IFunctionHandler *pH) { _SmartScriptObject pObj(m_pScriptSystem,true); _SmartScriptObject pTempObj(m_pScriptSystem,true); CScriptObjectVector oVec(m_pScriptSystem,true); Vec3 pos; float damage, rmin, rmax, radius, impulsive_pressure; float fDeafnessRadius=0.0f; float fDeafnessTime=0.0f; float fShakeFactor=1.0f; //float falloff, curDamage; float ImpactForceMul=45, ImpactForceMulFinal=62, ImpactForceMulFinalTorso=0; int nID; IEntity *shooter, *weapon=0; float rmin_occ = 0.1f; int nOccRes=0,nGrow=0; float fTerrainDefSize=0; INT_PTR nTerrainDecalId=0; int nCookie; int shooterSSID=0; pH->GetParam(1,*pObj); pObj->GetValue( "pos",*oVec ); pos=oVec.Get(); pObj->GetValue( "damage",damage ); pObj->GetValue( "rmin",rmin ); pObj->GetValue( "rmax",rmax ); pObj->GetValue( "radius",radius ); // give the explosion some control over the amount of shake which is being produced pObj->GetValue( "shake_factor", fShakeFactor); pObj->GetValue( "DeafnessRadius",fDeafnessRadius ); pObj->GetValue( "DeafnessTime",fDeafnessTime ); pObj->GetValue( "impulsive_pressure",impulsive_pressure ); pObj->GetValue( "iImpactForceMul",ImpactForceMul); pObj->GetValue( "iImpactForceMulFinal",ImpactForceMulFinal); pObj->GetValue( "iImpactForceMulFinalTorso",ImpactForceMulFinalTorso); pObj->GetValue("rmin_occlusion", rmin_occ); pObj->GetValue("occlusion_res", nOccRes); pObj->GetValue("occlusion_inflate", nGrow); pObj->GetValue( "shooter",*pTempObj ); // it gets the EntityId from the Entity pTempObj->GetValue("id",nID); shooter=m_pEntitySystem->GetEntity(nID); if(pObj->GetValue( "weapon",*pTempObj )) // it gets the EntityId from the Entity { pTempObj->GetValue("id",nID); weapon=m_pEntitySystem->GetEntity(nID); if (!weapon) return pH->EndFunction(); } if(!pObj->GetValue("shooterSSID", shooterSSID)) shooterSSID=-1; // no known shooter client id (e.g. vehicle explosion) pObj->GetUDValue("decal_id",nTerrainDecalId,nCookie); if(nTerrainDecalId && nCookie==USER_DATA_TEXTURE) pObj->GetValue("terrain_deform_size",fTerrainDefSize); m_pGame->CreateExplosion(pos,damage,rmin,rmax,radius,impulsive_pressure,fShakeFactor,fDeafnessRadius,fDeafnessTime,ImpactForceMul, ImpactForceMulFinal,ImpactForceMulFinalTorso,rmin_occ,nOccRes,nGrow, shooter,shooterSSID,weapon, fTerrainDefSize,nTerrainDecalId); return pH->EndFunction(); } int CScriptObjectGame::DrawLabel(IFunctionHandler *pH) { CHECK_PARAMETERS(3); CScriptObjectVector oVec(m_pScriptSystem,true); const char *szParam=NULL; float size; pH->GetParam(1,*oVec); pH->GetParam(2,size); string sStr; wstring swStr; const char *sStringKey = 0; if (pH->GetParam(3,sStringKey)) { m_pGame->m_StringTableMgr.Localize( sStringKey,swStr ); } if (!sStr.empty()) szParam=sStr.c_str(); if (szParam) { float clr[4]; clr[0] = clr[1] = clr[2] =clr[3] = 1.f; if (m_pRenderer) m_pRenderer->DrawLabelEx(oVec.Get(),size,clr,true,true,szParam); } return pH->EndFunction(); } int CScriptObjectGame::GetInstantHit(IFunctionHandler *pH) { CHECK_PARAMETERS(1); _SmartScriptObject pObj(m_pScriptSystem,true); _SmartScriptObject pShooter(m_pScriptSystem,true); CScriptObjectVector oVec(m_pScriptSystem,true); IEntity *shooter; int nID; Vec3 pos, angles, dir; float fDistance; int res; pH->GetParam(1,*pObj); pObj->GetValue( "shooter",*pShooter ); pShooter->GetValue("id",nID); shooter=m_pEntitySystem->GetEntity(nID); if(shooter==NULL) { TRACE("CScriptObjectSystem::GetInstantHit() shooter in nil"); return pH->EndFunctionNull(); } pObj->GetValue( "pos", *oVec ); pos=oVec.Get(); pObj->GetValue( "dir", *oVec ); dir=oVec.Get(); pObj->GetValue( "distance", fDistance ); dir*=fDistance; IPhysicalEntity *skip=shooter->GetPhysics(); ray_hit hit; res=m_pPhysicalWorld->RayWorldIntersection((const vectorf)pos,(const vectorf)dir, ent_all, rwi_stop_at_pierceable,&hit,1, skip); if (res) { _SmartScriptObject pOut(m_pScriptSystem); CScriptObjectVector tVec(m_pScriptSystem); CScriptObjectVector tPos(m_pScriptSystem); CScriptObjectVector tRet(m_pScriptSystem); int nObjType; if (hit.pCollider) { IEntity *centycontact = (IEntity *)hit.pCollider->GetForeignData(); if (centycontact) { nObjType=0; // entity IScriptObject *pObj=centycontact->GetScriptObject(); if(pObj) pOut->SetValue("target", pObj); } else { nObjType=1; // stat obj pOut->SetToNull("target"); } }else { nObjType=2; // terrain pOut->SetToNull("target"); } pOut->SetValue("shooter", pShooter); pOut->SetValue("objtype", nObjType); tPos=(Vec3)hit.pt; pOut->SetValue("pos", *tPos); tVec=(Vec3)hit.n; pOut->SetValue("normal", *tVec); tRet=GetNormalized(dir); pOut->SetValue( "dir", *tRet ); pOut->SetValue("target_material",m_pGame->m_XSurfaceMgr.GetMaterialBySurfaceID(hit.surface_idx)); return pH->EndFunction(*pOut); }else return pH->EndFunctionNull(); } int CScriptObjectGame::GetMeleeHit(IFunctionHandler *pH) { CHECK_PARAMETERS(1); _SmartScriptObject pObj(m_pScriptSystem,true); _SmartScriptObject pShooter(m_pScriptSystem,true); _SmartScriptObject pMeleeTarget(m_pScriptSystem,true); CScriptObjectVector oVec(m_pScriptSystem,true); IEntity *shooter; IEntity *target = NULL; int nID; Vec3 pos, angles, dir; float fDistance; pH->GetParam(1,*pObj); pObj->GetValue( "shooter",*pShooter); pShooter->GetValue("id",nID); shooter=m_pEntitySystem->GetEntity(nID); if(shooter==NULL) { TRACE("CScriptObjectSystem::GetMeleeHit() shooter in nil"); return pH->EndFunctionNull(); } pObj->GetValue( "pos", *oVec ); pos=oVec.Get(); pObj->GetValue( "dir", *oVec ); dir=oVec.Get(); dir.Normalize(); pObj->GetValue( "distance", fDistance ); dir*=fDistance; if (pObj->GetValue("melee_target", *pMeleeTarget)) { pMeleeTarget->GetValue("id",nID); target=m_pEntitySystem->GetEntity(nID); } IPhysicalEntity *skip=shooter->GetPhysics(); Vec3 boxCenter = pos + 0.5f * dir; Vec3 offset(0.5f * fDistance, 0.5f * fDistance, 0.5f * fDistance); IPhysicalEntity **pList; // get all entities in the hit box int num = m_pPhysicalWorld->GetEntitiesInBox(boxCenter-offset, boxCenter+offset, pList, ent_all); // move position to ensure that we calc piercability correct float radius = 1.f; pos = pos - GetNormalized(dir) * radius; dir += radius * GetNormalized(dir); int res = 0; ray_hit closestHit; // check each entity in the box for (int i = 0; i < num; ++i) { IEntity* pEntity = ((IEntity*)pList[i]->GetForeignData(OT_ENTITY)); // skip the shooter if (pEntity) { if (pEntity == shooter) continue; } if (target == NULL || target == pEntity || pEntity==NULL ) { ray_hit hit; // cast a 'fat' line segment if (m_pPhysicalWorld->CollideEntityWithBeam(pList[i], pos, dir, 0.3f, &hit)) { if (hit.dist <= fDistance+radius) { if (res == 0 || hit.dist < closestHit.dist) { closestHit = hit; } res = 1; } } } } if (res) { _SmartScriptObject pOut(m_pScriptSystem); CScriptObjectVector tVec(m_pScriptSystem); CScriptObjectVector tPos(m_pScriptSystem); CScriptObjectVector tRet(m_pScriptSystem); int nObjType; if (closestHit.pCollider) { IEntity *centycontact = (IEntity *)closestHit.pCollider->GetForeignData(OT_ENTITY); if (centycontact) { nObjType=0; // entity IScriptObject *pObj=centycontact->GetScriptObject(); if(pObj) pOut->SetValue("target", pObj); if (target != NULL && target != centycontact) pOut->SetToNull("target"); } else { nObjType=1; // stat obj pOut->SetToNull("target"); } }else { nObjType=2; // terrain pOut->SetToNull("target"); } pOut->SetValue("shooter", pShooter); pOut->SetValue("objtype", nObjType); tPos=(Vec3)closestHit.pt; pOut->SetValue("pos", *tPos); tVec=(Vec3)closestHit.n; pOut->SetValue("normal", *tVec); tRet=GetNormalized(dir); pOut->SetValue( "dir", *tRet ); pOut->SetValue("target_material",m_pGame->m_XSurfaceMgr.GetMaterialBySurfaceID(closestHit.surface_idx)); return pH->EndFunction(*pOut); }else return pH->EndFunctionNull(); } ////////////////////////////////////////////////////////////////////////// bool CScriptObjectGame::_GetProfileFileNames( IFunctionHandler *pH, string &outSystem, string &outGame, const char *insCallerName ) { outSystem="system.cfg"; outGame="game.cfg"; if(pH->GetParamCount()>0) // use given profile name or don't use profiles { CHECK_PARAMETERS(1); const char *sProfileName; pH->GetParam(1,sProfileName); if(!sProfileName || sProfileName=="") { m_pScriptSystem->RaiseError("%s profilename is nil or empty",insCallerName); return false; } string sName; outSystem=string("Profiles/Player/")+sProfileName+"_"+outSystem; outGame=string("Profiles/Player/")+sProfileName+"_"+outGame; } return true; } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::RemoveConfiguration(IFunctionHandler *pH) { string sSystemCfg("system.cfg"), sGameCfg("game.cfg"); if(m_pGame->m_bDedicatedServer) return pH->EndFunction(); if (m_pGame->m_bEditor) return pH->EndFunction(); char *szProfileName = 0; pH->GetParam(1, szProfileName); // profile is already specified in the string m_pGame->RemoveConfiguration(sSystemCfg,sGameCfg,szProfileName); return pH->EndFunction(); } int CScriptObjectGame::LoadConfiguration(IFunctionHandler *pH) { string sSystemCfg, sGameCfg; if(!_GetProfileFileNames(pH,sSystemCfg,sGameCfg,__FUNCTION__)) return pH->EndFunction(); //m_pScriptSystem->ExecuteFile(sSystemCfg.c_str(),true,true); //m_pScriptSystem->ExecuteFile(sGameCfg.c_str(),true,true); m_pGame->LoadConfiguration(sSystemCfg,sGameCfg); return pH->EndFunction(); } int CScriptObjectGame::LoadConfigurationEx(IFunctionHandler *pH) { CHECK_PARAMETERS(2); if (pH->GetParamCount() == 2) { char *szSystemConfig = 0; char *szGameConfig = 0; pH->GetParam(1, szSystemConfig); pH->GetParam(2, szGameConfig); if (szSystemConfig && szGameConfig) { m_pGame->LoadConfiguration(szSystemConfig, szGameConfig); } else if (szSystemConfig) { m_pGame->LoadConfiguration(szSystemConfig, ""); } else if (szGameConfig) { m_pGame->LoadConfiguration("", szGameConfig); } } return pH->EndFunction(); } // int CScriptObjectGame::SaveConfiguration(IFunctionHandler *pH) { string sSystemCfg, sGameCfg; if(!_GetProfileFileNames(pH,sSystemCfg,sGameCfg,__FUNCTION__)) return pH->EndFunction(); if(m_pGame->m_bDedicatedServer) return pH->EndFunction(); if (m_pGame->m_bEditor) return pH->EndFunction(); char *szProfileName = 0; if (pH->GetParamCount() > 0) { pH->GetParam(1, szProfileName); } // profile is already specified in the string m_pGame->SaveConfiguration(sSystemCfg.c_str(),sGameCfg.c_str(),NULL); if (szProfileName) { string path = "profiles/player/"; path += szProfileName; #if defined(LINUX) mkdir( path.c_str(), 0xFFFF ); #else _mkdir( path.c_str() ); #endif path += "savegames/"; #if defined(LINUX) mkdir( path.c_str(), 0xFFFF ); #else _mkdir( path.c_str() ); #endif } return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::DrawHealthBar(IFunctionHandler *pH) { return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::LoadScript(IFunctionHandler *pH) { if(pH->GetParamCount()>0) { const char *sPath; if(pH->GetParam(1,sPath)) { bool bForceReload=false; if(pH->GetParamCount()>1) pH->GetParam(2,bForceReload); return pH->EndFunction(m_pGame->ExecuteScript(sPath,bForceReload)); } } return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::CreateRenderer(IFunctionHandler *pH) { CScriptObjectRenderer *p=new CScriptObjectRenderer(); m_vRenderersObjs.push_back(p); return pH->EndFunction(p->Create(m_pScriptSystem,m_pRenderer)); } //! Generates a sound event on radar ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::SoundEvent(IFunctionHandler *pH) { CHECK_PARAMETERS(4); float fThreat,fRadius; //fInterest, int nID; CScriptObjectVector oVec(m_pScriptSystem,true); pH->GetParam(1,*oVec); pH->GetParam(2,fRadius); pH->GetParam(3,fThreat); pH->GetParam(4,nID); Vec3d pos = oVec.Get(); CXClient *pCli=m_pGame->GetClient(); if(pCli) { pCli->SoundEvent((EntityId)nID,pos,fRadius,fThreat); } return pH->EndFunction(); } int CScriptObjectGame::CheckMap(IFunctionHandler *pH) { char *szMapName = 0; char *szGameType = 0; if (pH->GetParamCount() > 0) { pH->GetParam(1, szMapName); } else { return pH->EndFunctionNull(); } if (!szMapName) { return pH->EndFunctionNull(); } if (strstr(szMapName, "/") || strstr(szMapName, "\\")) { return pH->EndFunctionNull(); } string szMapPath = m_pGame->GetLevelsFolder() + "/" + szMapName; string szPak = szMapPath + "/*.pak"; if (!m_pGame->OpenPacks(szPak.c_str())) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunctionNull(); } if (pH->GetParamCount() == 1) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunction(1); } if (pH->GetParamCount() > 1) { pH->GetParam(2, szGameType); } string szXMLPath = szMapPath + "/LevelData.xml"; XDOM::IXMLDOMDocumentPtr pLevelDataXML = m_pGame->GetSystem()->CreateXMLDocument(); if(!pLevelDataXML->load(szXMLPath.c_str())) { m_pGame->ClosePacks(szPak.c_str()); pLevelDataXML = 0; return pH->EndFunctionNull(); } else if (!szGameType) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunction(1); } XDOM::IXMLDOMNodeListPtr pNodes; #if !defined(LINUX64) if(pLevelDataXML != NULL) #else if(pLevelDataXML != 0) #endif { XDOM::IXMLDOMNodeListPtr pMissionTagList; XDOM::IXMLDOMNodePtr pMissionTag; pMissionTagList = pLevelDataXML->getElementsByTagName("Missions"); if (pMissionTagList) { pMissionTagList->reset(); pMissionTag = pMissionTagList->nextNode(); XDOM::IXMLDOMNodeListPtr pMissionList; pMissionList = pMissionTag->getElementsByTagName("Mission"); if (pMissionList) { pMissionList->reset(); XDOM::IXMLDOMNodePtr pMission; while (pMission = pMissionList->nextNode()) { XDOM::IXMLDOMNodePtr pName = pMission->getAttribute("Name"); #if defined(LINUX) RemoveCRLF(szGameType); #endif if(stricmp(szGameType, pName->getText()) == 0) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunction(1); } } pH->EndFunctionNull(); } } } m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunctionNull(); } int CScriptObjectGame::GetMapDefaultMission(IFunctionHandler *pH) { CHECK_PARAMETERS(1); char *szMapName = 0; if (!pH->GetParam(1, szMapName)) { return pH->EndFunctionNull(); } if (!strlen(szMapName)) { return pH->EndFunctionNull(); } if (strstr(szMapName, "/") || strstr(szMapName, "\\")) { return pH->EndFunctionNull(); } string szMapPath = m_pGame->GetLevelsFolder() + "/" + szMapName; string szPak = szMapPath + "/*.pak"; if (!m_pGame->OpenPacks(szPak.c_str())) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunctionNull(); } string szXMLPath = szMapPath + "/LevelData.xml"; XDOM::IXMLDOMDocumentPtr pLevelDataXML = m_pGame->GetSystem()->CreateXMLDocument(); if(!pLevelDataXML->load(szXMLPath.c_str())) { m_pGame->ClosePacks(szPak.c_str()); pLevelDataXML = 0; return pH->EndFunctionNull(); } XDOM::IXMLDOMNodeListPtr pNodes; #if !defined(LINUX64) if(pLevelDataXML != NULL) #else if(pLevelDataXML != 0) #endif { XDOM::IXMLDOMNodeListPtr pMissionTagList; XDOM::IXMLDOMNodePtr pMissionTag; pMissionTagList = pLevelDataXML->getElementsByTagName("Missions"); if (pMissionTagList) { pMissionTagList->reset(); pMissionTag = pMissionTagList->nextNode(); XDOM::IXMLDOMNodeListPtr pMissionList; pMissionList = pMissionTag->getElementsByTagName("Mission"); if (pMissionList) { pMissionList->reset(); XDOM::IXMLDOMNodePtr pMission; while (pMission = pMissionList->nextNode()) { XDOM::IXMLDOMNodePtr pName = pMission->getAttribute("Name"); if (pName->getText()) { m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunction(pName->getText()); } } } } } m_pGame->ClosePacks(szPak.c_str()); return pH->EndFunctionNull(); } int CScriptObjectGame::CleanUpLevel(IFunctionHandler *pH) { CHECK_PARAMETERS(0); m_pEntitySystem->EnableClient(false); m_pEntitySystem->EnableServer(false); m_pGame->MarkClientForDestruct(); m_pGame->ShutdownServer(); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::SavePlayerPos(IFunctionHandler *pH) { const char *sName = NULL; const char *sDesc = NULL; pH->GetParam(1,sName); pH->GetParam(2,sDesc); if (sName) m_pGame->DevMode_SavePlayerPos( 0,sName,sDesc ); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::LoadPlayerPos(IFunctionHandler *pH) { CHECK_PARAMETERS(1); const char *sName; if (pH->GetParam(1,sName)) { m_pGame->DevMode_LoadPlayerPos( 0,sName ); } return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::PlaySubtitle(IFunctionHandler * pH) { CHECK_PARAMETERS(1); int nCookie=0; ISound *pSound=NULL; if(pH->GetParamUDVal(1,(USER_DATA &)pSound,nCookie) && pSound && (nCookie==USER_DATA_SOUND)) //AMD Port { m_pGame->PlaySubtitle(pSound); } return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::GetModsList(IFunctionHandler * pH) { CGameMods *pMods=m_pGame->GetModsList(); if(!pMods) return pH->EndFunctionNull(); // game was not Init _SmartScriptObject pObj(m_pScriptSystem); int n=1; _SmartScriptObject pModDesc(m_pScriptSystem); pModDesc->SetValue("Title","- FarCry -"); pModDesc->SetValue("Name","FarCry"); pModDesc->SetValue("Version","1.3.3.0"); pModDesc->SetValue("Author","Crytek"); pModDesc->SetValue("Website","$2www.crytek.com"); pModDesc->SetValue("Description","This is the normal FarCry game. \nLoad this in case you got another mod loaded,\nand you want to switch back to normal FarCry."); pModDesc->SetValue("Folder",""); if ((!pMods->GetCurrentMod()) || (stricmp(pMods->GetCurrentMod(),"FarCry")==0)) { pModDesc->SetValue("CurrentMod",true); } pObj->SetAt(n, pModDesc); if (pMods->m_mods.empty()) return pH->EndFunction(pObj); n++; for (lstModsIt it=pMods->m_mods.begin();it!=pMods->m_mods.end();it++,n++) { SGameModDescription *pMod=(*it); char szTemp[256]; pMod->version.ToString(szTemp); _SmartScriptObject pModDesc1(m_pScriptSystem); pModDesc1->SetValue("Title",pMod->sTitle.c_str()); pModDesc1->SetValue("Name",pMod->sName.c_str()); pModDesc1->SetValue("Author",pMod->sAuthor.c_str()); pModDesc1->SetValue("Version",szTemp); pModDesc1->SetValue("Folder",pMod->sFolder.c_str()); pModDesc1->SetValue("Website",pMod->sWebsite.c_str()); pModDesc1->SetValue("Description",pMod->sDescription.c_str()); if (stricmp(pMods->GetCurrentMod(),pMod->sName.c_str())==0) { pModDesc1->SetValue("CurrentMod",true); } pObj->SetAt(n, pModDesc1); } return pH->EndFunction(pObj); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::LoadMOD(IFunctionHandler * pH) { const char *sName = NULL; bool bNeedsRestart; if (!pH->GetParam(1,sName)) return (pH->EndFunctionNull()); if (!pH->GetParam(2,bNeedsRestart)) bNeedsRestart=false; if (sName) { if (m_pGame->GetModsInterface()->SetCurrentMod(sName,bNeedsRestart)) { m_pGame->GetSystem()->GetILog()->Log("MOD %s loaded successfully",sName); } else m_pGame->GetSystem()->GetILog()->Log("MOD %s cannot be loaded",sName); } return (pH->EndFunction()); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::GetCurrentModName(IFunctionHandler * pH) { CGameMods *pMods=m_pGame->GetModsList(); if(!pMods) return pH->EndFunctionNull(); // game was not Init assert(pMods->GetCurrentMod()); return pH->EndFunction(pMods->GetCurrentMod()); } ////////////////////////////////////////////////////////////////////////// int CScriptObjectGame::EnableQuicksave(IFunctionHandler * pH) { CHECK_PARAMETERS(1); bool bEnable; pH->GetParam(1,bEnable); m_pGame->AllowQuicksave(bEnable); return pH->EndFunction(); }