creatures walk and outift fixes

This commit is contained in:
Henrique Santiago 2011-12-28 09:00:09 -02:00
parent df0f2febe6
commit 5faa903e18
5 changed files with 108 additions and 126 deletions

View File

@ -26,6 +26,7 @@
#include "util/types.h"
#define DEG_TO_RAD (acos(-1)/180.0)
#define RAD_TO_DEC (180.0/acos(-1))
namespace Fw
{

View File

@ -90,38 +90,24 @@ void Creature::draw(const Point& p)
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
for(int yi = 0; yi < m_type->dimensions[ThingType::Height]; yi++) {
for(int xi = 0; xi < m_type->dimensions[ThingType::Width]; xi++) {
int sprIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
* m_type->dimensions[ThingType::PatternZ] + m_zPattern)
* m_type->dimensions[ThingType::PatternY] + m_yPattern)
* m_type->dimensions[ThingType::PatternX] + m_xPattern)
* m_type->dimensions[ThingType::Layers] + 0)
* m_type->dimensions[ThingType::Height] + yi)
* m_type->dimensions[ThingType::Width] + xi;
for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) {
for(int w = 0; w < m_type->dimensions[ThingType::Width]; w++) {
if(m_type->dimensions[ThingType::Layers] > 1) {
int maskIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
* m_type->dimensions[ThingType::PatternZ] + m_zPattern)
* m_type->dimensions[ThingType::PatternY] + m_yPattern)
* m_type->dimensions[ThingType::PatternX] + m_xPattern)
* m_type->dimensions[ThingType::Layers] + 1)
* m_type->dimensions[ThingType::Height] + yi)
* m_type->dimensions[ThingType::Width] + xi;
int spriteId = m_type->sprites[maskIndex];
if(!spriteId)
int maskId = m_type->getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation);
if(!maskId)
continue;
TexturePtr maskTex = g_sprites.getSpriteTexture(spriteId);
TexturePtr maskTex = g_sprites.getSpriteTexture(maskId);
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
}
int spriteId = m_type->sprites[sprIndex];
int spriteId = m_type->getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation);
if(!spriteId)
continue;
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
Rect drawRect(((p + m_walkOffset).x - xi*32) - m_type->parameters[ThingType::DisplacementX],
((p + m_walkOffset).y - yi*32) - m_type->parameters[ThingType::DisplacementY],
Rect drawRect(((p + m_walkOffset).x - w*32) - m_type->parameters[ThingType::DisplacementX],
((p + m_walkOffset).y - h*32) - m_type->parameters[ThingType::DisplacementY],
32, 32);
g_painter.drawTexturedRect(drawRect, spriteTex);
}
@ -162,127 +148,104 @@ void Creature::drawInformation(int x, int y, bool useGray, const Rect& rect)
g_painter.setColor(fillColor);
g_painter.drawFilledRect(healthRect);
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
if(m_informationFont)
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
}
void Creature::walk(const Position& position, bool inverse)
{
// set walking state
bool sameWalk = m_walking && !m_inverseWalking && inverse;
m_walking = true;
m_inverseWalking = inverse;
int walkTimeFactor = 1;
// set new direction
// We're walking
if(m_position.isInRange(position, 1, 1, 0)) {
Otc::Direction direction = m_position.getDirectionFromPosition(position);
setDirection(direction);
if(direction == Otc::NorthWest) {
m_walkOffset.x = 32;
m_walkOffset.y = 32;
walkTimeFactor = 2;
if(inverse) {
Position positionDelta = m_position - position;
m_walkOffset = Point(positionDelta.x * 32, positionDelta.y * 32);
}
else if(direction == Otc::North) {
m_walkOffset.y = 32;
}
else if(direction == Otc::NorthEast) {
m_walkOffset.x = -32;
m_walkOffset.y = 32;
walkTimeFactor = 2;
}
else if(direction == Otc::East) {
m_walkOffset.x = -32;
}
else if(direction == Otc::SouthEast) {
m_walkOffset.x = -32;
m_walkOffset.y = -32;
walkTimeFactor = 2;
}
else if(direction == Otc::South) {
m_walkOffset.y = -32;
}
else if(direction == Otc::SouthWest) {
m_walkOffset.x = 32;
m_walkOffset.y = -32;
walkTimeFactor = 2;
}
else if(direction == Otc::West) {
m_walkOffset.x = 32;
}
}
else { // Teleport
// we teleported, dont walk or change direction
m_walking = false;
m_walkOffset.x = 0;
m_walkOffset.y = 0;
m_animation = 0;
}
else
m_walkOffset = Point(0, 0);
if(!m_inverseWalking) {
m_walkOffset.x = 0;
m_walkOffset.y = 0;
}
// Diagonal walking lasts 3 times more.
int walkTimeFactor = 1;
if(direction == Otc::NorthWest || direction == Otc::NorthEast || direction == Otc::SouthWest || direction == Otc::SouthEast)
walkTimeFactor = 3;
if(m_walking) {
// get walk speed
// Get walking speed
int groundSpeed = 100;
ItemPtr ground = g_map.getTile(position)->getGround();
if(ground)
if(ItemPtr ground = g_map.getTile(position)->getGround())
groundSpeed = ground->getType()->parameters[ThingType::GroundSpeed];
float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed;
float walkTime = 1000.0 * (float)groundSpeed / m_speed;
walkTime = (walkTime == 0) ? 1000 : walkTime;
bool sameWalk = m_walking && !m_inverseWalking && inverse;
m_inverseWalking = inverse;
m_walking = true;
m_walkTimePerPixel = walkTime / 32.0;
if(!sameWalk)
m_walkStartTicks = g_clock.ticks();
m_walkStart = sameWalk ? m_walkStart : g_clock.ticks();
m_walkEnd = m_walkStart + walkTime * walkTimeFactor;
m_turnDirection = m_direction;
updateWalk();
}
// Teleport
else {
m_walking = false;
m_walkOffset = Point(0, 0);
m_animation = 0;
}
}
void Creature::turn(Otc::Direction direction)
{
if(!m_walking)
setDirection(direction);
else
m_turnDirection = direction;
}
void Creature::updateWalk()
{
if(m_walking) {
int elapsedTicks = g_clock.ticksElapsed(m_walkStartTicks);
int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32);
if(!m_walking)
return;
if(m_inverseWalking) {
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
m_walkOffset.y = 32 - totalPixelsWalked;
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
m_walkOffset.y = totalPixelsWalked - 32;
int elapsedTicks = g_clock.ticksElapsed(m_walkStart);
int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32);
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
m_walkOffset.x = totalPixelsWalked - 32;
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
m_walkOffset.x = 32 - totalPixelsWalked;
}
else {
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
m_walkOffset.y = -totalPixelsWalked;
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
m_walkOffset.y = totalPixelsWalked;
if(m_inverseWalking) {
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
m_walkOffset.y = 32 - totalPixelsWalked;
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
m_walkOffset.y = totalPixelsWalked - 32;
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
m_walkOffset.x = totalPixelsWalked;
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
m_walkOffset.x = -totalPixelsWalked;
}
int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5;
if(m_type->dimensions[ThingType::AnimationPhases] > 0)
m_animation = (g_clock.ticks() % totalWalkTileTicks) / (totalWalkTileTicks / (m_type->dimensions[ThingType::AnimationPhases] - 1)) + 1;
else
m_animation = 0;
if(totalPixelsWalked == 32)
cancelWalk(m_direction);
else
g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel);
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
m_walkOffset.x = totalPixelsWalked - 32;
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
m_walkOffset.x = 32 - totalPixelsWalked;
}
else {
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
m_walkOffset.y = -totalPixelsWalked;
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
m_walkOffset.y = totalPixelsWalked;
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
m_walkOffset.x = totalPixelsWalked;
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
m_walkOffset.x = -totalPixelsWalked;
}
if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] == 0)
m_animation = 0;
else if(m_type->dimensions[ThingType::AnimationPhases] > 0)
m_animation = 1 + totalPixelsWalked * 4 / Map::NUM_TILE_PIXELS % (m_type->dimensions[ThingType::AnimationPhases] - 1);
if(g_clock.ticks() > m_walkEnd)
cancelWalk(m_turnDirection);
else
g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel);
}
void Creature::cancelWalk(Otc::Direction direction)
@ -296,15 +259,15 @@ void Creature::cancelWalk(Otc::Direction direction)
}
m_walking = false;
m_walkStartTicks = 0;
m_walkOffset.x = 0;
m_walkOffset.y = 0;
m_direction = direction;
m_walkStart = 0;
m_walkOffset = Point(0, 0);
setDirection(direction);
}
void Creature::setName(const std::string& name)
{
m_nameSize = m_informationFont->calculateTextRectSize(name);
if(m_informationFont)
m_nameSize = m_informationFont->calculateTextRectSize(name);
m_name = name;
}
@ -355,6 +318,14 @@ void Creature::setOutfit(const Outfit& outfit)
{
m_outfit = outfit;
m_type = getType();
// Do not apply any mask color.
if(m_type->dimensions[ThingType::Layers] == 1) {
m_outfit.setHead(0);
m_outfit.setBody(0);
m_outfit.setLegs(0);
m_outfit.setFeet(0);
}
}
ThingType *Creature::getType()

