int CMapImages::GetEntities() { CServerInfo Info; Client()->GetServerInfo(&Info); if(m_EntitiesTextures == -1 || str_comp(m_aEntitiesGameType, Info.m_aGameType)) { // DDNet default to prevent delay in seeing entities char file[64] = "ddnet"; if(IsDDNet(&Info)) str_copy(file, "ddnet", sizeof(file)); else if(IsDDRace(&Info)) str_copy(file, "ddrace", sizeof(file)); else if(IsRace(&Info)) str_copy(file, "race", sizeof(file)); else if(IsFNG(&Info)) str_copy(file, "fng", sizeof(file)); else if(IsVanilla(&Info)) str_copy(file, "vanilla", sizeof(file)); char path[64]; str_format(path, sizeof(path), "editor/entities_clear/%s.png", file); if(m_EntitiesTextures >= 0) Graphics()->UnloadTexture(m_EntitiesTextures); m_EntitiesTextures = Graphics()->LoadTexture(path, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0); str_copy(m_aEntitiesGameType, Info.m_aGameType, sizeof(m_aEntitiesGameType)); } return m_EntitiesTextures; }
void CCamera::ConZoomPlus(IConsole::IResult *pResult, void *pUserData) { CCamera *pSelf = (CCamera *)pUserData; CServerInfo Info; pSelf->Client()->GetServerInfo(&Info); if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active || IsRace(&Info) || IsBlockWorlds(&Info) || pSelf->Client()->State() == IClient::STATE_DEMOPLAYBACK) ((CCamera *)pUserData)->m_Zoom *= ZoomStep; }
static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData) { CInputState *pState = (CInputState *)pUserData; CServerInfo Info; pState->m_pControls->GameClient()->Client()->GetServerInfo(&Info); if ((IsRace(&Info) || IsDDRace(&Info)) && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active) return; if (g_Config.m_ClDummy) *pState->m_pVariable2 = pResult->GetInteger(0); else *pState->m_pVariable1 = pResult->GetInteger(0); }
void CGhost::OnNewPredictedSnapshot() { CServerInfo ServerInfo; Client()->GetServerInfo(&ServerInfo); if(!IsRace(&ServerInfo) || !g_Config.m_ClRaceGhost || Client()->State() != IClient::STATE_ONLINE) return; if(!m_pClient->m_Snap.m_pGameInfoObj || m_pClient->m_Snap.m_SpecInfo.m_Active || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter) return; bool RaceFlag = m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_RACETIME; bool ServerControl = RaceFlag && g_Config.m_ClRaceGhostServerControl; if(!ServerControl) CheckStartLocal(true); }
// Checks if this object matches with the specified object_node. // Also keeps wildcards in consideration. Used for triggers. bool Object::MatchNode(object_node* node) const { if (IsName(node->name) && IsClass(node->classs) && IsRace(node->race) && IsAlignment(node->alignment) && IsGender(node->gender) && IsGeneral(node->general) && IsSpecific(node->specific) && IsEnemyAlly(node->ea)) return true; return false; }
static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData) { CInputState *pState = (CInputState *)pUserData; CServerInfo Info; pState->m_pControls->GameClient()->Client()->GetServerInfo(&Info); if ((IsRace(&Info) || IsDDRace(&Info)) && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active) return; int *v; if (g_Config.m_ClDummy) v = pState->m_pVariable2; else v = pState->m_pVariable1; if(((*v)&1) != pResult->GetInteger(0)) (*v)++; *v &= INPUT_STATE_MASK; }
void CGhost::OnNewSnapshot() { CServerInfo ServerInfo; Client()->GetServerInfo(&ServerInfo); if(!IsRace(&ServerInfo) || !g_Config.m_ClRaceGhost || Client()->State() != IClient::STATE_ONLINE) return; if(!m_pClient->m_Snap.m_pGameInfoObj || m_pClient->m_Snap.m_SpecInfo.m_Active || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter) return; bool RaceFlag = m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_RACETIME; bool ServerControl = RaceFlag && g_Config.m_ClRaceGhostServerControl; if(!ServerControl) CheckStartLocal(false); else CheckStart(); if(m_Recording) AddInfos(m_pClient->m_Snap.m_pLocalCharacter); int RaceTick = -m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer; m_LastRaceTick = RaceFlag ? RaceTick : -1; }
void CControls::OnRender() { enum { JOYSTICK_RUN_DISTANCE = 65536 / 8, GAMEPAD_DEAD_ZONE = 65536 / 8, }; int64 CurTime = time_get(); bool FireWasPressed = false; if( m_Joystick ) { // Get input from left joystick int RunX = SDL_JoystickGetAxis(m_Joystick, LEFT_JOYSTICK_X); int RunY = SDL_JoystickGetAxis(m_Joystick, LEFT_JOYSTICK_Y); bool RunPressed = (RunX != 0 || RunY != 0); // Get input from right joystick int AimX = SDL_JoystickGetAxis(m_Joystick, SECOND_RIGHT_JOYSTICK_X); int AimY = SDL_JoystickGetAxis(m_Joystick, SECOND_RIGHT_JOYSTICK_Y); bool AimPressed = (AimX != 0 || AimY != 0); // Get input from another right joystick int HookX = SDL_JoystickGetAxis(m_Joystick, RIGHT_JOYSTICK_X); int HookY = SDL_JoystickGetAxis(m_Joystick, RIGHT_JOYSTICK_Y); bool HookPressed = (HookX != 0 || HookY != 0); if( m_JoystickRunPressed != RunPressed ) { if( RunPressed ) { if( m_JoystickTapTime + time_freq() > CurTime ) // Tap in less than 1 second to jump m_InputData[g_Config.m_ClDummy].m_Jump = 1; } else m_InputData[g_Config.m_ClDummy].m_Jump = 0; m_JoystickTapTime = CurTime; } m_JoystickRunPressed = RunPressed; if( RunPressed ) { m_InputDirectionLeft[g_Config.m_ClDummy] = (RunX < -JOYSTICK_RUN_DISTANCE); m_InputDirectionRight[g_Config.m_ClDummy] = (RunX > JOYSTICK_RUN_DISTANCE); } // Move 500ms in the same direction, to prevent speed bump when tapping if( !RunPressed && m_JoystickTapTime + time_freq() / 2 > CurTime ) { m_InputDirectionLeft[g_Config.m_ClDummy] = 0; m_InputDirectionRight[g_Config.m_ClDummy] = 0; } if( HookPressed ) { m_MousePos[g_Config.m_ClDummy] = vec2(HookX / 30, HookY / 30); ClampMousePos(); m_InputData[g_Config.m_ClDummy].m_Hook = 1; } else { m_InputData[g_Config.m_ClDummy].m_Hook = 0; } if( AimPressed ) { m_MousePos[g_Config.m_ClDummy] = vec2(AimX / 30, AimY / 30); ClampMousePos(); } if( AimPressed != m_JoystickFirePressed ) { // Fire when releasing joystick if( !AimPressed ) { m_InputData[g_Config.m_ClDummy].m_Fire ++; if( (bool)(m_InputData[g_Config.m_ClDummy].m_Fire % 2) != AimPressed ) m_InputData[g_Config.m_ClDummy].m_Fire ++; FireWasPressed = true; } } m_JoystickFirePressed = AimPressed; } if( m_Gamepad ) { // Get input from left joystick int RunX = SDL_JoystickGetAxis(m_Gamepad, LEFT_JOYSTICK_X); int RunY = SDL_JoystickGetAxis(m_Gamepad, LEFT_JOYSTICK_Y); if( m_UsingGamepad ) { m_InputDirectionLeft[g_Config.m_ClDummy] = (RunX < -GAMEPAD_DEAD_ZONE); m_InputDirectionRight[g_Config.m_ClDummy] = (RunX > GAMEPAD_DEAD_ZONE); } // Get input from right joystick int AimX = SDL_JoystickGetAxis(m_Gamepad, RIGHT_JOYSTICK_X); int AimY = SDL_JoystickGetAxis(m_Gamepad, RIGHT_JOYSTICK_Y); if( abs(AimX) > GAMEPAD_DEAD_ZONE || abs(AimY) > GAMEPAD_DEAD_ZONE ) { m_MousePos[g_Config.m_ClDummy] = vec2(AimX / 30, AimY / 30); ClampMousePos(); } if( !m_UsingGamepad && (abs(AimX) > GAMEPAD_DEAD_ZONE || abs(AimY) > GAMEPAD_DEAD_ZONE || abs(RunX) > GAMEPAD_DEAD_ZONE || abs(RunY) > GAMEPAD_DEAD_ZONE) ) { UI()->AndroidShowScreenKeys(false); m_UsingGamepad = true; } } CServerInfo Info; GameClient()->Client()->GetServerInfo(&Info); if( g_Config.m_ClAutoswitchWeaponsOutOfAmmo && !IsRace(&Info) && !IsDDRace(&Info) && m_pClient->m_Snap.m_pLocalCharacter ) { // Keep track of ammo count, we know weapon ammo only when we switch to that weapon, this is tracked on server and protocol does not track that m_AmmoCount[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS] = m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount; // Autoswitch weapon if we're out of ammo if( (m_InputData[g_Config.m_ClDummy].m_Fire % 2 != 0 || FireWasPressed) && m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount == 0 && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_HAMMER && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_NINJA ) { int w; for( w = WEAPON_RIFLE; w > WEAPON_GUN; w-- ) { if( w == m_pClient->m_Snap.m_pLocalCharacter->m_Weapon ) continue; if( m_AmmoCount[w] > 0 ) break; } if( w != m_pClient->m_Snap.m_pLocalCharacter->m_Weapon ) m_InputData[g_Config.m_ClDummy].m_WantedWeapon = w+1; } } // update target pos if(m_pClient->m_Snap.m_pGameInfoObj && !m_pClient->m_Snap.m_SpecInfo.m_Active) m_TargetPos[g_Config.m_ClDummy] = m_pClient->m_LocalCharacterPos + m_MousePos[g_Config.m_ClDummy]; else if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_UsePosition) m_TargetPos[g_Config.m_ClDummy] = m_pClient->m_Snap.m_SpecInfo.m_Position + m_MousePos[g_Config.m_ClDummy]; else m_TargetPos[g_Config.m_ClDummy] = m_MousePos[g_Config.m_ClDummy]; }
void CAStar::BuildPath(void *pUser) { CAStar* pSelf = (CAStar*)pUser; { CServerInfo Info; pSelf->Client()->GetServerInfo(&Info); if(!g_Config.m_ClPathFinding || !(IsRace(&Info) || IsDDNet(&Info))) return; } int SolutionLength = -1; int *pSolution = 0; int Start = pSelf->GetStart(); int Finish = pSelf->GetFinish(); /* if(Start == -1) dbg_msg("path", "didn't find start tile"); if(Finish == -1) dbg_msg("path", "didn't find finish tile"); */ if(Start >= 0 && Finish >= 0) { pSelf->FillGrid(true); pSolution = astar_compute((const char *)pSelf->m_pField, &SolutionLength, pSelf->Collision()->GetWidth(), pSelf->Collision()->GetHeight(), Start, Finish); dbg_msg("path", "start=%i, finish=%i, length=%i", Start, Finish, SolutionLength); } if(SolutionLength == -1) // try again, ignoring freeze { pSelf->FillGrid(false); pSolution = astar_compute((const char *)pSelf->m_pField, &SolutionLength, pSelf->Collision()->GetWidth(), pSelf->Collision()->GetHeight(), Start, Finish); dbg_msg("path", "ignored freeze: start=%i, finish=%i, length=%i", Start, Finish, SolutionLength); } if(g_Config.m_ClNotifications) { if(SolutionLength != -1) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Found path. Length: %i", SolutionLength); pSelf->m_pClient->m_pHud->PushNotification(aBuf); } else pSelf->m_pClient->m_pHud->PushNotification("No possible path found."); } if(pSolution) { if(SolutionLength > 0) { pSelf->m_PathFound = true; for(int i = SolutionLength; i >= 0 ; i--) { pSelf->m_Path.add(pSelf->Collision()->GetPos(pSolution[i])); thread_sleep(10); if(pSelf->m_ThreadShouldExit) { return; } } } free(pSolution); } }
void CCamera::OnRender() { CServerInfo Info; Client()->GetServerInfo(&Info); if(!(m_pClient->m_Snap.m_SpecInfo.m_Active || IsRace(&Info) || IsBlockWorlds(&Info) || Client()->State() == IClient::STATE_DEMOPLAYBACK)) { if(!Client()->DummyConnected() && !Client()->DummyConnecting()) { m_ZoomSet = false; m_Zoom = 1.0; } } else if(!m_ZoomSet && g_Config.m_ClDefaultZoom != 10) { m_ZoomSet = true; OnReset(); } // update camera center if(m_pClient->m_Snap.m_SpecInfo.m_Active && !m_pClient->m_Snap.m_SpecInfo.m_UsePosition) { if(m_CamType != CAMTYPE_SPEC) { m_LastPos[g_Config.m_ClDummy] = m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]; m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy] = m_PrevCenter; m_pClient->m_pControls->ClampMousePos(); m_CamType = CAMTYPE_SPEC; } m_Center = m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]; } else { if(m_CamType != CAMTYPE_PLAYER) { if(m_LastPos[g_Config.m_ClDummy].x < g_Config.m_ClMouseMinDistance) m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy].x = m_LastPos[g_Config.m_ClDummy].x + g_Config.m_ClMouseMinDistance; else m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy] = m_LastPos[g_Config.m_ClDummy]; m_pClient->m_pControls->ClampMousePos(); m_CamType = CAMTYPE_PLAYER; } vec2 CameraOffset(0, 0); float l = length(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]); if(l > 0.0001f) // make sure that this isn't 0 { float DeadZone = g_Config.m_ClDyncam ? g_Config.m_ClDyncamDeadzone : g_Config.m_ClMouseDeadzone; float FollowFactor = (g_Config.m_ClDyncam ? g_Config.m_ClDyncamFollowFactor : g_Config.m_ClMouseFollowfactor) / 100.0f; float OffsetAmount = maximum(l-DeadZone, 0.0f) * FollowFactor; CameraOffset = normalize(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy])*OffsetAmount; } if(m_pClient->m_Snap.m_SpecInfo.m_Active) m_Center = m_pClient->m_Snap.m_SpecInfo.m_Position + CameraOffset; else m_Center = m_pClient->m_LocalCharacterPos + CameraOffset; } m_PrevCenter = m_Center; }