Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

region visualization and misc QoL #145

Merged
merged 4 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions layout/pages/zoning/zoning.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@
<SettingsSlider text="#Zoning_GridSnapSize" class="zoning__slider" min="1" max="64" percentage="false" convar="mom_zone_grid" />
</Panel>
<Panel id="PropertyTabs" class="tabs">
<RadioButton group="ZoningRegion" class="tabs__tab" selected="true" onactivate="ZoneMenu.showRegionMenu('Points')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionPoints_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<RadioButton group="ZoningRegion" class="tabs__tab" value="Points" selected="true" onactivate="ZoneMenu.showRegionMenu('Points')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionPoints_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<Image src="file://{images}/vector-square-close.svg" class="tabs__icon" textureheight="48" />
</RadioButton>
<Panel class="tabs__gap" />
<RadioButton group="ZoningRegion" class="tabs__tab" onactivate="ZoneMenu.showRegionMenu('Properties')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionProperties_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<RadioButton group="ZoningRegion" class="tabs__tab" value="Properties" onactivate="ZoneMenu.showRegionMenu('Properties')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionProperties_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<Image src="file://{images}/list-box-outline.svg" class="tabs__icon" textureheight="48" />
</RadioButton>
<Panel class="tabs__gap" />
<RadioButton group="ZoningRegion" class="tabs__tab" onactivate="ZoneMenu.showRegionMenu('Teleport')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionTeleport_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<RadioButton group="ZoningRegion" class="tabs__tab" value="Teleport" onactivate="ZoneMenu.showRegionMenu('Teleport')" onmouseover="UiToolkitAPI.ShowTextTooltip('PropertyTabs', '#Zoning_RegionTeleport_Tooltip');" onmouseout="UiToolkitAPI.HideTextTooltip();">
<Image src="file://{images}/ray-start-arrow.svg" class="tabs__icon" textureheight="48" />
</RadioButton>
</Panel>
Expand Down
93 changes: 86 additions & 7 deletions scripts/pages/zoning/zoning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ const PickType = {
teleDestYaw: 'teleDestYaw'
};

const FLT_MAX = 3.402823466e38;
const DEFAULT_HEIGHT = 160;

