mirror of
https://github.com/devZoGok/PlanetFleet.git
synced 2026-08-26 19:43:29 +00:00
Merge pull request #211 from devZoGok/imp-207-shoot-down-missiles
Imp 207 shoot down missiles
This commit is contained in:
@@ -46,7 +46,7 @@ function Player:buildFort(arguments)
|
||||
angle = self.baseDir:getAngleBetween(Vector3:new(0, 0, 1)) * (right and -1 or 1)
|
||||
fort = GameObjectFactory.createUnit(self, UnitId.FORT, sp, Quaternion:new(angle, Vector3:new(0, 1, 0)), 0)
|
||||
self:addUnit(fort)
|
||||
self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(fort, Vector3:new(0, 0, 0))}, false)
|
||||
self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(fort:toGameObject(), Vector3:new(0, 0, 0))}, false)
|
||||
|
||||
return BTNodeResult.RUNNING
|
||||
end
|
||||
@@ -84,7 +84,7 @@ function Player:buildStructure(engineer, buildingId, buildPos, buildAngle)
|
||||
|
||||
building = GameObjectFactory.createUnit(self, buildingId, buildPos, Quaternion:new(1, 0, 0, 0), 0)
|
||||
self:addUnit(building)
|
||||
self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(building, Vector3:new(0, 0, 0))}, false)
|
||||
self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(building:toGameObject(), Vector3:new(0, 0, 0))}, false)
|
||||
end
|
||||
|
||||
building = self:getUnitsByClass(unitClass, 1)[1]
|
||||
@@ -155,7 +155,7 @@ function Player:startHarvesting()
|
||||
|
||||
self:deselectUnits()
|
||||
self:selectUnits({harvesters[1]})
|
||||
self:issueOrder(OrderType.SUPPLY, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false)
|
||||
self:issueOrder(OrderType.SUPPLY, Vector3:new(0, 0, 0), {Target:new(extractor:toGameObject(), Vector3:new(0, 0, 0))}, false)
|
||||
|
||||
return BTNodeResult.SUCCESS
|
||||
end
|
||||
@@ -258,7 +258,7 @@ function Player:clearNearEnemies(arguments)
|
||||
if not taskForce.clearing and targUnit then
|
||||
self:deselectUnits()
|
||||
self:selectUnits(taskForce.units)
|
||||
self:issueOrder(OrderType.MOVE, Vector3:new(0, 0, 0), {Target:new(targUnit, Vector3:new(0, 0, 0))}, false)
|
||||
self:issueOrder(OrderType.MOVE, Vector3:new(0, 0, 0), {Target:new(targUnit:toGameObject(), Vector3:new(0, 0, 0))}, false)
|
||||
|
||||
self.taskForces[arguments.tfId].clearing = true
|
||||
elseif taskForce.clearing and not targUnit then
|
||||
|
||||
@@ -51,6 +51,7 @@ projectiles = {
|
||||
},
|
||||
{
|
||||
projectileClass = ProjectileClass.CRUISE_MISSILE,
|
||||
health = 75,
|
||||
size = {x = 6, y = 13.5, z = 2.54},
|
||||
speed = .5,
|
||||
rotAngle = .1,
|
||||
@@ -64,6 +65,7 @@ projectiles = {
|
||||
},
|
||||
{
|
||||
projectileClass = ProjectileClass.MISSILE,
|
||||
health = 25,
|
||||
size = {x = 3, y = 7., z = 1.27},
|
||||
speed = .5,
|
||||
rotAngle = .1,
|
||||
|
||||
@@ -173,7 +173,8 @@ units = {
|
||||
rateOfFire = 1000,
|
||||
damage = 200,
|
||||
maxRange = 50,
|
||||
nodes = {{name = 'Turret', rotationSpeed = .05, maxFireAngle = .1}},
|
||||
maxFireAngle = .1,
|
||||
nodes = {{name = 'Turret', rotationSpeed = .05, vertical = false}},
|
||||
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 = {
|
||||
{
|
||||
@@ -230,9 +231,10 @@ units = {
|
||||
rateOfFire = 2000,
|
||||
damage = 5000,
|
||||
maxRange = 70,
|
||||
maxFireAngle = .1,
|
||||
nodes = {
|
||||
{name = 'turret', rotationSpeed = .05, maxFireAngle = .1},
|
||||
{name = 'tubes', rotationSpeed = .05, maxFireAngle = .1}
|
||||
{name = 'turret', rotationSpeed = .05, vertical = false},
|
||||
--{name = 'tubes', rotationSpeed = .05, vertical = true}
|
||||
},
|
||||
projectile = {id = ProjectileId.MISSILE, parent = 'tubes', pos = {x = 0.95, y = 2.16, z = 4.11}, rot = {w = 1, x = 0, y = 0, z = 0}},
|
||||
fireFx = {
|
||||
@@ -896,7 +898,8 @@ units = {
|
||||
rateOfFire = 1000,
|
||||
damage = 0,
|
||||
maxRange = 25,
|
||||
nodes = {{name = 'turret', rotationSpeed = .05, maxFireAngle = .1}},
|
||||
maxFireAngle = .1,
|
||||
nodes = {{name = 'turret', rotationSpeed = .05, vertical = false}},
|
||||
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 = {
|
||||
{
|
||||
@@ -1024,11 +1027,12 @@ units = {
|
||||
{
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 100,
|
||||
damage = 50,
|
||||
maxRange = 50,
|
||||
damage = 17,
|
||||
maxRange = 100,
|
||||
maxFireAngle = .4,
|
||||
nodes = {
|
||||
{name = 'TurretBody', rotationSpeed = .05, maxFireAngle = .1},
|
||||
{name = 'TurretArms', rotationSpeed = .05, maxFireAngle = .1}
|
||||
{name = 'TurretBody', rotationSpeed = .1, vertical = false},
|
||||
{name = 'TurretArms', rotationSpeed = .1, angleConstraint = 1.1, vertical = true}
|
||||
},
|
||||
fireFx = {
|
||||
{
|
||||
|
||||
+5
-3
@@ -24,18 +24,20 @@ set(TRADING_BUTTONS activeStateBackButton.cpp playerTradeButton.cpp tradingScree
|
||||
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(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 environment.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS})
|
||||
set(CORE gameManager.cpp game.cpp pathfinder.cpp environment.cpp fxManager.cpp defConfigs.cpp player.cpp trader.cpp ${CONSOLE} ${CONTROLLERS})
|
||||
|
||||
set(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.cpp)
|
||||
set(VEHICLES vehicle.cpp submarine.cpp engineer.cpp resourceRover.cpp freezer.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(WEAPONS weapon.cpp cryoGun.cpp)
|
||||
set(UNITS unit.cpp ${WEAPONS} ${STRUCTURES} ${VEHICLES})
|
||||
set(CONTENT map.cpp gameObject.cpp destructable.cpp gameObjectFrame.h gameObjectFactory.cpp resourceDeposit.cpp ${UNITS} ${PROJECTILES})
|
||||
|
||||
set(UTIL util.cpp binds.h)
|
||||
|
||||
|
||||
+19
-13
@@ -1,4 +1,5 @@
|
||||
#include "cruiseMissile.h"
|
||||
#include "destructable.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "map.h"
|
||||
@@ -12,7 +13,13 @@ namespace battleship{
|
||||
using namespace std;
|
||||
using namespace vb01;
|
||||
|
||||
CruiseMissile::CruiseMissile(Unit *unit, int id, Vector3 tp, Vector3 pos, Quaternion rot) : Projectile(unit, id, pos, rot), targetPoint(tp), flightStage(FlightStage::ASCENT){
|
||||
CruiseMissile::CruiseMissile(Unit *unit, int id, Vector3 tp, Vector3 pos, Quaternion rot) :
|
||||
Projectile(unit, id, pos, rot),
|
||||
targetPoint(tp),
|
||||
flightStage(FlightStage::ASCENT)
|
||||
{
|
||||
destructable = new Destructable(this);
|
||||
|
||||
Vector3 unitDir = unit->getDirVec();
|
||||
Vector3 leftDir = unit->getLeftVec();
|
||||
Vector3 targDir = (Vector3(targetPoint.x, pos.y, targetPoint.z) - pos).norm();
|
||||
@@ -22,20 +29,22 @@ namespace battleship{
|
||||
orientAt(Quaternion(angle, Vector3::VEC_J) * rot);
|
||||
}
|
||||
|
||||
CruiseMissile::~CruiseMissile(){delete destructable;}
|
||||
|
||||
void CruiseMissile::pitch(float rotAngle, Vector3 compVec){
|
||||
float minHeight = 20;
|
||||
float angleToCompVec = dirVec.getAngleBetween(compVec);
|
||||
float angleToCompVec = Projectile::dirVec.getAngleBetween(compVec);
|
||||
float angle = (angleToCompVec > rotAngle ? rotAngle : angleToCompVec);
|
||||
|
||||
if(flightStage == FlightStage::ASCENT && pos.y - initPos.y > minHeight){
|
||||
orientAt(Quaternion(angle, leftVec) * rot);
|
||||
if(dirVec.y <= .001) flightStage = FlightStage::CRUISE;
|
||||
if(flightStage == FlightStage::ASCENT && Projectile::pos.y - initPos.y > minHeight){
|
||||
Projectile::orientAt(Quaternion(angle, Projectile::leftVec) * Projectile::rot);
|
||||
if(Projectile::dirVec.y <= .001) flightStage = FlightStage::CRUISE;
|
||||
}
|
||||
else if(flightStage == FlightStage::DESCENT){
|
||||
Vector3 targDir = (Vector3(targetPoint.x, initPos.y, targetPoint.z) - initPos).norm();
|
||||
|
||||
if(dirVec.getAngleBetween(targDir) < PI / 2)
|
||||
orientAt(Quaternion(angle, leftVec) * rot);
|
||||
if(Projectile::dirVec.getAngleBetween(targDir) < PI / 2)
|
||||
Projectile::orientAt(Quaternion(angle, Projectile::leftVec) * Projectile::rot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,16 +52,17 @@ namespace battleship{
|
||||
float minDist = 6;
|
||||
float initDist = Vector3(targetPoint.x, initPos.y, targetPoint.z).getDistanceFrom(initPos);
|
||||
|
||||
if(pos.getDistanceFrom(Vector3(targetPoint.x, pos.y, targetPoint.z)) < minDist)
|
||||
if(Projectile::pos.getDistanceFrom(Vector3(targetPoint.x, Projectile::pos.y, targetPoint.z)) < minDist)
|
||||
flightStage = FlightStage::DESCENT;
|
||||
}
|
||||
|
||||
void CruiseMissile::update(){
|
||||
Projectile::update();
|
||||
destructable->update();
|
||||
|
||||
switch(flightStage){
|
||||
case FlightStage::ASCENT:
|
||||
pitch(rotAngle, Vector3(dirVec.x, 0, dirVec.z).norm());
|
||||
pitch(rotAngle, Vector3(Projectile::dirVec.x, 0, Projectile::dirVec.z).norm());
|
||||
break;
|
||||
case FlightStage::DESCENT:
|
||||
pitch(rotAngle, -Vector3::VEC_J);
|
||||
@@ -62,10 +72,6 @@ namespace battleship{
|
||||
break;
|
||||
}
|
||||
|
||||
checkCollision();
|
||||
}
|
||||
|
||||
void CruiseMissile::checkCollision(){
|
||||
if(flightStage == FlightStage::DESCENT)
|
||||
Projectile::checkCollision();
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,7 @@ namespace battleship{
|
||||
class CruiseMissile : public Projectile{
|
||||
public:
|
||||
CruiseMissile(Unit*, int, vb01::Vector3, vb01::Vector3, vb01::Quaternion);
|
||||
~CruiseMissile();
|
||||
void update();
|
||||
private:
|
||||
enum class FlightStage{ASCENT, CRUISE, DESCENT};
|
||||
@@ -15,7 +16,6 @@ namespace battleship{
|
||||
|
||||
void pitch(float, vb01::Vector3);
|
||||
void cruise();
|
||||
void checkCollision();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#include "cryoGun.h"
|
||||
#include "destructable.h"
|
||||
#include "unit.h"
|
||||
|
||||
namespace battleship{
|
||||
using namespace std;
|
||||
using namespace vb01;
|
||||
using namespace gameBase;
|
||||
|
||||
CryoGun::CryoGun(Unit *u, sol::table unitTable, int wid) : Weapon(u, unitTable, wid){}
|
||||
|
||||
void CryoGun::updateTarget(GameObject *target){
|
||||
if(canFreeze()){
|
||||
Destructable *destructTarg = target->getDestructable();
|
||||
destructTarg->setFreezeStatus(destructTarg->getFreezeStatus() + 1);
|
||||
lastFreezeTime = getTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef CRYOGUN_H
|
||||
#define CRYOGUN_H
|
||||
|
||||
#include "weapon.h"
|
||||
|
||||
#include <util.h>
|
||||
|
||||
#include <solUtil.h>
|
||||
|
||||
namespace battleship{
|
||||
class Unit;
|
||||
|
||||
class CryoGun : public Weapon{
|
||||
public:
|
||||
CryoGun(Unit*, sol::table, int);
|
||||
private:
|
||||
vb01::s64 lastFreezeTime = 0;
|
||||
|
||||
void updateTarget(GameObject*);
|
||||
inline bool canFreeze(){return vb01::getTime() - lastFreezeTime > rateOfFire;}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "destructable.h"
|
||||
#include "environment.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <root.h>
|
||||
#include <node.h>
|
||||
#include <quad.h>
|
||||
#include <material.h>
|
||||
|
||||
#include <solUtil.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace vb01;
|
||||
using namespace gameBase;
|
||||
|
||||
namespace battleship{
|
||||
Destructable::Destructable(GameObject *obj) : gameObject(obj){
|
||||
initProperties();
|
||||
}
|
||||
|
||||
void Destructable::initProperties(){
|
||||
//GameObject::initProperties();
|
||||
|
||||
int id = gameObject->getId();
|
||||
sol::state_view SOL_LUA_VIEW = generateView();
|
||||
string objType = gameObject->getGameObjTableName();
|
||||
sol::table objTable = SOL_LUA_VIEW[objType][gameObject->getId() + 1];
|
||||
|
||||
vector<int> currTechs = gameObject->getPlayer()->getTechnologies();
|
||||
health += Game::getSingleton()->calcAbilFromTech(Ability::Type::HEALTH, currTechs, (int)gameObject->getType(), id);
|
||||
maxHealth = objTable["health"];
|
||||
|
||||
if(health == 0) health = maxHealth;
|
||||
|
||||
string tblName = "armor";
|
||||
sol::optional<sol::table> at = objTable[tblName];
|
||||
|
||||
if(at != sol::nullopt){
|
||||
string varName = "numArmorTypes";
|
||||
SOL_LUA_VIEW.script(varName + " = #" + objType + "[" + to_string(id + 1) + "]." + tblName);
|
||||
int numArmorTypes = SOL_LUA_VIEW[varName];
|
||||
|
||||
for(int i = 0; i < numArmorTypes; i++){
|
||||
Armor arm = (Armor)objTable[tblName][i + 1];
|
||||
armorTypes.push_back(arm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO make this class a friend to GameObject
|
||||
void Destructable::update(){
|
||||
if (health <= DEATH_HP){
|
||||
gameObject->setRemove(true);
|
||||
|
||||
sol::optional<sol::table> tblOpt = generateView()[gameObject->getGameObjTableName()][gameObject->getId() + 1]["deathFx"];
|
||||
|
||||
if(tblOpt == sol::nullopt) return;
|
||||
|
||||
Vector3 pos = gameObject->getPos();
|
||||
sol::table tbl = generateView()[gameObject->getGameObjTableName()][gameObject->getId() + 1]["deathFx"];
|
||||
FxManager::Fx *fx = FxManager::getSingleton()->initFx(tbl, gameObject->getModel(), false, pos);
|
||||
Environment::explode(fx, Environment::Detonation::EXPLOSION, pos);
|
||||
}
|
||||
}
|
||||
|
||||
Node* Destructable::createBar(Vector2 pos, Vector2 size, Vector4 color){
|
||||
Root *root = Root::getSingleton();
|
||||
Material *mat = new Material(root->getLibPath() + "gui");
|
||||
mat->addBoolUniform("texturingEnabled", false);
|
||||
mat->addVec4Uniform("diffuseColor", color);
|
||||
|
||||
Quad *quad = new Quad(Vector3(size.x, size.y, 0), false);
|
||||
quad->setMaterial(mat);
|
||||
|
||||
Node *node = new Node(Vector3(pos.x, pos.y, 0));
|
||||
node->attachMesh(quad);
|
||||
node->setVisible(false);
|
||||
root->getGuiNode()->attachChild(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void Destructable::displayStats(Node *foreground, Node *background, int currVal, int maxVal, bool render, Vector2 offset) {
|
||||
foreground->setVisible(render);
|
||||
background->setVisible(render);
|
||||
|
||||
if(render){
|
||||
Vector3 offset3d = Vector3(offset.x, offset.y, 0);
|
||||
Vector2 screenPos = gameObject->getScreenPos();
|
||||
|
||||
Quad *bgQuad = (Quad*)background->getMesh(0);
|
||||
Vector3 size = bgQuad->getSize();
|
||||
float shiftedX = screenPos.x - 0.5 * size.x;
|
||||
background->setPosition(Vector3(shiftedX, screenPos.y, 0) + offset3d);
|
||||
|
||||
Quad *fgQuad = (Quad*)foreground->getMesh(0);
|
||||
fgQuad->setSize(Vector3((float)currVal / maxVal * size.x, size.y, 0));
|
||||
fgQuad->updateVerts(fgQuad->getMeshBase());
|
||||
foreground->setPosition(Vector3(shiftedX, screenPos.y, .01) + offset3d);
|
||||
}
|
||||
}
|
||||
|
||||
void Destructable::removeBar(Node *node){
|
||||
Root::getSingleton()->getGuiNode()->dettachChild(node);
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef DESTRUCTABLE_H
|
||||
#define DESTRUCTABLE_H
|
||||
|
||||
#include <vector.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace vb01{
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace battleship{
|
||||
enum class Armor {CAST, COMBINED, MECHANIC, SHELL, STEEL};
|
||||
|
||||
class GameObject;
|
||||
|
||||
class Destructable{
|
||||
public:
|
||||
Destructable(GameObject*);
|
||||
void update();
|
||||
void removeBar(vb01::Node*);
|
||||
vb01::Node* createBar(vb01::Vector2, vb01::Vector2, vb01::Vector4);
|
||||
void displayStats(vb01::Node*, vb01::Node*, int, int, bool, vb01::Vector2 offset = vb01::Vector2::VEC_ZERO);
|
||||
inline int getHealth(){return health;}
|
||||
inline int getMaxHealth(){return maxHealth;}
|
||||
inline int getDeathHp(){return DEATH_HP;}
|
||||
inline void takeDamage(int damage) {health -= damage * (1 + (freezeDmgFactor - 1) * freezeStatus * .01f);}
|
||||
inline GameObject* getGameObject(){return gameObject;}
|
||||
inline std::vector<Armor> getArmorTypes(){return armorTypes;}
|
||||
inline void setFreezeStatus(int fs){this->freezeStatus = std::clamp(fs, 0, 100);}
|
||||
inline int getFreezeStatus(){return freezeStatus;}
|
||||
private:
|
||||
std::vector<Armor> armorTypes;
|
||||
const int DEATH_HP = 0;
|
||||
int health = 0, maxHealth, freezeStatus = 0, freezeDmgFactor = 10;
|
||||
GameObject *gameObject = nullptr;
|
||||
|
||||
void initProperties();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+7
-6
@@ -1,5 +1,6 @@
|
||||
#include "engineer.h"
|
||||
#include "activeGameState.h"
|
||||
#include "destructable.h"
|
||||
#include "structure.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
@@ -21,13 +22,13 @@ namespace battleship{
|
||||
hackRange = generateView()["units"][id + 1]["hackRange"]; hackRange += game->calcAbilFromTech(Ability::Type::HACK_RANGE, currTechs, (int)GameObject::type, id);
|
||||
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
hackStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
hackStatusForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1));
|
||||
hackStatusBackground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
hackStatusForeground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1));
|
||||
}
|
||||
|
||||
Engineer::~Engineer(){
|
||||
removeBar(hackStatusBackground);
|
||||
removeBar(hackStatusForeground);
|
||||
destructable->removeBar(hackStatusBackground);
|
||||
destructable->removeBar(hackStatusForeground);
|
||||
}
|
||||
|
||||
void Engineer::update(){
|
||||
@@ -40,7 +41,7 @@ namespace battleship{
|
||||
bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
|
||||
if(hackStatus < 100)
|
||||
Unit::displayUnitStats(hackStatusForeground, hackStatusBackground, hackStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(hackStatusForeground, hackStatusBackground, hackStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
else{
|
||||
hackStatusBackground->setVisible(false);
|
||||
hackStatusForeground->setVisible(false);
|
||||
@@ -52,7 +53,7 @@ namespace battleship{
|
||||
|
||||
//TODO change unit colors after faction change
|
||||
void Engineer::hack(Order order){
|
||||
Unit *targUnit = order.targets[0].unit;
|
||||
Unit *targUnit = (Unit*)order.targets[0].unit;
|
||||
bool withinRange = (targUnit->getPos().getDistanceFrom(pos) < hackRange);
|
||||
int hackRate = int(generateView()["units"][id + 1]["hackTime"]) / 100;
|
||||
bool canHack = (getTime() - lastHackTime > hackRate);
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "game.h"
|
||||
#include "destructable.h"
|
||||
|
||||
#include <root.h>
|
||||
#include <node.h>
|
||||
@@ -36,7 +37,7 @@ namespace battleship{
|
||||
if(distance < radius){
|
||||
switch(det){
|
||||
case Detonation::EXPLOSION:
|
||||
un->takeDamage(int(damage * (1.f - distance / radius)));
|
||||
un->getDestructable()->takeDamage(int(damage * (1.f - distance / radius)));
|
||||
break;
|
||||
case Detonation::EMP:
|
||||
un->setCondition(Unit::Condition::EM_JAMMED);
|
||||
|
||||
+16
-15
@@ -1,6 +1,7 @@
|
||||
#include "extractor.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
#include "destructable.h"
|
||||
#include "activeGameState.h"
|
||||
#include "resourceDeposit.h"
|
||||
|
||||
@@ -12,25 +13,25 @@ namespace battleship{
|
||||
using namespace gameBase;
|
||||
|
||||
Extractor::Extractor(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus, ResourceDeposit *rd, Unit::State state) : Structure(player, id, pos, rot, buildStatus, state){
|
||||
if(!rd)
|
||||
for(ResourceDeposit *dep : Game::getSingleton()->getCivilianPlayer()->getResourceDeposits())
|
||||
if(dep->getPos().getDistanceFrom(pos) < .001){
|
||||
deposit = dep;
|
||||
deposit->setExtractor(this);
|
||||
break;
|
||||
}
|
||||
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
ammountBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
ammountForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1));
|
||||
ammountBackground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
ammountForeground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1));
|
||||
|
||||
if(rd) return;
|
||||
|
||||
for(ResourceDeposit *dep : Game::getSingleton()->getCivilianPlayer()->getResourceDeposits())
|
||||
if(dep->getPos().getDistanceFrom(pos) < .001){
|
||||
deposit = dep;
|
||||
deposit->setExtractor(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Extractor::~Extractor(){
|
||||
if(deposit)
|
||||
deposit->setExtractor(nullptr);
|
||||
if(deposit) deposit->setExtractor(nullptr);
|
||||
|
||||
removeBar(ammountForeground);
|
||||
removeBar(ammountBackground);
|
||||
destructable->removeBar(ammountForeground);
|
||||
destructable->removeBar(ammountBackground);
|
||||
}
|
||||
|
||||
void Extractor::initProperties(){
|
||||
@@ -58,7 +59,7 @@ namespace battleship{
|
||||
initAmmount = deposit->getInitAmmount();
|
||||
}
|
||||
|
||||
Unit::displayUnitStats(ammountForeground, ammountBackground, ammount, initAmmount, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(ammountForeground, ammountBackground, ammount, initAmmount, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
}
|
||||
|
||||
void Extractor::draw(){
|
||||
|
||||
+3
-6
@@ -1,6 +1,7 @@
|
||||
#include "factory.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
#include "destructable.h"
|
||||
#include "gameObjectFactory.h"
|
||||
#include "activeGameState.h"
|
||||
|
||||
@@ -21,16 +22,12 @@ namespace battleship{
|
||||
|
||||
if(!isComplete()) return;
|
||||
|
||||
if(!unitQueue.empty())
|
||||
train();
|
||||
if(!unitQueue.empty()) train();
|
||||
}
|
||||
|
||||
//TODO replace repetetive string literals
|
||||
void Factory::initProperties(){
|
||||
Structure::initProperties();
|
||||
Game *game = Game::getSingleton();
|
||||
vector<int> currTechs = player->getTechnologies();
|
||||
|
||||
}
|
||||
|
||||
int Factory::getNumQueueUnitsById(int unitId){
|
||||
@@ -60,7 +57,7 @@ namespace battleship{
|
||||
vector<Player*> selectingPlayers = getSelectingPlayers();
|
||||
bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
|
||||
Unit::displayUnitStats(buildStatusForeground, buildStatusBackground, trainingStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(buildStatusForeground, buildStatusBackground, trainingStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
sol::table targTable = generateView()["units"][unitQueue[0] + 1];
|
||||
int costRate = (int)targTable["cost"] / 100, trainRate = (int)targTable["buildTime"] / 100;
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
#include "freezer.h"
|
||||
#include "destructable.h"
|
||||
|
||||
namespace battleship{
|
||||
using namespace vb01;
|
||||
@@ -9,7 +10,7 @@ namespace battleship{
|
||||
void Freezer::attack(Order order){
|
||||
Vehicle::attack(order);
|
||||
|
||||
Unit *target = order.targets[0].unit;
|
||||
Destructable *target = order.targets[0].unit->getDestructable();
|
||||
|
||||
if(target && target->getFreezeStatus() == 100)
|
||||
removeOrder(0);
|
||||
|
||||
+5
-2
@@ -16,6 +16,7 @@
|
||||
#include "player.h"
|
||||
#include "factory.h"
|
||||
#include "engineer.h"
|
||||
#include "destructable.h"
|
||||
#include "pointDefense.h"
|
||||
#include "resourceDeposit.h"
|
||||
|
||||
@@ -44,7 +45,7 @@ namespace battleship{
|
||||
);
|
||||
|
||||
SOL_LUA_STATE.new_usertype<Order::Target>(
|
||||
"Target", sol::constructors<Order::Target(), Order::Target(Unit*, Vector3)>(),
|
||||
"Target", sol::constructors<Order::Target(), Order::Target(GameObject*, Vector3)>(),
|
||||
"unit", &Order::Target::unit,
|
||||
"pos", &Order::Target::pos
|
||||
);
|
||||
@@ -58,6 +59,7 @@ namespace battleship{
|
||||
SOL_LUA_STATE.new_usertype<Unit>(
|
||||
"Unit", sol::constructors<Unit(Player*, int, Vector3, Quaternion)>(),
|
||||
"setState", &Unit::setState,
|
||||
"getDestructable", &Unit::getDestructable,
|
||||
"getOrder", &Unit::getOrder,
|
||||
"getNumOrders", &Unit::getNumOrders,
|
||||
"getPos", &GameObject::getPos,
|
||||
@@ -66,7 +68,8 @@ namespace battleship{
|
||||
"toEngineer", &Unit::toEngineer,
|
||||
"toPointDefense", &Unit::toPointDefense,
|
||||
"toStructure", &Unit::toStructure,
|
||||
"toFactory", &Unit::toFactory
|
||||
"toFactory", &Unit::toFactory,
|
||||
"toGameObject", &Unit::toGameObject
|
||||
);
|
||||
|
||||
SOL_LUA_STATE.new_usertype<Structure>(
|
||||
|
||||
+1
-15
@@ -1,5 +1,6 @@
|
||||
#include "gameObject.h"
|
||||
#include "gameManager.h"
|
||||
#include "destructable.h"
|
||||
#include "defConfigs.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
@@ -222,19 +223,4 @@ namespace battleship{
|
||||
return "resources";
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::updateGameStats(Unit *targetUnit){
|
||||
if(targetUnit->getHealth() <= targetUnit->getDeathHp()){
|
||||
Player *targUnitPlayer = targetUnit->getPlayer();
|
||||
|
||||
if(targetUnit->isVehicle()){
|
||||
player->incVehiclesDestroyed();
|
||||
targUnitPlayer->incVehiclesLost();
|
||||
}
|
||||
else{
|
||||
player->incStructuresDestroyed();
|
||||
targUnitPlayer->incStructuresLost();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -13,6 +13,7 @@ namespace sf{
|
||||
namespace battleship{
|
||||
class Player;
|
||||
class Unit;
|
||||
class Destructable;
|
||||
|
||||
class GameObject{
|
||||
public:
|
||||
@@ -26,7 +27,6 @@ namespace battleship{
|
||||
virtual void placeAt(vb01::Vector3);
|
||||
void orientAt(vb01::Quaternion);
|
||||
std::string getGameObjTableName();
|
||||
void updateGameStats(Unit*);
|
||||
static sf::Sound* prepareSfx(sf::SoundBuffer*, std::string);
|
||||
bool pointWithinObj(vb01::Vector3, float = 0, float = 0, bool = false, float = 0);
|
||||
void changePlayer(Player *newPlayer);
|
||||
@@ -50,7 +50,9 @@ namespace battleship{
|
||||
inline int getId() {return id;}
|
||||
inline Type getType(){return type;}
|
||||
inline vb01::Node* getHitbox(){return hitbox;}
|
||||
inline void setRemove(bool rm){this->remove = rm;}
|
||||
inline bool isRemove(){return remove;}
|
||||
inline Destructable* getDestructable(){return destructable;}
|
||||
protected:
|
||||
virtual void useColor(vb01::Material*);
|
||||
virtual void initProperties();
|
||||
@@ -64,6 +66,7 @@ namespace battleship{
|
||||
Type type;
|
||||
int id;
|
||||
Player *player;
|
||||
Destructable *destructable = nullptr;
|
||||
vb01::Model *model = nullptr;
|
||||
vb01::Node *hitbox = nullptr;
|
||||
vb01::Vector3 pos = vb01::Vector3(0, 0, 0), upVec = vb01::Vector3(0, 1, 0), dirVec = vb01::Vector3(0, 0, 1), leftVec = vb01::Vector3(1, 0, 0), corners[8];
|
||||
|
||||
+12
-4
@@ -1,19 +1,27 @@
|
||||
#include "missile.h"
|
||||
#include "unit.h"
|
||||
#include "destructable.h"
|
||||
|
||||
namespace battleship{
|
||||
using namespace vb01;
|
||||
|
||||
Missile::Missile(Unit *un, int id, Vector3 tp, Vector3 pos, Quaternion rot) :
|
||||
Projectile(un, id, pos, rot),
|
||||
targetPos(tp){}
|
||||
targetPos(tp)
|
||||
{
|
||||
destructable = new Destructable(this);
|
||||
}
|
||||
|
||||
Missile::~Missile(){delete destructable;}
|
||||
|
||||
void Missile::update(){
|
||||
Vector3 targDir = (targetPos - pos).norm();
|
||||
float angle = targDir.getAngleBetween(dirVec);
|
||||
Vector3 targDir = (targetPos - Projectile::pos).norm();
|
||||
float angle = targDir.getAngleBetween(Projectile::dirVec);
|
||||
float ra = (rotAngle < angle ? rotAngle : angle);
|
||||
orientAt(Quaternion(ra, dirVec.cross(targDir)) * rot);
|
||||
orientAt(Quaternion(ra, Projectile::dirVec.cross(targDir)) * Projectile::rot);
|
||||
|
||||
Projectile::update();
|
||||
destructable->update();
|
||||
checkCollision();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace battleship{
|
||||
class Missile : public Projectile{
|
||||
public:
|
||||
Missile(Unit*, int, vb01::Vector3, vb01::Vector3, vb01::Quaternion);
|
||||
~Missile(){}
|
||||
~Missile();
|
||||
void update();
|
||||
private:
|
||||
vb01::Vector3 targetPos;
|
||||
|
||||
+31
@@ -6,6 +6,7 @@
|
||||
#include "structure.h"
|
||||
#include "projectile.h"
|
||||
#include "tradeOffer.h"
|
||||
#include "destructable.h"
|
||||
#include "activeGameState.h"
|
||||
#include "resourceDeposit.h"
|
||||
|
||||
@@ -255,4 +256,34 @@ namespace battleship{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vector<GameObject*> Player::getDestructables(){
|
||||
vector<GameObject*> destructables;
|
||||
|
||||
for(Projectile *p : projectiles)
|
||||
if(p->getDestructable())
|
||||
destructables.push_back(p);
|
||||
|
||||
for(Unit *unit : units)
|
||||
destructables.push_back((GameObject*)unit);
|
||||
|
||||
return destructables;
|
||||
}
|
||||
|
||||
void Player::updateGameStats(Unit *targetUnit){
|
||||
Destructable *destructTarg = targetUnit->getDestructable();
|
||||
|
||||
if(destructTarg->getHealth() <= destructTarg->getDeathHp()){
|
||||
Player *targUnitPlayer = targetUnit->getPlayer();
|
||||
|
||||
if(targetUnit->isVehicle()){
|
||||
incVehiclesDestroyed();
|
||||
targUnitPlayer->incVehiclesLost();
|
||||
}
|
||||
else{
|
||||
incStructuresDestroyed();
|
||||
targUnitPlayer->incStructuresLost();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace battleship{
|
||||
void addTradeOffer(Player*, TradeOffer*);
|
||||
std::vector<TradeOffer*> getTradeOffers(Player*);
|
||||
void deselectUnit(Unit*);
|
||||
std::vector<GameObject*> getDestructables();
|
||||
void updateGameStats(Unit*);
|
||||
inline int getResource(ResourceType rt){return resources[(int)rt];}
|
||||
inline void updateResource(ResourceType rt, int amount, bool add){resources[(int)rt] = (add ? resources[(int)rt] + amount : amount);}
|
||||
inline Trader* getTrader(){return trader;}
|
||||
|
||||
+4
-1
@@ -13,6 +13,7 @@
|
||||
#include "environment.h"
|
||||
#include "projectile.h"
|
||||
#include "defConfigs.h"
|
||||
#include "destructable.h"
|
||||
#include "resourceDeposit.h"
|
||||
#include "inGameAppState.h"
|
||||
|
||||
@@ -54,6 +55,8 @@ namespace battleship{
|
||||
vector<int> currTechs = player->getTechnologies();
|
||||
|
||||
sol::table projTable = generateView()[GameObject::getGameObjTableName()][id + 1];
|
||||
projClass = (ProjectileClass)projTable["projectileClass"];
|
||||
|
||||
rayLength = projTable["rayLength"];
|
||||
directHitDamage = projTable["directHitDamage"]; directHitDamage += game->calcAbilFromTech(Ability::Type::DIRECT_HIT_DAMAGE, currTechs, (int)GameObject::type, id);
|
||||
|
||||
@@ -70,7 +73,7 @@ namespace battleship{
|
||||
}
|
||||
|
||||
void Projectile::detonate(Unit *target){
|
||||
if(target) target->takeDamage(directHitDamage);
|
||||
if(target) target->getDestructable()->takeDamage(directHitDamage);
|
||||
|
||||
sol::table tbl = generateView()[getGameObjTableName()][id + 1]["explosion"];
|
||||
FxManager::Fx *fx = FxManager::getSingleton()->initFx(tbl["fx"], model, false, pos);
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace battleship {
|
||||
virtual ~Projectile();
|
||||
virtual void update();
|
||||
virtual void debug();
|
||||
inline ProjectileClass getProjectileClass(){return projClass;}
|
||||
private:
|
||||
void initProperties();
|
||||
void detonate(Unit *u = nullptr);
|
||||
@@ -31,6 +32,7 @@ namespace battleship {
|
||||
void checkCollision();
|
||||
|
||||
vb01::Vector3 initPos;
|
||||
ProjectileClass projClass;
|
||||
Unit *unit = nullptr;
|
||||
FxManager::Fx *explosionFx = nullptr;
|
||||
float speed, rayLength, explosionRadius, rotAngle;
|
||||
|
||||
+7
-6
@@ -1,5 +1,6 @@
|
||||
#include "researchStruct.h"
|
||||
#include "activeGameState.h"
|
||||
#include "destructable.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
|
||||
@@ -17,13 +18,13 @@ namespace battleship{
|
||||
researchCost = unitTable["researchCost"];
|
||||
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
researchStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
researchStatusForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1));
|
||||
researchStatusBackground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
researchStatusForeground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1));
|
||||
}
|
||||
|
||||
ResearchStruct::~ResearchStruct(){
|
||||
removeBar(researchStatusBackground);
|
||||
removeBar(researchStatusForeground);
|
||||
destructable->removeBar(researchStatusBackground);
|
||||
destructable->removeBar(researchStatusForeground);
|
||||
}
|
||||
|
||||
void ResearchStruct::update(){
|
||||
@@ -38,7 +39,7 @@ namespace battleship{
|
||||
bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
|
||||
if(researchQueue.empty()){
|
||||
if(health > .3 * maxHealth && player->getResource(ResourceType::REFINEDS) >= researchCost && canUpdateResearch()){
|
||||
if(destructable->getHealth() > .3 * destructable->getMaxHealth() && player->getResource(ResourceType::REFINEDS) >= researchCost && canUpdateResearch()){
|
||||
player->updateResource(ResourceType::RESEARCH, generationSpeed, true);
|
||||
player->updateResource(ResourceType::REFINEDS, -researchCost, true);
|
||||
lastUpdateTime = getTime();
|
||||
@@ -48,7 +49,7 @@ namespace battleship{
|
||||
researchStatusForeground->setVisible(false);
|
||||
}
|
||||
else if(!researchQueue.empty()){
|
||||
Unit::displayUnitStats(researchStatusForeground, researchStatusBackground, researchStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(researchStatusForeground, researchStatusBackground, researchStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
|
||||
int techCost = Game::getSingleton()->getTechnology(researchQueue[0]).cost;
|
||||
int playerResearch = player->getResource(ResourceType::RESEARCH);
|
||||
|
||||
+6
-5
@@ -1,5 +1,6 @@
|
||||
#include "resourceRover.h"
|
||||
#include "resourceDeposit.h"
|
||||
#include "destructable.h"
|
||||
#include "map.h"
|
||||
#include "game.h"
|
||||
#include "player.h"
|
||||
@@ -16,15 +17,15 @@ namespace battleship{
|
||||
|
||||
ResourceRover::ResourceRover(Player *player, int id, Vector3 pos, Quaternion rot, Unit::State state) : Vehicle(player, id, pos, rot, state) {
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
loadBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
loadForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 1, 0, 1));
|
||||
loadBackground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
loadForeground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(1, 1, 0, 1));
|
||||
|
||||
initProperties();
|
||||
}
|
||||
|
||||
ResourceRover::~ResourceRover(){
|
||||
removeBar(loadForeground);
|
||||
removeBar(loadBackground);
|
||||
destructable->removeBar(loadForeground);
|
||||
destructable->removeBar(loadBackground);
|
||||
}
|
||||
|
||||
void ResourceRover::initProperties(){
|
||||
@@ -166,7 +167,7 @@ namespace battleship{
|
||||
vector<Player*> selectingPlayers = getSelectingPlayers();
|
||||
bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
|
||||
Unit::displayUnitStats(loadForeground, loadBackground, calcTotalLoad(), capacity, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(loadForeground, loadBackground, calcTotalLoad(), capacity, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
}
|
||||
|
||||
Unit* ResourceRover::getClosestUnit(vector<Structure*> structs){
|
||||
|
||||
+6
-5
@@ -1,5 +1,6 @@
|
||||
#include "structure.h"
|
||||
#include "activeGameState.h"
|
||||
#include "destructable.h"
|
||||
|
||||
#include <stateManager.h>
|
||||
|
||||
@@ -12,13 +13,13 @@ using namespace std;
|
||||
namespace battleship{
|
||||
Structure::Structure(Player *player, int id, Vector3 pos, Quaternion rot, int bldSt, Unit::State state) : Unit(player, id, pos, rot, state), buildStatus(bldSt){
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
buildStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
buildStatusForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1));
|
||||
buildStatusBackground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
buildStatusForeground = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1));
|
||||
}
|
||||
|
||||
Structure::~Structure(){
|
||||
removeBar(buildStatusForeground);
|
||||
removeBar(buildStatusBackground);
|
||||
destructable->removeBar(buildStatusForeground);
|
||||
destructable->removeBar(buildStatusBackground);
|
||||
}
|
||||
|
||||
void Structure::update(){
|
||||
@@ -31,7 +32,7 @@ namespace battleship{
|
||||
bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
|
||||
if(buildStatus < 100)
|
||||
Unit::displayUnitStats(buildStatusForeground, buildStatusBackground, buildStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
destructable->displayStats(buildStatusForeground, buildStatusBackground, buildStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10));
|
||||
else{
|
||||
buildStatusBackground->setVisible(false);
|
||||
buildStatusForeground->setVisible(false);
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
#include <ext.hpp>
|
||||
|
||||
#include "unit.h"
|
||||
#include "cryoGun.h"
|
||||
#include "weapon.h"
|
||||
#include "util.h"
|
||||
#include "game.h"
|
||||
#include "map.h"
|
||||
#include "vehicle.h"
|
||||
#include "environment.h"
|
||||
#include "destructable.h"
|
||||
#include "gameObjectFactory.h"
|
||||
#include "activeGameState.h"
|
||||
#include "gameManager.h"
|
||||
@@ -33,9 +34,15 @@ using namespace gameBase;
|
||||
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){
|
||||
//TODO move restartTime to unitData.lua
|
||||
Unit::Unit(Player *player, int id, Vector3 pos, Quaternion rot, State st) :
|
||||
GameObject(GameObject::Type::UNIT, id, player, pos, rot),
|
||||
state(st),
|
||||
restartTime(2000)
|
||||
{
|
||||
selectable = true;
|
||||
restartTime = 2000;
|
||||
|
||||
destructable = new Destructable(this);
|
||||
|
||||
Unit::initProperties();
|
||||
initModel();
|
||||
@@ -46,14 +53,14 @@ namespace battleship{
|
||||
orientAt(rot);
|
||||
|
||||
Vector2 size = Vector2(lenHpBar, 10);
|
||||
hpBackgroundNode = createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
hpForegroundNode = createBar(Vector2::VEC_ZERO, size, Vector4(0, 1, 0, 1));
|
||||
hpBackgroundNode = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1));
|
||||
hpForegroundNode = destructable->createBar(Vector2::VEC_ZERO, size, Vector4(0, 1, 0, 1));
|
||||
}
|
||||
|
||||
Unit::~Unit() {
|
||||
Map::getSingleton()->unblockCells(this);
|
||||
removeBar(hpBackgroundNode);
|
||||
removeBar(hpForegroundNode);
|
||||
destructable->removeBar(hpBackgroundNode);
|
||||
destructable->removeBar(hpForegroundNode);
|
||||
destroyWeapons();
|
||||
destroySound();
|
||||
destroyHitbox();
|
||||
@@ -73,10 +80,6 @@ namespace battleship{
|
||||
string name = unitTable["name"];
|
||||
alignToSurface = unitTable["alignToSurface"].get_or(false);
|
||||
vehicle = unitTable["isVehicle"];
|
||||
health += game->calcAbilFromTech(Ability::Type::HEALTH, currTechs, (int)GameObject::type, id);
|
||||
maxHealth = unitTable["health"];
|
||||
|
||||
if(health == 0) health = maxHealth;
|
||||
|
||||
lineOfSight = unitTable["lineOfSight"]; lineOfSight += game->calcAbilFromTech(Ability::Type::LINE_OF_SIGHT, currTechs, (int)GameObject::type, id);
|
||||
unitClass = (UnitClass)unitTable["unitClass"];
|
||||
@@ -99,27 +102,13 @@ namespace battleship{
|
||||
for(int i = 0; i < numGarrisonSlots; i++){
|
||||
Vector2 size = 10 * Vector2::VEC_IJ;
|
||||
Vector2 pos = Vector2(1.5 * size.x * i, 20);
|
||||
Node *bg = createBar(pos, size, Vector4(0, 0, 0, 1));
|
||||
Node *fg = createBar(pos, size, Vector4(0, 1, 0, 1));
|
||||
Node *bg = destructable->createBar(pos, size, Vector4(0, 0, 0, 1));
|
||||
Node *fg = destructable->createBar(pos, size, Vector4(0, 1, 0, 1));
|
||||
int category = unitTable[tblName][i + 1];
|
||||
garrisonSlots.push_back(GarrisonSlot(bg, fg, pos, category));
|
||||
}
|
||||
}
|
||||
|
||||
tblName = "armor";
|
||||
sol::optional<sol::table> at = unitTable[tblName];
|
||||
|
||||
if(at != sol::nullopt){
|
||||
string varName = "numArmorTypes";
|
||||
SOL_LUA_VIEW.script(varName + " = #" + objType + "[" + to_string(id + 1) + "]." + tblName);
|
||||
int numArmorTypes = SOL_LUA_VIEW[varName];
|
||||
|
||||
for(int i = 0; i < numArmorTypes; i++){
|
||||
Armor arm = (Armor)unitTable[tblName][i + 1];
|
||||
armorTypes.push_back(arm);
|
||||
}
|
||||
}
|
||||
|
||||
tblName = "buildableUnits";
|
||||
sol::optional<sol::table> bu = unitTable[tblName];
|
||||
|
||||
@@ -153,8 +142,14 @@ namespace battleship{
|
||||
|
||||
if(wtOpt != sol::nullopt) wt = unitTable[tblName][i + 1]["type"];
|
||||
|
||||
Weapon *weapon = ((Weapon::Type)wt == Weapon::Type::FREEZER ? new CryoGun(this, unitTable, i) : new Weapon(this, unitTable, i));
|
||||
weapons.push_back(weapon);
|
||||
switch((Weapon::Type)wt){
|
||||
case Weapon::Type::FREEZER:
|
||||
weapons.push_back(new CryoGun(this, unitTable, i));
|
||||
break;
|
||||
default:
|
||||
weapons.push_back(new Weapon(this, unitTable, i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,28 +221,6 @@ namespace battleship{
|
||||
return false;
|
||||
}
|
||||
|
||||
Node* Unit::createBar(Vector2 pos, Vector2 size, Vector4 color){
|
||||
Root *root = Root::getSingleton();
|
||||
Material *mat = new Material(root->getLibPath() + "gui");
|
||||
mat->addBoolUniform("texturingEnabled", false);
|
||||
mat->addVec4Uniform("diffuseColor", color);
|
||||
|
||||
Quad *quad = new Quad(Vector3(size.x, size.y, 0), false);
|
||||
quad->setMaterial(mat);
|
||||
|
||||
Node *node = new Node(Vector3(pos.x, pos.y, 0));
|
||||
node->attachMesh(quad);
|
||||
node->setVisible(false);
|
||||
root->getGuiNode()->attachChild(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void Unit::removeBar(Node *node){
|
||||
Root::getSingleton()->getGuiNode()->dettachChild(node);
|
||||
delete node;
|
||||
}
|
||||
|
||||
void Unit::launch(Order order){
|
||||
getWeaponsByOrder(Order::TYPE::LAUNCH)[0]->fire(order);
|
||||
removeOrder(0);
|
||||
@@ -262,10 +235,6 @@ namespace battleship{
|
||||
return rotSpeed;
|
||||
}
|
||||
|
||||
|
||||
void Unit::initUnitStats(){
|
||||
}
|
||||
|
||||
void Unit::renderOrderLine(bool mainPlayerSelecting){
|
||||
if (!orders.empty() && orders[0].lineId != -1 && mainPlayerSelecting){
|
||||
bool display = canDisplayOrderLine();
|
||||
@@ -280,81 +249,56 @@ namespace battleship{
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::targetUnitsAutomatically(){
|
||||
//TODO clean up method code
|
||||
void Unit::autoAttackTargets(){
|
||||
if(!orders.empty()) return;
|
||||
|
||||
vector<Player*> players = Game::getSingleton()->getPlayers();
|
||||
vector<Unit*> units;
|
||||
vector<GameObject*> targets;
|
||||
|
||||
for(Player *pl : players)
|
||||
if(!(pl == player || pl->getTeam() == player->getTeam())){
|
||||
vector<Unit*> un = pl->getUnits();
|
||||
units.insert(units.end(), un.begin(), un.end());
|
||||
vector<GameObject*> targs = pl->getDestructables();
|
||||
targets.insert(targets.end(), targs.begin(), targs.end());
|
||||
}
|
||||
|
||||
if(orders.empty())
|
||||
for(Unit *unit : units)
|
||||
if(unit->getPos().getDistanceFrom(pos) < lineOfSight){
|
||||
receiveOrder(Order(Order::TYPE::ATTACK, vector<Order::Target>{Order::Target(unit)}, Vector3::VEC_ZERO, -1, false), false);
|
||||
break;
|
||||
}
|
||||
for(GameObject *targ : targets)
|
||||
if(targ->getPos().getDistanceFrom(pos) < lineOfSight){
|
||||
receiveOrder(Order(Order::TYPE::ATTACK, vector<Order::Target>{Order::Target(targ)}, Vector3::VEC_ZERO, -1, false), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::update() {
|
||||
GameObject::update();
|
||||
destructable->update();
|
||||
|
||||
if(condition == Condition::EM_JAMMED && getTime() - lastJamTime > restartTime)
|
||||
condition = Condition::ABLE;
|
||||
|
||||
if(freezeStatus >= 100) condition = Condition::FROZEN;
|
||||
if(destructable->getFreezeStatus() >= 100) condition = Condition::FROZEN;
|
||||
|
||||
if(state != State::HOLD_FIRE)
|
||||
autoAttackTargets();
|
||||
|
||||
ActiveGameState *activeState = (ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE);
|
||||
Player *mainPlayer = (activeState ? activeState->getPlayer() : nullptr);
|
||||
|
||||
if(state != State::HOLD_FIRE)
|
||||
targetUnitsAutomatically();
|
||||
|
||||
vector<Player*> selectingPlayers = getSelectingPlayers();
|
||||
bool mainPlayerSelecting = (find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end());
|
||||
bool mainPlayerOwner = (player == mainPlayer);
|
||||
bool renderSelectables = (mainPlayerSelecting && mainPlayerOwner);
|
||||
|
||||
renderOrderLine(renderSelectables);
|
||||
executeOrders();
|
||||
|
||||
displayUnitStats(hpForegroundNode, hpBackgroundNode, health, maxHealth, mainPlayerSelecting);
|
||||
executeOrders();
|
||||
destructable->displayStats(hpForegroundNode, hpBackgroundNode, destructable->getHealth(), destructable->getMaxHealth(), mainPlayerSelecting);
|
||||
|
||||
for(GarrisonSlot &slot : garrisonSlots)
|
||||
displayUnitStats(slot.foreground, slot.background, (int)((bool)slot.vehicle), (int)true, renderSelectables, slot.offset);
|
||||
|
||||
if (health <= DEATH_HP){
|
||||
sol::table tbl = generateView()[getGameObjTableName()][id + 1]["deathFx"];
|
||||
FxManager::Fx *fx = FxManager::getSingleton()->initFx(tbl, model, false, pos);
|
||||
Environment::explode(fx, Environment::Detonation::EXPLOSION, pos);
|
||||
remove = true;
|
||||
}
|
||||
destructable->displayStats(slot.foreground, slot.background, (int)((bool)slot.vehicle), (int)true, renderSelectables, slot.offset);
|
||||
|
||||
for(Weapon *weapon : weapons)
|
||||
weapon->update();
|
||||
}
|
||||
|
||||
void Unit::displayUnitStats(Node *foreground, Node *background, int currVal, int maxVal, bool render, Vector2 offset) {
|
||||
foreground->setVisible(render);
|
||||
background->setVisible(render);
|
||||
|
||||
if(render){
|
||||
Vector3 offset3d = Vector3(offset.x, offset.y, 0);
|
||||
|
||||
Quad *bgQuad = (Quad*)background->getMesh(0);
|
||||
Vector3 size = bgQuad->getSize();
|
||||
float shiftedX = screenPos.x - 0.5 * size.x;
|
||||
background->setPosition(Vector3(shiftedX, screenPos.y, 0) + offset3d);
|
||||
|
||||
Quad *fgQuad = (Quad*)foreground->getMesh(0);
|
||||
fgQuad->setSize(Vector3((float)currVal / maxVal * size.x, size.y, 0));
|
||||
fgQuad->updateVerts(fgQuad->getMeshBase());
|
||||
foreground->setPosition(Vector3(shiftedX, screenPos.y, .01) + offset3d);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO remove order argument from action methods
|
||||
void Unit::executeOrders() {
|
||||
if(orders.empty() || condition != Condition::ABLE) return;
|
||||
@@ -423,16 +367,16 @@ namespace battleship{
|
||||
}
|
||||
|
||||
void Unit::attack(Order order){
|
||||
vector<Unit*> units;
|
||||
vector<GameObject*> targets;
|
||||
|
||||
for(Player *pl : Game::getSingleton()->getPlayers()){
|
||||
vector<Unit*> un = pl->getUnits();
|
||||
units.insert(units.end(), un.begin(), un.end());
|
||||
vector<GameObject*> targs = pl->getDestructables();
|
||||
targets.insert(targets.end(), targs.begin(), targs.end());
|
||||
}
|
||||
|
||||
for(Order::Target &target : orders[0].targets)
|
||||
if(target.unit){
|
||||
if(find(units.begin(), units.end(), target.unit) != units.end())
|
||||
if(find(targets.begin(), targets.end(), target.unit) != targets.end())
|
||||
break;
|
||||
|
||||
removeOrder(0);
|
||||
@@ -447,8 +391,11 @@ namespace battleship{
|
||||
|
||||
bool Unit::validateOrder(Order order){
|
||||
switch (order.type) {
|
||||
case Order::TYPE::ATTACK:
|
||||
return !getWeaponsByOrder(Order::TYPE::ATTACK).empty();
|
||||
case Order::TYPE::ATTACK:{
|
||||
GameObject *target = order.targets[0].unit;
|
||||
bool destructTarg = (!target || (target && target->getDestructable()));
|
||||
return destructTarg && !getWeaponsByOrder(Order::TYPE::ATTACK).empty();
|
||||
}
|
||||
case Order::TYPE::BUILD:
|
||||
return (unitClass == UnitClass::ENGINEER || unitClass == UnitClass::FREEZER);
|
||||
case Order::TYPE::PATROL:
|
||||
|
||||
@@ -36,15 +36,16 @@ namespace battleship{
|
||||
class Engineer;
|
||||
class PointDefense;
|
||||
class Projectile;
|
||||
class GameObject;
|
||||
|
||||
struct Order {
|
||||
enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY, LOAD, UNLOAD, HACK};
|
||||
struct Target{
|
||||
Unit *unit = nullptr;
|
||||
GameObject *unit = nullptr;
|
||||
vb01::Vector3 pos;
|
||||
|
||||
Target(){}
|
||||
Target(Unit *u, vb01::Vector3 p = vb01::Vector3::VEC_ZERO) : unit(u), pos(p){}
|
||||
Target(GameObject *u, vb01::Vector3 p = vb01::Vector3::VEC_ZERO) : unit(u), pos(p){}
|
||||
};
|
||||
|
||||
TYPE type;
|
||||
@@ -100,7 +101,6 @@ namespace battleship{
|
||||
GarrisonSlot(vb01::Node *bg, vb01::Node *fg, vb01::Vector2 off, int cat, Vehicle *v = nullptr) : background(bg), foreground(fg), offset(off), category(cat), vehicle(v){}
|
||||
};
|
||||
|
||||
enum class Armor {CAST, COMBINED, MECHANIC, SHELL, STEEL};
|
||||
enum class State {CHASE, STAND_GROUND, HOLD_FIRE};
|
||||
enum class Condition{ABLE, FROZEN, EM_JAMMED};
|
||||
|
||||
@@ -123,15 +123,13 @@ namespace battleship{
|
||||
inline Factory* toFactory(){return (Factory*)this;}
|
||||
inline Cruiser* toCruiser(){return (Cruiser*)this;}
|
||||
inline PointDefense* toPointDefense(){return (PointDefense*)this;}
|
||||
inline GameObject* toGameObject(){return (GameObject*)this;}
|
||||
inline int getNumGarrisonSlots(){return garrisonSlots.size();}
|
||||
inline const std::vector<GarrisonSlot>& getGarrisonSlots(){return garrisonSlots;}
|
||||
inline float getLineOfSight() {return lineOfSight;}
|
||||
inline UnitType getType() {return type;}
|
||||
inline UnitClass getUnitClass() {return unitClass;}
|
||||
inline void takeDamage(int damage) {health -= damage * (1 + (freezeDmgFactor - 1) * freezeStatus * .01f);}
|
||||
inline int getPlayerId() {return playerId;}
|
||||
inline int getHealth(){return health;}
|
||||
inline int getDeathHp(){return DEATH_HP;}
|
||||
inline bool isVehicle(){return vehicle;}
|
||||
inline bool isTargetToTheRight(vb01::Vector3 dir, vb01::Vector3 lv){return lv.getAngleBetween(dir) > vb01::PI / 2;}
|
||||
inline Order getOrder(int i){return orders[i];}
|
||||
@@ -139,8 +137,6 @@ namespace battleship{
|
||||
inline std::string getGuiScreen(){return guiScreen;}
|
||||
inline BuildableUnit getBuildableUnit(int i){return buildableUnits[i];}
|
||||
inline vb01::Node* getLosLightNode(){return losLightNode;}
|
||||
inline void setFreezeStatus(int fs){this->freezeStatus = std::clamp(fs, 0, 100);}
|
||||
inline int getFreezeStatus(){return freezeStatus;}
|
||||
inline Condition getCondition(){return condition;}
|
||||
inline void setCondition(Condition cond){
|
||||
this->condition = cond;
|
||||
@@ -149,31 +145,30 @@ namespace battleship{
|
||||
}
|
||||
private:
|
||||
void renderOrderLine(bool);
|
||||
void updateScreenCoordinates();
|
||||
void initWeapons();
|
||||
void destroyWeapons();
|
||||
bool validateOrder(Order);
|
||||
inline bool canDisplayOrderLine(){return vb01::getTime() - orderLineDispTime < orderVecDispLength;}
|
||||
|
||||
const int orderVecDispLength = 2000, DEATH_HP = 0;
|
||||
const int orderVecDispLength = 2000;
|
||||
sf::SoundBuffer *selectionSfxBuffer;
|
||||
sf::Sound *selectionSfx = nullptr;
|
||||
vb01::Node *hpBackgroundNode = nullptr, *hpForegroundNode = nullptr, *losLightNode = nullptr;
|
||||
vb01::Node *losLightNode = nullptr;
|
||||
bool vehicle, currOrderStarted = false, alignToSurface = false;
|
||||
Condition condition = Condition::ABLE;
|
||||
protected:
|
||||
UnitClass unitClass;
|
||||
UnitType type;
|
||||
UnitClass unitClass;
|
||||
std::vector<Order> orders;
|
||||
std::string guiScreen = "";
|
||||
int health = 0, maxHealth, playerId, lenHpBar = 200, freezeStatus = 0, freezeDmgFactor = 10, restartTime;
|
||||
int playerId, restartTime, lenHpBar = 200;
|
||||
vb01::s64 orderLineDispTime = 0, lastFireTime = 0, lastJamTime = 0;
|
||||
float lineOfSight;
|
||||
std::vector<Armor> armorTypes;
|
||||
std::vector<Weapon*> weapons;
|
||||
std::vector<GarrisonSlot> garrisonSlots;
|
||||
std::vector<BuildableUnit> buildableUnits;
|
||||
State state = State::STAND_GROUND;
|
||||
vb01::Node *hpBackgroundNode = nullptr, *hpForegroundNode = nullptr;
|
||||
|
||||
void placeAt(vb01::Vector3);
|
||||
std::vector<Player*> getSelectingPlayers();
|
||||
@@ -181,12 +176,11 @@ namespace battleship{
|
||||
virtual void startCurrentOrder(){currOrderStarted = true;}
|
||||
virtual bool validateLaunchOrder(){return !getWeaponsByOrder(Order::TYPE::LAUNCH).empty();}
|
||||
virtual bool validateGarrisonOrder(Order){return false;}
|
||||
virtual void targetUnitsAutomatically();
|
||||
virtual void autoAttackTargets();
|
||||
virtual void reinit();
|
||||
virtual void initProperties();
|
||||
virtual void destroySound();
|
||||
virtual void initSound();
|
||||
virtual void initUnitStats();
|
||||
virtual void executeOrders();
|
||||
virtual void eject(Order);
|
||||
virtual void attack(Order);
|
||||
@@ -199,11 +193,7 @@ namespace battleship{
|
||||
virtual void hack(Order){}
|
||||
virtual void freeze(Order){}
|
||||
float calculateRotation(vb01::Vector3, float, float);
|
||||
void removeBar(vb01::Node*);
|
||||
vb01::Node* createBar(vb01::Vector2, vb01::Vector2, vb01::Vector4);
|
||||
void displayUnitStats(vb01::Node*, vb01::Node*, int, int, bool, vb01::Vector2 offset = vb01::Vector2::VEC_ZERO);
|
||||
std::vector<Weapon*> getWeaponsByOrder(Order::TYPE);
|
||||
inline std::vector<Armor> getArmorTypes(){return armorTypes;}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+15
-18
@@ -10,6 +10,7 @@
|
||||
#include <quaternion.h>
|
||||
|
||||
#include "pathfinder.h"
|
||||
#include "destructable.h"
|
||||
#include "defConfigs.h"
|
||||
#include "structure.h"
|
||||
#include "vehicle.h"
|
||||
@@ -57,7 +58,7 @@ namespace battleship{
|
||||
}
|
||||
|
||||
bool Vehicle::validateGarrisonOrder(Order order){
|
||||
Unit *targUnit = order.targets[0].unit;
|
||||
Unit *targUnit = (Unit*)order.targets[0].unit;
|
||||
|
||||
for(GarrisonSlot slot : targUnit->getGarrisonSlots())
|
||||
if(!slot.vehicle && slot.category >= garrisonCategory)
|
||||
@@ -259,7 +260,7 @@ namespace battleship{
|
||||
}
|
||||
|
||||
void Vehicle::enterGarrisonable(){
|
||||
Unit *targUnit = orders[0].targets[0].unit;
|
||||
Unit *targUnit = (Unit*)orders[0].targets[0].unit;
|
||||
targUnit->updateGarrison(this, true);
|
||||
|
||||
removeAllPathpoints();
|
||||
@@ -282,7 +283,7 @@ namespace battleship{
|
||||
}
|
||||
|
||||
void Vehicle::garrison(Order order){
|
||||
Unit *targUnit = order.targets[0].unit;
|
||||
Unit *targUnit = (Unit*)order.targets[0].unit;
|
||||
float distToGarrisonable = pos.getDistanceFrom(targUnit->getPos()), garrisonDist = Map::getSingleton()->getCellSize().x;
|
||||
|
||||
if(distToGarrisonable > garrisonDist)
|
||||
@@ -425,22 +426,18 @@ namespace battleship{
|
||||
|
||||
void Vehicle::build(Order order){
|
||||
if(pathPoints.empty()){
|
||||
if(!order.targets[0].unit)
|
||||
player->addUnit(order.targets[0].unit);
|
||||
else {
|
||||
Structure *structure = (Structure*)order.targets[0].unit;
|
||||
sol::table targTable = generateView()["units"][structure->getId()];
|
||||
int costRate = (int)targTable["cost"] / 100, buildRate = (int)targTable["buildTime"] / 100;
|
||||
Structure *structure = (Structure*)order.targets[0].unit;
|
||||
sol::table targTable = generateView()["units"][structure->getId()];
|
||||
int costRate = (int)targTable["cost"] / 100, buildRate = (int)targTable["buildTime"] / 100;
|
||||
|
||||
if(structure->getBuildStatus() < 100 && player->getResource(ResourceType::REFINEDS) >= costRate && getTime() - lastBuildTime > buildRate){
|
||||
structure->incrementBuildStatus();
|
||||
player->updateResource(ResourceType::REFINEDS, -costRate, true);
|
||||
lastBuildTime = getTime();
|
||||
}
|
||||
else if(structure->getBuildStatus() >= 100){
|
||||
removeOrder(0);
|
||||
player->incStructuresBuilt();
|
||||
}
|
||||
if(structure->getBuildStatus() < 100 && player->getResource(ResourceType::REFINEDS) >= costRate && getTime() - lastBuildTime > buildRate){
|
||||
structure->incrementBuildStatus();
|
||||
player->updateResource(ResourceType::REFINEDS, -costRate, true);
|
||||
lastBuildTime = getTime();
|
||||
}
|
||||
else if(structure->getBuildStatus() >= 100){
|
||||
removeOrder(0);
|
||||
player->incStructuresBuilt();
|
||||
}
|
||||
}
|
||||
else navigate(0.5 * Map::getSingleton()->getCellSize().x);
|
||||
|
||||
+54
-39
@@ -3,10 +3,12 @@
|
||||
#include <particleEmitter.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "unit.h"
|
||||
#include "util.h"
|
||||
#include "weapon.h"
|
||||
#include "player.h"
|
||||
#include "fxManager.h"
|
||||
#include "destructable.h"
|
||||
#include "gameObjectFactory.h"
|
||||
#include "projectile.h"
|
||||
|
||||
@@ -23,6 +25,7 @@ namespace battleship{
|
||||
{
|
||||
sol::table weaponTable = unitTable["weapons"][wid + 1];
|
||||
maxRange = weaponTable["maxRange"];
|
||||
maxFireAngle = weaponTable["maxFireAngle"].get_or(.1);
|
||||
orderType = (Order::TYPE)weaponTable["orderType"];
|
||||
|
||||
initProjectileData(weaponTable);
|
||||
@@ -48,11 +51,20 @@ namespace battleship{
|
||||
|
||||
for(int i = 0; i < numNodes; i++){
|
||||
sol::table nodeTbl = weaponTable["nodes"][i + 1];
|
||||
maxFireAngle = nodeTbl["maxFireAngle"];
|
||||
rotSpeed = nodeTbl["rotationSpeed"];
|
||||
float rotSpeed = nodeTbl["rotationSpeed"];
|
||||
bool vertical = nodeTbl["vertical"];
|
||||
|
||||
sol::optional<float> angleConstrOpt = nodeTbl["angleConstraint"];
|
||||
float angleConstr;
|
||||
|
||||
if(angleConstrOpt != sol::nullopt)
|
||||
angleConstr = nodeTbl["angleConstraint"];
|
||||
else angleConstr = (vertical ? PI / 2 : 0);
|
||||
|
||||
string name = nodeTbl["name"];
|
||||
nodes.push_back(unit->getModel()->findDescendant(name, true));
|
||||
Node *node = unit->getModel()->findDescendant(name, true);
|
||||
|
||||
components.push_back(Component(node, rotSpeed, angleConstr, vertical));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,19 +118,15 @@ namespace battleship{
|
||||
|
||||
int numOrders = unit->getNumOrders();
|
||||
int ordTp = (numOrders > 0 ? (int)unit->getOrder(0).type : -1);
|
||||
Unit *targUnit = (ordTp != -1 ? unit->getOrder(0).targets[0].unit : nullptr);
|
||||
GameObject *targDestruct = (ordTp != -1 ? unit->getOrder(0).targets[0].unit : nullptr);
|
||||
|
||||
if(ordTp == (int)orderType){
|
||||
Vector3 targPos = (targUnit ? targUnit->getPos() : unit->getOrder(0).targets[0].pos);
|
||||
Vector3 targPos = (targDestruct ? targDestruct->getPos() : unit->getOrder(0).targets[0].pos);
|
||||
float targDist = unit->getPos().getDistanceFrom(targPos);
|
||||
|
||||
bool withinRange = (minRange <= targDist && targDist <= maxRange);
|
||||
bool withinAngle = true;
|
||||
|
||||
if(!nodes.empty()){
|
||||
Vector3 dirVec = nodes[0]->getGlobalAxis(2);
|
||||
withinAngle = Vector3(dirVec.x, 0, dirVec.z).norm().getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle;
|
||||
}
|
||||
Vector3 dirVec = (components.empty() ? unit->getDirVec() : components[components.size() - 1].node->getGlobalAxis(2));
|
||||
bool withinAngle = (dirVec.getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle);
|
||||
|
||||
if((Order::TYPE)ordTp == Order::TYPE::ATTACK && withinRange && withinAngle)
|
||||
fire(unit->getOrder(0));
|
||||
@@ -128,10 +136,8 @@ namespace battleship{
|
||||
}
|
||||
|
||||
void Weapon::useFx(FxManager::Fx *fx, Vector3 targPos, bool fire){
|
||||
if(fx && !fire)
|
||||
FxManager::getSingleton()->addFx(fx);
|
||||
else if(!fx)
|
||||
return;
|
||||
if(fx && !fire) FxManager::getSingleton()->addFx(fx);
|
||||
else if(!fx) return;
|
||||
|
||||
fx->toggleComponents(true);
|
||||
|
||||
@@ -164,17 +170,19 @@ namespace battleship{
|
||||
}
|
||||
}
|
||||
|
||||
void Weapon::updateTargetUnit(Unit *targetUnit){
|
||||
targetUnit->takeDamage(damage);
|
||||
unit->updateGameStats(targetUnit);
|
||||
void Weapon::updateTarget(GameObject *target){
|
||||
target->getDestructable()->takeDamage(damage);
|
||||
|
||||
if(target->getType() == GameObject::Type::UNIT)
|
||||
unit->getPlayer()->updateGameStats((Unit*)target);
|
||||
}
|
||||
|
||||
//TODO replace the 'laser' flag literal
|
||||
void Weapon::fire(Order order){
|
||||
if(!canFire()) return;
|
||||
|
||||
Unit *targetUnit = order.targets[0].unit;
|
||||
Vector3 targPos = (targetUnit ? targetUnit->getPos() : order.targets[0].pos);
|
||||
GameObject *target = order.targets[0].unit;
|
||||
Vector3 targPos = (target ? target->getPos() : order.targets[0].pos);
|
||||
|
||||
if(fireFx) useFx(fireFx, targPos, true);
|
||||
|
||||
@@ -183,8 +191,7 @@ namespace battleship{
|
||||
FxManager *fxManager = FxManager::getSingleton();
|
||||
string fxKey = "unitHitFx";
|
||||
|
||||
if(targetUnit)
|
||||
updateTargetUnit(targetUnit);
|
||||
if(target) updateTarget(target);
|
||||
else{
|
||||
Map *map = Map::getSingleton();
|
||||
Map::Cell::Type cellType = map->getCells()[map->getCellId(targPos)].type;
|
||||
@@ -211,29 +218,37 @@ namespace battleship{
|
||||
|
||||
//TODO improve to allow for vertical alignment
|
||||
void Weapon::trackTarget(Vector3 targPos){
|
||||
if(nodes.empty()) return;
|
||||
for(Component &component : components){
|
||||
Vector3 unitPos = unit->getPos();
|
||||
Vector3 unitUp = unit->getUpVec();
|
||||
Vector3 targDir = (targPos - unitPos).norm();
|
||||
Vector3 targDirProj = getVecToPlane(unitPos, targDir, unitUp);
|
||||
|
||||
Vector3 unitPos = unit->getPos();
|
||||
Vector3 targDir = (targPos - unitPos).norm();
|
||||
targDir = getVecToPlane(unitPos, targDir, unit->getUpVec());
|
||||
Vector3 nodeDir = component.node->getGlobalAxis(2);
|
||||
|
||||
Vector3 dirVec = getVecToPlane(unitPos, nodes[0]->getGlobalAxis(2), unit->getUpVec());
|
||||
Vector3 leftVec = nodes[0]->getGlobalAxis(0);
|
||||
bool negate = (leftVec.getAngleBetween(targDir) < PI / 2);
|
||||
Vector3 rotAxis;
|
||||
float rotAngle;
|
||||
|
||||
float angle = dirVec.getAngleBetween(targDir);
|
||||
float rotAngle = (rotSpeed < angle ? rotSpeed : angle);
|
||||
if(component.vertical){
|
||||
float angle1 = targDir.getAngleBetween(targDirProj);
|
||||
float angle2 = nodeDir.getAngleBetween(getVecToPlane(unitPos, nodeDir, unitUp));
|
||||
float angleDiff = angle1 - angle2;
|
||||
rotAngle = (component.rotSpeed < fabs(angleDiff) ? component.rotSpeed : fabs(angleDiff)) * (angleDiff > 0 ? -1 : 1);
|
||||
|
||||
Quaternion rot = Quaternion((negate ? 1 : -1) * rotAngle, Vector3::VEC_J) * nodes[0]->getOrientation();
|
||||
nodes[0]->setOrientation(rot);
|
||||
}
|
||||
if(angle2 - rotAngle > component.angleConstr)
|
||||
rotAngle = -(fabs(rotAngle) - (angle2 + fabs(rotAngle) - component.angleConstr));
|
||||
|
||||
CryoGun::CryoGun(Unit *u, sol::table unitTable, int wid) : Weapon(u, unitTable, wid){}
|
||||
rotAxis = Vector3::VEC_I;
|
||||
}
|
||||
else{
|
||||
bool negate = (component.node->getGlobalAxis(0).getAngleBetween(targDirProj) < PI / 2);
|
||||
float angle = nodeDir.getAngleBetween(targDirProj);
|
||||
rotAngle = (negate ? 1 : -1) * (component.rotSpeed < angle ? component.rotSpeed : angle);
|
||||
rotAxis = Vector3::VEC_J;
|
||||
}
|
||||
|
||||
void CryoGun::updateTargetUnit(Unit *targetUnit){
|
||||
if(canFreeze()){
|
||||
targetUnit->setFreezeStatus(targetUnit->getFreezeStatus() + 1);
|
||||
lastFreezeTime = getTime();
|
||||
Quaternion rot = Quaternion(rotAngle, rotAxis) * component.node->getOrientation();
|
||||
component.node->setOrientation(rot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,38 @@
|
||||
#ifndef WEAPON_H
|
||||
#define WEAPON_H
|
||||
|
||||
#include "unit.h"
|
||||
|
||||
#include <vector>
|
||||
#include <util.h>
|
||||
#include <quaternion.h>
|
||||
|
||||
#include <solUtil.h>
|
||||
|
||||
#include "unit.h"
|
||||
|
||||
namespace vb01{
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace battleship{
|
||||
class FxManager;
|
||||
class GameObject;
|
||||
|
||||
class Weapon{
|
||||
public:
|
||||
enum class Type{FREEZER = 1};
|
||||
|
||||
struct Component{
|
||||
vb01::Node *node = nullptr;
|
||||
float rotSpeed, angleConstr;
|
||||
bool vertical;
|
||||
|
||||
Component(vb01::Node *n, float rs, float ac, bool v) :
|
||||
node(n),
|
||||
rotSpeed(rs),
|
||||
angleConstr(ac),
|
||||
vertical(v) {}
|
||||
};
|
||||
|
||||
Weapon(Unit*, sol::table, int);
|
||||
~Weapon();
|
||||
virtual void update();
|
||||
@@ -36,13 +49,11 @@ namespace battleship{
|
||||
Unit *unit = nullptr;
|
||||
Order::TYPE orderType;
|
||||
int id, projId = -1, damage = 0;
|
||||
float minRange = 0, maxRange, rotSpeed, maxFireAngle;
|
||||
float minRange = 0, maxRange, maxFireAngle;
|
||||
vb01::s64 lastFireTime = 0;
|
||||
FxManager::Fx *fireFx = nullptr;
|
||||
vb01::Quaternion projRot;
|
||||
vb01::Vector3 projPos;
|
||||
float horConstraint = 1.57, vertConstraint = 1.57;
|
||||
std::vector<vb01::Node*> nodes;
|
||||
vb01::Node *projPar = nullptr;
|
||||
static std::string LASER_FLAG;
|
||||
|
||||
@@ -52,18 +63,9 @@ namespace battleship{
|
||||
inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;}
|
||||
protected:
|
||||
int rateOfFire;
|
||||
std::vector<Component> components;
|
||||
|
||||
virtual void updateTargetUnit(Unit*);
|
||||
};
|
||||
|
||||
class CryoGun : public Weapon{
|
||||
public:
|
||||
CryoGun(Unit*, sol::table, int);
|
||||
private:
|
||||
vb01::s64 lastFreezeTime = 0;
|
||||
|
||||
void updateTargetUnit(Unit*);
|
||||
inline bool canFreeze(){return vb01::getTime() - lastFreezeTime > rateOfFire;}
|
||||
virtual void updateTarget(GameObject*);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user