thingstype rework

This commit is contained in:
Henrique 2011-11-12 04:24:32 -02:00
parent 56f7ed3dd1
commit 0fa61333fa
13 changed files with 196 additions and 327 deletions

View File

@ -47,7 +47,7 @@ void Creature::draw(const Point& p)
const ThingType& type = getType(); const ThingType& type = getType();
// Render creature // Render creature
for(m_yPattern = 0; m_yPattern < type.yPattern; m_yPattern++) { for(m_yPattern = 0; m_yPattern < 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.addons & (1 << (m_yPattern-1)))) if(m_yPattern > 0 && !(m_outfit.addons & (1 << (m_yPattern-1))))
@ -57,7 +57,7 @@ void Creature::draw(const Point& p)
internalDraw(p + m_walkOffset, 0); internalDraw(p + m_walkOffset, 0);
// draw mask if exists // draw mask if exists
if(type.layers > 1) { if(type.dimensions[ThingType::Layers] > 1) {
// switch to blend color mode // switch to blend color mode
g_graphics.bindBlendFunc(Fw::BlendColorzing); g_graphics.bindBlendFunc(Fw::BlendColorzing);
@ -187,7 +187,7 @@ void Creature::walk(const Position& position, bool inverse)
ItemPtr ground = g_map.getTile(position)->getGround(); ItemPtr ground = g_map.getTile(position)->getGround();
if(ground) if(ground)
groundSpeed = ground->getType().groundSpeed; groundSpeed = ground->getType().parameters[ThingType::GroundSpeed];
float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed; float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed;
walkTime = (walkTime == 0) ? 1000 : walkTime; walkTime = (walkTime == 0) ? 1000 : walkTime;
@ -233,7 +233,7 @@ void Creature::updateWalk()
} }
int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5; int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5;
m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.animationPhases - 1)) + 1; m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1;
g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel); g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel);
if(totalPixelsWalked == 32) if(totalPixelsWalked == 32)
@ -272,7 +272,7 @@ void Creature::setDirection(Otc::Direction direction)
const ThingType& Creature::getType() const ThingType& Creature::getType()
{ {
return g_thingsType.getCreatureType(m_outfit.type); return g_thingsType.getThingType(m_outfit.type, ThingsType::Creature);
} }
void Creature::onHealthPercentChange(int) void Creature::onHealthPercentChange(int)

View File

@ -55,5 +55,5 @@ void Effect::startAnimation()
const ThingType& Effect::getType() const ThingType& Effect::getType()
{ {
return g_thingsType.getEffectType(m_id); return g_thingsType.getThingType(m_id, ThingsType::Effect);
} }

View File

