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();
|
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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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&) {}
|
||||||
|
|
|
@ -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];
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue