diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 258bc672a..28295f15e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -25,7 +25,7 @@ jobs: CXXFLAGS: -Werror - os: ubuntu-20.04 cmake-path: /usr/bin/ - cmake-args: -G Ninja + cmake-args: -G Ninja -DTEST_MYSQL=ON package-file: "*-linux_x86_64.tar.xz" fancy: false env: @@ -60,15 +60,31 @@ jobs: sudo apt-get upgrade -y sudo apt-get install pkg-config cmake ninja-build libfreetype6-dev libnotify-dev libsdl2-dev libsqlite3-dev libvulkan-dev glslang-tools spirv-tools libavcodec-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev libx264-dev -y + - name: Prepare Linux (non-fancy) + if: ${{ contains(matrix.os, 'ubuntu') && !matrix.fancy }} + run: | + sudo rm -rf /var/lib/mysql/ /var/run/mysqld + sudo mkdir /var/lib/mysql/ /var/run/mysqld/ + sudo chown mysql:mysql /var/lib/mysql/ /var/run/mysqld/ + sudo mysqld --initialize-insecure --user=mysql --basedir=/usr --datadir=/var/lib/mysql/ + sudo /usr/bin/mysqld_safe --basedir=/usr --datadir='/var/lib/mysql/' & + sleep 10 + sudo mysql < #include #include -template -constexpr inline T clamp(T val, T min, T max) -{ - return val < min ? min : (val > max ? max : val); -} - -constexpr inline float sign(float f) -{ - return f < 0.0f ? -1.0f : 1.0f; -} +using std::clamp; constexpr inline int round_to_int(float f) { @@ -65,17 +57,6 @@ constexpr inline int fx2i(int v) return v / fxpscale; } -inline int gcd(int a, int b) -{ - while(b != 0) - { - int c = a % b; - a = b; - b = c; - } - return a; -} - class fxp { int value; diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index de5d12c19..2b803487d 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -1470,12 +1470,14 @@ void CGraphics_Threaded::QuadContainerUpload(int ContainerIndex) } } -void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) +int CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) { SQuadContainer &Container = m_QuadContainers[ContainerIndex]; if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES) - return; + return -1; + + int RetOff = (int)Container.m_Quads.size(); for(int i = 0; i < Num; ++i) { @@ -1514,14 +1516,18 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CQuadItem *pA if(Container.m_AutomaticUpload) QuadContainerUpload(ContainerIndex); + + return RetOff; } -void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) +int CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) { SQuadContainer &Container = m_QuadContainers[ContainerIndex]; if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES) - return; + return -1; + + int RetOff = (int)Container.m_Quads.size(); for(int i = 0; i < Num; ++i) { @@ -1551,6 +1557,8 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem if(Container.m_AutomaticUpload) QuadContainerUpload(ContainerIndex); + + return RetOff; } void CGraphics_Threaded::QuadContainerReset(int ContainerIndex) diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 2acb25c92..3a6f7d4f7 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -1141,8 +1141,8 @@ public: int CreateQuadContainer(bool AutomaticUpload = true) override; void QuadContainerChangeAutomaticUpload(int ContainerIndex, bool AutomaticUpload) override; void QuadContainerUpload(int ContainerIndex) override; - void QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) override; - void QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) override; + int QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) override; + int QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) override; void QuadContainerReset(int ContainerIndex) override; void DeleteQuadContainer(int ContainerIndex) override; void RenderQuadContainer(int ContainerIndex, int QuadDrawNum) override; diff --git a/src/engine/graphics.h b/src/engine/graphics.h index 378293acf..5f960fd94 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -422,8 +422,8 @@ public: virtual int CreateQuadContainer(bool AutomaticUpload = true) = 0; virtual void QuadContainerChangeAutomaticUpload(int ContainerIndex, bool AutomaticUpload) = 0; virtual void QuadContainerUpload(int ContainerIndex) = 0; - virtual void QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) = 0; - virtual void QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) = 0; + virtual int QuadContainerAddQuads(int ContainerIndex, CQuadItem *pArray, int Num) = 0; + virtual int QuadContainerAddQuads(int ContainerIndex, CFreeformItem *pArray, int Num) = 0; virtual void QuadContainerReset(int ContainerIndex) = 0; virtual void DeleteQuadContainer(int ContainerIndex) = 0; virtual void RenderQuadContainer(int ContainerIndex, int QuadDrawNum) = 0; diff --git a/src/engine/server/databases/mysql.cpp b/src/engine/server/databases/mysql.cpp index d34a18bc7..bcb979383 100644 --- a/src/engine/server/databases/mysql.cpp +++ b/src/engine/server/databases/mysql.cpp @@ -10,6 +10,10 @@ #include #include +#ifndef LIBMARIADB +typedef bool my_bool; +#endif + enum { MYSQLSTATE_UNINITIALIZED, diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 8ba2e87f0..fb4710da7 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -37,7 +37,7 @@ class CSnapIDPool { enum { - MAX_IDS = 16 * 1024, + MAX_IDS = 32 * 1024, }; class CID diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index f7aeb4af8..ed9c5dcff 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -141,7 +141,11 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu SPRITE_PICKUP_HEALTH, SPRITE_PICKUP_ARMOR, SPRITE_PICKUP_WEAPON, - SPRITE_PICKUP_NINJA}; + SPRITE_PICKUP_NINJA, + SPRITE_PICKUP_ARMOR_SHOTGUN, + SPRITE_PICKUP_ARMOR_GRENADE, + SPRITE_PICKUP_ARMOR_NINJA, + SPRITE_PICKUP_ARMOR_LASER}; int CurWeapon = clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS - 1); @@ -149,6 +153,14 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupHealth); else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR) Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmor); + else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR_SHOTGUN) + Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmorShotgun); + else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR_GRENADE) + Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmorGrenade); + else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR_LASER) + Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmorLaser); + else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR_NINJA) + Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmorNinja); else if(c[pCurrent->m_Type] == SPRITE_PICKUP_WEAPON) { Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupWeapons[CurWeapon]); @@ -178,6 +190,10 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu m_pClient->m_Effects.PowerupShine(Pos, vec2(96, 18)); Pos.x -= 10.0f; } + else if(c[pCurrent->m_Type] >= SPRITE_PICKUP_ARMOR_SHOTGUN && c[pCurrent->m_Type] <= SPRITE_PICKUP_ARMOR_NINJA) + { + QuadOffset = m_WeaponArmorQuadOffset + (c[pCurrent->m_Type] - SPRITE_PICKUP_ARMOR_SHOTGUN); + } } Graphics()->QuadsSetRotation(Angle); @@ -549,6 +565,19 @@ void CItems::OnInit() Graphics()->QuadsSetSubset(0, 0, 1, 1); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f); + RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR_SHOTGUN, ScaleX, ScaleY); + Graphics()->QuadsSetSubset(0, 0, 1, 1); + m_WeaponArmorQuadOffset = RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY); + RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR_GRENADE, ScaleX, ScaleY); + Graphics()->QuadsSetSubset(0, 0, 1, 1); + RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY); + RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR_NINJA, ScaleX, ScaleY); + Graphics()->QuadsSetSubset(0, 0, 1, 1); + RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY); + RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR_LASER, ScaleX, ScaleY); + Graphics()->QuadsSetSubset(0, 0, 1, 1); + RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY); + Graphics()->QuadContainerUpload(m_ItemsQuadContainerIndex); } diff --git a/src/game/client/components/items.h b/src/game/client/components/items.h index 11a09f59f..b60238403 100644 --- a/src/game/client/components/items.h +++ b/src/game/client/components/items.h @@ -15,6 +15,8 @@ class CItems : public CComponent int m_ItemsQuadContainerIndex; + int m_WeaponArmorQuadOffset = 0; + public: virtual int Sizeof() const override { return sizeof(*this); } virtual void OnRender() override; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index a92657d22..53af4f769 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -36,6 +36,7 @@ #include #include +#include CMenusKeyBinder CMenus::m_Binder; @@ -531,7 +532,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) { m_Dummy ^= 1; } - GameClient()->m_Tooltips.DoToolTip(&m_Dummy, &DummyLabel, Localize("Toggle to edit your dummy settings.")); + GameClient()->m_Tooltips.DoToolTip(&m_Dummy, &DummyLabel, Localize("Toggle to edit your dummy settings")); Dummy.HSplitTop(20.0f, &DummyLabel, &Dummy); @@ -639,7 +640,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) GameClient()->m_Emoticon.EyeEmote(CurrentEyeEmote); } } - GameClient()->m_Tooltips.DoToolTip(&s_aEyesToolTip[CurrentEyeEmote], &EyesTee, Localize("Choose default eyes when joining a server.")); + GameClient()->m_Tooltips.DoToolTip(&s_aEyesToolTip[CurrentEyeEmote], &EyesTee, Localize("Choose default eyes when joining a server")); RenderTools()->RenderTee(pIdleState, &OwnSkinInfo, CurrentEyeEmote, vec2(1, 0), vec2(EyesTee.x + 25.0f, EyesTee.y + EyesTee.h / 2.0f + OffsetToMid.y)); } @@ -1212,7 +1213,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) static const float sc_FontSizeResList = 10.0f; int OldSelected = -1; { - int G = gcd(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight); + int G = std::gcd(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight); str_format(aBuf, sizeof(aBuf), "%s: %dx%d @%dhz %d bit (%d:%d)", Localize("Current"), int(g_Config.m_GfxScreenWidth * Graphics()->ScreenHiDPIScale()), int(g_Config.m_GfxScreenHeight * Graphics()->ScreenHiDPIScale()), g_Config.m_GfxScreenRefreshRate, g_Config.m_GfxColorDepth, g_Config.m_GfxScreenWidth / G, g_Config.m_GfxScreenHeight / G); } @@ -1233,7 +1234,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) CListboxItem Item = UiDoListboxNextItem(&s_aModes[i], OldSelected == i); if(Item.m_Visible) { - int G = gcd(s_aModes[i].m_CanvasWidth, s_aModes[i].m_CanvasHeight); + int G = std::gcd(s_aModes[i].m_CanvasWidth, s_aModes[i].m_CanvasHeight); str_format(aBuf, sizeof(aBuf), " %dx%d @%dhz %d bit (%d:%d)", s_aModes[i].m_CanvasWidth, s_aModes[i].m_CanvasHeight, s_aModes[i].m_RefreshRate, Depth, s_aModes[i].m_CanvasWidth / G, s_aModes[i].m_CanvasHeight / G); UI()->DoLabelScaled(&Item.m_Rect, aBuf, sc_FontSizeResList, TEXTALIGN_LEFT); } @@ -1347,7 +1348,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) MainView.HSplitTop(20.0f, &Button, &MainView); if(DoButton_CheckBox(&g_Config.m_GfxHighDetail, Localize("High Detail"), g_Config.m_GfxHighDetail, &Button)) g_Config.m_GfxHighDetail ^= 1; - GameClient()->m_Tooltips.DoToolTip(&g_Config.m_GfxHighDetail, &Button, Localize("Allows maps to render with more detail.")); + GameClient()->m_Tooltips.DoToolTip(&g_Config.m_GfxHighDetail, &Button, Localize("Allows maps to render with more detail")); MainView.HSplitTop(20.0f, &Button, &MainView); if(DoButton_CheckBox(&g_Config.m_GfxHighdpi, Localize("Use high DPI"), g_Config.m_GfxHighdpi, &Button)) @@ -2723,7 +2724,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) { g_Config.m_ClRaceGhost ^= 1; } - GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClRaceGhost, &Button, Localize("When you cross the start line, show a ghost tee replicating the movements of your best time.")); + GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClRaceGhost, &Button, Localize("When you cross the start line, show a ghost tee replicating the movements of your best time")); if(g_Config.m_ClRaceGhost) { @@ -2812,7 +2813,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) { g_Config.m_ClAntiPing ^= 1; } - GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClAntiPing, &Button, Localize("Tries to predict other entities to give a feel of low latency.")); + GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClAntiPing, &Button, Localize("Tries to predict other entities to give a feel of low latency")); if(g_Config.m_ClAntiPing) { diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 0e512d03c..d7b5d5d26 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -394,13 +394,19 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch { if(m_pClient->m_Snap.m_aTeamSize[0] > 8) { - str_format(aBuf, sizeof(aBuf), "%d", DDTeam); + if(DDTeam == TEAM_SUPER) + str_copy(aBuf, Localize("Super"), sizeof(aBuf)); + else + str_format(aBuf, sizeof(aBuf), "%d", DDTeam); TextRender()->SetCursor(&Cursor, x - 10.0f, y + Spacing + FontSize - (FontSize / 1.5f), FontSize / 1.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = NameLength + 3; } else { - str_format(aBuf, sizeof(aBuf), "Team %d", DDTeam); + if(DDTeam == TEAM_SUPER) + str_copy(aBuf, Localize("Super"), sizeof(aBuf)); + else + str_format(aBuf, sizeof(aBuf), Localize("Team %d"), DDTeam); tw = TextRender()->TextWidth(0, FontSize, aBuf, -1, -1.0f); TextRender()->SetCursor(&Cursor, ScoreOffset + w / 2.0f - tw / 2.0f, y + LineHeight, FontSize / 1.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = NameLength + 3; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index a38f3fb9c..5199ccef8 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -2716,6 +2716,10 @@ void CGameClient::LoadGameSkin(const char *pPath, bool AsDir) Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupHealth); Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupArmor); + Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupArmorShotgun); + Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupArmorGrenade); + Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupArmorLaser); + Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupArmorNinja); Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupGrenade); Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupShotgun); Graphics()->UnloadTexture(&m_GameSkin.m_SpritePickupLaser); @@ -2849,6 +2853,10 @@ void CGameClient::LoadGameSkin(const char *pPath, bool AsDir) // pickups m_GameSkin.m_SpritePickupHealth = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_HEALTH]); m_GameSkin.m_SpritePickupArmor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR]); + m_GameSkin.m_SpritePickupArmorShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR_SHOTGUN]); + m_GameSkin.m_SpritePickupArmorGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR_GRENADE]); + m_GameSkin.m_SpritePickupArmorLaser = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR_LASER]); + m_GameSkin.m_SpritePickupArmorNinja = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR_NINJA]); m_GameSkin.m_SpritePickupGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GRENADE]); m_GameSkin.m_SpritePickupShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_SHOTGUN]); m_GameSkin.m_SpritePickupLaser = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_LASER]); diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 4dab565fc..1136a466e 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -592,6 +592,10 @@ public: // pickups IGraphics::CTextureHandle m_SpritePickupHealth; IGraphics::CTextureHandle m_SpritePickupArmor; + IGraphics::CTextureHandle m_SpritePickupArmorShotgun; + IGraphics::CTextureHandle m_SpritePickupArmorGrenade; + IGraphics::CTextureHandle m_SpritePickupArmorLaser; + IGraphics::CTextureHandle m_SpritePickupArmorNinja; IGraphics::CTextureHandle m_SpritePickupGrenade; IGraphics::CTextureHandle m_SpritePickupShotgun; IGraphics::CTextureHandle m_SpritePickupLaser; diff --git a/src/game/client/prediction/entities/pickup.cpp b/src/game/client/prediction/entities/pickup.cpp index 80d76e48f..f01f41729 100644 --- a/src/game/client/prediction/entities/pickup.cpp +++ b/src/game/client/prediction/entities/pickup.cpp @@ -50,6 +50,61 @@ void CPickup::Tick() pChr->SetActiveWeapon(WEAPON_HAMMER); break; + case POWERUP_ARMOR_SHOTGUN: + if(!GameWorld()->m_WorldConfig.m_IsDDRace || !GameWorld()->m_WorldConfig.m_PredictDDRace) + continue; + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_SHOTGUN)) + { + pChr->SetWeaponGot(WEAPON_SHOTGUN, false); + pChr->SetWeaponAmmo(WEAPON_SHOTGUN, 0); + pChr->SetLastWeapon(WEAPON_GUN); + } + if(pChr->GetActiveWeapon() == WEAPON_SHOTGUN) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + + case POWERUP_ARMOR_GRENADE: + if(!GameWorld()->m_WorldConfig.m_IsDDRace || !GameWorld()->m_WorldConfig.m_PredictDDRace) + continue; + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_GRENADE)) + { + pChr->SetWeaponGot(WEAPON_GRENADE, false); + pChr->SetWeaponAmmo(WEAPON_GRENADE, 0); + pChr->SetLastWeapon(WEAPON_GUN); + } + if(pChr->GetActiveWeapon() == WEAPON_GRENADE) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + + case POWERUP_ARMOR_NINJA: + if(!GameWorld()->m_WorldConfig.m_IsDDRace || !GameWorld()->m_WorldConfig.m_PredictDDRace) + continue; + if(pChr->Team() == TEAM_SUPER) + continue; + pChr->SetNinjaActivationDir(vec2(0, 0)); + pChr->SetNinjaActivationTick(-500); + pChr->SetNinjaCurrentMoveTime(0); + break; + + case POWERUP_ARMOR_LASER: + if(!GameWorld()->m_WorldConfig.m_IsDDRace || !GameWorld()->m_WorldConfig.m_PredictDDRace) + continue; + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_LASER)) + { + pChr->SetWeaponGot(WEAPON_LASER, false); + pChr->SetWeaponAmmo(WEAPON_LASER, 0); + pChr->SetLastWeapon(WEAPON_GUN); + } + if(pChr->GetActiveWeapon() == WEAPON_LASER) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + case POWERUP_WEAPON: if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || pChr->GetWeaponAmmo(m_Subtype) != -1)) pChr->GiveWeapon(m_Subtype); diff --git a/src/game/client/render.cpp b/src/game/client/render.cpp index b6ccbc89e..42be7aa25 100644 --- a/src/game/client/render.cpp +++ b/src/game/client/render.cpp @@ -129,28 +129,28 @@ void CRenderTools::DrawSprite(float x, float y, float ScaledWidth, float ScaledH Graphics()->QuadsDraw(&QuadItem, 1); } -void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size) +int CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size) { IGraphics::CQuadItem QuadItem(x, y, Size, Size); - Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); + return Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); } -void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size) +int CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size) { IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size)); - Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); + return Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); } -void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height) +int CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height) { IGraphics::CQuadItem QuadItem(-(Width) / 2.f, -(Height) / 2.f, (Width), (Height)); - Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); + return Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); } -void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height) +int CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height) { IGraphics::CQuadItem QuadItem(X, Y, Width, Height); - Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); + return Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); } void CRenderTools::DrawRoundRectExt(float x, float y, float w, float h, float r, int Corners) diff --git a/src/game/client/render.h b/src/game/client/render.h index e482b40ab..b77fa22ea 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -82,10 +82,10 @@ public: void DrawSprite(float x, float y, float size); void DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight); - void QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size); - void QuadContainerAddSprite(int QuadContainerIndex, float size); - void QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height); - void QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height); + int QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size); + int QuadContainerAddSprite(int QuadContainerIndex, float size); + int QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height); + int QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height); // rects void DrawRoundRect(float x, float y, float w, float h, float r); diff --git a/src/game/editor/explanations.cpp b/src/game/editor/explanations.cpp index d5aed39d7..cd5f6e6d8 100644 --- a/src/game/editor/explanations.cpp +++ b/src/game/editor/explanations.cpp @@ -402,6 +402,22 @@ const char *CEditor::Explain(int ExplanationID, int Tile, int Layer) //TODO: Add if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) return "BULLET: Bounces off the walls without explosion. Touching the bullet works like FREEZE tile (freezes for 3 seconds by default)."; break; + case ENTITY_OFFSET + ENTITY_ARMOR_SHOTGUN: + if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) + return "SHOTGUN SHIELD: Takes shotgun away."; + break; + case ENTITY_OFFSET + ENTITY_ARMOR_GRENADE: + if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) + return "GRENADE SHIELD: Takes grenade away."; + break; + case ENTITY_OFFSET + ENTITY_ARMOR_NINJA: + if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) + return "NINJA SHIELD: Takes ninja away."; + break; + case ENTITY_OFFSET + ENTITY_ARMOR_LASER: + if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) + return "LASER SHIELD: Takes laser away."; + break; case ENTITY_OFFSET + ENTITY_DRAGGER_WEAK: if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH) return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can't reach tees through walls and LASER BLOCKER. Weak."; diff --git a/src/game/mapitems.cpp b/src/game/mapitems.cpp index 0943d76c4..d683cd7cf 100644 --- a/src/game/mapitems.cpp +++ b/src/game/mapitems.cpp @@ -91,7 +91,7 @@ bool IsValidEntity(int Index) Index -= ENTITY_OFFSET; return ( (Index >= ENTITY_SPAWN && Index <= ENTITY_LASER_O_FAST) || - (Index >= ENTITY_PLASMAE && Index <= ENTITY_CRAZY_SHOTGUN) || + (Index >= ENTITY_PLASMAE && Index <= ENTITY_ARMOR_LASER) || (Index >= ENTITY_DRAGGER_WEAK && Index <= ENTITY_DRAGGER_STRONG_NW) || Index == ENTITY_DOOR); } diff --git a/src/game/mapitems.h b/src/game/mapitems.h index df0a3681b..06c2cbf0d 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -80,6 +80,11 @@ enum //DDRace - Shotgun ENTITY_CRAZY_SHOTGUN_EX, ENTITY_CRAZY_SHOTGUN, + //DDNet - Removing specific weapon + ENTITY_ARMOR_SHOTGUN, + ENTITY_ARMOR_GRENADE, + ENTITY_ARMOR_NINJA, + ENTITY_ARMOR_LASER, //DDRace - Draggers ENTITY_DRAGGER_WEAK = 42, ENTITY_DRAGGER_NORMAL, diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp index d1760cde8..a2a0d168b 100644 --- a/src/game/server/entities/pickup.cpp +++ b/src/game/server/entities/pickup.cpp @@ -95,6 +95,56 @@ void CPickup::Tick() pChr->SetActiveWeapon(WEAPON_HAMMER); break; + case POWERUP_ARMOR_SHOTGUN: + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_SHOTGUN)) + { + pChr->SetWeaponGot(WEAPON_SHOTGUN, false); + pChr->SetWeaponAmmo(WEAPON_SHOTGUN, 0); + pChr->SetLastWeapon(WEAPON_GUN); + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR, pChr->TeamMask()); + } + if(pChr->GetActiveWeapon() == WEAPON_SHOTGUN) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + + case POWERUP_ARMOR_GRENADE: + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_GRENADE)) + { + pChr->SetWeaponGot(WEAPON_GRENADE, false); + pChr->SetWeaponAmmo(WEAPON_GRENADE, 0); + pChr->SetLastWeapon(WEAPON_GUN); + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR, pChr->TeamMask()); + } + if(pChr->GetActiveWeapon() == WEAPON_GRENADE) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + + case POWERUP_ARMOR_NINJA: + if(pChr->Team() == TEAM_SUPER) + continue; + pChr->SetNinjaActivationDir(vec2(0, 0)); + pChr->SetNinjaActivationTick(-500); + pChr->SetNinjaCurrentMoveTime(0); + break; + + case POWERUP_ARMOR_LASER: + if(pChr->Team() == TEAM_SUPER) + continue; + if(pChr->GetWeaponGot(WEAPON_LASER)) + { + pChr->SetWeaponGot(WEAPON_LASER, false); + pChr->SetWeaponAmmo(WEAPON_LASER, 0); + pChr->SetLastWeapon(WEAPON_GUN); + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR, pChr->TeamMask()); + } + if(pChr->GetActiveWeapon() == WEAPON_LASER) + pChr->SetActiveWeapon(WEAPON_HAMMER); + break; + case POWERUP_WEAPON: if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || pChr->GetWeaponAmmo(m_Subtype) != -1)) diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 86568a174..086f2e6ee 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -278,6 +278,14 @@ bool IGameController::OnEntity(int Index, vec2 Pos, int Layer, int Flags, int Nu if(Index == ENTITY_ARMOR_1) Type = POWERUP_ARMOR; + else if(Index == ENTITY_ARMOR_SHOTGUN) + Type = POWERUP_ARMOR_SHOTGUN; + else if(Index == ENTITY_ARMOR_GRENADE) + Type = POWERUP_ARMOR_GRENADE; + else if(Index == ENTITY_ARMOR_NINJA) + Type = POWERUP_ARMOR_NINJA; + else if(Index == ENTITY_ARMOR_LASER) + Type = POWERUP_ARMOR_LASER; else if(Index == ENTITY_HEALTH_1) Type = POWERUP_HEALTH; else if(Index == ENTITY_WEAPON_SHOTGUN)