Changed Unit::Frame and Unit::SeenFrame to ints, added UnitType::NumDirections and MissileType::NumDirections
This commit is contained in:
parent
8980844f4b
commit
3b67b219c9
12 changed files with 77 additions and 43 deletions
|
@ -192,7 +192,11 @@ local int ActionMoveGeneric(Unit* unit,const Animation* anim)
|
|||
//
|
||||
unit->IX+=xd*anim[state].Pixel;
|
||||
unit->IY+=yd*anim[state].Pixel;
|
||||
unit->Frame+=anim[state].Frame;
|
||||
if( unit->Frame<0 ) {
|
||||
unit->Frame+=-anim[state].Frame;
|
||||
} else {
|
||||
unit->Frame+=anim[state].Frame;
|
||||
}
|
||||
unit->Wait=anim[state].Sleep;
|
||||
if( unit->Slow ) { // unit is slowed down
|
||||
unit->Wait<<=1;
|
||||
|
|
|
@ -86,7 +86,11 @@ global int UnitShowAnimation(Unit* unit,const Animation* animation)
|
|||
_C_ animation[state].Frame _C_ animation[state].Sleep);
|
||||
DebugLevel3("Heading %d +%d,%d\n" _C_ unit->Direction _C_ unit->IX _C_ unit->IY);
|
||||
|
||||
unit->Frame+=animation[state].Frame;
|
||||
if( unit->Frame<0 ) {
|
||||
unit->Frame+=-animation[state].Frame;
|
||||
} else {
|
||||
unit->Frame+=animation[state].Frame;
|
||||
}
|
||||
unit->IX+=animation[state].Pixel;
|
||||
unit->IY+=animation[state].Pixel;
|
||||
unit->Wait=animation[state].Sleep;
|
||||
|
|
|
@ -84,6 +84,10 @@
|
|||
** @note There is currently a limit of 127 sprite frames, which
|
||||
** can be lifted if needed.
|
||||
**
|
||||
** MissileType::NumDirections
|
||||
**
|
||||
** Number of directions missile can face.
|
||||
**
|
||||
** MissileType::FiredSound
|
||||
**
|
||||
** Sound of the missile, if fired. @note currently not used.
|
||||
|
@ -328,6 +332,7 @@ struct _missile_type_ {
|
|||
unsigned Width; /// missile width in pixels
|
||||
unsigned Height; /// missile height in pixels
|
||||
unsigned SpriteFrames; /// number of sprite frames in graphic
|
||||
int NumDirections; /// number of directions missile can face
|
||||
|
||||
// FIXME: FireSound defined but not used!
|
||||
SoundConfig FiredSound; /// fired sound
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
** Unit::SeenFrame
|
||||
**
|
||||
** Graphic image (see Unit::Frame) what the player on this
|
||||
** computer has last seen. If -1 (0xFF) the player haven't seen
|
||||
** computer has last seen. If UnitNotSeen the player haven't seen
|
||||
** this unit yet.
|
||||
**
|
||||
** Unit::Direction
|
||||
|
@ -455,6 +455,7 @@ enum _directions_ {
|
|||
};
|
||||
|
||||
#define NextDirection 32 /// Next direction N->NE->E...
|
||||
#define UnitNotSeen 0x7fffffff /// Unit not seen, used by Unit::SeenFrame
|
||||
|
||||
/// The big unit structure
|
||||
struct _unit_ {
|
||||
|
@ -478,8 +479,8 @@ struct _unit_ {
|
|||
UnitColors Colors; /// Player colors
|
||||
char IX; /// X image displacement to map position
|
||||
char IY; /// Y image displacement to map position
|
||||
unsigned Frame : 8; /// Image frame: high bit used for flip
|
||||
unsigned SeenFrame : 8; /// last seen frame/stage of buildings
|
||||
int Frame; /// Image frame: <0 is mirrored
|
||||
int SeenFrame; /// last seen frame/stage of buildings
|
||||
|
||||
unsigned Direction : 8; /// angle (0-255) unit looking
|
||||
|
||||
|
|
|
@ -158,6 +158,10 @@
|
|||
**
|
||||
** Selected box size height
|
||||
**
|
||||
** UnitType::NumDirections
|
||||
**
|
||||
** Number of directions the unit can face
|
||||
**
|
||||
** UnitType::MinAttackRange
|
||||
**
|
||||
** Minimal attack range
|
||||
|
@ -425,7 +429,7 @@ typedef struct _animation_ {
|
|||
unsigned char Flags; /// Flags for actions
|
||||
signed char Pixel; /// Change the position in pixels
|
||||
unsigned char Sleep; /// Wait for next animation
|
||||
unsigned char Frame; /// Sprite-frame to display
|
||||
int Frame; /// Sprite-frame to display
|
||||
} Animation;
|
||||
|
||||
#define AnimationRestart 1 /// Restart animation
|
||||
|
@ -497,6 +501,7 @@ struct _unit_type_ {
|
|||
int TileHeight; /// Tile size on map height
|
||||
int BoxWidth; /// Selected box size width
|
||||
int BoxHeight; /// Selected box size height
|
||||
int NumDirections; /// Number of directions unit can face
|
||||
int MinAttackRange; /// Minimal attack range
|
||||
int _AttackRange; /// How far can the unit attack
|
||||
int ReactRangeComputer; /// Reacts on enemy for computer
|
||||
|
@ -636,7 +641,7 @@ extern Animations* AnimationsByIdent(const char* ident);
|
|||
extern void SaveUnitTypes(FILE* file); /// Save the unit-type table
|
||||
extern UnitType* NewUnitTypeSlot(char*);/// Allocate an empty unit-type slot
|
||||
/// Draw the sprite frame of unit-type
|
||||
extern void DrawUnitType(const UnitType* type,unsigned frame,int x,int y);
|
||||
extern void DrawUnitType(const UnitType* type,int frame,int x,int y);
|
||||
|
||||
extern void InitUnitTypes(void); /// Init unit-type table
|
||||
extern void LoadUnitTypes(void); /// Load the unit-type data
|
||||
|
|
|
@ -761,11 +761,11 @@ global int CheckMissileToBeDrawn(const Missile* missile)
|
|||
/**
|
||||
** Draw missile.
|
||||
*/
|
||||
global void DrawMissile(const MissileType* mtype,unsigned frame,int x,int y)
|
||||
local void DrawMissile(const MissileType* mtype,int frame,int x,int y)
|
||||
{
|
||||
// FIXME: This is a hack for mirrored sprites
|
||||
if( frame&128 ) {
|
||||
VideoDrawClipX(mtype->Sprite,frame&127,x,y);
|
||||
if( frame<0 ) {
|
||||
VideoDrawClipX(mtype->Sprite,-frame,x,y);
|
||||
} else {
|
||||
VideoDrawClip(mtype->Sprite,frame,x,y);
|
||||
}
|
||||
|
@ -845,18 +845,21 @@ global void DrawMissiles(void)
|
|||
local void MissileNewHeadingFromXY(Missile* missile,int dx,int dy)
|
||||
{
|
||||
int dir;
|
||||
int nextdir;
|
||||
|
||||
// FIXME: depends on the missile directions wc 8, sc 32
|
||||
missile->SpriteFrame&=127;
|
||||
missile->SpriteFrame/=5;
|
||||
missile->SpriteFrame*=5;
|
||||
if( missile->SpriteFrame<0 ) {
|
||||
missile->SpriteFrame=-missile->SpriteFrame;
|
||||
}
|
||||
missile->SpriteFrame/=missile->Type->NumDirections/2+1;
|
||||
missile->SpriteFrame*=missile->Type->NumDirections/2+1;
|
||||
|
||||
dir=((DirectionToHeading(dx,dy)+NextDirection/2)&0xFF)/NextDirection;
|
||||
if( dir<=LookingS/NextDirection ) { // north->east->south
|
||||
nextdir=256/missile->Type->NumDirections;
|
||||
dir=((DirectionToHeading(dx,dy)+nextdir/2)&0xFF)/nextdir;
|
||||
if( dir<=LookingS/nextdir ) { // north->east->south
|
||||
missile->SpriteFrame+=dir;
|
||||
} else {
|
||||
// Note: 128 is the flag for flip graphic in X.
|
||||
missile->SpriteFrame+=128+256/NextDirection-dir;
|
||||
missile->SpriteFrame+=256/nextdir-dir;
|
||||
missile->SpriteFrame=-missile->SpriteFrame;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ local SCM CclDefineMissileType(SCM list)
|
|||
mtype=NewMissileTypeSlot(str); // str consumed!
|
||||
}
|
||||
|
||||
mtype->NumDirections=8;
|
||||
//
|
||||
// Parse the arguments, already the new tagged format.
|
||||
//
|
||||
|
@ -96,6 +97,8 @@ local SCM CclDefineMissileType(SCM list)
|
|||
mtype->Height=gh_scm2int(gh_car(value));
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("frames")) ) {
|
||||
mtype->SpriteFrames=gh_scm2int(gh_car(list));
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("num-directions")) ) {
|
||||
mtype->NumDirections=gh_scm2int(gh_car(list));
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("fired-sound")) ) {
|
||||
free(mtype->FiredSound.Name);
|
||||
mtype->FiredSound.Name=gh_scm2newstr(gh_car(list),NULL);
|
||||
|
|
|
@ -498,16 +498,16 @@ local SCM CclUnit(SCM list)
|
|||
unit->Frame=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("flipped-frame")) ) {
|
||||
unit->Frame=128|gh_scm2int(gh_car(list));
|
||||
unit->Frame=-gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("seen")) ) {
|
||||
unit->SeenFrame=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("flipped-seen")) ) {
|
||||
unit->SeenFrame=128|gh_scm2int(gh_car(list));
|
||||
unit->SeenFrame=-gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("not-seen")) ) {
|
||||
unit->SeenFrame=-1;
|
||||
unit->SeenFrame=UnitNotSeen;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("direction")) ) {
|
||||
unit->Direction=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
|
|
|
@ -84,11 +84,12 @@ local SCM CclDefineUnitType(SCM list)
|
|||
if( type ) {
|
||||
DebugLevel0Fn("Redefining unit-type `%s'\n" _C_ str);
|
||||
free(str);
|
||||
// FIXME: loose memory, old content isn't freed.
|
||||
// FIXME: lose memory, old content isn't freed.
|
||||
} else {
|
||||
type=NewUnitTypeSlot(str);
|
||||
}
|
||||
|
||||
type->NumDirections=8;
|
||||
//
|
||||
// Parse the list: (still everything could be changed!)
|
||||
//
|
||||
|
@ -189,6 +190,9 @@ local SCM CclDefineUnitType(SCM list)
|
|||
list=gh_cdr(list);
|
||||
type->BoxWidth=gh_scm2int(gh_car(sublist));
|
||||
type->BoxHeight=gh_scm2int(gh_cadr(sublist));
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("num-directions")) ) {
|
||||
type->NumDirections=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("sight-range")) ) {
|
||||
type->_SightRange=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
|
|
|
@ -266,7 +266,7 @@ global void InitUnit(Unit* unit, UnitType* type)
|
|||
// Initialise unit structure (must be zero filled!)
|
||||
//
|
||||
unit->Type = type;
|
||||
unit->SeenFrame = 0xFF; // Unit isn't yet seen
|
||||
unit->SeenFrame = UnitNotSeen; // Unit isn't yet seen
|
||||
|
||||
// FIXME: this is not needed for load+save, must move to other place
|
||||
if (1) { // Call CCL for name generation
|
||||
|
@ -543,7 +543,7 @@ global Unit* MakeUnitAndPlace(int x,int y,UnitType* type,Player* player)
|
|||
// fancy buildings: mirror buildings (but shadows not correct)
|
||||
//
|
||||
if ( FancyBuildings && unit->Rs > 50 ) {
|
||||
unit->Frame |= 128;
|
||||
unit->Frame = -unit->Frame;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ global int UnitKnownOnMap(const Unit* unit)
|
|||
for( ; h-->0; ) {
|
||||
for( w=w0; w-->0; ) {
|
||||
if( IsMapFieldVisible(x+w,y+h)
|
||||
|| (unit->Type->Building && unit->SeenFrame!=0xFF
|
||||
|| (unit->Type->Building && unit->SeenFrame!=UnitNotSeen
|
||||
&& IsMapFieldExplored(x+w,y+h)) ) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1131,7 +1131,7 @@ global int UnitVisibleInViewport (int v, const Unit* unit)
|
|||
for( ; h-->0; ) {
|
||||
for( w=w0; w-->0; ) {
|
||||
if( IsMapFieldVisible(x+w,y+h)
|
||||
|| (unit->Type->Building && unit->SeenFrame!=0xFF
|
||||
|| (unit->Type->Building && unit->SeenFrame!=UnitNotSeen
|
||||
&& IsMapFieldExplored(x+w,y+h)) ) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1210,7 +1210,7 @@ global int UnitVisibleOnScreen(const Unit* unit)
|
|||
for( ; h-->0; ) {
|
||||
for( w=w0; w-->0; ) {
|
||||
if( IsMapFieldVisible(x+w,y+h)
|
||||
|| (unit->Type->Building && unit->SeenFrame!=0xFF
|
||||
|| (unit->Type->Building && unit->SeenFrame!=UnitNotSeen
|
||||
&& IsMapFieldExplored(x+w,y+h)) ) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1804,17 +1804,22 @@ global int DirectionToHeading(int delta_x,int delta_y)
|
|||
global void UnitUpdateHeading(Unit* unit)
|
||||
{
|
||||
int dir;
|
||||
int nextdir;
|
||||
|
||||
// FIXME: depends on the possible unit directions wc 8, sc 32
|
||||
unit->Frame&=127;
|
||||
unit->Frame/=5;
|
||||
unit->Frame*=5; // Remove heading, keep animation frame
|
||||
dir=((unit->Direction+NextDirection/2)&0xFF)/NextDirection;
|
||||
if( dir<=LookingS/NextDirection ) { // north->east->south
|
||||
if( unit->Frame<0 ) {
|
||||
unit->Frame=-unit->Frame;
|
||||
}
|
||||
unit->Frame/=unit->Type->NumDirections/2+1;
|
||||
unit->Frame*=unit->Type->NumDirections/2+1;
|
||||
// Remove heading, keep animation frame
|
||||
|
||||
nextdir=256/unit->Type->NumDirections;
|
||||
dir=((unit->Direction+nextdir/2)&0xFF)/nextdir;
|
||||
if( dir<=LookingS/nextdir ) { // north->east->south
|
||||
unit->Frame+=dir;
|
||||
} else {
|
||||
// Note: 128 is the flag for flip graphic in X.
|
||||
unit->Frame+=128+256/NextDirection-dir;
|
||||
unit->Frame+=256/nextdir-dir;
|
||||
unit->Frame=-unit->Frame;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3856,10 +3861,10 @@ global void SaveUnit(const Unit* unit,FILE* file)
|
|||
#endif
|
||||
fprintf(file,"'pixel '(%d %d) ",unit->IX,unit->IY);
|
||||
fprintf(file,"'%sframe %d ",
|
||||
unit->Frame&128 ? "flipped-" : "" ,unit->Frame&127);
|
||||
if( unit->SeenFrame!=0xFF ) {
|
||||
unit->Frame<0 ? "flipped-" : "" ,unit->Frame<0?-unit->Frame:unit->Frame);
|
||||
if( unit->SeenFrame!=UnitNotSeen ) {
|
||||
fprintf(file,"'%sseen %d ",
|
||||
unit->SeenFrame&128 ? "flipped-" : "" ,unit->SeenFrame&127);
|
||||
unit->SeenFrame<0 ? "flipped-" : "" ,unit->SeenFrame<0?-unit->SeenFrame:unit->SeenFrame);
|
||||
} else {
|
||||
fprintf(file,"'not-seen ");
|
||||
}
|
||||
|
|
|
@ -1646,7 +1646,7 @@ local void DrawBuilding(Unit* unit)
|
|||
frame = unit->SeenFrame = unit->Frame;
|
||||
} else {
|
||||
frame = unit->SeenFrame;
|
||||
DebugCheck( frame==-1 || frame==0xFF );
|
||||
DebugCheck( frame==UnitNotSeen );
|
||||
}
|
||||
|
||||
type=unit->Type;
|
||||
|
@ -1678,7 +1678,7 @@ local void DrawBuilding(Unit* unit)
|
|||
} else if( unit->Orders[0].Action==UnitActionUpgradeTo ) {
|
||||
// FIXME: this frame is hardcoded!!!
|
||||
GraphicUnitPixels(unit,unit->Orders[0].Type->Sprite);
|
||||
DrawUnitType(unit->Orders[0].Type,(frame&128)+1,x,y);
|
||||
DrawUnitType(unit->Orders[0].Type,frame<0?-1:1,x,y);
|
||||
} else {
|
||||
GraphicUnitPixels(unit,type->Sprite);
|
||||
DrawUnitType(type,frame,x,y);
|
||||
|
|
|
@ -1070,15 +1070,15 @@ global UnitType* NewUnitTypeSlot(char* ident)
|
|||
** @todo Do screen position caculation in high level.
|
||||
** Better way to handle in x mirrored sprites.
|
||||
*/
|
||||
global void DrawUnitType(const UnitType* type,unsigned frame,int x,int y)
|
||||
global void DrawUnitType(const UnitType* type,int frame,int x,int y)
|
||||
{
|
||||
// FIXME: move this calculation to high level.
|
||||
x-=(type->Width-type->TileWidth*TileSizeX)/2;
|
||||
y-=(type->Height-type->TileHeight*TileSizeY)/2;
|
||||
|
||||
// FIXME: This is a hack for mirrored sprites
|
||||
if( frame&128 ) {
|
||||
VideoDrawClipX(type->Sprite,frame&127,x,y);
|
||||
if( frame<0 ) {
|
||||
VideoDrawClipX(type->Sprite,-frame,x,y);
|
||||
} else {
|
||||
VideoDrawClip(type->Sprite,frame,x,y);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue