From 35a632e892a715327af97a0ec29a1d4a9d5cdfd3 Mon Sep 17 00:00:00 2001 From: Linrador Date: Tue, 9 Sep 2025 23:32:08 +0200 Subject: [PATCH] added icons --- public/assets/img/icons/equipment/ak47.svg | 41 ++ public/assets/img/icons/equipment/ammobox.svg | 31 ++ .../img/icons/equipment/ammobox_threepack.svg | 28 + public/assets/img/icons/equipment/armor.svg | 34 ++ .../img/icons/equipment/armor_helmet.svg | 53 ++ .../img/icons/equipment/assaultsuit.svg | 4 + .../equipment/assaultsuit_helmet_only.svg | 4 + public/assets/img/icons/equipment/aug.svg | 55 ++ public/assets/img/icons/equipment/awp.svg | 52 ++ public/assets/img/icons/equipment/bayonet.svg | 36 ++ public/assets/img/icons/equipment/bizon.svg | 481 ++++++++++++++++++ public/assets/img/icons/equipment/c4.svg | 3 + .../img/icons/equipment/clothing_hands.svg | 6 + .../img/icons/equipment/customplayer.svg | 4 + public/assets/img/icons/equipment/cz75a.svg | 53 ++ public/assets/img/icons/equipment/deagle.svg | 44 ++ public/assets/img/icons/equipment/decoy.svg | 6 + public/assets/img/icons/equipment/defuser.svg | 3 + .../assets/img/icons/equipment/disconnect.svg | 4 + .../assets/img/icons/equipment/dronegun.svg | 24 + public/assets/img/icons/equipment/elite.svg | 89 ++++ public/assets/img/icons/equipment/famas.svg | 57 +++ .../assets/img/icons/equipment/firebomb.svg | 35 ++ .../assets/img/icons/equipment/fiveseven.svg | 38 ++ public/assets/img/icons/equipment/flair0.svg | 5 + .../assets/img/icons/equipment/flashbang.svg | 4 + .../img/icons/equipment/flashbang_assist.svg | 32 ++ public/assets/img/icons/equipment/g3sg1.svg | 86 ++++ public/assets/img/icons/equipment/galilar.svg | 64 +++ public/assets/img/icons/equipment/glock.svg | 39 ++ .../img/icons/equipment/grenadepack.svg | 48 ++ .../img/icons/equipment/grenadepack2.svg | 44 ++ .../assets/img/icons/equipment/healthshot.svg | 4 + .../img/icons/equipment/heavy_armor.svg | 39 ++ .../assets/img/icons/equipment/hegrenade.svg | 3 + public/assets/img/icons/equipment/helmet.svg | 29 ++ public/assets/img/icons/equipment/hkp2000.svg | 33 ++ .../assets/img/icons/equipment/incgrenade.svg | 3 + public/assets/img/icons/equipment/inferno.svg | 29 ++ public/assets/img/icons/equipment/kevlar.svg | 30 ++ public/assets/img/icons/equipment/knife.svg | 40 ++ .../img/icons/equipment/knife_bowie.svg | 40 ++ .../img/icons/equipment/knife_butterfly.svg | 82 +++ .../img/icons/equipment/knife_canis.svg | 59 +++ .../assets/img/icons/equipment/knife_cord.svg | 90 ++++ .../assets/img/icons/equipment/knife_css.svg | 20 + .../img/icons/equipment/knife_falchion.svg | 43 ++ .../assets/img/icons/equipment/knife_flip.svg | 42 ++ .../assets/img/icons/equipment/knife_gut.svg | 43 ++ .../icons/equipment/knife_gypsy_jackknife.svg | 20 + .../img/icons/equipment/knife_karambit.svg | 47 ++ .../img/icons/equipment/knife_kukri.svg | 36 ++ .../img/icons/equipment/knife_m9_bayonet.svg | 46 ++ .../img/icons/equipment/knife_outdoor.svg | 31 ++ .../assets/img/icons/equipment/knife_push.svg | 139 +++++ .../img/icons/equipment/knife_skeleton.svg | 34 ++ .../img/icons/equipment/knife_stiletto.svg | 18 + .../icons/equipment/knife_survival_bowie.svg | 40 ++ public/assets/img/icons/equipment/knife_t.svg | 34 ++ .../img/icons/equipment/knife_tactical.svg | 77 +++ .../img/icons/equipment/knife_twinblade.svg | 33 ++ .../img/icons/equipment/knife_ursus.svg | 77 +++ .../img/icons/equipment/knife_widowmaker.svg | 33 ++ public/assets/img/icons/equipment/knifegg.svg | 36 ++ public/assets/img/icons/equipment/m249.svg | 77 +++ public/assets/img/icons/equipment/m4a1.svg | 52 ++ .../img/icons/equipment/m4a1_silencer.svg | 55 ++ .../img/icons/equipment/m4a1_silencer_off.svg | 54 ++ public/assets/img/icons/equipment/mac10.svg | 50 ++ public/assets/img/icons/equipment/mag7.svg | 282 ++++++++++ public/assets/img/icons/equipment/melee.svg | 4 + public/assets/img/icons/equipment/molotov.svg | 4 + .../assets/img/icons/equipment/movelinear.svg | 179 +++++++ public/assets/img/icons/equipment/mp5sd.svg | 32 ++ public/assets/img/icons/equipment/mp7.svg | 333 ++++++++++++ public/assets/img/icons/equipment/mp9.svg | 217 ++++++++ public/assets/img/icons/equipment/negev.svg | 400 +++++++++++++++ public/assets/img/icons/equipment/nova.svg | 280 ++++++++++ public/assets/img/icons/equipment/p2000.svg | 37 ++ public/assets/img/icons/equipment/p250.svg | 184 +++++++ public/assets/img/icons/equipment/p90.svg | 50 ++ .../assets/img/icons/equipment/planted_c4.svg | 14 + .../icons/equipment/prop_exploding_barrel.svg | 14 + .../assets/img/icons/equipment/revolver.svg | 59 +++ .../assets/img/icons/equipment/sawedoff.svg | 233 +++++++++ public/assets/img/icons/equipment/scar20.svg | 339 ++++++++++++ public/assets/img/icons/equipment/sg556.svg | 258 ++++++++++ .../img/icons/equipment/smokegrenade.svg | 3 + public/assets/img/icons/equipment/spray0.svg | 9 + public/assets/img/icons/equipment/ssg08.svg | 318 ++++++++++++ .../img/icons/equipment/stomp_damage.svg | 26 + public/assets/img/icons/equipment/taser.svg | 38 ++ public/assets/img/icons/equipment/tec9.svg | 250 +++++++++ .../img/icons/equipment/trigger_hurt.svg | 2 + public/assets/img/icons/equipment/ump45.svg | 87 ++++ .../img/icons/equipment/usp_silencer.svg | 37 ++ .../img/icons/equipment/usp_silencer_off.svg | 34 ++ .../assets/img/icons/equipment/worldent.svg | 2 + public/assets/img/icons/equipment/xm1014.svg | 61 +++ public/assets/img/icons/ui/bomb.svg | 30 ++ public/assets/img/icons/ui/bomb_c4.svg | 111 ++++ public/assets/img/icons/ui/disconnect.svg | 10 + public/assets/img/icons/ui/kill.svg | 3 + public/assets/img/icons/ui/map_death.svg | 25 + src/app/components/radar/LiveRadar.tsx | 394 ++++++++++---- src/app/components/radar/MetaSocket.tsx | 2 + src/app/components/radar/PositionsSocket.tsx | 13 +- 107 files changed, 7397 insertions(+), 102 deletions(-) create mode 100644 public/assets/img/icons/equipment/ak47.svg create mode 100644 public/assets/img/icons/equipment/ammobox.svg create mode 100644 public/assets/img/icons/equipment/ammobox_threepack.svg create mode 100644 public/assets/img/icons/equipment/armor.svg create mode 100644 public/assets/img/icons/equipment/armor_helmet.svg create mode 100644 public/assets/img/icons/equipment/assaultsuit.svg create mode 100644 public/assets/img/icons/equipment/assaultsuit_helmet_only.svg create mode 100644 public/assets/img/icons/equipment/aug.svg create mode 100644 public/assets/img/icons/equipment/awp.svg create mode 100644 public/assets/img/icons/equipment/bayonet.svg create mode 100644 public/assets/img/icons/equipment/bizon.svg create mode 100644 public/assets/img/icons/equipment/c4.svg create mode 100644 public/assets/img/icons/equipment/clothing_hands.svg create mode 100644 public/assets/img/icons/equipment/customplayer.svg create mode 100644 public/assets/img/icons/equipment/cz75a.svg create mode 100644 public/assets/img/icons/equipment/deagle.svg create mode 100644 public/assets/img/icons/equipment/decoy.svg create mode 100644 public/assets/img/icons/equipment/defuser.svg create mode 100644 public/assets/img/icons/equipment/disconnect.svg create mode 100644 public/assets/img/icons/equipment/dronegun.svg create mode 100644 public/assets/img/icons/equipment/elite.svg create mode 100644 public/assets/img/icons/equipment/famas.svg create mode 100644 public/assets/img/icons/equipment/firebomb.svg create mode 100644 public/assets/img/icons/equipment/fiveseven.svg create mode 100644 public/assets/img/icons/equipment/flair0.svg create mode 100644 public/assets/img/icons/equipment/flashbang.svg create mode 100644 public/assets/img/icons/equipment/flashbang_assist.svg create mode 100644 public/assets/img/icons/equipment/g3sg1.svg create mode 100644 public/assets/img/icons/equipment/galilar.svg create mode 100644 public/assets/img/icons/equipment/glock.svg create mode 100644 public/assets/img/icons/equipment/grenadepack.svg create mode 100644 public/assets/img/icons/equipment/grenadepack2.svg create mode 100644 public/assets/img/icons/equipment/healthshot.svg create mode 100644 public/assets/img/icons/equipment/heavy_armor.svg create mode 100644 public/assets/img/icons/equipment/hegrenade.svg create mode 100644 public/assets/img/icons/equipment/helmet.svg create mode 100644 public/assets/img/icons/equipment/hkp2000.svg create mode 100644 public/assets/img/icons/equipment/incgrenade.svg create mode 100644 public/assets/img/icons/equipment/inferno.svg create mode 100644 public/assets/img/icons/equipment/kevlar.svg create mode 100644 public/assets/img/icons/equipment/knife.svg create mode 100644 public/assets/img/icons/equipment/knife_bowie.svg create mode 100644 public/assets/img/icons/equipment/knife_butterfly.svg create mode 100644 public/assets/img/icons/equipment/knife_canis.svg create mode 100644 public/assets/img/icons/equipment/knife_cord.svg create mode 100644 public/assets/img/icons/equipment/knife_css.svg create mode 100644 public/assets/img/icons/equipment/knife_falchion.svg create mode 100644 public/assets/img/icons/equipment/knife_flip.svg create mode 100644 public/assets/img/icons/equipment/knife_gut.svg create mode 100644 public/assets/img/icons/equipment/knife_gypsy_jackknife.svg create mode 100644 public/assets/img/icons/equipment/knife_karambit.svg create mode 100644 public/assets/img/icons/equipment/knife_kukri.svg create mode 100644 public/assets/img/icons/equipment/knife_m9_bayonet.svg create mode 100644 public/assets/img/icons/equipment/knife_outdoor.svg create mode 100644 public/assets/img/icons/equipment/knife_push.svg create mode 100644 public/assets/img/icons/equipment/knife_skeleton.svg create mode 100644 public/assets/img/icons/equipment/knife_stiletto.svg create mode 100644 public/assets/img/icons/equipment/knife_survival_bowie.svg create mode 100644 public/assets/img/icons/equipment/knife_t.svg create mode 100644 public/assets/img/icons/equipment/knife_tactical.svg create mode 100644 public/assets/img/icons/equipment/knife_twinblade.svg create mode 100644 public/assets/img/icons/equipment/knife_ursus.svg create mode 100644 public/assets/img/icons/equipment/knife_widowmaker.svg create mode 100644 public/assets/img/icons/equipment/knifegg.svg create mode 100644 public/assets/img/icons/equipment/m249.svg create mode 100644 public/assets/img/icons/equipment/m4a1.svg create mode 100644 public/assets/img/icons/equipment/m4a1_silencer.svg create mode 100644 public/assets/img/icons/equipment/m4a1_silencer_off.svg create mode 100644 public/assets/img/icons/equipment/mac10.svg create mode 100644 public/assets/img/icons/equipment/mag7.svg create mode 100644 public/assets/img/icons/equipment/melee.svg create mode 100644 public/assets/img/icons/equipment/molotov.svg create mode 100644 public/assets/img/icons/equipment/movelinear.svg create mode 100644 public/assets/img/icons/equipment/mp5sd.svg create mode 100644 public/assets/img/icons/equipment/mp7.svg create mode 100644 public/assets/img/icons/equipment/mp9.svg create mode 100644 public/assets/img/icons/equipment/negev.svg create mode 100644 public/assets/img/icons/equipment/nova.svg create mode 100644 public/assets/img/icons/equipment/p2000.svg create mode 100644 public/assets/img/icons/equipment/p250.svg create mode 100644 public/assets/img/icons/equipment/p90.svg create mode 100644 public/assets/img/icons/equipment/planted_c4.svg create mode 100644 public/assets/img/icons/equipment/prop_exploding_barrel.svg create mode 100644 public/assets/img/icons/equipment/revolver.svg create mode 100644 public/assets/img/icons/equipment/sawedoff.svg create mode 100644 public/assets/img/icons/equipment/scar20.svg create mode 100644 public/assets/img/icons/equipment/sg556.svg create mode 100644 public/assets/img/icons/equipment/smokegrenade.svg create mode 100644 public/assets/img/icons/equipment/spray0.svg create mode 100644 public/assets/img/icons/equipment/ssg08.svg create mode 100644 public/assets/img/icons/equipment/stomp_damage.svg create mode 100644 public/assets/img/icons/equipment/taser.svg create mode 100644 public/assets/img/icons/equipment/tec9.svg create mode 100644 public/assets/img/icons/equipment/trigger_hurt.svg create mode 100644 public/assets/img/icons/equipment/ump45.svg create mode 100644 public/assets/img/icons/equipment/usp_silencer.svg create mode 100644 public/assets/img/icons/equipment/usp_silencer_off.svg create mode 100644 public/assets/img/icons/equipment/worldent.svg create mode 100644 public/assets/img/icons/equipment/xm1014.svg create mode 100644 public/assets/img/icons/ui/bomb.svg create mode 100644 public/assets/img/icons/ui/bomb_c4.svg create mode 100644 public/assets/img/icons/ui/disconnect.svg create mode 100644 public/assets/img/icons/ui/kill.svg create mode 100644 public/assets/img/icons/ui/map_death.svg diff --git a/public/assets/img/icons/equipment/ak47.svg b/public/assets/img/icons/equipment/ak47.svg new file mode 100644 index 0000000..a9a96e0 --- /dev/null +++ b/public/assets/img/icons/equipment/ak47.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/ammobox.svg b/public/assets/img/icons/equipment/ammobox.svg new file mode 100644 index 0000000..ac6b0e6 --- /dev/null +++ b/public/assets/img/icons/equipment/ammobox.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/ammobox_threepack.svg b/public/assets/img/icons/equipment/ammobox_threepack.svg new file mode 100644 index 0000000..60b46fe --- /dev/null +++ b/public/assets/img/icons/equipment/ammobox_threepack.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/armor.svg b/public/assets/img/icons/equipment/armor.svg new file mode 100644 index 0000000..d883a07 --- /dev/null +++ b/public/assets/img/icons/equipment/armor.svg @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/armor_helmet.svg b/public/assets/img/icons/equipment/armor_helmet.svg new file mode 100644 index 0000000..f92670b --- /dev/null +++ b/public/assets/img/icons/equipment/armor_helmet.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/assaultsuit.svg b/public/assets/img/icons/equipment/assaultsuit.svg new file mode 100644 index 0000000..db5917a --- /dev/null +++ b/public/assets/img/icons/equipment/assaultsuit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/assaultsuit_helmet_only.svg b/public/assets/img/icons/equipment/assaultsuit_helmet_only.svg new file mode 100644 index 0000000..826ca63 --- /dev/null +++ b/public/assets/img/icons/equipment/assaultsuit_helmet_only.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/aug.svg b/public/assets/img/icons/equipment/aug.svg new file mode 100644 index 0000000..d0ab91a --- /dev/null +++ b/public/assets/img/icons/equipment/aug.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/awp.svg b/public/assets/img/icons/equipment/awp.svg new file mode 100644 index 0000000..fc72485 --- /dev/null +++ b/public/assets/img/icons/equipment/awp.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/bayonet.svg b/public/assets/img/icons/equipment/bayonet.svg new file mode 100644 index 0000000..3736d3c --- /dev/null +++ b/public/assets/img/icons/equipment/bayonet.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/bizon.svg b/public/assets/img/icons/equipment/bizon.svg new file mode 100644 index 0000000..b64560e --- /dev/null +++ b/public/assets/img/icons/equipment/bizon.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/c4.svg b/public/assets/img/icons/equipment/c4.svg new file mode 100644 index 0000000..dc5fabf --- /dev/null +++ b/public/assets/img/icons/equipment/c4.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/equipment/clothing_hands.svg b/public/assets/img/icons/equipment/clothing_hands.svg new file mode 100644 index 0000000..6e5f608 --- /dev/null +++ b/public/assets/img/icons/equipment/clothing_hands.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/assets/img/icons/equipment/customplayer.svg b/public/assets/img/icons/equipment/customplayer.svg new file mode 100644 index 0000000..79d219d --- /dev/null +++ b/public/assets/img/icons/equipment/customplayer.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/cz75a.svg b/public/assets/img/icons/equipment/cz75a.svg new file mode 100644 index 0000000..447b5b4 --- /dev/null +++ b/public/assets/img/icons/equipment/cz75a.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/deagle.svg b/public/assets/img/icons/equipment/deagle.svg new file mode 100644 index 0000000..49e74ef --- /dev/null +++ b/public/assets/img/icons/equipment/deagle.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/decoy.svg b/public/assets/img/icons/equipment/decoy.svg new file mode 100644 index 0000000..a69622e --- /dev/null +++ b/public/assets/img/icons/equipment/decoy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/assets/img/icons/equipment/defuser.svg b/public/assets/img/icons/equipment/defuser.svg new file mode 100644 index 0000000..1d0ad76 --- /dev/null +++ b/public/assets/img/icons/equipment/defuser.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/equipment/disconnect.svg b/public/assets/img/icons/equipment/disconnect.svg new file mode 100644 index 0000000..ee247fe --- /dev/null +++ b/public/assets/img/icons/equipment/disconnect.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/dronegun.svg b/public/assets/img/icons/equipment/dronegun.svg new file mode 100644 index 0000000..58e9ab1 --- /dev/null +++ b/public/assets/img/icons/equipment/dronegun.svg @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/elite.svg b/public/assets/img/icons/equipment/elite.svg new file mode 100644 index 0000000..60e799c --- /dev/null +++ b/public/assets/img/icons/equipment/elite.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/famas.svg b/public/assets/img/icons/equipment/famas.svg new file mode 100644 index 0000000..f7cc10c --- /dev/null +++ b/public/assets/img/icons/equipment/famas.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/firebomb.svg b/public/assets/img/icons/equipment/firebomb.svg new file mode 100644 index 0000000..fcde26d --- /dev/null +++ b/public/assets/img/icons/equipment/firebomb.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/fiveseven.svg b/public/assets/img/icons/equipment/fiveseven.svg new file mode 100644 index 0000000..11acf64 --- /dev/null +++ b/public/assets/img/icons/equipment/fiveseven.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/flair0.svg b/public/assets/img/icons/equipment/flair0.svg new file mode 100644 index 0000000..55834e8 --- /dev/null +++ b/public/assets/img/icons/equipment/flair0.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/assets/img/icons/equipment/flashbang.svg b/public/assets/img/icons/equipment/flashbang.svg new file mode 100644 index 0000000..aa6c75e --- /dev/null +++ b/public/assets/img/icons/equipment/flashbang.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/flashbang_assist.svg b/public/assets/img/icons/equipment/flashbang_assist.svg new file mode 100644 index 0000000..8ef46ae --- /dev/null +++ b/public/assets/img/icons/equipment/flashbang_assist.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/g3sg1.svg b/public/assets/img/icons/equipment/g3sg1.svg new file mode 100644 index 0000000..6b9bbb1 --- /dev/null +++ b/public/assets/img/icons/equipment/g3sg1.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/galilar.svg b/public/assets/img/icons/equipment/galilar.svg new file mode 100644 index 0000000..48ce1fe --- /dev/null +++ b/public/assets/img/icons/equipment/galilar.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/glock.svg b/public/assets/img/icons/equipment/glock.svg new file mode 100644 index 0000000..1266eeb --- /dev/null +++ b/public/assets/img/icons/equipment/glock.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/grenadepack.svg b/public/assets/img/icons/equipment/grenadepack.svg new file mode 100644 index 0000000..2f331e0 --- /dev/null +++ b/public/assets/img/icons/equipment/grenadepack.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/grenadepack2.svg b/public/assets/img/icons/equipment/grenadepack2.svg new file mode 100644 index 0000000..a65574d --- /dev/null +++ b/public/assets/img/icons/equipment/grenadepack2.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/healthshot.svg b/public/assets/img/icons/equipment/healthshot.svg new file mode 100644 index 0000000..f69eac9 --- /dev/null +++ b/public/assets/img/icons/equipment/healthshot.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/heavy_armor.svg b/public/assets/img/icons/equipment/heavy_armor.svg new file mode 100644 index 0000000..99c610a --- /dev/null +++ b/public/assets/img/icons/equipment/heavy_armor.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/hegrenade.svg b/public/assets/img/icons/equipment/hegrenade.svg new file mode 100644 index 0000000..0373a20 --- /dev/null +++ b/public/assets/img/icons/equipment/hegrenade.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/equipment/helmet.svg b/public/assets/img/icons/equipment/helmet.svg new file mode 100644 index 0000000..141f6b2 --- /dev/null +++ b/public/assets/img/icons/equipment/helmet.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/hkp2000.svg b/public/assets/img/icons/equipment/hkp2000.svg new file mode 100644 index 0000000..bf41676 --- /dev/null +++ b/public/assets/img/icons/equipment/hkp2000.svg @@ -0,0 +1,33 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/incgrenade.svg b/public/assets/img/icons/equipment/incgrenade.svg new file mode 100644 index 0000000..1b64c11 --- /dev/null +++ b/public/assets/img/icons/equipment/incgrenade.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/equipment/inferno.svg b/public/assets/img/icons/equipment/inferno.svg new file mode 100644 index 0000000..abfe94c --- /dev/null +++ b/public/assets/img/icons/equipment/inferno.svg @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/kevlar.svg b/public/assets/img/icons/equipment/kevlar.svg new file mode 100644 index 0000000..23e8ab9 --- /dev/null +++ b/public/assets/img/icons/equipment/kevlar.svg @@ -0,0 +1,30 @@ + + + + + + diff --git a/public/assets/img/icons/equipment/knife.svg b/public/assets/img/icons/equipment/knife.svg new file mode 100644 index 0000000..93eb367 --- /dev/null +++ b/public/assets/img/icons/equipment/knife.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_bowie.svg b/public/assets/img/icons/equipment/knife_bowie.svg new file mode 100644 index 0000000..8769320 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_bowie.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_butterfly.svg b/public/assets/img/icons/equipment/knife_butterfly.svg new file mode 100644 index 0000000..e615a50 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_butterfly.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_canis.svg b/public/assets/img/icons/equipment/knife_canis.svg new file mode 100644 index 0000000..e16b0f2 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_canis.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_cord.svg b/public/assets/img/icons/equipment/knife_cord.svg new file mode 100644 index 0000000..cfd6284 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_cord.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_css.svg b/public/assets/img/icons/equipment/knife_css.svg new file mode 100644 index 0000000..5220300 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_css.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_falchion.svg b/public/assets/img/icons/equipment/knife_falchion.svg new file mode 100644 index 0000000..967dd3d --- /dev/null +++ b/public/assets/img/icons/equipment/knife_falchion.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_flip.svg b/public/assets/img/icons/equipment/knife_flip.svg new file mode 100644 index 0000000..1d5c4ef --- /dev/null +++ b/public/assets/img/icons/equipment/knife_flip.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_gut.svg b/public/assets/img/icons/equipment/knife_gut.svg new file mode 100644 index 0000000..dcc0beb --- /dev/null +++ b/public/assets/img/icons/equipment/knife_gut.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_gypsy_jackknife.svg b/public/assets/img/icons/equipment/knife_gypsy_jackknife.svg new file mode 100644 index 0000000..7f2af68 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_gypsy_jackknife.svg @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_karambit.svg b/public/assets/img/icons/equipment/knife_karambit.svg new file mode 100644 index 0000000..7ed2544 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_karambit.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_kukri.svg b/public/assets/img/icons/equipment/knife_kukri.svg new file mode 100644 index 0000000..dbd82cd --- /dev/null +++ b/public/assets/img/icons/equipment/knife_kukri.svg @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_m9_bayonet.svg b/public/assets/img/icons/equipment/knife_m9_bayonet.svg new file mode 100644 index 0000000..6db46c3 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_m9_bayonet.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_outdoor.svg b/public/assets/img/icons/equipment/knife_outdoor.svg new file mode 100644 index 0000000..b5ecada --- /dev/null +++ b/public/assets/img/icons/equipment/knife_outdoor.svg @@ -0,0 +1,31 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_push.svg b/public/assets/img/icons/equipment/knife_push.svg new file mode 100644 index 0000000..f918752 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_push.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_skeleton.svg b/public/assets/img/icons/equipment/knife_skeleton.svg new file mode 100644 index 0000000..24cd94b --- /dev/null +++ b/public/assets/img/icons/equipment/knife_skeleton.svg @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_stiletto.svg b/public/assets/img/icons/equipment/knife_stiletto.svg new file mode 100644 index 0000000..771f392 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_stiletto.svg @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_survival_bowie.svg b/public/assets/img/icons/equipment/knife_survival_bowie.svg new file mode 100644 index 0000000..32b1392 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_survival_bowie.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_t.svg b/public/assets/img/icons/equipment/knife_t.svg new file mode 100644 index 0000000..7c4e32a --- /dev/null +++ b/public/assets/img/icons/equipment/knife_t.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_tactical.svg b/public/assets/img/icons/equipment/knife_tactical.svg new file mode 100644 index 0000000..5a32089 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_tactical.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_twinblade.svg b/public/assets/img/icons/equipment/knife_twinblade.svg new file mode 100644 index 0000000..59705e0 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_twinblade.svg @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_ursus.svg b/public/assets/img/icons/equipment/knife_ursus.svg new file mode 100644 index 0000000..72d625e --- /dev/null +++ b/public/assets/img/icons/equipment/knife_ursus.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knife_widowmaker.svg b/public/assets/img/icons/equipment/knife_widowmaker.svg new file mode 100644 index 0000000..4e4a923 --- /dev/null +++ b/public/assets/img/icons/equipment/knife_widowmaker.svg @@ -0,0 +1,33 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/knifegg.svg b/public/assets/img/icons/equipment/knifegg.svg new file mode 100644 index 0000000..e9cad6d --- /dev/null +++ b/public/assets/img/icons/equipment/knifegg.svg @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/m249.svg b/public/assets/img/icons/equipment/m249.svg new file mode 100644 index 0000000..ff6209e --- /dev/null +++ b/public/assets/img/icons/equipment/m249.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/m4a1.svg b/public/assets/img/icons/equipment/m4a1.svg new file mode 100644 index 0000000..2256d37 --- /dev/null +++ b/public/assets/img/icons/equipment/m4a1.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/m4a1_silencer.svg b/public/assets/img/icons/equipment/m4a1_silencer.svg new file mode 100644 index 0000000..92e9419 --- /dev/null +++ b/public/assets/img/icons/equipment/m4a1_silencer.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/m4a1_silencer_off.svg b/public/assets/img/icons/equipment/m4a1_silencer_off.svg new file mode 100644 index 0000000..4f0eda9 --- /dev/null +++ b/public/assets/img/icons/equipment/m4a1_silencer_off.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/mac10.svg b/public/assets/img/icons/equipment/mac10.svg new file mode 100644 index 0000000..e062fb0 --- /dev/null +++ b/public/assets/img/icons/equipment/mac10.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/mag7.svg b/public/assets/img/icons/equipment/mag7.svg new file mode 100644 index 0000000..121c112 --- /dev/null +++ b/public/assets/img/icons/equipment/mag7.svg @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/melee.svg b/public/assets/img/icons/equipment/melee.svg new file mode 100644 index 0000000..1a913e1 --- /dev/null +++ b/public/assets/img/icons/equipment/melee.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/molotov.svg b/public/assets/img/icons/equipment/molotov.svg new file mode 100644 index 0000000..f0a0365 --- /dev/null +++ b/public/assets/img/icons/equipment/molotov.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/img/icons/equipment/movelinear.svg b/public/assets/img/icons/equipment/movelinear.svg new file mode 100644 index 0000000..7d7af00 --- /dev/null +++ b/public/assets/img/icons/equipment/movelinear.svg @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/mp5sd.svg b/public/assets/img/icons/equipment/mp5sd.svg new file mode 100644 index 0000000..ba9ac3d --- /dev/null +++ b/public/assets/img/icons/equipment/mp5sd.svg @@ -0,0 +1,32 @@ + + + + + + diff --git a/public/assets/img/icons/equipment/mp7.svg b/public/assets/img/icons/equipment/mp7.svg new file mode 100644 index 0000000..4a7eb42 --- /dev/null +++ b/public/assets/img/icons/equipment/mp7.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/mp9.svg b/public/assets/img/icons/equipment/mp9.svg new file mode 100644 index 0000000..ed6814c --- /dev/null +++ b/public/assets/img/icons/equipment/mp9.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/negev.svg b/public/assets/img/icons/equipment/negev.svg new file mode 100644 index 0000000..efbf397 --- /dev/null +++ b/public/assets/img/icons/equipment/negev.svg @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/nova.svg b/public/assets/img/icons/equipment/nova.svg new file mode 100644 index 0000000..3a900e6 --- /dev/null +++ b/public/assets/img/icons/equipment/nova.svg @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/p2000.svg b/public/assets/img/icons/equipment/p2000.svg new file mode 100644 index 0000000..479d0c9 --- /dev/null +++ b/public/assets/img/icons/equipment/p2000.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/p250.svg b/public/assets/img/icons/equipment/p250.svg new file mode 100644 index 0000000..8afed22 --- /dev/null +++ b/public/assets/img/icons/equipment/p250.svg @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/p90.svg b/public/assets/img/icons/equipment/p90.svg new file mode 100644 index 0000000..784268b --- /dev/null +++ b/public/assets/img/icons/equipment/p90.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/planted_c4.svg b/public/assets/img/icons/equipment/planted_c4.svg new file mode 100644 index 0000000..64d318a --- /dev/null +++ b/public/assets/img/icons/equipment/planted_c4.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/prop_exploding_barrel.svg b/public/assets/img/icons/equipment/prop_exploding_barrel.svg new file mode 100644 index 0000000..64d318a --- /dev/null +++ b/public/assets/img/icons/equipment/prop_exploding_barrel.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/public/assets/img/icons/equipment/revolver.svg b/public/assets/img/icons/equipment/revolver.svg new file mode 100644 index 0000000..d0e13b3 --- /dev/null +++ b/public/assets/img/icons/equipment/revolver.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/sawedoff.svg b/public/assets/img/icons/equipment/sawedoff.svg new file mode 100644 index 0000000..70d65ec --- /dev/null +++ b/public/assets/img/icons/equipment/sawedoff.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/scar20.svg b/public/assets/img/icons/equipment/scar20.svg new file mode 100644 index 0000000..bd40d68 --- /dev/null +++ b/public/assets/img/icons/equipment/scar20.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/sg556.svg b/public/assets/img/icons/equipment/sg556.svg new file mode 100644 index 0000000..6c9934d --- /dev/null +++ b/public/assets/img/icons/equipment/sg556.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/smokegrenade.svg b/public/assets/img/icons/equipment/smokegrenade.svg new file mode 100644 index 0000000..f438432 --- /dev/null +++ b/public/assets/img/icons/equipment/smokegrenade.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/equipment/spray0.svg b/public/assets/img/icons/equipment/spray0.svg new file mode 100644 index 0000000..c91a0b1 --- /dev/null +++ b/public/assets/img/icons/equipment/spray0.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/assets/img/icons/equipment/ssg08.svg b/public/assets/img/icons/equipment/ssg08.svg new file mode 100644 index 0000000..551bad1 --- /dev/null +++ b/public/assets/img/icons/equipment/ssg08.svg @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/stomp_damage.svg b/public/assets/img/icons/equipment/stomp_damage.svg new file mode 100644 index 0000000..992cdf7 --- /dev/null +++ b/public/assets/img/icons/equipment/stomp_damage.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/taser.svg b/public/assets/img/icons/equipment/taser.svg new file mode 100644 index 0000000..d8094a4 --- /dev/null +++ b/public/assets/img/icons/equipment/taser.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/tec9.svg b/public/assets/img/icons/equipment/tec9.svg new file mode 100644 index 0000000..1e80d60 --- /dev/null +++ b/public/assets/img/icons/equipment/tec9.svg @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/trigger_hurt.svg b/public/assets/img/icons/equipment/trigger_hurt.svg new file mode 100644 index 0000000..e13238a --- /dev/null +++ b/public/assets/img/icons/equipment/trigger_hurt.svg @@ -0,0 +1,2 @@ + + diff --git a/public/assets/img/icons/equipment/ump45.svg b/public/assets/img/icons/equipment/ump45.svg new file mode 100644 index 0000000..716c7d4 --- /dev/null +++ b/public/assets/img/icons/equipment/ump45.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/usp_silencer.svg b/public/assets/img/icons/equipment/usp_silencer.svg new file mode 100644 index 0000000..575201a --- /dev/null +++ b/public/assets/img/icons/equipment/usp_silencer.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/usp_silencer_off.svg b/public/assets/img/icons/equipment/usp_silencer_off.svg new file mode 100644 index 0000000..bb7f06f --- /dev/null +++ b/public/assets/img/icons/equipment/usp_silencer_off.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/equipment/worldent.svg b/public/assets/img/icons/equipment/worldent.svg new file mode 100644 index 0000000..e13238a --- /dev/null +++ b/public/assets/img/icons/equipment/worldent.svg @@ -0,0 +1,2 @@ + + diff --git a/public/assets/img/icons/equipment/xm1014.svg b/public/assets/img/icons/equipment/xm1014.svg new file mode 100644 index 0000000..b69056e --- /dev/null +++ b/public/assets/img/icons/equipment/xm1014.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/ui/bomb.svg b/public/assets/img/icons/ui/bomb.svg new file mode 100644 index 0000000..2b7bcb0 --- /dev/null +++ b/public/assets/img/icons/ui/bomb.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/ui/bomb_c4.svg b/public/assets/img/icons/ui/bomb_c4.svg new file mode 100644 index 0000000..e1f3252 --- /dev/null +++ b/public/assets/img/icons/ui/bomb_c4.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + diff --git a/public/assets/img/icons/ui/disconnect.svg b/public/assets/img/icons/ui/disconnect.svg new file mode 100644 index 0000000..98fb3cc --- /dev/null +++ b/public/assets/img/icons/ui/disconnect.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/img/icons/ui/kill.svg b/public/assets/img/icons/ui/kill.svg new file mode 100644 index 0000000..71e10d4 --- /dev/null +++ b/public/assets/img/icons/ui/kill.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/img/icons/ui/map_death.svg b/public/assets/img/icons/ui/map_death.svg new file mode 100644 index 0000000..69e90ae --- /dev/null +++ b/public/assets/img/icons/ui/map_death.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/src/app/components/radar/LiveRadar.tsx b/src/app/components/radar/LiveRadar.tsx index d0f305d..a2473ac 100644 --- a/src/app/components/radar/LiveRadar.tsx +++ b/src/app/components/radar/LiveRadar.tsx @@ -33,7 +33,7 @@ const UI = { death: { stroke: '#9ca3af', lineWidthPx: 2, - sizePx: 10, + sizePx: 20, }, trail: { maxPoints: 60, @@ -44,6 +44,14 @@ const UI = { } /* ───────── helpers ───────── */ + +const steamIdOf = (src:any): string | null => { + const raw = src?.steamId ?? src?.steam_id ?? src?.steamid + const s = raw != null ? String(raw) : '' + return s && s !== '0' ? s : null +} + + function contrastStroke(hex: string) { const h = hex.replace('#','') const r = parseInt(h.slice(0,2),16)/255 @@ -150,7 +158,7 @@ type BombState = { x: number y: number z: number - status: 'carried'|'dropped'|'planted'|'unknown' + status: 'carried'|'dropped'|'planted'|'defusing'|'defused'|'unknown' changedAt: number } @@ -165,7 +173,7 @@ type Grenade = { team?: 'T' | 'CT' | string | null } -type DeathMarker = { id: string; x: number; y: number; t: number } +type DeathMarker = { id: string; sid?: string | null; x: number; y: number; t: number } type Trail = { id: string; kind: Grenade['kind']; pts: {x:number,y:number}[]; lastSeen: number } type Overview = { posX: number; posY: number; scale: number; rotate?: number } type Mapper = (xw: number, yw: number) => { x: number; y: number } @@ -184,6 +192,10 @@ export default function LiveRadar() { const playersRef = useRef>(new Map()) const [players, setPlayers] = useState([]) + // Deaths + const deathSeqRef = useRef(0); + const deathSeenRef = useRef>(new Set()); + // Grenaden + Trails const grenadesRef = useRef>(new Map()) const [grenades, setGrenades] = useState([]) @@ -222,26 +234,42 @@ export default function LiveRadar() { } }, []) - // Runden-/Map-Reset - const clearRoundArtifacts = () => { - deathMarkersRef.current = [] - trailsRef.current.clear() - grenadesRef.current.clear() - bombRef.current = null - scheduleFlush() - } + // ersetzt deine bisherige clearRoundArtifacts + const clearRoundArtifacts = (resetPlayers = false, hard = false) => { + // round/map visuals + deathMarkersRef.current = []; + deathSeenRef.current.clear(); + trailsRef.current.clear(); + grenadesRef.current.clear(); + bombRef.current = null; + + if (hard) { + // z.B. bei Mapwechsel: komplett leer + playersRef.current.clear(); + } else if (resetPlayers) { + // zum Rundenstart: alle wieder lebendig und ohne Bombe + for (const [id, p] of playersRef.current) { + playersRef.current.set(id, { ...p, alive: true, hasBomb: false }); + } + } + + scheduleFlush(); + }; + + useEffect(() => { - if (activeMapKey) clearRoundArtifacts() + if (activeMapKey) clearRoundArtifacts(true, true); // vorher: nur Artefakte // eslint-disable-next-line react-hooks/exhaustive-deps - }, [activeMapKey]) + }, [activeMapKey]); + /* ───────── Meta-Callbacks ───────── */ const handleMetaMap = (key: string) => setActiveMapKey(key.toLowerCase()) const handleMetaPlayersSnapshot = (list: Array<{ steamId: string|number; name?: string; team?: any }>) => { for (const p of list) { - const id = String(p.steamId ?? '') - if (!id) continue + const id = steamIdOf(p) + if (!id) continue // ⬅️ wichtig: keine name-basierten Keys mehr const old = playersRef.current.get(id) playersRef.current.set(id, { id, @@ -257,8 +285,8 @@ export default function LiveRadar() { } const handleMetaPlayerJoin = (p: any) => { - const id = String(p?.steamId ?? p?.id ?? p?.name ?? '') - if (!id) return + const id = steamIdOf(p) + if (!id) return // ⬅️ keine Duplikate über Namen erzeugen const old = playersRef.current.get(id) playersRef.current.set(id, { id, @@ -267,7 +295,7 @@ export default function LiveRadar() { x: old?.x ?? 0, y: old?.y ?? 0, z: old?.z ?? 0, yaw: old?.yaw ?? null, alive: true, - hasBomb: old?.hasBomb ?? false, + hasBomb: false, // ⬅️ safe default }) scheduleFlush() } @@ -292,103 +320,155 @@ export default function LiveRadar() { function normalizeBomb(raw:any): BombState | null { if (!raw) return null - // „event“-Hüllen abfangen const payload = raw.bomb ?? raw.c4 ?? raw - const pos = pickVec3(payload) + + const t = String(raw?.type ?? '').toLowerCase() + // Events, die nur den Beginn/Abbruch des Plantens signalisieren → ignorieren + if (t === 'bomb_beginplant' || t === 'bomb_abortplant') { + return null + } + let status: BombState['status'] = 'unknown' const s = String(payload?.status ?? payload?.state ?? '').toLowerCase() - if (s.includes('plant')) status = 'planted' - else if (s.includes('drop')) status = 'dropped' - else if (s.includes('carry')) status = 'carried' + // String-Status präzise auswerten + if (s.includes('planted')) status = 'planted' + else if (s.includes('planting')) status = 'unknown' // bewusst NICHT anzeigen + else if (s.includes('drop')) status = 'dropped' + else if (s.includes('carry')) status = 'carried' + else if (s.includes('defus')) status = 'defusing' - // bool-Varianten - if (payload?.planted === true) status = 'planted' - if (payload?.dropped === true) status = 'dropped' - if (payload?.carried === true) status = 'carried' + // Bool-Varianten + if (payload?.planted === true) status = 'planted' + if (payload?.dropped === true) status = 'dropped' + if (payload?.carried === true) status = 'carried' + if (payload?.defusing === true) status = 'defusing' + if (payload?.defused === true) status = 'defused' // Event-Typen - const t = String(raw?.type ?? '').toLowerCase() - if (t === 'bomb_planted') status = 'planted' - if (t === 'bomb_dropped') status = 'dropped' - if (t === 'bomb_pickup') status = 'carried' + if (t === 'bomb_planted') status = 'planted' + if (t === 'bomb_dropped') status = 'dropped' + if (t === 'bomb_pickup') status = 'carried' + if (t === 'bomb_begindefuse') status = 'defusing' + if (t === 'bomb_abortdefuse') status = 'planted' + if (t === 'bomb_defused') status = 'defused' - // Ohne brauchbare Position: ignorieren - if (!Number.isFinite(pos.x) || !Number.isFinite(pos.y)) return null + // Position kann bei Defuse-Events fehlen → später mit letzter Position mergen + const x = Number.isFinite(pos.x) ? pos.x : NaN + const y = Number.isFinite(pos.y) ? pos.y : NaN + const z = Number.isFinite(pos.z) ? pos.z : NaN - return { x: pos.x, y: pos.y, z: pos.z, status, changedAt: Date.now() } + return { x, y, z, status, changedAt: Date.now() } } // Fallback: aus Spielerzustand ableiten (Bombenträger) const updateBombFromPlayers = () => { + // geplante Bombe hat Vorrang – nicht überschreiben + if (bombRef.current?.status === 'planted') return + const carrier = Array.from(playersRef.current.values()).find(p => p.hasBomb) if (carrier) { + // Nur "carried" setzen, echte Dropposition kommt per Server-Event bombRef.current = { x: carrier.x, y: carrier.y, z: carrier.z, - status: 'carried', changedAt: Date.now() + status: 'carried', changedAt: bombRef.current?.status === 'carried' + ? (bombRef.current.changedAt) // plantedAt nicht antasten + : Date.now() } - } else if (bombRef.current?.status === 'carried') { - // Träger hat die Bombe nicht mehr → als „gedroppt“ an letzter Position belassen - bombRef.current = { ...bombRef.current, status: 'dropped', changedAt: Date.now() } } + // kein else → wir warten auf 'bomb_dropped' vom Server } /* ───────── Positions-Callbacks ───────── */ - const addDeathMarker = (x:number, y:number, idHint?: string) => { - deathMarkersRef.current.push({ id: idHint ?? `d#${Date.now()}`, x, y, t: Date.now() }) - } + const addDeathMarker = (x: number, y: number, steamId?: string) => { + const now = Date.now(); - const upsertPlayer = (e: any) => { - const id = String(e.steamId ?? e.steam_id ?? e.userId ?? e.playerId ?? e.id ?? e.name ?? '') - if (!id) return - const pos = e.pos ?? e.position ?? e.location ?? e.coordinates - const x = Number(e.x ?? pos?.x ?? (Array.isArray(pos) ? pos?.[0] : undefined)) - const y = Number(e.y ?? pos?.y ?? (Array.isArray(pos) ? pos?.[1] : undefined)) - const z = Number(e.z ?? pos?.z ?? (Array.isArray(pos) ? pos?.[2] : 0)) - if (!Number.isFinite(x) || !Number.isFinite(y)) return + // pro Runde nur ein Marker pro Spieler + if (steamId) { + if (deathSeenRef.current.has(steamId)) return; + deathSeenRef.current.add(steamId); + } - const yaw = Number( + // interne eindeutige ID behalten (für Fallback) + const uid = `${steamId ?? 'd'}#${now}#${deathSeqRef.current++}`; + deathMarkersRef.current.push({ id: uid, sid: steamId ?? null, x, y, t: now }); + }; + + + function upsertPlayer(e: any) { + // 1) Stabile ID bestimmen – nur SteamID benutzen + const id = steamIdOf(e); + if (!id) return; // keine name-basierten Keys mehr + + // 2) Position herausziehen + const pos = e.pos ?? e.position ?? e.location ?? e.coordinates; + const x = asNum(e.x ?? (Array.isArray(pos) ? pos?.[0] : pos?.x)); + const y = asNum(e.y ?? (Array.isArray(pos) ? pos?.[1] : pos?.y)); + const z = asNum(e.z ?? (Array.isArray(pos) ? pos?.[2] : pos?.z), 0); + if (!Number.isFinite(x) || !Number.isFinite(y)) return; + + // 3) Blickrichtung / Yaw + const yawVal = e.yaw ?? e.viewAngle?.yaw ?? e.view?.yaw ?? e.aim?.yaw ?? e.ang?.y ?? e.angles?.y ?? - e.rotation?.yaw - ) + e.rotation?.yaw; + const yaw = Number(yawVal); - const old = playersRef.current.get(id) - const nextAlive = (e.alive !== undefined) ? !!e.alive : old?.alive - const hp = Number( - e.hp ?? e.health ?? e.state?.health - ) - const armor = Number( - e.armor ?? e.state?.armor - ) - const helmet = Boolean( - e.helmet ?? e.hasHelmet ?? e.state?.helmet - ) - const defuse = Boolean( - e.defuse ?? e.hasDefuse ?? e.hasDefuser ?? e.state?.defusekit - ) - const hasBomb = detectHasBomb(e) || old?.hasBomb + // 4) Vorheriger Zustand + const old = playersRef.current.get(id); - if (old?.alive !== false && nextAlive === false) addDeathMarker(x, y, id) + // 5) Alive-State bestimmen + // - e.alive (bool) hat Vorrang + // - sonst aus Health ableiten + let nextAlive: boolean | undefined = undefined; + if (typeof e.alive === 'boolean') { + nextAlive = e.alive; + } else if (e.hp != null || e.health != null || e.state?.health != null) { + const hpProbe = asNum(e.hp ?? e.health ?? e.state?.health, NaN); + if (Number.isFinite(hpProbe)) nextAlive = hpProbe > 0; + } else { + nextAlive = old?.alive; + } + // 6) Armor/HP/Equipment + const hp = asNum(e.hp ?? e.health ?? e.state?.health, old?.hp ?? null as any); + const armor = asNum(e.armor ?? e.state?.armor, old?.armor ?? null as any); + const helmet = (e.helmet ?? e.hasHelmet ?? e.state?.helmet); + const defuse = (e.defuse ?? e.hasDefuse ?? e.hasDefuser ?? e.state?.defusekit); + + // 7) Bombenstatus: + // - nie als „carried“ markieren, wenn die Bombe bereits planted ist + // - sonst detektieren, mit altem Zustand „kleben“ + const hasBombDetected = !!detectHasBomb(e) || !!old?.hasBomb; + const hasBomb = + bombRef.current?.status === 'planted' + ? false + : hasBombDetected; + + // 8) Death-Marker setzen, wenn gerade gestorben + if ((old?.alive !== false) && nextAlive === false) { + addDeathMarker(x, y, id); + } + + // 9) Schreiben/mergen playersRef.current.set(id, { id, - name: e.name ?? old?.name ?? null, - team: mapTeam(e.team ?? old?.team), + name: e.name ?? old?.name ?? null, + team: mapTeam(e.team ?? old?.team), x, y, z, - yaw: Number.isFinite(yaw) ? yaw : old?.yaw ?? null, + yaw: Number.isFinite(yaw) ? yaw : (old?.yaw ?? null), alive: nextAlive, - hasBomb: !!hasBomb, - hp: Number.isFinite(hp) ? hp : old?.hp ?? null, - armor: Number.isFinite(armor) ? armor : old?.armor ?? null, - helmet: helmet ?? old?.helmet ?? null, - defuse: defuse ?? old?.defuse ?? null, - }) + hasBomb, + hp: Number.isFinite(hp) ? hp : (old?.hp ?? null), + armor: Number.isFinite(armor) ? armor : (old?.armor ?? null), + helmet: typeof helmet === 'boolean' ? helmet : (old?.helmet ?? null), + defuse: typeof defuse === 'boolean' ? defuse : (old?.defuse ?? null), + }); } const handlePlayersAll = (msg: any) => { @@ -681,6 +761,54 @@ export default function LiveRadar() { return (u: number) => u * k }, [imgSize, overview]) + // ── Bomb "beep" / pulse timing ────────────────────────────── + const BOMB_FUSE_MS = 40_000; + const plantedAtRef = useRef(null); + const beepTimerRef = useRef(null); + const [beepState, setBeepState] = useState<{ key: number; dur: number } | null>(null); + + const getBeepIntervalMs = (remainingMs: number) => { + const s = remainingMs / 1000; + if (s > 30) return 1000; + if (s > 20) return 900; + if (s > 10) return 800; + if (s > 5) return 700; + return 500; + }; + + const stopBeep = () => { + if (beepTimerRef.current != null) window.clearTimeout(beepTimerRef.current); + beepTimerRef.current = null; + plantedAtRef.current = null; + setBeepState(null); + }; + + const isBeepActive = !!bomb && (bomb.status === 'planted' || bomb.status === 'defusing'); + + useEffect(() => { + if (!isBeepActive) { stopBeep(); return; } + + // nur initial (beim Plant) Startzeit setzen + if (!plantedAtRef.current) { + // wenn wir aus "defusing" kommen, wollen wir NICHT resetten → changedAt beim Plant bleibt erhalten + plantedAtRef.current = bomb!.changedAt; + + const tick = () => { + if (!plantedAtRef.current) return; + const elapsed = Date.now() - plantedAtRef.current; + const remaining = Math.max(0, BOMB_FUSE_MS - elapsed); + if (remaining <= 0) { stopBeep(); return; } + + const dur = getBeepIntervalMs(remaining); + setBeepState(prev => ({ key: (prev?.key ?? 0) + 1, dur })); + beepTimerRef.current = window.setTimeout(tick, dur); + }; + + tick(); // erster Ping sofort + } + }, [isBeepActive]); + + /* ───────── Status-Badge ───────── */ const WsDot = ({ status, label }: { status: WsStatus, label: string }) => { const color = @@ -733,8 +861,51 @@ export default function LiveRadar() { onPlayerUpdate={(p)=> { upsertPlayer(p); scheduleFlush() }} onPlayersAll={(m)=> { handlePlayersAll(m); scheduleFlush() }} onGrenades={(g)=> { handleGrenades(g); scheduleFlush() }} - onRoundStart={() => { bombRef.current = null; scheduleFlush() }} // ⬅️ sinnvoll - onBomb={(b)=> { const nb = normalizeBomb(b); if (nb) { bombRef.current = nb; scheduleFlush() } }} // ⬅️ NEU + + // ⬇️ wichtig: sofort alles aufräumen + Spieler lebend/ohne Bombe + onRoundStart={() => { clearRoundArtifacts(true); }} + + // optional: am Round-End gleich aufräumen (nimmt die Leichen sofort weg) + onRoundEnd={() => { + // Spieler zurücksetzen + for (const [id, p] of playersRef.current) { + playersRef.current.set(id, { ...p, hasBomb: false }) + } + + // Bombenping aus, Marker ggf. als 'defused' stehen lassen + if (bombRef.current?.status === 'planted') { + bombRef.current = { ...bombRef.current, status: 'defused' } + } + stopBeep() + + // visuelle Artefakte (Trails, Nades, Deaths) aufräumen – Bombe NICHT löschen + deathMarkersRef.current = [] + trailsRef.current.clear() + grenadesRef.current.clear() + + scheduleFlush() + }} + + + onBomb={(b)=> { + const prev = bombRef.current + const nb = normalizeBomb(b) + if (!nb) return + + const withPos = { + x: Number.isFinite(nb.x) ? nb.x : (prev?.x ?? 0), + y: Number.isFinite(nb.y) ? nb.y : (prev?.y ?? 0), + z: Number.isFinite(nb.z) ? nb.z : (prev?.z ?? 0), + } + + const sameStatus = prev && prev.status === nb.status + bombRef.current = { + ...withPos, + status: nb.status, + changedAt: sameStatus ? prev!.changedAt : Date.now(), + } + scheduleFlush() + }} /> {/* Inhalt: 3-Spalten-Layout (T | Radar | CT) */} @@ -784,6 +955,8 @@ export default function LiveRadar() { className="absolute inset-0 h-full w-full object-contain pointer-events-none" viewBox={`0 0 ${imgSize.w} ${imgSize.h}`} preserveAspectRatio="xMidYMid meet" + xmlns="http://www.w3.org/2000/svg" + xmlnsXlink="http://www.w3.org/1999/xlink" > {/* Trails */} {trails.map(tr => { @@ -845,28 +1018,43 @@ export default function LiveRadar() { {/* Bombe */} {bomb && (() => { + const showBomb = bomb.status === 'planted' || bomb.status === 'defusing' || bomb.status === 'defused' + if (!showBomb) return null + const P = worldToPx(bomb.x, bomb.y) if (!Number.isFinite(P.x) || !Number.isFinite(P.y)) return null - const r = Math.max(6, unitsToPx(28)) // Marker-Größe - const color = bomb.status === 'planted' ? '#ef4444' : '#dddddd' + + // Mindestgrößen in Pixeln erzwingen + const rBase = Math.max(10, unitsToPx(28)) // Kreis darf klein sein, aber nicht <10px + const iconSize = Math.max(24, rBase * 1.8) // SVG-Icon mindestens 24px + + const isActive = bomb.status === 'planted' || bomb.status === 'defusing' + const isDefused = bomb.status === 'defused' + const color = isDefused ? '#10b981' : (isActive ? '#ef4444' : '#dddddd') return ( - {/* Ping nur wenn geplantet */} - {bomb.status === 'planted' && ( - - - - + {isActive && beepState && ( + + + )} - {/* Marker */} - - B + ) })()} + {/* Spieler */} {players .filter(p => (p.team === 'CT' || p.team === 'T') && p.alive !== false) @@ -912,16 +1100,22 @@ export default function LiveRadar() { ) })} - {/* Death-Marker */} + {/* Death-Marker (SVG statt "X") */} {deathMarkers.map(dm => { const P = worldToPx(dm.x, dm.y) - const s = UI.death.sizePx + const size = Math.max(10, UI.death.sizePx) // z.B. 16–20 für bessere Sichtbarkeit + const key = dm.sid ? `death-${dm.sid}` : `death-${dm.id}`; // Fallback, falls mal keine SID vorliegt return ( - - - + + ) })} @@ -950,6 +1144,12 @@ export default function LiveRadar() { )} + ) } diff --git a/src/app/components/radar/MetaSocket.tsx b/src/app/components/radar/MetaSocket.tsx index 915db3d..e21aef3 100644 --- a/src/app/components/radar/MetaSocket.tsx +++ b/src/app/components/radar/MetaSocket.tsx @@ -1,3 +1,5 @@ +// MetaSocket.tsx + 'use client' import { useEffect, useRef } from 'react' diff --git a/src/app/components/radar/PositionsSocket.tsx b/src/app/components/radar/PositionsSocket.tsx index 6fb3a98..e4194da 100644 --- a/src/app/components/radar/PositionsSocket.tsx +++ b/src/app/components/radar/PositionsSocket.tsx @@ -1,3 +1,5 @@ +// PositionsSocket.tsx + 'use client' import { useEffect, useRef } from 'react' @@ -32,13 +34,11 @@ export default function PositionsSocket({ const retryRef = useRef(null) const dispatch = (msg: any) => { - if (!msg) return + if (!msg) return; - // Runde: if (msg.type === 'round_start') { onRoundStart?.(); return } if (msg.type === 'round_end') { onRoundEnd?.(); return } - // Tick (Fast-Path) if (msg.type === 'tick') { if (typeof msg.map === 'string') onMap?.(msg.map.toLowerCase()) if (Array.isArray(msg.players)) msg.players.forEach(onPlayerUpdate ?? (() => {})) @@ -51,11 +51,14 @@ export default function PositionsSocket({ if (msg.allplayers) onPlayersAll?.(msg) if (msg.player || msg.steamId || msg.position || msg.pos) onPlayerUpdate?.(msg) if (msg.grenades && msg.type !== 'tick') onGrenades?.(msg.grenades) - if (msg.bomb || msg.c4 || ['bomb_planted','bomb_dropped','bomb_pickup'].includes(String(msg.type).toLowerCase())) { - onBomb?.(msg) + + const t = String(msg.type || '').toLowerCase(); + if (msg.bomb || msg.c4 || t.startsWith('bomb_')) { + onBomb?.(msg); } } + useEffect(() => { aliveRef.current = true const connect = () => {