This commit is contained in:
@@ -41,7 +41,7 @@ class DashBoard extends EventManager {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
dash.add(dashMesh);
|
dash.add(dashMesh);
|
||||||
engine.scene.add(dash);
|
engine.cameraRig.add(dash);
|
||||||
|
|
||||||
const loadingPlane = new Mesh(
|
const loadingPlane = new Mesh(
|
||||||
new PlaneGeometry(dashWidth, dashHeight),
|
new PlaneGeometry(dashWidth, dashHeight),
|
||||||
@@ -112,12 +112,11 @@ class DashBoard extends EventManager {
|
|||||||
pointsText.position.set(0.86 * dashWidth/2, 0.47 * dashHeight, -0.001);
|
pointsText.position.set(0.86 * dashWidth/2, 0.47 * dashHeight, -0.001);
|
||||||
dash.add(pointsText);
|
dash.add(pointsText);
|
||||||
|
|
||||||
engine.addEventListener('beforeRender', ()=>{
|
//engine.addEventListener('beforeRender', ()=>{
|
||||||
dash.quaternion.copy(engine.camera.quaternion)
|
dash.quaternion.copy(engine.camera.quaternion)
|
||||||
dash.position.copy(engine.camera.position)
|
dash.position.copy(engine.camera.position)
|
||||||
//dash.translateZ(-1.2 * engine.camera.zoom);
|
|
||||||
dash.translateZ(-dashDistance -0.75/Math.tan(engine.camera.fov/2 * Math.PI/180) * engine.camera.zoom);
|
dash.translateZ(-dashDistance -0.75/Math.tan(engine.camera.fov/2 * Math.PI/180) * engine.camera.zoom);
|
||||||
})
|
//})
|
||||||
|
|
||||||
this.initScene = function(scene, startBtnCallback){
|
this.initScene = function(scene, startBtnCallback){
|
||||||
this.loading(0,0);
|
this.loading(0,0);
|
||||||
@@ -203,7 +202,7 @@ class DashBoard extends EventManager {
|
|||||||
//dashPlacement, rotate = false, plane = false
|
//dashPlacement, rotate = false, plane = false
|
||||||
this.attach = (object, opts = {})=>{
|
this.attach = (object, opts = {})=>{
|
||||||
this.cameraFix = engine.hero.cameraZ;
|
this.cameraFix = engine.hero.cameraZ;
|
||||||
engine.hero.cameraZ = 6;
|
engine.hero.cameraZ = 12;
|
||||||
hud.visible = true;
|
hud.visible = true;
|
||||||
hudPlane.visible = !!opts.plane;
|
hudPlane.visible = !!opts.plane;
|
||||||
if (opts.plane){
|
if (opts.plane){
|
||||||
|
|||||||
+53
-31
@@ -33,7 +33,7 @@ class GameEngine extends EventManager{
|
|||||||
|
|
||||||
this.perspectiveCamera = new THREE.PerspectiveCamera(45, this.aspect, 0.001, 99);
|
this.perspectiveCamera = new THREE.PerspectiveCamera(45, this.aspect, 0.001, 99);
|
||||||
this.raycaster = new THREE.Raycaster();
|
this.raycaster = new THREE.Raycaster();
|
||||||
this.perspectiveCamera.position.set(0, 0, 10);
|
//this.perspectiveCamera.position.set(0, 0, 10);
|
||||||
|
|
||||||
this.camera = this.perspectiveCamera;
|
this.camera = this.perspectiveCamera;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class GameEngine extends EventManager{
|
|||||||
this.frustumSize / - 2,
|
this.frustumSize / - 2,
|
||||||
0.01, 1000
|
0.01, 1000
|
||||||
);
|
);
|
||||||
this.orthographicCamera.position.set(0, 0, 100);
|
|
||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@ class GameEngine extends EventManager{
|
|||||||
renderer.setViewport(0, 0, this.w, this.h);
|
renderer.setViewport(0, 0, this.w, this.h);
|
||||||
renderer.autoClear = true;
|
renderer.autoClear = true;
|
||||||
renderer.alpha = true
|
renderer.alpha = true
|
||||||
|
this.renderer = renderer;
|
||||||
|
|
||||||
this.anaglyph = new AnaglyphEffect(renderer);
|
this.anaglyph = new AnaglyphEffect(renderer);
|
||||||
this.anaglyph.setSize(this.w, this.h);
|
this.anaglyph.setSize(this.w, this.h);
|
||||||
@@ -120,29 +121,31 @@ class GameEngine extends EventManager{
|
|||||||
this.activeObjects = new THREE.Group();
|
this.activeObjects = new THREE.Group();
|
||||||
scene.add(this.activeObjects);
|
scene.add(this.activeObjects);
|
||||||
|
|
||||||
const controls = new OrbitControls(this.camera, renderer.domElement);
|
|
||||||
if (opts.gizmo) {
|
if (opts.gizmo) {
|
||||||
|
this.orbitControls = new OrbitControls(this.camera, renderer.domElement);
|
||||||
|
this.orbitControls.enableZoom = false;
|
||||||
const gizmo = new ViewportGizmo(this.camera, renderer, {
|
const gizmo = new ViewportGizmo(this.camera, renderer, {
|
||||||
container: '.renderer-gizmo',
|
container: '.renderer-gizmo',
|
||||||
//type:'cube'
|
//type:'cube'
|
||||||
});
|
});
|
||||||
gizmo.attachControls(controls);
|
gizmo.attachControls(this.orbitControls);
|
||||||
this.gizmo = gizmo;
|
this.gizmo = gizmo;
|
||||||
|
this.perspectiveCamera.position.set(0, 0, 10);
|
||||||
|
this.orthographicCamera.position.set(0, 0, 100);
|
||||||
|
this.cameraRig.rotation.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.telemetry){
|
if (opts.telemetry){
|
||||||
this.tm = new Telemetry(opts.telemetry, opts.mode);
|
this.tm = new Telemetry(opts.telemetry, opts.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.orbitControls = controls;
|
|
||||||
controls.enableZoom = false;
|
|
||||||
//const controls = new MapControls( camera, renderer.domElement );
|
//const controls = new MapControls( camera, renderer.domElement );
|
||||||
this.transformControls = new TransformControls(this.camera, renderer.domElement);
|
this.transformControls = new TransformControls(this.camera, renderer.domElement);
|
||||||
this.transformControls.addEventListener('dragging-changed', function (event) {
|
this.transformControls.addEventListener('dragging-changed', function (event) {
|
||||||
controls.enabled = !event.value;
|
controls.enabled = !event.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pointerControls = new PointerControls(this.camera, renderer.domElement);
|
this.pointerControls = new PointerControls(this);
|
||||||
// controls.enableDamping = true;
|
// controls.enableDamping = true;
|
||||||
// controls.screenSpacePanning = true;
|
// controls.screenSpacePanning = true;
|
||||||
|
|
||||||
@@ -173,7 +176,6 @@ class GameEngine extends EventManager{
|
|||||||
const clock = new THREE.Clock();
|
const clock = new THREE.Clock();
|
||||||
|
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.renderer = renderer;
|
|
||||||
|
|
||||||
this.draco = new DRACOLoader().setDecoderPath('/3rdparty/draco/');
|
this.draco = new DRACOLoader().setDecoderPath('/3rdparty/draco/');
|
||||||
this.loader = new GLTFLoader();
|
this.loader = new GLTFLoader();
|
||||||
@@ -204,7 +206,7 @@ class GameEngine extends EventManager{
|
|||||||
gameEngine.camera.zoom -= event.deltaY / (1000 / gameEngine.camera.zoom);
|
gameEngine.camera.zoom -= event.deltaY / (1000 / gameEngine.camera.zoom);
|
||||||
gameEngine.camera.zoom = Math.max(gameEngine.camera.zoom, .01);
|
gameEngine.camera.zoom = Math.max(gameEngine.camera.zoom, .01);
|
||||||
//controls.rotateSpeed = 1 / Math.sqrt(gameEngine.camera.zoom);
|
//controls.rotateSpeed = 1 / Math.sqrt(gameEngine.camera.zoom);
|
||||||
controls.panSpeed = 1 / gameEngine.camera.zoom;
|
gameEngine.orbitControls.panSpeed = 1 / gameEngine.camera.zoom;
|
||||||
gameEngine.camera.updateProjectionMatrix();
|
gameEngine.camera.updateProjectionMatrix();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -226,23 +228,25 @@ class GameEngine extends EventManager{
|
|||||||
if (opts.xr) {
|
if (opts.xr) {
|
||||||
renderer.xr.enabled = true;
|
renderer.xr.enabled = true;
|
||||||
this.xrBtn = XRButton.createButton(renderer, opts.depthSense ? {
|
this.xrBtn = XRButton.createButton(renderer, opts.depthSense ? {
|
||||||
'requiredFeatures': ['depth-sensing'],
|
requiredFeatures: ['depth-sensing'],
|
||||||
'depthSensing': {
|
depthSensing: {
|
||||||
usagePreference: ["gpu-optimized"],
|
usagePreference: ["gpu-optimized"],
|
||||||
dataFormatPreference: ["unsigned-short"],
|
dataFormatPreference: ["unsigned-short"],
|
||||||
matchDepthView: false
|
matchDepthView: false
|
||||||
}
|
}
|
||||||
} : {})
|
} : {
|
||||||
|
|
||||||
|
})
|
||||||
this.xrBtn.classList.add('engine-xr-btn');
|
this.xrBtn.classList.add('engine-xr-btn');
|
||||||
document.body.appendChild(this.xrBtn);
|
document.body.appendChild(this.xrBtn);
|
||||||
this.initXrControllers();
|
this.initXr();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clickable = new Clickable(20);
|
this.clickable = new Clickable(20);
|
||||||
this.draggable = new Draggable(20);
|
this.draggable = new Draggable(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
initXrControllers() {
|
initXr() {
|
||||||
let c1 = this.renderer.xr.getController(0);
|
let c1 = this.renderer.xr.getController(0);
|
||||||
c1.addEventListener('select', this.onSelect.bind(this));
|
c1.addEventListener('select', this.onSelect.bind(this));
|
||||||
c1.addEventListener('selectstart', this.onControllerEvent.bind(this));
|
c1.addEventListener('selectstart', this.onControllerEvent.bind(this));
|
||||||
@@ -287,22 +291,32 @@ class GameEngine extends EventManager{
|
|||||||
|
|
||||||
this.xrController1 = c1
|
this.xrController1 = c1
|
||||||
this.xrController2 = c2
|
this.xrController2 = c2
|
||||||
|
|
||||||
|
this.xrCamera = this.renderer.xr.getCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
initCameraPivot() {
|
initCameraPivot() {
|
||||||
const pivot = new THREE.Object3D()
|
// const pivot = new THREE.Object3D()
|
||||||
pivot.position.set(0, 0, 0)
|
// pivot.position.set(0, 0, 0)
|
||||||
|
|
||||||
const yaw = new THREE.Object3D()
|
// const yaw = new THREE.Object3D()
|
||||||
const pitch = new THREE.Object3D()
|
// const pitch = new THREE.Object3D()
|
||||||
|
|
||||||
this.scene.add(pivot)
|
// this.scene.add(pivot)
|
||||||
pivot.add(yaw)
|
// pivot.add(yaw)
|
||||||
yaw.add(pitch)
|
// yaw.add(pitch)
|
||||||
this.scene.add(this.perspectiveCamera);
|
// this.scene.add(this.perspectiveCamera);
|
||||||
this.scene.add(this.orthographicCamera);
|
// this.scene.add(this.orthographicCamera);
|
||||||
this.cameraPivot = pivot;
|
// this.cameraPivot = pivot;
|
||||||
this.cameraYaw = yaw;
|
// this.cameraYaw = yaw;
|
||||||
|
|
||||||
|
this.cameraWorld = new THREE.Group();
|
||||||
|
this.cameraRig = new THREE.Group();
|
||||||
|
this.cameraRig.add(this.perspectiveCamera);
|
||||||
|
this.cameraRig.add(this.orthographicCamera);
|
||||||
|
this.cameraRig.rotation.y = Math.PI;
|
||||||
|
this.cameraWorld.add(this.cameraRig);
|
||||||
|
this.scene.add(this.cameraWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
async initPhysics() {
|
async initPhysics() {
|
||||||
@@ -540,7 +554,7 @@ class GameEngine extends EventManager{
|
|||||||
// o.updateProjectionMatrix();
|
// o.updateProjectionMatrix();
|
||||||
this.camera = o;
|
this.camera = o;
|
||||||
this.transformControls.camera = o;
|
this.transformControls.camera = o;
|
||||||
this.orbitControls.object = o;
|
//this.orbitControls.object = o;
|
||||||
if (this.gizmo) {
|
if (this.gizmo) {
|
||||||
this.gizmo.camera = o;
|
this.gizmo.camera = o;
|
||||||
}
|
}
|
||||||
@@ -554,7 +568,7 @@ class GameEngine extends EventManager{
|
|||||||
// o.updateProjectionMatrix();
|
// o.updateProjectionMatrix();
|
||||||
this.camera = o;
|
this.camera = o;
|
||||||
this.transformControls.camera = o;
|
this.transformControls.camera = o;
|
||||||
this.orbitControls.object = o;
|
//this.orbitControls.object = o;
|
||||||
if (this.gizmo) {
|
if (this.gizmo) {
|
||||||
this.gizmo.camera = o;
|
this.gizmo.camera = o;
|
||||||
}
|
}
|
||||||
@@ -607,12 +621,20 @@ class GameEngine extends EventManager{
|
|||||||
this.ambientSound.play();
|
this.ambientSound.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
showBackground(show, t = 1){
|
immersive(show, t = 1){
|
||||||
this.motionQueue.add({
|
this.motionQueue.add([
|
||||||
|
{
|
||||||
o: this.scene,
|
o: this.scene,
|
||||||
a: { backgroundIntensity: show ? 1 : 0},
|
a: {
|
||||||
|
backgroundIntensity: show ? 0.1 : 1, environmentIntensity: show ? 0.1 : 1
|
||||||
|
},
|
||||||
t
|
t
|
||||||
})
|
},{
|
||||||
|
o: this.ambientLight,
|
||||||
|
a: { intensity: show ? 0.1 : 11},
|
||||||
|
t
|
||||||
|
}
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy(){
|
destroy(){
|
||||||
|
|||||||
+20
-8
@@ -5,7 +5,7 @@ import { QueryFilterFlags } from '@dimforge/rapier3d';
|
|||||||
class Hero{
|
class Hero{
|
||||||
walkDirection = new Vector3()
|
walkDirection = new Vector3()
|
||||||
rotateAngle = new Vector3(0, 1, 0)
|
rotateAngle = new Vector3(0, 1, 0)
|
||||||
#cameraZ = 5/1.77
|
#cameraZ = 6
|
||||||
|
|
||||||
get cameraZ(){
|
get cameraZ(){
|
||||||
return this.#cameraZ;
|
return this.#cameraZ;
|
||||||
@@ -76,7 +76,8 @@ class Hero{
|
|||||||
// this.characterController.setCharacterMass(50);
|
// this.characterController.setCharacterMass(50);
|
||||||
|
|
||||||
this.orbitControl = this.engine.orbitControls
|
this.orbitControl = this.engine.orbitControls
|
||||||
this.camera = this.engine.camera
|
//this.camera = this.engine.camera;
|
||||||
|
this.camera = this.engine.cameraWorld;
|
||||||
this.cameraY = this.size.y * 1.5;
|
this.cameraY = this.size.y * 1.5;
|
||||||
|
|
||||||
this.direction = this.model.rotation.y;
|
this.direction = this.model.rotation.y;
|
||||||
@@ -88,8 +89,17 @@ class Hero{
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(delta){
|
update(delta){
|
||||||
if (this.ready && this.engine.physics.started && !this.disableInput && !this.engine.renderer.xr.isPresenting) {
|
if (this.ready && this.engine.physics.started && !this.disableInput) {
|
||||||
this.updateCharacterControls(delta)
|
this.updateCharacterControls(delta)
|
||||||
|
// if (this.engine.renderer.xr.isPresenting){
|
||||||
|
// this.camera = this.engine.cameraWorld;
|
||||||
|
// // this.engine.activeObjects.position.x = -this.camera.position.x;
|
||||||
|
// // this.engine.activeObjects.position.z = -this.camera.position.z;
|
||||||
|
// }else{
|
||||||
|
// this.camera = this.engine.cameraWorld;
|
||||||
|
// this.engine.camera.position.set(0,0,0);
|
||||||
|
// this.engine.camera.rotation.set(0,0,0);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,9 +116,9 @@ class Hero{
|
|||||||
}
|
}
|
||||||
if (!pc.controls.isLocked && !this.model.visible){
|
if (!pc.controls.isLocked && !this.model.visible){
|
||||||
this.model.visible = true;
|
this.model.visible = true;
|
||||||
this.#cameraZ = 5/1.77
|
this.#cameraZ = 6
|
||||||
this.camera.fov = 45;
|
this.engine.camera.fov = 45;
|
||||||
this.camera.updateProjectionMatrix();
|
this.engine.camera.updateProjectionMatrix();
|
||||||
}
|
}
|
||||||
let input = pc.input;
|
let input = pc.input;
|
||||||
|
|
||||||
@@ -230,12 +240,14 @@ class Hero{
|
|||||||
cameraPosition.lerp(cameraDesiredPosition, delta*2)
|
cameraPosition.lerp(cameraDesiredPosition, delta*2)
|
||||||
this.camera.position.copy(cameraPosition)
|
this.camera.position.copy(cameraPosition)
|
||||||
if (!pc.controls.isLocked){
|
if (!pc.controls.isLocked){
|
||||||
this.orbitControl.target.set(
|
// this.orbitControl.target.set(
|
||||||
|
|
||||||
|
// )
|
||||||
|
this.camera.lookAt(
|
||||||
this.model.position.x,
|
this.model.position.x,
|
||||||
this.cameraY -this.size.y * 0.5 + this.model.position.y,
|
this.cameraY -this.size.y * 0.5 + this.model.position.y,
|
||||||
this.model.position.z
|
this.model.position.z
|
||||||
)
|
)
|
||||||
this.camera.lookAt(this.orbitControl.target)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-24
@@ -2,9 +2,9 @@ import { Vector3 } from 'three';
|
|||||||
import { PointerLockControls } from 'three/examples/jsm/Addons.js';
|
import { PointerLockControls } from 'three/examples/jsm/Addons.js';
|
||||||
|
|
||||||
class PointerControls {
|
class PointerControls {
|
||||||
constructor(camera, domElement) {
|
constructor(engine) {
|
||||||
this.kb = {};
|
this.kb = {};
|
||||||
this.dom = domElement;
|
this.dom = engine.renderer.domElement;
|
||||||
|
|
||||||
this.canJump = false;
|
this.canJump = false;
|
||||||
this.velocity = new Vector3();
|
this.velocity = new Vector3();
|
||||||
@@ -13,10 +13,10 @@ class PointerControls {
|
|||||||
this.vertex = new Vector3();
|
this.vertex = new Vector3();
|
||||||
this.rvelo = 0;
|
this.rvelo = 0;
|
||||||
|
|
||||||
this.camera = camera;
|
this.engine = engine;
|
||||||
this.click = false;
|
this.click = false;
|
||||||
|
|
||||||
this.controls = new PointerLockControls(camera, domElement);
|
this.controls = new PointerLockControls(engine.camera, this.dom);
|
||||||
|
|
||||||
const onKeyDown = (event) => {
|
const onKeyDown = (event) => {
|
||||||
this.kb[event.code] = true;
|
this.kb[event.code] = true;
|
||||||
@@ -35,55 +35,49 @@ class PointerControls {
|
|||||||
document.addEventListener('keydown', onKeyDown);
|
document.addEventListener('keydown', onKeyDown);
|
||||||
document.addEventListener('keyup', onKeyUp);
|
document.addEventListener('keyup', onKeyUp);
|
||||||
|
|
||||||
window.addEventListener("gamepadconnected", (e) => {
|
this.dom.addEventListener('click', () => {
|
||||||
this.gp = navigator.getGamepads()[e.gamepad.index];
|
|
||||||
console.log("Gamepad connected", this.gp);
|
|
||||||
});
|
|
||||||
|
|
||||||
domElement.addEventListener('click', () => {
|
|
||||||
this.controls.isLocked && this.clicked && this.clicked();
|
this.controls.isLocked && this.clicked && this.clicked();
|
||||||
});
|
});
|
||||||
|
|
||||||
domElement.addEventListener('mousedown', () => {
|
this.dom.addEventListener('mousedown', () => {
|
||||||
this.controls.isLocked && this.onpointer && this.onpointer('start');
|
this.controls.isLocked && this.onpointer && this.onpointer('start');
|
||||||
});
|
});
|
||||||
|
|
||||||
domElement.addEventListener('mousemove', () => {
|
this.dom.addEventListener('mousemove', () => {
|
||||||
this.controls.isLocked && this.onpointer && this.onpointer('drag');
|
this.controls.isLocked && this.onpointer && this.onpointer('drag');
|
||||||
});
|
});
|
||||||
|
|
||||||
domElement.addEventListener('mouseup', () => {
|
this.dom.addEventListener('mouseup', () => {
|
||||||
this.controls.isLocked && this.onpointer && this.onpointer('end');
|
this.controls.isLocked && this.onpointer && this.onpointer('end');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.update = () => { };
|
this.update = () => { };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveForward(){
|
get moveForward(){
|
||||||
return this.kb['ArrowUp'] || this.kb['KeyW'] || false
|
return this.kb['ArrowUp'] || this.kb['KeyW'] || this.engine.xrController1?.gamepad?.axes[3] < -0.5 || false
|
||||||
|
}
|
||||||
|
|
||||||
|
get moveBackward(){
|
||||||
|
return this.kb['ArrowDown'] || this.kb['KeyS'] || this.engine.xrController1?.gamepad?.axes[3] > 0.5 || false
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveLeft(){
|
get moveLeft(){
|
||||||
return this.kb['ArrowLeft'] || this.kb['KeyA'] || false
|
return this.kb['ArrowLeft'] || this.kb['KeyA'] || this.engine.xrController1?.gamepad?.axes[2] < -0.5 || false
|
||||||
|
}
|
||||||
|
|
||||||
|
get moveRight(){
|
||||||
|
return this.kb['ArrowRight'] || this.kb['KeyD'] || this.engine.xrController1?.gamepad?.axes[2] > 0.5 || false
|
||||||
}
|
}
|
||||||
|
|
||||||
get rotateLeft(){
|
get rotateLeft(){
|
||||||
return this.moveLeft;
|
return this.moveLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveRight(){
|
|
||||||
return this.kb['ArrowRight'] || this.kb['KeyD'] || false
|
|
||||||
}
|
|
||||||
|
|
||||||
get rotateRight(){
|
get rotateRight(){
|
||||||
return this.moveRight;
|
return this.moveRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveBackward(){
|
|
||||||
return this.kb['ArrowDown'] || this.kb['KeyS'] || false
|
|
||||||
}
|
|
||||||
|
|
||||||
get moveUp(){
|
get moveUp(){
|
||||||
return this.kb['KeyR'] || false
|
return this.kb['KeyR'] || false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user