Code refactoring.

master
Vectozavr 2021-10-17 00:22:55 +07:00
parent eba88a178a
commit 6856f48054
41 changed files with 244 additions and 172 deletions

View File

@ -7,18 +7,33 @@
#include "engine/ResourceManager.h"
#include "engine/utils/Log.h"
Player::Player() {
loadObj(ShooterConsts::CUBE_OBJ, "", Vec3D{0.5, 1.9, 0.5});
setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0});
setCollision(true);
setVisible(false);
setColor({240, 168, 168});
_changeWeaponSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::CHANGE_WEAPON_SOUND));
_fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_HEALTH_SOUND));
_fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_ABILITY_SOUND));
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<RigidBody> obj) {collisionWithObject(objName, obj);});
}
void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, double val) {
for(auto& weapon : _weapons)
weapon->rotateRelativePoint(point4D, v, val);
}
void Player::playDeath() {
_deathSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/classic_hurt.ogg"));
_deathSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::DEATH_SOUND));
_deathSound.play();
}
void Player::playKill() {
_killSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/kill.ogg"));
_killSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::KILL_SOUND));
_killSound.play();
}
@ -111,7 +126,7 @@ void Player::previousWeapon() {
void Player::fire() {
if(attached("camera") != nullptr) {
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction, attached("camera")->position(), attached("camera")->lookAt());
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction);
for(auto& damagedPlayer : damagedPlayers) {
sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(6));
_damagePlayerCallBack(targetId, damagedPlayer.second);
@ -122,3 +137,13 @@ void Player::fire() {
void Player::reload() {
_weapons[_selectedWeapon]->reload();
}
void Player::setFullHealth() {
_health = ShooterConsts::HEALTH_MAX;
_fullHealthSound.play();
}
void Player::setFullAbility() {
_ability = ShooterConsts::ABILITY_MAX;
_fullAbilitySound.play();
}

View File

@ -15,22 +15,18 @@
#include "weapon/Gun.h"
#include "weapon/Gold_Ak47.h"
#include "weapon/Rifle.h"
#include "ShooterConsts.h"
class Player final : public RigidBody{
private:
double _healthMax = 100;
double _health = _healthMax;
double _abilityMax = 10;
double _ability = _abilityMax;
double _health = ShooterConsts::HEALTH_MAX;
double _ability = ShooterConsts::ABILITY_MAX;
double _headAngle = 0;
int _kills = 0;
int _deaths = 0;
double _g = 35;
// sounds
sf::Sound _killSound;
sf::Sound _deathSound;
@ -50,20 +46,7 @@ private:
std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> _rayCastFunction;
public:
Player() {
loadObj("obj/cube.obj", "", Vec3D{0.5, 1.9, 0.5});
setAcceleration(Vec3D{0, -_g, 0});
setCollision(true);
//setVisible(false);
setColor({240, 168, 168});
_changeWeaponSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/change_weapon.ogg"));
_fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/fullHealth.ogg"));
_fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer("sound/fullAbility.ogg"));
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<RigidBody> obj) {collisionWithObject(objName, obj);});
};
Player();
void setHealth(double h) {
_health = h;
@ -75,17 +58,9 @@ public:
[[nodiscard]] double health() const { return _health; }
[[nodiscard]] double ability() const { return _ability; }
[[nodiscard]] double maxHealth() const { return _healthMax; }
[[nodiscard]] double maxAbility() const { return _abilityMax; }
void setFullHealth() {
_health = _healthMax;
_fullHealthSound.play();
}
void setFullAbility() {
_ability = _abilityMax;
_fullAbilitySound.play();
}
void setFullHealth();
void setFullAbility();
void initWeapons();
void addWeapon(std::shared_ptr<Weapon> weapon);
@ -117,7 +92,7 @@ public:
_takeBonusCallBack = std::move(take);
}
void setAddWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> addWeapon) {
_addWeaponCallBack = addWeapon;
_addWeaponCallBack = std::move(addWeapon);
}
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
_removeWeaponCallBack = std::move(removeWeapon);

View File