@ -34,12 +34,12 @@ Item::Item() : Thing()
void Item::draw(const Point& p) void Item::draw(const Point& p)
{ {
const ThingType& type = g_thingsType.getItemType(m_id); const ThingType& type = getType();
if(type.animationPhases > 1) if(type.dimensions[ThingType::AnimationPhases] > 1)
m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.animationPhases)) / TICKS_PER_FRAME; m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME;
for(int b = 0; b < type.layers; b++) for(int b = 0; b < type.dimensions[ThingType::Layers]; b++)
internalDraw(p, b); internalDraw(p, b);
} }
@ -52,25 +52,25 @@ void Item::setData(int count)
const ThingType& Item::getType() const ThingType& Item::getType()
{ {
return g_thingsType.getItemType(m_id); return g_thingsType.getThingType(m_id, ThingsType::Item);
} }
void Item::onPositionChange(const Position&) void Item::onPositionChange(const Position&)
{ {
const ThingType& type = g_thingsType.getItemType(m_id); const ThingType& type = getType();
if(type.isNotMoveable) { if(type.properties[ThingType::NotMovable]) {
m_xPattern = m_position.x % type.xPattern; m_xPattern = m_position.x % type.dimensions[ThingType::PatternX];
m_yPattern = m_position.y % type.yPattern; m_yPattern = m_position.y % type.dimensions[ThingType::PatternY];
m_zPattern = m_position.z % type.zPattern; m_zPattern = m_position.z % type.dimensions[ThingType::PatternZ];
} }
} }
void Item::onDataChange(int) void Item::onDataChange(int)
{ {
const ThingType& type = g_thingsType.getItemType(m_id); const ThingType& type = getType();
if(type.isStackable && type.xPattern == 4 && type.yPattern == 2) { if(type.properties[ThingType::IsStackable] && type.dimensions[ThingType::PatternX] == 4 && type.dimensions[ThingType::PatternY] == 2) {
if(m_data < 5) { if(m_data < 5) {
m_xPattern = m_data-1; m_xPattern = m_data-1;
m_yPattern = 0; m_yPattern = 0;
@ -92,15 +92,15 @@ void Item::onDataChange(int)
m_yPattern = 1; m_yPattern = 1;
} }
} }
else if(type.isHangable) { else if(type.properties[ThingType::IsHangable]) {
if(type.isHookSouth) { if(type.properties[ThingType::HookSouth]) {
m_xPattern = type.xPattern >= 2 ? 1 : 0; m_xPattern = type.dimensions[ThingType::PatternX] >= 2 ? 1 : 0;
} }
else if(type.isHookEast) { else if(type.properties[ThingType::HookEast]) {
m_xPattern = type.xPattern >= 3 ? 2 : 0; m_xPattern = type.dimensions[ThingType::PatternX] >= 3 ? 2 : 0;
} }
} }
else if(type.isSplash || type.isFluidContainer) { else if(type.properties[ThingType::IsFluid] || type.properties[ThingType::IsFluidContainer]) {
int var = 0; int var = 0;
// TODO: find out what the heck does it mean // TODO: find out what the heck does it mean
switch(m_data) { switch(m_data) {
@ -163,7 +163,7 @@ void Item::onDataChange(int)
break; break;
} }
m_xPattern = (var & 3) % type.xPattern; m_xPattern = (var & 3) % type.dimensions[ThingType::PatternX];
m_yPattern = (var >> 2) % type.yPattern; m_yPattern = (var >> 2) % type.dimensions[ThingType::PatternY];
} }
} }

View File

