Skip to content

Commit 872e117

Browse files
authored
Merge branch 'ReactiveDrop:reactivedrop_beta' into reactivedrop_beta
2 parents 227248d + a5cfed2 commit 872e117

24 files changed

Lines changed: 170 additions & 31 deletions

contentsrc/mapsrc/rd-bonus11_synrev.vmf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ versioninfo
22
{
33
"editorversion" "400"
44
"editorbuild" "7397"
5-
"mapversion" "3039"
5+
"mapversion" "3040"
66
"formatversion" "100"
77
"prefab" "0"
88
}
@@ -50,7 +50,7 @@ viewsettings
5050
world
5151
{
5252
"id" "394754"
53-
"mapversion" "3039"
53+
"mapversion" "3040"
5454
"classname" "worldspawn"
5555
"detailmaterial" "detail/detailsprites"
5656
"detailvbsp" "detail.vbsp"
@@ -124298,10 +124298,10 @@ entity
124298124298
{
124299124299
"id" "583660"
124300124300
"classname" "asw_objective_escape"
124301-
"objectivedescription1" "Proceed to the Rydberg Reactor"
124301+
"objectivedescription1" "#asw_ob_office_rev1b"
124302124302
"objectiveimage" "obresidentialexit"
124303124303
"objectiveinfoicon1" "OIconPlanet"
124304-
"objectivetitle" "Escape using south door"
124304+
"objectivetitle" "#asw_ob_office_rev1"
124305124305
"targetname" "Objective_Escape"
124306124306
"Visible" "1"
124307124307
"origin" "-160 -3112 161"
@@ -197531,7 +197531,7 @@ hidden
197531197531
editor
197532197532
{
197533197533
"color" "0 180 0"
197534-
"visgroupshown" "0"
197534+
"visgroupshown" "1"
197535197535
"visgroupautoshown" "1"
197536197536
}
197537197537
}

reactivedrop/fgd/swarm.fgd

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,6 +2995,15 @@
29952995
0 : "No"
29962996
1 : "Yes"
29972997
]
2998+
ClassRequirementOverride(choices) : "Class Requirement Override" : -1 : "Change which marine class can pickup this item" =
2999+
[
3000+
-1 : "No Change"
3001+
0 : "Officer"
3002+
1 : "Special Weapons"
3003+
2 : "Medic"
3004+
3 : "Tech"
3005+
999 : "Any"
3006+
]
29983007
]
29993008

30003009
@PointClass base(Targetname, Parentname, Angles) studio("models/items/Ammobag/AmmoBag.mdl") = asw_ammo_drop : "Generic ammo stash"

src/game/client/hud_basechat.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,8 @@ CBaseHudChatInputLine::CBaseHudChatInputLine( CBaseHudChat *parent, char const *
466466
m_pPrompt = new vgui::Label( this, "ChatInputPrompt", L"Enter text:" );
467467
m_pInput = new CBaseHudChatEntry( this, "ChatInput", parent );
468468
m_pInput->SetMaximumCharCount( 127 );
469+
// Send converts text to utf-8
470+
m_pInput->m_iMaxByteCount = 127;
469471
}
470472

