diff options
author | Björn Steinbrink <B.Steinbrink@gmx.de> | 2006-02-07 10:37:54 +0000 |
---|---|---|
committer | Björn Steinbrink <B.Steinbrink@gmx.de> | 2006-02-07 10:37:54 +0000 |
commit | ac08acd4b4029a2519c81eecf938e1c03b51233c (patch) | |
tree | 78405d149cff52b310343a1e557062345b784d41 | |
parent | c395103a0f190598e234b2c5f373d3fde25f77cf (diff) | |
download | mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.gz mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.bz2 mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.xz mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.zip |
Made the being directions being stored in a bitfield.
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | src/being.cpp | 36 | ||||
-rw-r--r-- | src/being.h | 18 | ||||
-rw-r--r-- | src/game.cpp | 154 | ||||
-rw-r--r-- | src/localplayer.cpp | 78 | ||||
-rw-r--r-- | src/localplayer.h | 3 | ||||
-rw-r--r-- | src/monster.cpp | 5 | ||||
-rw-r--r-- | src/net/messagein.cpp | 32 | ||||
-rw-r--r-- | src/net/protocol.cpp | 32 | ||||
-rw-r--r-- | src/player.cpp | 4 |
10 files changed, 191 insertions, 190 deletions
@@ -1,9 +1,16 @@ -2006-02-06 Philipp Sehmisch <tmw@crushnet.org> +2006-02-07 Björn Steinbrink <B.Steinbrink@gmx.de> + + * src/being.cpp, src/being.h, src/game.cpp, src/localplayer.cpp, + src/localplayer.h, src/monster.cpp, src/player.cpp, + src/net/messagein.cpp, src/net/protocol.cpp: Made the being directions + being stored in a bitfield. + +2006-02-06 Philipp Sehmisch <tmw@crushnet.org> + * data/graphics/tiles/Woodland_ground.png, - data/graphics/tiles/Woodland_x2.png, - data/maps/new_9.1.tmx.gz: added dynamic grass that - covers the lower area of sprites (doesn't work for flower - beds yet). + data/graphics/tiles/Woodland_x2.png, data/maps/new_9.1.tmx.gz: added + dynamic grass that covers the lower area of sprites (doesn't work for + flower beds yet). 2006-02-06 Eugenio Favalli <elvenprogrammer@gmail.com> @@ -1792,4 +1799,4 @@ restore some doxygen comments, improved size adaption and made the window a shorter. * data/graphics/images/login_wallpaper.png: New login wallpaper by - Momotaro.
\ No newline at end of file + Momotaro. diff --git a/src/being.cpp b/src/being.cpp index 9a0e6d2f..2fb13607 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -42,7 +42,7 @@ PATH_NODE::PATH_NODE(Uint16 iX, Uint16 iY): Being::Being(Uint32 id, Uint16 job, Map *map): job(job), - x(0), y(0), direction(SOUTH), + x(0), y(0), direction(DOWN), action(0), mFrame(0), speech_color(0), walk_time(0), @@ -163,20 +163,15 @@ Being::nextStep() PATH_NODE node = mPath.front(); mPath.pop_front(); - if (node.x > x) { - if (node.y > y) direction = SE; - else if (node.y < y) direction = NE; - else direction = EAST; - } - else if (node.x < x) { - if (node.y > y) direction = SW; - else if (node.y < y) direction = NW; - else direction = WEST; - } - else { - if (node.y > y) direction = SOUTH; - else if (node.y < y) direction = NORTH; - } + direction = 0; + if (node.x > x) + direction |= RIGHT; + else if (node.x < x) + direction |= LEFT; + if (node.y > y) + direction |= DOWN; + else if (node.y < y) + direction |= UP; x = node.x; y = node.y; @@ -323,7 +318,7 @@ int Being::getXOffset() const { // Only beings walking to the left or the right have an x offset - if (action != WALK || direction == NORTH || direction == SOUTH) { + if (action != WALK || !(direction & (LEFT | RIGHT))) { return 0; } @@ -335,8 +330,8 @@ Being::getXOffset() const offset = 0; } - // Going to the right? Invert the offset. - if (direction == WEST || direction == NW || direction == SW) { + // Going to the left? Invert the offset. + if (direction & LEFT) { offset = -offset; } @@ -347,7 +342,7 @@ int Being::getYOffset() const { // Only beings walking up or down have an y offset - if (action != WALK || direction == EAST || direction == WEST) { + if (action != WALK || !(direction & (UP | DOWN))) { return 0; } @@ -359,7 +354,8 @@ Being::getYOffset() const offset = 0; } - if (direction == NORTH || direction == NW || direction == NE) { + // Going up? Invert the offset. + if (direction & UP) { offset = -offset; } diff --git a/src/being.h b/src/being.h index 9b6596e5..45cfb15d 100644 --- a/src/being.h +++ b/src/being.h @@ -71,17 +71,13 @@ class Being : public Sprite DEAD = 15 }; - enum Direction { - DIR_NONE = -1, - SOUTH = 0, - SW = 1, - WEST = 2, - NW = 3, - NORTH = 4, - NE = 5, - EAST = 6, - SE = 7 - }; + /** + * Directions, to be used as bitmask values + */ + static const char DOWN = 1; + static const char LEFT = 2; + static const char UP = 4; + static const char RIGHT = 8; Uint16 job; /**< Job (player job, npc, monster, ) */ Uint16 x, y; /**< Tile coordinates */ diff --git a/src/game.cpp b/src/game.cpp index 9f28096a..c1c81c67 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -83,7 +83,6 @@ std::string map_path; bool done = false; volatile int tick_time; -volatile bool action_time = false; volatile int fps = 0, frame = 0; Engine *engine = NULL; Joystick *joystick; @@ -141,12 +140,10 @@ Uint32 nextTick(Uint32 interval, void *param) } /** - * Lets u only trigger an action every other second - * tmp. counts fps + * Updates fps. */ Uint32 nextSecond(Uint32 interval, void *param) { - action_time = true; fps = frame; frame = 0; return interval; @@ -483,19 +480,15 @@ void Game::handleInput() if (!item) { Uint16 x = player_node->x; Uint16 y = player_node->y; + if (player_node->direction & Being::UP) + y--; + if (player_node->direction & Being::DOWN) + y++; + if (player_node->direction & Being::LEFT) + x--; + if (player_node->direction & Being::RIGHT) + x++; - switch (player_node->direction) - { - case Being::NORTH: y--; break; - case Being::SOUTH: y++; break; - case Being::WEST: x--; break; - case Being::EAST: x++; break; - case Being::NW: x--; y--; break; - case Being::NE: x++; y--; break; - case Being::SW: x--; y++; break; - case Being::SE: x++; y++; break; - default: break; - } item = floorItemManager->findByCoordinates(x, y); } @@ -538,10 +531,6 @@ void Game::handleInput() { case SDLK_s: // Player sit action - if (!action_time) { - break; - } - player_node->toggleSit(); used = true; break; @@ -570,30 +559,26 @@ void Game::handleInput() } // Emotions - if (action_time && !player_node->emotion) + Uint8 emotion; + switch (event.key.keysym.sym) { - Uint8 emotion = 0; - switch (event.key.keysym.sym) - { - case SDLK_1: emotion = 1; break; - case SDLK_2: emotion = 2; break; - case SDLK_3: emotion = 3; break; - case SDLK_4: emotion = 4; break; - case SDLK_5: emotion = 5; break; - case SDLK_6: emotion = 6; break; - case SDLK_7: emotion = 7; break; - case SDLK_8: emotion = 8; break; - case SDLK_9: emotion = 9; break; - case SDLK_0: emotion = 10; break; - default: break; - } + case SDLK_1: emotion = 1; break; + case SDLK_2: emotion = 2; break; + case SDLK_3: emotion = 3; break; + case SDLK_4: emotion = 4; break; + case SDLK_5: emotion = 5; break; + case SDLK_6: emotion = 6; break; + case SDLK_7: emotion = 7; break; + case SDLK_8: emotion = 8; break; + case SDLK_9: emotion = 9; break; + case SDLK_0: emotion = 10; break; + default: emotion = 0; break; + } - if (emotion) - { - player_node->emote(emotion); - action_time = false; - used = true; - } + if (emotion) + { + player_node->emote(emotion); + used = true; } } } @@ -618,54 +603,32 @@ void Game::handleInput() { Uint16 x = player_node->x; Uint16 y = player_node->y; - Being::Direction Direction = Being::DIR_NONE; + unsigned char Direction = 0; // Translate pressed keys to movement and direction - if (keys[SDLK_UP] || keys[SDLK_KP8] || joystick && joystick->isUp()) - { - Direction = Being::NORTH; - } - if (keys[SDLK_DOWN] || keys[SDLK_KP2] || joystick && joystick->isDown()) + if (keys[SDLK_UP] || keys[SDLK_KP8] || + keys[SDLK_KP7] || keys[SDLK_KP9] || + joystick && joystick->isUp()) { - Direction = Being::SOUTH; + Direction |= Being::UP; } - if (keys[SDLK_LEFT] || keys[SDLK_KP4] || joystick && joystick->isLeft()) + else if (keys[SDLK_DOWN] || keys[SDLK_KP2] || + keys[SDLK_KP1] || keys[SDLK_KP3] || + joystick && joystick->isDown()) { - // Allow diagonal walking - // TODO: Make this nicer, once we got a bitfield for directions - if (Direction == Being::NORTH) - Direction = Being::NW; - else if (Direction == Being::SOUTH) - Direction = Being::SW; - else - Direction = Being::WEST; + Direction |= Being::DOWN; } - if (keys[SDLK_RIGHT] || keys[SDLK_KP6] || joystick && joystick->isRight()) + if (keys[SDLK_LEFT] || keys[SDLK_KP4] || + keys[SDLK_KP1] || keys[SDLK_KP7] || + joystick && joystick->isLeft()) { - // Allow diagonal walking - // TODO: Make this nicer, once we got a bitfield for directions - if (Direction == Being::NORTH) - Direction = Being::NE; - else if (Direction == Being::SOUTH) - Direction = Being::SE; - else - Direction = Being::EAST; + Direction |= Being::LEFT; } - if (keys[SDLK_KP1]) // Bottom Left + else if (keys[SDLK_RIGHT] || keys[SDLK_KP6] || + keys[SDLK_KP3] || keys[SDLK_KP9] || + joystick && joystick->isRight()) { - Direction = Being::SW; - } - if (keys[SDLK_KP3]) // Bottom Right - { - Direction = Being::SE; - } - if (keys[SDLK_KP7]) // Top Left - { - Direction = Being::NW; - } - if (keys[SDLK_KP9]) // Top Right - { - Direction = Being::NE; + Direction |= Being::RIGHT; } player_node->walk(Direction); @@ -682,24 +645,14 @@ void Game::handleInput() { Uint16 targetX = x, targetY = y; - switch (player_node->direction) - { - case Being::SOUTH: - targetY++; - break; - - case Being::WEST: - targetX--; - break; - - case Being::NORTH: - targetY--; - break; - - case Being::EAST: - targetX++; - break; - } + if (player_node->direction & Being::UP) + targetY--; + if (player_node->direction & Being::DOWN) + targetY++; + if (player_node->direction & Being::LEFT) + targetX--; + if (player_node->direction & Being::RIGHT) + targetX++; // Attack priorioty is: Monster, Player, auto target target = beingManager->findBeing( @@ -722,10 +675,9 @@ void Game::handleInput() if (item) player_node->pickUp(item); } - else if (joystick->buttonPressed(2) && action_time) + else if (joystick->buttonPressed(2)) { player_node->toggleSit(); - action_time = false; } } } diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 1b3178e1..43cf0069 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -41,7 +41,7 @@ LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): mInventory(new Inventory()), mEquipment(new Equipment()), mTarget(NULL), mPickUpTarget(NULL), - mTrading(false) + mTrading(false), mLastAction(-1) { } @@ -69,6 +69,11 @@ void LocalPlayer::logic() break; } + // Actions are allowed once per second + if (get_elapsed_time(mLastAction) >= 1000) { + mLastAction = -1; + } + Being::logic(); } @@ -161,9 +166,9 @@ void LocalPlayer::pickUp(FloorItem *item) } } -void LocalPlayer::walk(Being::Direction dir) +void LocalPlayer::walk(unsigned char dir) { - if (!mMap || dir == DIR_NONE) + if (!mMap || !dir) return; if (action == WALK) @@ -174,47 +179,14 @@ void LocalPlayer::walk(Being::Direction dir) } Sint16 dx = 0, dy = 0; - switch (dir) - { - case SOUTH: - dy = 1; - break; - - case WEST: - dx = -1; - break; - - case NORTH: - dy = -1; - break; - - case EAST: - dx = 1; - break; - - case SW: - dx = -1; - dy = 1; - break; - - case NW: - dx = -1; - dy = -1; - break; - - case NE: - dx = 1; - dy = -1; - break; - - case SE: - dx = 1; - dy = 1; - break; - - default: - break; - } + if (dir & UP) + dy--; + if (dir & DOWN) + dy++; + if (dir & LEFT) + dx--; + if (dir & RIGHT) + dx++; // Prevent skipping corners over colliding tiles if (dx && mMap->tileCollides(x + dx, y)) @@ -231,7 +203,7 @@ void LocalPlayer::walk(Being::Direction dir) { setDestination(x + dx, y + dy); } - else if (dir != DIR_NONE) + else if (dir) { // Update the player direction to where he wants to walk // Warning: Not communicated to the server yet @@ -298,6 +270,10 @@ void LocalPlayer::raiseSkill(Uint16 skillId) void LocalPlayer::toggleSit() { + if (mLastAction != -1) + return; + mLastAction = tick_time; + char type; switch (action) { @@ -314,6 +290,10 @@ void LocalPlayer::toggleSit() void LocalPlayer::emote(Uint8 emotion) { + if (mLastAction != -1) + return; + mLastAction = tick_time; + MessageOut outMsg(mNetwork); outMsg.writeInt16(0x00bf); outMsg.writeInt8(emotion); @@ -361,16 +341,16 @@ void LocalPlayer::attack(Being *target, bool keep) if (abs(dist_y) >= abs(dist_x)) { if (dist_y > 0) - direction = SOUTH; + direction = DOWN; else - direction = NORTH; + direction = UP; } else { if (dist_x > 0) - direction = EAST; + direction = RIGHT; else - direction = WEST; + direction = LEFT; } // Implement charging attacks here diff --git a/src/localplayer.h b/src/localplayer.h index 7867e13d..3107657c 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -104,7 +104,7 @@ class LocalPlayer : public Player void stopAttack(); Being* getTarget() const; - void walk(Being::Direction dir); + void walk(unsigned char dir); /** * Sets a new destination for this being to walk to. @@ -150,6 +150,7 @@ class LocalPlayer : public Player FloorItem *mPickUpTarget; bool mTrading; + int mLastAction; /**< Time stamp of the last action, -1 if none */ }; extern LocalPlayer *player_node; diff --git a/src/monster.cpp b/src/monster.cpp index f07f7447..299940c5 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -87,7 +87,10 @@ void Monster::draw(Graphics *graphics, int offsetX, int offsetY) mSpriteFrame += mFrame; } - mSpriteFrame = direction / 2 + 4 * mSpriteFrame; + unsigned char dir = 0; + while (!(direction & (1 << dir))) dir++; + + mSpriteFrame = dir + 4 * mSpriteFrame; Being::draw(graphics, offsetX - 12, offsetY - 25); } diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp index 9f2b38f7..9abe4a2d 100644 --- a/src/net/messagein.cpp +++ b/src/net/messagein.cpp @@ -87,6 +87,38 @@ MessageIn::readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction) direction = data[2] & 0x000f; + // Translate from eAthena format + switch (direction) + { + case 0: + direction = 1; + break; + case 1: + direction = 3; + break; + case 2: + direction = 2; + break; + case 3: + direction = 6; + break; + case 4: + direction = 4; + break; + case 5: + direction = 12; + break; + case 6: + direction = 8; + break; + case 7: + direction = 9; + break; + default: + // OOPSIE! Impossible or unknown + direction = 0; + } + mPos += 3; } diff --git a/src/net/protocol.cpp b/src/net/protocol.cpp index f31d4a39..d3db50bf 100644 --- a/src/net/protocol.cpp +++ b/src/net/protocol.cpp @@ -43,5 +43,37 @@ void set_coordinates(char *data, temp <<= 4; data[1] |= HIBYTE(temp); data[2] = LOBYTE(temp); + + // Translate direction to eAthena format + switch (direction) + { + case 1: + direction = 0; + break; + case 3: + direction = 1; + break; + case 2: + direction = 2; + break; + case 6: + direction = 3; + break; + case 4: + direction = 4; + break; + case 12: + direction = 5; + break; + case 8: + direction = 6; + break; + case 9: + direction = 7; + break; + default: + // OOPSIE! Impossible or unknown + direction = (unsigned char)-1; + } data[2] |= direction; } diff --git a/src/player.cpp b/src/player.cpp index 71bb6ca5..d6363242 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -85,7 +85,6 @@ Being::Type Player::getType() const void Player::draw(Graphics *graphics, int offsetX, int offsetY) { - unsigned char dir = direction / 2; int px = mPx + offsetX; int py = mPy + offsetY; int frame = action; @@ -102,6 +101,9 @@ void Player::draw(Graphics *graphics, int offsetX, int offsetY) frame += 4 * (getWeapon() - 1); } + unsigned char dir = 0; + while (!(direction & (1 << dir))) dir++; + graphics->drawImage(playerset->spriteset[frame + 16 * dir], px - 16, py - 32); |