Skip to content

Instantly share code, notes, and snippets.

@NotAFile
Created July 6, 2017 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NotAFile/dc31929e88c58632ed6d24f75b5f84e1 to your computer and use it in GitHub Desktop.
Save NotAFile/dc31929e88c58632ed6d24f75b5f84e1 to your computer and use it in GitHub Desktop.
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
namespace spades {
class ThirdPersonSMGSkin:
IToolSkin, IThirdPersonToolSkin, IWeaponSkin, IWeaponSkin2 {
private float sprintState;
private float raiseState;
private Vector3 teamColor;
private bool muted;
private Matrix4 originMatrix;
private float aimDownSightState;
private float readyState;
private bool reloading;
private float reloadProgress;
private int ammo, clipSize;
private float environmentRoom;
private float environmentSize;
private float environmentDistance;
private Vector3 soundOrigin;
float SprintState {
set { sprintState = value; }
}
float RaiseState {
set { raiseState = value; }
}
Vector3 TeamColor {
set { teamColor = value; }
}
bool IsMuted {
set { muted = value; }
}
Matrix4 OriginMatrix {
set { originMatrix = value; }
}
float PitchBias {
get { return 0.f; }
}
float AimDownSightState {
set { aimDownSightState = value; }
}
bool IsReloading {
set { reloading = value; }
}
float ReloadProgress {
set { reloadProgress = value; }
}
int Ammo {
set { ammo = value; }
}
int ClipSize {
set { clipSize = value; }
}
float ReadyState {
set { readyState = value; }
}
// IWeaponSkin2
void SetSoundEnvironment(float room, float size, float distance) {
environmentRoom = room;
environmentSize = size;
environmentDistance = distance;
}
Vector3 SoundOrigin {
set { soundOrigin = value; }
}
private Renderer@ renderer;
private AudioDevice@ audioDevice;
private Model@ model;
private AudioChunk@[] fireMediumSounds(4);
private AudioChunk@ fireFarSound;
private AudioChunk@ fireStereoSound;
private AudioChunk@[] fireSmallReverbSounds(4);
private AudioChunk@[] fireLargeReverbSounds(4);
private AudioChunk@ reloadSound;
ThirdPersonSMGSkin(Renderer@ r, AudioDevice@ dev) {
@renderer = r;
@audioDevice = dev;
@model = renderer.RegisterModel
("Models/Weapons/SMG/Weapon.kv6");
@fireMediumSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Third1.opus");
@fireMediumSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Third2.opus");
@fireMediumSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Third3.opus");
@fireMediumSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Third4.opus");
@fireSmallReverbSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall1.opus");
@fireSmallReverbSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall2.opus");
@fireSmallReverbSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall3.opus");
@fireSmallReverbSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall4.opus");
@fireLargeReverbSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge1.opus");
@fireLargeReverbSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge2.opus");
@fireLargeReverbSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge3.opus");
@fireLargeReverbSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge4.opus");
@fireFarSound = dev.RegisterSound
("Sounds/Weapons/SMG/FireFar.opus");
@fireStereoSound = dev.RegisterSound
("Sounds/Weapons/SMG/FireStereo.opus");
@reloadSound = dev.RegisterSound
("Sounds/Weapons/SMG/Reload.opus");
}
void Update(float dt) {
}
void WeaponFired(){
if(!muted){
Vector3 origin = soundOrigin;
AudioParam param;
param.volume = 9.f;
audioDevice.Play(fireMediumSounds[GetRandom(fireMediumSounds.length)], origin, param);
param.volume = 8.f * environmentRoom;
param.referenceDistance = 10.f;
if (environmentSize < 0.5f) {
audioDevice.Play(fireSmallReverbSounds[GetRandom(fireSmallReverbSounds.length)], origin, param);
} else {
audioDevice.Play(fireLargeReverbSounds[GetRandom(fireLargeReverbSounds.length)], origin, param);
}
param.volume = .4f;
param.referenceDistance = 10.f;
audioDevice.Play(fireFarSound, origin, param);
param.referenceDistance = 1.f;
audioDevice.Play(fireStereoSound, origin, param);
}
}
void ReloadingWeapon() {
if(!muted){
Vector3 origin = soundOrigin;
AudioParam param;
param.volume = 0.2f;
audioDevice.Play(reloadSound, origin, param);
}
}
void ReloadedWeapon() {
}
void AddToScene() {
Matrix4 mat = CreateScaleMatrix(0.05f);
mat = mat * CreateScaleMatrix(-1.f, -1.f, 1.f);
mat = CreateTranslateMatrix(0.35f, -1.f, 0.0f) * mat;
ModelRenderParam param;
param.matrix = originMatrix * mat;
renderer.AddModel(model, param);
}
}
IWeaponSkin@ CreateThirdPersonSMGSkin(Renderer@ r, AudioDevice@ dev) {
return ThirdPersonSMGSkin(r, dev);
}
}
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
namespace spades {
class ViewSMGSkin:
IToolSkin, IViewToolSkin, IWeaponSkin, IWeaponSkin2,
BasicViewWeapon {
private AudioDevice@ audioDevice;
private Model@ gunModel;
private Model@ magazineModel;
private Model@ scopeModel;
private Image@ reflexImage;
private AudioChunk@[] fireSounds(4);
private AudioChunk@ fireFarSound;
private AudioChunk@ fireStereoSound;
private AudioChunk@[] fireSmallReverbSounds(4);
private AudioChunk@[] fireLargeReverbSounds(4);
private AudioChunk@ reloadSound;
ViewSMGSkin(Renderer@ r, AudioDevice@ dev){
super(r);
@audioDevice = dev;
@gunModel = renderer.RegisterModel
("Models/Weapons/SMG/WeaponNoMagazine.kv6");
@magazineModel = renderer.RegisterModel
("Models/Weapons/SMG/Magazine.kv6");
@scopeModel = renderer.RegisterModel
("Models/Weapons/SMG/Scope.kv6");
@reflexImage = renderer.RegisterImage
("Gfx/ReflexSight.png");
("Models/Weapons/SMG/Sight3.kv6");
@fireSmallReverbSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall1.opus");
@fireSmallReverbSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall2.opus");
@fireSmallReverbSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall3.opus");
@fireSmallReverbSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceSmall4.opus");
@fireLargeReverbSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge1.opus");
@fireLargeReverbSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge2.opus");
@fireLargeReverbSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge3.opus");
@fireLargeReverbSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2AmbienceLarge4.opus");
@fireSounds[0] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Local1.opus");
@fireSounds[1] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Local2.opus");
@fireSounds[2] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Local3.opus");
@fireSounds[3] = dev.RegisterSound
("Sounds/Weapons/SMG/V2Local4.opus");
@fireFarSound = dev.RegisterSound
("Sounds/Weapons/SMG/FireFar.opus");
@fireStereoSound = dev.RegisterSound
("Sounds/Weapons/SMG/FireStereo.opus");
@reloadSound = dev.RegisterSound
("Sounds/Weapons/SMG/ReloadLocal.opus");
}
void Update(float dt) {
BasicViewWeapon::Update(dt);
}
void WeaponFired(){
BasicViewWeapon::WeaponFired();
if(!IsMuted){
Vector3 origin = Vector3(0.4f, -0.3f, 0.5f);
AudioParam param;
param.volume = 8.f;
audioDevice.PlayLocal(fireSounds[GetRandom(fireSounds.length)], origin, param);
param.volume = 8.f * environmentRoom;
if (environmentSize < 0.5f) {
audioDevice.PlayLocal(fireSmallReverbSounds[GetRandom(fireSmallReverbSounds.length)], origin, param);
} else {
audioDevice.PlayLocal(fireLargeReverbSounds[GetRandom(fireLargeReverbSounds.length)], origin, param);
}
}
}
void ReloadingWeapon() {
if(!IsMuted){
Vector3 origin = Vector3(0.4f, -0.3f, 0.5f);
AudioParam param;
param.volume = 0.2f;
audioDevice.PlayLocal(reloadSound, origin, param);
}
}
float GetZPos() {
return 0.2f - AimDownSightStateSmooth * 0.012f;
}
// rotates gun matrix to ensure the sight is in
// the center of screen (0, ?, 0).
Matrix4 AdjustToAlignSight(Matrix4 mat, Vector3 sightPos, float fade) {
Vector3 p = mat * sightPos;
mat = CreateRotateMatrix(Vector3(0.f, 0.f, 1.f), atan(p.x / p.y) * fade) * mat;
mat = CreateRotateMatrix(Vector3(-1.f, 0.f, 0.f), atan(p.z / p.y) * fade) * mat;
return mat;
}
void Draw2D() {
if(AimDownSightState > 0.6)
return;
BasicViewWeapon::Draw2D();
}
void AddToScene() {
Matrix4 mat = CreateScaleMatrix(0.033f);
mat = GetViewWeaponMatrix() * mat;
bool reloading = IsReloading;
float reload = ReloadProgress;
Vector3 leftHand, rightHand;
leftHand = mat * Vector3(1.f, 6.f, 1.f);
rightHand = mat * Vector3(0.f, -8.f, 2.f);
Vector3 leftHand2 = mat * Vector3(5.f, -10.f, 4.f);
Vector3 leftHand3 = mat * Vector3(1.f, 6.f, -4.f);
Vector3 leftHand4 = mat * Vector3(1.f, 9.f, -6.f);
// stick the scope to the center of screen
if(AimDownSightStateSmooth > 0.8f){
mat = AdjustToAlignSight(mat, Vector3(0.f, -8.f, -5.75f), (AimDownSightStateSmooth - 0.8f) / 0.2f);
}
ModelRenderParam param;
Matrix4 weapMatrix = eyeMatrix * mat;
param.matrix = weapMatrix;
param.depthHack = true;
renderer.AddModel(gunModel, param);
// draw sights
Matrix4 sightMat = weapMatrix;
sightMat *= CreateTranslateMatrix(0.5f / 6.f, -8.f, -5.9f);
sightMat *= CreateScaleMatrix(1.f / 6.f);
param.matrix = sightMat;
renderer.AddModel(scopeModel, param);
// draw reflex image
float reflexOpacity = (AimDownSightState > 0.8f) ? AimDownSightState * 5.f - 4.f : 0.f;
Vector3 reflexPos = eyeMatrix * Vector3(0.f, 0.2f, 0.f);
renderer.Color = Vector4(reflexOpacity, reflexOpacity, reflexOpacity, 0.f); // premultiplied alpha
renderer.AddLongSprite(reflexImage, reflexPos, reflexPos, 0.004f);
// magazine/reload action
mat *= CreateTranslateMatrix(0.f, 3.f, 1.f);
reload *= 2.5f;
if(reloading) {
if(reload < 0.7f){
// magazine release
float per = reload / 0.7f;
mat *= CreateTranslateMatrix(0.f, 0.f, per*per*50.f);
leftHand = Mix(leftHand, leftHand2, SmoothStep(per));
}else if(reload < 1.4f) {
// insert magazine
float per = (1.4f - reload) / 0.7f;
if(per < 0.3f) {
// non-smooth insertion
per *= 4.f; per -= 0.4f;
per = Clamp(per, 0.0f, 0.3f);
}
mat *= CreateTranslateMatrix(0.f, 0.f, per*per*10.f);
leftHand = mat * Vector3(0.f, 0.f, 4.f);
}else if(reload < 1.9f){
// move the left hand to the original position
// and start doing something with the right hand
float per = (reload - 1.4f) / 0.5f;
leftHand = mat * Vector3(0.f, 0.f, 4.f);
leftHand = Mix(leftHand, leftHand3, SmoothStep(per));
}else if(reload < 2.2f){
float per = (reload - 1.9f) / 0.3f;
leftHand = Mix(leftHand3, leftHand4, SmoothStep(per));
}else{
float per = (reload - 2.2f) / 0.3f;
leftHand = Mix(leftHand4, leftHand, SmoothStep(per));
}
}
param.matrix = eyeMatrix * mat;
renderer.AddModel(magazineModel, param);
LeftHandPosition = leftHand;
RightHandPosition = rightHand;
}
}
IWeaponSkin@ CreateViewSMGSkin(Renderer@ r, AudioDevice@ dev) {
return ViewSMGSkin(r, dev);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment