/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* 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, see .
*
*/
//Filename : OSPRITE.H
//Description : Sprite object
#ifndef __OSPRITE_H
#define __OSPRITE_H
#ifndef __ODYNARRB_H
#include
#endif
#ifndef __OSPRTRES_H
#include
#endif
#ifndef __OWORLD_H
#include
#endif
//---------- Define action types ---------//
enum { SPRITE_IDLE=1,
SPRITE_READY_TO_MOVE,
SPRITE_MOVE,
SPRITE_WAIT, // During a movement course, waiting for blocked sprites to pass
SPRITE_ATTACK,
SPRITE_TURN,
SPRITE_SHIP_EXTRA_MOVE, // for ship only
SPRITE_DIE,
};
//----------- Define constant ----------//
#define GUARD_COUNT_MAX 5
//---------- Define class Sprite -----------//
#pragma pack(1)
class Sprite
{
public:
//------------------------------------------//
short sprite_id; // sprite id. in SpriteRes
short sprite_recno;
char mobile_type;
UCHAR cur_action; // current action
UCHAR cur_dir; // current direction
UCHAR cur_frame; // current frame
UCHAR cur_attack; // current attack mode
UCHAR final_dir; // for turning dir before attacking or moving
char turn_delay; // value between -60 and 60
char guard_count; // shield guarding, affecting move/stop frame
// 0=not guarding, count up from 1 when guarding, reset to 0 after guard
UCHAR remain_attack_delay; // no. of frames has to be delayed before the next attack motion
UCHAR remain_frames_per_step; // no. of frames remained in this step
short cur_x , cur_y; // current location
short go_x , go_y; // the destination of the path
short next_x, next_y; // next tile in the moving path
//----- clone vars from sprite_res for fast access -----//
SpriteInfo* sprite_info;
//--------- static member vars --------------//
static short view_top_x, view_top_y; // the view window in the scene, they are relative coordinations on the entire virtual surface.
//---------- function member vars -------------//
short cur_x_loc() { return cur_x>>ZOOM_X_SHIFT_COUNT; } // >>5 = divided by 32, which is ZOOM_LOC_WIDTH & ZOOM_LOC_HEIGHT
short cur_y_loc() { return cur_y>>ZOOM_Y_SHIFT_COUNT; }
short next_x_loc() { return next_x>>ZOOM_X_SHIFT_COUNT; } // >>5 = divided by 32, which is ZOOM_LOC_WIDTH & ZOOM_LOC_HEIGHT
short next_y_loc() { return next_y>>ZOOM_Y_SHIFT_COUNT; }
short go_x_loc() { return go_x>>ZOOM_X_SHIFT_COUNT; }
short go_y_loc() { return go_y>>ZOOM_Y_SHIFT_COUNT; }
SpriteMove* cur_sprite_move() { return sprite_info->move_array+cur_dir; }
SpriteAttack* cur_sprite_attack() { return sprite_info->attack_array[cur_attack]+cur_dir; }
SpriteStop* cur_sprite_stop() { return sprite_info->stop_array+cur_dir; }
SpriteDie* cur_sprite_die() { return &(sprite_info->die); }
SpriteFrame* cur_sprite_frame(int *needMirror=0);
//----------- static variables -------------//
static short abs_x1, abs_y1; // the absolute postion, taking in account of sprite offset
static short abs_x2, abs_y2;
public:
Sprite();
virtual ~Sprite();
void init(short spriteId, short startX, short startY);
void deinit();
virtual void draw();
void sprite_move(int desX, int desY);
void set_cur(int curX, int curY) { cur_x=curX; cur_y=curY; update_abs_pos(); }
virtual void set_next(int nextX, int nextY, int para=0, int blockedChecked=0);
int move_step_magn();
virtual void pre_process() {;}
virtual void process_idle();
virtual void process_move();
virtual void process_wait() {;}
virtual int process_attack();
virtual int process_die();
void process_turn();
virtual void process_extra_move() {;} // for ship only
void set_dir(int curX, int curY, int destX, int destY);
void set_dir(UCHAR newDir); // overloading function
int get_dir(int curX, int curY, int destX, int destY);
int is_dir_correct();
int match_dir();
void set_remain_attack_delay();
virtual void update_abs_pos(SpriteFrame* =0);
UCHAR display_dir();
int need_mirror(UCHAR dispDir);
void set_guard_on();
void set_guard_off();
int is_guarding() { return guard_count > 0; }
virtual int is_shealth();
//-------------- multiplayer checking codes ---------------//
virtual UCHAR crc8();
virtual void clear_ptr();
};
#pragma pack()
//------- Define class SpriteArray ---------//
class SpriteArray : public DynArrayB
{
public:
short restart_recno; // indicate the unit's sprite_recno to process first in next process_cycle
SpriteArray(int initArraySize);
~SpriteArray();
void init();
void deinit();
void add(Sprite*);
void add_sorted(Sprite*);
void del(int);
virtual void die(int spriteRecno) { del(spriteRecno); }
virtual void process();
#ifdef DEBUG
Sprite* operator[](int recNo);
#else
Sprite* operator[](int recNo) { return (Sprite*) get_ptr(recNo); }
#endif
int is_deleted(int recNo) { return get_ptr(recNo) == NULL; }
};
//------------------------------------------//
extern unsigned long last_unit_ai_profile_time;
extern unsigned long unit_ai_profile_time;
extern unsigned long last_unit_profile_time;
extern unsigned long unit_profile_time;
extern unsigned long last_sprite_array_profile_time;
extern unsigned long sprite_array_profile_time;
extern unsigned long last_sprite_idle_profile_time;
extern unsigned long sprite_idle_profile_time;
extern unsigned long last_sprite_move_profile_time;
extern unsigned long sprite_move_profile_time;
extern unsigned long last_sprite_wait_profile_time;
extern unsigned long sprite_wait_profile_time;
extern unsigned long last_sprite_attack_profile_time;
extern unsigned long sprite_attack_profile_time;
extern unsigned long last_unit_attack_profile_time;
extern unsigned long unit_attack_profile_time;
extern unsigned long last_unit_assign_profile_time;
extern unsigned long unit_assign_profile_time;
#endif