?? cell.cpp
字號:
// ============================================================================
// Cell implementation
//
// (c) 2003 Ken Reed
//
// This is free software. You can redistribute it and/or modify it under the
// terms of the GNU General Public License version 2 as published by the Free
// Software Foundation.
// ============================================================================
#include "stdafx.h"
#include "cell.h"
#include "brush.h"
#include "pen.h"
#include "universal.h"
#include "socket.h"
#include <fstream>
#include <assert.h>
#include <math.h>
#include <sstream>
#include <cmath>
using namespace std;
struct CellBuffer {
int sync;
int i, j, player, type;
double troops, elevation, strength;
POINT position;
bool vector[6];
};
class spoint { // Signed version of POINT
public: // that can be statically
int x; // initialised
int y;
};
namespace {
const int c = cell_size; // Abbreviations for data
const int h = half_cell_size; // initialisation
const int q = quarter_cell_size;
const int t = cell_size - q;
const double deg_to_rad = 3.1415925 / 180;
// The x coordinate for a movement vector that isn't straight up or down
// is 3/8th of the cell size.
const int m = q + (q / 2);
POINT hexagon[] = {q,0, t,0, c,h, t,c, q,c, 0,h, q,0};
spoint offset[6] = {m,q, 0,h, -m,q, -m,-q, 0,-h, m,-q};
spoint unitvec[6] = {1,1, 0,1, -1,1, -1,-1, 0,-1, 1,-1};
COLORREF colours[max_players] = {RGB(255, 50, 50), RGB(255, 50, 255),
RGB(255, 255, 255), RGB(255, 255, 0),
RGB(100, 255, 100), RGB(150, 150, 255)
};
const int num_points (sizeof(hexagon) / sizeof(POINT));
}
// ============================================================================
// Reset a cell to its default state
// ============================================================================
void Cell::reset(bool exploring)
{
changed = false;
elevation = 0;
explored = ! exploring;
march = false;
scanned = false;
player = -1;
troops = 0;
type = Empty;
strength = 0;
for (int i = 0; i < 6; i++) {
vector[i] = false;
}
}
// ============================================================================
// Construction
// ============================================================================
Cell::Cell()
{
reset(true);
}
// ============================================================================
// Draw a circle
// ============================================================================
static void circle(HDC hdc, POINT center, int diameter)
{
int x = center.x - (diameter / 2);
int y = center.y - (diameter / 2);
Ellipse(hdc, x, y, x + diameter, y + diameter);
}
// ============================================================================
// Draw a cell
// ============================================================================
void Cell::draw_cell(HDC hdc, bool hide_vectors, int client)
{
POINT points[num_points];
COLORREF cell_colour;
// The cell background colour depends on its elevation. Sea-level is green
// and the colour shifts to brown with increasing altitude. Shades of blue
// are used for negative altitudes (sea).
int hue (225);
double adjustment (abs((double) hue * (elevation / max_elevation)));
if (elevation < 0) {
cell_colour = RGB(0, 0, hue - (adjustment * 0.7));
}
else {
cell_colour = RGB(adjustment * 0.5, hue - (adjustment * 0.7), 0);
}
if (explored == false) {
cell_colour = RGB(128, 128, 128);
}
Brush cell_brush(hdc, cell_colour);
int i;
for (i = 0; i < num_points; i++) {
points[i].x = hexagon[i].x + position.x;
points[i].y = hexagon[i].y + position.y;
}
Polygon(hdc, points, num_points);
if (explored == false) return;
POINT centre = get_centre();
COLORREF player_colour(colours[player]);
Pen troop_pen(hdc, player_colour, 1);
Brush troop_brush(hdc, player_colour);
int circle_size(0);
int scale(1);
// If there are troops in this cell draw a solid circle of a representative
// size.
if (troops > 0.0) {
circle_size = (int) (((double) cell_size-8) * (troops / max_troops));
circle_size |= 1;
circle(hdc, centre, circle_size);
}
else {
scale = 2;
}
// Draw movement vectors in the player's colour. If the cell is empty,
// vectors are drawn half size. For readability, draw the bit of the
// movement vector that is inside the troop circle in black.
double theta(30);
double radius(circle_size / 2);
if ((player == client) || !hide_vectors || (troops > 0)) {
for (i = 0; i < 6; i++) {
if (vector[i]) {
int x = centre.x + (offset[i].x / scale);
int y = centre.y + (offset[i].y / scale);
Pen troop_pen(hdc, player_colour, 3);
MoveToEx(hdc, centre.x, centre.y, 0);
LineTo(hdc, x, y);
if (circle_size > 2) {
int xo = (int)(radius * cos(theta * deg_to_rad));
int yo = (int)(radius * sin(theta * deg_to_rad));
xo += centre.x;
yo += centre.y;
Pen black_pen(hdc, RGB(0, 0, 0), 1);
MoveToEx(hdc, centre.x, centre.y, 0);
LineTo(hdc, xo, yo);
}
}
theta += 60;
}
}
HBRUSH null_brush = static_cast<HBRUSH>(GetStockObject(HOLLOW_BRUSH));
SelectObject(hdc, null_brush);
// Draw a circle to indicate the strength of this base
if (type == Base) {
Pen pen(hdc, RGB(0,0,0), 2);
double size(cell_size - 3);
size *= strength / 100.0;
circle(hdc, centre, size);
}
}
// ============================================================================
// Draw this cell
// ============================================================================
void Cell::draw(HWND window, bool hide_vectors, int client)
{
HDC hdc (GetDC(window));
assert(hdc != 0);
HBRUSH old_brush = static_cast<HBRUSH>(GetCurrentObject(hdc, OBJ_BRUSH));
HPEN old_pen = static_cast<HPEN> (GetCurrentObject(hdc, OBJ_PEN));
draw_cell(hdc, hide_vectors, client);
SelectObject(hdc, old_brush);
SelectObject(hdc, old_pen);
ReleaseDC(window, hdc);
}
// ============================================================================
// Update this cell
// ============================================================================
void Cell::update(double elapsed)
{
if ((type == Base) && (troops < max_troops)) {
troops += (growth_rate * (strength / 100)) * elapsed;
if (troops > max_troops) troops = max_troops;
changed = true;
}
}
// ============================================================================
// Put a cell into march mode
// ============================================================================
void Cell::set_march(Point position)
{
clear_vector(all_vectors);
int side (which_side(position));
if (side == -1) {
return;
}
march_vector = side;
march = true;;
march_timer = 0;
}
// ============================================================================
// Toggle a movement vector
// ============================================================================
void Cell::toggle_vector(Point position)
{
march = false;
int side (which_side(position));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -