Skip to content

Commit dee9273

Browse files
committed
Add wiggle wiggle to portal
1 parent 1190a92 commit dee9273

File tree

3 files changed

+74
-12
lines changed

3 files changed

+74
-12
lines changed

src/lib/location.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ class Location<T extends Vector3> {
3030
*/
3131
static creator<V extends Vector3, L extends typeof Location<V>>(this: L) {
3232
/** @param group - Location group */
33-
return (place: Place, fallback?: V) => {
34-
const location = new this(place.group.id, place.shortId, place.group.dimensionType, fallback)
33+
return (place: Place, fallback?: V, floor = false) => {
34+
const location = new this(place.group.id, place.shortId, place.group.dimensionType, fallback, floor)
3535

36-
;(Settings.worldMap[place.group.id] ??= {})[place.shortId] = {
36+
const wm = (Settings.worldMap[place.group.id] ??= {})
37+
wm[place.shortId] = {
3738
name: place.name,
3839
description: location.format,
3940
value: fallback ? Object.values(fallback).join(' ').trim() : '',
@@ -42,6 +43,12 @@ class Location<T extends Vector3> {
4243

4344
location.load()
4445
location.firstLoad = true
46+
if (floor && !Vec.equals(location.location, Vec.zero)) {
47+
Settings.parseConfig(Settings.worldDatabase, place.group.id, wm)[place.shortId] = Vec.string(
48+
location.location,
49+
false,
50+
)
51+
}
4552

4653
return location.safe
4754
}
@@ -74,6 +81,7 @@ class Location<T extends Vector3> {
7481
protected name: string,
7582
readonly dimensionType: DimensionType,
7683
protected fallback?: T,
84+
protected readonly floor = false,
7785
) {}
7886

7987
private load(throws = false) {
@@ -90,15 +98,20 @@ class Location<T extends Vector3> {
9098
else return console.warn(error)
9199
}
92100

93-
for (const [i, key] of Object.keys(this.locationFormat).entries()) {
101+
const loc = Object.assign({}, this.locationFormat)
102+
for (const [i, key] of Object.keys(loc).entries()) {
94103
const n = input[i]
95104
if (typeof n === 'undefined') throw new TypeError(`I out of bounds: ${i}`)
96-
;(this.locationFormat[key as keyof T] as number) = n
105+
;(loc[key as keyof T] as number) = n
97106
}
98-
this.updateLocation(this.locationFormat)
107+
this.updateLocation(loc)
99108
}
100109

101110
private updateLocation(location: T) {
111+
if (this.floor) {
112+
const { x, y, z } = Vec.floor(location)
113+
location = { ...location, x, y, z }
114+
}
102115
this.location = location
103116
EventLoaderWithArg.load(this.onLoad, this.safe as ValidLocation<T>)
104117
this.firstLoad = false

src/lib/vector.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,38 @@ export class VecXZ {
8686
/** Z component of this vector. */
8787
public z: number,
8888
) {}
89+
90+
/** Returns the length of this vector. */
91+
length() {
92+
return Math.hypot(this.x, this.z)
93+
}
94+
95+
/** Returns this vector as a normalized vector. */
96+
normalized() {
97+
const magnitude = this.length()
98+
if (magnitude === 0) return this
99+
100+
const directionX = this.x / magnitude
101+
const directionZ = this.z / magnitude
102+
103+
return new VecXZ(directionX, directionZ)
104+
}
105+
106+
add(a: VectorXZ) {
107+
return VecXZ.add(this, a)
108+
}
109+
110+
substract(a: VectorXZ) {
111+
return VecXZ.subtract(this, a)
112+
}
113+
114+
multiply(a: number) {
115+
return VecXZ.multiply(this, a)
116+
}
117+
118+
multiplyVec(a: VectorXZ) {
119+
return VecXZ.multiplyVec(this, a)
120+
}
89121
}
90122

91123
export class Vec {

src/modules/places/lib/safe-place.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
locationWithRotation,
1111
Portal,
1212
SafeAreaRegion,
13+
Vec,
1314
Vector3Radius,
1415
} from 'lib'
1516
import { Sounds } from 'lib/assets/custom-sounds'
@@ -29,9 +30,9 @@ export class SafePlace {
2930

3031
portalTeleportsTo = locationWithRotation(this.group.place('portal teleports to').name('портал телепортирует на'))
3132

32-
private portalFrom = location(this.group.place('portal from').name('портал от'))
33+
private portalFrom = location(this.group.place('portal from').name('портал от'), undefined, true)
3334

34-
private portalTo = location(this.group.place('portal to').name('портал до'))
35+
private portalTo = location(this.group.place('portal to').name('портал до'), undefined, true)
3536

3637
safeArea?: SafeAreaRegion
3738

@@ -61,7 +62,9 @@ export class SafePlace {
6162
}
6263

6364
private createPortal(from: Vector3, to: Vector3) {
64-
new Portal(this.group.id, from, to, player => {
65+
const start = Vec.min(from, to)
66+
const end = Vec.max(from, to)
67+
new Portal(this.group.id, start, end, player => {
6568
if (!Portal.canTeleport(player)) return
6669

6770
player.database.unlockedPortals ??= []
@@ -70,7 +73,7 @@ export class SafePlace {
7073
player.database.unlockedPortals.push(this.groupId)
7174
}
7275

73-
portalMenuOnce(player, undefined, this.group)
76+
portalMenuOnce(player, undefined, this.group, start, end)
7477
})
7578
}
7679

@@ -110,7 +113,13 @@ system.delay(() => {
110113
}, ActionGuardOrder.Feature)
111114
})
112115

113-
const portalMenuOnce = debounceMenu(function portalMenu(player: Player, message?: MaybeRawText, group?: Group) {
116+
const portalMenuOnce = debounceMenu(function portalMenu(
117+
player: Player,
118+
message?: MaybeRawText,
119+
group?: Group,
120+
from?: Vector3,
121+
to?: Vector3,
122+
) {
114123
return new ArrayForm(
115124
'Перемещение...',
116125
SafePlace.places
@@ -120,7 +129,7 @@ const portalMenuOnce = debounceMenu(function portalMenu(player: Player, message?
120129
.description(message)
121130
.button(place => {
122131
const [name, , callback] = Product.create()
123-
.form(message => portalMenu(player, message))
132+
.form(message => portalMenu(player, message, group, from, to))
124133
.player(player)
125134
.name(place.group.name ?? 'Unknown')
126135
.cost(new MoneyCost(1000))
@@ -136,6 +145,14 @@ const portalMenuOnce = debounceMenu(function portalMenu(player: Player, message?
136145
return [name, callback]
137146
})
138147
.show(player)
148+
.then(success => {
149+
if (!success && from && to) {
150+
const direction = from.x === to.x ? 'x' : 'z'
151+
const distance = player.location[direction] - from[direction]
152+
player.applyKnockback({ x: 0, z: 0, [direction]: distance * 5 }, 0.5)
153+
}
154+
return success
155+
})
139156
})
140157

141158
new Command('portals')

0 commit comments

Comments
 (0)