// string string.SetAt(int a_index, int a_char); // Returns string with modified character at offset, or original string if index out of range. static int GM_CDECL gmStringSetAt(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_INT_PARAM(index, 0); GM_CHECK_INT_PARAM(newChar, 1); const gmVariable * var = a_thread->GetThis(); GM_ASSERT(var->m_type == GM_STRING); gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); const char * str = (const char *) *strObj; int strLength = strObj->GetLength(); if(index < 0 || index >= strLength) { a_thread->PushString(strObj); //Return original string if index out of range return GM_OK; } char * buffer = (char *) alloca(strLength + 1); memcpy(buffer, str, strLength + 1); //Copy old string buffer[index] = (char)newChar; //Set character in string a_thread->PushNewString(buffer, strLength); return GM_OK; }
static int GM_CDECL gmfFireTeamLeave( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 0 ); InterfaceFuncs::FireTeamLeave( native ); return GM_OK; }
static int GM_CDECL gmfStringSpanExcluding(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); if(a_thread->ParamType(0) == GM_STRING) { const gmVariable * var = a_thread->GetThis(); GM_ASSERT(var->m_type == GM_STRING); gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); const char * thisStr = (const char *) *strObj; const char * otherStr = a_thread->ParamString(0); int offset = strcspn(thisStr, otherStr); char * buffer = (char *) alloca(offset + 1); memcpy(buffer, thisStr, offset); buffer[offset] = 0; a_thread->PushNewString(buffer, offset); return GM_OK; } return GM_EXCEPTION; }
static int GM_CDECL gmfFireTeamGetInfo( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 0 ); ET_FireTeamInfo ft; if ( InterfaceFuncs::FireTeamGetInfo( native, ft ) && ft.mInFireTeam ) { DisableGCInScope gcEn( a_thread->GetMachine() ); gmMachine *pM = a_thread->GetMachine(); gmTableObject *tbl = pM->AllocTableObject(); gmTableObject *mbrtbl = pM->AllocTableObject(); tbl->Set( pM, "Members", gmVariable( mbrtbl ) ); tbl->Set( pM, "FireTeamNum", gmVariable( ft.mFireTeamNum ) ); tbl->Set( pM, "Leader", gmVariable::EntityVar( ft.mLeader.AsInt() ) ); int m = 0; for ( int i = 0; i < ET_FireTeamInfo::MaxMembers; ++i ) { if ( ft.mMembers[ i ].IsValid() ) { mbrtbl->Set( pM, m++, gmVariable::EntityVar( ft.mMembers[ i ].AsInt() ) ); } } a_thread->PushTable( tbl ); } else a_thread->PushNull(); return GM_OK; }
static int GM_CDECL gmfMax(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(2); int minType = gmMin<int>(a_thread->ParamType(0), a_thread->ParamType(1)); if(minType < GM_INT) { return GM_EXCEPTION; } int maxType = gmMax<int>(a_thread->ParamType(0), a_thread->ParamType(1)); if(maxType == GM_INT) { int valX = a_thread->Param(0).m_value.m_int; int valY = a_thread->Param(1).m_value.m_int; a_thread->PushInt( gmMax(valX, valY) ); return GM_OK; } else if(maxType == GM_FLOAT) { float valX = gmGetFloatOrIntParamAsFloat(a_thread, 0); float valY = gmGetFloatOrIntParamAsFloat(a_thread, 1); a_thread->PushFloat( gmMax(valX, valY) ); return GM_OK; } else { return GM_EXCEPTION; } }
// function: GetMG42Info // Returns currently mounted mg42 info for the bot // // // Parameters: // // GameEntity // Table // // Returns: // MG42 Info static int gmfGetMG42Info( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_TABLE_PARAM( tbl, 0 ); DisableGCInScope gcEn( a_thread->GetMachine() ); if ( !tbl ) tbl = a_thread->GetMachine()->AllocTableObject(); ET_MG42Info mg42Info; if ( tbl != NULL && InterfaceFuncs::GetMg42Properties( native, mg42Info ) ) { tbl->Set( a_thread->GetMachine(), "CenterFacing", gmVariable( mg42Info.mCenterFacing ) ); tbl->Set( a_thread->GetMachine(), "MinHorizontal", gmVariable( mg42Info.mMinHorizontalArc ) ); tbl->Set( a_thread->GetMachine(), "MaxHorizontal", gmVariable( mg42Info.mMaxHorizontalArc ) ); tbl->Set( a_thread->GetMachine(), "MinVertical", gmVariable( mg42Info.mMinVerticalArc ) ); tbl->Set( a_thread->GetMachine(), "MaxVertical", gmVariable( mg42Info.mMaxVerticalArc ) ); a_thread->PushInt( 1 ); } else { a_thread->PushNull(); } return GM_OK; }
static int GM_CDECL gmfVoteNo( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 0 ); native->GameCommand( "vote no" ); return GM_OK; }
// function: GetCabinetData // Returns table of data for the cabinet // // // Parameters: // // GameEntity // Table // // Returns: // Table of Cabinet Data static int gmfGetCabinetData( gmThread *a_thread ) { GM_CHECK_NUM_PARAMS( 2 ); GameEntity gameEnt; GM_CHECK_GAMEENTITY_FROM_PARAM( gameEnt, 0 ); GM_CHECK_TABLE_PARAM( tbl, 1 ); DisableGCInScope gcEn( a_thread->GetMachine() ); if ( !tbl ) tbl = a_thread->GetMachine()->AllocTableObject(); ET_CabinetData cabinetData; if ( tbl != NULL && InterfaceFuncs::GetCabinetData( gameEnt, cabinetData ) ) { tbl->Set( a_thread->GetMachine(), "CurrentAmount", gmVariable( cabinetData.mCurrentAmount ) ); tbl->Set( a_thread->GetMachine(), "MaxAmount", gmVariable( cabinetData.mMaxAmount ) ); tbl->Set( a_thread->GetMachine(), "Rate", gmVariable( cabinetData.mRate ) ); a_thread->PushInt( 1 ); } else { a_thread->PushNull(); } return GM_OK; }
static int GM_CDECL gmfCreateFolder(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(path, 0); BOOL result = CreateDirectory(path, NULL); if(result) { a_thread->PushInt(1); } else { WIN32_FIND_DATA findData; HANDLE handle = FindFirstFile(path, &findData); if(handle == INVALID_HANDLE_VALUE) { a_thread->PushInt(0); } else { if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { a_thread->PushInt(2); } else { a_thread->PushInt(0); } FindClose(handle); } } return GM_OK; }
static int GM_CDECL gmfFileSeek(gmThread * a_thread) // return false on error { gmUserObject * fileObject = a_thread->ThisUserObject(); GM_ASSERT(fileObject->m_userType == s_gmFileType); GM_CHECK_NUM_PARAMS(2); GM_CHECK_INT_PARAM(offset, 0); GM_CHECK_INT_PARAM(origin, 1); if( origin != SEEK_CUR && origin != SEEK_END && origin != SEEK_SET ) { return GM_EXCEPTION; } int result = fseek((FILE*)fileObject->m_user, offset, origin); if(result != 0) { a_thread->PushInt(false); } a_thread->PushInt(true); return GM_OK; }
static int GM_CDECL gmfEchoTable( gmThread *a_thread ) { GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_STRING_PARAM( tablename, 0 ); const int BUF_SIZE = 512; char buffer[ BUF_SIZE ] = { 0 }; char buffer2[ BUF_SIZE ] = { 0 }; gmMachine *pMachine = a_thread->GetMachine(); gmVariable vTable = pMachine->GetGlobals()->Get( pMachine, tablename ); gmTableObject *pTable = vTable.GetTableObjectSafe(); if ( pTable ) { gmTableIterator tIt; gmTableNode *pNode = pTable->GetFirst( tIt ); while ( pNode ) { EngineFuncs::ConsoleMessage( va( "%s = %s", pNode->m_key.AsString( pMachine, buffer, BUF_SIZE ), pNode->m_value.AsString( pMachine, buffer2, BUF_SIZE ) ) ); pNode = pTable->GetNext( tIt ); } } return GM_OK; }
// int string.ReverseFind(char/string a_charOrStringToFind); // Find the last instance of a specific character in a string. // Returns character offset or -1 if not found. static int GM_CDECL gmStringReverseFind(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); const char* retCharPtr = NULL; const gmVariable * var = a_thread->GetThis(); GM_ASSERT(var->m_type == GM_STRING); gmStringObject * thisStrObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); const char* thisStr = (const char *) *thisStrObj; if(a_thread->ParamType(0) == GM_INT) { const char otherChar = (char)a_thread->ParamInt(0); //Find character retCharPtr = strrchr(thisStr, otherChar); } else if(a_thread->ParamType(0) == GM_STRING) { gmStringObject * otherStrObj = a_thread->ParamStringObject(0); const char* otherStr = a_thread->ParamString(0); //Find string const char* lastFoundPtr = NULL; const char* newTestPtr = NULL; const char* curTestPtr = thisStr; const char* endThisStr = thisStr + thisStrObj->GetLength(); int searchStrLength = otherStrObj->GetLength(); //Search through string for last occurence //Not very efficient, but very rarely used. for(;;) { newTestPtr = strstr(curTestPtr, otherStr); if(!newTestPtr) { break; } lastFoundPtr = newTestPtr; curTestPtr = newTestPtr + searchStrLength; if(curTestPtr > endThisStr) { break; } }; retCharPtr = lastFoundPtr; } else { return GM_EXCEPTION; } // return -1 for not found, distance from beginning otherwise int retOffset = (retCharPtr == NULL) ? -1 : (int)(retCharPtr - thisStr); a_thread->PushInt(retOffset); return GM_OK; }
static int GM_CDECL LengthSquared(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(0); gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); a_thread->PushFloat( gmVector3::LengthSquared(*thisVec) ); return GM_OK; }
// function: GetReinforceTime // Gets the current reinforcement time for this bots team // // Parameters: // // none // // Returns: // int - reinforce timer static int GM_CDECL gmfGetReinforceTime( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 0 ); a_thread->PushFloat( InterfaceFuncs::GetReinforceTime( native ) ); return GM_OK; }
int gmMatrix3::gmfInverse(gmThread *a_thread) { GM_CHECK_NUM_PARAMS(0); gmMat3Type* native = gmMatrix3::GetThisObject( a_thread ); Matrix3f mInv = native->Inverse(); gmMatrix3::PushObject(a_thread, mInv); return GM_OK; }
static int GM_CDECL gmfEnable(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_INT_PARAM(enable, 0); VirtualMachine::Get()->GetConsole().Enable(enable != 0); return GM_OK; }
static int GM_CDECL gmfFireTeamApply( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_INT_PARAM( fireteamnum, 0 ); InterfaceFuncs::FireTeamApply( native, fireteamnum ); return GM_OK; }
static int GM_CDECL Dot(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); a_thread->PushFloat( gmVector3::Dot(*thisVec, *otherVec) ); return GM_OK; }
// function: BotPush // Set the bots push flag. // // // Parameters: // // int push - 0 or 1 // // Returns: // none static int GM_CDECL gmfDisableBotPush( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_INT_PARAM( botPush, 0 ); InterfaceFuncs::DisableBotPush( native, botPush ); return GM_OK; }
// void randseed(int a_seed); static int GM_CDECL gmfRandSeed(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_INT_PARAM(seed, 0); srand(seed); return GM_OK; }
static int GM_CDECL gmfFireTeamPropose( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GameEntity ent; GM_CHECK_GAMEENTITY_FROM_PARAM( ent, 0 ); InterfaceFuncs::FireTeamPropose( native, ent ); return GM_OK; }
static int GM_CDECL putString(gmThread* a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(data, 0); gmByteBuffer* buf = (gmByteBuffer*)a_thread->ThisUser_NoChecks(); buf->m_byteBuffer->append((const char*)data, strlen(data) + 1); return GM_OK; }
// function: ChangeSpawnPoint // Changes the bots active spawn point // // Parameters: // // int - Spawn point to change to // // Returns: // none static int GM_CDECL gmfChangeSpawnPoint( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_INT_PARAM( spawnpoint, 0 ); InterfaceFuncs::ChangeSpawnPoint( native, spawnpoint ); return GM_OK; }
static int GM_CDECL gmfSetSwapFreeze(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_INT_PARAM(swap_freeze, 0); g_swap_freeze = swap_freeze != 0; return GM_OK; }
static int GM_CDECL putShort(gmThread* a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_INT_PARAM(data, 0); gmByteBuffer* buf = (gmByteBuffer*)a_thread->ThisUser_NoChecks(); buf->m_byteBuffer->append<short>((short)data); return GM_OK; }
static int GM_CDECL putFloat(gmThread* a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_FLOAT_PARAM(data, 0); gmByteBuffer* buf = (gmByteBuffer*)a_thread->ThisUser_NoChecks(); buf->m_byteBuffer->append<float>(data); return GM_OK; }
// function: ChangeSecondaryWeapon // Sets the bots secondary weapon to a new weapon to use upon respawn // // Parameters: // // int - weapon id to choose for secondary weapon // // Returns: // int - true if success, false if error static int GM_CDECL gmfBotPickSecondaryWeapon( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GM_CHECK_INT_PARAM( weaponId, 0 ); bool bSucess = InterfaceFuncs::SelectSecondaryWeapon( native, (ET_Weapon)weaponId ); a_thread->PushInt( bSucess ? 1 : 0 ); return GM_OK; }
// function: IsMG42Repairable // Returns whether or not the MG42 is repairable // // // Parameters: // // GameEntity // // Returns: // 1 if the Mg42 is repairable static int gmfIsMG42Repairable( gmThread *a_thread ) { CHECK_THIS_BOT(); GM_CHECK_NUM_PARAMS( 1 ); GameEntity gameEnt; GM_CHECK_GAMEENTITY_FROM_PARAM( gameEnt, 0 ); a_thread->PushInt( InterfaceFuncs::IsMountableGunRepairable( native, gameEnt ) ? 1 : 0 ); return GM_OK; }
// int randint(int a_min, int a_max); // returned number is >= a_min and < a_max (exclusive of max) static int GM_CDECL gmfRandInt(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(2); GM_CHECK_INT_PARAM(min, 0); GM_CHECK_INT_PARAM(max, 1); a_thread->PushInt( gmRandomInt(min, max) ); return GM_OK; }
// float randfloat(float a_min, float a_max); // returned number is >= a_min and < a_max (exclusive of max) static int GM_CDECL gmfRandFloat(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(2); GM_CHECK_FLOAT_PARAM(min, 0); GM_CHECK_FLOAT_PARAM(max, 1); a_thread->PushFloat( gmRandomFloat(min, max) ); return GM_OK; }