/**
* @class Entity
* @brief A superclass for all objects existing within the world
* @author Samuel Kaufman
* @date 2002
*/
/**
* @class LandTile
* @brief An entity representing a landscape tile
* @author Samuel Kaufman
* @date 2002
*/
/**
* @class Static
* @brief An entity representing a static object in the game
* @author Samuel Kaufman
* @date 2002
*/
/*****
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****/
#include "uop.h"
#include <SDL/SDL.h>
#include <iostream>
#include "tiledata.h"
#include "entity.h"
#include "world.h"
extern Animations *anims;
extern TileData *tileData;
extern World *world;
/**
* Function calculates animation_id
* using model_id
* @param model Model ID
*/
Uint32 getAnimationBase(Uint32 model)
{
if(model < 0xc8)
{
return model * 110;
}
if(model < 0x190)
{
return (model - 0x0C8) * 65 + 22000;
}
return (model - 0x190) * 175 + 35000;
}
Entity::Entity()
{
inCell = NULL;
}
Entity::~Entity()
{
if (inCell)
inCell->remove(this);
}
void Entity::blit(unsigned int x, unsigned int y)
{
}
/**
* A function for sorting entities within the
* blitting order.
* @param lesser The entity being compared.
*/
bool Entity::operator>(Entity &lesser)
{
if (z != lesser.z)
return (z > lesser.z);
if(order() != lesser.order())
return order()>lesser.order();
return (sHeight() > lesser.sHeight());
}
void LandTile::blit(unsigned int x, unsigned int y)
{
image.blit(x-22, y);
}
/**
* Creates a land tile's sprite. It performs
* all necessary special effect and stretching
* as appropriate.
* @param y2 The right tile corner's Y position.
* @param y3 The bottom tile corner's Y position.
* @param y4 The left tile corner's Y position.
*/
void LandTile::render(int y2, int y3, int y4)
{
if ((y2 == 22)&&(y3 == 43)&&(y4 == 22))
{
image = world->artSprites[index];
return;
}
Sprite &oldSprite = world->artSprites[index];
Uint16 *old=oldSprite.data;
if (y3>0)
{
int offsetY=0;
if (y2<0 || y4<0)
{
if (y2<y4)
offsetY=-(y2-1);
else
offsetY=-(y4-1);
}
Uint16 height;
height=y3+1;
if (y2>height) height=y2+2;
if (y4>height) height=y4+2;
height+=offsetY;
int topYM=offsetY,
topYL=y4+offsetY-1,
topYR=y2+offsetY-1;
int btmYM=y3+offsetY,
btmYL=y4+offsetY,
btmYR=y2+offsetY;
image.resize(44,height);
int oy;
Uint16 *sd=image.data;
Uint16 *od=old;
int top,bottom;
int otop,oheight;
for (int ex=0;ex<44;ex++)
{
if (ex>=22)
{
top=topYM+((topYR-topYM)*(ex-22))/22;
bottom=btmYM-((btmYM-btmYR)*(ex-22))/22;
otop=(ex-22)*44+ex;
oheight=(22-(ex-21))*2+2;
}
else
{
top=topYL-((topYL-topYM)*ex)/21;
bottom=btmYL+((btmYM-btmYL)*ex)/21;
otop=(21-ex)*44+ex;
oheight=ex*2+2;
}
int lineheight=bottom-top;
for (int why=0;why<=lineheight;why++)
{
oy=otop+((why*oheight)/lineheight)*44;
*(sd+(top+why)*44+ex)=*(od+oy);
}
}
}
}
void Static::blit(unsigned int x, unsigned int y)
{
Sprite &image = world->artSprites[index];
image.blit(x-(image.width/2), y - image.height);
}
/**
* The height to be used in sorting the static
* within the drawing order.
*/
Uint8 Static::sHeight()
{
return ((StaticEntry*)(*tileData)[index])->height;
}
Mobile::Mobile(Uint32 serial, Uint32 id)
{
Entity::Entity();
this->serial = serial;
this->id = id;
this->action = HE_STAND;
this->animation_base = getAnimationBase(id);
this->x = 0;
this->y = 0;
this->z = 0;
this->status = 0;
this->color = 0;
this->hue = 0;
this->inThirdDawn = false;
updateAnimation();
}
void Mobile::blit(unsigned int x, unsigned int y)
{
Animation &anim = anims->anims[animation_base + status*8 + (dir + 8 - 3)];
//Animation &anim = anims->anims[id];
if (anim.frames)
{
anim.frames[0].blit(x, y, anim.palette);
}
else
{
assert(false);
static int i = 0;
cout << "Producing " << animation_base + i << endl;
anim.produce(animation_base + i + (dir + 8 - 3) , anim);
i++;
}
//currentState.blit(x, y);
}
void Mobile::updateAnimation()
{
currentState.animIndex = this->id;
}