fix castingVision giving vision to neutrals

This commit is contained in:
2025-01-24 14:41:30 +09:00
parent de3c175914
commit 2b2336bf70
11 changed files with 72 additions and 55 deletions
BIN
View File
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

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

+51 -42
View File
@@ -36,6 +36,8 @@ const teamMaterials = {
redTransparent: new THREE.MeshToonMaterial({ color: 0xff4444, transparent: true, opacity }),
projectile: new THREE.MeshToonMaterial({ color: 0xff00ff, transparent: true, opacity }),
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
@@ -70,9 +72,9 @@ const preloadGLTF = function loadTemplate(path) {
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) {
setTimeout(() => addGLTF(scene, path, id), 200)
setTimeout(() => addGLTF(scene, path, id, additionalSteps), 200)
return
}
@@ -89,6 +91,7 @@ const addGLTF = function addGLTF(scene, path, id) {
})
model.scale.set(scale, scale, scale)
additionalSteps(model)
scene.add(model)
}
@@ -208,6 +211,7 @@ var websocket = null
global.websocket = null
var timerId = null
var playerId = null
var playerTeam = null
function connectWebSocket() {
websocket = new WebSocket(`ws://${window.location.hostname}:1280/ws`)
@@ -236,6 +240,11 @@ function connectWebSocket() {
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) {
state.width = stateUpdates.width
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)) {
e.userData.flaggedForRemoval = true
}
for (const e of state.entities ?? []) {
let entity
let created = false
if (e.id == playerId && playerTeam != e.team) {
playerTeam = e.team
}
if (e.id in entities) {
entity = entities[e.id]
}
@@ -335,17 +345,19 @@ function connectWebSocket() {
// const entityMaterial = teamMaterials[e.team]
// entity = new THREE.Mesh(new THREE.CylinderGeometry(e.visualRadius / 100, e.visualRadius / 100, e.height / 50), entityMaterial)
// TODO: change entity material
created = true
entity = new THREE.Group()
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.id = e.id
entity.position.set(e.position.x / 100, e.position.y / 100, 0)
scene.add(entity)
const hpMargin = 4.8
const hpMargin = 0.5
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.layers.set(1)
entity.add(maxHp)
@@ -358,36 +370,20 @@ function connectWebSocket() {
const teamMaterial = teamMaterials[`${e.team}Transparent`]
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)
const buffMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, transparent: true, opacity: 0.4 })
const buffMarkerRadius = 0.6
const buffMarker = new THREE.Mesh(new THREE.CylinderGeometry(buffMarkerRadius, buffMarkerRadius, 0.3), buffMaterial)
buffMarker.position.y = 2
const buffMarker = new THREE.Mesh(new THREE.TorusGeometry(0.95, 0.15), buffMaterial)
buffMarker.rotation.x = Math.PI / 2
buffMarker.layers.set(1)
buffMarker.visible = false
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 rangeSize = e.visionRange ?? 0
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)
rangeMarker.position.y = 0.002
rangeMarker.position.y = 0.004
rangeMarker.layers.set(1)
rangeMarker.visible = false
entity.add(rangeMarker)
@@ -397,10 +393,22 @@ function connectWebSocket() {
modelRotationBase.layers.set(1)
entity.add(modelRotationBase)
addGLTF(modelRotationBase, 'models/generic-player-placeholder.gltf', e.id)
const animations = animationActions[e.id] ?? {}
if (e.dead) {
animations.dead?.reset().play()
const visionRangeMaterial = teamMaterials['visionRange']
const visionRangeSize = e.visionRange ?? 0
const visionRangeMarker = new THREE.Mesh(new THREE.CylinderGeometry(visionRangeSize / e.visualRadius, visionRangeSize / e.visualRadius, 0.001), visionRangeMaterial)
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
@@ -411,7 +419,7 @@ function connectWebSocket() {
entity.children.at(2).visible = e.buffs.some((it) => it.id == 'exposed') // TODO: only works for Exposed now
const animations = animationActions[e.id] ?? {}
const fadeIn = 0.15
const fadeIn = created ? 0 : 0.15
if (e.dead) {
if (!animations.dead?.isRunning()) {
@@ -433,26 +441,25 @@ function connectWebSocket() {
}
entity.userData.flaggedForRemoval = false
entity.children.at(3).rotation.y = e.rotation
const oldRotationY = entity.children.at(5).rotation.y
const oldRotationY = entity.children.at(4).rotation.y
const newRotationY = e.rotation - (Math.PI / 2)
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)) {
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()
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 percentageHp = e.health / e.maxHealth
hp.scale.x = percentageHp
hp.position.x = -(1 - percentageHp) / 2
entity.children.at(4).visible = e.id == playerId
// entity.children.at(3).children.at(0).visible = e.casting != null
entity.children.at(3).visible = e.id == playerId
// entity.children.at(5).visible = !e.dead && e.team == playerTeam
}
for (const e of Object.values(entities)) {
@@ -613,7 +620,9 @@ function connectWebSocket() {
}
window.addEventListener('load', () => {
preloadGLTF('models/generic-bam-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())
playerId = params.id
+2
View File
@@ -20,6 +20,7 @@ export default class Entity {
health = null
height = null
maxHealth = 1
model = null
position = null
radius = 0
rotation = 0
@@ -681,6 +682,7 @@ export default class Entity {
owner: this.id,
position: this.position.clone(),
visionRange: radius,
team: enemyTeam,
})
this.game?.spawnProjectile(projectile)
+15 -12
View File
@@ -7,9 +7,10 @@ export default class Template {
return {
abilities: {},
logic: this.#basiliskLogic(),
maxHealth: 3000,
model: 'models/generic-bam-placeholder.gltf',
radius: 180,
speed: 230,
maxHealth: 3000,
...overrides,
}
}
@@ -19,6 +20,7 @@ export default class Template {
abilities: { a: options.ranged ? Ability.rangedAttack.id : Ability.meleeAttack.id },
logic: this.#minionLogic(options.route, (team != Team.blue)),
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,
pathfindingObstacleLimit: 0,
position: options.route?.at(0) ?? options.position ?? new Vector2(0, 0),
@@ -42,6 +44,7 @@ export default class Template {
},
logic: this.#playerLogic,
maxHealth: 600,
model: Team.blue == (overrides.team ?? Team.blue) ? 'models/generic-player-placeholder.gltf' : 'models/generic-player-placeholder-red.gltf',
pathfindingObstacleLimit: 3,
radius: 65,
spawnPosition: new Vector2(500, 150),
@@ -60,17 +63,17 @@ export default class Template {
const despawnDelay = entity.game?.secToTick(despawnDelaySec) ?? 1
const timestamp = entity.game?.currentTick ?? 0
if (entity.dead) {
if (diedOnTick == null) {
diedOnTick = timestamp
}
else if (diedOnTick + despawnDelay < timestamp) {
entity.despawn()
}
}
else if (diedOnTick != null) {
diedOnTick = null
}
if (entity.dead && diedOnTick == null) { diedOnTick = timestamp }
if (entity.dead && diedOnTick != null && diedOnTick + despawnDelay < timestamp) { entity.despawn() }
if (!entity.dead) { diedOnTick = null }
if (entity.dead) { return }
const target = entity.closestTargetTo(entity.position, 500)
if (target == null) { return }
const directionToTarget = target.position.clone().sub(entity.position).normalize()
const entityRotationVector = new Vector2(1, 0).rotateAround(new Vector2(), entity.rotation)
entity.rotation = directionToTarget.clone().add(entityRotationVector).add(entityRotationVector).add(entityRotationVector).angle()
}
}