diff --git a/resources/maps/BlackSea.json b/resources/maps/BlackSea.json index 3b2e42087..ae90b80cb 100644 --- a/resources/maps/BlackSea.json +++ b/resources/maps/BlackSea.json @@ -52,4 +52,4 @@ "flag": "am" } ] -} \ No newline at end of file +} diff --git a/resources/maps/Europe.json b/resources/maps/Europe.json index be6b6c0ff..885344df5 100644 --- a/resources/maps/Europe.json +++ b/resources/maps/Europe.json @@ -1,193 +1,193 @@ { - "name": "Europe", - "width": 2000, - "height": 1000, - "nations": [ - { - "coordinates": [171, 171], - "name": "Iceland", - "strength": 1, - "flag": "is" - }, - { - "coordinates": [477, 473], - "name": "Ireland", - "strength": 1, - "flag": "ie" - }, - { - "coordinates": [650, 500], - "name": "United Kingdom", - "strength": 3, - "flag": "gb" - }, - { - "coordinates": [560, 800], - "name": "Spain", - "strength": 2, - "flag": "es" - }, - { - "coordinates": [726, 616], - "name": "France", - "strength": 2, - "flag": "fr" - }, - { - "coordinates": [1050, 745], - "name": "Italy", - "strength": 1, - "flag": "it" - }, - { - "coordinates": [872, 634], - "name": "Switzerland", - "strength": 1, - "flag": "ch" - }, - { - "coordinates": [960, 271], - "name": "Norway", - "strength": 1, - "flag": "no" - }, - { - "coordinates": [1095, 336], - "name": "Sweden", - "strength": 1, - "flag": "se" - }, - { - "coordinates": [1403, 235], - "name": "Finland", - "strength": 1, - "flag": "fi" - }, - { - "coordinates": [775, 541], - "name": "Belgium", - "strength": 1, - "flag": "be" - }, - { - "coordinates": [868, 487], - "name": "Netherlands", - "strength": 1, - "flag": "nl" - }, - { - "coordinates": [1000, 480], - "name": "Germany", - "strength": 1, - "flag": "de" - }, - { - "coordinates": [1017, 628], - "name": "Austria", - "strength": 1, - "flag": "at" - }, - { - "coordinates": [1120, 477], - "name": "Poland", - "strength": 1, - "flag": "pl" - }, - { - "coordinates": [1060, 530], - "name": "Czech Republic", - "strength": 1, - "flag": "cz" - }, - { - "coordinates": [1540, 602], - "name": "Ukraine", - "strength": 1, - "flag": "ua" - }, - { - "coordinates": [1500, 440], - "name": "Belarus", - "strength": 1, - "flag": "by" - }, - { - "coordinates": [1400, 670], - "name": "Romania", - "strength": 1, - "flag": "ro" - }, - { - "coordinates": [1580, 834], - "name": "Turkey", - "strength": 1, - "flag": "tr" - }, - { - "coordinates": [525, 955], - "name": "Morocco", - "strength": 1, - "flag": "ma" - }, - { - "coordinates": [1674, 449], - "name": "Russian Federation", - "strength": 3, - "flag": "ru" - }, - { - "coordinates": [1750, 950], - "name": "Syrian Arab Republic", - "strength": 1, - "flag": "sy" - }, - { - "coordinates": [1930, 950], - "name": "Iraq", - "strength": 1, - "flag": "iq" - }, - { - "coordinates": [1900, 720], - "name": "Georgia", - "strength": 1, - "flag": "ge" - }, - { - "coordinates": [950, 930], - "name": "Tunisia", - "strength": 1, - "flag": "tn" - }, - { - "coordinates": [740, 940], - "name": "Algeria", - "strength": 1, - "flag": "dz" - }, - { - "coordinates": [460, 830], - "name": "Portugal", - "strength": 1, - "flag": "pt" - }, - { - "coordinates": [1300, 830], - "name": "Greece", - "strength": 1, - "flag": "gr" - }, - { - "coordinates": [1270, 700], - "name": "Serbia", - "strength": 1, - "flag": "rs" - }, - { - "coordinates": [1200, 630], - "name": "Hungary", - "strength": 1, - "flag": "hu" - } - ] - } \ No newline at end of file + "name": "Europe", + "width": 2000, + "height": 1000, + "nations": [ + { + "coordinates": [171, 171], + "name": "Iceland", + "strength": 1, + "flag": "is" + }, + { + "coordinates": [477, 473], + "name": "Ireland", + "strength": 1, + "flag": "ie" + }, + { + "coordinates": [650, 500], + "name": "United Kingdom", + "strength": 3, + "flag": "gb" + }, + { + "coordinates": [560, 800], + "name": "Spain", + "strength": 2, + "flag": "es" + }, + { + "coordinates": [726, 616], + "name": "France", + "strength": 2, + "flag": "fr" + }, + { + "coordinates": [1050, 745], + "name": "Italy", + "strength": 1, + "flag": "it" + }, + { + "coordinates": [872, 634], + "name": "Switzerland", + "strength": 1, + "flag": "ch" + }, + { + "coordinates": [960, 271], + "name": "Norway", + "strength": 1, + "flag": "no" + }, + { + "coordinates": [1095, 336], + "name": "Sweden", + "strength": 1, + "flag": "se" + }, + { + "coordinates": [1403, 235], + "name": "Finland", + "strength": 1, + "flag": "fi" + }, + { + "coordinates": [775, 541], + "name": "Belgium", + "strength": 1, + "flag": "be" + }, + { + "coordinates": [868, 487], + "name": "Netherlands", + "strength": 1, + "flag": "nl" + }, + { + "coordinates": [1000, 480], + "name": "Germany", + "strength": 1, + "flag": "de" + }, + { + "coordinates": [1017, 628], + "name": "Austria", + "strength": 1, + "flag": "at" + }, + { + "coordinates": [1120, 477], + "name": "Poland", + "strength": 1, + "flag": "pl" + }, + { + "coordinates": [1060, 530], + "name": "Czech Republic", + "strength": 1, + "flag": "cz" + }, + { + "coordinates": [1540, 602], + "name": "Ukraine", + "strength": 1, + "flag": "ua" + }, + { + "coordinates": [1500, 440], + "name": "Belarus", + "strength": 1, + "flag": "by" + }, + { + "coordinates": [1400, 670], + "name": "Romania", + "strength": 1, + "flag": "ro" + }, + { + "coordinates": [1580, 834], + "name": "Turkey", + "strength": 1, + "flag": "tr" + }, + { + "coordinates": [525, 955], + "name": "Morocco", + "strength": 1, + "flag": "ma" + }, + { + "coordinates": [1674, 449], + "name": "Russian Federation", + "strength": 3, + "flag": "ru" + }, + { + "coordinates": [1750, 950], + "name": "Syrian Arab Republic", + "strength": 1, + "flag": "sy" + }, + { + "coordinates": [1930, 950], + "name": "Iraq", + "strength": 1, + "flag": "iq" + }, + { + "coordinates": [1900, 720], + "name": "Georgia", + "strength": 1, + "flag": "ge" + }, + { + "coordinates": [950, 930], + "name": "Tunisia", + "strength": 1, + "flag": "tn" + }, + { + "coordinates": [740, 940], + "name": "Algeria", + "strength": 1, + "flag": "dz" + }, + { + "coordinates": [460, 830], + "name": "Portugal", + "strength": 1, + "flag": "pt" + }, + { + "coordinates": [1300, 830], + "name": "Greece", + "strength": 1, + "flag": "gr" + }, + { + "coordinates": [1270, 700], + "name": "Serbia", + "strength": 1, + "flag": "rs" + }, + { + "coordinates": [1200, 630], + "name": "Hungary", + "strength": 1, + "flag": "hu" + } + ] +} diff --git a/resources/maps/Mena.json b/resources/maps/Mena.json index 30a4937e6..15d36cc3c 100644 --- a/resources/maps/Mena.json +++ b/resources/maps/Mena.json @@ -7,211 +7,211 @@ "coordinates": [200, 100], "name": "Spain", "strength": 1, - "flag": "ES" + "flag": "es" }, { "coordinates": [50, 135], "name": "Portugal", "strength": 1, - "flag": "PT" + "flag": "pt" }, { "coordinates": [125, 375], "name": "Morocco", "strength": 1, - "flag": "MA" + "flag": "ma" }, { "coordinates": [425, 300], "name": "Algeria", "strength": 1, - "flag": "DZ" + "flag": "dz" }, { "coordinates": [600, 275], "name": "Tunisia", "strength": 1, - "flag": "TN" + "flag": "tn" }, { "coordinates": [750, 450], "name": "Libyan Arab Jamahiriya", "strength": 1, - "flag": "LY" + "flag": "ly" }, { "coordinates": [1100, 450], "name": "Egypt", "strength": 1, - "flag": "EG" + "flag": "eg" }, { "coordinates": [1333, 333], "name": "Israel", "strength": 1, - "flag": "IL" + "flag": "il" }, { "coordinates": [1338, 388], "name": "Palestinian Territory, Occupied", "strength": 1, - "flag": "PS" + "flag": "ps" }, { "coordinates": [1370, 325], "name": "Lebanon", "strength": 1, - "flag": "LB" + "flag": "lb" }, { "coordinates": [1228, 728], "name": "Sudan", "strength": 1, - "flag": "SD" + "flag": "sd" }, { "coordinates": [1450, 275], "name": "Syrian Arab Republic", "strength": 1, - "flag": "SY" + "flag": "sy" }, { "coordinates": [1600, 300], "name": "Iraq", "strength": 1, - "flag": "IQ" + "flag": "iq" }, { "coordinates": [1550, 600], "name": "Saudi Arabia", "strength": 1, - "flag": "SA" + "flag": "sa" }, { "coordinates": [1700, 850], "name": "Yemen", "strength": 1, - "flag": "YE" + "flag": "ye" }, { "coordinates": [1950, 725], "name": "Oman", "strength": 1, - "flag": "OM" + "flag": "om" }, { "coordinates": [1860, 620], "name": "United Arab Emirates", "strength": 1, - "flag": "AE" + "flag": "ae" }, { "coordinates": [1730, 580], "name": "Qatar", "strength": 1, - "flag": "QA" + "flag": "qa" }, { "coordinates": [1900, 350], "name": "Iran, Islamic Republic Of", "strength": 1, - "flag": "IR" + "flag": "ir" }, { "coordinates": [1300, 150], "name": "Turkey", "strength": 1, - "flag": "TR" + "flag": "tr" }, { "coordinates": [675, 50], "name": "Italy", "strength": 1, - "flag": "IT" + "flag": "it" }, { "coordinates": [950, 125], "name": "Greece", "strength": 1, - "flag": "GR" + "flag": "gr" }, { "coordinates": [1000, 25], "name": "Bulgaria", "strength": 1, - "flag": "BG" + "flag": "bg" }, { "coordinates": [1980, 45], "name": "Uzbekistan", "strength": 1, - "flag": "UZ" + "flag": "uz" }, { "coordinates": [1400, 400], "name": "Jordan", "strength": 1, - "flag": "JO" + "flag": "jo" }, { "coordinates": [750, 930], "name": "Chad", "strength": 1, - "flag": "TD" + "flag": "td" }, { "coordinates": [500, 900], "name": "Niger", "strength": 1, - "flag": "NE" + "flag": "ne" }, { "coordinates": [230, 940], "name": "Mali", "strength": 1, - "flag": "ML" + "flag": "ml" }, { "coordinates": [40, 830], "name": "Mauritania", "strength": 1, - "flag": "MR" + "flag": "mr" }, { "coordinates": [1490, 980], "name": "Eritrea", "strength": 1, - "flag": "ER" + "flag": "er" }, { "coordinates": [1630, 460], "name": "Kuwait", "strength": 1, - "flag": "KW" + "flag": "kw" }, { "coordinates": [1550, 25], "name": "Georgia", "strength": 1, - "flag": "GE" + "flag": "ge" }, { "coordinates": [1640, 100], "name": "Azerbaijan", "strength": 1, - "flag": "AZ" + "flag": "az" }, { "coordinates": [1226, 280], "name": "Cyprus", "strength": 1, - "flag": "CY" + "flag": "cy" }, { "coordinates": [1800, 40], "name": "Kazakhstan", "strength": 1, - "flag": "KZ" + "flag": "kz" } ] } diff --git a/resources/maps/NorthAmerica.json b/resources/maps/NorthAmerica.json index a93917d43..4c789d21a 100644 --- a/resources/maps/NorthAmerica.json +++ b/resources/maps/NorthAmerica.json @@ -7,97 +7,97 @@ "coordinates": [1280, 582], "name": "United States", "strength": 3, - "flag": "US" + "flag": "us" }, { "coordinates": [1235, 509], "name": "Canada", "strength": 2, - "flag": "CA" + "flag": "ca" }, { "coordinates": [983, 832], "name": "Mexico", "strength": 2, - "flag": "MX" + "flag": "mx" }, { "coordinates": [1126, 871], "name": "Belize", "strength": 1, - "flag": "BZ" + "flag": "bz" }, { "coordinates": [1096, 893], "name": "Guatemala", "strength": 1, - "flag": "GT" + "flag": "gt" }, { "coordinates": [1124, 916], "name": "El Salvador", "strength": 1, - "flag": "SV" + "flag": "sv" }, { "coordinates": [1143, 906], "name": "Honduras", "strength": 1, - "flag": "HN" + "flag": "hn" }, { "coordinates": [1157, 937], "name": "Nicaragua", "strength": 1, - "flag": "NI" + "flag": "ni" }, { "coordinates": [1184, 963], "name": "Costa Rica", "strength": 1, - "flag": "CR" + "flag": "cr" }, { "coordinates": [1235, 974], "name": "Panama", "strength": 1, - "flag": "PA" + "flag": "pa" }, { "coordinates": [1304, 997], "name": "Colombia", "strength": 1, - "flag": "CO" + "flag": "co" }, { "coordinates": [1392, 955], "name": "Venezuela", "strength": 1, - "flag": "VE" + "flag": "ve" }, { "coordinates": [1228, 802], "name": "Cuba", "strength": 1, - "flag": "CU" + "flag": "cu" }, { "coordinates": [1263, 857], "name": "Jamaica", "strength": 1, - "flag": "JM" + "flag": "jm" }, { "coordinates": [1326, 849], "name": "Haiti", "strength": 1, - "flag": "HT" + "flag": "ht" }, { "coordinates": [1358, 852], "name": "Dominican Republic", "strength": 1, - "flag": "DO" + "flag": "do" } ] } diff --git a/resources/maps/Oceania.json b/resources/maps/Oceania.json index 4d492a8af..c321f1672 100644 --- a/resources/maps/Oceania.json +++ b/resources/maps/Oceania.json @@ -7,199 +7,199 @@ "coordinates": [718, 738], "name": "Australia", "strength": 1, - "flag": "AU" + "flag": "au" }, { "coordinates": [1050, 809], "name": "New Zealand", "strength": 1, - "flag": "NZ" + "flag": "nz" }, { "coordinates": [686, 407], "name": "Papua New Guinea", "strength": 1, - "flag": "PG" + "flag": "pg" }, { "coordinates": [436, 407], "name": "Timor-Leste", "strength": 1, - "flag": "TL" + "flag": "tl" }, { "coordinates": [182, 378], "name": "Indonesia", "strength": 1, - "flag": "ID" + "flag": "id" }, { "coordinates": [292, 243], "name": "Brunei Darussalam", "strength": 1, - "flag": "BN" + "flag": "bn" }, { "coordinates": [152, 282], "name": "Singapore", "strength": 1, - "flag": "SG" + "flag": "sg" }, { "coordinates": [120, 261], "name": "Malaysia", "strength": 1, - "flag": "MY" + "flag": "my" }, { "coordinates": [106, 129], "name": "Thailand", "strength": 1, - "flag": "TH" + "flag": "th" }, { "coordinates": [51, 42], "name": "Myanmar", "strength": 1, - "flag": "MM" + "flag": "mm" }, { "coordinates": [158, 162], "name": "Cambodia", "strength": 1, - "flag": "KH" + "flag": "kh" }, { "coordinates": [182, 43], "name": "Viet Nam", "strength": 1, - "flag": "VN" + "flag": "vn" }, { "coordinates": [143, 37], "name": "Lao People's Democratic Republic", "strength": 1, - "flag": "LA" + "flag": "la" }, { "coordinates": [278, 18], "name": "Hong Kong", "strength": 1, - "flag": "HK" + "flag": "hk" }, { "coordinates": [359, 1], "name": "Taiwan, Province of China", "strength": 1, - "flag": "TW" + "flag": "tw" }, { "coordinates": [366, 119], "name": "Philippines", "strength": 1, - "flag": "PH" + "flag": "ph" }, { "coordinates": [536, 207], "name": "Palau", "strength": 1, - "flag": "PW" + "flag": "pw" }, { "coordinates": [834, 215], "name": "Micronesia, Federated States of", "strength": 1, - "flag": "FM" + "flag": "fm" }, { "coordinates": [664, 113], "name": "Guam", "strength": 1, - "flag": "GU" + "flag": "gu" }, { "coordinates": [1042, 317], "name": "Marshall Islands", "strength": 1, - "flag": "MH" + "flag": "mh" }, { "coordinates": [799, 385], "name": "Papua New Guinea", "strength": 1, - "flag": "PG" + "flag": "pg" }, { "coordinates": [862, 442], "name": "Solomon Islands", "strength": 1, - "flag": "SB" + "flag": "sb" }, { "coordinates": [945, 497], "name": "Vanuatu", "strength": 1, - "flag": "VU" + "flag": "vu" }, { "coordinates": [930, 574], "name": "New Caledonia", "strength": 1, - "flag": "NC" + "flag": "nc" }, { "coordinates": [1085, 526], "name": "Fiji", "strength": 1, - "flag": "FJ" + "flag": "fj" }, { "coordinates": [1169, 568], "name": "Tonga", "strength": 1, - "flag": "TO" + "flag": "to" }, { "coordinates": [1236, 541], "name": "Niue", "strength": 1, - "flag": "NU" + "flag": "nu" }, { "coordinates": [1204, 473], "name": "Samoa", "strength": 1, - "flag": "WS" + "flag": "ws" }, { "coordinates": [1491, 523], "name": "Cook Islands", "strength": 1, - "flag": "CK" + "flag": "ck" }, { "coordinates": [1623, 424], "name": "French Polynesia", "strength": 1, - "flag": "PF" + "flag": "pf" }, { "coordinates": [1393, 278], "name": "Kiribati", "strength": 1, - "flag": "KI" + "flag": "ki" }, { "coordinates": [1420, 56], "name": "United States", "strength": 1, - "flag": "US" + "flag": "us" }, { "coordinates": [1996, 644], "name": "Chile", "strength": 1, - "flag": "CL" + "flag": "cl" } ] } diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index 0a37a2410..784e19562 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -3,12 +3,15 @@ import { customElement, property, state } from "lit/decorators.js"; import { Difficulty, GameMapType, GameType } from "../core/game/Game"; import { Lobby } from "../core/Schemas"; import { consolex } from "../core/Consolex"; +import "./components/Difficulties"; +import { DifficultyDescription } from "./components/Difficulties"; +import "./components/Maps"; @customElement("host-lobby-modal") export class HostLobbyModal extends LitElement { @state() private isModalOpen = false; @state() private selectedMap: GameMapType = GameMapType.World; - @state() private selectedDiffculty: Difficulty = Difficulty.Medium; + @state() private selectedDifficulty: Difficulty = Difficulty.Medium; @state() private disableNPCs = false; @state() private disableBots = false; @state() private creativeMode = false; @@ -28,16 +31,57 @@ export class HostLobbyModal extends LitElement { width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); + overflow-y: auto; + display: flex; + align-items: center; + justify-content: center; } .modal-content { - background-color: white; - margin: 15% auto; + background-color: rgb(35 35 35 / 0.8); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + color: white; padding: 20px; border-radius: 8px; width: 80%; - max-width: 500px; + max-width: 1280px; + max-height: 80vh; + overflow-y: auto; text-align: center; + box-shadow: 0 0 40px rgba(0, 0, 0, 0.5); + border: 1px solid rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + position: relative; + } + + /* Add custom scrollbar styles */ + .modal-content::-webkit-scrollbar { + width: 8px; + } + + .modal-content::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + } + + .modal-content::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 4px; + } + + .modal-content::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); + } + + .title { + font-size: 28px; + color: #fff; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + padding: 0 0 0 20px; } .close { @@ -50,55 +94,183 @@ export class HostLobbyModal extends LitElement { .close:hover, .close:focus { - color: black; + color: white; text-decoration: none; cursor: pointer; } - button { - padding: 10px 20px; + .start-game-button { + width: 100%; + max-width: 300px; + padding: 15px 20px; font-size: 16px; cursor: pointer; background-color: #007bff; color: white; border: none; - border-radius: 4px; + border-radius: 8px; transition: background-color 0.3s; display: inline-block; - margin-top: 20px; + margin: 0 0 20px 0; } - button:hover { + .start-game-button:not(:disabled):hover { background-color: #0056b3; } - select { - padding: 8px; - font-size: 16px; - margin-top: 10px; - width: 200px; + .start-game-button:disabled { + background: linear-gradient(to right, #4a4a4a, #3d3d3d); + opacity: 0.7; + cursor: not-allowed; } - .lobby-id-container { + .options-layout { + display: grid; + grid-template-columns: 1fr; + gap: 24px; + margin: 24px 0; + } + + .options-section { + background: rgba(0, 0, 0, 0.2); + padding: 12px 24px 24px 24px; + border-radius: 12px; + } + + .option-title { + margin: 0 0 16px 0; + font-size: 20px; + color: #fff; + text-align: center; + } + + .option-cards { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 16px; + } + + .option-card { + width: 100%; + min-width: 100px; + max-width: 120px; + padding: 4px 4px 0 4px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + background: rgba(30, 30, 30, 0.95); + border: 2px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + cursor: pointer; + transition: all 0.2s ease-in-out; + } + + .option-card:hover { + transform: translateY(-2px); + border-color: rgba(255, 255, 255, 0.3); + background: rgba(40, 40, 40, 0.95); + } + + .option-card.selected { + border-color: #4a9eff; + background: rgba(74, 158, 255, 0.1); + } + + .option-card-title { + font-size: 14px; + color: #aaa; + text-align: center; + margin: 0 0 4px 0; + } + + .option-image { + width: 100%; + aspect-ratio: 4/2; + color: #aaa; + transition: transform 0.2s ease-in-out; + border-radius: 8px; + background-color: rgba(255, 255, 255, 0.1); + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + } + + /* HostLobbyModal css */ + .clipboard-icon { + display: flex; + align-items: center; + justify-content: center; + color: #fff; + } + + .copy-success { + position: relative; + transform: translateY(-10px); + color: green; + font-size: 14px; + margin-top: 5px; + } + + .copy-success-icon { + width: 18px; + height: 18px; + color: #4caf50; + } + + .lobby-id-box { display: flex; align-items: center; justify-content: center; gap: 10px; + margin: 8px 0px 0px 0px; } - .clipboard-icon { + .lobby-id-button { + display: flex; + align-items: center; + gap: 8px; + background: rgba(0, 0, 0, 0.2); + padding: 8px 16px; + border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.1); cursor: pointer; - transition: opacity 0.3s; + transition: all 0.2s ease-in-out; } - .clipboard-icon:hover { - opacity: 0.7; + .lobby-id-button:hover { + background: rgba(0, 0, 0, 0.3); + border-color: rgba(255, 255, 255, 0.2); + transform: translateY(-1px); } - .copy-success { - color: green; + .lobby-id { font-size: 14px; - margin-top: 5px; + color: #fff; + text-align: center; + } + + .players-list { + display: flex; + flex-wrap: wrap; + gap: 8px; + justify-content: center; + padding: 0 16px; + } + + .player-tag { + display: flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.1); + padding: 4px 16px; + border-radius: 16px; + font-size: 14px; + color: #fff; + border: 1px solid rgba(255, 255, 255, 0.2); } `; @@ -106,97 +278,133 @@ export class HostLobbyModal extends LitElement { return html` + `; @@ -217,14 +425,14 @@ export class HostLobbyModal extends LitElement { id: this.lobbyId, }, map: this.selectedMap, - difficulty: this.selectedDiffculty, + difficulty: this.selectedDifficulty, disableBots: this.disableBots, disableNPCs: this.disableNPCs, creativeMode: this.creativeMode, }, bubbles: true, composed: true, - }), + }) ); }); this.isModalOpen = true; @@ -240,19 +448,12 @@ export class HostLobbyModal extends LitElement { } } - private async handleMapChange(e: Event) { - this.selectedMap = String( - (e.target as HTMLSelectElement).value, - ) as GameMapType; - consolex.log(`updating map to ${this.selectedMap}`); + private async handleMapSelection(value: GameMapType) { + this.selectedMap = value; this.putGameConfig(); } - - private async handleDifficultyChange(e: Event) { - this.selectedDiffculty = String( - (e.target as HTMLSelectElement).value, - ) as Difficulty; - consolex.log(`updating difficulty to ${this.selectedDiffculty}`); + private async handleDifficultySelection(value: Difficulty) { + this.selectedDifficulty = value; this.putGameConfig(); } @@ -282,7 +483,7 @@ export class HostLobbyModal extends LitElement { }, body: JSON.stringify({ gameMap: this.selectedMap, - difficulty: this.selectedDiffculty, + difficulty: this.selectedDifficulty, disableBots: this.disableBots, disableNPCs: this.disableNPCs, creativeMode: this.creativeMode, @@ -292,7 +493,7 @@ export class HostLobbyModal extends LitElement { private async startGame() { consolex.log( - `Starting private game with map: ${GameMapType[this.selectedMap]}`, + `Starting private game with map: ${GameMapType[this.selectedMap]}` ); this.close(); const response = await fetch(`/start_private_lobby/${this.lobbyId}`, { diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts index b2394a48e..9748d5fef 100644 --- a/src/client/InputHandler.ts +++ b/src/client/InputHandler.ts @@ -2,46 +2,31 @@ import { EventBus, GameEvent } from "../core/EventBus"; import { Game } from "../core/game/Game"; export class MouseUpEvent implements GameEvent { - constructor( - public readonly x: number, - public readonly y: number, - ) {} + constructor(public readonly x: number, public readonly y: number) {} } export class MouseDownEvent implements GameEvent { - constructor( - public readonly x: number, - public readonly y: number, - ) {} + constructor(public readonly x: number, public readonly y: number) {} } export class MouseMoveEvent implements GameEvent { - constructor( - public readonly x: number, - public readonly y: number, - ) {} + constructor(public readonly x: number, public readonly y: number) {} } export class ContextMenuEvent implements GameEvent { - constructor( - public readonly x: number, - public readonly y: number, - ) {} + constructor(public readonly x: number, public readonly y: number) {} } export class ZoomEvent implements GameEvent { constructor( public readonly x: number, public readonly y: number, - public readonly delta: number, + public readonly delta: number ) {} } export class DragEvent implements GameEvent { - constructor( - public readonly deltaX: number, - public readonly deltaY: number, - ) {} + constructor(public readonly deltaX: number, public readonly deltaY: number) {} } export class AlternateViewEvent implements GameEvent { @@ -51,10 +36,7 @@ export class AlternateViewEvent implements GameEvent { export class RefreshGraphicsEvent implements GameEvent {} export class ShowBuildMenuEvent implements GameEvent { - constructor( - public readonly x: number, - public readonly y: number, - ) {} + constructor(public readonly x: number, public readonly y: number) {} } export class InputHandler { @@ -72,10 +54,13 @@ export class InputHandler { private alternateView = false; - constructor( - private canvas: HTMLCanvasElement, - private eventBus: EventBus, - ) {} + private moveInterval: any = null; + private activeKeys = new Set(); + + private readonly PAN_SPEED = 5; + private readonly ZOOM_SPEED = 10; + + constructor(private canvas: HTMLCanvasElement, private eventBus: EventBus) {} initialize() { this.canvas.addEventListener("pointerdown", (e) => this.onPointerDown(e)); @@ -95,14 +80,67 @@ export class InputHandler { }); this.pointers.clear(); + // Initialize the combined movement interval + this.moveInterval = setInterval(() => { + let deltaX = 0; + let deltaY = 0; + + // Handle both WASD and arrow keys + if (this.activeKeys.has("KeyW") || this.activeKeys.has("ArrowUp")) + deltaY += this.PAN_SPEED; + if (this.activeKeys.has("KeyS") || this.activeKeys.has("ArrowDown")) + deltaY -= this.PAN_SPEED; + if (this.activeKeys.has("KeyA") || this.activeKeys.has("ArrowLeft")) + deltaX += this.PAN_SPEED; + if (this.activeKeys.has("KeyD") || this.activeKeys.has("ArrowRight")) + deltaX -= this.PAN_SPEED; + + if (deltaX !== 0 || deltaY !== 0) { + this.eventBus.emit(new DragEvent(deltaX, deltaY)); + } + + // Handle zooming + const screenCenterX = window.innerWidth / 2; + const screenCenterY = window.innerHeight / 2; + + if (this.activeKeys.has("Minus")) { + this.eventBus.emit( + new ZoomEvent(screenCenterX, screenCenterY, this.ZOOM_SPEED) + ); + } + if (this.activeKeys.has("Equal")) { + this.eventBus.emit( + new ZoomEvent(screenCenterX, screenCenterY, -this.ZOOM_SPEED) + ); + } + }, 1); + window.addEventListener("keydown", (e) => { if (e.code === "Space") { - e.preventDefault(); // Prevent page scrolling + e.preventDefault(); if (!this.alternateView) { this.alternateView = true; this.eventBus.emit(new AlternateViewEvent(true)); } } + + // Add all movement keys to activeKeys + if ( + [ + "KeyW", + "KeyA", + "KeyS", + "KeyD", + "ArrowUp", + "ArrowLeft", + "ArrowDown", + "ArrowRight", + "Minus", + "Equal", + ].includes(e.code) + ) { + this.activeKeys.add(e.code); + } }); window.addEventListener("keyup", (e) => { @@ -115,6 +153,24 @@ export class InputHandler { e.preventDefault(); this.eventBus.emit(new RefreshGraphicsEvent()); } + + // Remove all movement keys from activeKeys + if ( + [ + "KeyW", + "KeyA", + "KeyS", + "KeyD", + "ArrowUp", + "ArrowLeft", + "ArrowDown", + "ArrowRight", + "Minus", + "Equal", + ].includes(e.code) + ) { + this.activeKeys.delete(e.code); + } }); } @@ -193,10 +249,9 @@ export class InputHandler { const pinchDelta = currentPinchDistance - this.lastPinchDistance; if (Math.abs(pinchDelta) > 1) { - // Threshold to avoid tiny zoom adjustments const zoomCenter = this.getPinchCenter(); this.eventBus.emit( - new ZoomEvent(zoomCenter.x, zoomCenter.y, -pinchDelta * 2), + new ZoomEvent(zoomCenter.x, zoomCenter.y, -pinchDelta * 2) ); this.lastPinchDistance = currentPinchDistance; } @@ -222,4 +277,9 @@ export class InputHandler { y: (pointerEvents[0].clientY + pointerEvents[1].clientY) / 2, }; } + + destroy() { + clearInterval(this.moveInterval); + this.activeKeys.clear(); + } } diff --git a/src/client/JoinPrivateLobbyModal.ts b/src/client/JoinPrivateLobbyModal.ts index dede85d4e..09cfc6833 100644 --- a/src/client/JoinPrivateLobbyModal.ts +++ b/src/client/JoinPrivateLobbyModal.ts @@ -20,16 +20,58 @@ export class JoinPrivateLobbyModal extends LitElement { width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); + overflow-y: auto; + display: flex; + align-items: center; + justify-content: center; } .modal-content { - background-color: white; - margin: 15% auto; + background-color: rgb(35 35 35 / 0.8); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + color: white; padding: 20px; border-radius: 8px; width: 80%; max-width: 500px; + max-height: 80vh; + overflow-y: auto; text-align: center; + box-shadow: 0 0 40px rgba(0, 0, 0, 0.5); + border: 1px solid rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + position: relative; } + + /* Add custom scrollbar styles */ + .modal-content::-webkit-scrollbar { + width: 8px; + } + + .modal-content::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + } + + .modal-content::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 4px; + } + + .modal-content::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); + } + + .title { + font-size: 28px; + color: #fff; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + padding: 0 0 0 20px; + } + .close { color: #aaa; float: right; @@ -37,47 +79,41 @@ export class JoinPrivateLobbyModal extends LitElement { font-weight: bold; cursor: pointer; } + .close:hover, .close:focus { - color: black; + color: white; text-decoration: none; cursor: pointer; } - button { - padding: 10px 20px; + + .start-game-button { + width: 100%; + max-width: 300px; + padding: 15px 20px; font-size: 16px; cursor: pointer; background-color: #007bff; color: white; border: none; - border-radius: 4px; + border-radius: 8px; transition: background-color 0.3s; + display: inline-block; + margin: 0 0 20px 0; } - button:hover { + + .start-game-button:not(:disabled):hover { background-color: #0056b3; } - .lobby-id-container { - display: flex; - align-items: stretch; - justify-content: center; - gap: 10px; - margin: 20px 0; - } - .lobby-id-container input { - flex-grow: 1; - max-width: 200px; - padding: 10px; - font-size: 16px; - border: 1px solid #ccc; - border-radius: 4px; - } - .lobby-id-container button { - padding: 10px 15px; - } - .join-button { - margin-top: 10px; + + .start-game-button:disabled { + background: linear-gradient(to right, #4a4a4a, #3d3d3d); + opacity: 0.7; + cursor: not-allowed; } + /* JoinPrivateLobbyModal css */ + .message-area { margin-top: 10px; padding: 10px; @@ -104,26 +140,84 @@ export class JoinPrivateLobbyModal extends LitElement { background-color: #e8f5e9; color: #2e7d32; } + + .lobby-id-box { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin: 40px 0px 0px 0px; + } + .lobby-id-box input { + flex-grow: 1; + max-width: 200px; + padding: 10px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 8px; + } + + .lobby-id-paste-button { + display: flex; + align-items: center; + background: rgba(0, 0, 0, 0.2); + padding: 10px 16px; + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.1); + cursor: pointer; + transition: all 0.2s ease-in-out; + } + + .lobby-id-paste-button:hover { + background: rgba(0, 0, 0, 0.3); + border-color: rgba(255, 255, 255, 0.2); + transform: translateY(-1px); + } + + .lobby-id-paste-button-icon { + display: flex; + align-items: center; + justify-content: center; + color: #fff; + } `; render() { return html`