diff --git a/images/adjust.svg b/images/adjust.svg new file mode 100644 index 00000000..64ae74f4 --- /dev/null +++ b/images/adjust.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/close-box-outline.svg b/images/close-box-outline.svg new file mode 100644 index 00000000..e052af7a --- /dev/null +++ b/images/close-box-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/list-box-outline.svg b/images/list-box-outline.svg new file mode 100644 index 00000000..2dcd8c9c --- /dev/null +++ b/images/list-box-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/pencil-off-outline.svg b/images/pencil-off-outline.svg new file mode 100644 index 00000000..d42b413f --- /dev/null +++ b/images/pencil-off-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/pencil-outline.svg b/images/pencil-outline.svg new file mode 100644 index 00000000..c184d5ef --- /dev/null +++ b/images/pencil-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/ray-start-arrow.svg b/images/ray-start-arrow.svg new file mode 100644 index 00000000..26170e89 --- /dev/null +++ b/images/ray-start-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/vector-square-close.svg b/images/vector-square-close.svg new file mode 100644 index 00000000..77d8cdd0 --- /dev/null +++ b/images/vector-square-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/hud/tab-menu.xml b/layout/hud/tab-menu.xml index de26117b..7a2eb3aa 100644 --- a/layout/hud/tab-menu.xml +++ b/layout/hud/tab-menu.xml @@ -52,13 +52,19 @@ - + + + diff --git a/layout/modals/context-menus/zoning-df-flags.xml b/layout/modals/context-menus/zoning-df-flags.xml new file mode 100644 index 00000000..e47fb670 --- /dev/null +++ b/layout/modals/context-menus/zoning-df-flags.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/layout/pages/zoning/zoning.xml b/layout/pages/zoning/zoning.xml index 9fa54cee..6bfdbf3d 100644 --- a/layout/pages/zoning/zoning.xml +++ b/layout/pages/zoning/zoning.xml @@ -1,3 +1,243 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/hud/tab-menu.js b/scripts/hud/tab-menu.js index a513c205..bb41b164 100644 --- a/scripts/hud/tab-menu.js +++ b/scripts/hud/tab-menu.js @@ -9,6 +9,12 @@ class HudTabMenu { leaderboardsContainer: $('#LeaderboardsContainer'), /** @type {Panel} @static */ endOfRunContainer: $('#EndOfRunContainer'), + /** @type {Panel} @static */ + zoningContainer: $('#ZoningContainer'), + /** @type {Panel} @static */ + zoningOpenButton: $('#ZoningOpen'), + /** @type {Panel} @static */ + zoningCloseButton: $('#ZoningClose'), /** @type {Image} @static */ gamemodeImage: $('#HudTabMenuGamemodeImage'), /** @type {Panel} @static */ @@ -20,16 +26,40 @@ class HudTabMenu { $.RegisterForUnhandledEvent('HudTabMenu_ForceClose', this.close.bind(this)); $.RegisterForUnhandledEvent('EndOfRun_Show', this.showEndOfRun.bind(this)); $.RegisterForUnhandledEvent('EndOfRun_Hide', this.hideEndOfRun.bind(this)); + $.RegisterForUnhandledEvent('ZoneMenu_Show', this.showZoneMenu.bind(this)); + $.RegisterForUnhandledEvent('ZoneMenu_Hide', this.hideZoneMenu.bind(this)); } static showEndOfRun(_showReason) { this.panels.leaderboardsContainer.AddClass('hud-tab-menu__leaderboards--hidden'); this.panels.endOfRunContainer.RemoveClass('hud-tab-menu__endofrun--hidden'); + this.panels.zoningContainer.AddClass('hud-tab-menu__zoning--hidden'); } static hideEndOfRun() { this.panels.leaderboardsContainer.RemoveClass('hud-tab-menu__leaderboards--hidden'); this.panels.endOfRunContainer.AddClass('hud-tab-menu__endofrun--hidden'); + this.panels.zoningContainer.AddClass('hud-tab-menu__zoning--hidden'); + } + + static showZoneMenu() { + this.panels.tabMenu.AddClass('hud-tab-menu--offset'); + this.panels.leaderboardsContainer.AddClass('hud-tab-menu__leaderboards--hidden'); + this.panels.endOfRunContainer.AddClass('hud-tab-menu__endofrun--hidden'); + + this.panels.zoningContainer.RemoveClass('hud-tab-menu__zoning--hidden'); + this.panels.zoningOpenButton.AddClass('hud-tab-menu__zoning--hidden'); + this.panels.zoningCloseButton.RemoveClass('hud-tab-menu__zoning--hidden'); + } + + static hideZoneMenu() { + this.panels.tabMenu.RemoveClass('hud-tab-menu--offset'); + this.panels.leaderboardsContainer.RemoveClass('hud-tab-menu__leaderboards--hidden'); + this.panels.endOfRunContainer.AddClass('hud-tab-menu__endofrun--hidden'); + + this.panels.zoningContainer.AddClass('hud-tab-menu__zoning--hidden'); + this.panels.zoningOpenButton.RemoveClass('hud-tab-menu__zoning--hidden'); + this.panels.zoningCloseButton.AddClass('hud-tab-menu__zoning--hidden'); } static setMapData(isOfficial) { diff --git a/scripts/pages/zoning/zoning.ts b/scripts/pages/zoning/zoning.ts new file mode 100644 index 00000000..ff0e3da8 --- /dev/null +++ b/scripts/pages/zoning/zoning.ts @@ -0,0 +1,999 @@ +/***************************************************************************************** */ + +interface Region extends JsonObject { + points: number[][]; + bottom: number; + height: number; + teleDestTargetname: string; // mutually exclusive to other two teleport fields + teleDestPos: number[]; // TODO: This below are required if region is part of a volume used by stafe or major checkpoint zone + teleDestYaw: number; // See convo in mom red 25/09/23 02:00 GMT + safeHeight: number; +} + +interface Zone extends JsonObject { + regions: Region[]; + filtername: string; +} + +interface Segment extends JsonObject { + limitStartGroundSpeed: boolean; + checkpointsRequired: boolean; + checkpointsOrdered: boolean; + checkpoints: Zone[]; + cancel: Zone[]; + name: string; +} + +interface TrackZones extends JsonObject { + segments: Segment[]; + end: Zone; +} + +interface MainTrack extends JsonObject { + zones: TrackZones; + stagesEndAtStageStarts: boolean; +} + +interface BonusTrack extends JsonObject { + zones: TrackZones; + defragFlags: number; +} + +interface MapTracks extends JsonObject { + main: MainTrack; + bonuses: BonusTrack[]; +} + +interface ZoneDef extends JsonObject { + formatVersion: number; + dataTimestamp: number; + maxVelocity: number; + tracks: MapTracks; +} + +interface EntityList { + filter: string[]; + teleport: string[]; +} +/**************************************************************************************************************/ + +/** + * Zoning UI logic + */ + +const TracklistSnippet = { + TRACK: 'tracklist-track', + SEGMENT: 'tracklist-segment', + CHECKPOINT: 'tracklist-checkpoint' +}; + +const DefragFlags = { + HASTE: 1 << 0, + SLICK: 1 << 1, + DAMAGEBOOST: 1 << 2, + ROCKETS: 1 << 3, + PLASMA: 1 << 4, + BFG: 1 << 5 +}; + +// future: get this from c++ +const FORMAT_VERSION = 1; + +const PickType = { + none: '""', + corner: 'corner', + bottom: 'bottom', + height: 'height', + safeHeight: 'safe height', + teleDestPos: 'teleDestPos', + teleDestYaw: 'teleDestYaw' +}; + +class ZoneMenu { + static panels = { + zoningMenu: $.GetContextPanel(), + trackList: $('#TrackList')!, + propertiesTrack: $('#TrackProperties')!, + maxVelocity: $('#MaxVelocity')!, + defragFlags: $('#DefragFlags')!, + stagesEndAtStageStarts: $('#StagesEndAtStageStarts')!.FindChild('CheckBox') as ToggleButton, + propertiesSegment: $('#SegmentProperties')!, + limitGroundSpeed: $('#LimitGroundSpeed')!.FindChild('CheckBox') as ToggleButton, + checkpointsRequired: $('#CheckpointsRequired')!.FindChild('CheckBox') as ToggleButton, + checkpointsOrdered: $('#CheckpointsOrdered')!.FindChild('CheckBox') as ToggleButton, + segmentName: $('#SegmentName')!, + propertiesZone: $('#ZoneProperties')!, + filterSelect: $('#FilterSelect')!, + volumeSelect: $('#VolumeSelect')!, + regionSelect: $('#RegionSelect')!, + pointsSection: $('#PointsSection')!, + pointsList: $('#PointsList')!, + propertiesSection: $('#PropertiesSection')!, + teleportSection: $('#TeleportSection')!, + regionBottom: $('#RegionBottom')!, + regionHeight: $('#RegionHeight')!, + regionSafeHeight: $('#RegionSafeHeight')!, + regionTPDest: $('#RegionTPDest')!, + regionTPPos: { + x: $('#TeleX')!, + y: $('#TeleY')!, + z: $('#TeleZ')! + }, + regionTPPosPick: $