class ZoneMenu {
static panels = {
zoningMenu: $.GetContextPanel(),
Expand All @@ -103,6 +106,7 @@ class ZoneMenu {
checkpointsOrdered: $('#CheckpointsOrdered')!.FindChild('CheckBox') as ToggleButton,
segmentName: $<TextEntry>('#SegmentName')!,
propertiesZone: $<Panel>('#ZoneProperties')!,
propertyTabs: $<Panel>('#PropertyTabs')!,
filterSelect: $<DropDown>('#FilterSelect')!,
volumeSelect: $<DropDown>('#VolumeSelect')!,
regionSelect: $<DropDown>('#RegionSelect')!,
Expand Down Expand Up @@ -130,7 +134,6 @@ class ZoneMenu {
zone: null as Zone | null
};
static mapZoneData: ZoneDef | null;
static backupZoneData: ZoneDef | null;
static filternameList: string[] | null;
static teleDestList: string[] | null;
static pointPick: string;
Expand Down Expand Up @@ -184,7 +187,7 @@ class ZoneMenu {
this.teleDestList.unshift($.Localize('#Zoning_TPDest_None')!);
this.populateDropdown(this.teleDestList, this.panels.regionTPDest, '', true);

this.showRegionMenu('Points');
this.showRegionMenu('reset');

this.createTrackEntry(this.panels.trackList, this.mapZoneData.tracks.main, 'Main');

Expand Down Expand Up @@ -356,8 +359,8 @@ class ZoneMenu {
static createRegion() {
return {
points: [] as number[][],
bottom: 0,
height: 0,
bottom: FLT_MAX,
height: DEFAULT_HEIGHT,
teleDestTargetname: ''
} as Region;
}
Expand Down Expand Up @@ -412,6 +415,7 @@ class ZoneMenu {
this.populateDropdown(zone.regions, this.panels.regionSelect, 'Region', true);
this.panels.regionSelect.SetSelectedIndex(0);
this.populateRegionProperties();
this.showRegionMenu('');
}

static populateSegmentProperties() {
Expand Down Expand Up @@ -439,6 +443,8 @@ class ZoneMenu {

const filterIndex = this.panels.filterSelect.GetSelected()?.GetAttributeInt('value', 0);
this.selectedZone.zone.filtername = filterIndex ? this.filternameList[filterIndex] : '';

this.updateZones();
}

static populateRegionProperties() {
Expand Down Expand Up @@ -469,6 +475,8 @@ class ZoneMenu {
this.populateDropdown(this.selectedZone.zone.regions, this.panels.regionSelect, 'Region', true);
this.panels.regionSelect.SetSelectedIndex(this.selectedZone.zone.regions.length - 1);
this.populateRegionProperties();

this.updateZones();
}

static deleteRegion() {
Expand All @@ -480,19 +488,25 @@ class ZoneMenu {
this.selectedZone.zone?.regions.splice(index, 1);
this.panels.regionSelect.SetSelectedIndex(0);
this.populateRegionProperties();

this.updateZones();
}

static pickCorners() {
if (!this.selectedZone || !this.selectedZone.zone) return;

this.pointPick = PickType.corner;
const index = this.panels.regionSelect.GetSelected().GetAttributeInt('value', -1);
const region = this.selectedZone.zone.regions[index];
if (GameInterfaceAPI.GetSettingBool('mom_zone_two_click')) {
const index = this.panels.regionSelect.GetSelected().GetAttributeInt('value', -1);
this.selectedZone.zone.regions[index].points.length = 0;
region.points.length = 0;
this.panels.pointsList.RemoveAndDeleteChildren();
}
//@ts-expect-error function name
this.panels.zoningMenu.startPointPick(true);

//@ts-expect-error function name
this.panels.zoningMenu.setCornersFromRegion(region);
}

static addPointToList(i: number, point: number[]) {
Expand All @@ -513,6 +527,8 @@ class ZoneMenu {
const index = this.panels.regionSelect.GetSelected().GetAttributeInt('value', -1);
this.selectedZone.zone?.regions[index].points.splice(n, 1);
point.DeleteAsync(0);

this.updateZones();
}

static pickBottom() {
Expand All @@ -528,6 +544,8 @@ class ZoneMenu {
const region = this.selectedZone.zone.regions[regionIndex];
const bottom = Number.parseFloat(this.panels.regionBottom.text);
region.bottom = Number.isNaN(bottom) ? 0 : bottom;

this.updateZones();
}

static pickHeight() {
Expand All @@ -543,6 +561,8 @@ class ZoneMenu {
const region = this.selectedZone.zone.regions[regionIndex];
const height = Number.parseFloat(this.panels.regionHeight.text);
region.height = Number.isNaN(height) ? 0 : height;

this.updateZones();
}

static pickSafeHeight() {
Expand All @@ -558,6 +578,8 @@ class ZoneMenu {
const region = this.selectedZone.zone.regions[regionIndex];
const height = Number.parseFloat(this.panels.regionSafeHeight.text);
region.safeHeight = Number.isNaN(height) ? 0 : height;

this.updateZones();
}

static pickTeleDestPos() {
Expand Down Expand Up @@ -621,6 +643,8 @@ class ZoneMenu {
this.panels.regionTPYaw.text = '';
this.setRegionTPDestTextEntriesActive(false);
}

this.updateZones();
}

static setRegionTeleDestOrientation() {
Expand All @@ -635,6 +659,8 @@ class ZoneMenu {

region.teleDestPos = [Number.isNaN(x) ? 0 : x, Number.isNaN(y) ? 0 : y, Number.isNaN(z) ? 0 : z];
region.teleDestYaw = Number.isNaN(yaw) ? 0 : yaw;

this.updateZones();
}

static setRegionTPDestTextEntriesActive(enable: boolean) {
Expand All @@ -657,6 +683,10 @@ class ZoneMenu {
return;

case PickType.corner:
if (point.z < region.bottom) {
region.bottom = point.z;
this.panels.regionBottom.text = point.z.toFixed(2);
}
if (GameInterfaceAPI.GetSettingBool('mom_zone_two_click') && region.points.length === 1) {
region.points.push([region.points[0][0], point.y]);
this.addPointToList(region.points.length - 1, [region.points[0][0], point.y]);
Expand Down Expand Up @@ -696,10 +726,14 @@ class ZoneMenu {
this.panels.regionTPYaw.text = region.teleDestYaw.toFixed(2);
break;
}

this.updateZones();
}

static onPickCanceled() {
this.pointPick = PickType.none;

this.updateZones();
}

static addBonus() {
Expand All @@ -716,6 +750,8 @@ class ZoneMenu {
bonus,
`${$.Localize('#Zoning_Bonus')!} ${this.mapZoneData.tracks.bonuses.length}`
);

this.updateZones();
}

static addSegment() {
Expand Down Expand Up @@ -745,6 +781,8 @@ class ZoneMenu {
segment: newSegment,
zone: newSegment.checkpoints[0]
});

this.updateZones();
}

static addCheckpoint() {
Expand Down Expand Up @@ -773,6 +811,8 @@ class ZoneMenu {
segment: this.selectedZone.segment,
zone: newZone
});

this.updateZones();
}

static addEndZone() {
Expand Down Expand Up @@ -805,6 +845,8 @@ class ZoneMenu {
zone: endZone
});
}

this.updateZones();
}

static addCancelZone() {
Expand Down Expand Up @@ -837,6 +879,8 @@ class ZoneMenu {
segment: this.selectedZone.segment,
zone: newZone
});

this.updateZones();
}

static showAddMenu() {
Expand Down Expand Up @@ -909,17 +953,23 @@ class ZoneMenu {
//hack: this can be a little more surgical
this.panels.trackList.RemoveAndDeleteChildren();
this.initMenu();

this.updateZones();
}

static setMaxVelocity() {
if (!this.mapZoneData) return;
const velocity = Number.parseFloat(this.panels.maxVelocity.text);
this.mapZoneData.maxVelocity = !Number.isNaN(velocity) && velocity > 0 ? velocity : 0;

this.updateZones();
}

static setStageEndAtStageStarts() {
if (!this.isSelectionValid().track || !('stagesEndAtStageStarts' in this.selectedZone.track!)) return;
this.selectedZone.track.stagesEndAtStageStarts = this.panels.stagesEndAtStageStarts.checked;

this.updateZones();
}

static showDefragFlagMenu() {
Expand Down Expand Up @@ -975,47 +1025,76 @@ class ZoneMenu {
const trackPanel = this.panels.trackList.GetChild(1 + bonusIndex)!;
trackPanel.FindChildTraverse('CollapseButton')!.visible = false;
trackPanel.FindChildTraverse('ChildContainer')!.RemoveAndDeleteChildren();

this.updateZones();
}

static setLimitGroundSpeed() {
if (!this.isSelectionValid().segment) return;
this.selectedZone.segment!.limitStartGroundSpeed = this.panels.limitGroundSpeed.checked;

this.updateZones();
}

static setCheckpointsOrdered() {
if (!this.isSelectionValid().segment) return;
this.selectedZone.segment!.checkpointsOrdered = this.panels.checkpointsOrdered.checked;

this.updateZones();
}

static setCheckpointsRequired() {
if (!this.isSelectionValid().segment) return;
this.selectedZone.segment!.checkpointsRequired = this.panels.checkpointsRequired.checked;

this.updateZones();
}

static setSegmentName() {
if (!this.isSelectionValid().segment) return;
this.selectedZone.segment!.name = this.panels.segmentName.text;
// feat: later
// update segment name in trasklist tree

this.updateZones();
}

static showRegionMenu(menu: string) {
const pointsTab = this.panels.propertyTabs.GetChild(0) as RadioButton;
if (menu === 'reset') {
pointsTab.SetSelected(true);
}
menu = menu || pointsTab.GetSelectedButton().GetAttributeString('value', 'Points');

this.panels.pointsSection.visible = menu === 'Points';
this.panels.propertiesSection.visible = menu === 'Properties';
this.panels.teleportSection.visible = menu === 'Teleport';
}

static updateZones() {
if (!this.mapZoneData) return;

//future: validation here

this.mapZoneData.dataTimestamp = Date.now();
//@ts-expect-error API name not recognized
MomentumTimerAPI.SetActiveZoneDefs(this.mapZoneData);
}

static saveZones() {
if (!this.mapZoneData) return;
this.mapZoneData.dataTimestamp = Date.now();
//@ts-expect-error API name not recognized
MomentumTimerAPI.SaveZoneDefs(this.mapZoneData);
// reload zones
}

static cancelEdit() {
this.panels.trackList.RemoveAndDeleteChildren();
this.mapZoneData = null;

//@ts-expect-error API name not recognized
MomentumTimerAPI.LoadZoneDefs();

this.initMenu();
}

Expand Down
Loading