summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Steinbrink <B.Steinbrink@gmx.de>2006-02-07 10:37:54 +0000
committerBjörn Steinbrink <B.Steinbrink@gmx.de>2006-02-07 10:37:54 +0000
commitac08acd4b4029a2519c81eecf938e1c03b51233c (patch)
tree78405d149cff52b310343a1e557062345b784d41 /src
parentc395103a0f190598e234b2c5f373d3fde25f77cf (diff)
downloadmana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.gz
mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.bz2
mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.tar.xz
mana-ac08acd4b4029a2519c81eecf938e1c03b51233c.zip
Made the being directions being stored in a bitfield.
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp36
-rw-r--r--src/being.h18
-rw-r--r--src/game.cpp154
-rw-r--r--src/localplayer.cpp78
-rw-r--r--src/localplayer.h3
-rw-r--r--src/monster.cpp5
-rw-r--r--src/net/messagein.cpp32
-rw-r--r--src/net/protocol.cpp32
-rw-r--r--src/player.cpp4
9 files changed, 178 insertions, 184 deletions
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);