@ -129,7 +129,7 @@ int Map::getFirstVisibleFloor()
if(TilePtr tile = m_tiles[upperPos]) { if(TilePtr tile = m_tiles[upperPos]) {
if(ThingPtr firstThing = tile->getThing(0)) { if(ThingPtr firstThing = tile->getThing(0)) {
const ThingType type = firstThing->getType(); const ThingType type = firstThing->getType();
if((type.isGround || type.isOnBottom) && !type.isDontHide) { if((type.properties[ThingType::IsGround] || type.properties[ThingType::IsOnBottom]) && !type.properties[ThingType::DontHide]) {
firstFloor = upperPos.z + 1; firstFloor = upperPos.z + 1;
break; break;
} }
@ -138,7 +138,7 @@ int Map::getFirstVisibleFloor()
if(TilePtr tile = m_tiles[perspectivePos]) { if(TilePtr tile = m_tiles[perspectivePos]) {
if(ThingPtr firstThing = tile->getThing(0)) { if(ThingPtr firstThing = tile->getThing(0)) {
const ThingType type = firstThing->getType(); const ThingType type = firstThing->getType();
if((type.isGround || type.isOnBottom) && !type.isDontHide) { if((type.properties[ThingType::IsGround] || type.properties[ThingType::IsOnBottom]) && !type.properties[ThingType::DontHide]) {
firstFloor = perspectivePos.z + 1; firstFloor = perspectivePos.z + 1;
break; break;
} }

View File

@ -119,5 +119,5 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition)
const ThingType& Missile::getType() const ThingType& Missile::getType()
{ {
return g_thingsType.getShotType(m_id); return g_thingsType.getThingType(m_id, ThingsType::Missile);
} }

View File

@ -52,15 +52,15 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
{ {
const ThingType& type = getType(); const ThingType& type = getType();
for(int yi = 0; yi < type.height; yi++) { for(int yi = 0; yi < type.dimensions[ThingType::Height]; yi++) {
for(int xi = 0; xi < type.width; xi++) { for(int xi = 0; xi < type.dimensions[ThingType::Width]; xi++) {
int sprIndex = ((((((m_animation % type.animationPhases) int sprIndex = ((((((m_animation % type.dimensions[ThingType::AnimationPhases])
* type.zPattern + m_zPattern) * type.dimensions[ThingType::PatternZ] + m_zPattern)
* type.yPattern + m_yPattern) * type.dimensions[ThingType::PatternY] + m_yPattern)
* type.xPattern + m_xPattern) * type.dimensions[ThingType::PatternX] + m_xPattern)
* type.layers + layers) * type.dimensions[ThingType::Layers] + layers)
* type.height + yi) * type.dimensions[ThingType::Height] + yi)
* type.width + xi; * type.dimensions[ThingType::Width] + xi;
int spriteId = type.sprites[sprIndex]; int spriteId = type.sprites[sprIndex];
if(!spriteId) if(!spriteId)
@ -68,8 +68,8 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask); TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask);
Rect drawRect((p.x - xi*32) - type.xDisplacement, Rect drawRect((p.x - xi*32) - type.parameters[ThingType::DisplacementX],
(p.y - yi*32) - type.yDisplacement, (p.y - yi*32) - type.parameters[ThingType::DisplacementY],
32, 32); 32, 32);
g_graphics.drawTexturedRect(drawRect, spriteTex); g_graphics.drawTexturedRect(drawRect, spriteTex);
} }
@ -79,13 +79,13 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
int Thing::getStackPriority() int Thing::getStackPriority()
{ {
const ThingType& type = getType(); const ThingType& type = getType();
if(type.isGround) if(type.properties[ThingType::IsGround])
return 0; return 0;
else if(type.isGroundClip) else if(type.properties[ThingType::IsGroundBorder])
return 1; return 1;
else if(type.isOnBottom) else if(type.properties[ThingType::IsOnBottom])
return 2; return 2;
else if(type.isOnTop) else if(type.properties[ThingType::IsOnTop])
return 3; return 3;
else if(asCreature()) else if(asCreature())
return 4; return 4;

View File

@ -48,7 +48,7 @@ public:
Position getPosition() const { return m_position; } Position getPosition() const { return m_position; }
int getStackPriority(); int getStackPriority();
virtual const ThingType& getType() = 0; virtual const ThingType& getType() = 0;
int getAnimationPhases() { return getType().animationPhases; } int getAnimationPhases() { return getType().dimensions[ThingType::AnimationPhases]; }
virtual void onIdChange(int) {} virtual void onIdChange(int) {}
virtual void onPositionChange(const Position&) {} virtual void onPositionChange(const Position&) {}

View File

@ -34,26 +34,18 @@ bool ThingsType::load(const std::string& file)
g_resources.loadFile(file, fin); g_resources.loadFile(file, fin);
m_signature = Fw::getU32(fin); m_signature = Fw::getU32(fin);
int numItems = Fw::getU16(fin);
int numCreatures = Fw::getU16(fin);
int numEffects = Fw::getU16(fin);
int numShots = Fw::getU16(fin);
m_itemsType.resize(numItems-100); int numThings[LastCategory];
for(int id = 100; id < numItems; ++id) for(int i = 0; i < LastCategory; ++i)
parseThingType(fin, m_itemsType[id - 100]); numThings[i] = Fw::getU16(fin);
m_creaturesType.resize(numCreatures); numThings[Item] -= 100;
for(int id = 0; id < numCreatures; ++id)
parseThingType(fin, m_creaturesType[id]);
m_effectsType.resize(numEffects); for(int i = 0; i < LastCategory; ++i) {
for(int id = 0; id < numEffects; ++id) m_things[i].resize(numThings[i]);
parseThingType(fin, m_effectsType[id]); for(int id = 0; id < numThings[i]; ++id)
parseThingType(fin, m_things[i][id]);
m_shotsType.resize(numShots); }
for(int id = 0; id < numShots; ++id)
parseThingType(fin, m_shotsType[id]);
return true; return true;
} catch(std::exception& e) { } catch(std::exception& e) {
@ -64,162 +56,67 @@ bool ThingsType::load(const std::string& file)
void ThingsType::unload() void ThingsType::unload()
{ {
m_itemsType.clear(); for(int i = 0; i < LastCategory; ++i)
m_creaturesType.clear(); m_things[i].clear();
m_effectsType.clear();
m_shotsType.clear();
} }
void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType) void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
{ {
assert(fin.good()); assert(fin.good());
bool done = false; while(true) {
while(!done) { int property = Fw::getU8(fin);
uint8 opt = Fw::getU8(fin); if(property == ThingType::LastPropertyValue)
break;
switch(opt) { thingType.properties[property] = true;
case Otc::DatGround: // Grounds, must be drawn first
thingType.groundSpeed = Fw::getU16(fin); if(property == ThingType::IsGround)
thingType.isGround = true; thingType.parameters[ThingType::GroundSpeed] = Fw::getU16(fin);
break; else if(property == ThingType::IsWritable || property == ThingType::IsWritableOnce)
case Otc::DatGroundClip: // Objects that clips (has transparent pixels) and must be drawn just after ground (e.g: ground borders) thingType.parameters[ThingType::MaxTextLenght] = Fw::getU16(fin);
thingType.isGroundClip = true; else if(property == ThingType::HasLight) {
break; thingType.parameters[ThingType::LightLevel] = Fw::getU16(fin);
case Otc::DatOnBottom: // Bottom items, must be drawn above general items and below creatures (e.g: stairs) thingType.parameters[ThingType::LightColor] = Fw::getU16(fin);
thingType.isOnBottom = true;
break;
case Otc::DatOnTop: // Top items, must be drawn above creatures (e.g: doors)
thingType.isOnTop = true;
break;
case Otc::DatContainer: // Containers
thingType.isContainer = true;
break;
case Otc::DatStackable: // Stackable
thingType.isStackable = true;
break;
case Otc::DatForceUse: // Items that are automatically used when step over?
thingType.isForceUse = true;
break;
case Otc::DatMultiUse: // Usable items
thingType.isMultiUse = true;
break;
case Otc::DatWritable: // Writable
thingType.isWritable = true;
thingType.maxTextLength = Fw::getU16(fin);
break;
case Otc::DatWritableOnce: // Writable once. objects that can't be edited by players
thingType.isWritableOnce = true;
thingType.maxTextLength = Fw::getU16(fin);
break;
case Otc::DatFluidContainer: // Fluid containers
thingType.isFluidContainer = true;
break;
case Otc::DatSplash: // Splashes
thingType.isSplash = true;
break;
case Otc::DatBlockWalk: // Blocks solid objects (creatures, walls etc)
thingType.isNotWalkable = true;
break;
case Otc::DatNotMovable: // Not movable
thingType.isNotMoveable = true;
break;
case Otc::DatBlockProjectile: // Blocks missiles (walls, magic wall etc)
thingType.isUnsight = true;
break;
case Otc::DatBlockPathFind: // Blocks pathfind algorithms (monsters)
thingType.isNotPathable = true;
break;
case Otc::DatPickupable: // Pickupable
thingType.isPickupable = true;
break;
case Otc::DatHangable: // Hangable objects (wallpaper etc)
thingType.isHangable = true;
break;
case Otc::DatHookSouth: // Horizontal walls
thingType.isHookSouth = true;
break;
case Otc::DatHookEast: // Vertical walls
thingType.isHookEast = true;
break;
case Otc::DatRotable: // Rotable
thingType.isRotable = true;
break;
case Otc::DatLight: // Light info
thingType.hasLight = true;
thingType.lightLevel = Fw::getU16(fin);
thingType.lightColor = Fw::getU16(fin);
break;
case Otc::DatDontHide: // A few monuments that are not supposed to be hidden by floors
thingType.isDontHide = true;
break;
case Otc::DatTranslucent: // Grounds that are translucent
thingType.isTranslucent = true;
break;
case Otc::DatDisplacement: // Must shift draw
thingType.xDisplacement = Fw::getU16(fin);
thingType.yDisplacement = Fw::getU16(fin);
break;
case Otc::DatElevation: // Must elevate draw
thingType.elevation = Fw::getU16(fin);
break;
case Otc::DatLyingCorpse: // Some corpses
thingType.isLyingCorpse = true;
break;
case Otc::DatAnimateAlways: // Unknown, check if firesword is a kind of AnimateAlways.
thingType.isAnimatedAlways = true;
break;
case Otc::DatMinimapColor: // Minimap color
thingType.hasMiniMapColor = true;
thingType.miniMapColor = Fw::getU16(fin);
break;
case Otc::DatLensHelp: // Used for giving players tips?
thingType.isLensHelp = true;
thingType.lensHelp = Fw::getU16(fin);
break;
case Otc::DatFullGround: // Grounds that has no transparent pixels
thingType.isFullGround = true;
break;
case Otc::DatIgnoreLook: // Ignore look, then looks at the item on the bottom of it
thingType.isIgnoreLook = true;
break;
case Otc::DatCloth: // Clothes
thingType.isCloth = true;
thingType.clothSlot = Fw::getU16(fin);
break;
case Otc::DatLastOpt:
done = true;
break;
default:
throw std::runtime_error(Fw::mkstr("unknown .dat byte code: ", (int)opt));
} }
else if(property == ThingType::HasDisplacement) {
thingType.parameters[ThingType::DisplacementX] = Fw::getU16(fin);
thingType.parameters[ThingType::DisplacementY] = Fw::getU16(fin);
}
else if(property == ThingType::HasElevation)
thingType.parameters[ThingType::Elevation] = Fw::getU16(fin);
else if(property == ThingType::MiniMap)
thingType.parameters[ThingType::MiniMapColor] = Fw::getU16(fin);
else if(property == ThingType::LensHelp)
thingType.parameters[ThingType::LensHelpParameter] = Fw::getU16(fin);
else if(property == ThingType::Cloth)
thingType.parameters[ThingType::ClothSlot] = Fw::getU16(fin);
} }
thingType.width = Fw::getU8(fin); int totalSprites = 1;
thingType.height = Fw::getU8(fin); for(int i = 0; i < ThingType::LastDimension; ++i) {
if(i == ThingType::ExactSize && thingType.dimensions[ThingType::Width] <= 1 && thingType.dimensions[ThingType::Height] <= 1) {
thingType.dimensions[i] = 32;
continue;
}
if(thingType.width > 1 || thingType.height > 1) thingType.dimensions[i] = Fw::getU8(fin);
thingType.exactSize = Fw::getU8(fin);
else
thingType.exactSize = 32;
thingType.layers = Fw::getU8(fin); if(i != ThingType::ExactSize)
thingType.xPattern = Fw::getU8(fin); totalSprites *= thingType.dimensions[i];
thingType.yPattern = Fw::getU8(fin); }
thingType.zPattern = Fw::getU8(fin);
thingType.animationPhases = Fw::getU8(fin);
if(thingType.animationPhases > 1)
thingType.isAnimation = true;
int totalSprites = thingType.width
* thingType.height
* thingType.layers
* thingType.xPattern
* thingType.yPattern
* thingType.zPattern
* thingType.animationPhases;
thingType.sprites.resize(totalSprites); thingType.sprites.resize(totalSprites);
for(uint16 i = 0; i < totalSprites; i++) for(int i = 0; i < totalSprites; i++)
thingType.sprites[i] = Fw::getU16(fin); thingType.sprites[i] = Fw::getU16(fin);
} }
ThingType& ThingsType::getThingType(uint16 id, Categories category)
{
if(category == Item)
id -= 100;
assert(id < m_things[category].size());
return m_things[category][id];
}

View File

@ -29,25 +29,28 @@
class ThingsType class ThingsType
{ {
public: public:
enum Categories {
Item = 0,
Creature,
Effect,
Missile,
LastCategory
};
bool load(const std::string& file); bool load(const std::string& file);
void unload(); void unload();
void parseThingType(std::stringstream& fin, ThingType& thingType); void parseThingType(std::stringstream& fin, ThingType& thingType);
ThingType& getItemType(uint16 id) { return m_itemsType[id - 100]; } ThingType& getThingType(uint16 id, Categories category);
ThingType& getCreatureType(uint16 id) { return m_creaturesType[id]; }
ThingType& getEffectType(uint16 id) { return m_effectsType[id]; }
ThingType& getShotType(uint16 id) { return m_shotsType[id]; }
uint32 getSignature() { return m_signature; } uint32 getSignature() { return m_signature; }
private: private:
uint32 m_signature; uint32 m_signature;
ThingTypeList m_itemsType; ThingTypeList m_things[LastCategory];
ThingTypeList m_creaturesType;
ThingTypeList m_effectsType;
ThingTypeList m_shotsType;
}; };
extern ThingsType g_thingsType; extern ThingsType g_thingsType;

View File

@ -27,106 +27,75 @@
struct ThingType struct ThingType
{ {
ThingType() { enum Dimensions {
layers = 0; Width = 0,
width = height = 0; Height,
exactSize = 0; ExactSize,
xPattern = yPattern = zPattern = 0; Layers,
animationPhases = 0; PatternX,
xDisplacement = yDisplacement = 0; PatternY,
elevation = 0; PatternZ,
AnimationPhases,
isGround = false; LastDimension
isGroundClip = false; };
isOnBottom = false; std::array<int, LastDimension> dimensions;
isOnTop = false;
isContainer = false;
isStackable = false;
isForceUse = false;
isMultiUse = false;
isWritable = false;
isWritableOnce = false;
isFluidContainer = false;
isSplash = false;
isNotWalkable = false;
isNotMoveable = false;
isUnsight = false;
isNotPathable = false;
isPickupable = false;
isHangable = false;
isHookSouth = false;
isHookEast = false;
isRotable = false;
isDontHide = false;
isTranslucent = false;
isLyingCorpse = false;
isAnimatedAlways = false;
isLensHelp = false;
isFullGround = false;
isIgnoreLook = false;
isCloth = false;
isAnimation = false;
hasLight = false;
hasMiniMapColor = false;
groundSpeed = 0;
fluidParam = 0;
maxTextLength = 0;
lightLevel = lightColor = 0;
miniMapColor = 0;
lensHelp = 0;
clothSlot = 0;
}
uint8 layers;
uint8 width, height;
uint8 exactSize;
uint8 xPattern, yPattern, zPattern;
uint8 animationPhases;
uint16 xDisplacement, yDisplacement;
uint16 elevation;
std::vector<int> sprites; std::vector<int> sprites;
bool isGround; enum Properties {
bool isGroundClip; IsGround = 0,
bool isOnBottom; IsGroundBorder,
bool isOnTop; IsOnBottom,
bool isContainer; IsOnTop,
bool isStackable; IsContainer,
bool isForceUse; IsStackable,
bool isMultiUse; IsForceUse,
bool isWritable; IsMultiUse,
bool isWritableOnce; IsWritable,
bool isFluidContainer; IsWritableOnce,
bool isSplash; IsFluidContainer,
bool isNotWalkable; IsFluid,
bool isNotMoveable; NotWalkable,
bool isUnsight; NotMovable,
bool isNotPathable; BlockProjectile,
bool isPickupable; NotPathable,
bool isHangable; Pickupable,
bool isHookSouth; IsHangable,
bool isHookEast; HookSouth,
bool isRotable; HookEast,
bool isDontHide; IsRotable,
bool isTranslucent; HasLight,
bool isLyingCorpse; DontHide,
bool isAnimatedAlways; IsTranslucent,
bool isLensHelp; HasDisplacement,
bool isFullGround; HasElevation,
bool isIgnoreLook; IsLyingCorpse,
bool isCloth; AnimateAlways,
bool isAnimation; MiniMap,
bool hasLight; LensHelp,
bool hasMiniMapColor; IsFullGround,
IgnoreLook,
Cloth,
Animation,
LastProperty,
LastPropertyValue = 255
};
std::array<bool, LastProperty> properties;
uint16 groundSpeed; enum Parameters {
uint8 fluidParam; GroundSpeed = 0,
uint16 maxTextLength; Fluid,
uint16 lightLevel, lightColor; MaxTextLenght,
uint16 miniMapColor; LightLevel,
uint16 lensHelp; LightColor,
uint16 clothSlot; MiniMapColor,
LensHelpParameter,
ClothSlot,
DisplacementX,
DisplacementY,
Elevation,
LastParameter
};
std::array<int, LastParameter> parameters;
}; };
typedef std::vector<ThingType> ThingTypeList; typedef std::vector<ThingType> ThingTypeList;

View File

@ -43,10 +43,10 @@ void Tile::draw(const Point& p)
// first bottom items // first bottom items
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
const ThingType& type = thing->getType(); const ThingType& type = thing->getType();
if(!type.isGround && !type.isGroundClip && !type.isOnBottom) if(!type.properties[ThingType::IsGround] && !type.properties[ThingType::IsGroundBorder] && !type.properties[ThingType::IsOnBottom])
break; break;
thing->draw(p - m_drawElevation); thing->draw(p - m_drawElevation);
m_drawElevation += type.elevation; m_drawElevation += type.parameters[ThingType::Elevation];
if(m_drawElevation > MAX_DRAW_ELEVATION) if(m_drawElevation > MAX_DRAW_ELEVATION)
m_drawElevation = MAX_DRAW_ELEVATION; m_drawElevation = MAX_DRAW_ELEVATION;
} }
@ -55,10 +55,10 @@ void Tile::draw(const Point& p)
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
const ThingPtr& thing = *it; const ThingPtr& thing = *it;
const ThingType& type = thing->getType(); const ThingType& type = thing->getType();
if(thing->asCreature() || type.isOnTop || type.isOnBottom || type.isGroundClip || type.isGround) if(thing->asCreature() || type.properties[ThingType::IsOnTop] || type.properties[ThingType::IsOnBottom] || type.properties[ThingType::IsGroundBorder] || type.properties[ThingType::IsGround])
break; break;
thing->draw(p - m_drawElevation); thing->draw(p - m_drawElevation);
m_drawElevation += type.elevation; m_drawElevation += type.parameters[ThingType::Elevation];
if(m_drawElevation > MAX_DRAW_ELEVATION) if(m_drawElevation > MAX_DRAW_ELEVATION)
m_drawElevation = MAX_DRAW_ELEVATION; m_drawElevation = MAX_DRAW_ELEVATION;
} }
@ -68,8 +68,8 @@ void Tile::draw(const Point& p)
for(int xi = -1; xi <= 1; ++xi) { for(int xi = -1; xi <= 1; ++xi) {
for(int yi = -1; yi <= 1; ++yi) { for(int yi = -1; yi <= 1; ++yi) {
for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) { for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) {
auto& type = creature->getType(); const ThingType& type = creature->getType();
Rect creatureRect(p.x + xi*32 + creature->getWalkOffset().x - type.xDisplacement, p.y + yi*32 + creature->getWalkOffset().y - type.yDisplacement, 32, 32); Rect creatureRect(p.x + xi*32 + creature->getWalkOffset().x - type.parameters[ThingType::DisplacementX], p.y + yi*32 + creature->getWalkOffset().y - type.parameters[ThingType::DisplacementY], 32, 32);
Rect thisTileRect(p.x, p.y, 32, 32); Rect thisTileRect(p.x, p.y, 32, 32);
// only render creatures where bottom right is inside our rect // only render creatures where bottom right is inside our rect
@ -87,7 +87,7 @@ void Tile::draw(const Point& p)
// top items // top items
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
const ThingType& type = thing->getType(); const ThingType& type = thing->getType();
if(type.isOnTop) if(type.properties[ThingType::IsOnTop])
thing->draw(p); thing->draw(p);
} }
} }
@ -180,7 +180,7 @@ ItemPtr Tile::getGround()
if(!firstObject) if(!firstObject)
return nullptr; return nullptr;
const ThingType& type = firstObject->getType(); const ThingType& type = firstObject->getType();
if(type.isGround) if(type.properties[ThingType::IsGround])
return firstObject->asItem(); return firstObject->asItem();
return nullptr; return nullptr;
} }
@ -192,7 +192,7 @@ bool Tile::isWalkable()
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
const ThingType& type = thing->getType(); const ThingType& type = thing->getType();
if(type.isNotWalkable) if(type.properties[ThingType::NotWalkable])
return false; return false;
} }
return true; return true;
@ -204,7 +204,7 @@ bool Tile::isFullGround()
if(!ground) if(!ground)
return false; return false;
const ThingType& type = ground->getType(); const ThingType& type = ground->getType();
if(type.isGround && type.isFullGround) if(type.properties[ThingType::IsGround] && type.properties[ThingType::IsFullGround])
return true; return true;
return false; return false;
} }
@ -214,7 +214,7 @@ bool Tile::isFullyOpaque()
ThingPtr firstObject = getThing(0); ThingPtr firstObject = getThing(0);
if(firstObject) { if(firstObject) {
const ThingType& type = firstObject->getType(); const ThingType& type = firstObject->getType();
if(type.isFullGround) if(type.properties[ThingType::IsFullGround])
return true; return true;
} }
return false; return false;
@ -224,7 +224,7 @@ bool Tile::isLookPossible()
{ {
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
const ThingType& type = thing->getType(); const ThingType& type = thing->getType();
if(type.isUnsight) if(type.properties[ThingType::BlockProjectile])
return false; return false;
} }
return true; return true;

