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 "item.h"
#include "game.h"
#include "effect.h"
#include <framework/graphics/graphics.h>
#include <framework/core/eventdispatcher.h>
@ -84,46 +85,54 @@ void Creature::draw(const Point& p, const Rect&)
}
// 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.
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
continue;
// continue if we dont have this addon.
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
continue;
g_painter.setCustomProgram(outfitProgram);
g_painter.setCustomProgram(outfitProgram);
outfitProgram->bind();
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
outfitProgram->bind();
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) {
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);
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)
for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) {
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);
if(!spriteId)
continue;
TexturePtr maskTex = g_sprites.getSpriteTexture(maskId);
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
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;
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)
@ -260,10 +269,12 @@ void Creature::updateWalk()
m_walkOffset.x = -totalPixelsWalked;
}
if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] <= 1)
m_animation = 0;
else if(m_type->dimensions[ThingType::AnimationPhases] > 1)
m_animation = 1 + totalPixelsWalked * 4 / Map::NUM_TILE_PIXELS % (m_type->dimensions[ThingType::AnimationPhases] - 1);
if(m_outfit.getCategory() == ThingsType::Creature) {
if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] <= 1)
m_animation = 0;
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)
cancelWalk(m_turnDirection);
@ -275,7 +286,8 @@ void Creature::cancelWalk(Otc::Direction direction, bool)
{
m_walking = false;
m_walkStart = 0;
m_animation = 0;
if(m_outfit.getCategory() == ThingsType::Creature)
m_animation = 0;
m_walkOffset = Point(0, 0);
setDirection(direction);
}
@ -320,23 +332,44 @@ void Creature::setHealthPercent(uint8 healthPercent)
void Creature::setDirection(Otc::Direction direction)
{
if(direction == Otc::NorthEast || direction == Otc::SouthEast)
m_xPattern = Otc::East;
else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
m_xPattern = Otc::West;
else
m_xPattern = direction;
if(m_outfit.getCategory() == ThingsType::Creature) {
if(direction == Otc::NorthEast || direction == Otc::SouthEast)
m_xPattern = Otc::East;
else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
m_xPattern = Otc::West;
else
m_xPattern = direction;
}
else {
m_xPattern = 0;
}
m_direction = direction;
}
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_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();
}
}
void Creature::setSkull(uint8 skull)
@ -354,7 +387,6 @@ void Creature::setShield(uint8 shield)
void Creature::setEmblem(uint8 emblem)
{
m_emblem = emblem;
g_lua.callGlobalField("Creature","onEmblemChange", asCreature(), m_emblem);
}
@ -385,7 +417,26 @@ void Creature::addVolatileSquare(uint8 color)
}, 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()
{
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:
enum {
INVISIBLE_TICKS = 500,
VOLATILE_SQUARE_DURATION = 1000
};
@ -70,6 +71,9 @@ public:
uint8 getShield() { return m_shield; }
uint8 getEmblem() { return m_emblem; }
bool getPassable() { return m_passable; }
void updateAnimation();
ThingType *getType();
//virtual void walk(const Position& oldPos, const Position& newPos, bool inverse = true);

View File

@ -28,11 +28,11 @@
class Effect : public Thing
{
public:
enum {
TICKS_PER_FRAME = 75
};
public:
Effect();
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)
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++)
internalDraw(p, b);
for(int l = 0; l < m_type->dimensions[ThingType::Layers]; l++)
internalDraw(p, l);
}
void Item::setPos(const Position& position)

View File

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

View File

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

View File

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

View File

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

View File

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