This repository has been archived on 2019-12-07. You can view files and clone it, but cannot push or open issues or pull requests.
dungeon-gunner/source/items/Weapon.cpp

172 lines
3.8 KiB
C++
Raw Normal View History

/*
* Weapon.cpp
*
* Created on: 12.08.2012
* Author: Felix
*/
#include "Weapon.h"
2013-05-20 10:07:05 +00:00
#include <Thor/Vectors.hpp>
2012-09-12 12:21:57 +00:00
2012-12-22 13:56:17 +00:00
#include "../World.h"
#include "../effects/Bullet.h"
2013-03-29 17:34:51 +00:00
#include "../util/Yaml.h"
2013-07-14 19:56:44 +00:00
Weapon::Weapon(World& world, Character& holder, const Yaml& config) :
Item(sf::Vector2f(80, 30), "weapon.png"),
mWorld(world),
2013-07-21 08:52:50 +00:00
mHolder(&holder),
2013-07-06 11:38:15 +00:00
mName(config.get("name", std::string())),
mProjectile(config.get("bullet", std::string("bullet.yaml"))),
mDamage(config.get("damage", 0)),
mProjectileSpeed(config.get("projectile_speed", 0.0f)),
mFireInterval(config.get("fire_interval", 0)),
mReloadTime(config.get("reload_time", 0)),
mFiring(false),
mAutomatic(config.get("automatic", false)),
mMagazineSize(config.get("magazine_size", 0)),
mMagazineAmmo(mMagazineSize),
mMaxTotalAmmo(config.get("max_total_ammo", 0)),
mTotalAmmo(mMaxTotalAmmo),
mPellets(config.get("pellets", 0)),
mPelletSpread(config.get("pellet_spread", 0.0f)),
mReloadSingle(config.get("reload_single", false)),
mSpread(config.get("spread", 0.0f)),
2013-07-06 11:22:55 +00:00
mSpreadMoving(config.get("spread_moving", 0.0f)),
mMaxRange(config.get("max_range", 0.0f)),
mRequiresAmmo(!config.get("requires_no_ammo", false)) {
}
/**
* Pull the trigger.
*/
void
2012-12-24 00:14:22 +00:00
Weapon::pullTrigger() {
mFiring = true;
2012-12-24 00:14:22 +00:00
}
/**
* Release the trigger.
*/
void
Weapon::releaseTrigger() {
mFiring = false;
2012-12-24 00:14:22 +00:00
}
/**
* Fire if the trigger has been pulled, time between bullets is over, has ammo etc.
2013-03-09 15:25:04 +00:00
*
* @param elapsed Amount of time to simulate.
2012-12-24 00:14:22 +00:00
*/
void
2013-03-09 15:25:04 +00:00
Weapon::onThink(int elapsed) {
if (!mTimer.isExpired())
return;
if (mIsReloading) {
if (!mReloadSingle) {
mMagazineAmmo = (mTotalAmmo >= mMagazineSize)
? mMagazineSize
: mTotalAmmo;
mTotalAmmo -= mMagazineAmmo;
mIsReloading = false;
}
else if (mTotalAmmo > 0) {
mMagazineAmmo++;
mTotalAmmo--;
if (mMagazineAmmo == mMagazineSize)
mIsReloading = false;
else
reload();
}
else
mIsReloading = false;
}
2013-07-06 11:22:55 +00:00
if (mFiring && (!mRequiresAmmo || mMagazineAmmo != 0)) {
fire();
2013-04-04 21:13:08 +00:00
if (!mAutomatic)
mFiring = false;
}
2013-07-06 11:22:55 +00:00
if (mRequiresAmmo && mMagazineAmmo == 0 && mTotalAmmo != 0)
reload();
}
/**
* Creates and fires a projectile.
*/
void
Weapon::fire() {
mTimer.restart(sf::milliseconds(mFireInterval));
2013-07-06 11:22:55 +00:00
if (mRequiresAmmo)
mMagazineAmmo--;
if (mPellets == 0)
insertProjectile(0.0f);
else
for (int i = - mPellets / 2; i < mPellets / 2; i++) {
insertProjectile(i * mPelletSpread);
}
}
int
Weapon::getMagazineAmmo() const {
return mMagazineAmmo;
}
int
Weapon::getTotalAmmo() const {
return mTotalAmmo;
}
2013-07-06 11:38:15 +00:00
std::string
Weapon::getName() const {
return mName;
}
void
Weapon::reload() {
if (mMagazineAmmo == mMagazineSize)
return;
mIsReloading = true;
mTimer.restart(sf::milliseconds(mReloadTime));
}
2013-06-25 20:00:40 +00:00
void
Weapon::cancelReload() {
mIsReloading = false;
// To make sure time isn't skipped.
mTimer.restart(sf::milliseconds(mFireInterval));
}
2013-07-21 08:52:50 +00:00
void
Weapon::setHolder(Character& holder) {
mHolder = &holder;
}
/**
* 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) {
2013-07-21 08:52:50 +00:00
sf::Vector2f offset(mHolder->getDirection() * mHolder->getRadius());
2013-07-21 08:52:50 +00:00
float spread = (mHolder->getSpeed() == sf::Vector2f())
? mSpread
: mSpreadMoving;
std::uniform_real_distribution<float> distribution(- spread, spread);
2013-07-10 21:25:53 +00:00
angle += distribution(mGenerator) + 90.0f;
2013-07-21 08:52:50 +00:00
sf::Vector2f direction(thor::rotatedVector(mHolder->getDirection(), angle));
2013-07-21 08:52:50 +00:00
std::shared_ptr<Sprite> projectile(new Bullet(mHolder->getPosition() + offset,
*mHolder, direction, mProjectile, mProjectileSpeed,
2013-07-06 11:22:55 +00:00
mDamage, mMaxRange));
mWorld.insert(projectile);
}