void CKillMessages::OnMessage(int MsgType, void *pRawMsg) { if(MsgType == NETMSGTYPE_SV_KILLMSG) { CNetMsg_Sv_KillMsg *pMsg = (CNetMsg_Sv_KillMsg *)pRawMsg; if(pMsg->m_Victim == GameClient()->m_Snap.m_LocalClientID) GameClient()->m_pAStar->OnPlayerDeath(); // unpack messages CKillMsg Kill; Kill.m_VictimID = pMsg->m_Victim; Kill.m_VictimTeam = m_pClient->m_aClients[Kill.m_VictimID].m_Team; Kill.m_VictimDDTeam = m_pClient->m_Teams.Team(Kill.m_VictimID); str_copy(Kill.m_aVictimName, m_pClient->m_aClients[Kill.m_VictimID].m_aName, sizeof(Kill.m_aVictimName)); Kill.m_VictimRenderInfo = m_pClient->m_aClients[Kill.m_VictimID].m_RenderInfo; Kill.m_KillerID = pMsg->m_Killer; Kill.m_KillerTeam = m_pClient->m_aClients[Kill.m_KillerID].m_Team; str_copy(Kill.m_aKillerName, m_pClient->m_aClients[Kill.m_KillerID].m_aName, sizeof(Kill.m_aKillerName)); Kill.m_KillerRenderInfo = m_pClient->m_aClients[Kill.m_KillerID].m_RenderInfo; Kill.m_Weapon = pMsg->m_Weapon; Kill.m_ModeSpecial = pMsg->m_ModeSpecial; Kill.m_Tick = Client()->GameTick(); // EVENT CALL LUA_FIRE_EVENT("OnKill", Kill.m_KillerID, Kill.m_VictimID, Kill.m_Weapon); // add the message m_KillmsgCurrent = (m_KillmsgCurrent+1)%MAX_KILLMSGS; m_aKillmsgs[m_KillmsgCurrent] = Kill; } }
void CBackground::LoadBackground() { if(time_get()-m_LastLoad < 10*time_freq()) return; if(m_Loaded && m_pMap == m_pBackgroundMap) m_pMap->Unload(); m_Loaded = false; m_pMap = m_pBackgroundMap; m_pLayers->m_pLayers = m_pBackgroundLayers; m_pImages = m_pBackgroundImages; str_format(m_aMapName, sizeof(m_aMapName), "%s", g_Config.m_ClBackgroundEntities); char aBuf[128]; str_format(aBuf, sizeof(aBuf), "maps/%s", g_Config.m_ClBackgroundEntities); if(m_pMap->Load(aBuf)) { m_pLayers->m_pLayers->InitBackground(m_pMap); m_pImages->LoadBackground(m_pMap); RenderTools()->RenderTilemapGenerateSkip(m_pLayers->m_pLayers); m_Loaded = true; } else if(str_comp(g_Config.m_ClBackgroundEntities, CURRENT) == 0) { m_pMap = Kernel()->RequestInterface<IEngineMap>(); m_pLayers->m_pLayers = GameClient()->Layers(); m_pImages = GameClient()->m_pMapimages; m_Loaded = true; } m_LastLoad = time_get(); }
void CBackground::OnInit() { m_pImages->m_pClient = GameClient(); m_pLayers->m_pClient = GameClient(); Kernel()->ReregisterInterface(static_cast<IEngineMap*>(m_pMap)); str_format(m_aMapName, sizeof(m_aMapName), "%s", g_Config.m_ClBackgroundEntities); if(str_comp(g_Config.m_ClBackgroundEntities, CURRENT)) LoadBackground(); }
void CEmoticon::EyeEmote(int Emote) { char aBuf[32]; switch(Emote) { case EMOTE_NORMAL: str_format(aBuf, sizeof(aBuf), "/emote normal %d", g_Config.m_ClEyeDuration); break; case EMOTE_PAIN: str_format(aBuf, sizeof(aBuf), "/emote pain %d", g_Config.m_ClEyeDuration); break; case EMOTE_HAPPY: str_format(aBuf, sizeof(aBuf), "/emote happy %d", g_Config.m_ClEyeDuration); break; case EMOTE_SURPRISE: str_format(aBuf, sizeof(aBuf), "/emote surprise %d", g_Config.m_ClEyeDuration); break; case EMOTE_ANGRY: str_format(aBuf, sizeof(aBuf), "/emote angry %d", g_Config.m_ClEyeDuration); break; case EMOTE_BLINK: str_format(aBuf, sizeof(aBuf), "/emote blink %d", g_Config.m_ClEyeDuration); break; } GameClient()->m_pChat->Say(0, aBuf); }
CBackground::~CBackground() { if(m_pLayers->m_pLayers != GameClient()->Layers()) { delete m_pLayers->m_pLayers; delete m_pLayers; delete m_pImages; } }
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]; }
int CControls::SnapInput(int *pData) { static int64 LastSendTime = 0; bool Send = false; // update player state if(m_pClient->m_pChat->IsActive()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_CHATTING; else if(m_pClient->m_pMenus->IsActive()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_IN_MENU; else { if(m_InputData[g_Config.m_ClDummy].m_PlayerFlags == PLAYERFLAG_CHATTING) { CServerInfo Info; GameClient()->Client()->GetServerInfo(&Info); if(IsDDNet(&Info)) ResetInput(g_Config.m_ClDummy); } m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_PLAYING; } if(m_pClient->m_pScoreboard->Active()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; if(m_InputData[g_Config.m_ClDummy].m_PlayerFlags != PLAYERFLAG_PLAYING) m_JoystickTapTime = 0; // Do not launch hook on first tap if (m_pClient->m_pControls->m_ShowHookColl[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_AIM; if(m_LastData[g_Config.m_ClDummy].m_PlayerFlags != m_InputData[g_Config.m_ClDummy].m_PlayerFlags) Send = true; m_LastData[g_Config.m_ClDummy].m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags; // we freeze the input if chat or menu is activated if(!(m_InputData[g_Config.m_ClDummy].m_PlayerFlags&PLAYERFLAG_PLAYING)) { CServerInfo Info; GameClient()->Client()->GetServerInfo(&Info); if(!IsDDNet(&Info)) ResetInput(g_Config.m_ClDummy); mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); // send once a second just to be sure if(time_get() > LastSendTime + time_freq()) Send = true; } else { m_InputData[g_Config.m_ClDummy].m_TargetX = (int)m_MousePos[g_Config.m_ClDummy].x; m_InputData[g_Config.m_ClDummy].m_TargetY = (int)m_MousePos[g_Config.m_ClDummy].y; if(!m_InputData[g_Config.m_ClDummy].m_TargetX && !m_InputData[g_Config.m_ClDummy].m_TargetY) { m_InputData[g_Config.m_ClDummy].m_TargetX = 1; m_MousePos[g_Config.m_ClDummy].x = 1; } // set direction m_InputData[g_Config.m_ClDummy].m_Direction = 0; if(m_InputDirectionLeft[g_Config.m_ClDummy] && !m_InputDirectionRight[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_Direction = -1; if(!m_InputDirectionLeft[g_Config.m_ClDummy] && m_InputDirectionRight[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_Direction = 1; // dummy copy moves if(g_Config.m_ClDummyCopyMoves) { CNetObj_PlayerInput *pDummyInput = &m_pClient->m_DummyInput; pDummyInput->m_Direction = m_InputData[g_Config.m_ClDummy].m_Direction; pDummyInput->m_Hook = m_InputData[g_Config.m_ClDummy].m_Hook; pDummyInput->m_Jump = m_InputData[g_Config.m_ClDummy].m_Jump; pDummyInput->m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags; pDummyInput->m_TargetX = m_InputData[g_Config.m_ClDummy].m_TargetX; pDummyInput->m_TargetY = m_InputData[g_Config.m_ClDummy].m_TargetY; pDummyInput->m_WantedWeapon = m_InputData[g_Config.m_ClDummy].m_WantedWeapon; pDummyInput->m_Fire += m_InputData[g_Config.m_ClDummy].m_Fire - m_LastData[g_Config.m_ClDummy].m_Fire; pDummyInput->m_NextWeapon += m_InputData[g_Config.m_ClDummy].m_NextWeapon - m_LastData[g_Config.m_ClDummy].m_NextWeapon; pDummyInput->m_PrevWeapon += m_InputData[g_Config.m_ClDummy].m_PrevWeapon - m_LastData[g_Config.m_ClDummy].m_PrevWeapon; m_InputData[!g_Config.m_ClDummy] = *pDummyInput; } if(g_Config.m_ClDummyControl){ CNetObj_PlayerInput *pDummyInput = &m_pClient->m_DummyInput; pDummyInput->m_Jump = g_Config.m_ClDummyJump; pDummyInput->m_Fire = g_Config.m_ClDummyFire; pDummyInput->m_Hook = g_Config.m_ClDummyHook; } // stress testing #ifdef CONF_DEBUG if(g_Config.m_DbgStress) { float t = Client()->LocalTime(); mem_zero(&m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); m_InputData[g_Config.m_ClDummy].m_Direction = ((int)t/2)&1; m_InputData[g_Config.m_ClDummy].m_Jump = ((int)t); m_InputData[g_Config.m_ClDummy].m_Fire = ((int)(t*10)); m_InputData[g_Config.m_ClDummy].m_Hook = ((int)(t*2))&1; m_InputData[g_Config.m_ClDummy].m_WantedWeapon = ((int)t)%NUM_WEAPONS; m_InputData[g_Config.m_ClDummy].m_TargetX = (int)(sinf(t*3)*100.0f); m_InputData[g_Config.m_ClDummy].m_TargetY = (int)(cosf(t*3)*100.0f); } #endif // check if we need to send input if(m_InputData[g_Config.m_ClDummy].m_Direction != m_LastData[g_Config.m_ClDummy].m_Direction) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Jump != m_LastData[g_Config.m_ClDummy].m_Jump) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Fire != m_LastData[g_Config.m_ClDummy].m_Fire) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Hook != m_LastData[g_Config.m_ClDummy].m_Hook) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_WantedWeapon != m_LastData[g_Config.m_ClDummy].m_WantedWeapon) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_NextWeapon != m_LastData[g_Config.m_ClDummy].m_NextWeapon) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_PrevWeapon != m_LastData[g_Config.m_ClDummy].m_PrevWeapon) Send = true; // send at at least 10hz if(time_get() > LastSendTime + time_freq()/25) Send = true; if(m_pClient->m_Snap.m_pLocalCharacter && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon == WEAPON_NINJA && (m_InputData[g_Config.m_ClDummy].m_Direction || m_InputData[g_Config.m_ClDummy].m_Jump || m_InputData[g_Config.m_ClDummy].m_Hook)) Send = true; } // copy and return size m_LastData[g_Config.m_ClDummy] = m_InputData[g_Config.m_ClDummy]; if(!Send) return 0; LastSendTime = time_get(); mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); return sizeof(m_InputData[0]); }
void CMenus::RenderSettingsIdentTee(CUIRect MainView, int Page) { CIdentity::CIdentEntry *pEntry = m_pClient->m_pIdentity->GetIdent(Page); if(!m_pClient->m_pIdentity->NumIdents() || !pEntry) return; CUIRect Button, Label, View; // skin info const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(pEntry->m_aSkin)); CTeeRenderInfo OwnSkinInfo; if(pEntry->m_UseCustomColor) { OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorBody); OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorFeet); } else { OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; OwnSkinInfo.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f); OwnSkinInfo.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f); } OwnSkinInfo.m_Size = 50.0f*UI()->Scale(); MainView.Margin(10.0f, &MainView); MainView.HSplitTop(50.0f, &Label, &MainView); Label.VSplitMid(&View, &Label); // skin view RenderTools()->DrawUIRect(&Label, vec4(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, 10.0f); RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Label.x+30.0f, Label.y+28.0f)); Label.HSplitTop(15.0f, 0, &Label); Label.VSplitLeft(70.0f, 0, &Label); UI()->DoLabelScaled(&Label, pEntry->m_aSkin, 14.0f, -1, 150); // player name View.HSplitTop(20.0f, &Button, &View); Button.VSplitLeft(230.0f, &Button, 0); static CButtonContainer s_VanillaSkinsOnly; if(DoButton_CheckBox(&s_VanillaSkinsOnly, Localize("Allow Vanilla Skins only"), g_Config.m_ClVanillaSkinsOnly, &Button)) { g_Config.m_ClVanillaSkinsOnly ^= 1; GameClient()->m_pSkins->RefreshSkinList(); m_InitSkinlist = true; } // player clan View.HSplitTop(5.0f, 0, &View); View.HSplitTop(20.0f, &Button, &View); Button.VSplitLeft(230.0f, &Button, 0); static CButtonContainer s_CheckboxUseCustomColor; if(DoButton_CheckBox(&s_CheckboxUseCustomColor, Localize("Custom colors"), pEntry->m_UseCustomColor, &Button)) { pEntry->m_UseCustomColor ^= 1; m_NeedSendinfo = true; } // apply identity MainView.HSplitTop(5.0f, 0, &MainView); // vanilla skins only MainView.HSplitTop(10.0f, 0, &View); if(pEntry->m_UseCustomColor) { CUIRect aRects[2]; MainView.VSplitMid(&aRects[0], &aRects[1]); aRects[0].VSplitRight(10.0f, &aRects[0], 0); aRects[1].VSplitRight(10.0f, &aRects[1], 0); int *paColors[2] = { &pEntry->m_ColorBody, &pEntry->m_ColorFeet }; const char *paParts[] = { Localize("Body"), Localize("Feet")}; const char *paLabels[] = { Localize("Hue"), Localize("Sat."), Localize("Lht.")}; static int s_aColorSlider[2][3] = { { 0 } }; for(int i = 0; i < 2; i++) { aRects[i].HSplitTop(20.0f, &Label, &aRects[i]); UI()->DoLabelScaled(&Label, paParts[i], 14.0f, -1); aRects[i].VSplitLeft(20.0f, 0, &aRects[i]); aRects[i].HSplitTop(2.5f, 0, &aRects[i]); int PrevColor = *paColors[i]; int Color = 0; for(int s = 0; s < 3; s++) { aRects[i].HSplitTop(20.0f, &Label, &aRects[i]); Label.VSplitLeft(100.0f, &Label, &Button); Button.HMargin(2.0f, &Button); float k = ((PrevColor>>((2-s)*8))&0xff) / 255.0f; CPointerContainer Container(&s_aColorSlider[i][s]); k = DoScrollbarH(&Container, &Button, k, 0, (int)(k * 100.0f)); Color <<= 8; Color += clamp((int)(k*255), 0, 255); UI()->DoLabelScaled(&Label, paLabels[s], 14.0f, -1); } if(PrevColor != Color) m_NeedSendinfo = true; *paColors[i] = Color; } }
void CMenus::RenderSettingsIdentPlayer(CUIRect MainView, int Page) { CIdentity::CIdentEntry *pEntry = m_pClient->m_pIdentity->GetIdent(Page); if(!m_pClient->m_pIdentity->NumIdents() || !pEntry) return; CUIRect Button, Label; // skin info const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(pEntry->m_aSkin)); CTeeRenderInfo OwnSkinInfo; if(pEntry->m_UseCustomColor) { OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorBody); OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorFeet); } else { OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; OwnSkinInfo.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f); OwnSkinInfo.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f); } OwnSkinInfo.m_Size = 50.0f*UI()->Scale(); char aBuf[128]; MainView.Margin(10.0f, &MainView); MainView.HSplitTop(50.0f, &Label, &MainView); RenderTools()->DrawUIRect(&Label, vec4(1,1,1,0.2f), CUI::CORNER_ALL, 25.0f); Label.VSplitLeft(15.0f, 0, &Label); Label.HSplitTop(3.0f, 0, &Label); const bool IsMain = m_pClient->m_pIdentity->UsingIdent(Page, false); const bool IsDummy = m_pClient->m_pIdentity->UsingIdent(Page, true); str_format(aBuf, sizeof(aBuf), "%s", IsMain && !IsDummy ? Localize("Main Identity: ") : !IsMain && IsDummy ? Localize("Dummy's Identity: ") : IsMain && IsDummy ? Localize("Both's Identity: ") : ""); if(str_length(pEntry->m_aTitle) > 0) str_append(aBuf, pEntry->m_aTitle, sizeof(aBuf)); else str_append(aBuf, pEntry->m_aName, sizeof(aBuf)); UI()->DoLabelScaled(&Label, aBuf, 35.0f, -1, (int)Label.w); MainView.HSplitTop(10.0f, 0, &MainView); // skin view MainView.HSplitTop(50.0f, &Label, 0); Label.VSplitMid(0, &Label); RenderTools()->DrawUIRect(&Label, vec4(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, 10.0f); RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Label.x+30.0f, Label.y+28.0f)); Label.HSplitTop(15.0f, 0, &Label); Label.VSplitLeft(70.0f, 0, &Label); UI()->DoLabelScaled(&Label, pEntry->m_aSkin, 14.0f, -1, 150); // ident title MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Title")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); static float s_OffsetTitle[512] = {0.0f}; CPointerContainer ContainerTitle(&s_OffsetTitle[Page]); if(DoEditBox(&ContainerTitle, &Button, pEntry->m_aTitle, sizeof(pEntry->m_aTitle), 14.0f, &s_OffsetTitle[Page], false, CUI::CORNER_ALL, "", 0, Localize("a custom title to display this identity"))) m_NeedSendinfo = true; // player name MainView.HSplitTop(3.0f, 0, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); static float s_OffsetName[512] = {0.0f}; CPointerContainer ContainerName(&s_OffsetName[Page]); if(DoEditBox(&ContainerName, &Button, pEntry->m_aName, sizeof(g_Config.m_PlayerName), 14.0f, &s_OffsetName[Page])) m_NeedSendinfo = true; // player clan MainView.HSplitTop(3.0f, 0, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Clan")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); static float s_OffsetClan[512] = {0.0f}; CPointerContainer ContainerClan(&s_OffsetClan[Page]); if(DoEditBox(&ContainerClan, &Button, pEntry->m_aClan, sizeof(g_Config.m_PlayerClan), 14.0f, &s_OffsetClan[Page])) m_NeedSendinfo = true; // apply identity MainView.HSplitTop(3.0f, 0, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Apply as")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); Button.VSplitMid(&Button, &Label); static CButtonContainer s_ApplyButtonMain[512], s_ApplyButtonDummy[512]; if(!IsMain) { if(DoButton_Menu(&s_ApplyButtonMain[Page], Localize("Main"), 0, &Button, "", CUI::CORNER_L|CUI::CORNER_R*IsDummy, vec4(0.7f, 0.7f, 0.2f, 1.0f))) GameClient()->m_pIdentity->ApplyIdent(Page, false); } if(!IsDummy) { if(DoButton_Menu(&s_ApplyButtonDummy[Page], Localize("Dummy"), 0, &Label, "", CUI::CORNER_R|CUI::CORNER_L*IsMain, vec4(0.2f, 0.7f, 0.7f, 1.0f))) GameClient()->m_pIdentity->ApplyIdent(Page, true); } // country flag selector int *Country = &pEntry->m_Country; MainView.HSplitTop(20.0f, 0, &MainView); static float s_ScrollValue = 0.0f; int OldSelected = -1; static CButtonContainer s_Listbox; UiDoListboxStart(&s_Listbox, &MainView, 50.0f, Localize("Country"), "", m_pClient->m_pCountryFlags->Num(), 6, OldSelected, s_ScrollValue); for(int i = 0; i < m_pClient->m_pCountryFlags->Num(); ++i) { const CCountryFlags::CCountryFlag *pFlag = m_pClient->m_pCountryFlags->GetByIndex(i); if(pFlag->m_CountryCode == *Country) OldSelected = i; CPointerContainer Container(&pFlag->m_CountryCode); CListboxItem Item = UiDoListboxNextItem(&Container, OldSelected == i); if(Item.m_Visible) { CUIRect FlagLabel; Item.m_Rect.Margin(5.0f, &Item.m_Rect); Item.m_Rect.HSplitBottom(10.0f, &Item.m_Rect, &FlagLabel); float OldWidth = Item.m_Rect.w; Item.m_Rect.w = Item.m_Rect.h*2; Item.m_Rect.x += (OldWidth-Item.m_Rect.w)/ 2.0f; vec4 Color(1.0f, 1.0f, 1.0f, 1.0f); m_pClient->m_pCountryFlags->Render(pFlag->m_CountryCode, &Color, Item.m_Rect.x, Item.m_Rect.y, Item.m_Rect.w, Item.m_Rect.h); if(pFlag->m_Texture != -1) UI()->DoLabel(&FlagLabel, pFlag->m_aCountryCodeString, 10.0f, 0); } } const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { *Country = m_pClient->m_pCountryFlags->GetByIndex(NewSelected)->m_CountryCode; if(m_Dummy) m_NeedSendDummyinfo = true; else m_NeedSendinfo = true; } }
void CMenus::RenderIdents(CUIRect MainView) { const int NumIdentities = m_pClient->m_pIdentity->NumIdents(); CUIRect Button, Label, Temp; static float s_Scrollbar = 0; static float s_ScrollValue = 0; RenderTools()->DrawUIRect(&MainView, vec4(0.65f, 0.68f, 0.9f, 0.64f), CUI::CORNER_T, 10.0f); MainView.HSplitTop(8.0f, &Button, &Temp); Button.VSplitMid(&Button, &Label); // scrollbar Temp.HSplitTop(16.0f, &Button, &Temp); Button.VMargin(4.0f, &Button); s_ScrollValue = DoScrollbarH(&s_Scrollbar, &Button, s_ScrollValue); Temp.HSplitTop(68.0f, &Button, &Temp); UI()->ClipEnable(&Button); Button.HMargin(5.0f, &Button); Button.VSplitLeft(7.5f, 0, &Button); int Offset = 2*30.0f + 80 * (NumIdentities - 4); if(Offset > 0) Button.x -= Offset * s_ScrollValue; for(int i = 0; i < NumIdentities; i++) { CIdentity::CIdentEntry *pIdent = m_pClient->m_pIdentity->GetIdent(i); if(pIdent == NULL) continue; const CSkins::CSkin *pSkin = NULL; CTeeRenderInfo SkinInfo; pSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(pIdent->m_aSkin)); if(pIdent->m_UseCustomColor) { SkinInfo.m_Texture = pSkin->m_ColorTexture; SkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(pIdent->m_ColorBody); SkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pIdent->m_ColorFeet); } else { SkinInfo.m_Texture = pSkin->m_OrgTexture; SkinInfo.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f); SkinInfo.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f); } Button.VSplitLeft(80.0f, &Label, &Button); static int s_Button[512] = {0}; if(DoButton_Menu(&s_Button[i], "", 0, &Label, 0, CUI::CORNER_ALL, pIdent->m_UseCustomColor ? mix(SkinInfo.m_ColorBody, SkinInfo.m_ColorFeet, 0.4f)*0.7f : vec4(pSkin->m_BloodColor.r, pSkin->m_BloodColor.g, pSkin->m_BloodColor.b, 0.7f))) { CIdentity::CIdentEntry *pIdent = m_pClient->m_pIdentity->GetIdent(i); str_format(g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), pIdent->m_aName); str_format(g_Config.m_PlayerClan, sizeof(g_Config.m_PlayerClan), pIdent->m_aClan); str_format(g_Config.m_ClPlayerSkin, sizeof(g_Config.m_ClPlayerSkin), pIdent->m_aSkin); g_Config.m_ClPlayerUseCustomColor = pIdent->m_UseCustomColor; g_Config.m_ClPlayerColorBody = pIdent->m_ColorBody; g_Config.m_ClPlayerColorFeet = pIdent->m_ColorFeet; m_pClient->SendInfo(false); } SkinInfo.m_Size = 50.0f*UI()->Scale(); RenderTools()->RenderTee(CAnimState::GetIdle(), &SkinInfo, 0, vec2(1, 0), vec2(Label.x + Label.w * 0.5f, Label.y + Label.h * 0.5f + 8.0f)); Label.HSplitBottom(15.0f, 0, &Label); Label.y = Button.y; // some h4XoRinG right here to get awesome R41NB0W!! static float s_Hue = 1000.0f; if(s_Hue > 1.0f) s_Hue = RgbToHsl(vec3(1.0f, 0.0f, 0.0f)).h; s_Hue += 0.0007f; vec3 rgb = HslToRgb(vec3(s_Hue, 1.0f, 0.5f)); RenderTools()->DrawUIRect(&Label, GameClient()->m_pIdentity->UsingIdent(i) ? vec4(rgb.r, rgb.g, rgb.b, 0.71f) : vec4(pSkin->m_BloodColor.r * 0.3f, pSkin->m_BloodColor.g * 0.3f, pSkin->m_BloodColor.b * 0.3f, 0.95f), CUI::CORNER_T, 4.0f); UI()->DoLabelScaled(&Label, pIdent->m_aName, 10.0f, 0); Button.VSplitLeft(15.0f, 0, &Button); } UI()->ClipDisable(); }