thingstype rework
This commit is contained in:
parent
56f7ed3dd1
commit
0fa61333fa
|
@ -47,7 +47,7 @@ void Creature::draw(const Point& p)
|
|||
const ThingType& type = getType();
|
||||
|
||||
// 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.
|
||||
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);
|
||||
|
||||
// draw mask if exists
|
||||
if(type.layers > 1) {
|
||||
if(type.dimensions[ThingType::Layers] > 1) {
|
||||
// switch to blend color mode
|
||||
g_graphics.bindBlendFunc(Fw::BlendColorzing);
|
||||
|
||||
|
@ -187,7 +187,7 @@ void Creature::walk(const Position& position, bool inverse)
|
|||
|
||||
ItemPtr ground = g_map.getTile(position)->getGround();
|
||||
if(ground)
|
||||
groundSpeed = ground->getType().groundSpeed;
|
||||
groundSpeed = ground->getType().parameters[ThingType::GroundSpeed];
|
||||
|
||||
float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed;
|
||||
walkTime = (walkTime == 0) ? 1000 : walkTime;
|
||||
|
@ -233,7 +233,7 @@ void Creature::updateWalk()
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
if(totalPixelsWalked == 32)
|
||||
|
@ -272,7 +272,7 @@ void Creature::setDirection(Otc::Direction direction)
|
|||
|
||||
const ThingType& Creature::getType()
|
||||
{
|
||||
return g_thingsType.getCreatureType(m_outfit.type);
|
||||
return g_thingsType.getThingType(m_outfit.type, ThingsType::Creature);
|
||||
}
|
||||
|
||||
void Creature::onHealthPercentChange(int)
|
||||
|
|
|
@ -55,5 +55,5 @@ void Effect::startAnimation()
|
|||
|
||||
const ThingType& Effect::getType()
|
||||
{
|
||||
return g_thingsType.getEffectType(m_id);
|
||||
return g_thingsType.getThingType(m_id, ThingsType::Effect);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ Item::Item() : Thing()
|
|||
|
||||
void Item::draw(const Point& p)
|
||||
{
|
||||
const ThingType& type = g_thingsType.getItemType(m_id);
|
||||
const ThingType& type = getType();
|
||||
|
||||
if(type.animationPhases > 1)
|
||||
m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.animationPhases)) / TICKS_PER_FRAME;
|
||||
if(type.dimensions[ThingType::AnimationPhases] > 1)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -52,25 +52,25 @@ void Item::setData(int count)
|
|||
|
||||
const ThingType& Item::getType()
|
||||
{
|
||||
return g_thingsType.getItemType(m_id);
|
||||
return g_thingsType.getThingType(m_id, ThingsType::Item);
|
||||
}
|
||||
|
||||
void Item::onPositionChange(const Position&)
|
||||
{
|
||||
const ThingType& type = g_thingsType.getItemType(m_id);
|
||||
const ThingType& type = getType();
|
||||
|
||||
if(type.isNotMoveable) {
|
||||
m_xPattern = m_position.x % type.xPattern;
|
||||
m_yPattern = m_position.y % type.yPattern;
|
||||
m_zPattern = m_position.z % type.zPattern;
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
m_xPattern = m_data-1;
|
||||
m_yPattern = 0;
|
||||
|
@ -92,15 +92,15 @@ void Item::onDataChange(int)
|
|||
m_yPattern = 1;
|
||||
}
|
||||
}
|
||||
else if(type.isHangable) {
|
||||
if(type.isHookSouth) {
|
||||
m_xPattern = type.xPattern >= 2 ? 1 : 0;
|
||||
else if(type.properties[ThingType::IsHangable]) {
|
||||
if(type.properties[ThingType::HookSouth]) {
|
||||
m_xPattern = type.dimensions[ThingType::PatternX] >= 2 ? 1 : 0;
|
||||
}
|
||||
else if(type.isHookEast) {
|
||||
m_xPattern = type.xPattern >= 3 ? 2 : 0;
|
||||
else if(type.properties[ThingType::HookEast]) {
|
||||
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;
|
||||
// TODO: find out what the heck does it mean
|
||||
switch(m_data) {
|
||||
|
@ -163,7 +163,7 @@ void Item::onDataChange(int)
|
|||
break;
|
||||
}
|
||||
|
||||
m_xPattern = (var & 3) % type.xPattern;
|
||||
m_yPattern = (var >> 2) % type.yPattern;
|
||||
m_xPattern = (var & 3) % type.dimensions[ThingType::PatternX];
|
||||
m_yPattern = (var >> 2) % type.dimensions[ThingType::PatternY];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ int Map::getFirstVisibleFloor()
|
|||
if(TilePtr tile = m_tiles[upperPos]) {
|
||||
if(ThingPtr firstThing = tile->getThing(0)) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ int Map::getFirstVisibleFloor()
|
|||
if(TilePtr tile = m_tiles[perspectivePos]) {
|
||||
if(ThingPtr firstThing = tile->getThing(0)) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -119,5 +119,5 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
|||
|
||||
const ThingType& Missile::getType()
|
||||
{
|
||||
return g_thingsType.getShotType(m_id);
|
||||
return g_thingsType.getThingType(m_id, ThingsType::Missile);
|
||||
}
|
||||
|
|
|
@ -52,15 +52,15 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
|||
{
|
||||
const ThingType& type = getType();
|
||||
|
||||
for(int yi = 0; yi < type.height; yi++) {
|
||||
for(int xi = 0; xi < type.width; xi++) {
|
||||
int sprIndex = ((((((m_animation % type.animationPhases)
|
||||
* type.zPattern + m_zPattern)
|
||||
* type.yPattern + m_yPattern)
|
||||
* type.xPattern + m_xPattern)
|
||||
* type.layers + layers)
|
||||
* type.height + yi)
|
||||
* type.width + xi;
|
||||
for(int yi = 0; yi < type.dimensions[ThingType::Height]; yi++) {
|
||||
for(int xi = 0; xi < type.dimensions[ThingType::Width]; xi++) {
|
||||
int sprIndex = ((((((m_animation % type.dimensions[ThingType::AnimationPhases])
|
||||
* type.dimensions[ThingType::PatternZ] + m_zPattern)
|
||||
* type.dimensions[ThingType::PatternY] + m_yPattern)
|
||||
* type.dimensions[ThingType::PatternX] + m_xPattern)
|
||||
* type.dimensions[ThingType::Layers] + layers)
|
||||
* type.dimensions[ThingType::Height] + yi)
|
||||
* type.dimensions[ThingType::Width] + xi;
|
||||
|
||||
int spriteId = type.sprites[sprIndex];
|
||||
if(!spriteId)
|
||||
|
@ -68,8 +68,8 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
|||
|
||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask);
|
||||
|
||||
Rect drawRect((p.x - xi*32) - type.xDisplacement,
|
||||
(p.y - yi*32) - type.yDisplacement,
|
||||
Rect drawRect((p.x - xi*32) - type.parameters[ThingType::DisplacementX],
|
||||
(p.y - yi*32) - type.parameters[ThingType::DisplacementY],
|
||||
32, 32);
|
||||
g_graphics.drawTexturedRect(drawRect, spriteTex);
|
||||
}
|
||||
|
@ -79,13 +79,13 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
|||
int Thing::getStackPriority()
|
||||
{
|
||||
const ThingType& type = getType();
|
||||
if(type.isGround)
|
||||
if(type.properties[ThingType::IsGround])
|
||||
return 0;
|
||||
else if(type.isGroundClip)
|
||||
else if(type.properties[ThingType::IsGroundBorder])
|
||||
return 1;
|
||||
else if(type.isOnBottom)
|
||||
else if(type.properties[ThingType::IsOnBottom])
|
||||
return 2;
|
||||
else if(type.isOnTop)
|
||||
else if(type.properties[ThingType::IsOnTop])
|
||||
return 3;
|
||||
else if(asCreature())
|
||||
return 4;
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
Position getPosition() const { return m_position; }
|
||||
int getStackPriority();
|
||||
virtual const ThingType& getType() = 0;
|
||||
int getAnimationPhases() { return getType().animationPhases; }
|
||||
int getAnimationPhases() { return getType().dimensions[ThingType::AnimationPhases]; }
|
||||
|
||||
virtual void onIdChange(int) {}
|
||||
virtual void onPositionChange(const Position&) {}
|
||||
|
|
|
@ -34,26 +34,18 @@ bool ThingsType::load(const std::string& file)
|
|||
g_resources.loadFile(file, 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);
|
||||
for(int id = 100; id < numItems; ++id)
|
||||
parseThingType(fin, m_itemsType[id - 100]);
|
||||
int numThings[LastCategory];
|
||||
for(int i = 0; i < LastCategory; ++i)
|
||||
numThings[i] = Fw::getU16(fin);
|
||||
|
||||
m_creaturesType.resize(numCreatures);
|
||||
for(int id = 0; id < numCreatures; ++id)
|
||||
parseThingType(fin, m_creaturesType[id]);
|
||||
numThings[Item] -= 100;
|
||||
|
||||
m_effectsType.resize(numEffects);
|
||||
for(int id = 0; id < numEffects; ++id)
|
||||
parseThingType(fin, m_effectsType[id]);
|
||||
|
||||
m_shotsType.resize(numShots);
|
||||
for(int id = 0; id < numShots; ++id)
|
||||
parseThingType(fin, m_shotsType[id]);
|
||||
for(int i = 0; i < LastCategory; ++i) {
|
||||
m_things[i].resize(numThings[i]);
|
||||
for(int id = 0; id < numThings[i]; ++id)
|
||||
parseThingType(fin, m_things[i][id]);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
|
@ -64,162 +56,67 @@ bool ThingsType::load(const std::string& file)
|
|||
|
||||
void ThingsType::unload()
|
||||
{
|
||||
m_itemsType.clear();
|
||||
m_creaturesType.clear();
|
||||
m_effectsType.clear();
|
||||
m_shotsType.clear();
|
||||
for(int i = 0; i < LastCategory; ++i)
|
||||
m_things[i].clear();
|
||||
}
|
||||
|
||||
void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
|
||||
{
|
||||
assert(fin.good());
|
||||
|
||||
bool done = false;
|
||||
while(!done) {
|
||||
uint8 opt = Fw::getU8(fin);
|
||||
while(true) {
|
||||
int property = Fw::getU8(fin);
|
||||
if(property == ThingType::LastPropertyValue)
|
||||
break;
|
||||
|
||||
switch(opt) {
|
||||
case Otc::DatGround: // Grounds, must be drawn first
|
||||
thingType.groundSpeed = Fw::getU16(fin);
|
||||
thingType.isGround = true;
|
||||
break;
|
||||
case Otc::DatGroundClip: // Objects that clips (has transparent pixels) and must be drawn just after ground (e.g: ground borders)
|
||||
thingType.isGroundClip = true;
|
||||
break;
|
||||
case Otc::DatOnBottom: // Bottom items, must be drawn above general items and below creatures (e.g: stairs)
|
||||
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));
|
||||
thingType.properties[property] = true;
|
||||
|
||||
if(property == ThingType::IsGround)
|
||||
thingType.parameters[ThingType::GroundSpeed] = Fw::getU16(fin);
|
||||
else if(property == ThingType::IsWritable || property == ThingType::IsWritableOnce)
|
||||
thingType.parameters[ThingType::MaxTextLenght] = Fw::getU16(fin);
|
||||
else if(property == ThingType::HasLight) {
|
||||
thingType.parameters[ThingType::LightLevel] = Fw::getU16(fin);
|
||||
thingType.parameters[ThingType::LightColor] = Fw::getU16(fin);
|
||||
}
|
||||
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);
|
||||
thingType.height = Fw::getU8(fin);
|
||||
int totalSprites = 1;
|
||||
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.exactSize = Fw::getU8(fin);
|
||||
else
|
||||
thingType.exactSize = 32;
|
||||
thingType.dimensions[i] = Fw::getU8(fin);
|
||||
|
||||
thingType.layers = Fw::getU8(fin);
|
||||
thingType.xPattern = Fw::getU8(fin);
|
||||
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;
|
||||
if(i != ThingType::ExactSize)
|
||||
totalSprites *= thingType.dimensions[i];
|
||||
}
|
||||
|
||||
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& ThingsType::getThingType(uint16 id, Categories category)
|
||||
{
|
||||
if(category == Item)
|
||||
id -= 100;
|
||||
|
||||
assert(id < m_things[category].size());
|
||||
|
||||
return m_things[category][id];
|
||||
}
|
||||
|
|
|
@ -29,25 +29,28 @@
|
|||
class ThingsType
|
||||
{
|
||||
public:
|
||||
|
||||
enum Categories {
|
||||
Item = 0,
|
||||
Creature,
|
||||
Effect,
|
||||
Missile,
|
||||
LastCategory
|
||||
};
|
||||
|
||||
bool load(const std::string& file);
|
||||
void unload();
|
||||
|
||||
void parseThingType(std::stringstream& fin, ThingType& thingType);
|
||||
|
||||
ThingType& getItemType(uint16 id) { return m_itemsType[id - 100]; }
|
||||
ThingType& getCreatureType(uint16 id) { return m_creaturesType[id]; }
|
||||
ThingType& getEffectType(uint16 id) { return m_effectsType[id]; }
|
||||
ThingType& getShotType(uint16 id) { return m_shotsType[id]; }
|
||||
ThingType& getThingType(uint16 id, Categories category);
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
|
||||
private:
|
||||
uint32 m_signature;
|
||||
|
||||
ThingTypeList m_itemsType;
|
||||
ThingTypeList m_creaturesType;
|
||||
ThingTypeList m_effectsType;
|
||||
ThingTypeList m_shotsType;
|
||||
ThingTypeList m_things[LastCategory];
|
||||
};
|
||||
|
||||
extern ThingsType g_thingsType;
|
||||
|
|
|
@ -27,106 +27,75 @@
|
|||
|
||||
struct ThingType
|
||||
{
|
||||
ThingType() {
|
||||
layers = 0;
|
||||
width = height = 0;
|
||||
exactSize = 0;
|
||||
xPattern = yPattern = zPattern = 0;
|
||||
animationPhases = 0;
|
||||
xDisplacement = yDisplacement = 0;
|
||||
elevation = 0;
|
||||
|
||||
isGround = false;
|
||||
isGroundClip = false;
|
||||
isOnBottom = false;
|
||||
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;
|
||||
enum Dimensions {
|
||||
Width = 0,
|
||||
Height,
|
||||
ExactSize,
|
||||
Layers,
|
||||
PatternX,
|
||||
PatternY,
|
||||
PatternZ,
|
||||
AnimationPhases,
|
||||
LastDimension
|
||||
};
|
||||
std::array<int, LastDimension> dimensions;
|
||||
std::vector<int> sprites;
|
||||
|
||||
bool isGround;
|
||||
bool isGroundClip;
|
||||
bool isOnBottom;
|
||||
bool isOnTop;
|
||||
bool isContainer;
|
||||
bool isStackable;
|
||||
bool isForceUse;
|
||||
bool isMultiUse;
|
||||
bool isWritable;
|
||||
bool isWritableOnce;
|
||||
bool isFluidContainer;
|
||||
bool isSplash;
|
||||
bool isNotWalkable;
|
||||
bool isNotMoveable;
|
||||
bool isUnsight;
|
||||
bool isNotPathable;
|
||||
bool isPickupable;
|
||||
bool isHangable;
|
||||
bool isHookSouth;
|
||||
bool isHookEast;
|
||||
bool isRotable;
|
||||
bool isDontHide;
|
||||
bool isTranslucent;
|
||||
bool isLyingCorpse;
|
||||
bool isAnimatedAlways;
|
||||
bool isLensHelp;
|
||||
bool isFullGround;
|
||||
bool isIgnoreLook;
|
||||
bool isCloth;
|
||||
bool isAnimation;
|
||||
bool hasLight;
|
||||
bool hasMiniMapColor;
|
||||
enum Properties {
|
||||
IsGround = 0,
|
||||
IsGroundBorder,
|
||||
IsOnBottom,
|
||||
IsOnTop,
|
||||
IsContainer,
|
||||
IsStackable,
|
||||
IsForceUse,
|
||||
IsMultiUse,
|
||||
IsWritable,
|
||||
IsWritableOnce,
|
||||
IsFluidContainer,
|
||||
IsFluid,
|
||||
NotWalkable,
|
||||
NotMovable,
|
||||
BlockProjectile,
|
||||
NotPathable,
|
||||
Pickupable,
|
||||
IsHangable,
|
||||
HookSouth,
|
||||
HookEast,
|
||||
IsRotable,
|
||||
HasLight,
|
||||
DontHide,
|
||||
IsTranslucent,
|
||||
HasDisplacement,
|
||||
HasElevation,
|
||||
IsLyingCorpse,
|
||||
AnimateAlways,
|
||||
MiniMap,
|
||||
LensHelp,
|
||||
IsFullGround,
|
||||
IgnoreLook,
|
||||
Cloth,
|
||||
Animation,
|
||||
LastProperty,
|
||||
LastPropertyValue = 255
|
||||
};
|
||||
std::array<bool, LastProperty> properties;
|
||||
|
||||
uint16 groundSpeed;
|
||||
uint8 fluidParam;
|
||||
uint16 maxTextLength;
|
||||
uint16 lightLevel, lightColor;
|
||||
uint16 miniMapColor;
|
||||
uint16 lensHelp;
|
||||
uint16 clothSlot;
|
||||
enum Parameters {
|
||||
GroundSpeed = 0,
|
||||
Fluid,
|
||||
MaxTextLenght,
|
||||
LightLevel,
|
||||
LightColor,
|
||||
MiniMapColor,
|
||||
LensHelpParameter,
|
||||
ClothSlot,
|
||||
DisplacementX,
|
||||
DisplacementY,
|
||||
Elevation,
|
||||
LastParameter
|
||||
};
|
||||
std::array<int, LastParameter> parameters;
|
||||
};
|
||||
|
||||
typedef std::vector<ThingType> ThingTypeList;
|
||||
|
|
|
@ -43,10 +43,10 @@ void Tile::draw(const Point& p)
|
|||
// first bottom items
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
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;
|
||||
thing->draw(p - m_drawElevation);
|
||||
m_drawElevation += type.elevation;
|
||||
m_drawElevation += type.parameters[ThingType::Elevation];
|
||||
if(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) {
|
||||
const ThingPtr& thing = *it;
|
||||
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;
|
||||
thing->draw(p - m_drawElevation);
|
||||
m_drawElevation += type.elevation;
|
||||
m_drawElevation += type.parameters[ThingType::Elevation];
|
||||
if(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 yi = -1; yi <= 1; ++yi) {
|
||||
for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) {
|
||||
auto& 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);
|
||||
const ThingType& type = creature->getType();
|
||||
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);
|
||||
|
||||
// only render creatures where bottom right is inside our rect
|
||||
|
@ -87,7 +87,7 @@ void Tile::draw(const Point& p)
|
|||
// top items
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
const ThingType& type = thing->getType();
|
||||
if(type.isOnTop)
|
||||
if(type.properties[ThingType::IsOnTop])
|
||||
thing->draw(p);
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ ItemPtr Tile::getGround()
|
|||
if(!firstObject)
|
||||
return nullptr;
|
||||
const ThingType& type = firstObject->getType();
|
||||
if(type.isGround)
|
||||
if(type.properties[ThingType::IsGround])
|
||||
return firstObject->asItem();
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ bool Tile::isWalkable()
|
|||
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
const ThingType& type = thing->getType();
|
||||
if(type.isNotWalkable)
|
||||
if(type.properties[ThingType::NotWalkable])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -204,7 +204,7 @@ bool Tile::isFullGround()
|
|||
if(!ground)
|
||||
return false;
|
||||
const ThingType& type = ground->getType();
|
||||
if(type.isGround && type.isFullGround)
|
||||
if(type.properties[ThingType::IsGround] && type.properties[ThingType::IsFullGround])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ bool Tile::isFullyOpaque()
|
|||
ThingPtr firstObject = getThing(0);
|
||||
if(firstObject) {
|
||||
const ThingType& type = firstObject->getType();
|
||||
if(type.isFullGround)
|
||||
if(type.properties[ThingType::IsFullGround])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -224,7 +224,7 @@ bool Tile::isLookPossible()
|
|||
{
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
const ThingType& type = thing->getType();
|
||||
if(type.isUnsight)
|
||||
if(type.properties[ThingType::BlockProjectile])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -96,7 +96,7 @@ private:
|
|||
void parseWorldLight(InputMessage& msg);
|
||||
void parseMagicEffect(InputMessage& msg);
|
||||
void parseAnimatedText(InputMessage& msg);
|
||||
void parseDistanceShot(InputMessage& msg);
|
||||
void parseDistanceMissile(InputMessage& msg);
|
||||
void parseCreatureSquare(InputMessage& msg);
|
||||
void parseCreatureHealth(InputMessage& msg);
|
||||
void parseCreatureLight(InputMessage& msg);
|
||||
|
|
|
@ -140,7 +140,7 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
parseAnimatedText(msg);
|
||||
break;
|
||||
case Otc::GameServerMissleEffect:
|
||||
parseDistanceShot(msg);
|
||||
parseDistanceMissile(msg);
|
||||
break;
|
||||
case Otc::GameServerMarkCreature:
|
||||
parseCreatureSquare(msg);
|
||||
|
@ -532,7 +532,7 @@ void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
|||
msg.getString(); // text
|
||||
}
|
||||
|
||||
void ProtocolGame::parseDistanceShot(InputMessage& msg)
|
||||
void ProtocolGame::parseDistanceMissile(InputMessage& msg)
|
||||
{
|
||||
Position fromPos = parsePosition(msg);
|
||||
Position toPos = parsePosition(msg);
|
||||
|
@ -1057,8 +1057,8 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
|
|||
id = msg.getU16();
|
||||
item->setId(id);
|
||||
|
||||
const ThingType& itemType = g_thingsType.getItemType(id);
|
||||
if(itemType.isStackable || itemType.isFluidContainer || itemType.isSplash)
|
||||
const ThingType& itemType = item->getType();
|
||||
if(itemType.properties[ThingType::IsStackable] || itemType.properties[ThingType::IsFluidContainer] || itemType.properties[ThingType::IsFluid])
|
||||
item->setData(msg.getU8());
|
||||
|
||||
return item;
|
||||
|
|
Loading…
Reference in New Issue