OSDN Git Service

日本語版
[nazghul-jp/nazghul-jp.git] / src / Missile.cpp
1 //
2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 2 of the License, or (at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 // more details.
14 //
15 // You should have received a copy of the GNU General Public License along with
16 // this program; if not, write to the Free Foundation, Inc., 59 Temple Place,
17 // Suite 330, Boston, MA 02111-1307 USA
18 //
19 // Gordon McNutt
20 // gmcnutt@users.sourceforge.net
21 //
22
23 #include "Missile.h"
24 #include "dice.h"
25 #include "character.h"
26 #include "screen.h"
27 #include "mmode.h"
28 #include "sprite.h"
29 #include "map.h"
30 #include "console.h"
31 #include "Field.h"
32 #include "place.h"
33 #include "player.h"
34 #include "vehicle.h"
35 #include "session.h"
36
37 MissileType::MissileType()
38 {
39         // Don't ever expect to call this. Defining it to override the default
40         // one c++ automatically creates.
41         assert(false);
42         
43         beam = false;
44 }
45
46 MissileType::MissileType(const char *tag, const char *name, struct sprite *sprite, bool isBeam, bool isFixedRange, struct mmode *mmode)
47         : ObjectType(tag, name, sprite, item_layer),
48                 beam(isBeam),
49                 fixedrange(isFixedRange)
50 {
51         setMovementMode(mmode);
52 }
53
54 MissileType::~MissileType()
55 {
56         //dont think theres anything here that needs cleaning up?
57 }
58
59 bool MissileType::isType(int classID)
60 {
61         if (classID == MISSILE_TYPE_ID)
62                 return true;
63         return ObjectType::isType(classID);
64 }
65
66 int MissileType::getType()
67 {
68         return MISSILE_TYPE_ID;
69 }
70
71 bool MissileType::isBeam()
72 {
73         return beam;
74 }
75
76 // A fixed range missile always fires to its maximum range (LOS allowing).
77 // target selection merely affects the angle it travels at
78 bool MissileType::isFixedRange()
79 {
80         return fixedrange;
81 }
82
83 void MissileType::fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam)
84 {
85         if (canHitLocation())
86                 hitLocation(NULL, attacker, target, place, x, y, dam);  
87 }
88
89 bool MissileType::fireEnterTile(Missile *missile, struct place *place, int x, int y)
90 {
91         if (closure_exec(gifc, "yppdd", "enter", missile, place, x, y))
92         {
93                 return true;    
94         }
95         else
96         {
97                 return false;   
98         }
99 }
100
101 Missile::Missile(MissileType* type)
102         : Object(type)
103 {
104
105 }
106
107 Missile::~Missile()
108 {
109 }
110
111 class MissileType *Missile::getObjectType() 
112 {
113         return (class MissileType *) Object::getObjectType();
114 }
115
116 /* set hit=true if a party or object has been struck
117 return true if the missile has not been interupted */
118 bool Missile::enterTile(struct place *place, int x, int y)
119 {
120         if (! (flags & MISSILE_IGNORE_LOS))
121                         {
122                                 int obstruction = place_get_movement_cost(place, x, y, this,0);
123                                  //int opacity = place_visibility(place, x, y);
124                                  return ((obstruction != 20) && (dice_roll_numeric(1,100,0)>obstruction));
125                         }       
126                         
127         if (! (flags & MISSILE_HIT_PARTY))
128                 return true;
129
130         struck = place_get_Party(place, x, y);
131
132         if (struck != NULL) {
133                 hit = true;
134                 return false;
135         }
136
137         // fugly hack...
138         if (player_party->getPlace() == place &&
139             player_party->getX() == x &&
140             player_party->getY() == y) {
141                 struck = player_party;
142                 hit = true;
143                 return false;
144         }
145
146         /* Allow wilderness-scale weapons to destroy empty vehicles. */
147         struck = place_get_vehicle(place, x, y);
148         if (struck != NULL) {
149                 hit = true;
150                 return false;
151         }
152
153         return true;
154 }
155
156 /*
157         triggers a hit-loc ifc event if appropriate
158 */
159 void Missile::fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam)
160 {
161         if (getObjectType()->canHitLocation())
162                 getObjectType()->hitLocation(this, attacker, target, place, x, y, dam); 
163 }
164
165 /*
166         Calculates & animates trajectory, returns true if the missile reached the target location
167         alters Bx, By to be where it reached (so you can tell where it wound up if blocked)
168 */
169 void Missile::animate(int Ax, int Ay, int *Bx, int *By, int _flags, float fixedrange)
170 {
171         int origBx = *Bx;
172         int origBy = *By;
173         
174         hit = false;
175         struck = NULL;
176         flags = _flags;
177
178         struct sprite *tmpSprite = sprite_clone(getSprite(), 0);
179         mapAnimateProjectile(Ax, Ay, Bx, By, tmpSprite, getPlace(), this, fixedrange);
180         sprite_del(tmpSprite);
181
182         hit = (hit || (origBx == *Bx && origBy == *By));
183 }
184
185 bool Missile::hitTarget()
186 {
187         return hit;
188 }
189
190 class Object * Missile::getStruck()
191 {
192         return struck;
193 }
194