@@ -12,6 +12,11 @@ void KZPaintService::Reset()
1212 // Reset to default: red color and default size
1313 player->optionService ->SetPreferenceInt (" paintColor" , 0xFF0000FF ); // Red (RGBA format)
1414 player->optionService ->SetPreferenceFloat (" paintSize" , DEFAULT_PAINT_SIZE);
15+ player->optionService ->SetPreferenceBool (" showAllPaint" , false );
16+
17+ this ->autoPaintEnabled = false ;
18+ this ->hasLastAutoPaintPosition = false ;
19+ this ->nextAutoPaintTime = 0.0 ;
1520}
1621
1722Color KZPaintService::GetColor () const
@@ -137,16 +142,56 @@ const char *KZPaintService::GetColorName() const
137142 return " Custom" ;
138143}
139144
145+ bool KZPaintService::ShouldShowAllPaint () const
146+ {
147+ return this ->player ->optionService ->GetPreferenceBool (" showAllPaint" , false );
148+ }
149+
150+ bool KZPaintService::IsAutoPaintEnabled () const
151+ {
152+ return this ->autoPaintEnabled ;
153+ }
154+
155+ void KZPaintService::OnGameFrame ()
156+ {
157+ for (i32 i = 1 ; i <= MAXPLAYERS; i++)
158+ {
159+ KZPlayer *player = g_pKZPlayerManager->ToPlayer (i);
160+ if (!player || !player->paintService )
161+ {
162+ continue ;
163+ }
164+
165+ player->paintService ->TryAutoPaint ();
166+ }
167+ }
168+
169+ void KZPaintService::ToggleAutoPaint ()
170+ {
171+ this ->autoPaintEnabled = !this ->autoPaintEnabled ;
172+ if (this ->autoPaintEnabled )
173+ {
174+ this ->hasLastAutoPaintPosition = false ;
175+ this ->nextAutoPaintTime = 0.0 ;
176+ }
177+ }
178+
179+ void KZPaintService::ToggleShowAllPaint ()
180+ {
181+ bool newValue = !this ->player ->optionService ->GetPreferenceBool (" showAllPaint" , false );
182+ this ->player ->optionService ->SetPreferenceBool (" showAllPaint" , newValue);
183+ }
184+
140185// Commands
141186
142187#define KZ_PAINT_TRACE_DISTANCE 32768 .0f
143188
144- void KZPaintService::PlacePaint ()
189+ bool KZPaintService::TracePaint ( trace_t &tr) const
145190{
146191 CCSPlayerPawnBase *pawn = static_cast <CCSPlayerPawnBase *>(this ->player ->GetCurrentPawn ());
147192 if (!pawn)
148193 {
149- return ;
194+ return false ;
150195 }
151196
152197 Vector origin;
@@ -157,23 +202,63 @@ void KZPaintService::PlacePaint()
157202 AngleVectors (angles, &forward);
158203 Vector endPos = origin + forward * KZ_PAINT_TRACE_DISTANCE;
159204
160- trace_t tr;
161205 bbox_t bounds ({vec3_origin, vec3_origin});
162206 CTraceFilterPlayerMovementCS filter (pawn);
163207 filter.EnableInteractsExcludeLayer (LAYER_INDEX_CONTENTS_PLAYER_CLIP);
164208 filter.EnableInteractsExcludeLayer (LAYER_INDEX_CONTENTS_PLAYER);
165209 g_pKZUtils->TracePlayerBBox (origin, endPos, bounds, &filter, tr);
166210
167- if (!tr.DidHit ())
211+ return tr.DidHit ();
212+ }
213+
214+ void KZPaintService::PlacePaint ()
215+ {
216+ trace_t tr;
217+ if (!this ->TracePaint (tr))
168218 {
169219 return ;
170220 }
221+
171222 CGlobalSymbol paintDecal = MakeGlobalSymbol (" paint" );
172223 this ->pendingPaint = true ;
173224 g_pKZUtils->DecalTrace (&tr, &paintDecal, 0 .0f );
174225 this ->pendingPaint = false ;
175226}
176227
228+ void KZPaintService::TryAutoPaint ()
229+ {
230+ if (!this ->autoPaintEnabled )
231+ {
232+ return ;
233+ }
234+
235+ f64 curTime = g_pKZUtils->GetGlobals ()->curtime ;
236+ if (curTime < this ->nextAutoPaintTime )
237+ {
238+ return ;
239+ }
240+ this ->nextAutoPaintTime = curTime + 0.05 ;
241+
242+ trace_t tr;
243+ if (!this ->TracePaint (tr))
244+ {
245+ return ;
246+ }
247+
248+ if (this ->hasLastAutoPaintPosition && (tr.m_vEndPos - this ->lastAutoPaintPosition ).LengthSqr () < 1 .0f )
249+ {
250+ return ;
251+ }
252+
253+ CGlobalSymbol paintDecal = MakeGlobalSymbol (" paint" );
254+ this ->pendingPaint = true ;
255+ g_pKZUtils->DecalTrace (&tr, &paintDecal, 0 .0f );
256+ this ->pendingPaint = false ;
257+
258+ this ->lastAutoPaintPosition = tr.m_vEndPos ;
259+ this ->hasLastAutoPaintPosition = true ;
260+ }
261+
177262SCMD (kz_paint, SCFL_MISC)
178263{
179264 KZPlayer *player = g_pKZPlayerManager->ToPlayer (controller);
@@ -191,14 +276,14 @@ SCMD(kz_paintcolor, SCFL_PREFERENCE | SCFL_MISC)
191276 player->languageService ->PrintChat (true , false , " Current Paint Color" , player->paintService ->GetColorName (),
192277 player->paintService ->GetColor ().r (), player->paintService ->GetColor ().g (),
193278 player->paintService ->GetColor ().b ());
194- return MRES_HANDLED ;
279+ return MRES_SUPERCEDE ;
195280 }
196281
197282 // Check for predefined colors
198283 if (player->paintService ->SetColor (args->Arg (1 )))
199284 {
200285 player->languageService ->PrintChat (true , false , " Paint Color Set" , player->paintService ->GetColorName ());
201- return MRES_HANDLED ;
286+ return MRES_SUPERCEDE ;
202287 }
203288
204289 // Try to parse as RGB values
@@ -216,11 +301,11 @@ SCMD(kz_paintcolor, SCFL_PREFERENCE | SCFL_MISC)
216301
217302 player->paintService ->SetColorRGB (r, g, b, a);
218303 player->languageService ->PrintChat (true , false , " Paint Color RGB Set" , r, g, b, a);
219- return MRES_HANDLED ;
304+ return MRES_SUPERCEDE ;
220305 }
221306
222307 player->languageService ->PrintChat (true , false , " Paint Color Command Usage" );
223- return MRES_HANDLED ;
308+ return MRES_SUPERCEDE ;
224309}
225310
226311SCMD (kz_paintsize, SCFL_PREFERENCE | SCFL_MISC)
@@ -231,18 +316,36 @@ SCMD(kz_paintsize, SCFL_PREFERENCE | SCFL_MISC)
231316 {
232317 player->languageService ->PrintChat (true , false , " Paint Size Command Usage" );
233318 player->languageService ->PrintChat (true , false , " Current Paint Size" , player->paintService ->GetSize ());
234- return MRES_HANDLED ;
319+ return MRES_SUPERCEDE ;
235320 }
236321
237322 f32 value = (f32 )atof (args->Arg (1 ));
238323 if (player->paintService ->SetSize (value))
239324 {
240325 player->languageService ->PrintChat (true , false , " Paint Size Set" , player->paintService ->GetSize ());
241- return MRES_HANDLED ;
326+ return MRES_SUPERCEDE ;
242327 }
243328
244329 player->languageService ->PrintChat (true , false , " Paint Size Command Usage" );
245- return MRES_HANDLED;
330+ return MRES_SUPERCEDE;
331+ }
332+
333+ SCMD (kz_togglepaint, SCFL_MISC | SCFL_PREFERENCE)
334+ {
335+ KZPlayer *player = g_pKZPlayerManager->ToPlayer (controller);
336+ player->paintService ->ToggleAutoPaint ();
337+
338+ player->languageService ->PrintChat (true , false , player->paintService ->IsAutoPaintEnabled () ? " Paint Toggle Enabled" : " Paint Toggle Disabled" );
339+ return MRES_SUPERCEDE;
340+ }
341+
342+ SCMD (kz_showpaint, SCFL_MISC | SCFL_PREFERENCE)
343+ {
344+ KZPlayer *player = g_pKZPlayerManager->ToPlayer (controller);
345+ player->paintService ->ToggleShowAllPaint ();
346+
347+ player->languageService ->PrintChat (true , false , player->paintService ->ShouldShowAllPaint () ? " Show Paint Enabled" : " Show Paint Disabled" );
348+ return MRES_SUPERCEDE;
246349}
247350
248351SCMD (kz_cleardecals, SCFL_MISC)
0 commit comments