From 8a2d67ec2a040148c9830ba39c5dc5f7e2cf0655 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Fri, 6 Jun 2025 16:33:55 +0300 Subject: [PATCH] EMP boat moved explode() to the Environment class --- .../Projectiles/projectileData.lua | 15 +++- Assets/Scripts/GameObjects/Units/unitData.lua | 82 ++++++++++++++----- CMakeLists.txt | 11 ++- environment.cpp | 58 +++++++++++++ environment.h | 20 +++++ game.cpp | 41 ---------- game.h | 1 - projectile.cpp | 5 +- unit.cpp | 11 ++- unit.h | 12 +-- weapon.cpp | 2 +- 11 files changed, 180 insertions(+), 78 deletions(-) create mode 100644 environment.cpp create mode 100644 environment.h diff --git a/Assets/Scripts/GameObjects/Projectiles/projectileData.lua b/Assets/Scripts/GameObjects/Projectiles/projectileData.lua index a7c9969..949f41f 100644 --- a/Assets/Scripts/GameObjects/Projectiles/projectileData.lua +++ b/Assets/Scripts/GameObjects/Projectiles/projectileData.lua @@ -1,4 +1,4 @@ -ProjectileId = {SHELL = 0, CRUISE_MISSILE = 1, MISSILE = 2, TORPEDO = 3} +ProjectileId = {HE_SHELL = 0, EMP_SHELL = 1, CRUISE_MISSILE = 2, MISSILE = 3, TORPEDO = 4} ProjectileClass = {SHELL = 0, CRUISE_MISSILE = 1, MISSILE = 2, TORPEDO = 3} G = 9.8 @@ -16,6 +16,19 @@ projectiles = { meshPath = "shell.xml", albedoPath = 'shell.jpg' }, + { + projectileClass = ProjectileClass.SHELL, + size = {x = 1, y = 1, z = 1}, + speed = 5, + rotAngle = .1, + explosion = {damage = 0, radius = 20, sfx = PATH .. 'Sounds/SFX/Explosions/explosion02.ogg'}, + directHitDamage = 0, + rayLength = 1, + name = "Shell", + basePath = PATH .. "Models/GameObjects/Projectiles/Shells/", + meshPath = "shell.xml", + albedoPath = 'shell.jpg' + }, { projectileClass = ProjectileClass.CRUISE_MISSILE, size = {x = 6, y = 13.5, z = 2.54}, diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index e75829e..432786a 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -31,15 +31,16 @@ UnitId = { STEALTH_SUBMARINE = 14, ICEBREAKER = 15, FREEZER = 16, - LAND_FACTORY = 17, - NAVAL_FACTORY = 18, - TRADE_CENTER = 19, - LAB = 20, - POINT_DEFENSE = 21, - EXTRACTOR = 22, - REFINERY = 23, - FORT = 24, - ICE_SHEET = 25 + EMP_BOAT = 17, + LAND_FACTORY = 18, + NAVAL_FACTORY = 19, + TRADE_CENTER = 20, + LAB = 21, + POINT_DEFENSE = 22, + EXTRACTOR = 23, + REFINERY = 24, + FORT = 25, + ICE_SHEET = 26 } WeaponClass = {FREEZE = 1} UnitClass = { @@ -54,15 +55,16 @@ UnitClass = { SUBMARINE = 8, ICEBREAKER = 9, FREEZER = 10, - LAND_FACTORY = 11, - NAVAL_FACTORY = 12, - TRADE_CENTER = 13, - LAB = 14, - POINT_DEFENSE = 15, - EXTRACTOR = 16, - REFINERY = 17, - FORT = 18, - ICE_SHEET = 19 + EMP_BOAT = 11, + LAND_FACTORY = 12, + NAVAL_FACTORY = 13, + TRADE_CENTER = 14, + LAB = 15, + POINT_DEFENSE = 16, + EXTRACTOR = 17, + REFINERY = 18, + FORT = 19, + ICE_SHEET = 20 } UnitType = {UNDERWATER = 0, SEA_LEVEL = 1, HOVER = 2, LAND = 3, AIR = 4} @@ -172,7 +174,7 @@ units = { damage = 200, maxRange = 25, horizontalNode = {name = 'Turret', rotationSpeed = .05, maxFireAngle = .1}, - projectile = {id = ProjectileId.SHELL, parent = 'Turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = 1, x = 0, y = 0, z = 0}}, + projectile = {id = ProjectileId.HE_SHELL, parent = 'Turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = 1, x = 0, y = 0, z = 0}}, fireFx = { { vfx = false, @@ -402,7 +404,7 @@ units = { { orderType = OrderType.ATTACK, rateOfFire = 200, - damage = 300, + damage = 10, maxRange = 50, fireFx = { { @@ -870,6 +872,46 @@ units = { maxTurnAngle = .1, garrisonCategory = 3 }, + { + weapons = { + { + orderType = OrderType.ATTACK, + rateOfFire = 1000, + damage = 0, + maxRange = 25, + horizontalNode = {name = 'turret', rotationSpeed = .05, maxFireAngle = .1}, + projectile = {id = ProjectileId.EMP_SHELL, parent = 'turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = .998, x = -.066, y = 0, z = 0}}, + fireFx = { + { + vfx = false, + duration = 300, + path = PATH .. 'Sounds/Units/Tanks/attack.ogg', + }, + }, + } + }, + unitClass = UnitClass.EMP_BOAT, + unitType = UnitType.SEA_LEVEL, + isVehicle = true, + health = 500, + buildTime = 1000, + cost = 500, + size = {x = 4.75, y = 5.15, z = 19.55}, + hitboxOffset = {x = 0, y = .18, z = .25}, + lineOfSight = 25, + name = 'EMP boat', + --colorNodes = {'stealthSubmarine.001'}, + basePath = PATH .. vehiclePrefix .. 'EMPShips/', + meshPath = 'empShip.xml', + albedoPath = 'empShip.jpg', + selectionSfx = PATH .. 'Sounds/Units/Submarines/selection.ogg', + deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', + speed = .1, + destinationOffset = .1, + anglePrecision = .1, + maxTurnAngle = .1, + garrisonCategory = 3 + }, { buildableUnits = { {id = UnitId.WAR_MECH, buildable = true, trigger = 87}, diff --git a/CMakeLists.txt b/CMakeLists.txt index 481c7a0..4443f17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,26 +16,29 @@ set(BUILD_TESTS ON) set(BUILD_SHARED_LIBS OFF CACHE BOOL FORCED) cmake_policy(SET CMP0015 NEW) +set(STATES activeGameState.cpp inGameAppState.cpp guiAppState.cpp mapEditorAppState.cpp loadingAppState.cpp) + set(UNIT_BUTTONS unitButton.cpp tradeButton.cpp buildButton.cpp trainButton.cpp researchButton.cpp orderButton.cpp stateToggleButton.cpp) set(OPTIONS_BUTTONS optionsButton.cpp tabButton.cpp okButton.cpp defaultsButton.cpp) set(TRADING_BUTTONS activeStateBackButton.cpp playerTradeButton.cpp tradingScreenButton.cpp offerButton.cpp resourceAmmountButton.cpp) set(MENU_BUTTONS mainMenuButton.cpp singlePlayerButton.cpp exitButton.cpp backButton.cpp playButton.cpp) set(MAP_EDITOR_BUTTONS mapEditorButton.cpp newMapButton.cpp loadMapButton.cpp exportButton.cpp) set(BUTTONS statsButton.cpp activeStateButton.cpp minimapButton.cpp ${TRADING_BUTTONS} ${OPTIONS_BUTTONS} ${MENU_BUTTONS} ${MAP_EDITOR_BUTTONS} ${UNIT_BUTTONS}) - set(LISTBOXES skyboxTextureListbox.cpp landTextureListbox.cpp gameObjectListbox.cpp mapListbox.cpp) set(GUI tooltip.cpp concreteGuiManager.cpp ${BUTTONS} ${LISTBOXES}) -set(STATES activeGameState.cpp inGameAppState.cpp guiAppState.cpp mapEditorAppState.cpp loadingAppState.cpp) -set(UTIL util.cpp binds.h) set(CONTROLLERS gameObjectFrameController.cpp cameraController.cpp) set(CONSOLE console.cpp abstractCommand.cpp addUnitCommand.cpp addResourceCommand.cpp addTechnologyCommand.cpp toggleDebugCommand.cpp) -set(CORE gameManager.cpp game.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS}) +set(CORE gameManager.cpp game.cpp environment.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS}) + set(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.cpp) set(VEHICLES vehicle.cpp submarine.cpp engineer.cpp resourceRover.cpp) set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp researchStruct.cpp iceSheet.cpp) set(UNITS gameObjectFactory.cpp unit.cpp weapon.cpp ${STRUCTURES} ${VEHICLES}) set(CONTENT player.cpp trader.cpp pathfinder.cpp map.cpp gameObject.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES}) + +set(UTIL util.cpp binds.h) + set(GAME_SRC ${STATES} ${GUI} ${CORE} ${CONTENT} ${UTIL}) set(SFML_DIR external/SFML) diff --git a/environment.cpp b/environment.cpp new file mode 100644 index 0000000..fe0e83e --- /dev/null +++ b/environment.cpp @@ -0,0 +1,58 @@ +#include "environment.h" + +#include + +namespace battleship{ + using namespace std; + using namespace vb01; + + static Environment *environment = nullptr; + + static Environment* getSingleton(){ + if(!environment) + environment = new Environment(); + + return environment; + } + + static Environment::explode(Vector3 pos, int damage, float radius, sf::Sound *explosionSfx){ + if(!(damage == 0 || radius == 0)) + for(Player *pl : players){ + for(Unit *un : pl->getUnits()){ + float distance = un->getPos().getDistanceFrom(pos); + + if(distance < radius) + un->takeDamage(int(damage * (1.f - distance / radius))); + } + } + + Root *root = Root::getSingleton(); + + const int numFrames = 1; + string p[numFrames]; + + for(int i = 0; i < numFrames; i++) + p[i] = GameManager::getSingleton()->getPath() + "Textures/Explosion/explosion07.png"; + + Texture *tex = new Texture(p, numFrames, false); + + Material *mat = new Material(root->getLibPath() + "particle"); + mat->addTexUniform("tex", tex, true); + + ParticleEmitter *pe = new ParticleEmitter(1); + pe->setMaterial(mat); + pe->setLowLife(3); + pe->setHighLife(3); + pe->setSize(10 * Vector2::VEC_IJ); + pe->setSpeed(0); + + Node *node = new Node(pos + Vector3(0, 2, 0)); + node->attachParticleEmitter(pe); + node->lookAt(Vector3::VEC_J, Vector3::VEC_K); + root->getRootNode()->attachChild(node); + + typedef FxManager::Fx Fx; + typedef FxManager::Fx::Component Component; + FxManager::getSingleton()->addFx(new Fx(vector{Component((void*)node, true, 50), Component((void*)explosionSfx, false, 2500)})); + } +} diff --git a/environment.h b/environment.h new file mode 100644 index 0000000..634de46 --- /dev/null +++ b/environment.h @@ -0,0 +1,20 @@ +#ifndef ENVIRONMENT_H +#define ENVIRONMENT_H + +#include + +namespace sf{ + class Sound; +} + +namespace battleship{ + class Environment{ + public: + static Environment* getSingleton(); + static void explode(vb01::Vector3, int, float, sf::Sound*); + private: + Environment(){} + }; +} + +#endif diff --git a/game.cpp b/game.cpp index 1427a4d..68e4ac2 100644 --- a/game.cpp +++ b/game.cpp @@ -137,47 +137,6 @@ namespace battleship{ paused = !paused; } - void Game::explode(Vector3 pos, int damage, float radius, sf::Sound *explosionSfx){ - if(!(damage == 0 || radius == 0)) - for(Player *pl : players){ - for(Unit *un : pl->getUnits()){ - float distance = un->getPos().getDistanceFrom(pos); - - if(distance < radius) - un->takeDamage(int(damage * (1.f - distance / radius))); - } - } - - Root *root = Root::getSingleton(); - - const int numFrames = 1; - string p[numFrames]; - - for(int i = 0; i < numFrames; i++) - p[i] = GameManager::getSingleton()->getPath() + "Textures/Explosion/explosion07.png"; - - Texture *tex = new Texture(p, numFrames, false); - - Material *mat = new Material(root->getLibPath() + "particle"); - mat->addTexUniform("tex", tex, true); - - ParticleEmitter *pe = new ParticleEmitter(1); - pe->setMaterial(mat); - pe->setLowLife(3); - pe->setHighLife(3); - pe->setSize(10 * Vector2::VEC_IJ); - pe->setSpeed(0); - - Node *node = new Node(pos + Vector3(0, 2, 0)); - node->attachParticleEmitter(pe); - node->lookAt(Vector3::VEC_J, Vector3::VEC_K); - root->getRootNode()->attachChild(node); - - typedef FxManager::Fx Fx; - typedef FxManager::Fx::Component Component; - FxManager::getSingleton()->addFx(new Fx(vector{Component((void*)node, true, 50), Component((void*)explosionSfx, false, 2500)})); - } - void Game::changeUnitPlayer(Unit *unit, Player *newPlayer){ Player *oldPlayer = unit->getPlayer(); vector &oldPlayerUnits = oldPlayer->getUnits(); diff --git a/game.h b/game.h index f9fde6e..1d862af 100644 --- a/game.h +++ b/game.h @@ -22,7 +22,6 @@ namespace battleship{ void update(); void togglePause(); void removeAllElements(); - void explode(vb01::Vector3, int, float, sf::Sound*); void changeUnitPlayer(Unit*, Player*); void initTechnologies(); float calcAbilFromTech(Ability::Type, std::vector, int, int); diff --git a/projectile.cpp b/projectile.cpp index b10f147..5f7750c 100755 --- a/projectile.cpp +++ b/projectile.cpp @@ -10,6 +10,7 @@ #include "unit.h" #include "util.h" #include "player.h" +#include "environment.h" #include "projectile.h" #include "defConfigs.h" #include "resourceDeposit.h" @@ -96,7 +97,7 @@ namespace battleship{ for(int i = 0; i < targetNodes.size(); i++) if(targetNodes[i]->getMesh(0) == results[0].mesh){ targetUnits[i]->takeDamage(directHitDamage); - Game::getSingleton()->explode(pos, explosionDamage, explosionRadius, explosionSfx); + Environment::getSingleton()->explode(pos, explosionDamage, explosionRadius, explosionSfx); remove = true; } } @@ -107,7 +108,7 @@ namespace battleship{ int cellId = map->getCellId(pos, false); if((pos + dirVec * rayLength).y <= map->getCells()[cellId].pos.y){ - Game::getSingleton()->explode(pos, explosionDamage, explosionRadius, explosionSfx); + Environment::getSingleton()->explode(pos, explosionDamage, explosionRadius, explosionSfx); remove = true; } } diff --git a/unit.cpp b/unit.cpp index 18610de..f03d39b 100755 --- a/unit.cpp +++ b/unit.cpp @@ -18,6 +18,7 @@ #include "game.h" #include "map.h" #include "vehicle.h" +#include "environment.h" #include "gameObjectFactory.h" #include "activeGameState.h" #include "gameManager.h" @@ -34,6 +35,7 @@ using namespace std; namespace battleship{ Unit::Unit(Player *player, int id, Vector3 pos, Quaternion rot, State st) : GameObject(GameObject::Type::UNIT, id, player, pos, rot), state(st){ selectable = true; + restartTime = 2000; Unit::initProperties(); initModel(); @@ -298,7 +300,10 @@ namespace battleship{ void Unit::update() { GameObject::update(); - if(freezeStatus >= 100) enabled = false; + if(condition == Condition::EM_JAMMED && getTime() - lastJamTime > restartTime) + condition = Condition::ABLE; + + if(freezeStatus >= 100) condition = Condition::FROZEN; ActiveGameState *activeState = (ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE); Player *mainPlayer = (activeState ? activeState->getPlayer() : nullptr); @@ -320,7 +325,7 @@ namespace battleship{ displayUnitStats(slot.foreground, slot.background, (int)((bool)slot.vehicle), (int)true, renderSelectables, slot.offset); if (health <= DEATH_HP){ - Game::getSingleton()->explode(pos, 0, 0, deathSfx); + Environment::getSingleton()->explode(pos, 0, 0, deathSfx); remove = true; } @@ -349,7 +354,7 @@ namespace battleship{ //TODO remove order argument from action methods void Unit::executeOrders() { - if(!enabled) return; + if(condition != Condition::ABLE) return; if (orders.size() > 0) { Order order = orders[0]; diff --git a/unit.h b/unit.h index 3bf8fda..b2f001f 100755 --- a/unit.h +++ b/unit.h @@ -77,6 +77,7 @@ namespace battleship{ SUBMARINE, ICEBREAKER, FREEZER, + EMP_BOAT, LAND_FACTORY, NAVAL_FACTORY, TRADE_CENTER, @@ -90,7 +91,6 @@ namespace battleship{ class Unit : public GameObject{ public: - struct GarrisonSlot{ Vehicle *vehicle = nullptr; int category; @@ -102,6 +102,7 @@ namespace battleship{ enum class Armor {CAST, COMBINED, MECHANIC, SHELL, STEEL}; enum class State {CHASE, STAND_GROUND, HOLD_FIRE}; + enum class Condition{ABLE, FROZEN, EM_JAMMED}; Unit(Player*, int, vb01::Vector3, vb01::Quaternion, State = State::STAND_GROUND); virtual ~Unit(); @@ -140,7 +141,7 @@ namespace battleship{ inline vb01::Node* getLosLightNode(){return losLightNode;} inline void setFreezeStatus(int fs){this->freezeStatus = std::clamp(fs, 0, 100);} inline int getFreezeStatus(){return freezeStatus;} - inline bool isEnabled(){return enabled;} + inline Condition getCondition(){return condition;} private: void renderOrderLine(bool); void updateScreenCoordinates(); @@ -153,14 +154,15 @@ namespace battleship{ sf::SoundBuffer *selectionSfxBuffer; sf::Sound *selectionSfx = nullptr; vb01::Node *hpBackgroundNode = nullptr, *hpForegroundNode = nullptr, *losLightNode = nullptr; - bool vehicle, enabled = true; + bool vehicle; + Condition condition = Condition::ABLE; protected: UnitClass unitClass; UnitType type; std::vector orders; std::string guiScreen = ""; - int health = 0, maxHealth, playerId, lenHpBar = 200, freezeStatus = 0, freezeDmgFactor = 10; - vb01::s64 orderLineDispTime = 0, lastFireTime = 0; + int health = 0, maxHealth, playerId, lenHpBar = 200, freezeStatus = 0, freezeDmgFactor = 10, restartTime; + vb01::s64 orderLineDispTime = 0, lastFireTime = 0, lastJamTime = 0; float lineOfSight; std::vector armorTypes; std::vector weapons; diff --git a/weapon.cpp b/weapon.cpp index ac04593..6b30bb5 100644 --- a/weapon.cpp +++ b/weapon.cpp @@ -232,7 +232,7 @@ namespace battleship{ //TODO replace unit pos with absolute weapon pos for withinAngle void Weapon::update(){ - if(!unit->isEnabled()) return; + if(unit->getCondition() != Unit::Condition::ABLE) return; int numOrders = unit->getNumOrders(); int ordTp = (numOrders > 0 ? (int)unit->getOrder(0).type : -1);