content/hifi-content/huffman/ctf/portalGunClientEntity.js
2022-02-13 23:27:08 +01:00

222 lines
8 KiB
JavaScript

// pingPongGun.js
//
// Script Type: Entity
// Created by James B. Pollack @imgntn on 9/21/2015
// Copyright 2015 High Fidelity, Inc.
//
// This script shoots a ping pong ball.
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
var TRIGGER_THRESHOLD = 0.3;
var BULLET_BLUE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-blue.fbx";
var BULLET_RED_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-red.fbx";
var GUN_LOAD_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunLoad02.wav";
var GUN_FIRE1_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire01.wav";
var GUN_FIRE2_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire02.wav";
var GUN_FIRE3_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire03.wav";
var GUN_TIP_FWD_OFFSET = -1;
var GUN_TIP_UP_OFFSET = 0.12;
var GUN_FORCE = 20;
var BALL_RESTITUTION = 0.2;
var BALL_LINEAR_DAMPING = 0.1;
var BALL_DENSITY = 10000;
var BALL_GRAVITY = {
x: 0,
y: -10,
z: 0
};
var BALL_DIMENSIONS = {
x: 2.5,
y: 2.5,
z: 2.5
};
var BALL_COLLIDER_DIMENSIONS = {
x: 0.94,
y: 2.0,
z: 0.94
};
var BALL_ANGULAR_VEL = {
x: 2,
y: 3,
z: 1
};
var TRIGGER_CONTROLS = [
Controller.Standard.LT,
Controller.Standard.RT
];
function PortalGun() {
}
PortalGun.prototype = {
hand: null,
gunTipPosition: null,
cooldownActive: false,
preload: function(entityID) {
this.entityID = entityID;
this.gunFireSound = SoundCache.getSound(GUN_FIRE1_SOUND_URL);
this.gunLoadSound = SoundCache.getSound(GUN_LOAD_SOUND_URL);
this.hasReleasedInitialTriggerPress = false;
this.color = 'red';
var userData = Entities.getEntityProperties(entityID, 'userData').userData;
try {
userData = JSON.parse(userData);
if (userData.color === 'red' || userData.color === 'blue') {
this.color = userData.color;
} else {
print("ERROR, invalid color:", userData.color);
}
} catch (e) {
print("ERROR, could not find gun color");
}
},
startEquip: function(entityID, args) {
this.hand = args[0] === "left" ? 0 : 1;
},
continueEquip: function(entityID, args) {
if (this.cooldownActive) {
return;
}
var triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]);
if (triggerValue > TRIGGER_THRESHOLD) {
if (this.hasReleasedInitialTriggerPress) {
this.shootBall();
}
} else {
this.hasReleasedInitialTriggerPress = true;
}
},
releaseEquip: function(entityID, args) {
},
shootBall: function() {
if (this.cooldownActive) {
print("Not allowing portal bullet to be shot while cooldown active");
return;
}
Controller.triggerHapticPulse(10.0, 0.5, this.hand);
var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]);
var gunTipPosition = this.getGunTipPosition(gunProperties);
var audioProperties = {
volume: 0.9,
position: gunTipPosition,
localOnly: true
};
Audio.playSound(this.gunFireSound, audioProperties);
var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 180, 0)));
forwardVec = Vec3.normalize(forwardVec);
forwardVec = Vec3.multiply(forwardVec, GUN_FORCE);
var projectileProperties = {
name: 'CTF/PortalBullet',
type: 'Model',
modelURL: this.color === 'blue' ? BULLET_BLUE_MODEL_URL : BULLET_RED_MODEL_URL,
dimensions: BALL_DIMENSIONS,
damping: BALL_LINEAR_DAMPING,
gravity: BALL_GRAVITY,
restitution: BALL_RESTITUTION,
density: BALL_DENSITY,
dynamic: true,
rotation: gunProperties.rotation,
position: gunTipPosition,
angularDamping: 0,
angularVelocity: BALL_ANGULAR_VEL,
velocity: forwardVec,
lifetime: 10,
collisionless: true,
visible: true
};
var projectileID = Entities.addEntity(projectileProperties);
var portalProperties = {
name: 'CTF/PortalCollider',
type: 'Sphere',
localPosition: { x: 0, y: 0, z: 0 },
dimensions: BALL_DIMENSIONS,
parentID: projectileID,
dynamic: false,
lifetime: 10,
visible: false,
script: Script.resolvePath("portalBulletClientEntity.js"),
collisionless: true,
userData: JSON.stringify({
//portalTargetLocation: "hifi://lionsgate.highfidelity.io/-104.376,-0.496867,-8.28224/0,0.721841,0,0.692059"
portalTargetLocation: "/16.0555,-0.372284,18.5259/0,0.631228,0,0.775597"
})
};
Entities.addEntity(portalProperties);
var self = this;
this.cooldownActive = true;
Script.setTimeout(function() {
var gunProperties = Entities.getEntityProperties(self.entityID, ["position", "rotation"]);
var gunTipPosition = self.getGunTipPosition(gunProperties);
var audioProperties = {
volume: 0.9,
position: gunTipPosition,
localOnly: true
};
Audio.playSound(self.gunLoadSound, audioProperties);
self.cooldownActive = false;
}, 1000);
},
getGunTipPosition: function(properties) {
// the tip of the gun is going to be in a different place than the center,
// so we move in space relative to the model to find that position
var frontVector = Quat.getFront(properties.rotation);
var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET);
var upVector = Quat.getUp(properties.rotation);
var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET);
var gunTipPosition = Vec3.sum(properties.position, frontOffset);
gunTipPosition = Vec3.sum(gunTipPosition, upOffset);
return gunTipPosition;
},
createTipEntity: function(entityID) {
// for debugging where its going to shoot from
var gunProperties = Entities.getEntityProperties(entityID, ["position", "rotation"]);
var tipProps = {
name: 'Ping pong tip test',
dimensions: {
x: 0.1,
y: 0.1,
z: 0.1
},
color: {
red: 0,
green: 255,
blue: 0
},
type: 'Box',
parentID: entityID,
position: this.getGunTipPosition(gunProperties)
};
Entities.addEntity(tipProps);
}
};
// entity scripts should return a newly varructed object of our type
return new PortalGun();
});