invisible creatures

This commit is contained in:
Henrique Santiago 2012-01-09 22:36:18 -02:00
parent d6ff85754c
commit ab4dc91d90
9 changed files with 128 additions and 60 deletions

View File

@ -27,6 +27,7 @@
#include "tile.h" #include "tile.h"
#include "item.h" #include "item.h"
#include "game.h" #include "game.h"
#include "effect.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/core/eventdispatcher.h> #include <framework/core/eventdispatcher.h>
@ -84,46 +85,54 @@ void Creature::draw(const Point& p, const Rect&)
} }
// Render creature // Render creature
for(m_yPattern = 0; m_yPattern < m_type->dimensions[ThingType::PatternY]; m_yPattern++) { if(m_outfit.getCategory() == ThingsType::Creature) {
for(m_yPattern = 0; m_yPattern < m_type->dimensions[ThingType::PatternY]; m_yPattern++) {
// continue if we dont have this addon. // continue if we dont have this addon.
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1)))) if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
continue; continue;
g_painter.setCustomProgram(outfitProgram); g_painter.setCustomProgram(outfitProgram);
outfitProgram->bind(); outfitProgram->bind();
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor()); outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor()); outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor()); outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor()); outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) { for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) {
for(int w = 0; w < m_type->dimensions[ThingType::Width]; w++) { for(int w = 0; w < m_type->dimensions[ThingType::Width]; w++) {
int spriteId = m_type->getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation); int spriteId = m_type->getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation);
if(!spriteId) if(!spriteId)
continue;
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
if(!spriteTex)
continue;
if(m_type->dimensions[ThingType::Layers] > 1) {
int maskId = m_type->getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation);
if(!maskId)
continue; continue;
TexturePtr maskTex = g_sprites.getSpriteTexture(maskId); TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1); if(!spriteTex)
continue;
if(m_type->dimensions[ThingType::Layers] > 1) {
int maskId = m_type->getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation);
if(!maskId)
continue;
TexturePtr maskTex = g_sprites.getSpriteTexture(maskId);
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
}
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);
} }
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);
} }
}
g_painter.releaseCustomProgram(); g_painter.releaseCustomProgram();
}
} }
else if(m_outfit.getCategory() == ThingsType::Item) {
for(int l = 0; l < m_type->dimensions[ThingType::Layers]; l++)
internalDraw(p + m_walkOffset, l);
}
else if(m_outfit.getCategory() == ThingsType::Effect)
internalDraw(p + m_walkOffset, 0);
} }
void Creature::drawInformation(int x, int y, bool useGray, const Rect& visibleRect) void Creature::drawInformation(int x, int y, bool useGray, const Rect& visibleRect)
@ -260,10 +269,12 @@ void Creature::updateWalk()
m_walkOffset.x = -totalPixelsWalked; m_walkOffset.x = -totalPixelsWalked;
} }
if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] <= 1) if(m_outfit.getCategory() == ThingsType::Creature) {
m_animation = 0; if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] <= 1)
else if(m_type->dimensions[ThingType::AnimationPhases] > 1) m_animation = 0;
m_animation = 1 + totalPixelsWalked * 4 / Map::NUM_TILE_PIXELS % (m_type->dimensions[ThingType::AnimationPhases] - 1); else if(m_type->dimensions[ThingType::AnimationPhases] > 1)
m_animation = 1 + totalPixelsWalked * 4 / Map::NUM_TILE_PIXELS % (m_type->dimensions[ThingType::AnimationPhases] - 1);
}
if(g_clock.ticks() > m_walkEnd) if(g_clock.ticks() > m_walkEnd)
cancelWalk(m_turnDirection); cancelWalk(m_turnDirection);
@ -275,7 +286,8 @@ void Creature::cancelWalk(Otc::Direction direction, bool)
{ {
m_walking = false; m_walking = false;
m_walkStart = 0; m_walkStart = 0;
m_animation = 0; if(m_outfit.getCategory() == ThingsType::Creature)
m_animation = 0;
m_walkOffset = Point(0, 0); m_walkOffset = Point(0, 0);
setDirection(direction); setDirection(direction);
} }
@ -320,23 +332,44 @@ void Creature::setHealthPercent(uint8 healthPercent)
void Creature::setDirection(Otc::Direction direction) void Creature::setDirection(Otc::Direction direction)
{ {
if(direction == Otc::NorthEast || direction == Otc::SouthEast) if(m_outfit.getCategory() == ThingsType::Creature) {
m_xPattern = Otc::East; if(direction == Otc::NorthEast || direction == Otc::SouthEast)
else if(direction == Otc::NorthWest || direction == Otc::SouthWest) m_xPattern = Otc::East;
m_xPattern = Otc::West; else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
else m_xPattern = Otc::West;
m_xPattern = direction; else
m_xPattern = direction;
}
else {
m_xPattern = 0;
}
m_direction = direction; m_direction = direction;
} }
void Creature::setOutfit(const Outfit& outfit) void Creature::setOutfit(const Outfit& outfit)
{ {
if(m_outfit.getCategory() != ThingsType::Effect && outfit.getCategory() == ThingsType::Effect) {
auto self = asCreature();
g_dispatcher.scheduleEvent([self]() {
self->updateAnimation();
}, INVISIBLE_TICKS);
m_xPattern = 0;
m_yPattern = 0;
}
if(m_outfit.getCategory() == ThingsType::Item) {
m_xPattern = 0;
m_yPattern = 0;
}
m_outfit = outfit; m_outfit = outfit;
m_type = getType(); m_type = getType();
if(m_type->dimensions[ThingType::Layers] == 1) if(m_outfit.getCategory() == ThingsType::Creature && m_type->dimensions[ThingType::Layers] == 1) {
m_animation = 0;
m_outfit.resetClothes(); m_outfit.resetClothes();
}
} }
void Creature::setSkull(uint8 skull) void Creature::setSkull(uint8 skull)
@ -354,7 +387,6 @@ void Creature::setShield(uint8 shield)
void Creature::setEmblem(uint8 emblem) void Creature::setEmblem(uint8 emblem)
{ {
m_emblem = emblem; m_emblem = emblem;
g_lua.callGlobalField("Creature","onEmblemChange", asCreature(), m_emblem); g_lua.callGlobalField("Creature","onEmblemChange", asCreature(), m_emblem);
} }
@ -385,7 +417,26 @@ void Creature::addVolatileSquare(uint8 color)
}, VOLATILE_SQUARE_DURATION); }, VOLATILE_SQUARE_DURATION);
} }
void Creature::updateAnimation()
{
if(m_animation == 1)
m_animation = 2;
else if(m_animation == 2)
m_animation = 3;
else if(m_animation == 3)
m_animation = 1;
else
m_animation = 1;
if(g_game.isOnline() && m_outfit.getCategory() == ThingsType::Effect) {
auto self = asCreature();
g_dispatcher.scheduleEvent([self]() {
self->updateAnimation();
}, INVISIBLE_TICKS);
}
}
ThingType *Creature::getType() ThingType *Creature::getType()
{ {
return g_thingsType.getThingType(m_outfit.getType(), ThingsType::Creature); return g_thingsType.getThingType(m_outfit.getId(), m_outfit.getCategory());
} }

