outfits, item, creature, thing rework

This commit is contained in:
Henrique 2011-11-13 06:46:19 -02:00
parent ca702109d6
commit 5f34648c0e
11 changed files with 247 additions and 248 deletions

View File

@ -70,6 +70,7 @@ SET(SOURCES src/framework/ui/uiframecounter.cpp
src/otclient/core/effect.cpp
src/otclient/core/missile.cpp
src/otclient/core/localplayer.cpp
src/otclient/core/outfit.cpp
# otclient ui
src/otclient/ui/uiitem.cpp

View File

@ -334,147 +334,6 @@ namespace Otc
SpeakMonsterYell = 0x0E //Yell orange
};
static const Color OutfitColors[] = {
Color(255,255,255),
Color(255,212,191),
Color(255,233,191),
Color(255,255,191),
Color(233,255,191),
Color(212,255,191),
Color(191,255,191),
Color(191,255,212),
Color(191,255,233),
Color(191,255,255),
Color(191,233,255),
Color(191,212,255),
Color(191,191,255),
Color(212,191,255),
Color(233,191,255),
Color(255,191,255),
Color(255,191,233),
Color(255,191,212),
Color(255,191,191),
Color(128,128,128),
Color(191,159,143),
Color(191,175,143),
Color(191,191,143),
Color(175,191,143),
Color(159,191,143),
Color(143,191,143),
Color(143,191,159),
Color(143,191,175),
Color(143,191,191),
Color(143,175,191),
Color(143,159,191),
Color(143,143,191),
Color(159,143,191),
Color(175,143,191),
Color(191,143,191),
Color(191,143,175),
Color(191,143,159),
Color(191,143,143),
Color(182,182,182),
Color(191,127,95),
Color(191,159,95),
Color(191,191,95),
Color(159,191,95),
Color(127,191,95),
Color(95,191,95),
Color(95,191,127),
Color(95,191,159),
Color(95,191,191),
Color(95,159,191),
Color(95,127,191),
Color(95,95,191),
Color(127,95,191),
Color(159,95,191),
Color(191,95,191),
Color(191,95,159),
Color(191,95,127),
Color(191,95,95),
Color(145,145,145),
Color(191,106,63),
Color(191,148,63),
Color(191,191,63),
Color(148,191,63),
Color(107,191,63),
Color(63,191,63),
Color(63,191,106),
Color(63,191,148),
Color(63,191,191),
Color(63,148,191),
Color(63,106,191),
Color(63,63,191),
Color(106,63,191),
Color(148,63,191),
Color(191,63,191),
Color(191,63,148),
Color(191,63,106),
Color(191,63,63),
Color(109,109,109),
Color(255,85,0),
Color(255,170,0),
Color(255,255,0),
Color(170,255,0),
Color(84,255,0),
Color(0,255,0),
Color(0,255,84),
Color(0,255,170),
Color(0,255,255),
Color(0,169,255),
Color(0,85,255),
Color(0,0,255),
Color(85,0,255),
Color(169,0,255),
Color(254,0,255),
Color(255,0,170),
Color(255,0,85),
Color(255,0,0),
Color(72,72,72),
Color(191,63,0),
Color(191,127,0),
Color(191,191,0),
Color(127,191,0),
Color(63,191,0),
Color(0,191,0),
Color(0,191,63),
Color(0,191,127),
Color(0,191,191),
Color(0,127,191),
Color(0,63,191),
Color(0,0,191),
Color(63,0,191),
Color(127,0,191),
Color(191,0,191),
Color(191,0,127),
Color(191,0,63),
Color(191,0,0),
Color(36,36,36),
Color(127,42,0),
Color(127,85,0),
Color(127,127,0),
Color(85,127,0),
Color(42,127,0),
Color(0,127,0),
Color(0,127,42),
Color(0,127,85),
Color(0,127,127),
Color(0,84,127),
Color(0,42,127),
Color(0,0,127),
Color(42,0,127),
Color(84,0,127),
Color(127,0,127),
Color(191,0,85),
Color(127,0,42),
Color(127,0,0)
};
}
#endif

View File

