invisible creatures
This commit is contained in:
parent
d6ff85754c
commit
ab4dc91d90
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
|
||||
class Effect : public Thing
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
TICKS_PER_FRAME = 75
|
||||
};
|
||||
|
||||
public:
|
||||
Effect();
|
||||
|
||||
void draw(const Point& p, const Rect&);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
Outfit::Outfit()
|
||||
{
|
||||
m_type = 128;
|
||||
m_category = ThingsType::Creature;
|
||||
m_id = 1;
|
||||
resetClothes();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue