1 /* Copyright (C) 2013-2014 Michal Brzozowski (rusolis@poczta.fm)
2
3 This file is part of KeeperRL.
4
5 KeeperRL is free software; you can redistribute it and/or modify it under the terms of the
6 GNU General Public License as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with this program.
14 If not, see http://www.gnu.org/licenses/ . */
15
16 #include "stdafx.h"
17
18 #include "ranged_weapon.h"
19 #include "creature.h"
20 #include "level.h"
21 #include "attack.h"
22 #include "view.h"
23 #include "game.h"
24 #include "sound.h"
25 #include "attack_level.h"
26 #include "attack_type.h"
27 #include "skill.h"
28 #include "creature_attributes.h"
29 #include "player_message.h"
30 #include "view_id.h"
31 #include "event_listener.h"
32 #include "vision.h"
33
SERIALIZE_DEF(RangedWeapon,damageAttr,projectileName,projectileViewId)34 SERIALIZE_DEF(RangedWeapon, damageAttr, projectileName, projectileViewId)
35 SERIALIZATION_CONSTRUCTOR_IMPL(RangedWeapon)
36
37 RangedWeapon::RangedWeapon(AttrType attr, const string& name, ViewId id)
38 : damageAttr(attr), projectileName(name), projectileViewId(id) {}
39
fire(WCreature c,Vec2 dir) const40 void RangedWeapon::fire(WCreature c, Vec2 dir) const {
41 CHECK(dir.length8() == 1);
42 c->getGame()->getView()->addSound(SoundId::SHOOT_BOW);
43 int damage = c->getAttr(damageAttr);
44 Attack attack(c, Random.choose(AttackLevel::LOW, AttackLevel::MIDDLE, AttackLevel::HIGH),
45 AttackType::SHOOT, damage, damageAttr, none);
46 const auto position = c->getPosition();
47 auto vision = c->getVision().getId();
48 Position lastPos;
49 for (Position pos = position.plus(dir);; pos = pos.plus(dir)) {
50 lastPos = pos;
51 if (auto c = pos.getCreature()) {
52 c->you(MsgType::HIT_THROWN_ITEM, "the " + projectileName);
53 c->takeDamage(attack);
54 break;
55 }
56 if (pos.stopsProjectiles(vision)) {
57 pos.globalMessage("the " + projectileName + " hits the " + pos.getName());
58 break;
59 }
60 }
61 c->getGame()->addEvent(EventInfo::Projectile{projectileViewId, position, lastPos});
62 }
63
getDamageAttr() const64 AttrType RangedWeapon::getDamageAttr() const {
65 return damageAttr;
66 }
67