mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
Merge #5639
5639: Add different laser colors for different types r=def- a=VoxelDoesCode Since we're doing a push to assist newer players, I think it would be a good idea to differentiate the different types of lasers, so that non-moving laser entities aren't confused with doors (I'm aware the blinking is a sign, but it's very subtle). This also includes a new color for Shotgun's laser, which would be a nice touch for both customization and clarity. ![image](https://user-images.githubusercontent.com/95713843/179640279-06bb52a0-9070-48ca-b39f-013034f9c16e.png) ![image](https://user-images.githubusercontent.com/95713843/179640326-bcfad3a9-6209-4514-8850-98c5146e28b8.png) If this were to be implemented though, it would require a server update, because the server actually needs to send the DDNetLaser to clients with a high enough client version (It's set to 17000 currently). As of right now it's a solid concept. Huge thanks to Fokkonaut for finalizing this concept! ## Checklist - [x] Tested the change ingame - [x] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [x] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: heinrich5991 <heinrich5991@gmail.com> Co-authored-by: VoxelDoesCode <bluheadcat@gmail.com> Co-authored-by: fokkonaut <35420825+fokkonaut@users.noreply.github.com>
This commit is contained in:
commit
ed2b0f40b9
|
@ -2073,6 +2073,8 @@ if(CLIENT)
|
||||||
components/voting.h
|
components/voting.h
|
||||||
gameclient.cpp
|
gameclient.cpp
|
||||||
gameclient.h
|
gameclient.h
|
||||||
|
laser_data.cpp
|
||||||
|
laser_data.h
|
||||||
lineinput.cpp
|
lineinput.cpp
|
||||||
lineinput.h
|
lineinput.h
|
||||||
prediction/entities/character.cpp
|
prediction/entities/character.cpp
|
||||||
|
|
|
@ -34,6 +34,8 @@ ProjectileFlags = [f"CLIENTID_BIT{i}" for i in range(8)] + [
|
||||||
"EXPLOSIVE", "FREEZE",
|
"EXPLOSIVE", "FREEZE",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
LaserTypes = ["RIFLE", "SHOTGUN", "DOOR", "FREEZE"]
|
||||||
|
|
||||||
Emoticons = ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT", "MUSIC", "SORRY", "GHOST", "SUSHI", "SPLATTEE", "DEVILTEE", "ZOMG", "ZZZ", "WTF", "EYES", "QUESTION"]
|
Emoticons = ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT", "MUSIC", "SORRY", "GHOST", "SUSHI", "SPLATTEE", "DEVILTEE", "ZOMG", "ZZZ", "WTF", "EYES", "QUESTION"]
|
||||||
|
|
||||||
Powerups = ["HEALTH", "ARMOR", "WEAPON", "NINJA", "ARMOR_SHOTGUN", "ARMOR_GRENADE", "ARMOR_NINJA", "ARMOR_LASER"]
|
Powerups = ["HEALTH", "ARMOR", "WEAPON", "NINJA", "ARMOR_SHOTGUN", "ARMOR_GRENADE", "ARMOR_NINJA", "ARMOR_LASER"]
|
||||||
|
@ -78,6 +80,7 @@ Enums = [
|
||||||
Enum("EMOTICON", Emoticons),
|
Enum("EMOTICON", Emoticons),
|
||||||
Enum("AUTHED", Authed),
|
Enum("AUTHED", Authed),
|
||||||
Enum("ENTITYCLASS", EntityClasses),
|
Enum("ENTITYCLASS", EntityClasses),
|
||||||
|
Enum("LASERTYPE", LaserTypes),
|
||||||
]
|
]
|
||||||
|
|
||||||
Flags = [
|
Flags = [
|
||||||
|
@ -273,6 +276,16 @@ Objects = [
|
||||||
NetTick("m_StartTick"),
|
NetTick("m_StartTick"),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
NetObjectEx("DDNetLaser", "laser@netobj.ddnet.tw", [
|
||||||
|
NetIntAny("m_ToX"),
|
||||||
|
NetIntAny("m_ToY"),
|
||||||
|
NetIntAny("m_FromX"),
|
||||||
|
NetIntAny("m_FromY"),
|
||||||
|
NetTick("m_StartTick"),
|
||||||
|
NetIntRange("m_Owner", 0, 'MAX_CLIENTS-1'),
|
||||||
|
NetIntAny("m_Type"),
|
||||||
|
]),
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
|
||||||
NetEvent("Common", [
|
NetEvent("Common", [
|
||||||
|
|
|
@ -296,8 +296,14 @@ MACRO_CONFIG_COL(ClMessageClientColor, cl_message_client_color, 9633471, CFGFLAG
|
||||||
MACRO_CONFIG_COL(ClMessageHighlightColor, cl_message_highlight_color, 65471, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Highlighted message color")
|
MACRO_CONFIG_COL(ClMessageHighlightColor, cl_message_highlight_color, 65471, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Highlighted message color")
|
||||||
MACRO_CONFIG_COL(ClMessageTeamColor, cl_message_team_color, 5636050, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Team message color")
|
MACRO_CONFIG_COL(ClMessageTeamColor, cl_message_team_color, 5636050, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Team message color")
|
||||||
MACRO_CONFIG_COL(ClMessageColor, cl_message_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Message color")
|
MACRO_CONFIG_COL(ClMessageColor, cl_message_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Message color")
|
||||||
MACRO_CONFIG_COL(ClLaserInnerColor, cl_laser_inner_color, 11206591, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser inner color")
|
MACRO_CONFIG_COL(ClLaserRifleInnerColor, cl_laser_rifle_inner_color, 11206591, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser inner color for Rifle")
|
||||||
MACRO_CONFIG_COL(ClLaserOutlineColor, cl_laser_outline_color, 11176233, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser outline color")
|
MACRO_CONFIG_COL(ClLaserRifleOutlineColor, cl_laser_rifle_outline_color, 11176233, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser outline color for Rifle")
|
||||||
|
MACRO_CONFIG_COL(ClLaserShotgunInnerColor, cl_laser_sg_inner_color, 1900385, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser inner color for Shotgun")
|
||||||
|
MACRO_CONFIG_COL(ClLaserShotgunOutlineColor, cl_laser_sg_outline_color, 1866773, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser outline color for Shotgun")
|
||||||
|
MACRO_CONFIG_COL(ClLaserDoorInnerColor, cl_laser_door_inner_color, 7701379, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser inner color for doors")
|
||||||
|
MACRO_CONFIG_COL(ClLaserDoorOutlineColor, cl_laser_door_outline_color, 7667473, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser outline color for doors")
|
||||||
|
MACRO_CONFIG_COL(ClLaserFreezeInnerColor, cl_laser_freeze_inner_color, 15958915, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser inner color for freezes")
|
||||||
|
MACRO_CONFIG_COL(ClLaserFreezeOutlineColor, cl_laser_freeze_outline_color, 15972381, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Laser outline color for freezes")
|
||||||
MACRO_CONFIG_COL(ClKillMessageNormalColor, cl_kill_message_normal_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLALPHA, "Kill message normal color")
|
MACRO_CONFIG_COL(ClKillMessageNormalColor, cl_kill_message_normal_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLALPHA, "Kill message normal color")
|
||||||
MACRO_CONFIG_COL(ClKillMessageHighlightColor, cl_kill_message_highlight_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLALPHA, "Kill message highlight color")
|
MACRO_CONFIG_COL(ClKillMessageHighlightColor, cl_kill_message_highlight_color, 255, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLALPHA, "Kill message highlight color")
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@ enum
|
||||||
VERSION_DDNET_INDEPENDENT_SPECTATORS_TEAM = 16000,
|
VERSION_DDNET_INDEPENDENT_SPECTATORS_TEAM = 16000,
|
||||||
VERSION_DDNET_WEAPON_SHIELDS = 16010,
|
VERSION_DDNET_WEAPON_SHIELDS = 16010,
|
||||||
VERSION_DDNET_NEW_HUD = 16020,
|
VERSION_DDNET_NEW_HUD = 16020,
|
||||||
|
VERSION_DDNET_MULTI_LASER = 16040,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
|
|
||||||
#include <game/client/gameclient.h>
|
#include <game/client/gameclient.h>
|
||||||
|
#include <game/client/laser_data.h>
|
||||||
#include <game/client/projectile_data.h>
|
#include <game/client/projectile_data.h>
|
||||||
#include <game/client/render.h>
|
#include <game/client/render.h>
|
||||||
|
|
||||||
|
@ -237,18 +238,52 @@ void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent,
|
||||||
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y - Size * 0.75f);
|
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y - Size * 0.75f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
|
void CItems::RenderLaser(const CLaserData *pCurrent, bool IsPredicted)
|
||||||
{
|
{
|
||||||
|
int Type = clamp(pCurrent->m_Type, -1, NUM_LASERTYPES - 1);
|
||||||
|
|
||||||
ColorRGBA RGB;
|
ColorRGBA RGB;
|
||||||
vec2 Pos = vec2(pCurrent->m_X, pCurrent->m_Y);
|
vec2 Pos = pCurrent->m_To;
|
||||||
vec2 From = vec2(pCurrent->m_FromX, pCurrent->m_FromY);
|
vec2 From = pCurrent->m_From;
|
||||||
float Len = distance(Pos, From);
|
float Len = distance(Pos, From);
|
||||||
RGB = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClLaserOutlineColor));
|
|
||||||
|
int ColorIn, ColorOut;
|
||||||
|
switch(Type)
|
||||||
|
{
|
||||||
|
case LASERTYPE_RIFLE:
|
||||||
|
ColorOut = g_Config.m_ClLaserRifleOutlineColor;
|
||||||
|
ColorIn = g_Config.m_ClLaserRifleInnerColor;
|
||||||
|
break;
|
||||||
|
case LASERTYPE_SHOTGUN:
|
||||||
|
ColorOut = g_Config.m_ClLaserShotgunOutlineColor;
|
||||||
|
ColorIn = g_Config.m_ClLaserShotgunInnerColor;
|
||||||
|
break;
|
||||||
|
case LASERTYPE_DOOR:
|
||||||
|
ColorOut = g_Config.m_ClLaserDoorOutlineColor;
|
||||||
|
ColorIn = g_Config.m_ClLaserDoorInnerColor;
|
||||||
|
break;
|
||||||
|
case LASERTYPE_FREEZE:
|
||||||
|
ColorOut = g_Config.m_ClLaserFreezeOutlineColor;
|
||||||
|
ColorIn = g_Config.m_ClLaserFreezeInnerColor;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ColorOut = g_Config.m_ClLaserRifleOutlineColor;
|
||||||
|
ColorIn = g_Config.m_ClLaserRifleInnerColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
RGB = color_cast<ColorRGBA>(ColorHSLA(ColorOut));
|
||||||
ColorRGBA OuterColor(RGB.r, RGB.g, RGB.b, 1.0f);
|
ColorRGBA OuterColor(RGB.r, RGB.g, RGB.b, 1.0f);
|
||||||
RGB = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClLaserInnerColor));
|
RGB = color_cast<ColorRGBA>(ColorHSLA(ColorIn));
|
||||||
ColorRGBA InnerColor(RGB.r, RGB.g, RGB.b, 1.0f);
|
ColorRGBA InnerColor(RGB.r, RGB.g, RGB.b, 1.0f);
|
||||||
|
|
||||||
int TuneZone = GameClient()->m_GameWorld.m_WorldConfig.m_UseTuneZones ? Collision()->IsTune(Collision()->GetMapIndex(From)) : 0;
|
int TuneZone = GameClient()->m_GameWorld.m_WorldConfig.m_UseTuneZones ? Collision()->IsTune(Collision()->GetMapIndex(From)) : 0;
|
||||||
|
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
|
||||||
|
|
||||||
|
float Alpha = 1.f;
|
||||||
|
if(IsOtherTeam)
|
||||||
|
{
|
||||||
|
Alpha = g_Config.m_ClShowOthersAlpha / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
vec2 Dir;
|
vec2 Dir;
|
||||||
if(Len > 0)
|
if(Len > 0)
|
||||||
|
@ -271,7 +306,7 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
|
||||||
Graphics()->QuadsBegin();
|
Graphics()->QuadsBegin();
|
||||||
|
|
||||||
// do outline
|
// do outline
|
||||||
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
|
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, Alpha);
|
||||||
Out = vec2(Dir.y, -Dir.x) * (7.0f * Ia);
|
Out = vec2(Dir.y, -Dir.x) * (7.0f * Ia);
|
||||||
|
|
||||||
IGraphics::CFreeformItem Freeform(
|
IGraphics::CFreeformItem Freeform(
|
||||||
|
@ -283,7 +318,7 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
|
||||||
|
|
||||||
// do inner
|
// do inner
|
||||||
Out = vec2(Dir.y, -Dir.x) * (5.0f * Ia);
|
Out = vec2(Dir.y, -Dir.x) * (5.0f * Ia);
|
||||||
Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f); // center
|
Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, Alpha); // center
|
||||||
|
|
||||||
Freeform = IGraphics::CFreeformItem(
|
Freeform = IGraphics::CFreeformItem(
|
||||||
From.x - Out.x, From.y - Out.y,
|
From.x - Out.x, From.y - Out.y,
|
||||||
|
@ -300,9 +335,9 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
|
||||||
int CurParticle = (Client()->GameTick(g_Config.m_ClDummy) % 3);
|
int CurParticle = (Client()->GameTick(g_Config.m_ClDummy) % 3);
|
||||||
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_aSpriteParticleSplat[CurParticle]);
|
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_aSpriteParticleSplat[CurParticle]);
|
||||||
Graphics()->QuadsSetRotation(Client()->GameTick(g_Config.m_ClDummy));
|
Graphics()->QuadsSetRotation(Client()->GameTick(g_Config.m_ClDummy));
|
||||||
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
|
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, Alpha);
|
||||||
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, m_aParticleSplatOffset[CurParticle], Pos.x, Pos.y);
|
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, m_aParticleSplatOffset[CurParticle], Pos.x, Pos.y);
|
||||||
Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f);
|
Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, Alpha);
|
||||||
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, m_aParticleSplatOffset[CurParticle], Pos.x, Pos.y, 20.f / 24.f, 20.f / 24.f);
|
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, m_aParticleSplatOffset[CurParticle], Pos.x, Pos.y, 20.f / 24.f, 20.f / 24.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,8 +376,7 @@ void CItems::OnRender()
|
||||||
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
|
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
|
||||||
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
||||||
continue;
|
continue;
|
||||||
CNetObj_Laser Data;
|
CLaserData Data = pLaser->GetData();
|
||||||
pLaser->FillInfo(&Data);
|
|
||||||
RenderLaser(&Data, true);
|
RenderLaser(&Data, true);
|
||||||
}
|
}
|
||||||
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
||||||
|
@ -419,7 +453,7 @@ void CItems::OnRender()
|
||||||
if(pPrev)
|
if(pPrev)
|
||||||
RenderPickup((const CNetObj_Pickup *)pPrev, (const CNetObj_Pickup *)pData);
|
RenderPickup((const CNetObj_Pickup *)pPrev, (const CNetObj_Pickup *)pData);
|
||||||
}
|
}
|
||||||
else if(Item.m_Type == NETOBJTYPE_LASER)
|
else if(Item.m_Type == NETOBJTYPE_LASER || Item.m_Type == NETOBJTYPE_DDNETLASER)
|
||||||
{
|
{
|
||||||
if(UsePredicted)
|
if(UsePredicted)
|
||||||
{
|
{
|
||||||
|
@ -427,7 +461,16 @@ void CItems::OnRender()
|
||||||
if(pLaser && pLaser->GetOwner() >= 0 && GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
if(pLaser && pLaser->GetOwner() >= 0 && GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CNetObj_Laser Laser = *((const CNetObj_Laser *)pData);
|
|
||||||
|
CLaserData Data;
|
||||||
|
if(Item.m_Type == NETOBJTYPE_LASER)
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfo((const CNetObj_Laser *)pData, &GameClient()->m_GameWorld);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfoDDNet((const CNetObj_DDNetLaser *)pData, &GameClient()->m_GameWorld);
|
||||||
|
}
|
||||||
|
|
||||||
if(pEntEx)
|
if(pEntEx)
|
||||||
{
|
{
|
||||||
|
@ -435,31 +478,35 @@ void CItems::OnRender()
|
||||||
{
|
{
|
||||||
if(Inactive && BlinkingLight)
|
if(Inactive && BlinkingLight)
|
||||||
continue;
|
continue;
|
||||||
Laser.m_StartTick = DraggerStartTick;
|
Data.m_StartTick = DraggerStartTick;
|
||||||
|
Data.m_Type = LASERTYPE_FREEZE;
|
||||||
}
|
}
|
||||||
if(pEntEx->m_EntityClass >= ENTITYCLASS_GUN_NORMAL && pEntEx->m_EntityClass <= ENTITYCLASS_GUN_UNFREEZE)
|
if(pEntEx->m_EntityClass >= ENTITYCLASS_GUN_NORMAL && pEntEx->m_EntityClass <= ENTITYCLASS_GUN_UNFREEZE)
|
||||||
{
|
{
|
||||||
if(Inactive && BlinkingGun)
|
if(Inactive && BlinkingGun)
|
||||||
continue;
|
continue;
|
||||||
Laser.m_StartTick = GunStartTick;
|
Data.m_StartTick = GunStartTick;
|
||||||
|
Data.m_Type = pEntEx->m_EntityClass == ENTITYCLASS_GUN_FREEZE ? LASERTYPE_FREEZE : LASERTYPE_DOOR;
|
||||||
}
|
}
|
||||||
if(pEntEx->m_EntityClass >= ENTITYCLASS_DRAGGER_WEAK && pEntEx->m_EntityClass <= ENTITYCLASS_DRAGGER_STRONG)
|
if(pEntEx->m_EntityClass >= ENTITYCLASS_DRAGGER_WEAK && pEntEx->m_EntityClass <= ENTITYCLASS_DRAGGER_STRONG)
|
||||||
{
|
{
|
||||||
if(Inactive && BlinkingDragger)
|
if(Inactive && BlinkingDragger)
|
||||||
continue;
|
continue;
|
||||||
Laser.m_StartTick = DraggerStartTick;
|
Data.m_StartTick = DraggerStartTick;
|
||||||
|
Data.m_Type = LASERTYPE_DOOR;
|
||||||
}
|
}
|
||||||
if(pEntEx->m_EntityClass == ENTITYCLASS_DOOR)
|
if(pEntEx->m_EntityClass == ENTITYCLASS_DOOR)
|
||||||
{
|
{
|
||||||
if(Inactive || IsSuper)
|
if(Inactive || IsSuper)
|
||||||
{
|
{
|
||||||
Laser.m_FromX = Laser.m_X;
|
Data.m_From.x = Data.m_To.x;
|
||||||
Laser.m_FromY = Laser.m_Y;
|
Data.m_From.y = Data.m_To.y;
|
||||||
}
|
}
|
||||||
Laser.m_StartTick = Client()->GameTick(g_Config.m_ClDummy);
|
Data.m_StartTick = Client()->GameTick(g_Config.m_ClDummy);
|
||||||
|
Data.m_Type = LASERTYPE_DOOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RenderLaser(&Laser);
|
RenderLaser(&Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
#include <game/generated/protocol.h>
|
#include <game/generated/protocol.h>
|
||||||
|
|
||||||
class CProjectileData;
|
class CProjectileData;
|
||||||
|
class CLaserData;
|
||||||
|
|
||||||
class CItems : public CComponent
|
class CItems : public CComponent
|
||||||
{
|
{
|
||||||
void RenderProjectile(const CProjectileData *pCurrent, int ItemID);
|
void RenderProjectile(const CProjectileData *pCurrent, int ItemID);
|
||||||
void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent, bool IsPredicted = false);
|
void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent, bool IsPredicted = false);
|
||||||
void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent, const CNetObj_GameData *pPrevGameData, const CNetObj_GameData *pCurGameData);
|
void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent, const CNetObj_GameData *pPrevGameData, const CNetObj_GameData *pCurGameData);
|
||||||
void RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted = false);
|
void RenderLaser(const CLaserData *pCurrent, bool IsPredicted = false);
|
||||||
|
|
||||||
int m_ItemsQuadContainerIndex;
|
int m_ItemsQuadContainerIndex;
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ int CMenus::DoButton_CheckBox_Common(const void *pID, const char *pText, const c
|
||||||
return UI()->DoButtonLogic(pID, 0, pRect);
|
return UI()->DoButtonLogic(pID, 0, pRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMenus::DoLaserPreview(const CUIRect *pRect, const ColorHSLA LaserOutlineColor, const ColorHSLA LaserInnerColor)
|
void CMenus::DoLaserPreview(const CUIRect *pRect, const ColorHSLA LaserOutlineColor, const ColorHSLA LaserInnerColor, const int LaserType)
|
||||||
{
|
{
|
||||||
ColorRGBA LaserRGB;
|
ColorRGBA LaserRGB;
|
||||||
CUIRect Section = *pRect;
|
CUIRect Section = *pRect;
|
||||||
|
@ -356,12 +356,34 @@ void CMenus::DoLaserPreview(const CUIRect *pRect, const ColorHSLA LaserOutlineCo
|
||||||
Graphics()->QuadsDraw(&QuadItem, 1);
|
Graphics()->QuadsDraw(&QuadItem, 1);
|
||||||
Graphics()->QuadsEnd();
|
Graphics()->QuadsEnd();
|
||||||
|
|
||||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponLaser);
|
switch(LaserType)
|
||||||
Graphics()->QuadsBegin();
|
{
|
||||||
RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY);
|
case LASERTYPE_RIFLE:
|
||||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponLaser);
|
||||||
RenderTools()->DrawSprite(Section.x + 30.0f, Section.y + Section.h / 2.0f, 60.0f);
|
RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY);
|
||||||
Graphics()->QuadsEnd();
|
Graphics()->QuadsBegin();
|
||||||
|
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||||
|
RenderTools()->DrawSprite(Section.x + 30.0f, Section.y + Section.h / 2.0f, 60.0f);
|
||||||
|
Graphics()->QuadsEnd();
|
||||||
|
break;
|
||||||
|
case LASERTYPE_SHOTGUN:
|
||||||
|
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponShotgun);
|
||||||
|
RenderTools()->SelectSprite(SPRITE_WEAPON_SHOTGUN_BODY);
|
||||||
|
Graphics()->QuadsBegin();
|
||||||
|
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||||
|
RenderTools()->DrawSprite(Section.x + 30.0f, Section.y + Section.h / 2.0f, 60.0f);
|
||||||
|
Graphics()->QuadsEnd();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Graphics()->QuadsBegin();
|
||||||
|
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
|
||||||
|
QuadItem = IGraphics::CQuadItem(From.x, From.y, 24, 24);
|
||||||
|
Graphics()->QuadsDraw(&QuadItem, 1);
|
||||||
|
Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f);
|
||||||
|
QuadItem = IGraphics::CQuadItem(From.x, From.y, 20, 20);
|
||||||
|
Graphics()->QuadsDraw(&QuadItem, 1);
|
||||||
|
Graphics()->QuadsEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float LineSize, const float WantedPickerPosition, const float LabelSize, const float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, const ColorRGBA DefaultColor, bool CheckBoxSpacing, bool UseCheckBox, int *pCheckBoxValue)
|
ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float LineSize, const float WantedPickerPosition, const float LabelSize, const float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, const ColorRGBA DefaultColor, bool CheckBoxSpacing, bool UseCheckBox, int *pCheckBoxValue)
|
||||||
|
|
|
@ -87,8 +87,9 @@ class CMenus : public CComponent
|
||||||
int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
||||||
int DoButton_CheckBoxAutoVMarginAndSet(const void *pID, const char *pText, int *pValue, CUIRect *pRect, float VMargin);
|
int DoButton_CheckBoxAutoVMarginAndSet(const void *pID, const char *pText, int *pValue, CUIRect *pRect, float VMargin);
|
||||||
int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
||||||
|
|
||||||
ColorHSLA DoLine_ColorPicker(CButtonContainer *pResetID, float LineSize, float WantedPickerPosition, float LabelSize, float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, ColorRGBA DefaultColor, bool CheckBoxSpacing = true, bool UseCheckBox = false, int *pCheckBoxValue = nullptr);
|
ColorHSLA DoLine_ColorPicker(CButtonContainer *pResetID, float LineSize, float WantedPickerPosition, float LabelSize, float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, ColorRGBA DefaultColor, bool CheckBoxSpacing = true, bool UseCheckBox = false, int *pCheckBoxValue = nullptr);
|
||||||
void DoLaserPreview(const CUIRect *pRect, ColorHSLA OutlineColor, ColorHSLA InnerColor);
|
void DoLaserPreview(const CUIRect *pRect, ColorHSLA OutlineColor, ColorHSLA InnerColor, const int LaserType);
|
||||||
int DoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, bool UseScroll, int Current, int Min, int Max, int Step, float Scale, bool IsHex, float Round, ColorRGBA *pColor);
|
int DoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, bool UseScroll, int Current, int Min, int Max, int Step, float Scale, bool IsHex, float Round, ColorRGBA *pColor);
|
||||||
int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
||||||
|
|
||||||
|
|
|
@ -2966,18 +2966,34 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView)
|
||||||
{
|
{
|
||||||
MainView.VSplitMid(&LeftView, &RightView);
|
MainView.VSplitMid(&LeftView, &RightView);
|
||||||
|
|
||||||
// ***** Laser ***** //
|
// ***** Weapons ***** //
|
||||||
LeftView.HSplitTop(HeadlineAndVMargin, &Label, &LeftView);
|
LeftView.HSplitTop(HeadlineAndVMargin, &Label, &LeftView);
|
||||||
UI()->DoLabel(&Label, Localize("Laser"), HeadlineFontSize, TEXTALIGN_LEFT);
|
UI()->DoLabel(&Label, Localize("Weapons"), HeadlineFontSize, TEXTALIGN_LEFT);
|
||||||
|
|
||||||
// General laser settings
|
// General weapon laser settings
|
||||||
LeftView.HSplitTop(SectionTotalMargin + 2 * ColorPickerLineSize, &Section, &LeftView);
|
LeftView.HSplitTop(SectionTotalMargin + 4 * ColorPickerLineSize, &Section, &LeftView);
|
||||||
Section.Margin(SectionMargin, &Section);
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
|
||||||
static CButtonContainer s_LaserOutResetID, s_LaserInResetID;
|
static CButtonContainer s_LaserRifleOutResetID, s_LaserRifleInResetID, s_LaserShotgunOutResetID, s_LaserShotgunInResetID;
|
||||||
|
|
||||||
ColorHSLA LaserOutlineColor = DoLine_ColorPicker(&s_LaserOutResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Laser Outline Color"), &g_Config.m_ClLaserOutlineColor, ColorRGBA(0.074402f, 0.074402f, 0.247166f, 1.0f), false);
|
ColorHSLA LaserRifleOutlineColor = DoLine_ColorPicker(&s_LaserRifleOutResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Rifle Laser Outline Color"), &g_Config.m_ClLaserRifleOutlineColor, ColorRGBA(0.074402f, 0.074402f, 0.247166f, 1.0f), false);
|
||||||
ColorHSLA LaserInnerColor = DoLine_ColorPicker(&s_LaserInResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Laser Inner Color"), &g_Config.m_ClLaserInnerColor, ColorRGBA(0.498039f, 0.498039f, 1.0f, 1.0f), false);
|
ColorHSLA LaserRifleInnerColor = DoLine_ColorPicker(&s_LaserRifleInResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Rifle Laser Inner Color"), &g_Config.m_ClLaserRifleInnerColor, ColorRGBA(0.498039f, 0.498039f, 1.0f, 1.0f), false);
|
||||||
|
ColorHSLA LaserShotgunOutlineColor = DoLine_ColorPicker(&s_LaserShotgunOutResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Shotgun Laser Outline Color"), &g_Config.m_ClLaserShotgunOutlineColor, ColorRGBA(0.125490f, 0.098039f, 0.043137f, 1.0f), false);
|
||||||
|
ColorHSLA LaserShotgunInnerColor = DoLine_ColorPicker(&s_LaserShotgunInResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Shotgun Laser Inner Color"), &g_Config.m_ClLaserShotgunInnerColor, ColorRGBA(0.764705f, 0.505882f, 0.0f, 1.0f), false);
|
||||||
|
// ***** Entities ***** //
|
||||||
|
LeftView.HSplitTop(HeadlineAndVMargin, &Label, &LeftView);
|
||||||
|
UI()->DoLabel(&Label, Localize("Entities"), HeadlineFontSize, TEXTALIGN_LEFT);
|
||||||
|
|
||||||
|
// General entity laser settings
|
||||||
|
LeftView.HSplitTop(SectionTotalMargin + 4 * ColorPickerLineSize, &Section, &LeftView);
|
||||||
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
|
||||||
|
static CButtonContainer s_LaserDoorOutResetID, s_LaserDoorInResetID, s_LaserFreezeOutResetID, s_LaserFreezeInResetID;
|
||||||
|
|
||||||
|
ColorHSLA LaserDoorOutlineColor = DoLine_ColorPicker(&s_LaserDoorOutResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Door Laser Outline Color"), &g_Config.m_ClLaserDoorOutlineColor, ColorRGBA(0.0f, 0.129411f, 0.094117f, 1.0f), false);
|
||||||
|
ColorHSLA LaserDoorInnerColor = DoLine_ColorPicker(&s_LaserDoorInResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Door Laser Inner Color"), &g_Config.m_ClLaserDoorInnerColor, ColorRGBA(0.262745f, 0.760784f, 0.639215f, 1.0f), false);
|
||||||
|
ColorHSLA LaserFreezeOutlineColor = DoLine_ColorPicker(&s_LaserFreezeOutResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Freeze Laser Outline Color"), &g_Config.m_ClLaserFreezeOutlineColor, ColorRGBA(0.192156f, 0.031372f, 0.074509f, 1.0f), false);
|
||||||
|
ColorHSLA LaserFreezeInnerColor = DoLine_ColorPicker(&s_LaserFreezeInResetID, ColorPickerLineSize, LeftViewColorPickerPosition, ColorPickerLabelSize, ColorPickerLineSpacing, &Section, Localize("Freeze Laser Inner Color"), &g_Config.m_ClLaserFreezeInnerColor, ColorRGBA(0.760784f, 0.262745f, 0.403921f, 1.0f), false);
|
||||||
|
|
||||||
// ***** Laser Preview ***** //
|
// ***** Laser Preview ***** //
|
||||||
RightView.HSplitTop(HeadlineAndVMargin, &Label, &RightView);
|
RightView.HSplitTop(HeadlineAndVMargin, &Label, &RightView);
|
||||||
|
@ -2985,8 +3001,19 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView)
|
||||||
|
|
||||||
RightView.HSplitTop(SectionTotalMargin + 50.0f, &Section, &RightView);
|
RightView.HSplitTop(SectionTotalMargin + 50.0f, &Section, &RightView);
|
||||||
Section.Margin(SectionMargin, &Section);
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
DoLaserPreview(&Section, LaserRifleOutlineColor, LaserRifleInnerColor, LASERTYPE_RIFLE);
|
||||||
|
|
||||||
DoLaserPreview(&Section, LaserOutlineColor, LaserInnerColor);
|
RightView.HSplitTop(SectionTotalMargin + 50.0f, &Section, &RightView);
|
||||||
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
DoLaserPreview(&Section, LaserShotgunOutlineColor, LaserShotgunInnerColor, LASERTYPE_SHOTGUN);
|
||||||
|
|
||||||
|
RightView.HSplitTop(SectionTotalMargin + 50.0f, &Section, &RightView);
|
||||||
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
DoLaserPreview(&Section, LaserDoorOutlineColor, LaserDoorInnerColor, LASERTYPE_DOOR);
|
||||||
|
|
||||||
|
RightView.HSplitTop(SectionTotalMargin + 50.0f, &Section, &RightView);
|
||||||
|
Section.Margin(SectionMargin, &Section);
|
||||||
|
DoLaserPreview(&Section, LaserFreezeOutlineColor, LaserFreezeInnerColor, LASERTYPE_DOOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3311,7 +3311,7 @@ void CGameClient::SnapCollectEntities()
|
||||||
const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item);
|
const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item);
|
||||||
if(Item.m_Type == NETOBJTYPE_ENTITYEX)
|
if(Item.m_Type == NETOBJTYPE_ENTITYEX)
|
||||||
vItemEx.push_back({Item, pData, 0});
|
vItemEx.push_back({Item, pData, 0});
|
||||||
else if(Item.m_Type == NETOBJTYPE_PICKUP || Item.m_Type == NETOBJTYPE_LASER || Item.m_Type == NETOBJTYPE_PROJECTILE || Item.m_Type == NETOBJTYPE_DDNETPROJECTILE)
|
else if(Item.m_Type == NETOBJTYPE_PICKUP || Item.m_Type == NETOBJTYPE_LASER || Item.m_Type == NETOBJTYPE_DDNETLASER || Item.m_Type == NETOBJTYPE_PROJECTILE || Item.m_Type == NETOBJTYPE_DDNETPROJECTILE)
|
||||||
vItemData.push_back({Item, pData, 0});
|
vItemData.push_back({Item, pData, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
src/game/client/laser_data.cpp
Normal file
40
src/game/client/laser_data.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||||
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||||
|
|
||||||
|
#include "laser_data.h"
|
||||||
|
|
||||||
|
#include <engine/shared/snapshot.h>
|
||||||
|
#include <game/client/prediction/gameworld.h>
|
||||||
|
#include <game/generated/protocol.h>
|
||||||
|
|
||||||
|
#include <game/collision.h>
|
||||||
|
|
||||||
|
CLaserData ExtractLaserInfo(const CNetObj_Laser *pLaser, CGameWorld *pGameWorld)
|
||||||
|
{
|
||||||
|
CLaserData Result = {vec2(0, 0)};
|
||||||
|
Result.m_From.x = pLaser->m_FromX;
|
||||||
|
Result.m_From.y = pLaser->m_FromY;
|
||||||
|
Result.m_To.x = pLaser->m_X;
|
||||||
|
Result.m_To.y = pLaser->m_Y;
|
||||||
|
Result.m_StartTick = pLaser->m_StartTick;
|
||||||
|
Result.m_ExtraInfo = false;
|
||||||
|
Result.m_Owner = -1;
|
||||||
|
Result.m_Type = -1;
|
||||||
|
Result.m_TuneZone = pGameWorld && pGameWorld->m_WorldConfig.m_UseTuneZones ? pGameWorld->Collision()->IsTune(pGameWorld->Collision()->GetMapIndex(Result.m_From)) : 0;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLaserData ExtractLaserInfoDDNet(const CNetObj_DDNetLaser *pLaser, CGameWorld *pGameWorld)
|
||||||
|
{
|
||||||
|
CLaserData Result = {vec2(0, 0)};
|
||||||
|
Result.m_From.x = pLaser->m_FromX;
|
||||||
|
Result.m_From.y = pLaser->m_FromY;
|
||||||
|
Result.m_To.x = pLaser->m_ToX;
|
||||||
|
Result.m_To.y = pLaser->m_ToY;
|
||||||
|
Result.m_StartTick = pLaser->m_StartTick;
|
||||||
|
Result.m_ExtraInfo = true;
|
||||||
|
Result.m_Owner = pLaser->m_Owner;
|
||||||
|
Result.m_Type = pLaser->m_Type;
|
||||||
|
Result.m_TuneZone = pGameWorld && pGameWorld->m_WorldConfig.m_UseTuneZones ? pGameWorld->Collision()->IsTune(pGameWorld->Collision()->GetMapIndex(Result.m_From)) : 0;
|
||||||
|
return Result;
|
||||||
|
}
|
28
src/game/client/laser_data.h
Normal file
28
src/game/client/laser_data.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||||
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||||
|
#ifndef GAME_CLIENT_LASER_DATA_H
|
||||||
|
#define GAME_CLIENT_LASER_DATA_H
|
||||||
|
|
||||||
|
#include <base/vmath.h>
|
||||||
|
|
||||||
|
struct CNetObj_Laser;
|
||||||
|
struct CNetObj_DDNetLaser;
|
||||||
|
|
||||||
|
class CLaserData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
vec2 m_From;
|
||||||
|
vec2 m_To;
|
||||||
|
int m_StartTick;
|
||||||
|
bool m_ExtraInfo;
|
||||||
|
// The rest is only set if m_ExtraInfo is true.
|
||||||
|
int m_Owner;
|
||||||
|
int m_Type;
|
||||||
|
// TuneZone is introduced locally
|
||||||
|
int m_TuneZone;
|
||||||
|
};
|
||||||
|
|
||||||
|
CLaserData ExtractLaserInfo(const CNetObj_Laser *pLaser, class CGameWorld *pGameWorld);
|
||||||
|
CLaserData ExtractLaserInfoDDNet(const CNetObj_DDNetLaser *pLaser, class CGameWorld *pGameWorld);
|
||||||
|
|
||||||
|
#endif // GAME_CLIENT_LASER_DATA_H
|
|
@ -2,6 +2,7 @@
|
||||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||||
#include "laser.h"
|
#include "laser.h"
|
||||||
#include "character.h"
|
#include "character.h"
|
||||||
|
#include <game/client/laser_data.h>
|
||||||
#include <game/collision.h>
|
#include <game/collision.h>
|
||||||
#include <game/generated/protocol.h>
|
#include <game/generated/protocol.h>
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
|
@ -185,13 +186,11 @@ void CLaser::Tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLaser::CLaser(CGameWorld *pGameWorld, int ID, CNetObj_Laser *pLaser) :
|
CLaser::CLaser(CGameWorld *pGameWorld, int ID, CLaserData *pLaser) :
|
||||||
CEntity(pGameWorld, CGameWorld::ENTTYPE_LASER)
|
CEntity(pGameWorld, CGameWorld::ENTTYPE_LASER)
|
||||||
{
|
{
|
||||||
m_Pos.x = pLaser->m_X;
|
m_Pos = pLaser->m_To;
|
||||||
m_Pos.y = pLaser->m_Y;
|
m_From = pLaser->m_From;
|
||||||
m_From.x = pLaser->m_FromX;
|
|
||||||
m_From.y = pLaser->m_FromY;
|
|
||||||
m_EvalTick = pLaser->m_StartTick;
|
m_EvalTick = pLaser->m_StartTick;
|
||||||
m_TuneZone = GameWorld()->m_WorldConfig.m_UseTuneZones ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0;
|
m_TuneZone = GameWorld()->m_WorldConfig.m_UseTuneZones ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0;
|
||||||
m_Owner = -2;
|
m_Owner = -2;
|
||||||
|
@ -204,7 +203,7 @@ CLaser::CLaser(CGameWorld *pGameWorld, int ID, CNetObj_Laser *pLaser) :
|
||||||
m_Dir = normalize(m_Dir);
|
m_Dir = normalize(m_Dir);
|
||||||
else
|
else
|
||||||
m_Energy = 0;
|
m_Energy = 0;
|
||||||
m_Type = WEAPON_LASER;
|
m_Type = pLaser->m_Type == LASERTYPE_SHOTGUN ? WEAPON_SHOTGUN : WEAPON_LASER;
|
||||||
m_PrevPos = m_From;
|
m_PrevPos = m_From;
|
||||||
m_ID = ID;
|
m_ID = ID;
|
||||||
}
|
}
|
||||||
|
@ -229,3 +228,18 @@ bool CLaser::Match(CLaser *pLaser)
|
||||||
const float DirError = distance(normalize(OtherDiff) * length(ThisDiff), ThisDiff);
|
const float DirError = distance(normalize(OtherDiff) * length(ThisDiff), ThisDiff);
|
||||||
return DirError <= 2.f;
|
return DirError <= 2.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLaserData CLaser::GetData() const
|
||||||
|
{
|
||||||
|
CLaserData Result;
|
||||||
|
Result.m_From.x = m_From.x;
|
||||||
|
Result.m_From.y = m_From.y;
|
||||||
|
Result.m_To.x = m_Pos.x;
|
||||||
|
Result.m_To.y = m_Pos.y;
|
||||||
|
Result.m_StartTick = m_EvalTick;
|
||||||
|
Result.m_ExtraInfo = true;
|
||||||
|
Result.m_Owner = m_Owner;
|
||||||
|
Result.m_Type = m_Type == WEAPON_SHOTGUN ? LASERTYPE_SHOTGUN : LASERTYPE_RIFLE;
|
||||||
|
Result.m_TuneZone = m_TuneZone;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <game/client/prediction/entity.h>
|
#include <game/client/prediction/entity.h>
|
||||||
|
|
||||||
|
class CLaserData;
|
||||||
|
|
||||||
class CLaser : public CEntity
|
class CLaser : public CEntity
|
||||||
{
|
{
|
||||||
friend class CGameWorld;
|
friend class CGameWorld;
|
||||||
|
@ -17,9 +19,10 @@ public:
|
||||||
const vec2 &GetFrom() { return m_From; }
|
const vec2 &GetFrom() { return m_From; }
|
||||||
const int &GetOwner() { return m_Owner; }
|
const int &GetOwner() { return m_Owner; }
|
||||||
const int &GetEvalTick() { return m_EvalTick; }
|
const int &GetEvalTick() { return m_EvalTick; }
|
||||||
CLaser(CGameWorld *pGameWorld, int ID, CNetObj_Laser *pLaser);
|
CLaser(CGameWorld *pGameWorld, int ID, CLaserData *pLaser);
|
||||||
void FillInfo(CNetObj_Laser *pLaser);
|
void FillInfo(CNetObj_Laser *pLaser);
|
||||||
bool Match(CLaser *pLaser);
|
bool Match(CLaser *pLaser);
|
||||||
|
CLaserData GetData() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool HitCharacter(vec2 From, vec2 To);
|
bool HitCharacter(vec2 From, vec2 To);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
|
#include <game/client/laser_data.h>
|
||||||
#include <game/client/projectile_data.h>
|
#include <game/client/projectile_data.h>
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -480,9 +481,18 @@ void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const C
|
||||||
CEntity *pEnt = new CPickup(NetPickup);
|
CEntity *pEnt = new CPickup(NetPickup);
|
||||||
InsertEntity(pEnt, true);
|
InsertEntity(pEnt, true);
|
||||||
}
|
}
|
||||||
else if(ObjType == NETOBJTYPE_LASER && m_WorldConfig.m_PredictWeapons)
|
else if((ObjType == NETOBJTYPE_LASER || ObjType == NETOBJTYPE_DDNETLASER) && m_WorldConfig.m_PredictWeapons)
|
||||||
{
|
{
|
||||||
CLaser NetLaser = CLaser(this, ObjID, (CNetObj_Laser *)pObjData);
|
CLaserData Data;
|
||||||
|
if(ObjType == NETOBJTYPE_PROJECTILE)
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfo((const CNetObj_Laser *)pObjData, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfoDDNet((const CNetObj_DDNetLaser *)pObjData, this);
|
||||||
|
}
|
||||||
|
CLaser NetLaser = CLaser(this, ObjID, &Data);
|
||||||
CLaser *pMatching = 0;
|
CLaser *pMatching = 0;
|
||||||
if(CLaser *pLaser = dynamic_cast<CLaser *>(GetEntity(ObjID, ENTTYPE_LASER)))
|
if(CLaser *pLaser = dynamic_cast<CLaser *>(GetEntity(ObjID, ENTTYPE_LASER)))
|
||||||
if(NetLaser.Match(pLaser))
|
if(NetLaser.Match(pLaser))
|
||||||
|
@ -632,7 +642,25 @@ CEntity *CGameWorld::FindMatch(int ObjID, int ObjType, const void *pObjData)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case NETOBJTYPE_LASER: FindType(ENTTYPE_LASER, CLaser, CNetObj_Laser);
|
case NETOBJTYPE_LASER:
|
||||||
|
case NETOBJTYPE_DDNETLASER:
|
||||||
|
{
|
||||||
|
CLaserData Data;
|
||||||
|
if(ObjType == NETOBJTYPE_LASER)
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfo((const CNetObj_Laser *)pObjData, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Data = ExtractLaserInfoDDNet((const CNetObj_DDNetLaser *)pObjData, this);
|
||||||
|
}
|
||||||
|
CLaser *pEnt = (CLaser *)GetEntity(ObjID, ENTTYPE_LASER);
|
||||||
|
if(pEnt && CLaser(this, ObjID, &Data).Match(pEnt))
|
||||||
|
{
|
||||||
|
return pEnt;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case NETOBJTYPE_PICKUP: FindType(ENTTYPE_PICKUP, CPickup, CNetObj_Pickup);
|
case NETOBJTYPE_PICKUP: FindType(ENTTYPE_PICKUP, CPickup, CNetObj_Pickup);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -313,15 +313,33 @@ void CLaser::Snap(int SnappingClient)
|
||||||
|
|
||||||
if(SnappingClient != SERVER_DEMO_CLIENT && !CmaskIsSet(TeamMask, SnappingClient))
|
if(SnappingClient != SERVER_DEMO_CLIENT && !CmaskIsSet(TeamMask, SnappingClient))
|
||||||
return;
|
return;
|
||||||
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));
|
|
||||||
if(!pObj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pObj->m_X = (int)m_Pos.x;
|
if(GameServer()->GetClientVersion(SnappingClient) >= VERSION_DDNET_MULTI_LASER)
|
||||||
pObj->m_Y = (int)m_Pos.y;
|
{
|
||||||
pObj->m_FromX = (int)m_From.x;
|
CNetObj_DDNetLaser *pObj = static_cast<CNetObj_DDNetLaser *>(Server()->SnapNewItem(NETOBJTYPE_DDNETLASER, GetID(), sizeof(CNetObj_DDNetLaser)));
|
||||||
pObj->m_FromY = (int)m_From.y;
|
if(!pObj)
|
||||||
pObj->m_StartTick = m_EvalTick;
|
return;
|
||||||
|
|
||||||
|
pObj->m_ToX = (int)m_Pos.x;
|
||||||
|
pObj->m_ToY = (int)m_Pos.y;
|
||||||
|
pObj->m_FromX = (int)m_From.x;
|
||||||
|
pObj->m_FromY = (int)m_From.y;
|
||||||
|
pObj->m_StartTick = m_EvalTick;
|
||||||
|
pObj->m_Owner = m_Owner;
|
||||||
|
pObj->m_Type = m_Type == WEAPON_LASER ? LASERTYPE_RIFLE : m_Type == WEAPON_SHOTGUN ? LASERTYPE_SHOTGUN : -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));
|
||||||
|
if(!pObj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pObj->m_X = (int)m_Pos.x;
|
||||||
|
pObj->m_Y = (int)m_Pos.y;
|
||||||
|
pObj->m_FromX = (int)m_From.x;
|
||||||
|
pObj->m_FromY = (int)m_From.y;
|
||||||
|
pObj->m_StartTick = m_EvalTick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLaser::SwapClients(int Client1, int Client2)
|
void CLaser::SwapClients(int Client1, int Client2)
|
||||||
|
|
Loading…
Reference in a new issue