471473
void CBaseHudChatInputLine::ApplySchemeSettings(vgui::IScheme *pScheme)
@@ -2519,3 +2521,59 @@ void CBaseHudChat::FireGameEvent( IGameEvent *event )
25192521
ChatPrintf( player->entindex(), CHAT_FILTER_NONE, "(SourceTV) %s", event->GetString( "text" ) );
25202522
}
25212523
}
2524+
2525+
// Prevent player from inserting text over utf-8 byte limit
2526+
void CBaseHudChatEntry::InsertChar(wchar_t ch)
2527+
{
2528+
if ( m_iMaxByteCount == -1 )
2529+
{
2530+
BaseClass::InsertChar(ch);
2531+
return;
2532+
}
2533+
2534+
// single utf-16 char converted to utf-8 is 3 byte long in worst case
2535+
const int iBufLen = BaseClass::GetTextLength() * 3;
2536+
2537+
// Shortcut: fitting max byte count even in worst case
2538+
if ( iBufLen + 4 <= m_iMaxByteCount )
2539+
{
2540+
BaseClass::InsertChar(ch);
2541+
return;
2542+
}
2543+
2544+
// Count bytes of converted utf-8 str
2545+
m_szCharBuf.EnsureCapacity( iBufLen );
2546+
BaseClass::GetText( m_szCharBuf.Base(), m_szCharBuf.Count() );
2547+
const int iCurrentByteLen = Q_strlen( m_szCharBuf.Base() );
2548+
2549+
// Shortcut: average case
2550+
if ( iCurrentByteLen + 4 <= m_iMaxByteCount )
2551+
{
2552+
BaseClass::InsertChar(ch);
2553+
return;
2554+
}
2555+
2556+
// Edge case: check if current wchar_t will cause Send to truncate message
2557+
int iCharByteLen; // utf-8
2558+
if ( ch < 0x80 ) iCharByteLen = 1;
2559+
else if ( ch < 0x800 ) iCharByteLen = 2;
2560+
else if ( ch >= 0xD800 && ch <= 0xDBFF ) iCharByteLen = 4; // high surrogate, assume pair
2561+
else if ( ch >= 0xDC00 && ch <= 0xDFFF ) // low surrogate
2562+
{
2563+
// Check if previous wchar was a high surrogate
2564+
wchar_t wszHigh[2];
2565+
const int iLast = BaseClass::GetTextLength() - 1;
2566+
BaseClass::GetTextRange( wszHigh, iLast, 1 );
2567+
if ( wszHigh[0] >= 0xD800 && wszHigh[0] <= 0xDBFF ) { BaseClass::InsertChar(ch); return; }
2568+
else return; // it was not a hight surrogate, reject
2569+
}
2570+
else iCharByteLen = 3;
2571+
2572+
if ( iCurrentByteLen + iCharByteLen <= m_iMaxByteCount )
2573+
{
2574+
BaseClass::InsertChar(ch);
2575+
return;
2576+
}
2577+
2578+
return; // do not insert anything
2579+
}

