invisible creatures
This commit is contained in:
parent
d6ff85754c
commit
ab4dc91d90
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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&);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
Outfit::Outfit()
|
Outfit::Outfit()
|
||||||
{
|
{
|
||||||
m_type = 128;
|
m_category = ThingsType::Creature;
|
||||||
|
m_id = 1;
|
||||||
resetClothes();
|
resetClothes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue