diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-01-30 01:34:16 +0100 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-02-09 20:00:07 +0100 |
commit | 1b1050da1c7b84cc72b7efbb2229294975be9e10 (patch) | |
tree | 68d15ccb015d58aeb5797ffd06efca3e55997c24 /src/localplayer.cpp | |
parent | 0d4142a891cd228da24ee3aa3bbd7dc622da5b75 (diff) | |
parent | 955a7613d1fe116fe5e1da07a222b6849b3c885c (diff) | |
download | mana-1b1050da1c7b84cc72b7efbb2229294975be9e10.tar.gz mana-1b1050da1c7b84cc72b7efbb2229294975be9e10.tar.bz2 mana-1b1050da1c7b84cc72b7efbb2229294975be9e10.tar.xz mana-1b1050da1c7b84cc72b7efbb2229294975be9e10.zip |
Merged with Aethyra master as of 2009-01-27
Conflicts:
Almost everywhere.
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r-- | src/localplayer.cpp | 241 |
1 files changed, 222 insertions, 19 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 07044ce7..15f5b6b2 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -18,15 +18,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <cassert> -#include "localplayer.h" - +#include "configuration.h" #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" @@ -38,10 +40,16 @@ #include "net/messageout.h" #include "net/protocol.h" +#include "resources/imageset.h" +#include "resources/resourcemanager.h" + #include "utils/tostring.h" LocalPlayer *player_node = NULL; +static const int NAME_X_OFFSET = 15; +static const int NAME_Y_OFFSET = 30; + LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): Player(id, job, map), mCharId(0), @@ -60,20 +68,52 @@ 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)) { + // Variable to keep the local player from doing certain actions before a map + // is initialized. e.g. drawing a player's name using the TextManager, since + // it appears to be dependant upon map coordinates for updating drawing. + mMapInitialized = false; + + mUpdateName = true; + + initTargetCursor(); } LocalPlayer::~LocalPlayer() { delete mInventory; + delete mStorage; + delete mName; + + 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) { @@ -91,7 +131,6 @@ void LocalPlayer::logic() mFrame = (get_elapsed_time(mWalkTime) * frames) / mAttackSpeed; if (mFrame >= frames) { nextStep(); - attack(); } break; } @@ -100,10 +139,65 @@ 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(); } +void LocalPlayer::setGM() +{ + mIsGM = !mIsGM; + mNameColor = mIsGM ? 0x009000: 0x202020; + setName(getName()); + config.setValue(getName() + "GMassert", mIsGM); +} + +void LocalPlayer::setName(const std::string &name) +{ + if (mName) + { + delete mName; + mName = 0; + } + + if (config.getValue("showownname", false) && mMapInitialized) + { + Player::setName(name); + } + else + { + Being::setName(name); + } +} + void LocalPlayer::nextStep() { if (mPath.empty()) @@ -240,9 +334,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) { @@ -384,25 +488,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) @@ -418,8 +522,13 @@ void LocalPlayer::attack(Being *target, bool keep) setDirection(LEFT); } - setAction(ATTACK); + // Implement charging attacks here + mLastAttackTime = 0; + mWalkTime = tick_time; + mTargetTime = tick_time; + + setAction(ATTACK); if (mEquippedWeapon) { @@ -434,11 +543,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 @@ -481,6 +601,7 @@ bool LocalPlayer::withinAttackRange(Being *target) void LocalPlayer::setGotoTarget(Being *target) { + mLastTarget = -1; setTarget(target); mGoingToTarget = true; setDestination(target->mX, target->mY); @@ -527,3 +648,85 @@ void LocalPlayer::handleStatusEffect(StatusEffect *effect, int effectId) } } } + +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; +} |