@ -50,7 +50,7 @@ void Creature::draw(const Point& p)
for(m_yPattern = 0; m_yPattern < type.dimensions[ThingType::PatternY]; m_yPattern++) {
// continue if we dont have this addon.
if(m_yPattern > 0 && !(m_outfit.addons & (1 << (m_yPattern-1))))
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
continue;
// draw white item
@ -62,19 +62,19 @@ void Creature::draw(const Point& p)
g_graphics.bindBlendFunc(Fw::BlendColorzing);
// head
g_graphics.bindColor(Otc::OutfitColors[m_outfit.head]);
g_graphics.bindColor(m_outfit.getHead());
internalDraw(p + m_walkOffset, 1, Otc::SpriteYellowMask);
// body
g_graphics.bindColor(Otc::OutfitColors[m_outfit.body]);
g_graphics.bindColor(m_outfit.getBody());
internalDraw(p + m_walkOffset, 1, Otc::SpriteRedMask);
// legs
g_graphics.bindColor(Otc::OutfitColors[m_outfit.legs]);
g_graphics.bindColor(m_outfit.getLegs());
internalDraw(p + m_walkOffset, 1, Otc::SpriteGreenMask);
// feet
g_graphics.bindColor(Otc::OutfitColors[m_outfit.feet]);
g_graphics.bindColor(m_outfit.getFeet());
internalDraw(p + m_walkOffset, 1, Otc::SpriteBlueMask);
// restore default blend func
@ -95,8 +95,7 @@ void Creature::drawInformation(int x, int y, bool useGray, const Rect& rect)
Rect backgroundRect = Rect(x-(13.5), y, 27, 4);
backgroundRect.bound(rect);
Size textSize = m_informationFont->calculateTextRectSize(m_name);
Rect textRect = Rect(x - textSize.width() / 2.0, y-15, textSize);
Rect textRect = Rect(x - m_nameSize.width() / 2.0, y-15, m_nameSize);
textRect.bound(rect);
// distance them
@ -256,63 +255,59 @@ void Creature::cancelWalk(Otc::Direction direction)
}, m_walkTimePerPixel * 2);
}
void Creature::setName(const std::string& name)
{
m_nameSize = m_informationFont->calculateTextRectSize(name);
m_name = name;
}
void Creature::setHealthPercent(uint8 healthPercent)
{
int oldHealthPercent = m_healthPercent;
m_healthPercent = healthPercent;
onHealthPercentChange(oldHealthPercent);
}
void Creature::setDirection(Otc::Direction direction)
{
Otc::Direction oldDirection = m_direction;
m_direction = direction;
onDirectionChange(oldDirection);
}
const ThingType& Creature::getType()
{
return g_thingsType.getThingType(m_outfit.type, ThingsType::Creature);
}
void Creature::onHealthPercentChange(int)
{
m_informationColor = Fw::black;
if(m_healthPercent > 92) {
if(healthPercent > 92) {
m_informationColor.setGreen(188);
}
else if(m_healthPercent > 60) {
else if(healthPercent > 60) {
m_informationColor.setRed(80);
m_informationColor.setGreen(161);
m_informationColor.setBlue(80);
}
else if(m_healthPercent > 30) {
else if(healthPercent > 30) {
m_informationColor.setRed(161);
m_informationColor.setGreen(161);
}
else if(m_healthPercent > 8) {
else if(healthPercent > 8) {
m_informationColor.setRed(160);
m_informationColor.setGreen(39);
m_informationColor.setBlue(39);
}
else if(m_healthPercent > 3) {
else if(healthPercent > 3) {
m_informationColor.setRed(160);
}
else {
m_informationColor.setRed(79);
}
m_healthPercent = healthPercent;
}
void Creature::onDirectionChange(Otc::Direction)
void Creature::setDirection(Otc::Direction direction)
{
if(m_direction >= 4) {
if(m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
if(direction >= 4) {
if(direction == Otc::NorthEast || direction == Otc::SouthEast)
m_xPattern = Otc::East;
else if(m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
m_xPattern = Otc::West;
}
else {
m_xPattern = m_direction;
m_xPattern = direction;
}
m_direction = direction;
}
const ThingType& Creature::getType()
{
return g_thingsType.getThingType(m_outfit.getType(), ThingsType::Creature);
}

View File

@ -24,18 +24,9 @@
#define CREATURE_H
#include "thing.h"
#include "outfit.h"
#include <framework/graphics/fontmanager.h>
//TODO: create Outfit class and move to a separate file
struct Outfit {
uint16 type;
uint8 head;
uint8 body;
uint8 legs;
uint8 feet;
uint8 addons;
};
class Creature : public Thing
{
public:
@ -45,7 +36,7 @@ public:
virtual void draw(const Point& p);
void drawInformation(int x, int y, bool useGray, const Rect& rect);
void setName(const std::string& name) { m_name = name; }
void setName(const std::string& name);
void setHealthPercent(uint8 healthPercent);
void setDirection(Otc::Direction direction);
void setOutfit(const Outfit& outfit) { m_outfit = outfit; }
@ -68,9 +59,6 @@ public:
bool getImpassable() { return m_impassable; }
const ThingType& getType();
void onHealthPercentChange(int);
void onDirectionChange(Otc::Direction);
virtual void walk(const Position& position, bool inverse = true);
virtual void cancelWalk(Otc::Direction direction);
Point getWalkOffset() { return m_walkOffset; }
@ -83,6 +71,7 @@ protected:
void updateWalk();
std::string m_name;
Size m_nameSize;
uint8 m_healthPercent;
Otc::Direction m_direction;
Outfit m_outfit;

View File

@ -43,51 +43,41 @@ void Item::draw(const Point& p)
internalDraw(p, b);
}
void Item::setData(int count)
{
int oldData = m_data;
m_data = count;
onDataChange(oldData);
}
const ThingType& Item::getType()
{
return g_thingsType.getThingType(m_id, ThingsType::Item);
}
void Item::onPositionChange(const Position&)
void Item::setPosition(const Position& position)
{
const ThingType& type = getType();
if(type.properties[ThingType::NotMovable]) {
m_xPattern = m_position.x % type.dimensions[ThingType::PatternX];
m_yPattern = m_position.y % type.dimensions[ThingType::PatternY];
m_zPattern = m_position.z % type.dimensions[ThingType::PatternZ];
m_xPattern = position.x % type.dimensions[ThingType::PatternX];
m_yPattern = position.y % type.dimensions[ThingType::PatternY];
m_zPattern = position.z % type.dimensions[ThingType::PatternZ];
}
Thing::setPosition(position);
}
void Item::onDataChange(int)
void Item::setData(int data)
{
const ThingType& type = getType();
if(type.properties[ThingType::IsStackable] && type.dimensions[ThingType::PatternX] == 4 && type.dimensions[ThingType::PatternY] == 2) {
if(m_data < 5) {
m_xPattern = m_data-1;
if(data < 5) {
m_xPattern = data-1;
m_yPattern = 0;
}
else if(m_data < 10) {
else if(data < 10) {
m_xPattern = 0;
m_yPattern = 1;
}
else if(m_data < 25) {
else if(data < 25) {
m_xPattern = 1;
m_yPattern = 1;
}
else if(m_data < 50) {
else if(data < 50) {
m_xPattern = 2;
m_yPattern = 1;
}
else if(m_data <= 100) {
else if(data <= 100) {
m_xPattern = 3;
m_yPattern = 1;
}
@ -103,7 +93,7 @@ void Item::onDataChange(int)
else if(type.properties[ThingType::IsFluid] || type.properties[ThingType::IsFluidContainer]) {
int var = 0;
// TODO: find out what the heck does it mean
switch(m_data) {
switch(data) {
case 0:
var = 0;
break;
@ -166,4 +156,11 @@ void Item::onDataChange(int)
m_xPattern = (var & 3) % type.dimensions[ThingType::PatternX];
m_yPattern = (var >> 2) % type.dimensions[ThingType::PatternY];
}
m_data = data;
}
const ThingType& Item::getType()
{
return g_thingsType.getThingType(m_id, ThingsType::Item);
}

View File

@ -37,14 +37,12 @@ public:
void draw(const Point& p);
void setData(int count);
void setPosition(const Position &position);
void setData(int data);
int getData() { return m_data; }
const ThingType& getType();
void onPositionChange(const Position&);
void onDataChange(int);
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
private:

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "outfit.h"
Color Outfit::internalGetColor(int color)
{
if(color >= HSI_H_STEPS * HSI_SI_VALUES)
color = 0;
float loc1 = 0, loc2 = 0, loc3 = 0;
if(color % HSI_H_STEPS != 0) {
loc1 = color % HSI_H_STEPS * 1.0/18.0;
loc2 = 1;
loc3 = 1;
switch(int(color / HSI_H_STEPS)) {
case 0:
loc2 = 0.25;
loc3 = 1.00;
break;
case 1:
loc2 = 0.25;
loc3 = 0.75;
break;
case 2:
loc2 = 0.50;
loc3 = 0.75;
break;
case 3:
loc2 = 0.667;
loc3 = 0.75;
break;
case 4:
loc2 = 1.00;
loc3 = 1.00;
break;
case 5:
loc2 = 1.00;
loc3 = 0.75;
break;
case 6:
loc2 = 1.00;
loc3 = 0.50;
break;
}
}
else {
loc1 = 0;
loc2 = 0;
loc3 = 1 - (float)color / HSI_H_STEPS / (float)HSI_SI_VALUES;
}
if(loc3 == 0)
return Color(0, 0, 0);
if (loc2 == 0) {
int loc7 = int(loc3 * 255);
return Color(loc7, loc7, loc7);
}
float loc4 = 0, loc5 = 0, loc6 = 0;
if(loc1 < 1.0/6.0) {
loc4 = loc3;
loc6 = loc3 * (1 - loc2);
loc5 = loc6 + (loc3 - loc6) * 6 * loc1;
}
else if (loc1 < 2.0/6.0) {
loc5 = loc3;
loc6 = loc3 * (1 - loc2);
loc4 = loc5 - (loc3 - loc6) * (6 * loc1 - 1);
}
else if(loc1 < 3.0/6.0) {
loc5 = loc3;
loc4 = loc3 * (1 - loc2);
loc6 = loc4 + (loc3 - loc4) * (6 * loc1 - 2);
}
else if (loc1 < 4.0/6.0) {
loc6 = loc3;
loc4 = loc3 * (1 - loc2);
loc5 = loc6 - (loc3 - loc4) * (6 * loc1 - 3);
}
else if (loc1 < 5.0/6.0) {
loc6 = loc3;
loc5 = loc3 * (1 - loc2);
loc4 = loc5 + (loc3 - loc5) * (6 * loc1 - 4);
}
else {
loc4 = loc3;
loc5 = loc3 * (1 - loc2);
loc6 = loc4 - (loc3 - loc5) * (6 * loc1 - 5);
}
return Color(int(loc4 * 255), int(loc5 * 255), int(loc6 * 255));
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef OUTFIT_H
#define OUTFIT_H
#include <framework/util/color.h>
class Outfit
{
enum {
HSI_SI_VALUES = 7,
HSI_H_STEPS = 19
};
public:
void setType(int type) { m_type = type; }
void setHead(int head) { m_head = internalGetColor(head); }
void setBody(int body) { m_body = internalGetColor(body); }
void setLegs(int legs) { m_legs = internalGetColor(legs); }
void setFeet(int feet) { m_feet = internalGetColor(feet); }
void setAddons(int addons) { m_addons = addons; }
int getType() { return m_type; }
Color getHead() { return m_head; }
Color getBody() { return m_body; }
Color getLegs() { return m_legs; }
Color getFeet() { return m_feet; }
int getAddons() { return m_addons; }
private:
Color internalGetColor(int color);
int m_type, m_addons;
Color m_head, m_body, m_legs, m_feet;
};
#endif

View File

@ -32,22 +32,6 @@ Thing::Thing() : m_id(0)
m_animation = 0;
}
void Thing::setId(uint32 id)
{
int oldId = m_id;
m_id = id;
onIdChange(oldId);
}
void Thing::setPosition(const Position& position)
{
Position oldPosition = m_position;
m_position = position;
onPositionChange(oldPosition);
}
void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
{
const ThingType& type = getType();

View File

@ -41,8 +41,8 @@ public:
virtual void draw(const Point& p) = 0;
void setId(uint32 id);
void setPosition(const Position& position);
void setId(uint32 id) { m_id = id; }
virtual void setPosition(const Position& position) { m_position = position; }
uint32 getId() const { return m_id; }
Position getPosition() const { return m_position; }
@ -50,9 +50,6 @@ public:
virtual const ThingType& getType() = 0;
int getAnimationPhases() { return getType().dimensions[ThingType::AnimationPhases]; }
virtual void onIdChange(int) {}
virtual void onPositionChange(const Position&) {}
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; }
virtual CreaturePtr asCreature() { return nullptr; }

View File

@ -959,16 +959,24 @@ Outfit ProtocolGame::internalGetOutfit(InputMessage& msg)
{
Outfit outfit;
outfit.type = msg.getU16(); // looktype
if(outfit.type != 0) {
outfit.head = msg.getU8();
outfit.body = msg.getU8();
outfit.legs = msg.getU8();
outfit.feet = msg.getU8();
outfit.addons = msg.getU8();
uint16 type = msg.getU16();
if(type != 0) {
uint8 head = msg.getU8();
uint8 body = msg.getU8();
uint8 legs = msg.getU8();
uint8 feet = msg.getU8();
uint8 addons = msg.getU8();
outfit.setType(type);
outfit.setHead(head);
outfit.setBody(body);
outfit.setLegs(legs);
outfit.setFeet(feet);
outfit.setAddons(addons);
}
else {
outfit.type = msg.getU16();
uint16 type = msg.getU16();
outfit.setType(type);
}
return outfit;