fix castingVision giving vision to neutrals
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 95 B After Width: | Height: | Size: 95 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 543 B |
Binary file not shown.
|
After Width: | Height: | Size: 95 B |
Binary file not shown.
|
After Width: | Height: | Size: 95 B |
+51
-42
@@ -36,6 +36,8 @@ const teamMaterials = {
|
|||||||
redTransparent: new THREE.MeshToonMaterial({ color: 0xff4444, transparent: true, opacity }),
|
redTransparent: new THREE.MeshToonMaterial({ color: 0xff4444, transparent: true, opacity }),
|
||||||
projectile: new THREE.MeshToonMaterial({ color: 0xff00ff, transparent: true, opacity }),
|
projectile: new THREE.MeshToonMaterial({ color: 0xff00ff, transparent: true, opacity }),
|
||||||
range: new THREE.MeshToonMaterial({ color: 0x00ffff, transparent: true, opacity: opacity / 2 }),
|
range: new THREE.MeshToonMaterial({ color: 0x00ffff, transparent: true, opacity: opacity / 2 }),
|
||||||
|
visionRange: new THREE.MeshToonMaterial({ color: 0x226022 }),
|
||||||
|
// visionRange: new THREE.MeshToonMaterial({ color: 0x00ffff, transparent: true, opacity: opacity / 6 }),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: draw lines of path for minimap camera
|
// TODO: draw lines of path for minimap camera
|
||||||
@@ -70,9 +72,9 @@ const preloadGLTF = function loadTemplate(path) {
|
|||||||
gltfLoader.load(path, (loadedGLTF) => gltf[path] = loadedGLTF)
|
gltfLoader.load(path, (loadedGLTF) => gltf[path] = loadedGLTF)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addGLTF = function addGLTF(scene, path, id) {
|
const addGLTF = function addGLTF(scene, path, id, additionalSteps = function noAdditionalSteps() {}) {
|
||||||
if (gltf[path] == null) {
|
if (gltf[path] == null) {
|
||||||
setTimeout(() => addGLTF(scene, path, id), 200)
|
setTimeout(() => addGLTF(scene, path, id, additionalSteps), 200)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +91,7 @@ const addGLTF = function addGLTF(scene, path, id) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
model.scale.set(scale, scale, scale)
|
model.scale.set(scale, scale, scale)
|
||||||
|
additionalSteps(model)
|
||||||
scene.add(model)
|
scene.add(model)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +211,7 @@ var websocket = null
|
|||||||
global.websocket = null
|
global.websocket = null
|
||||||
var timerId = null
|
var timerId = null
|
||||||
var playerId = null
|
var playerId = null
|
||||||
|
var playerTeam = null
|
||||||
|
|
||||||
function connectWebSocket() {
|
function connectWebSocket() {
|
||||||
websocket = new WebSocket(`ws://${window.location.hostname}:1280/ws`)
|
websocket = new WebSocket(`ws://${window.location.hostname}:1280/ws`)
|
||||||
@@ -236,6 +240,11 @@ function connectWebSocket() {
|
|||||||
tweenDuration = 1000 / stateUpdates.tickRate
|
tweenDuration = 1000 / stateUpdates.tickRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateUpdates.width != null && stateUpdates.height != null && stateUpdates.width != (state.width ?? -1) && stateUpdates.height != (state.height ?? -1) ) {
|
||||||
|
ground.geometry = new THREE.PlaneGeometry(stateUpdates.width / 100, stateUpdates.height / 100)
|
||||||
|
ground.position.set(stateUpdates.width / 200, stateUpdates.height / 200, 0)
|
||||||
|
}
|
||||||
|
|
||||||
if (stateUpdates.width != null && stateUpdates.height != null) {
|
if (stateUpdates.width != null && stateUpdates.height != null) {
|
||||||
state.width = stateUpdates.width
|
state.width = stateUpdates.width
|
||||||
state.height = stateUpdates.height
|
state.height = stateUpdates.height
|
||||||
@@ -317,17 +326,18 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.width != null && state.height != null && (ground.geometry.attributes.width != state.width || ground.geometry.attributes.height != state.height)) {
|
|
||||||
ground.geometry = new THREE.PlaneGeometry(state.width / 100, state.height / 100)
|
|
||||||
ground.position.set(state.width / 200, state.height / 200, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const e of Object.values(entities)) {
|
for (const e of Object.values(entities)) {
|
||||||
e.userData.flaggedForRemoval = true
|
e.userData.flaggedForRemoval = true
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const e of state.entities ?? []) {
|
for (const e of state.entities ?? []) {
|
||||||
let entity
|
let entity
|
||||||
|
let created = false
|
||||||
|
|
||||||
|
if (e.id == playerId && playerTeam != e.team) {
|
||||||
|
playerTeam = e.team
|
||||||
|
}
|
||||||
|
|
||||||
if (e.id in entities) {
|
if (e.id in entities) {
|
||||||
entity = entities[e.id]
|
entity = entities[e.id]
|
||||||
}
|
}
|
||||||
@@ -335,17 +345,19 @@ function connectWebSocket() {
|
|||||||
// const entityMaterial = teamMaterials[e.team]
|
// const entityMaterial = teamMaterials[e.team]
|
||||||
// entity = new THREE.Mesh(new THREE.CylinderGeometry(e.visualRadius / 100, e.visualRadius / 100, e.height / 50), entityMaterial)
|
// entity = new THREE.Mesh(new THREE.CylinderGeometry(e.visualRadius / 100, e.visualRadius / 100, e.height / 50), entityMaterial)
|
||||||
// TODO: change entity material
|
// TODO: change entity material
|
||||||
|
created = true
|
||||||
|
|
||||||
entity = new THREE.Group()
|
entity = new THREE.Group()
|
||||||
entity.rotation.x = Math.PI / 2
|
entity.rotation.x = Math.PI / 2
|
||||||
entity.scale.set(e.visualRadius / 100, e.height / 100, e.visualRadius / 100)
|
entity.scale.set(e.visualRadius / 100, e.visualRadius / 100, e.visualRadius / 100)
|
||||||
entity.userData.type = 'entity'
|
entity.userData.type = 'entity'
|
||||||
entity.userData.id = e.id
|
entity.userData.id = e.id
|
||||||
entity.position.set(e.position.x / 100, e.position.y / 100, 0)
|
entity.position.set(e.position.x / 100, e.position.y / 100, 0)
|
||||||
scene.add(entity)
|
scene.add(entity)
|
||||||
|
|
||||||
const hpMargin = 4.8
|
const hpMargin = 0.5
|
||||||
const maxHp = new THREE.Sprite(new THREE.SpriteMaterial({ color: 0xd03333 }))
|
const maxHp = new THREE.Sprite(new THREE.SpriteMaterial({ color: 0xd03333 }))
|
||||||
maxHp.position.set(0, hpMargin, 0)
|
maxHp.position.set(0, 0, 0)
|
||||||
maxHp.scale.set(1.5, 0.2, 1)
|
maxHp.scale.set(1.5, 0.2, 1)
|
||||||
maxHp.layers.set(1)
|
maxHp.layers.set(1)
|
||||||
entity.add(maxHp)
|
entity.add(maxHp)
|
||||||
@@ -358,36 +370,20 @@ function connectWebSocket() {
|
|||||||
|
|
||||||
const teamMaterial = teamMaterials[`${e.team}Transparent`]
|
const teamMaterial = teamMaterials[`${e.team}Transparent`]
|
||||||
const teamMarker = new THREE.Mesh(new THREE.CylinderGeometry(1, 0.00001, 1), teamMaterial)
|
const teamMarker = new THREE.Mesh(new THREE.CylinderGeometry(1, 0.00001, 1), teamMaterial)
|
||||||
teamMarker.position.y = -0.496
|
teamMarker.position.y = -0.493
|
||||||
entity.add(teamMarker)
|
entity.add(teamMarker)
|
||||||
|
|
||||||
const buffMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, transparent: true, opacity: 0.4 })
|
const buffMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, transparent: true, opacity: 0.4 })
|
||||||
const buffMarkerRadius = 0.6
|
const buffMarker = new THREE.Mesh(new THREE.TorusGeometry(0.95, 0.15), buffMaterial)
|
||||||
const buffMarker = new THREE.Mesh(new THREE.CylinderGeometry(buffMarkerRadius, buffMarkerRadius, 0.3), buffMaterial)
|
buffMarker.rotation.x = Math.PI / 2
|
||||||
buffMarker.position.y = 2
|
|
||||||
buffMarker.layers.set(1)
|
buffMarker.layers.set(1)
|
||||||
buffMarker.visible = false
|
buffMarker.visible = false
|
||||||
entity.add(buffMarker)
|
entity.add(buffMarker)
|
||||||
|
|
||||||
const castingMarkerrotationBase = new THREE.Group()
|
|
||||||
entity.add(castingMarkerrotationBase)
|
|
||||||
|
|
||||||
const castingMaterial = new THREE.MeshToonMaterial({ color: 0x10dde0, transparent: true, opacity: 0.4 })
|
|
||||||
const castingMarker = new THREE.Mesh(new THREE.CylinderGeometry((e.height * 0.9) / 100, (e.height * 0.9) / 100, 1), castingMaterial)
|
|
||||||
const castingMarkerSize = 800
|
|
||||||
castingMarker.rotation.z = Math.PI / 2
|
|
||||||
castingMarker.position.x = 1
|
|
||||||
castingMarker.position.y = 1
|
|
||||||
castingMarker.scale.y = e.height / castingMarkerSize
|
|
||||||
castingMarker.layers.set(1)
|
|
||||||
castingMarker.visible = false
|
|
||||||
castingMarkerrotationBase.add(castingMarker)
|
|
||||||
|
|
||||||
const rangeMaterial = teamMaterials['range']
|
const rangeMaterial = teamMaterials['range']
|
||||||
// const rangeSize = e.visionRange ?? 0
|
|
||||||
const rangeSize = (state.abilities.find((it) => it.id == e.abilities?.a)?.range ?? 0) + e.radius
|
const rangeSize = (state.abilities.find((it) => it.id == e.abilities?.a)?.range ?? 0) + e.radius
|
||||||
const rangeMarker = new THREE.Mesh(new THREE.CylinderGeometry(rangeSize / e.visualRadius, rangeSize / e.visualRadius, 0.001), rangeMaterial)
|
const rangeMarker = new THREE.Mesh(new THREE.CylinderGeometry(rangeSize / e.visualRadius, rangeSize / e.visualRadius, 0.001), rangeMaterial)
|
||||||
rangeMarker.position.y = 0.002
|
rangeMarker.position.y = 0.004
|
||||||
rangeMarker.layers.set(1)
|
rangeMarker.layers.set(1)
|
||||||
rangeMarker.visible = false
|
rangeMarker.visible = false
|
||||||
entity.add(rangeMarker)
|
entity.add(rangeMarker)
|
||||||
@@ -397,10 +393,22 @@ function connectWebSocket() {
|
|||||||
modelRotationBase.layers.set(1)
|
modelRotationBase.layers.set(1)
|
||||||
entity.add(modelRotationBase)
|
entity.add(modelRotationBase)
|
||||||
|
|
||||||
addGLTF(modelRotationBase, 'models/generic-player-placeholder.gltf', e.id)
|
const visionRangeMaterial = teamMaterials['visionRange']
|
||||||
const animations = animationActions[e.id] ?? {}
|
const visionRangeSize = e.visionRange ?? 0
|
||||||
if (e.dead) {
|
const visionRangeMarker = new THREE.Mesh(new THREE.CylinderGeometry(visionRangeSize / e.visualRadius, visionRangeSize / e.visualRadius, 0.001), visionRangeMaterial)
|
||||||
animations.dead?.reset().play()
|
visionRangeMarker.position.y = 0.002
|
||||||
|
visionRangeMarker.layers.set(1)
|
||||||
|
visionRangeMarker.visible = false
|
||||||
|
entity.add(visionRangeMarker)
|
||||||
|
|
||||||
|
if (e.model != null) {
|
||||||
|
addGLTF(modelRotationBase, e.model, e.id, function(model) {
|
||||||
|
const box = new THREE.Box3().setFromObject(model)
|
||||||
|
const size = box.getSize(new THREE.Vector3())
|
||||||
|
maxHp.position.set(0, size.y + hpMargin, 0)
|
||||||
|
buffMarker.position.y = size.y / 2
|
||||||
|
buffMarker.scale.z = size.y / 10
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
entities[e.id] = entity
|
entities[e.id] = entity
|
||||||
@@ -411,7 +419,7 @@ function connectWebSocket() {
|
|||||||
entity.children.at(2).visible = e.buffs.some((it) => it.id == 'exposed') // TODO: only works for Exposed now
|
entity.children.at(2).visible = e.buffs.some((it) => it.id == 'exposed') // TODO: only works for Exposed now
|
||||||
|
|
||||||
const animations = animationActions[e.id] ?? {}
|
const animations = animationActions[e.id] ?? {}
|
||||||
const fadeIn = 0.15
|
const fadeIn = created ? 0 : 0.15
|
||||||
|
|
||||||
if (e.dead) {
|
if (e.dead) {
|
||||||
if (!animations.dead?.isRunning()) {
|
if (!animations.dead?.isRunning()) {
|
||||||
@@ -433,26 +441,25 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
entity.userData.flaggedForRemoval = false
|
entity.userData.flaggedForRemoval = false
|
||||||
entity.children.at(3).rotation.y = e.rotation
|
const oldRotationY = entity.children.at(4).rotation.y
|
||||||
const oldRotationY = entity.children.at(5).rotation.y
|
|
||||||
const newRotationY = e.rotation - (Math.PI / 2)
|
const newRotationY = e.rotation - (Math.PI / 2)
|
||||||
if (Math.abs((oldRotationY - (2 * Math.PI)) - newRotationY) < Math.abs(oldRotationY - newRotationY)) {
|
if (Math.abs((oldRotationY - (2 * Math.PI)) - newRotationY) < Math.abs(oldRotationY - newRotationY)) {
|
||||||
entity.children.at(5).rotation.y = oldRotationY - (2 * Math.PI)
|
entity.children.at(4).rotation.y = oldRotationY - (2 * Math.PI)
|
||||||
}
|
}
|
||||||
if (Math.abs((oldRotationY + (2 * Math.PI)) - newRotationY) < Math.abs(oldRotationY - newRotationY)) {
|
if (Math.abs((oldRotationY + (2 * Math.PI)) - newRotationY) < Math.abs(oldRotationY - newRotationY)) {
|
||||||
entity.children.at(5).rotation.y = oldRotationY + (2 * Math.PI)
|
entity.children.at(4).rotation.y = oldRotationY + (2 * Math.PI)
|
||||||
}
|
}
|
||||||
|
|
||||||
positionTweens[entity.id] = new Tween(entity.position).to({ x: e.position.x / 100, y: e.position.y / 100, z: 0 }, tweenDuration).start()
|
positionTweens[entity.id] = new Tween(entity.position).to({ x: e.position.x / 100, y: e.position.y / 100, z: 0 }, tweenDuration).start()
|
||||||
rotationTweens[entity.id] = new Tween(entity.children.at(5).rotation).to({ x: 0, y: newRotationY, z: 0 }, tweenDuration).start()
|
rotationTweens[entity.id] = new Tween(entity.children.at(4).rotation).to({ x: 0, y: newRotationY, z: 0 }, tweenDuration).start()
|
||||||
|
|
||||||
const hp = entity.children.at(0).children.at(0)
|
const hp = entity.children.at(0).children.at(0)
|
||||||
const percentageHp = e.health / e.maxHealth
|
const percentageHp = e.health / e.maxHealth
|
||||||
hp.scale.x = percentageHp
|
hp.scale.x = percentageHp
|
||||||
hp.position.x = -(1 - percentageHp) / 2
|
hp.position.x = -(1 - percentageHp) / 2
|
||||||
|
|
||||||
entity.children.at(4).visible = e.id == playerId
|
entity.children.at(3).visible = e.id == playerId
|
||||||
// entity.children.at(3).children.at(0).visible = e.casting != null
|
// entity.children.at(5).visible = !e.dead && e.team == playerTeam
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const e of Object.values(entities)) {
|
for (const e of Object.values(entities)) {
|
||||||
@@ -613,7 +620,9 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
|
preloadGLTF('models/generic-bam-placeholder.gltf')
|
||||||
preloadGLTF('models/generic-player-placeholder.gltf')
|
preloadGLTF('models/generic-player-placeholder.gltf')
|
||||||
|
preloadGLTF('models/generic-player-placeholder-red.gltf')
|
||||||
|
|
||||||
const params = Object.fromEntries(new URLSearchParams(window.location.search).entries())
|
const params = Object.fromEntries(new URLSearchParams(window.location.search).entries())
|
||||||
playerId = params.id
|
playerId = params.id
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export default class Entity {
|
|||||||
health = null
|
health = null
|
||||||
height = null
|
height = null
|
||||||
maxHealth = 1
|
maxHealth = 1
|
||||||
|
model = null
|
||||||
position = null
|
position = null
|
||||||
radius = 0
|
radius = 0
|
||||||
rotation = 0
|
rotation = 0
|
||||||
@@ -681,6 +682,7 @@ export default class Entity {
|
|||||||
owner: this.id,
|
owner: this.id,
|
||||||
position: this.position.clone(),
|
position: this.position.clone(),
|
||||||
visionRange: radius,
|
visionRange: radius,
|
||||||
|
team: enemyTeam,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.game?.spawnProjectile(projectile)
|
this.game?.spawnProjectile(projectile)
|
||||||
|
|||||||
+15
-12
@@ -7,9 +7,10 @@ export default class Template {
|
|||||||
return {
|
return {
|
||||||
abilities: {},
|
abilities: {},
|
||||||
logic: this.#basiliskLogic(),
|
logic: this.#basiliskLogic(),
|
||||||
|
maxHealth: 3000,
|
||||||
|
model: 'models/generic-bam-placeholder.gltf',
|
||||||
radius: 180,
|
radius: 180,
|
||||||
speed: 230,
|
speed: 230,
|
||||||
maxHealth: 3000,
|
|
||||||
...overrides,
|
...overrides,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +20,7 @@ export default class Template {
|
|||||||
abilities: { a: options.ranged ? Ability.rangedAttack.id : Ability.meleeAttack.id },
|
abilities: { a: options.ranged ? Ability.rangedAttack.id : Ability.meleeAttack.id },
|
||||||
logic: this.#minionLogic(options.route, (team != Team.blue)),
|
logic: this.#minionLogic(options.route, (team != Team.blue)),
|
||||||
maxHealth: options.ranged ? 300 : 450,
|
maxHealth: options.ranged ? 300 : 450,
|
||||||
|
model: Team.blue == (team ?? Team.blue) ? 'models/generic-player-placeholder.gltf' : 'models/generic-player-placeholder-red.gltf',
|
||||||
pathfindingCooldown: 0.2,
|
pathfindingCooldown: 0.2,
|
||||||
pathfindingObstacleLimit: 0,
|
pathfindingObstacleLimit: 0,
|
||||||
position: options.route?.at(0) ?? options.position ?? new Vector2(0, 0),
|
position: options.route?.at(0) ?? options.position ?? new Vector2(0, 0),
|
||||||
@@ -42,6 +44,7 @@ export default class Template {
|
|||||||
},
|
},
|
||||||
logic: this.#playerLogic,
|
logic: this.#playerLogic,
|
||||||
maxHealth: 600,
|
maxHealth: 600,
|
||||||
|
model: Team.blue == (overrides.team ?? Team.blue) ? 'models/generic-player-placeholder.gltf' : 'models/generic-player-placeholder-red.gltf',
|
||||||
pathfindingObstacleLimit: 3,
|
pathfindingObstacleLimit: 3,
|
||||||
radius: 65,
|
radius: 65,
|
||||||
spawnPosition: new Vector2(500, 150),
|
spawnPosition: new Vector2(500, 150),
|
||||||
@@ -60,17 +63,17 @@ export default class Template {
|
|||||||
const despawnDelay = entity.game?.secToTick(despawnDelaySec) ?? 1
|
const despawnDelay = entity.game?.secToTick(despawnDelaySec) ?? 1
|
||||||
const timestamp = entity.game?.currentTick ?? 0
|
const timestamp = entity.game?.currentTick ?? 0
|
||||||
|
|
||||||
if (entity.dead) {
|
if (entity.dead && diedOnTick == null) { diedOnTick = timestamp }
|
||||||
if (diedOnTick == null) {
|
if (entity.dead && diedOnTick != null && diedOnTick + despawnDelay < timestamp) { entity.despawn() }
|
||||||
diedOnTick = timestamp
|
if (!entity.dead) { diedOnTick = null }
|
||||||
}
|
if (entity.dead) { return }
|
||||||
else if (diedOnTick + despawnDelay < timestamp) {
|
|
||||||
entity.despawn()
|
const target = entity.closestTargetTo(entity.position, 500)
|
||||||
}
|
if (target == null) { return }
|
||||||
}
|
|
||||||
else if (diedOnTick != null) {
|
const directionToTarget = target.position.clone().sub(entity.position).normalize()
|
||||||
diedOnTick = null
|
const entityRotationVector = new Vector2(1, 0).rotateAround(new Vector2(), entity.rotation)
|
||||||
}
|
entity.rotation = directionToTarget.clone().add(entityRotationVector).add(entityRotationVector).add(entityRotationVector).angle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user