@ -4,18 +4,18 @@
#include "PlayerController.h"
#include "engine/utils/Log.h"
#include "engine/animation/AColor.h"
#include "engine/animation/AFunction.h"
#include "engine/animation/AWait.h"
#include "engine/animation/ATranslate.h"
#include "engine/animation/ATranslateToPoint.h"
#include "engine/animation/Timeline.h"
#include "ShooterConsts.h"
PlayerController::PlayerController(std::shared_ptr<Player> player,
std::shared_ptr<Keyboard> keyboard,
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard), _mouse(mouse) {
_slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/slow_mo.ogg"));
_unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/unslow_mo.ogg"));
_slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SLOW_MO_SOUND));
_unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::UN_SLOW_MO_SOUND));
}
void PlayerController::update() {
@ -29,14 +29,14 @@ void PlayerController::update() {
else {
_player->setAbility(0);
_isInSlowMo = false;
_player->setVelocity(_player->velocity() * _slowMoCoefficient);
_player->setAcceleration(_player->acceleration() * _slowMoCoefficient * _slowMoCoefficient);
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
_slowMoSound.stop();
_unSlowMoSound.play();
}
}
double coeff = _isInSlowMo ? 1.0 / _slowMoCoefficient : 1.0;
double coeff = _isInSlowMo ? 1.0 / ShooterConsts::SLOW_MO_COEFFICIENT : 1.0;
bool inRunning_old = _inRunning;
_inRunning = ( Keyboard::isKeyPressed(sf::Keyboard::A) ||
@ -71,25 +71,25 @@ void PlayerController::update() {
// Left and right
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
_player->translate(_player->left() * Time::deltaTime() * _walkSpeed * coeff);
_player->translate(_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
if(_player->inCollision())
_player->setVelocity(Vec3D{0,0,0});
}
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
_player->translate(-_player->left() * Time::deltaTime() * _walkSpeed * coeff);
_player->translate(-_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
if(_player->inCollision())
_player->setVelocity(Vec3D{0,0,0});
}
// Forward and backward
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
_player->translate(_player->lookAt() * Time::deltaTime() * _walkSpeed * coeff);
_player->translate(_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
if(_player->inCollision())
_player->setVelocity(Vec3D{0,0,0});
}
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
_player->translate(-_player->lookAt() * Time::deltaTime() * _walkSpeed * coeff);
_player->translate(-_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
if(_player->inCollision())
_player->setVelocity(Vec3D{0,0,0});
@ -98,14 +98,14 @@ void PlayerController::update() {
if (_player->ability() > 0 && !_isInSlowMo && Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
// slow mo
_isInSlowMo = true;
_player->setVelocity(_player->velocity() / _slowMoCoefficient);
_player->setAcceleration(_player->acceleration() / (_slowMoCoefficient * _slowMoCoefficient));
_player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(_player->acceleration() / (ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT));
_unSlowMoSound.stop();
_slowMoSound.play();
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
_isInSlowMo = false;
_player->setVelocity(_player->velocity() * _slowMoCoefficient);
_player->setAcceleration(_player->acceleration() * _slowMoCoefficient * _slowMoCoefficient);
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT, 0));
_slowMoSound.stop();
_unSlowMoSound.play();
}
@ -113,12 +113,12 @@ void PlayerController::update() {
if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) {
// if we just want to jump, we have to add particular speed
if (!_isSliding)
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * _jumpHeight) * coeff, 0 });
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff, 0 });
// if we want to slide, we have to add speed * 60/fps to make it independent on frame rate
else
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * _jumpHeight) * coeff * 60.0 / Time::fps(), 0 });
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff * 60.0 / Time::fps(), 0 });
_player->translate(Vec3D{ 0, Time::deltaTime() * _walkSpeed * 2 * coeff * 60.0 / Time::fps(), 0 });
_player->translate(Vec3D{ 0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff * 60.0 / Time::fps(), 0 });
_isSliding = true;
} else {
_isSliding = false;
@ -127,10 +127,10 @@ void PlayerController::update() {
// Mouse movement
Vec2D displacement = _mouse->getMouseDisplacement();
_player->rotate(Vec3D{0, -displacement.x() / 1000.0, 0});
_player->setVelocity(Matrix4x4::RotationY(-displacement.x() / 1000.0) * _player->velocity());
_player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0});
_player->setVelocity(Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
double rotationLeft = displacement.y() / 1000.0;
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
// You can only see in range [-90 : 90] grad
if (_player->headAngle() + rotationLeft > Consts::PI / 2)

View File

@ -17,15 +17,12 @@ private:
bool _inRunning = false;
bool _isSliding = false;
double _slowMoCoefficient = 5;
bool _isInSlowMo = false;
sf::Sound _slowMoSound;
sf::Sound _unSlowMoSound;
sf::Sound _walkSound;
double _jumpHeight = 3;
double _walkSpeed = 10;
public:
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
void update();

View File

@ -123,8 +123,8 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se
}
void Server::processStop() {
for (auto it = _players.begin(); it != _players.end();)
_players.erase(it++);
_players.clear();
_bonuses.clear();
}
void Server::generateBonuses() {
@ -161,3 +161,7 @@ void Server::updateInfo() {
}
}
}
Server::~Server() {
processStop();
}

View File

@ -37,6 +37,8 @@ public:
void generateBonuses();
void updateInfo() override;
~Server() override;
};

View File

@ -8,6 +8,7 @@
#include "engine/animation/AFunction.h"
#include "engine/animation/ARotate.h"
#include "engine/animation/Timeline.h"
#include "ShooterConsts.h"
using namespace std;
@ -68,14 +69,14 @@ void Shooter::start() {
mouse->setMouseCursorVisible(true);
world->loadMap("maps/map1.obj", "maps/materials.txt", "map", Vec3D{5, 5, 5});
world->loadMap(ShooterConsts::MAP_OBJ, "maps/materials.txt", "map", Vec3D{5, 5, 5});
player = std::make_shared<Player>();
playerController = std::make_shared<PlayerController>(player, keyboard, mouse);
player->setAddTraceCallBack([this](const Vec3D& from, const Vec3D& to){ client->addTrace(from, to); addFireTrace(from, to); });
player->setDamagePlayerCallBack([this] (sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
player->setRayCastFunction([this](const Vec3D& from, const Vec3D& to) { return world->rayCast(from, to); });
player->setRayCastFunction([this](const Vec3D& from, const Vec3D& to) { return world->rayCast(from, to, "Enemy"); });
player->setTakeBonusCallBack([this] (const string& bonusName) { client->takeBonus(bonusName); });
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ addWeapon(weapon); });
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ removeWeapon(weapon); });
@ -93,12 +94,12 @@ void Shooter::start() {
// windows init:
mainMenu.title("Main menu");
mainMenu.setBackgroundTexture("textures/back.png", 1.1, 1.1, screen->width(), screen->height());
mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height());
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); }, "Play", 5, 5, "textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "sound/click.ogg");
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); }, "Respawn", 5, 5, "textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "sound/click.ogg");
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); }, "Play", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND);
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); }, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND);
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, "textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "sound/click.ogg");
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND);
// connecting to the server
InitNetwork();
@ -133,7 +134,7 @@ void Shooter::update() {
}
if(inGame) {
screen->setTitle("Shooter");
screen->setTitle(ShooterConsts::PROJECT_NAME);
playerController->update();
mouse->setMouseInCenter();
} else {
@ -144,7 +145,7 @@ void Shooter::update() {
// background sounds and music control
if(backgroundNoise.getStatus() != sf::Sound::Status::Playing) {
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer("sound/backNoise.ogg"));
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::BACK_NOISE));
backgroundNoise.play();
}
}
@ -152,7 +153,7 @@ void Shooter::update() {
void Shooter::gui() {
sf::Sprite sprite;
sprite.setTexture(*ResourceManager::loadTexture("textures/gui.png"));
sprite.setTexture(*ResourceManager::loadTexture(ShooterConsts::MAIN_MENU_GUI));
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
sprite.scale(3, 3);
sprite.setPosition(screen->width() / 2.0f - 27.0f/2.0f, screen->height() / 2.0f - 27.0f/2.0f);
@ -172,14 +173,14 @@ void Shooter::drawPlayerStats() {
int height = 10;
screen->drawTetragon(Vec2D{xPos, yPos},
Vec2D{xPos + width * player->health() / player->maxHealth(), yPos},
Vec2D{xPos + width * player->health() / player->maxHealth(), yPos + height},
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos},
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos + height},
Vec2D{xPos, yPos + height},
{ static_cast<sf::Uint8>((player->maxHealth() - player->health())/player->maxHealth() * 255), static_cast<sf::Uint8>(player->health() * 255 / player->maxHealth()), 0, 100 });
{ static_cast<sf::Uint8>((ShooterConsts::HEALTH_MAX - player->health())/ShooterConsts::HEALTH_MAX * 255), static_cast<sf::Uint8>(player->health() * 255 / ShooterConsts::HEALTH_MAX), 0, 100 });
screen->drawTetragon(Vec2D{xPos, yPos - 15},
Vec2D{xPos + width * player->ability() / player->maxAbility(), yPos - 15},
Vec2D{xPos + width * player->ability() / player->maxAbility(), yPos - 15 + height},
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15},
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15 + height},
Vec2D{xPos, yPos - 15 + height},
{ 255, 168, 168, 100 });
@ -208,18 +209,18 @@ void Shooter::spawnPlayer(sf::Uint16 id) {
newPlayer->setAcceleration(Vec3D{0, 0, 0});
// add head and other stuff:
world->loadBody(name + "_head", "obj/cube.obj", "", Vec3D{0.7, 0.7, 0.7});
world->loadBody(name + "_head", ShooterConsts::CUBE_OBJ, "", Vec3D{0.7, 0.7, 0.7});
world->body(name + "_head")->translate(Vec3D{0, 2, 0});
world->body(name + "_head")->setCollider(false);
newPlayer->attach(world->body(name + "_head"), "head");
world->loadBody(name + "_eye1", "obj/cube.obj", "", Vec3D{0.2, 0.2, 0.05});
world->loadBody(name + "_eye1", ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(name + "_eye1")->translate(Vec3D{0.3, 2.1, 0.7});
world->body(name + "_eye1")->setCollider(false);
world->body(name + "_eye1")->setColor({147, 159, 255});
world->body(name + "_head")->attach(world->body(name + "_eye1"), "eye1");
world->loadBody(name + "_eye2", "obj/cube.obj", "", Vec3D{0.2, 0.2, 0.05});
world->loadBody(name + "_eye2", ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(name + "_eye2")->translate(Vec3D{-0.3, 2.1, 0.7});
world->body(name + "_eye2")->setCollider(false);
world->body(name + "_eye2")->setColor({147, 159, 255});

View File

@ -7,7 +7,49 @@
namespace ShooterConsts {
const double GRAVITY = 35;
const double HEALTH_MAX = 100;
const double ABILITY_MAX = 10;
const double JUMP_HEIGHT = 3;
const double WALK_SPEED = 10;
const double MOUSE_SENSITIVITY = 1.0 / 1000.0;
const double SLOW_MO_COEFFICIENT = 5;
const double FIRE_DISTANCE = 1000;
const std::string PROJECT_NAME = "Shooter";
const std::string ABILITY_OBJ = "obj/ability.obj";
const std::string HILL_OBJ = "obj/hill.obj";
const std::string GUN_OBJ = "obj/gun.obj";
const std::string GUN_FIRE_SOUND = "sound/weapons/gun.ogg";
const std::string GUN_RELOAD_SOUND = "sound/weapons/reload_gun.ogg";
const std::string AK47_OBJ = "obj/ak47.obj";
const std::string AK47_FIRE_SOUND = "sound/weapons/ak47.ogg";
const std::string AK47_RELOAD_SOUND = "sound/weapons/reload_ak47.ogg";
const std::string GOLD_AK47_OBJ = "gold_ak47.obj";
const std::string GOLD_AK47_FIRE_SOUND = "sound/weapons/ak47.ogg";
const std::string GOLD_AK47_RELOAD_SOUND = "sound/weapons/reload_ak47.ogg";
const std::string RIFLE_OBJ = "obj/rifle.obj";
const std::string RIFLE_FIRE_SOUND = "sound/weapons/shotgun.ogg";
const std::string RIFLE_RELOAD_SOUND = "sound/weapons/reload_ak47.ogg";
const std::string SHOTGUN_OBJ = "obj/shotgun.obj";
const std::string SHOTGUN_FIRE_SOUND = "sound/weapons/shotgun.ogg";
const std::string SHOTGUN_RELOAD_SOUND = "sound/weapons/reload_shotgun.ogg";
const std::string CUBE_OBJ = "obj/cube.obj";
const std::string MAP_OBJ = "maps/map1.obj";
const std::string MAIN_MENU_BACK = "textures/back.png";
const std::string MAIN_MENU_GUI = "textures/gui.png";
const std::string CLICK_SOUND = "sound/click.ogg";
const std::string BACK_NOISE = "sound/backNoise.ogg";
const std::string CHANGE_WEAPON_SOUND = "sound/weapons/change_weapon.ogg";
const std::string RESTORE_HEALTH_SOUND = "sound/fullHealth.ogg";
const std::string RESTORE_ABILITY_SOUND = "sound/fullAbility.ogg";
const std::string KILL_SOUND = "sound/kill.ogg";
const std::string DEATH_SOUND = "sound/classic_hurt.ogg";
const std::string SLOW_MO_SOUND = "sound/slow_mo.ogg";
const std::string UN_SLOW_MO_SOUND = "sound/unslow_mo.ogg";
const std::string NO_AMMO_SOUND = "sound/weapons/no_ammo.ogg";
}
#endif //SHOOTER_SHOOTERCONSTS_H

View File

@ -9,11 +9,11 @@ using namespace std;
int main() {
Shooter game;
game.create(1280, 720, "Shooter");
//game.create(1920, 1080, "Shooter", true, {255, 255, 255}, sf::Style::Fullscreen);
game.create(1280, 720, ShooterConsts::PROJECT_NAME);
//game.create(1920, 1080, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
//game.create(2048, 1152, "Shooter");
//game.create(3072, 1920, "Shooter", true, {255, 255, 255}, sf::Style::Fullscreen);
//game.create(2048, 1152, ShooterConsts::PROJECT_NAME);
//game.create(3072, 1920, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
return 0;
}

View File

@ -4,14 +4,31 @@
#ifndef SHOOTER_CONSTS_H
#define SHOOTER_CONSTS_H
#include <SFML/Graphics.hpp>
namespace Consts {
const int STANDARD_SCREEN_WIDTH = 1920;
const int STANDARD_SCREEN_HEIGHT = 1920;
const sf::Color BACKGROUND_COLOR = sf::Color(255, 255, 255);
const std::string PROJECT_NAME = "engine";
const double PI = 3.14159265358979323846264338327950288;
const double EPS = 0.000001;
const double EPA_EPS = 0.0001;
const double RAY_CAST_MAX_DISTANCE = 10000;
const std::string THIN_FONT = "engine/fonts/Roboto-Thin.ttf";
const std::string MEDIUM_FONT = "engine/fonts/Roboto-Medium.ttf";
const double TAP_DELAY = 0.2;
const unsigned NETWORK_VERSION = 1U;
const int NETWORK_TIMEOUT = 1U;
const int NETWORK_WORLD_UPDATE_RATE = 30;
const double NETWORK_RELIABLE_RETRY_TIME = 1.0/20;
}
#endif //SHOOTER_CONSTS_H

View File

@ -42,7 +42,7 @@ public:
virtual ~Engine() = default;
void create(int screenWidth = 1920, int screenHeight = 1080, const std::string& name = "engine", bool verticalSync = true, sf::Color background = sf::Color(255, 255, 255), sf::Uint32 style = sf::Style::Default);
void create(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT, const std::string& name = Consts::PROJECT_NAME, bool verticalSync = true, sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
void exit();
};

View File

@ -4,6 +4,7 @@
#include "Keyboard.h"
#include "utils/Time.h"
#include "Consts.h"
bool Keyboard::isKeyPressed(sf::Keyboard::Key key) {
return sf::Keyboard::isKeyPressed(key);
@ -16,7 +17,7 @@ bool Keyboard::isKeyTapped(sf::Keyboard::Key key) {
if(_tappedKeys.count(key) == 0) {
_tappedKeys.emplace(key, Time::time());
return true;
} else if((Time::time() - _tappedKeys[key]) > 0.2) {
} else if((Time::time() - _tappedKeys[key]) > Consts::TAP_DELAY) {
_tappedKeys[key] = Time::time();
return true;
}

View File

@ -215,3 +215,7 @@ void Mesh::setTriangles(const vector<Triangle> &t) {
_tris.push_back(tri);
}
}
Mesh::~Mesh() {
_tris.clear();
}

View File

@ -49,6 +49,8 @@ public:
void setVisible(bool visibility) { _visible = visibility; }
[[nodiscard]] bool isVisible() const { return _visible; }
~Mesh() override;
Mesh static Obj(const std::string& filename);
std::vector<std::shared_ptr<Mesh>> static LoadObjects(const std::string& filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1});
Mesh static LineTo(const Vec3D& from, const Vec3D& to, double line_width = 0.1, const sf::Color& color = {150, 150, 150, 255});

View File

@ -34,7 +34,7 @@ bool Mouse::isButtonTapped(sf::Mouse::Button button) {
if(_tappedButtons.count(button) == 0) {
_tappedButtons.emplace(button, Time::time());
return true;
} else if((Time::time() - _tappedButtons[button]) > 0.2) {
} else if((Time::time() - _tappedButtons[button]) > Consts::TAP_DELAY) {
_tappedButtons[button] = Time::time();
return true;
}

View File

@ -137,3 +137,7 @@ void Object::attach(std::shared_ptr<Object> object, const std::string &name) {
void Object::unattach(const std::string &name) {
_attachedObjects.erase(name);
}
Object::~Object() {
_attachedObjects.clear();
}

View File

@ -48,6 +48,8 @@ public:
void attach(std::shared_ptr<Object> object, const std::string& name);
void unattach(const std::string& name);
std::shared_ptr<Object> attached(const std::string& name);
virtual ~Object();
};
#endif //MINECRAFT_3DZAVR_OBJECT_H

View File

@ -7,8 +7,6 @@
#include <utility>
#include "utils/Log.h"
#include "ResourceManager.h"
#include <cstdio>
void Screen::open(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background, sf::Uint32 style) {
_title = name;
@ -69,7 +67,7 @@ void Screen::close() {
void Screen::debugText(const std::string& text) {
sf::Text t;
t.setFont(*ResourceManager::loadFont(_font));
t.setFont(*ResourceManager::loadFont(Consts::THIN_FONT));
t.setString(text);
t.setCharacterSize(30);
t.setFillColor(sf::Color::Black);
@ -92,7 +90,7 @@ void Screen::drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, con
void Screen::drawText(const std::string& string, const Vec2D &position, int size, sf::Color color) {
sf::Text text;
text.setFont(*ResourceManager::loadFont("engine/fonts/Roboto-Medium.ttf"));
text.setFont(*ResourceManager::loadFont(Consts::MEDIUM_FONT));
text.setCharacterSize(size);
text.setFillColor(color);

View File

@ -12,21 +12,20 @@
#include <map>
#include "utils/Time.h"
#include "Mouse.h"
#include "Consts.h"
class Screen final {
private:
int _w = 1920;
int _h = 1080;
int _w;
int _h;
std::string _title;
sf::Color _background;
std::string _font = "engine/fonts/Roboto-Thin.ttf";
std::shared_ptr<sf::RenderWindow> _window;
public:
void open(int screenWidth = 1920, int screenHeight = 1080, const std::string& name = "engine", bool verticalSync = true, sf::Color background = sf::Color(255, 255, 255), sf::Uint32 style = sf::Style::Default);
void open(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT, const std::string& name = Consts::PROJECT_NAME, bool verticalSync = true, sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
void display();
void clear();

View File

@ -19,7 +19,7 @@ void World::loadBody(const string &name, const string &filename, const std::stri
Log::log("World::loadBody(): inserted body from " + filename + " with title '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris.");
}
std::pair<Vec3D, string> World::rayCast(const Vec3D& from, const Vec3D& to) {
std::pair<Vec3D, string> World::rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag) {
std::pair<Vec3D, string> result;
std::unique_ptr<Vec3D> point = std::make_unique<Vec3D>();
@ -27,7 +27,7 @@ std::pair<Vec3D, string> World::rayCast(const Vec3D& from, const Vec3D& to) {
double minDistance = Consts::RAY_CAST_MAX_DISTANCE;
for(auto& object : _objects) {
if((object.first.find("Player") != std::string::npos) || (object.first.find("Bonus") != std::string::npos))
if(!tag.empty() && object.first.find(tag) == std::string::npos)
continue;
for(auto& tri : object.second->triangles()) {

View File

@ -27,7 +27,7 @@ public:
// rayCast returns pair of Point4D and std::string:
// 1) Point4D is point of collision
// 2) std::string - title of the object
std::pair<Vec3D, std::string> rayCast(const Vec3D& from, const Vec3D& to);
std::pair<Vec3D, std::string> rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag = "");
void loadMap(const std::string& filename, const std::string& materials, const std::string& name = "map", const Vec3D & scale = Vec3D{1, 1, 1});
};

View File

@ -31,7 +31,7 @@ public:
std::function<void()> click,
const std::string& text = "_button", double sx = 1, double sy = 1,
const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {},
const std::string& font = "../engine/fonts/Roboto-Medium.ttf", sf::Color textColor = {255, 255, 255}, const std::string& clickSound = "");
const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255}, const std::string& clickSound = "");
[[nodiscard]] std::string title() const { return _name; }
void title(const std::string& title) { _name = title; }

View File

@ -8,6 +8,7 @@
#include "../utils/Time.h"
#include <cmath>
#include "../utils/Log.h"
#include "../Consts.h"
ClientUDP::ClientUDP() : _lastBroadcast(-std::numeric_limits<double>::max()), _working(false)
{
@ -27,7 +28,7 @@ bool ClientUDP::isWorking() const
void ClientUDP::connect(sf::IpAddress ip, sf::Uint16 port)
{
sf::Packet packet;
packet << MsgType::Connect << Network::VERSION;
packet << MsgType::Connect << Consts::NETWORK_VERSION;
_working = _socket.bind(0);
_socket.addConnection(_socket.serverId(), ip, port);
_socket.sendRely(packet, _socket.serverId());
@ -43,7 +44,7 @@ void ClientUDP::update()
while (isWorking() && process());
// Send new client information to server
if (Time::time() - _lastBroadcast > 1.0 / Network::WORLD_UPDATE_RATE && connected()) {
if (Time::time() - _lastBroadcast > 1.0 / Consts::NETWORK_WORLD_UPDATE_RATE && connected()) {
updatePacket();
_lastBroadcast = Time::time();
}

View File

@ -7,7 +7,6 @@
#include "ReliableMsg.h"
#include "UDPSocket.h"
#include "config.h"
#include <memory>
class ClientUDP
@ -41,6 +40,8 @@ public:
virtual void processCustomPacket(MsgType type, sf::Packet& packet){};
virtual void processDisconnected(){};
virtual ~ClientUDP() = default;
};

View File

@ -5,16 +5,16 @@
#include <cmath>
#include "ReliableMsg.h"
#include "../utils/Time.h"
#include "config.h"
#include "../Consts.h"
ReliableMsg::ReliableMsg(sf::Packet& packet, sf::IpAddress address, sf::Uint16 port) : packet(packet), address(address), port(port), lastTry(-std::numeric_limits<double>::max()), firstTry(Time::time()) {}
ReliableMsg::ReliableMsg(const ReliableMsg& msg) : packet(msg.packet), address(msg.address), port(msg.port), lastTry(msg.lastTry), firstTry(msg.firstTry) {}
bool ReliableMsg::trySend(sf::UdpSocket& socket)
{
if (Time::time() - firstTry > Network::TIMEOUT)
if (Time::time() - firstTry > Consts::NETWORK_TIMEOUT)
return false;
if (Time::time() - lastTry > Network::RELIABLE_RETRY_TIME)
if (Time::time() - lastTry > Consts::NETWORK_RELIABLE_RETRY_TIME)
{
lastTry = Time::time();
socket.send(packet, address, port);

View File

@ -3,9 +3,7 @@
//
#include "ServerUDP.h"
#include "../utils/Time.h"
#include "MsgType.h"
#include "config.h"
#include "../utils/Log.h"
#include <cmath>
@ -39,7 +37,7 @@ void ServerUDP::update()
while (process());
// World state broadcast
if (Time::time() - _lastBroadcast > 1.0 / Network::WORLD_UPDATE_RATE) {
if (Time::time() - _lastBroadcast > 1.0 / Consts::NETWORK_WORLD_UPDATE_RATE) {
broadcast();
_lastBroadcast = Time::time();
}
@ -126,3 +124,8 @@ bool ServerUDP::process()
return true;
}
ServerUDP::~ServerUDP() {
stop();
_clients.clear();
}

View File

@ -23,7 +23,6 @@ protected:
bool timeout(sf::Uint16 id);
std::set<sf::Uint16> _clients{};
public:
explicit ServerUDP();
[[nodiscard]] bool isWorking() const;
@ -44,6 +43,8 @@ public:
virtual void processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 senderId){};
virtual void processStop(){};
virtual ~ServerUDP();
};

View File

@ -4,7 +4,7 @@
#include "UDPConnection.h"
#include "../utils/Time.h"
#include "config.h"
#include "../Consts.h"
UDPConnection::UDPConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port) : _id(id), _ip(ip), _port(port), lastMsg(Time::time()) {}
@ -25,7 +25,7 @@ sf::Uint16 UDPConnection::port() const
bool UDPConnection::timeout() const
{
return Time::time() - lastMsg > Network::TIMEOUT;
return Time::time() - lastMsg > Consts::NETWORK_TIMEOUT;
}
bool UDPConnection::same(sf::IpAddress& ip, sf::Uint16 port) const

View File

@ -4,8 +4,8 @@
#include "UDPSocket.h"
#include "../utils/Time.h"
#include "config.h"
#include <algorithm>
#include "../Consts.h"
UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0)
{
@ -123,7 +123,7 @@ void UDPSocket::update()
for (auto it = _confirmTimes.begin(); it != _confirmTimes.end();)
{
if (Time::time() - it->second > Network::TIMEOUT)
if (Time::time() - it->second > Consts::NETWORK_TIMEOUT)
_confirmTimes.erase(it++);
else
++it;
@ -160,7 +160,7 @@ MsgType UDPSocket::receive(sf::Packet& packet, sf::Uint16& senderId)
if (type == MsgType::Connect)
{
sf::Uint32 version = 0;
if (!(packet >> version) || version != Network::VERSION)
if (!(packet >> version) || version != Consts::NETWORK_VERSION)
return MsgType::Error;
sf::Uint16 tmp;
for (tmp = 64; tmp >= 1; tmp--)
@ -193,3 +193,7 @@ bool UDPSocket::confirmed(sf::Uint16 msgId, sf::Uint16 senderId)
return repeat;
}
UDPSocket::~UDPSocket() {
unbind();
}

View File

@ -46,6 +46,8 @@ public:
void update();
MsgType receive(sf::Packet& packet, sf::Uint16& senderId);
~UDPSocket();
};

View File

@ -1,15 +0,0 @@
//
// Created by Иван Ильин on 05.04.2021.
//
#ifndef ENGINE_CONFIG_H
#define ENGINE_CONFIG_H
namespace Network {
const unsigned VERSION = 1U;
const int TIMEOUT = 1U;
const int WORLD_UPDATE_RATE = 30;
const double RELIABLE_RETRY_TIME = 1.0/20;
}
#endif //INC_3DZAVR_CONFIG_H

View File

@ -3,7 +3,6 @@
//
#include "RigidBody.h"
#include "../Plane.h"
#include "../utils/Log.h"
#include "../utils/Time.h"
#include <iostream>

View File

@ -82,6 +82,8 @@ public:
[[nodiscard]] const std::function<void(const std::string&, std::shared_ptr<RigidBody>)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const std::string&, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }
~RigidBody() override = default;
};

View File

@ -4,12 +4,13 @@
#include "../engine/ResourceManager.h"
#include "Ak47.h"
#include "../ShooterConsts.h"
using namespace std;
Ak47::Ak47(int ammo, const std::string& weaponName) : Weapon(weaponName, "obj/ak47.obj", "obj/ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/ak47.ogg"));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/reload_ak47.ogg"));
Ak47::Ak47(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::AK47_OBJ, "obj/ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_RELOAD_SOUND));
_stockAmmo = ammo - _clipCapacity;

View File

@ -6,12 +6,13 @@
#define SHOOTER_GOLD_AK47_H
#include "Weapon.h"
#include "../ShooterConsts.h"
class Gold_Ak47 final : public Weapon {
public:
explicit Gold_Ak47(int ammo = 200, const std::string& weaponName = "gold_ak47") : Weapon(weaponName, "obj/ak47.obj", "obj/gold_ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/ak47.ogg"));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/reload_ak47.ogg"));
explicit Gold_Ak47(int ammo = 200, const std::string& weaponName = "gold_ak47") : Weapon(weaponName, ShooterConsts::GOLD_AK47_OBJ, "obj/gold_ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_RELOAD_SOUND));
_initialPack = 200;
_spreading = 1.0;

View File

@ -4,12 +4,13 @@
#include "../engine/ResourceManager.h"
#include "Gun.h"
#include "../ShooterConsts.h"
using namespace std;
Gun::Gun(int ammo, const std::string& weaponName) : Weapon(weaponName, "obj/gun.obj", "obj/gun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/gun.ogg"));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/reload_gun.ogg"));
Gun::Gun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::GUN_OBJ, "obj/gun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_RELOAD_SOUND));
_initialPack = 30;
_clipCapacity = 6; // how much ammo can be stored in one clip

View File

@ -4,10 +4,11 @@
#include "../engine/ResourceManager.h"
#include "Rifle.h"
#include "../ShooterConsts.h"
Rifle::Rifle(int ammo, const std::string &weaponName) : Weapon(weaponName, "obj/rifle.obj", "obj/rifle_mat.txt", Vec3D{3, 3, 3}, Vec3D{-1.2, 1, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/shotgun.ogg"));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/reload_ak47.ogg"));
Rifle::Rifle(int ammo, const std::string &weaponName) : Weapon(weaponName, ShooterConsts::RIFLE_OBJ, "obj/rifle_mat.txt", Vec3D{3, 3, 3}, Vec3D{-1.2, 1, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_RELOAD_SOUND));
_initialPack = 5;
_clipCapacity = 1; // how much ammo can be stored in one clip

View File

@ -4,14 +4,14 @@
#include "../engine/ResourceManager.h"
#include "Shotgun.h"
#include "../engine/animation/AColor.h"
#include "../engine/animation/AFunction.h"
#include "../ShooterConsts.h"
using namespace std;
Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, "obj/shotgun.obj", "obj/shotgun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.95, 1.3, -0.6}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/shotgun.ogg"));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/reload_shotgun.ogg"));
Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::SHOTGUN_OBJ, "obj/shotgun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.95, 1.3, -0.6}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_RELOAD_SOUND));
//reloadSound.setVolume(30);
_initialPack = 15;
@ -25,24 +25,14 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, "
}
std::map<std::string, double>
Shotgun::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& pos, const Vec3D& direction) {
Shotgun::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<std::string, double> damagedPlayers;
for(int i = 0; i < 15; i++) {
//generate random vector
Vec3D randV(10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
// damage player
auto rayCast = rayCastFunction(pos, pos + direction * 1000 + randV);
if (rayCast.second.find("Enemy") != std::string::npos) {
damagedPlayers[rayCast.second] += _damage / (1.0 + (pos - rayCast.first).abs());
std::map<std::string, double> damaged = addTrace(rayCastFunction, position() + Vec3D(triangles().back()[0]), -lookAt());
for(auto& player : damaged)
damagedPlayers[player.first] += player.second;
}
Vec3D to = rayCast.first == Vec3D(0) ? pos + direction * 1000 + randV: rayCast.first;
Vec3D from = position() + Vec3D(triangles().back()[0]);
_addTraceCallBack(from, to);
}
return damagedPlayers;
}

View File

@ -10,7 +10,7 @@
class Shotgun final : public Weapon {
public:
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun");
std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) override;
std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) override;
};

View File

@ -2,13 +2,13 @@
// Created by Иван Ильин on 01.06.2021.
//
#include <sstream>
#include <utility>
#include "Weapon.h"
#include "../engine/ResourceManager.h"
#include "../engine/utils/Log.h"
#include "../engine/animation/AColor.h"
#include "../engine/animation/AFunction.h"
#include "../ShooterConsts.h"
using namespace std;
@ -20,10 +20,10 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
rotate(r);
translate(t);
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/weapons/no_ammo.ogg"));
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::NO_AMMO_SOUND));
}
std::map<std::string, double> Weapon::fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
std::map<std::string, double> Weapon::fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
if(_clipAmmo == 0) {
reload();
if(_clipAmmo == 0)
@ -39,7 +39,7 @@ std::map<std::string, double> Weapon::fire(std::function<std::pair<Vec3D, std::s
fireSound.play();
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
return processFire(std::move(rayCastFunction), position, direction);
return processFire(std::move(rayCastFunction));
}
void Weapon::reload() {
@ -58,21 +58,26 @@ void Weapon::reload() {
_lastReloadTime = Time::time();
}
std::map<std::string, double> Weapon::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& pos, const Vec3D& direction) {
std::map<std::string, double> Weapon::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
return addTrace(std::move(rayCastFunction), position() + Vec3D(triangles().back()[0]), -lookAt());
}
std::map<std::string, double> Weapon::addTrace(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
std::map<std::string, double> damagedPlayers;
double spreading = _spreading*ShooterConsts::FIRE_DISTANCE/100;
//generate random vector
Vec3D randV(10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
Vec3D randV(spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
// damage player
auto rayCast = rayCastFunction(pos, pos + direction * 1000 + randV);
auto rayCast = rayCastFunction(from, from + directionTo * ShooterConsts::FIRE_DISTANCE + randV);
if(rayCast.second.find("Enemy") != std::string::npos) {
damagedPlayers[rayCast.second] += _damage/(1.0 + (pos - rayCast.first).abs());
damagedPlayers[rayCast.second] += _damage/(1.0 + (from - rayCast.first).abs());
}
// add trace line
Vec3D to = rayCast.first == Vec3D(0) ? pos + direction * 1000 + randV: rayCast.first;
Vec3D from = position() + Vec3D(triangles().back()[0]);
Vec3D to = rayCast.first == Vec3D(0) ? from + directionTo * ShooterConsts::FIRE_DISTANCE + randV: rayCast.first;
_addTraceCallBack(from, to);
return damagedPlayers;

View File

@ -29,7 +29,7 @@ protected:
double _spreading = 2.0;
std::string _name = "Weapon_name";
std::string _name = "Weapon";
double _lastFireTime = std::numeric_limits<double>::min();
double _lastReloadTime = std::numeric_limits<double>::min();
@ -42,12 +42,14 @@ protected:
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
virtual std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
std::map<std::string, double> addTrace(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
virtual std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction);
public:
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Vec3D& scale, const Vec3D& translate, const Vec3D& rotate);
std::map<std::string, double> fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
std::map<std::string, double> fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction);
void reload();
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }