📄 battle.cpp
字号:
//
// 执行战斗
//
// Copyright (c) 2000-2001 Chihiro.SAKAMOTO (HyperWorks)
//
#include "stdafx.h"
#include <stdlib.h>
#include "MainWin.h"
#include "File.h"
#include "Misc.h"
#include "Battle.h"
#include "Lexer.h"
#include "less.h"
//
// 构造函数
//
CBattleAction::CBattleAction(CMainWin *win, CAction *oldAction):
CAction(win, oldAction), _map_data(0), map_data(0),
ViewImage(win->GetViewImage()),
MixedImage(win->GetMixedImage()),
BackLayer(win->GetBackLayer())
{
status = STATUS_NONE;
turn = PLAYER_TURN;
// 角色信息的显示
for (int i=0; i<MAX_CHARACTER; i++) {
StatusCharacter[i] = 0;
}
// 事前字型的产生
hFont = CreateFont(-16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "冼极");
}
//
// 析构函数
//
CBattleAction::~CBattleAction()
{
DeleteObject(hFont);
delete _map_data;
delete map_data;
}
//
// 暂停
//
void CBattleAction::Pause()
{
}
//
// 暂停解除
//
void CBattleAction::Resume()
{
}
//
// 按下鼠标左键时执行的处理
//
void CBattleAction::LButtonDown(UINT modKeys, CPoint point)
{
// 只有轮到的游戏角色才有的鼠标按钮反应
if (turn == PLAYER_TURN) {
CPoint pos = PointToIndex(point); // 需要地图座标
switch (status) {
case STATUS_NONE:
// 选取游戏角色
if (MapRect.PtInRect(pos) && map_data[pos.y][pos.x].type & PLAYER) {
SelPos = pos;
SelChar = (CCharacter *)map_data[SelPos.y][SelPos.x].sprite;
ShowCommand(point);
}
break;
case STATUS_COMMAND:
SelectCommand(point);
break;
case STATUS_MOVE:
// 点选时的移动范围
if (MapRect.PtInRect(pos) && map_data[pos.y][pos.x].type & MOVEDIST) {
MovePlayer(SelChar, pos);
SelChar->move_done = true;
}
break;
case STATUS_ATTACK:
// 已点选攻击目标
if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | ENEMY)) == (ATTACKDIST | ENEMY)) {
Attack(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
SelChar->attack_done = true;
}
break;
case STATUS_MAGIC_ENEMY:
// 点选时的魔法范围
if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | ENEMY)) == (ATTACKDIST | ENEMY)) {
Magic(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
SelChar->attack_done = true;
}
break;
case STATUS_MAGIC_PLAYER:
// 点选时的魔法范围
if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | PLAYER)) == (ATTACKDIST | PLAYER)) {
Magic(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
SelChar->attack_done = true;
}
break;
case STATUS_ANIME:
break;
case STATUS_NEXTTURN:
// 点选Turn End(轮完)结束
if (TurnEndSprite.PtIn(point)) {
status = STATUS_NONE;
HideTurnEnd();
ChangeTurn(ENEMY_TURN);
}
break;
}
}
}
//
// 按下鼠标右键时执行的处理
//
void CBattleAction::RButtonDown(UINT modKeys, CPoint point)
{
// 按下右键传回的动作
if (turn == PLAYER_TURN) {
switch (status) {
case STATUS_NONE: // 若没有选取任何东西时
status = STATUS_NEXTTURN; // 显示“下一轮”(NEXT TURN)
ShowTurnEnd(point);
break;
case STATUS_COMMAND: // 若选取了指令时
status = STATUS_NONE; // 设定状态为“无”
HideCommand();
break;
case STATUS_MOVE: // 移动
case STATUS_ATTACK: // 攻击范围
case STATUS_MAGIC_ENEMY: // 魔法范围
case STATUS_MAGIC_PLAYER: // 当指定角色
status = STATUS_NONE; // 指定回“无”的状态
ClearDistCursor();
break;
case STATUS_NEXTTURN: // 若是下一轮(Next turn)时
status = STATUS_NONE; // 指定回“无”的状态
HideTurnEnd();
break;
}
}
}
//
// 移动鼠标时的处理
//
void CBattleAction::MouseMove(UINT modKeys, CPoint point)
{
if (turn == PLAYER_TURN) {
switch (status) {
case STATUS_NONE: // 初始状态
case STATUS_MOVE: // 显示移动范围
case STATUS_ATTACK: // 显示攻击范围
case STATUS_MAGIC_ENEMY: // 显示魔法范围
case STATUS_MAGIC_PLAYER: // 显示魔法范围
SetCursor(PointToIndex(point));
break;
case STATUS_COMMAND: // 显示指令菜单
HighlightCommand(point);
break;
case STATUS_NEXTTURN: // 显示下一轮指令菜单
SelectTurnEnd(TurnEndSprite.PtIn(point)? true: false);
break;
}
}
}
//
// 按下键盘时的处理
//
void CBattleAction::KeyDown(UINT key)
{
}
//
// IDLE处理
//
BOOL CBattleAction::IdleAction()
{
if (turn == ENEMY_TURN) {
if (status != STATUS_ANIME) {
if (!enemy_ptr->move_done) { // 若尚未移动,则移动
MoveEnemy();
}
else if (!enemy_ptr->attack_done) { // 若尚未攻击,则攻击
AttackEnemy();
}
else {
if (status == STATUS_BATTLE_END) { // 结束
return FALSE;
}
else if (++enemy_ptr == enemy_list.end()) {
ChangeTurn(PLAYER_TURN);
}
}
}
return TRUE;
}
return FALSE;
}
//
// 计时器的处理
//
bool CBattleAction::TimedOut(int timerId)
{
switch (timerId) {
case TIMER_MOVE_ID: // 移动动画
{
ASSERT(status == STATUS_ANIME);
MoveAnime &ar = anime.front();
CCharacter *character = ar.character;
RemoveSprite(character);
character->MoveAnime(ar.action, ar.count);
AddSprite(character);
if (ar.count++ == 3) { // 4个模式后前进到下一格
anime.pop_front();
// 若不再登录,则结束动画
if (anime.size() == 0) {
CPoint pos = character->GetMapPoint();
map_data[pos.y][pos.x].type |= (turn == PLAYER_TURN)? PLAYER: ENEMY;
map_data[pos.y][pos.x].sprite = character;
status = STATUS_NONE;
return true;
}
}
}
break;
case TIMER_ATTACK_ID: // 峌攻击动画
ASSERT(status == STATUS_ANIME);
if (AttackAnimeCount < CCharacter::ATTACK_STEP) {
AttackFrom->AttackAnime(AttackAnimeCount++);
RedrawSprite(AttackFrom);
}
else if (AttackAnimeCount < CCharacter::ATTACK_STEP + CCharacter::HIT_STEP) {
AttackTo->HitAnime(AttackAnimeCount++ - CCharacter::ATTACK_STEP);
RedrawSprite(AttackTo);
}
else {
AttackFrom->NormalStatus();
AttackTo->NormalStatus();
RedrawSprite(AttackFrom);
RedrawSprite(AttackTo);
AttackPhase2();
return true;
}
break;
case TIMER_NUMBER_ID: // 破坏力动画
ASSERT(status == STATUS_ANIME);
if (AttackAnimeCount < 4) {
for (int i=0; i<NumberView; i++) {
Number[i].SetDrawPos(Number[i].GetDrawPos().x, Number[i].GetDrawPos().y - 1);
CRect rect;
Number[i].GetRect(&rect);
rect.bottom++;
UpdateRect(rect);
}
}
else if (AttackAnimeCount < 8) {
for (int i=0; i<NumberView; i++) {
Number[i].SetDrawPos(Number[i].GetDrawPos().x, Number[i].GetDrawPos().y + 1);
CRect rect;
Number[i].GetRect(&rect);
rect.top--;
UpdateRect(rect);
}
}
else {
int n = NumberView;
NumberView = 0;
for (int i=0; i<n; i++) {
RedrawSprite(Number + i);
}
AttackPhase3();
return true;
}
AttackAnimeCount++;
break;
case TIMER_MAGIC_ID: // 魔法动画
ASSERT(status == STATUS_ANIME);
switch (magic_param.id) {
case MAGIC_HEAL: // 恢复
return MagicHeal();
case MAGIC_FIREBALL: // Fire ball
return MagicFireBall();
}
}
return false;
}
//
// 擦入(Wipe)结束时的处理
//
void CBattleAction::WipeDone()
{
if (status == STATUS_WAIT_START) // 开始Wipe等待
status = STATUS_NONE;
}
//
// Wave播放结束时的处理
//
void CBattleAction::WaveDone()
{
}
//
// 结束执行
//
void CBattleAction::Abort()
{
}
//
// 输出错误事件
//
void __cdecl CBattleAction::Error(TextReader &reader, const char *fmt, ...)
{
va_list args;
char str[256];
int len = sprintf(str, "%s:%d ", reader.GetFileName(), reader.GetLineNo());
va_start(args, fmt);
_vsnprintf(str + len, sizeof(str) - len, fmt, args);
va_end(args);
Parent->MessageBox(str);
}
// player
bool CBattleAction::PlayerCmd(TextReader &reader, Lexer &lexer)
{
int number;
bool b = lexer.GetValue(&number);
const char *name = lexer.GetString();
const char *file = lexer.GetString();
if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
Error(reader, "文法错误");
return false;
}
CChip chip(name, file);
if (chip.image == 0) {
Error(reader, "无法读取CG资料");
return false;
}
chip_list.insert(pair<int, CChip>(PlayerNumber(number - 1), chip));
return true;
}
// enemy
bool CBattleAction::EnemyCmd(TextReader &reader, Lexer &lexer)
{
int number;
bool b = lexer.GetValue(&number);
const char *name = lexer.GetString();
const char *file = lexer.GetString();
if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
Error(reader, "文法错误");
return false;
}
CChip chip(name, file);
if (chip.image == 0) {
Error(reader, "无法读取CG资料");
return false;
}
chip_list.insert(pair<int, CChip>(EnemyNumber(number - 1), chip));
return true;
}
// object
bool CBattleAction::ObjectCmd(TextReader &reader, Lexer &lexer)
{
int number;
bool b = lexer.GetValue(&number);
const char *name = lexer.GetString();
const char *file = lexer.GetString();
if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
Error(reader, "文法错误");
return false;
}
CChip chip(name, file);
if (chip.image == 0) {
Error(reader, "无法读取CG资料");
return false;
}
chip_list.insert(pair<int, CChip>(ObjectNumber(number - 1), chip));
return true;
}
// mapsize
bool CBattleAction::MapSizeCmd(TextReader &reader, Lexer &lexer)
{
int width, height;
if (!lexer.GetValue(&width)
|| !lexer.GetValue(&height)
|| lexer.GetString() != 0) {
Error(reader, "文法错误");
return false;
}
MapSize.cx = width;
MapSize.cy = height;
MapRect.SetRect(0, 0, width, height);
// 保留map_data的空间
_map_data = new MapData[width * height];
map_data = new MapData *[height];
for (int i=0; i<height; i++) {
map_data[i] = _map_data + i * width;
}
return true;
}
// mapimage
bool CBattleAction::MapImageCmd(TextReader &reader, Lexer &lexer)
{
const char *name = lexer.GetString();
if (name == 0 || lexer.GetString() != 0) {
Error(reader, "文法错误");
return false;
}
if (!MapImage.LoadImage(name)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -