diff options
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r-- | src/localplayer.cpp | 200 |
1 files changed, 181 insertions, 19 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 3550b092..292f70e0 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -18,15 +18,16 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "localplayer.h" +#include <cassert> #include "equipment.h" #include "floor_item.h" #include "game.h" #include "inventory.h" #include "item.h" +#include "localplayer.h" #include "main.h" +#include "monster.h" #include "particle.h" #include "sound.h" #include "monster.h" @@ -36,6 +37,9 @@ #include "net/messageout.h" #include "net/protocol.h" +#include "resources/imageset.h" +#include "resources/resourcemanager.h" + #include "utils/tostring.h" LocalPlayer *player_node = NULL; @@ -48,20 +52,44 @@ LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): mXp(0), mNetwork(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mGoingToTarget(false), - mLastAction(-1), - mWalkingDir(0), mDestX(0), mDestY(0), - mInventory(new Inventory) + mTargetTime(-1), mLastAction(-1), + mLastTarget(-1), mWalkingDir(0), + mDestX(0), mDestY(0), + mInventory(new Inventory(INVENTORY_SIZE)), + mStorage(new Inventory(STORAGE_SIZE)) { + initTargetCursor(); } LocalPlayer::~LocalPlayer() { delete mInventory; + delete mStorage; + + for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++) + { + delete mTargetCursorInRange[i]; + delete mTargetCursorOutRange[i]; + mInRangeImages[i]->decRef(); + mOutRangeImages[i]->decRef(); + } } void LocalPlayer::logic() { switch (mAction) { + case STAND: + break; + + case SIT: + break; + + case DEAD: + break; + + case HURT: + break; + case WALK: mFrame = (get_elapsed_time(mWalkTime) * 6) / mWalkSpeed; if (mFrame >= 6) { @@ -79,7 +107,6 @@ void LocalPlayer::logic() mFrame = (get_elapsed_time(mWalkTime) * frames) / mAttackSpeed; if (mFrame >= frames) { nextStep(); - attack(); } break; } @@ -88,6 +115,35 @@ void LocalPlayer::logic() if (get_elapsed_time(mLastAction) >= 1000) { mLastAction = -1; } + // Targeting allowed 4 times a second + if (get_elapsed_time(mLastTarget) >= 250) { + mLastTarget = -1; + } + // Remove target if its been on a being for more than a minute + if (get_elapsed_time(mTargetTime) >= 60000) + { + mTargetTime = -1; + setTarget(NULL); + mLastTarget = -1; + } + + if (mTarget) + { + if (mTarget->mAction == DEAD) + { + stopAttack(); + } + if (mKeepAttacking && mTarget) + { + attack(mTarget, true); + } + + for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++) + { + player_node->mTargetCursorInRange[i]->update(10); + player_node->mTargetCursorOutRange[i]->update(10); + } + } Being::logic(); } @@ -228,9 +284,19 @@ void LocalPlayer::walk(unsigned char dir) void LocalPlayer::setTarget(Being *target) { - if (target == mTarget) - { + if (mLastTarget != -1 || target == this) return; + mLastTarget = tick_time; + + if ((target == NULL) || target == mTarget) + { + target = NULL; + mKeepAttacking = false; + mTargetTime = -1; + } + if (target) + { + mTargetTime = tick_time; } if (mTarget && mTarget->getType() == Being::MONSTER) { @@ -375,25 +441,25 @@ bool LocalPlayer::tradeRequestOk() const void LocalPlayer::attack(Being *target, bool keep) { - // Can only attack when standing still - if (mAction != STAND) + mKeepAttacking = keep; + + if (!target) return; - if (keep && target) + if ((mTarget != target) || !mTarget) { + mLastTarget = -1; setTarget(target); } - else if (mTarget) - { - target = mTarget; - } - - if (!target) - return; int dist_x = target->mX - mX; int dist_y = target->mY - mY; + // Must be standing and be within attack range to continue + if ((mAction != STAND) || (mAttackRange < abs(dist_x)) || + (mAttackRange < abs(dist_y))) + return; + if (abs(dist_y) >= abs(dist_x)) { if (dist_y > 0) @@ -412,8 +478,10 @@ void LocalPlayer::attack(Being *target, bool keep) // Implement charging attacks here mLastAttackTime = 0; - setAction(ATTACK); mWalkTime = tick_time; + mTargetTime = tick_time; + + setAction(ATTACK); if (mEquippedWeapon) { @@ -428,11 +496,22 @@ void LocalPlayer::attack(Being *target, bool keep) outMsg.writeInt16(0x0089); outMsg.writeInt32(target->getId()); outMsg.writeInt8(0); + + if (!keep) + { + stopAttack(); + } } void LocalPlayer::stopAttack() { + if (mTarget) + { + setAction(STAND); + mLastTarget = -1; + } setTarget(NULL); + mLastTarget = -1; } Being* LocalPlayer::getTarget() const @@ -475,7 +554,90 @@ bool LocalPlayer::withinAttackRange(Being *target) void LocalPlayer::setGotoTarget(Being *target) { + mLastTarget = -1; setTarget(target); mGoingToTarget = true; setDestination(target->mX, target->mY); } + +void LocalPlayer::initTargetCursor() +{ + // Load target cursors + loadTargetCursor("graphics/gui/target-cursor-blue-s.png", 44, 35, + false, TC_SMALL); + loadTargetCursor("graphics/gui/target-cursor-red-s.png", 44, 35, + true, TC_SMALL); + loadTargetCursor("graphics/gui/target-cursor-blue-m.png", 62, 44, + false, TC_MEDIUM); + loadTargetCursor("graphics/gui/target-cursor-red-m.png", 62, 44, + true, TC_MEDIUM); + loadTargetCursor("graphics/gui/target-cursor-blue-l.png", 82, 60, + false, TC_LARGE); + loadTargetCursor("graphics/gui/target-cursor-red-l.png", 82, 60, + true, TC_LARGE); +} + +void LocalPlayer::loadTargetCursor(std::string filename, int width, int height, + bool outRange, TargetCursorSize size) +{ + assert(size > -1); + assert(size < 3); + + ImageSet* currentImageSet; + SimpleAnimation* currentCursor; + + ResourceManager *resman = ResourceManager::getInstance(); + + currentImageSet = resman->getImageSet(filename, width, height); + Animation *anim = new Animation(); + for (unsigned int i = 0; i < currentImageSet->size(); ++i) + { + anim->addFrame(currentImageSet->get(i), 75, 0, 0); + } + currentCursor = new SimpleAnimation(anim); + + if (outRange) + { + mOutRangeImages[size] = currentImageSet; + mTargetCursorOutRange[size] = currentCursor; + } + else + { + mInRangeImages[size] = currentImageSet; + mTargetCursorInRange[size] = currentCursor; + } +} + +void LocalPlayer::drawTargetCursor(Graphics *graphics, int scrollX, int scrollY) +{ + + // Draw target marker if needed + if (mTarget) + { + // Calculate target circle position + + // Find whether target is in range + int rangeX = abs(mTarget->mX - mX); + int rangeY = abs(mTarget->mY - mY); + int attackRange = getAttackRange(); + + // Get the correct target cursors graphic + TargetCursorSize cursorSize = mTarget->getTargetCursorSize(); + + if (rangeX > attackRange || rangeY > attackRange) + { + mTarget->mTargetCursor = mTargetCursorOutRange[cursorSize]->getCurrentImage(); + } + else + { + mTarget->mTargetCursor = mTargetCursorInRange[cursorSize]->getCurrentImage(); + } + + // Draw the target cursor at the correct position + int posX = mTarget->getPixelX() + 16 - mTarget->mTargetCursor->getWidth() / 2 - scrollX; + int posY = mTarget->getPixelY() + 16 - mTarget->mTargetCursor->getHeight() / 2 - scrollY; + + graphics->drawImage(mTarget->mTargetCursor, posX, posY); + } + return; +} |