View File

@ -96,7 +96,7 @@ private:
void parseWorldLight(InputMessage& msg); void parseWorldLight(InputMessage& msg);
void parseMagicEffect(InputMessage& msg); void parseMagicEffect(InputMessage& msg);
void parseAnimatedText(InputMessage& msg); void parseAnimatedText(InputMessage& msg);
void parseDistanceShot(InputMessage& msg); void parseDistanceMissile(InputMessage& msg);
void parseCreatureSquare(InputMessage& msg); void parseCreatureSquare(InputMessage& msg);
void parseCreatureHealth(InputMessage& msg); void parseCreatureHealth(InputMessage& msg);
void parseCreatureLight(InputMessage& msg); void parseCreatureLight(InputMessage& msg);

View File

@ -140,7 +140,7 @@ void ProtocolGame::parseMessage(InputMessage& msg)
parseAnimatedText(msg); parseAnimatedText(msg);
break; break;
case Otc::GameServerMissleEffect: case Otc::GameServerMissleEffect:
parseDistanceShot(msg); parseDistanceMissile(msg);
break; break;
case Otc::GameServerMarkCreature: case Otc::GameServerMarkCreature:
parseCreatureSquare(msg); parseCreatureSquare(msg);
@ -532,7 +532,7 @@ void ProtocolGame::parseAnimatedText(InputMessage& msg)
msg.getString(); // text msg.getString(); // text
} }
void ProtocolGame::parseDistanceShot(InputMessage& msg) void ProtocolGame::parseDistanceMissile(InputMessage& msg)
{ {
Position fromPos = parsePosition(msg); Position fromPos = parsePosition(msg);
Position toPos = parsePosition(msg); Position toPos = parsePosition(msg);
@ -1057,8 +1057,8 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
id = msg.getU16(); id = msg.getU16();
item->setId(id); item->setId(id);
const ThingType& itemType = g_thingsType.getItemType(id); const ThingType& itemType = item->getType();
if(itemType.isStackable || itemType.isFluidContainer || itemType.isSplash) if(itemType.properties[ThingType::IsStackable] || itemType.properties[ThingType::IsFluidContainer] || itemType.properties[ThingType::IsFluid])
item->setData(msg.getU8()); item->setData(msg.getU8());
return item; return item;