View File

@ -31,6 +31,7 @@ class Creature : public Thing
{ {
public: public:
enum { enum {
INVISIBLE_TICKS = 500,
VOLATILE_SQUARE_DURATION = 1000 VOLATILE_SQUARE_DURATION = 1000
}; };
@ -70,6 +71,9 @@ public:
uint8 getShield() { return m_shield; } uint8 getShield() { return m_shield; }
uint8 getEmblem() { return m_emblem; } uint8 getEmblem() { return m_emblem; }
bool getPassable() { return m_passable; } bool getPassable() { return m_passable; }
void updateAnimation();
ThingType *getType(); ThingType *getType();
//virtual void walk(const Position& oldPos, const Position& newPos, bool inverse = true); //virtual void walk(const Position& oldPos, const Position& newPos, bool inverse = true);

View File

@ -28,11 +28,11 @@
class Effect : public Thing class Effect : public Thing
{ {
public:
enum { enum {
TICKS_PER_FRAME = 75 TICKS_PER_FRAME = 75
}; };
public:
Effect(); Effect();
void draw(const Point& p, const Rect&); void draw(const Point& p, const Rect&);

View File

@ -44,8 +44,8 @@ void Item::draw(const Point& p, const Rect&)
if(m_type->dimensions[ThingType::AnimationPhases] > 1) if(m_type->dimensions[ThingType::AnimationPhases] > 1)
m_animation = (g_clock.ticks() % (TICKS_PER_FRAME * m_type->dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME; m_animation = (g_clock.ticks() % (TICKS_PER_FRAME * m_type->dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME;
for(int b = 0; b < m_type->dimensions[ThingType::Layers]; b++) for(int l = 0; l < m_type->dimensions[ThingType::Layers]; l++)
internalDraw(p, b); internalDraw(p, l);
} }
void Item::setPos(const Position& position) void Item::setPos(const Position& position)

View File

@ -24,7 +24,8 @@
Outfit::Outfit() Outfit::Outfit()
{ {
m_type = 128; m_category = ThingsType::Creature;
m_id = 1;
resetClothes(); resetClothes();
} }

View File

@ -24,6 +24,7 @@
#define OUTFIT_H #define OUTFIT_H
#include <framework/math/color.h> #include <framework/math/color.h>
#include <otclient/core/thingstype.h>
class Outfit class Outfit
{ {
@ -37,21 +38,23 @@ public:
static Color getColor(int color); static Color getColor(int color);
void setType(int type) { m_type = type; } void setId(int id) { m_id = id; }
void setHead(int head) { m_head = head; m_headColor = getColor(head); } void setHead(int head) { m_head = head; m_headColor = getColor(head); }
void setBody(int body) { m_body = body; m_bodyColor = getColor(body); } void setBody(int body) { m_body = body; m_bodyColor = getColor(body); }
void setLegs(int legs) { m_legs = legs; m_legsColor = getColor(legs); } void setLegs(int legs) { m_legs = legs; m_legsColor = getColor(legs); }
void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); } void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); }
void setAddons(int addons) { m_addons = addons; } void setAddons(int addons) { m_addons = addons; }
void setCategory(ThingsType::Categories category) { m_category = category; }
void resetClothes(); void resetClothes();
int getType() const { return m_type; } int getId() const { return m_id; }
int getHead() const { return m_head; } int getHead() const { return m_head; }
int getBody() const { return m_body; } int getBody() const { return m_body; }
int getLegs() const { return m_legs; } int getLegs() const { return m_legs; }
int getFeet() const { return m_feet; } int getFeet() const { return m_feet; }
int getAddons() const { return m_addons; } int getAddons() const { return m_addons; }
ThingsType::Categories getCategory() const { return m_category; }
Color getHeadColor() { return m_headColor; } Color getHeadColor() { return m_headColor; }
Color getBodyColor() { return m_bodyColor; } Color getBodyColor() { return m_bodyColor; }
@ -59,7 +62,8 @@ public:
Color getFeetColor() { return m_feetColor; } Color getFeetColor() { return m_feetColor; }
private: private:
int m_type, m_head, m_body, m_legs, m_feet, m_addons; ThingsType::Categories m_category;
int m_id, m_head, m_body, m_legs, m_feet, m_addons;
Color m_headColor, m_bodyColor, m_legsColor, m_feetColor; Color m_headColor, m_bodyColor, m_legsColor, m_feetColor;
}; };

View File

@ -26,7 +26,7 @@
void push_luavalue(const Outfit& outfit) void push_luavalue(const Outfit& outfit)
{ {
g_lua.newTable(); g_lua.newTable();
g_lua.pushInteger(outfit.getType()); g_lua.pushInteger(outfit.getId());
g_lua.setField("type"); g_lua.setField("type");
g_lua.pushInteger(outfit.getAddons()); g_lua.pushInteger(outfit.getAddons());
g_lua.setField("addons"); g_lua.setField("addons");
@ -44,7 +44,7 @@ bool luavalue_cast(int index, Outfit& outfit)
{ {
if(g_lua.isTable(index)) { if(g_lua.isTable(index)) {
g_lua.getField("type", index); g_lua.getField("type", index);
outfit.setType(g_lua.popInteger()); outfit.setId(g_lua.popInteger());
g_lua.getField("addons", index); g_lua.getField("addons", index);
outfit.setAddons(g_lua.popInteger()); outfit.setAddons(g_lua.popInteger());
g_lua.getField("head", index); g_lua.getField("head", index);

View File

@ -996,15 +996,16 @@ Outfit ProtocolGame::internalGetOutfit(InputMessage& msg)
{ {
Outfit outfit; Outfit outfit;
uint16 type = msg.getU16(); uint16 id = msg.getU16();
if(type != 0) { if(id != 0) {
outfit.setCategory(ThingsType::Creature);
uint8 head = msg.getU8(); uint8 head = msg.getU8();
uint8 body = msg.getU8(); uint8 body = msg.getU8();
uint8 legs = msg.getU8(); uint8 legs = msg.getU8();
uint8 feet = msg.getU8(); uint8 feet = msg.getU8();
uint8 addons = msg.getU8(); uint8 addons = msg.getU8();
outfit.setType(type); outfit.setId(id);
outfit.setHead(head); outfit.setHead(head);
outfit.setBody(body); outfit.setBody(body);
outfit.setLegs(legs); outfit.setLegs(legs);
@ -1012,8 +1013,15 @@ Outfit ProtocolGame::internalGetOutfit(InputMessage& msg)
outfit.setAddons(addons); outfit.setAddons(addons);
} }
else { else {
uint16 type = msg.getU16(); uint16 id = msg.getU16();
outfit.setType(type); if(id == 0) {
outfit.setCategory(ThingsType::Effect);
outfit.setId(13);
}
else {
outfit.setCategory(ThingsType::Item);
outfit.setId(id);
}
} }
return outfit; return outfit;

View File

@ -537,7 +537,7 @@ void ProtocolGame::sendSetOutfit(const Outfit& outfit)
OutputMessage oMsg; OutputMessage oMsg;
oMsg.addU8(Proto::ClientSetOutfit); oMsg.addU8(Proto::ClientSetOutfit);
oMsg.addU16(outfit.getType()); oMsg.addU16(outfit.getId());
oMsg.addU8(outfit.getHead()); oMsg.addU8(outfit.getHead());
oMsg.addU8(outfit.getBody()); oMsg.addU8(outfit.getBody());
oMsg.addU8(outfit.getLegs()); oMsg.addU8(outfit.getLegs());