Added shotgun/auto shotgun, removed Particle/Emitter.

This commit is contained in:
Felix Ableitner 2013-06-25 20:59:03 +02:00
parent db662808c2
commit 6923092c3b
7 changed files with 97 additions and 32 deletions

View file

@ -0,0 +1,13 @@
name: Automatic Shotgun
bullet: bullet.yaml
projectile_speed: 750
damage: 2
pellets: 6
pellet_spread: 2.0
fire_interval: 400
reload_time: 2000
reload_single: false
automatic: true
magazine_size: 6
max_total_ammo: 60

View file

@ -5,5 +5,5 @@ health: 100
speed: 100 speed: 100
radius: 25 radius: 25
size: [50, 50] size: [50, 50]
weapon: rifle.yaml weapon: shotgun.yaml
faction: 0 faction: 0

View file

@ -0,0 +1,13 @@
name: Shotgun
bullet: bullet.yaml
projectile_speed: 750
damage: 5
pellets: 6
pellet_spread: 2.0
fire_interval: 800
reload_time: 500
reload_single: true
automatic: false
magazine_size: 6
max_total_ammo: 60

View file

@ -23,7 +23,7 @@
Bullet::Bullet(const sf::Vector2f& position, Character& shooter, Bullet::Bullet(const sf::Vector2f& position, Character& shooter,
sf::Vector2f direction, const Yaml& config, float speed, sf::Vector2f direction, const Yaml& config, float speed,
float damage) : float damage) :
Particle(position, CATEGORY_PARTICLE, ~CATEGORY_PARTICLE, Circle(position, CATEGORY_PARTICLE, ~CATEGORY_PARTICLE,
config, thor::rotatedVector(direction, -90.0f)), config, thor::rotatedVector(direction, -90.0f)),
mShooter(shooter), mShooter(shooter),
mDamage(damage), mDamage(damage),

View file

@ -8,7 +8,7 @@
#ifndef DG_BULLET_H_ #ifndef DG_BULLET_H_
#define DG_BULLET_H_ #define DG_BULLET_H_
#include "../particle/Particle.h" #include "../abstract/Circle.h"
class Character; class Character;
class Yaml; class Yaml;
@ -16,7 +16,7 @@ class Yaml;
/** /**
* Bullet particle fired by a weapon, may damage actors. * Bullet particle fired by a weapon, may damage actors.
*/ */
class Bullet : public Particle { class Bullet : public Circle {
public: public:
explicit Bullet(const sf::Vector2f& position, Character& shooter, explicit Bullet(const sf::Vector2f& position, Character& shooter,
sf::Vector2f direction, const Yaml& config, float speed, sf::Vector2f direction, const Yaml& config, float speed,

View file

@ -14,19 +14,22 @@
#include "../util/Yaml.h" #include "../util/Yaml.h"
Weapon::Weapon(World& world, Character& holder, const Yaml& config) : Weapon::Weapon(World& world, Character& holder, const Yaml& config) :
Emitter(world), mWorld(world),
mHolder(holder), mHolder(holder),
mProjectile(config.get("bullet", std::string("bullet.yaml"))), mProjectile(config.get("bullet", std::string("bullet.yaml"))),
mDamage(config.get("damage", 0)), mDamage(config.get("damage", 0)),
mProjectileSpeed(config.get("projectile_speed", 0.0f)), mProjectileSpeed(config.get("projectile_speed", 0.0f)),
mFireInterval(config.get("fire_interval", 0)), mFireInterval(config.get("fire_interval", 0)),
mReloadTime(config.get("reload_time", 0)), mReloadTime(config.get("reload_time", 0)),
mFire(false), mFiring(false),
mAutomatic(config.get("automatic", false)), mAutomatic(config.get("automatic", false)),
mMagazineSize(config.get("magazine_size", 0)), mMagazineSize(config.get("magazine_size", 0)),
mMagazineAmmo(mMagazineSize), mMagazineAmmo(mMagazineSize),
mMaxTotalAmmo(config.get("max_total_ammo", 0)), mMaxTotalAmmo(config.get("max_total_ammo", 0)),
mTotalAmmo(mMaxTotalAmmo) { mTotalAmmo(mMaxTotalAmmo),
mPellets(config.get("pellets", 1)),
mPelletSpread(config.get("pellet_spread", 0.0f)),
mReloadSingle(config.get("reload_single", false)) {
} }
/** /**
@ -34,7 +37,7 @@ Weapon::Weapon(World& world, Character& holder, const Yaml& config) :
*/ */
void void
Weapon::pullTrigger() { Weapon::pullTrigger() {
mFire = true; mFiring = true;
} }
/** /**
@ -42,7 +45,7 @@ Weapon::pullTrigger() {
*/ */
void void
Weapon::releaseTrigger() { Weapon::releaseTrigger() {
mFire = false; mFiring = false;
} }
/** /**
@ -54,18 +57,31 @@ void
Weapon::onThink(int elapsed) { Weapon::onThink(int elapsed) {
if (!mTimer.isExpired()) if (!mTimer.isExpired())
return; return;
if (mIsReloading) { if (mIsReloading) {
if (!mReloadSingle) {
mMagazineAmmo = (mTotalAmmo >= mMagazineSize) mMagazineAmmo = (mTotalAmmo >= mMagazineSize)
? mMagazineSize ? mMagazineSize
: mTotalAmmo; : mTotalAmmo;
mTotalAmmo -= mMagazineAmmo; mTotalAmmo -= mMagazineAmmo;
mIsReloading = false; mIsReloading = false;
} }
else if (mTotalAmmo > 0) {
mMagazineAmmo++;
mTotalAmmo--;
if (mMagazineAmmo == mMagazineSize)
mIsReloading = false;
else
reload();
}
else
mIsReloading = false;
}
if (mFire && mMagazineAmmo != 0) { if (mFiring && mMagazineAmmo != 0) {
emit(); fire();
if (!mAutomatic) if (!mAutomatic)
mFire = false; mFiring = false;
} }
if (mMagazineAmmo == 0 && mTotalAmmo != 0) if (mMagazineAmmo == 0 && mTotalAmmo != 0)
@ -75,17 +91,17 @@ Weapon::onThink(int elapsed) {
/** /**
* Creates and fires a projectile. * Creates and fires a projectile.
*/ */
std::shared_ptr<Sprite> void
Weapon::createParticle() { Weapon::fire() {
mTimer.restart(sf::milliseconds(mFireInterval)); mTimer.restart(sf::milliseconds(mFireInterval));
mMagazineAmmo--; mMagazineAmmo--;
// Minus to account for positive y-axis going downwards in SFML.
sf::Vector2f offset(0, - mHolder.getRadius()); if (mPellets == 0) insertProjectile(0.0f);
thor::rotate(offset, thor::polarAngle(mHolder.getDirection())); else
return std::shared_ptr<Sprite>(new Bullet(mHolder.getPosition() + offset, for (int i = - mPellets / 2; i < mPellets / 2; i++) {
mHolder, mHolder.getDirection(), mProjectile, mProjectileSpeed, insertProjectile(i * mPelletSpread);
mDamage)); }
} }
int int
@ -100,6 +116,25 @@ Weapon::getTotalAmmo() const {
void void
Weapon::reload() { Weapon::reload() {
if (mMagazineAmmo == mMagazineSize)
return;
mIsReloading = true; mIsReloading = true;
mTimer.restart(sf::milliseconds(mReloadTime)); mTimer.restart(sf::milliseconds(mReloadTime));
} }
/**
* Creates a new projectile and inserts it into the world.
*
* @param angle Inaccuracy of the projectile, 0 is straight forward.
*/
void
Weapon::insertProjectile(float angle) {
// Minus to account for positive y-axis going downwards in SFML.
sf::Vector2f offset(0, - mHolder.getRadius());
thor::rotate(offset, thor::polarAngle(mHolder.getDirection()));
sf::Vector2f direction(thor::rotatedVector(mHolder.getDirection(), angle));
std::shared_ptr<Sprite> projectile(new Bullet(mHolder.getPosition() + offset,
mHolder, direction, mProjectile, mProjectileSpeed,
mDamage));
mWorld.insert(projectile);
}

View file

@ -14,7 +14,6 @@
#include <Thor/Time.hpp> #include <Thor/Time.hpp>
#include "../particle/Emitter.h"
#include "../util/Yaml.h" #include "../util/Yaml.h"
class Character; class Character;
@ -27,7 +26,7 @@ class Yaml;
* - pass enum value and load mapped xml * - pass enum value and load mapped xml
* - pass xml filename * - pass xml filename
*/ */
class Weapon : public Emitter { class Weapon {
public: public:
explicit Weapon(World& world, Character& holder, const Yaml& config); explicit Weapon(World& world, Character& holder, const Yaml& config);
@ -38,10 +37,12 @@ public:
int getTotalAmmo() const; int getTotalAmmo() const;
void reload(); void reload();
protected: private:
std::shared_ptr<Sprite> createParticle(); void fire();
void insertProjectile(float angle);
private: private:
World& mWorld;
Character& mHolder; Character& mHolder;
thor::Timer mTimer; thor::Timer mTimer;
@ -50,13 +51,16 @@ private:
const float mProjectileSpeed; const float mProjectileSpeed;
const int mFireInterval; const int mFireInterval;
const int mReloadTime; const int mReloadTime;
bool mFire; bool mFiring;
bool mAutomatic; const bool mAutomatic;
const int mMagazineSize; const int mMagazineSize;
int mMagazineAmmo; int mMagazineAmmo;
const int mMaxTotalAmmo; const int mMaxTotalAmmo;
int mTotalAmmo; int mTotalAmmo;
bool mIsReloading = false; bool mIsReloading = false;
const int mPellets;
const float mPelletSpread;
const bool mReloadSingle;
}; };