src/game/client/hud_basechat.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ class CBaseHudChatEntry : public vgui::TextEntry
324324
{
325325
typedef vgui::TextEntry BaseClass;
326326
public:
327+
int m_iMaxByteCount = -1; // utf-8 string length
328+
327329
CBaseHudChatEntry( vgui::Panel *parent, char const *panelName, CBaseHudChat *pChat )
328330
: BaseClass( parent, panelName )
329331
{
@@ -340,6 +342,8 @@ class CBaseHudChatEntry : public vgui::TextEntry
340342
SetPaintBorderEnabled( false );
341343
}
342344

345+
virtual void InsertChar(wchar_t ch);
346+
343347
virtual void OnKeyCodeTyped(vgui::KeyCode code)
344348
{
345349
if ( code == KEY_ENTER || code == KEY_PAD_ENTER || code == KEY_ESCAPE )
@@ -371,6 +375,7 @@ class CBaseHudChatEntry : public vgui::TextEntry
371375

372376
private:
373377
CBaseHudChat *m_pHudChat;
378+
CUtlMemory<char> m_szCharBuf{ 0, 64 }; // tmp buffer
374379
};
375380

376381
//-----------------------------------------------------------------------------

src/game/client/swarm/c_asw_pickup_weapon.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ IMPLEMENT_CLIENTCLASS_DT( C_ASW_Pickup_Weapon, DT_ASW_Pickup_Weapon, CASW_Pickup
2222
RecvPropInt (RECVINFO(m_iBulletsInGun)),
2323
RecvPropInt (RECVINFO(m_iClips)),
2424
RecvPropInt (RECVINFO(m_iSecondary)),
25-
RecvPropBool (RECVINFO(m_bIsTemporaryPickup)),
25+
RecvPropBool (RECVINFO(m_bIsTemporaryPickup)),
26+
RecvPropInt (RECVINFO(m_iClassRequirementOverride)),
2627
END_RECV_TABLE()
2728

2829
C_ASW_Pickup_Weapon::C_ASW_Pickup_Weapon()

src/game/client/swarm/c_asw_pickup_weapon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class C_ASW_Pickup_Weapon : public C_ASW_Pickup
2323
CNetworkVar(int, m_iClips);
2424
CNetworkVar(int, m_iSecondary);
2525
CNetworkVar(bool, m_bIsTemporaryPickup);
26+
CNetworkVar(int, m_iClassRequirementOverride);
2627

2728
int m_nUseIconTextureID;
2829
bool m_bWideIcon;

src/game/client/swarm/c_asw_weapon.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ BEGIN_NETWORK_TABLE( CASW_Weapon, DT_ASW_Weapon )
6464
RecvPropBool ( RECVINFO( m_bIsTemporaryPickup ) ),
6565
RecvPropEHandle( RECVINFO( m_hOriginalOwnerMR ) ),
6666
RecvPropInt( RECVINFO( m_iInventoryEquipSlot ) ),
67+
RecvPropInt( RECVINFO( m_iClassRequirementOverride ) ),
6768
END_NETWORK_TABLE()
6869

6970
BEGIN_PREDICTION_DATA( C_ASW_Weapon )
@@ -169,6 +170,7 @@ m_GlowObject( this, glow_outline_color_weapon.GetColorAsVector(), 1.0f, false, t
169170

170171
m_bPoweredUp = false;
171172
m_bIsTemporaryPickup = false;
173+
m_iClassRequirementOverride = -1;
172174
}
173175

174176

src/game/client/swarm/c_asw_weapon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class C_ASW_Weapon : public C_BaseCombatWeapon, public IASW_Client_Usable_Entity
202202
virtual bool AllowedToPickup( C_ASW_Inhabitable_NPC *pNPC );
203203
bool m_bSwappingWeapon;
204204
bool m_bIsTemporaryPickup;
205+
int m_iClassRequirementOverride;
205206

206207
// check if this weapon wants to perform a sync kill
207208
virtual bool CheckSyncKill( byte &forced_action, short &sync_kill_ent ) { return false; }

src/game/server/client.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ char * CheckChatText( CBasePlayer *pPlayer, char *text )
7373

7474
// cut off after P_MAX_LEN chars
7575
if ( length > P_MAX_LEN )
76-
p[P_MAX_LEN] = 0;
76+
{
77+
// don't split utf-8 code point
78+
size_t i = P_MAX_LEN;
79+
while( i > 0 && ( static_cast<uint8_t>(p[i]) & 0b1100'0000 ) == 0b1000'0000 ) --i;
80+
p[i] = '\0';
81+
}
7782

7883
GameRules()->CheckChatText( pPlayer, p );
7984

src/game/server/swarm/asw_grenade_cluster.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ void CASW_Grenade_Cluster::Spawn( void )
132132
SetThink( &CASW_Grenade_Cluster::CheckNearbyDrones );
133133
SetNextThink( gpGlobals->curtime + asw_cluster_grenade_radius_check_interval.GetFloat() );
134134
}
135-
m_CreatorWeaponClass = (Class_T)CLASS_ASW_UNKNOWN;
136135

137136
m_bTeslaAmped = false;
138137

@@ -226,6 +225,10 @@ CASW_Grenade_Cluster* CASW_Grenade_Cluster::Cluster_Grenade_Create( float flDama
226225
pGrenade->SetAbsAngles( angles );
227226
UTIL_SetOrigin( pGrenade, position );
228227
pGrenade->m_vecInitPos = position;
228+
if ( pCreatorWeapon )
229+
{
230+
pGrenade->m_CreatorWeaponClass = pCreatorWeapon->Classify();
231+
}
229232
pGrenade->Spawn();
230233
pGrenade->m_flDamage = flDamage;
231234
pGrenade->m_DmgRadius = fRadius;
@@ -236,7 +239,6 @@ CASW_Grenade_Cluster* CASW_Grenade_Cluster::Cluster_Grenade_Create( float flDama
236239
pGrenade->m_hCreatorWeapon = pCreatorWeapon;
237240
if ( pCreatorWeapon )
238241
{
239-
pGrenade->m_CreatorWeaponClass = pCreatorWeapon->Classify();
240242
pGrenade->m_ProjectileData.GetForModify().SetFromWeapon( pCreatorWeapon );
241243
}
242244

0 commit comments

Comments
 (0)