View File

@ -61,6 +61,7 @@ public:
ThingType *getType();
virtual void walk(const Position& position, bool inverse = true);
void turn(Otc::Direction direction);
virtual void cancelWalk(Otc::Direction direction);
Point getWalkOffset() { return m_walkOffset; }
@ -88,10 +89,11 @@ protected:
FontPtr m_informationFont;
Color m_informationColor;
ticks_t m_walkStartTicks;
ticks_t m_walkStart, m_walkEnd;
bool m_walking, m_inverseWalking;
float m_walkTimePerPixel;
Point m_walkOffset;
Otc::Direction m_turnDirection;
};
#endif

View File

@ -408,9 +408,17 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
Position newPos = parsePosition(msg);
ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos);
assert(thing);
if(!thing) {
logError("could not get thing");
return;
}
CreaturePtr creature = thing->asCreature();
assert(creature);
if(!creature) {
logError("thing is not a creature");
return;
}
creature->walk(newPos);
// update map tiles
@ -642,7 +650,7 @@ void ProtocolGame::parseCreatureTurn(InputMessage& msg)
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setDirection(direction);
creature->turn(direction);
}
void ProtocolGame::parseItemTextWindow(InputMessage& msg)

View File

@ -74,7 +74,7 @@ public:
return Otc::East;
}
else {
float angle = std::atan2(positionDelta.y * -1, positionDelta.x) * DEG_TO_RAD;
float angle = std::atan2(positionDelta.y * -1, positionDelta.x) * RAD_TO_DEC;
if(angle < 0)
angle += 360;