00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "animatedsprite.h"
00023 #include "game.h"
00024 #include "localplayer.h"
00025 #include "monster.h"
00026 #include "particle.h"
00027 #include "sound.h"
00028 #include "text.h"
00029
00030 #include "gui/palette.h"
00031
00032 #include "resources/monsterdb.h"
00033 #include "resources/monsterinfo.h"
00034
00035 Monster::Monster(int id, int job, Map *map):
00036 Being(id, job, map),
00037 mText(0)
00038 {
00039 const MonsterInfo& info = getInfo();
00040
00041
00042 int c = BASE_SPRITE;
00043 const std::list<std::string> &sprites = info.getSprites();
00044
00045 for (std::list<std::string>::const_iterator i = sprites.begin();
00046 i != sprites.end(); i++)
00047 {
00048 if (c == VECTOREND_SPRITE) break;
00049
00050 std::string file = "graphics/sprites/" + *i;
00051 mSprites[c] = AnimatedSprite::load(file);
00052 c++;
00053 }
00054
00055
00056 if (c == BASE_SPRITE)
00057 {
00058 mSprites[c] = AnimatedSprite::load("graphics/sprites/error.xml");
00059 }
00060
00061 if (mParticleEffects)
00062 {
00063 const std::list<std::string> &particleEffects = info.getParticleEffects();
00064 for (std::list<std::string>::const_iterator i = particleEffects.begin();
00065 i != particleEffects.end(); i++)
00066 {
00067 controlParticle(particleEngine->addEffect((*i), 0, 0));
00068 }
00069 }
00070
00071 mNameColor = &guiPalette->getColor(Palette::MONSTER);
00072
00073 Being::setName(getInfo().getName());
00074 }
00075
00076 Monster::~Monster()
00077 {
00078 delete mText;
00079 }
00080
00081 #ifdef EATHENA_SUPPORT
00082 void Monster::logic()
00083 {
00084 if (mAction != STAND)
00085 {
00086 mFrame = (get_elapsed_time(mWalkTime) * 4) / getWalkSpeed();
00087
00088 if (mFrame >= 4 && mAction != DEAD)
00089 nextStep();
00090 }
00091
00092 Being::logic();
00093 }
00094 #endif
00095
00096 Being::Type Monster::getType() const
00097 {
00098 return MONSTER;
00099 }
00100
00101 void Monster::setAction(Action action, int attackType)
00102 {
00103 SpriteAction currentAction = ACTION_INVALID;
00104 int rotation = 0;
00105 std::string particleEffect;
00106
00107 switch (action)
00108 {
00109 case WALK:
00110 currentAction = ACTION_WALK;
00111 break;
00112 case DEAD:
00113 currentAction = ACTION_DEAD;
00114 sound.playSfx(getInfo().getSound(MONSTER_EVENT_DIE));
00115 break;
00116 case ATTACK:
00117 currentAction = getInfo().getAttackAction(attackType);
00118 mSprites[BASE_SPRITE]->reset();
00119
00120
00121 particleEffect = getInfo().getAttackParticleEffect(attackType);
00122 if (!particleEffect.empty() && mParticleEffects)
00123 {
00124 switch (mDirection)
00125 {
00126 case DOWN: rotation = 0; break;
00127 case LEFT: rotation = 90; break;
00128 case UP: rotation = 180; break;
00129 case RIGHT: rotation = 270; break;
00130 default: break;
00131 }
00132 Particle *p;
00133 p = particleEngine->addEffect(particleEffect, 0, 0, rotation);
00134 controlParticle(p);
00135 }
00136 break;
00137 case STAND:
00138 currentAction = ACTION_STAND;
00139 break;
00140 case HURT:
00141
00142 break;
00143 case SIT:
00144
00145 break;
00146 }
00147
00148 if (currentAction != ACTION_INVALID)
00149 {
00150 for (int i = 0; i < VECTOREND_SPRITE; i++)
00151 {
00152 if (mSprites[i])
00153 mSprites[i]->play(currentAction);
00154 }
00155 mAction = action;
00156 }
00157 }
00158
00159 #ifdef TMWSERV_SUPPORT
00160
00161 void Monster::handleAttack()
00162 {
00163 Being::handleAttack();
00164
00165 const MonsterInfo &mi = getInfo();
00166
00167
00168
00169
00170 sound.playSfx(mi.getSound(MONSTER_EVENT_HIT));
00171 }
00172
00173 #else
00174
00175 void Monster::handleAttack(Being *victim, int damage, AttackType type)
00176 {
00177 Being::handleAttack(victim, damage, type);
00178
00179 const MonsterInfo &mi = getInfo();
00180 sound.playSfx(mi.getSound((damage > 0) ?
00181 MONSTER_EVENT_HIT : MONSTER_EVENT_MISS));
00182 }
00183
00184 #endif
00185
00186 void Monster::takeDamage(Being *attacker, int amount, AttackType type)
00187 {
00188 if (amount > 0)
00189 sound.playSfx(getInfo().getSound(MONSTER_EVENT_HURT));
00190
00191 Being::takeDamage(attacker, amount, type);
00192 }
00193
00194 Being::TargetCursorSize Monster::getTargetCursorSize() const
00195 {
00196 return getInfo().getTargetCursorSize();
00197 }
00198
00199 const MonsterInfo &Monster::getInfo() const
00200 {
00201 return MonsterDB::get(mJob);
00202 }
00203
00204 void Monster::setShowName(bool show)
00205 {
00206 delete mText;
00207
00208 if (show)
00209 {
00210 mText = new Text(getInfo().getName(),
00211 getPixelX(),
00212 getPixelY() - getHeight(),
00213 gcn::Graphics::CENTER,
00214 &guiPalette->getColor(Palette::MONSTER));
00215 }
00216 else
00217 {
00218 mText = 0;
00219 }
00220 }
00221
00222 void Monster::updateCoords()
00223 {
00224 if (mText)
00225 {
00226 mText->adviseXY(getPixelX(),
00227 getPixelY() - getHeight() - mText->getHeight());
00228 }
00229 }