[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[glob2-devel] patch with improvements: brushes (6), fix AI cheating (2),
From: |
Joe Wells |
Subject: |
[glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7) |
Date: |
Mon, 30 Apr 2007 02:09:15 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) |
Dear Globulation 2 gurus,
Attached is a patch to the source code of glob2 version 0.8.23 that
has a number of improvements, described below. Also attached are some
image files that go with one of the changes.
Please don't worry about the indentation and line breaks. That can be
easily changed. Please just look at the coding ideas for now.
I'm sorry that I'm putting these changes all in one message. If I
delayed until I had time to describe them all separately, I would
probably never have time to send them, so I think it is better that I
show them to you now.
The coding of some of the changes is not perfect. Generally, when
this has happened, it is because I was following the style of code
already in glob2. (An example is the way the code everywhere knows
that the size of the myUnits array is 1024. ☹)
If you don't like how I have done things, I _might_ have time to redo
some of them differently. Just ask.
I hope you find this contribution useful.
Joe
----------------------------------------------------------------------
The changes are as follows:
1. Changes in the effect of area brushes:
A. This patch changes the shapes of the 3rd and 4th brushes to:
X X
X and X
X X
I never used the previous shapes of the 3rd and 4th brushes, but
I now use the new shapes all the time for farming.
(The .png images used for the button to select these shapes have
not been updated and still show the old shapes. It would be
nice if these were calculated at game startup instead of being
static .png files.)
B. This patch changes things so that when drawing areas with a
brush of size 1 by 1 (there is only one such brush), if an
attempt is made to use the brush which would have no effect, we
first toggle the state of whether we are adding or removing the
area, so the use of the brush will have an effect. This allows
quickly repairing errors without having to explicitly change the
mode by hand. We don't do this when dragging, so only explicit
mouse clicks can change the mode.
C. This patch fixes bugs in drawing areas while dragging. It is
now far more likely that if you quickly draw a path with the
mouse that all of the map cells the mouse goes through will be
correctly handled. Two separate changes needed to be made.
First, it was necessary to stop discarding as many mouse motion
events (but only when dragging). Second, it was necessary to
change to using the mouse position and button state at the time
of each event rather than using SDL_GetMouseState (which can
return the mouse position and button state after many events
that have not yet been processed).
(If SDL doesn't supply enough mouse motion events, then it is
still possible to skip over some cells, even after this patch.
This potential problem seems not to happen in practice.)
2. Changes to the visual appearance of area brushes:
A. This patch makes the area brushes show the exact cells that will
be turned on or off, instead of just a square or circle. (This
change is needed by the new brush shapes.)
B. This patch draws the area brush in a color (red, blue, or
yellow) corresponding to the kind of area (forbidden, guard, or
clearing) that is being added or removed. The actual colors
that are used were obtained by inspecting the .png files for the
area animations.
C. The area brushes were dimmer to indicate area removal. However,
the brushes for removal were still bright enough that it was
hard to notice the difference. (I never realized there was a
difference until I saw the code.) This patch makes them even
more dim, so that the difference is more likely to be noticed.
3. Changes to AI behavior:
A. There was code in AIEcho.cpp that allows AIs to cheat by telling
them where each player's starting buildings are located. This
allows AIs to launch attacks with war flags against enemies they
have never even seen. This patch disables this “feature”.
B. This patch adds code to ensure that Nicowar does not commit to
defeating a particular enemy until it has seen at least one
building of that enemy. (This is a necessary adjustment to the
removal of the feature that the AIs know the location of all
other players' starting buildings.)
4. Changes to explorer behavior:
A. This patch greatly increases the likelihood that explorers will
explore unknown areas on large maps. Explorers now effectively
explore 128 by 128 and 256 by 256 maps. (This has not been
tested on 512 by 512 maps, due to the memory use bug since glob2
version 0.8.22 (bug #19601).)
B. This patch makes explorers prefer to try to heal immediately
after feeding and to feed immediately after healing. This is
necessary for explorers to have enough range to explore large
maps.
C. This patch works around the problem where exploredArea is not
included in saved games by assuming on game reloading that all
discovered cells are explored. (This avoids all explorers going
completely haywire when saving and reloading a game.)
D. This patch improves decisions about whether a direction is
diagonal or not which affect explorer behavior.
4. Other changes to visual displays:
A. The units working for a building are always shown with white
circles while the building is selected, instead of just when the
mouse button is held down.
B. This patch reduces the amount of dimness from the fog of war,
because the old amount of dimness made it painful to view the
screen. The .png files used for the borders of the fog of war
have been correspondingly adjusted.
C. This patch reduces the amount of screen dimming due to pausing
the game.
5. Other changes to user interface controls:
A. This patch adds new keyboard commands for selecting all of the
building construction tools, the flag tools, and the area tools,
and for setting the area adding/removing mode, and for setting
the area brush. These commands can be bound to any of the keys
from “a” to “z”. Also, there are 3 prefix commands which group
together all of the building tools, the flag tools, and the area
tools. For example, if you bind the prefix command for
buildings to “b”, then “b” followed by “i” selects the “inn”
tool. You can also bind “i” directly to the command for
selecting the “inn” tool if you want. The default binding of
the prefix command for area tools is “a”, for building tools is
“b”, and for flag tools is “f”. (The default for the team
marking command (which shows the team numbers for each globule)
has been moved from “a” to “h”.)
(The language translations of the new commands have not yet been
added (not even English).)
B. This patch enables holding the Control key while pressing the
arrow keys to move the viewport by half-screens instead of by
single cells. At the same time, some bugs are solved where
window manager controls involving arrow keys and other modifiers
could sometimes accidentally be interpreted by glob2.
C. This patch enables using the Tab key to cycle through all of
your globules of a given kind (worker, explorer, or warrior).
(This was vital for debugging explorer behavior.)
D. This patch allows the user to require the Control key to be held
down before the scrollwheel changes the number of requested
workers. This solves a problem (bug #19600) where the number of
workers keeps getting accidentally messed up. (With this patch,
the user requests this by setting the GLOB2_NO_RAW_MOUSEWHEEL
environment variable; this should be done with a user option
instead.)
6. Various new methods are added to support the changes
(BrushTool::setFigure, BrushTool::setType,
GameGUI::isBuildingEnabled, GameGUI::isFlagEnabled).
diff -ru ../../glob-virgin/glob2-0.8.23/src/AIEcho.cpp ./AIEcho.cpp
--- ../../glob-virgin/glob2-0.8.23/src/AIEcho.cpp 2007-04-15
02:02:38.000000000 +0100
+++ ./AIEcho.cpp 2007-04-22 20:01:31.000000000 +0100
@@ -4217,7 +4217,10 @@
Building*
b=echo->player->game->teams[team]->myBuildings[current_index];
if(b)
{
- if( (b->seenByMask&echo->player->team->me ||
echo->get_starting_buildings().find(b->gid)!=echo->get_starting_buildings().end())
&&
+ if( (b->seenByMask&echo->player->team->me
+ // Don't allow AIs to cheat!!!!!!
+ // ||
echo->get_starting_buildings().find(b->gid)!=echo->get_starting_buildings().end()
+ ) &&
(building_type==-1 ||
b->type->shortTypeNum==building_type) &&
(level==-1 || b->type->level==(level-1)))
{
diff -ru ../../glob-virgin/glob2-0.8.23/src/AINicowar.cpp ./AINicowar.cpp
--- ../../glob-virgin/glob2-0.8.23/src/AINicowar.cpp 2007-04-15
00:36:21.000000000 +0100
+++ ./AINicowar.cpp 2007-04-22 21:15:55.000000000 +0100
@@ -1200,7 +1200,17 @@
{
if(echo.player->game->teams[*i]->isAlive)
{
+ enemy_building_iterator ebi(echo, *i, -1, -1,
indeterminate);
+ /* Make sure we know of at least one
+ building before committing to a
+ particular enemy. It used to be that we
+ did not (normally) need to test this,
+ because all starting buildings were
+ known. But that was cheating and has
+ been fixed. */
+ if (ebi != enemy_building_iterator()) {
available_targets.push_back(*i);
+ }
}
}
if(available_targets.size()==0)
diff -ru ../../glob-virgin/glob2-0.8.23/src/Brush.cpp ./Brush.cpp
--- ../../glob-virgin/glob2-0.8.23/src/Brush.cpp 2007-04-17
22:48:06.000000000 +0100
+++ ./Brush.cpp 2007-04-29 19:34:56.000000000 +0100
@@ -63,8 +63,35 @@
void BrushTool::drawBrush(int x, int y, bool onlines)
{
+ /* We use 2/3 intensity to indicate removing areas. This was
+ formerly 78% intensity, which was bright enough that it was hard
+ to notice any difference, so the brightness has been lowered. */
+ int i = ((mode == MODE_ADD) ? 255 : 170);
+ drawBrush(x, y, Color(i,i,i), onlines);
+}
+
+void BrushTool::drawBrush(int x, int y, GAGCore::Color c, bool onlines)
+{
+ /* It violates good abstraction practices that Brush.cpp knows
+ this much about the visual layout of the GUI. */
x = ((x+(onlines ? 16 : 0)) & ~0x1f) + (!onlines ? 16 : 0);
y = ((y+(onlines ? 16 : 0)) & ~0x1f) + (!onlines ? 16 : 0);
+ int w = getBrushWidth(figure);
+ int h = getBrushHeight(figure);
+ /* Move x and y from center of focus point to upper left of
+ brush shape. */
+ const int cell_size = 32; // This file should not know this value!!!
+ x -= ((cell_size * getBrushDimX(figure)) + (cell_size / 2));
+ y -= ((cell_size * getBrushDimY(figure)) + (cell_size / 2));
+ const int inset = 2;
+ for (int cx = 0; cx < w; cx++) {
+ for (int cy = 0; cy < h; cy++) {
+ if (getBrushValue(figure, cx, cy)) {
+ globalContainer->gfx->drawRect(x + (cell_size * cx) + inset, y +
(cell_size * cy) + inset, cell_size - inset, cell_size - inset, c); }}}
+ /* The following code is the old way of doing things. It is
+ kept in case anyone wants to restore it, which might be
+ useful for some of the brush shapes. */
+ /*
if (figure < 4)
{
int r = (getBrushWidth(figure) + getBrushHeight(figure)) * 8;
@@ -82,20 +109,27 @@
else
globalContainer->gfx->drawRect(x-w, y-h, 2*w, 2*h, 200,
200, 200);
}
+ */
}
#define BRUSH_COUNT 8
+void BrushTool::setFigure(unsigned f)
+{
+ assert (figure < BRUSH_COUNT);
+ figure = f;
+}
+
int BrushTool::getBrushWidth(unsigned figure)
{
- int dim[BRUSH_COUNT] = { 1, 3, 5, 7, 5, 5, 3, 5};
+ int dim[BRUSH_COUNT] = { 1, 3, 3, 3, 5, 5, 3, 5};
assert(figure < BRUSH_COUNT);
return dim[figure];
}
int BrushTool::getBrushHeight(unsigned figure)
{
- int dim[BRUSH_COUNT] = { 1, 3, 5, 7, 5, 5, 3, 5};
+ int dim[BRUSH_COUNT] = { 1, 3, 3, 3, 5, 5, 3, 5};
assert(figure < BRUSH_COUNT);
return dim[figure];
}
@@ -117,18 +151,12 @@
int brush1[] = { 0, 1, 0,
1, 1, 1,
0, 1, 0 };
- int brush2[] = { 0, 1, 1, 1, 0,
- 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 0 };
- int brush3[] = { 0, 0, 1, 1, 1, 0, 0,
- 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 0,
- 0, 0, 1, 1, 1, 0, 0 };
+ int brush2[] = { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1, };
+ int brush3[] = { 0, 0, 1,
+ 0, 1, 0,
+ 1, 0, 0, };
int brush4[] = { 1, 0, 1, 0, 1,
0, 1, 0, 1, 0,
1, 0, 1, 0, 1,
diff -ru ../../glob-virgin/glob2-0.8.23/src/Brush.h ./Brush.h
--- ../../glob-virgin/glob2-0.8.23/src/Brush.h 2007-04-17 22:48:06.000000000
+0100
+++ ./Brush.h 2007-04-29 05:08:36.000000000 +0100
@@ -21,6 +21,7 @@
#define __BRUSH_H
#include <vector>
+#include "GraphicContext.h" // just to get Color, really this should only be
in GameGUI
//! A click of the brush tool to the map
struct BrushApplication
@@ -59,10 +60,15 @@
//! Draw the actual brush (not the brush tool)
void drawBrush(int x, int y, bool onlines=false);
+ void drawBrush(int x, int y, GAGCore::Color c, bool onlines=false);
//! Return the mode of the brush
unsigned getType(void) { return static_cast<unsigned>(mode); }
+ //! Set the mode of the brush
+ void setType(Mode m) { mode = m; }
//! Return the id of the actual figure
unsigned getFigure(void) { return figure; }
+ //! Set the id of the actual figure
+ void setFigure(unsigned f);
//! Return the full width of a brush
static int getBrushWidth(unsigned figure);
diff -ru ../../glob-virgin/glob2-0.8.23/src/Game.cpp ./Game.cpp
--- ../../glob-virgin/glob2-0.8.23/src/Game.cpp 2007-04-17 22:48:06.000000000
+0100
+++ ./Game.cpp 2007-04-19 21:05:44.000000000 +0100
@@ -2385,7 +2385,7 @@
unsigned shadeValue = i0 + (i1<<1) +
(i2<<2) + (i3<<3);
if (shadeValue==15)
-
globalContainer->gfx->drawFilledRect((x<<5)+16, (y<<5)+16, 32, 32, 0, 0, 0,
127);
+
globalContainer->gfx->drawFilledRect((x<<5)+16, (y<<5)+16, 32, 32, 0, 0, 0, 40);
else if (shadeValue)
globalContainer->gfx->drawSprite((x<<5)+16, (y<<5)+16,
globalContainer->terrainShader, shadeValue);
}
diff -ru ../../glob-virgin/glob2-0.8.23/src/GameGUI.cpp ./GameGUI.cpp
--- ../../glob-virgin/glob2-0.8.23/src/GameGUI.cpp 2007-04-17
22:48:06.000000000 +0100
+++ ./GameGUI.cpp 2007-04-30 01:39:23.000000000 +0100
@@ -175,6 +175,8 @@
}
+bool noRawMousewheel = false;
+
void GameGUI::init()
{
notmenu = false;
@@ -199,7 +201,7 @@
highlightSelection = 0.0f;
miniMapPushed=false;
putMark=false;
- showUnitWorkingToBuilding=false;
+ showUnitWorkingToBuilding=true;
chatMask=0xFFFFFFFF;
hasSpaceBeenClicked=false;
swallowSpaceKey=false;
@@ -259,6 +261,9 @@
missionName="";
initUnitCount();
+
+ if (getenv ("GLOB2_NO_RAW_MOUSEWHEEL")) {
+ noRawMousewheel = true; }
}
void GameGUI::adjustLocalTeam()
@@ -323,7 +328,7 @@
}
}
-void GameGUI::brushStep(int mx, int my)
+void GameGUI::brushStep(bool maybeToggleMode, int mx, int my)
{
// if we have an area over 32x32, which mean over 128 bytes, send it
if (brushAccumulator.getAreaSurface() > 32*32)
@@ -334,6 +339,26 @@
int mapX, mapY;
game.map.displayToMapCaseAligned(mx, my, &mapX, &mapY, viewportX,
viewportY);
int fig = brush.getFigure();
+ /* We treat any brush of size 1 by 1 specially. If an attempt
+ is made to use the brush which would have no effect, we
+ first toggle the state of whether we are adding or removing
+ the area, so the use of the brush will have an effect.
+ This allows quickly repairing errors without having to
+ explicitly change the mode by hand. We don't do this when
+ dragging, so only explicit mouse clicks can change the
+ mode. */
+ if (maybeToggleMode && (brush.getBrushHeight(fig) == 1) &&
(brush.getBrushWidth(fig) == 1)) {
+ int isAlreadyOn =
+ ((brushType == FORBIDDEN_BRUSH) && game.map.isForbiddenLocal(mapX,
mapY))
+ || ((brushType == GUARD_AREA_BRUSH) &&
game.map.isGuardAreaLocal(mapX, mapY))
+ || ((brushType == CLEAR_AREA_BRUSH) &&
game.map.isClearAreaLocal(mapX, mapY));
+ unsigned mode = brush.getType();
+ if (((mode == BrushTool::MODE_ADD) && isAlreadyOn)
+ || ((mode == BrushTool::MODE_DEL) && !isAlreadyOn)) {
+ sendBrushOrders();
+ brush.setType((mode == BrushTool::MODE_ADD) ? BrushTool::MODE_DEL
: BrushTool::MODE_ADD);
+ brushStep(false, mx,my); // restart action after changing mode;
set maybeToggleMode to false to guarantee no further recursion
+ return; }}
brushAccumulator.applyBrush(&game.map, BrushApplication(mapX, mapY,
fig));
// we get coordinates
int startX = mapX-BrushTool::getBrushDimX(fig);
@@ -394,10 +419,18 @@
}
}
-void GameGUI::dragStep(void)
+void GameGUI::dragStep(int mx, int my, int button)
{
- int mx, my;
- Uint8 button = SDL_GetMouseState(&mx, &my);
+ /* We used to use SDL_GetMouseState, like the following
+ commented-out code, but that was buggy and prevented
+ dragging from correctly going through intermediate cells.
+ It is vital to use the mouse position and button status as
+ it was at the time in the middle of the event stream, not
+ as it is now. So instead we make sure the correct data is
+ passed to us as a parameter. */
+ // int mx, my;
+ // Uint8 button = SDL_GetMouseState(&mx, &my);
+ // fprintf (stderr, "enter dragStep: button: %d, mx: %d,
selectionMode: %d\n", button, mx, selectionMode);
if ((button&SDL_BUTTON(1)) && (mx<globalContainer->gfx->getW()-128))
{
// Update flag
@@ -410,24 +443,81 @@
// Update brush
else if (selectionMode==BRUSH_SELECTION)
{
- brushStep(mx, my);
+ brushStep(false, mx, my);
}
}
+ // fprintf (stderr, "exit dragStep\n");
}
+/* We need to keep track of the last recorded mouse position for use
+ in drag steps. We can't simply use SDL_GetMouseState to get this
+ information, because we need the information as it was in the
+ middle of the event stream. (There may be many later events we
+ have not yet processed.) */
+int lastMouseX = 0, lastMouseY = 0; // can't make these Uint16 because of
SDL_GetMouseState
+Uint16 lastMouseButtonState = 0;
+
void GameGUI::step(void)
{
SDL_Event event, mouseMotionEvent, windowEvent;
bool wasMouseMotion=false;
bool wasWindowEvent=false;
+ int oldMouseMapX = -1, oldMouseMapY = -1; // hopefully the values here
will never matter
// we get all pending events but for mousemotion we only keep the last
one
while (SDL_PollEvent(&event))
{
if (event.type==SDL_MOUSEMOTION)
{
+ lastMouseX = event.motion.x;
+ lastMouseY = event.motion.y;
+ lastMouseButtonState = event.motion.state;
+ int mouseMapX, mouseMapY;
+ bool onViewport = (lastMouseX <
globalContainer->gfx->getW()-128);
+ /* We keep track for each mouse motion event
+ of which map cell it corresponds to. When
+ dragging, we will use this to make sure we
+ process at least one event per map cell,
+ and only discard multiple events when they
+ are for the same map cell. This is
+ necessary to make dragging work correctly
+ when drawing areas with the brush. */
+ if (onViewport) {
+ game.map.cursorToBuildingPos (lastMouseX,
lastMouseY, 1, 1, &mouseMapX, &mouseMapY, viewportX, viewportY); }
+ else {
+ /* We interpret all locations outside the
+ viewport as being equivalent, and
+ distinct from any map location. */
+ mouseMapX = -1;
+ mouseMapY = -1; }
+ // fprintf (stderr, "mouse motion:
(lastMouseX,lastMouseY): (%d,%d), (mouseMapX,mouseMapY): (%d,%d),
(oldMouseMapX,oldMouseMapY): (%d,%d)\n", lastMouseX, lastMouseY, mouseMapX,
mouseMapY, oldMouseMapX, oldMouseMapY);
+ /* Make sure dragging does not skip over map cells by
+ processing the old stored event rather than throwing
+ it away. */
+ if (wasMouseMotion
+ && (lastMouseButtonState & SDL_BUTTON(1)) // are
we dragging? (should not be hard-coding this condition but should be abstract
somehow)
+ && ((mouseMapX != oldMouseMapX)
+ || (mouseMapY != oldMouseMapY))) {
+ // fprintf (stderr, "processing old event instead of
discarding it\n");
+ processEvent(&mouseMotionEvent); }
+ oldMouseMapX = mouseMapX;
+ oldMouseMapY = mouseMapY;
mouseMotionEvent=event;
wasMouseMotion=true;
}
+ else if ((event.type == SDL_MOUSEBUTTONDOWN) || (event.type ==
SDL_MOUSEBUTTONUP)) {
+ lastMouseButtonState = SDL_GetMouseState (&lastMouseX,
&lastMouseY);
+ /* We ignore what SDL_GetMouseState does to
+ lastMouseX and lastMouseY, because that may
+ reflect many subsequent events that we have not
+ yet processed. Technically, we shouldn't use
+ SDL_GetMouseState at all but should calculate the
+ button state by keeping track of what has
+ happened. However, I haven't had the programming
+ energy to do this, so I am cheating in the line
+ above. */
+ lastMouseX = event.button.x;
+ lastMouseY = event.button.y;
+ processEvent (&event); }
else if (event.type==SDL_ACTIVEEVENT)
{
windowEvent=event;
@@ -454,7 +544,7 @@
viewportY&=game.map.getMaskH();
if ((viewportX!=oldViewportX) || (viewportY!=oldViewportY))
- dragStep();
+ dragStep(lastMouseX, lastMouseY, lastMouseButtonState);
assert(localTeam);
if (localTeam->wasEvent(Team::UNIT_UNDER_ATTACK_EVENT))
@@ -994,9 +1084,11 @@
if
((selBuild->owner->teamNumber==localTeamNo) &&
(selBuild->buildingState==Building::ALIVE))
{
+ /* fprintf (stderr,
"s=SDL_GetModState(): %d, S=KMOD_SHIFT: %d, C=KMOD_CTRL: %d\n",
+ SDL_GetModState(),
KMOD_SHIFT, KMOD_CTRL); */
if
((selBuild->type->maxUnitWorking) &&
(selBuild->maxUnitWorkingLocal<MAX_UNIT_WORKING)&&
-
!(SDL_GetModState()&KMOD_SHIFT))
+ (noRawMousewheel ?
(SDL_GetModState() & KMOD_CTRL) : !(SDL_GetModState()&KMOD_SHIFT)))
{
int
nbReq=(selBuild->maxUnitWorkingLocal+=1);
orderQueue.push_back(new OrderModifyBuilding(selBuild->gid, nbReq));
@@ -1023,7 +1115,7 @@
{
if
((selBuild->type->maxUnitWorking) &&
(selBuild->maxUnitWorkingLocal>0)&&
-
!(SDL_GetModState()&KMOD_SHIFT))
+ (noRawMousewheel ?
(SDL_GetModState() & KMOD_CTRL) : !(SDL_GetModState()&KMOD_SHIFT)))
{
int
nbReq=(selBuild->maxUnitWorkingLocal-=1);
orderQueue.push_back(new OrderModifyBuilding(selBuild->gid, nbReq));
@@ -1060,7 +1152,7 @@
miniMapPushed=false;
selectionPushed=false;
panPushed=false;
- showUnitWorkingToBuilding=false;
+ // showUnitWorkingToBuilding=false;
}
}
@@ -1159,6 +1251,14 @@
}
}
+enum TwoKeyMode
+{
+ TWOKEY_NONE = 0,
+ TWOKEY_BUILDING = 1,
+ TWOKEY_FLAG = 2,
+ TWOKEY_AREA = 3,
+} twoKeyMode = TWOKEY_NONE;
+
void GameGUI::handleKey(SDLKey key, bool pressed, bool shift, bool ctrl)
{
int modifier;
@@ -1171,6 +1271,104 @@
if (typingInputScreen == NULL)
{
std::string action="";
+ // fprintf (stderr, "twoKeyMode: %d, key: %d\n", twoKeyMode,
key);
+ if (twoKeyMode != TWOKEY_NONE) {
+ if (pressed) {
+ switch (twoKeyMode) {
+ case TWOKEY_BUILDING:
+ switch (key) {
+ case SDLK_a: /* swArm */
+ action = "select make swarm tool";
+ break;
+ case SDLK_i: /* Inn */
+ action = "select make inn tool";
+ break;
+ case SDLK_h: /* Hospital */
+ action = "select make hospital tool";
+ break;
+ case SDLK_r: /* Racetrack */
+ action = "select make racetrack tool";
+ break;
+ case SDLK_p: /* swimming Pool */
+ action = "select make swimming pool tool";
+ break;
+ case SDLK_b: /* Barracks */
+ action = "select make barracks tool";
+ break;
+ case SDLK_s: /* School */
+ action = "select make school tool";
+ break;
+ case SDLK_d: /* Defense tower */
+ action = "select make defense tower tool";
+ break;
+ case SDLK_w: /* stone Wall */
+ action = "select make stone wall tool";
+ break;
+ case SDLK_m: /* Market */
+ action = "select make market tool";
+ break; }
+ break;
+ case TWOKEY_FLAG:
+ switch (key) {
+ case SDLK_e: /* Exploration */
+ action = "select make exploration flag tool";
+ break;
+ case SDLK_w: /* War */
+ action = "select make war flag tool";
+ break;
+ case SDLK_c: /* Clearing */
+ action = "select make clearing flag tool";
+ break; }
+ break;
+ case TWOKEY_AREA:
+ switch (key) {
+ case SDLK_f: /* Forbidden */
+ action = "select forbidden area tool";
+ break;
+ case SDLK_g: /* Guard */
+ action = "select guard area tool";
+ break;
+ case SDLK_c: /* Clearing */
+ action = "select clearing area tool";
+ break;
+ case SDLK_a: /* Add */
+ action = "switch to adding areas";
+ break;
+ case SDLK_d: /* Delete */
+ action = "switch to deleting areas";
+ break;
+ case SDLK_1:
+ action = "switch to area brush 1";
+ break;
+ case SDLK_2:
+ action = "switch to area brush 2";
+ break;
+ case SDLK_3:
+ action = "switch to area brush 3";
+ break;
+ case SDLK_4:
+ action = "switch to area brush 4";
+ break;
+ case SDLK_5:
+ action = "switch to area brush 5";
+ break;
+ case SDLK_6:
+ action = "switch to area brush 6";
+ break;
+ case SDLK_7:
+ action = "switch to area brush 7";
+ break;
+ case SDLK_8:
+ action = "switch to area brush 8";
+ break; }
+ break; }
+ key = SDLK_UNKNOWN;
+ twoKeyMode = TWOKEY_NONE; }
+ else {
+ /* this case happens when the initial prefix key is
released */
+ }}
+ // fprintf (stderr, "action: [%s]\n", action.c_str());
+
switch (key)
{
case SDLK_ESCAPE:
@@ -1464,6 +1662,130 @@
if (pressed)
orderQueue.push_back(new
PauseGameOrder(!gamePaused));
}
+ else if ((action == "prefix key select area tool") && pressed)
{
+ twoKeyMode = TWOKEY_AREA; }
+ else if ((action == "prefix key select building tool") &&
pressed) {
+ twoKeyMode = TWOKEY_BUILDING; }
+ else if ((action == "prefix key select flag tool") && pressed)
{
+ twoKeyMode = TWOKEY_FLAG; }
+ else if (pressed
+ && ((action == "select make swarm tool")
+ || (action == "select make inn tool")
+ || (action == "select make hospital tool")
+ || (action == "select make racetrack tool")
+ || (action == "select make swimming pool tool")
+ || (action == "select make barracks tool")
+ || (action == "select make school tool")
+ || (action == "select make defense tower tool")
+ || (action == "select make stone wall tool")
+ || (action == "select make market tool")
+ || (action == "select make exploration flag tool")
+ || (action == "select make war flag tool")
+ || (action == "select make clearing flag tool")
+ || (action == "select forbidden area tool")
+ || (action == "select guard area tool")
+ || (action == "select clearing area tool")
+ || (action == "switch to adding areas")
+ || (action == "switch to deleting areas")
+ || (action == "switch to area brush 1")
+ || (action == "switch to area brush 2")
+ || (action == "switch to area brush 3")
+ || (action == "switch to area brush 4")
+ || (action == "switch to area brush 5")
+ || (action == "switch to area brush 6")
+ || (action == "switch to area brush 7")
+ || (action == "switch to area brush 8"))) {
+ clearSelection();
+ char * buildingType = NULL;
+ BrushType tmpBrushType;
+ bool isArea = false;
+ BrushTool::Mode tmpBrushMode = BrushTool::MODE_NONE;
+ int brushFigure;
+ bool isBrush = false;
+ char * flagType = NULL;
+ if (action == "select make swarm tool") {
+ buildingType = "swarm"; }
+ else if (action == "select make inn tool") {
+ buildingType = "inn"; }
+ else if (action == "select make hospital tool") {
+ buildingType = "hospital"; }
+ else if (action == "select make racetrack tool") {
+ buildingType = "racetrack"; }
+ else if (action == "select make swimming pool tool") {
+ buildingType = "swimmingpool"; }
+ else if (action == "select make barracks tool") {
+ buildingType = "barracks"; }
+ else if (action == "select make school tool") {
+ buildingType = "school"; }
+ else if (action == "select make defense tower tool") {
+ buildingType = "defencetower"; }
+ else if (action == "select make stone wall tool") {
+ buildingType = "stonewall"; }
+ else if (action == "select make market tool") {
+ buildingType = "market"; }
+ else if (action == "select make exploration flag tool") {
+ flagType = "explorationflag"; }
+ else if (action == "select make war flag tool") {
+ flagType = "warflag"; }
+ else if (action == "select make clearing flag tool") {
+ flagType = "clearingflag"; }
+ else if (action == "select forbidden area tool") {
+ isArea = true;
+ tmpBrushType = FORBIDDEN_BRUSH; }
+ else if (action == "select guard area tool") {
+ isArea = true;
+ tmpBrushType = GUARD_AREA_BRUSH; }
+ else if (action == "select clearing area tool") {
+ isArea = true;
+ tmpBrushType = CLEAR_AREA_BRUSH; }
+ else if (action == "switch to adding areas") {
+ tmpBrushMode = BrushTool::MODE_ADD; }
+ else if (action == "switch to deleting areas") {
+ tmpBrushMode = BrushTool::MODE_DEL; }
+ else if (action == "switch to area brush 1") {
+ brushFigure = 0;
+ isBrush = true; }
+ else if (action == "switch to area brush 2") {
+ brushFigure = 1;
+ isBrush = true; }
+ else if (action == "switch to area brush 3") {
+ brushFigure = 2;
+ isBrush = true; }
+ else if (action == "switch to area brush 4") {
+ brushFigure = 3;
+ isBrush = true; }
+ else if (action == "switch to area brush 5") {
+ brushFigure = 4;
+ isBrush = true; }
+ else if (action == "switch to area brush 6") {
+ brushFigure = 5;
+ isBrush = true; }
+ else if (action == "switch to area brush 7") {
+ brushFigure = 6;
+ isBrush = true; }
+ else if (action == "switch to area brush 8") {
+ brushFigure = 7;
+ isBrush = true; }
+ if (buildingType) {
+ if (isBuildingEnabled(std::string(buildingType))) {
+ displayMode = BUILDING_VIEW; // Can hiddenGUIElements
forbid showing building view if the particular building type is enabled? Do I
need to check this?
+ setSelection(TOOL_SELECTION, (void *) buildingType); }}
+ else if (flagType) {
+ if (isFlagEnabled(std::string(flagType))) {
+ displayMode = FLAG_VIEW; // Can hiddenGUIElements
forbid showing flag view if the particular flag type is enabled? Do I need to
check this?
+ setSelection(TOOL_SELECTION, (void*) flagType); }}
+ else if (isArea || (tmpBrushMode != BrushTool::MODE_NONE) ||
isBrush) {
+ // Do I need to check if the GUI is enabled for this?
+ displayMode = FLAG_VIEW;
+ if (isArea) {
+ brushType = tmpBrushType; }
+ if (tmpBrushMode != BrushTool::MODE_NONE) {
+ brush.setType(tmpBrushMode); }
+ else if (brush.getType() == BrushTool::MODE_NONE) {
+ brush.setType(BrushTool::MODE_ADD); }
+ if (isBrush) {
+ brush.setFigure (brushFigure); }
+ setSelection(BRUSH_SELECTION); }}
}
}
@@ -1498,42 +1820,70 @@
Uint8 *keystate = SDL_GetKeyState(NULL);
if (notmenu == false)
{
+ SDLMod modState = SDL_GetModState();
+ int xMotion = 1;
+ int yMotion = 1;
+ /* We check that only Control is held to avoid accidentally
+ matching window manager bindings for switching windows
+ and/or desktops. */
+ if ((modState & KMOD_CTRL) && ! (modState &
(KMOD_ALT|KMOD_SHIFT))) {
+ /* It violates good abstraction principles that I
+ have to do the calculations in the next two
+ lines. There should be methods that abstract
+ these computations. */
+ /* We move by half screens if Control is held while
+ the arrow keys are held. So we shift by 6
+ instead of 5. (If we shifted by 5, it would be
+ good to subtract 1 so that there would be a small
+ overlap between what is viewable both before and
+ after the motion.) */
+ xMotion = ((globalContainer->gfx->getW()-128)>>6);
+ yMotion = ((globalContainer->gfx->getH())>>6); }
+ else if (modState) {
+ /* Probably some keys held down as part of window
+ manager operations. */
+ xMotion = 0;
+ yMotion = 0; }
+ // int oldViewportX = viewportX;
+ // int oldViewportY = viewportY;
if (keystate[SDLK_UP])
- viewportY--;
+ viewportY -= yMotion;
if (keystate[SDLK_KP8])
- viewportY--;
+ viewportY -= yMotion;
if (keystate[SDLK_DOWN])
- viewportY++;
+ viewportY += yMotion;
if (keystate[SDLK_KP2])
- viewportY++;
+ viewportY += yMotion;
if ((keystate[SDLK_LEFT]) && (typingInputScreen == NULL)) // we
haave a test in handleKeyAlways, that's not very clean, but as every key check
based on key states and not key events are here, it is much simpler and thus
easier to understand and thus cleaner ;-)
- viewportX--;
+ viewportX -= xMotion;
if (keystate[SDLK_KP4])
- viewportX--;
+ viewportX -= xMotion;
if ((keystate[SDLK_RIGHT]) && (typingInputScreen == NULL)) //
we haave a test in handleKeyAlways, that's not very clean, but as every key
check based on key states and not key events are here, it is much simpler and
thus easier to understand and thus cleaner ;-)
- viewportX++;
+ viewportX += xMotion;
if (keystate[SDLK_KP6])
- viewportX++;
+ viewportX += xMotion;
if (keystate[SDLK_KP7])
{
- viewportX--;
- viewportY--;
+ viewportX -= xMotion;
+ viewportY -= yMotion;
}
if (keystate[SDLK_KP9])
{
- viewportX++;
- viewportY--;
+ viewportX += xMotion;
+ viewportY -= yMotion;
}
if (keystate[SDLK_KP1])
{
- viewportX--;
- viewportY++;
+ viewportX -= xMotion;
+ viewportY += yMotion;
}
if (keystate[SDLK_KP3])
{
- viewportX++;
- viewportY++;
+ viewportX += xMotion;
+ viewportY += yMotion;
}
+ // if ((oldViewportX != viewportX) || (oldViewportY !=
viewportY)) {
+ // fprintf (stderr, "xMotion: %d, yMotion: %d, viewportX:
%d, viewportY: %d\n", xMotion, yMotion, viewportX, viewportY); }
}
}
@@ -1597,7 +1947,7 @@
viewportY=(panViewY+dy)&game.map.getMaskH();
}
- dragStep();
+ dragStep(mx, my, button);
}
void GameGUI::handleMapClick(int mx, int my, int button)
@@ -1636,7 +1986,7 @@
}
else if (selectionMode==BRUSH_SELECTION)
{
- brushStep(mouseX, mouseY);
+ brushStep(true, mouseX, mouseY);
}
else if (putMark)
{
@@ -1707,7 +2057,7 @@
{
setSelection(BUILDING_SELECTION, gbid);
selectionPushed=true;
- showUnitWorkingToBuilding=true;
+ // showUnitWorkingToBuilding=true;
// handle dump of building
characteristics
if ((SDL_GetModState() & KMOD_SHIFT) !=
0)
{
@@ -3287,7 +3637,37 @@
else if (selectionMode==BRUSH_SELECTION)
{
globalContainer->gfx->setClipRect(0, 0,
globalContainer->gfx->getW()-128, globalContainer->gfx->getH());
- brush.drawBrush(mouseX, mouseY);
+ /* Instead of using a dimmer intensity to indicate
+ removing of areas, this should rather use dashed
+ lines. (The intensities used below are 2/3 as
+ bright for the case of removing areas.) */
+ /* This reasoning should be abstracted out and reused
+ in MapEdit.cpp to choose a color for those cases
+ where areas are being drawn. */
+ unsigned mode = brush.getType();
+ Color c = Color(0,0,0);
+ /* The following colors have been chosen to match the
+ colors in the .png files for the animations of
+ areas as of 2007-04-29. If those .png files are
+ updated with different colors, then the following
+ code should change accordingly. */
+ if (brushType == FORBIDDEN_BRUSH) {
+ if (mode == BrushTool::MODE_ADD) {
+ c = Color(255,0,0); }
+ else {
+ c = Color(170,0,0); }}
+ else if (brushType == GUARD_AREA_BRUSH) {
+ if (mode == BrushTool::MODE_ADD) {
+ c = Color(27,0,255); }
+ else {
+ c = Color(18,0,170); }}
+ else if (brushType == CLEAR_AREA_BRUSH) {
+ if (mode == BrushTool::MODE_ADD) {
+ /* some of the clearing area images use (252,207,0)
instead */
+ c = Color(251,206,0); }
+ else {
+ c = Color(167,137,0); }}
+ brush.drawBrush(mouseX, mouseY, c);
}
else if (selectionMode==BUILDING_SELECTION)
{
@@ -3568,7 +3948,7 @@
// if paused, tint the game area
if (gamePaused)
{
- globalContainer->gfx->drawFilledRect(0, 0,
globalContainer->gfx->getW()-128, globalContainer->gfx->getH(), 0, 0, 0, 127);
+ globalContainer->gfx->drawFilledRect(0, 0,
globalContainer->gfx->getW()-128, globalContainer->gfx->getH(), 0, 0, 0, 20);
const char *s =
Toolkit::getStringTable()->getString("[Paused]");
int x =
(globalContainer->gfx->getW()-globalContainer->menuFont->getStringWidth(s))>>1;
globalContainer->gfx->drawString(x,
globalContainer->gfx->getH()-80, globalContainer->menuFont, s);
@@ -4067,21 +4447,70 @@
}
}
}
+ else if (selectionMode == UNIT_SELECTION)
+ {
+ Unit * selUnit = selection.unit;
+ assert(selUnit);
+ Uint16 gid = selUnit->gid;
+ /* to be safe should check if gid is valid here? */
+ /* if looking at one of our pieces, continue with the next
+ one of our pieces of same type, otherwise start at the
+ beginning of our pieces of that type. */
+ Sint32 id = ((Unit::GIDtoTeam(gid) == localTeamNo) ?
Unit::GIDtoID(gid) : 0);
+ /* It violates good abstraction principles that we know
+ that the size of the myUnits array is 1024. This
+ information should be abstracted by some method that we
+ call instead to get the next unit. */
+ id %= 1024; /* just in case! */
+ // std::cerr << "starting id: " << id << std::endl;
+ Sint32 i = id;
+ while (1)
+ {
+ i = ((i + 1) % 1024);
+ if (i == id) break;
+ // std::cerr << "trying id: " << i << std::endl;
+ Unit * u = game.teams[localTeamNo]->myUnits[i];
+ if (u && (u->typeNum == selUnit->typeNum))
+ {
+ // std::cerr << "found id: " << i << std::endl;
+ setSelection(UNIT_SELECTION, u);
+ centerViewportOnSelection();
+ break;
+ }
+ }
+ }
}
void GameGUI::centerViewportOnSelection(void)
{
- if (selectionMode==BUILDING_SELECTION)
- {
- Building* b=selection.building;
- //assert (selBuild);
- //Building
*b=game.teams[Building::GIDtoTeam(selectionGBID)]->myBuildings[Building::GIDtoID(selectionGBID)];
- assert(b);
- viewportX=b->getMidX()-((globalContainer->gfx->getW()-128)>>6);
- viewportY=b->getMidY()-((globalContainer->gfx->getH())>>6);
- viewportX=viewportX&game.map.getMaskW();
- viewportY=viewportY&game.map.getMaskH();
- }
+ if ((selectionMode==BUILDING_SELECTION) || (selectionMode==UNIT_SELECTION))
+ {
+ Sint32 posX, posY;
+ if (selectionMode==BUILDING_SELECTION)
+ {
+ Building* b=selection.building;
+ //assert (selBuild);
+ //Building
*b=game.teams[Building::GIDtoTeam(selectionGBID)]->myBuildings[Building::GIDtoID(selectionGBID)];
+ assert(b);
+ posX = b->getMidX();
+ posY = b->getMidY();
+ }
+ else if (selectionMode==UNIT_SELECTION)
+ {
+ Unit * u = selection.unit;
+ assert (u);
+ posX = u->posX;
+ posY = u->posY;
+ }
+ /* It violates good abstraction principles that we know here
+ that the size of the right panel is 128 pixels, and that each
+ map cell is 32 pixels. This information should be
+ abstracted. */
+ viewportX = posX - ((globalContainer->gfx->getW()-128)>>6);
+ viewportY = posY - ((globalContainer->gfx->getH())>>6);
+ viewportX = viewportX & game.map.getMaskW();
+ viewportY = viewportY & game.map.getMaskH();
+ }
}
void GameGUI::enableBuildingsChoice(const std::string &name)
@@ -4102,6 +4531,16 @@
}
}
+bool GameGUI::isBuildingEnabled(const std::string &name)
+{
+ for (size_t i=0; i<buildingsChoiceName.size(); ++i)
+ {
+ if (name == buildingsChoiceName[i])
+ return buildingsChoiceState[i];
+ }
+ assert (false);
+}
+
void GameGUI::enableFlagsChoice(const std::string &name)
{
for (size_t i=0; i<flagsChoiceName.size(); ++i)
@@ -4120,6 +4559,16 @@
}
}
+bool GameGUI::isFlagEnabled(const std::string &name)
+{
+ for (size_t i=0; i<flagsChoiceName.size(); ++i)
+ {
+ if (name == flagsChoiceName[i])
+ return flagsChoiceState[i];
+ }
+ assert (false);
+}
+
void GameGUI::enableGUIElement(int id)
{
hiddenGUIElements &= ~(1<<id);
diff -ru ../../glob-virgin/glob2-0.8.23/src/GameGUI.h ./GameGUI.h
--- ../../glob-virgin/glob2-0.8.23/src/GameGUI.h 2007-04-17
22:48:06.000000000 +0100
+++ ./GameGUI.h 2007-04-29 21:08:35.000000000 +0100
@@ -108,8 +108,10 @@
// Script interface
void enableBuildingsChoice(const std::string &name);
void disableBuildingsChoice(const std::string &name);
+ bool isBuildingEnabled(const std::string &name);
void enableFlagsChoice(const std::string &name);
void disableFlagsChoice(const std::string &name);
+ bool isFlagEnabled(const std::string &name);
void enableGUIElement(int id);
void disableGUIElement(int id);
bool isSpaceSet() { return hasSpaceBeenClicked; }
@@ -181,11 +183,11 @@
void moveFlag(int mx, int my, bool drop);
//! Update the brush and the local map due to mouse motion
- void brushStep(int mx, int my);
+ void brushStep(bool maybeToggleMode, int mx, int my);
//! Send a brush order and reinitialize the brush accumulator
void sendBrushOrders(void);
//! One viewport has moved and a flag or a brush is selected, update
its position
- void dragStep(void);
+ void dragStep(int mx, int my, int button);
//! on each step, check if we have won or lost
void checkWonConditions(void);
diff -ru ../../glob-virgin/glob2-0.8.23/src/Map.cpp ./Map.cpp
--- ../../glob-virgin/glob2-0.8.23/src/Map.cpp 2007-04-17 22:48:06.000000000
+0100
+++ ./Map.cpp 2007-04-29 06:00:02.000000000 +0100
@@ -1115,6 +1115,11 @@
if (game)
{
+ /* Must set game field before following action as they
+ may need it (in particular
+ makeDiscoveredAreasExplored uses it). */
+ this->game=game;
+
// This is a game, so we do compute gradients
for (int t=0; t<sessionGame->numberOfTeam; t++)
for (int r=0; r<MAX_RESSOURCES; r++)
@@ -1144,9 +1149,8 @@
assert(exploredArea[t] == NULL);
exploredArea[t] = new Uint8[size];
initExploredArea(t);
+ makeDiscoveredAreasExplored(t);
}
-
- this->game=game;
}
// We load sectors:
@@ -4881,6 +4885,23 @@
std::fill(exploredArea[teamNumber], exploredArea[teamNumber] + size, 0);
}
+void Map::makeDiscoveredAreasExplored (int teamNumber)
+{
+ /* This function is a stupid hack to make up for the fact that
+ exploredArea is not saved in saved games. It allows doing
+ something less awful than simply making everything considered
+ unexplored (which completely messes up explorer behavior and
+ makes them explore the entire world all over again) when games
+ are reloaded. */
+ assert(game->teams[teamNumber]);
+ assert(game->teams[teamNumber]->me);
+ assert(exploredArea[teamNumber]);
+ for (int x = 0; x < getW(); x++) {
+ for (int y = 0; y < getH(); y++) {
+ if (isMapDiscovered (x, y, game->teams[teamNumber]->me)) {
+ setMapExploredByUnit (x, y, 1, 1, teamNumber); }}}
+}
+
void Map::updateExploredArea(int teamNumber)
{
for (size_t i = 0; i < size; i++)
diff -ru ../../glob-virgin/glob2-0.8.23/src/Map.h ./Map.h
--- ../../glob-virgin/glob2-0.8.23/src/Map.h 2007-04-17 22:48:06.000000000
+0100
+++ ./Map.h 2007-04-22 04:03:07.000000000 +0100
@@ -582,6 +582,7 @@
void updateGuardAreasGradient();
void initExploredArea(int teamNumber);
+ void makeDiscoveredAreasExplored(int teamNumber);
void updateExploredArea(int teamNumber);
protected:
diff -ru ../../glob-virgin/glob2-0.8.23/src/Settings.cpp ./Settings.cpp
--- ../../glob-virgin/glob2-0.8.23/src/Settings.cpp 2007-04-17
22:48:06.000000000 +0100
+++ ./Settings.cpp 2007-04-29 21:32:04.000000000 +0100
@@ -112,14 +112,14 @@
void Settings::restoreDefaultShortcuts()
{
- keyboard_shortcuts["akey"]="toggle draw accessibility aids";
- keyboard_shortcuts["bkey"]="";
+ keyboard_shortcuts["akey"]="prefix key select area tool";
+ keyboard_shortcuts["bkey"]="prefix key select building tool";
keyboard_shortcuts["ckey"]="";
keyboard_shortcuts["dkey"]="destroy building";
keyboard_shortcuts["ekey"]="";
- keyboard_shortcuts["fkey"]="";
+ keyboard_shortcuts["fkey"]="prefix key select flag tool";
keyboard_shortcuts["gkey"]="";
- keyboard_shortcuts["hkey"]="";
+ keyboard_shortcuts["hkey"]="toggle draw accessibility aids";
keyboard_shortcuts["ikey"]="toggle draw information";
keyboard_shortcuts["jkey"]="";
keyboard_shortcuts["kkey"]="";
diff -ru ../../glob-virgin/glob2-0.8.23/src/SettingsScreen.cpp
./SettingsScreen.cpp
--- ../../glob-virgin/glob2-0.8.23/src/SettingsScreen.cpp 2007-04-17
22:48:06.000000000 +0100
+++ ./SettingsScreen.cpp 2007-04-29 22:25:48.000000000 +0100
@@ -233,6 +233,47 @@
shortcut_actions.push_back("record voice");
shortcut_names.push_back(Toolkit::getStringTable()->getString("[pause
game]"));
shortcut_actions.push_back("pause game");
+ char * (commands[]) = {
+ "prefix key select area tool",
+ "prefix key select building tool",
+ "prefix key select flag tool",
+ "select make swarm tool",
+ "select make inn tool",
+ "select make hospital tool",
+ "select make racetrack tool",
+ "select make swimming pool tool",
+ "select make barracks tool",
+ "select make school tool",
+ "select make defense tower tool",
+ "select make stone wall tool",
+ "select make market tool",
+ "select make exploration flag tool",
+ "select make war flag tool",
+ "select make clearing flag tool",
+ "select forbidden area tool",
+ "select guard area tool",
+ "select clearing area tool",
+ "switch to adding areas",
+ "switch to deleting areas",
+ "switch to area brush 1",
+ "switch to area brush 2",
+ "switch to area brush 3",
+ "switch to area brush 4",
+ "switch to area brush 5",
+ "switch to area brush 6",
+ "switch to area brush 7",
+ "switch to area brush 8", };
+ // fprintf (stderr, "before loop: sizeof(commands): %d\n", sizeof
(commands));
+ for (int i = 0; i < (sizeof (commands) / (sizeof (commands[0]))); i++)
{
+ // fprintf (stderr, "i: %d\n", i);
+ char buffer[100];
+ snprintf (buffer, sizeof(buffer), "[%s]", commands[i]);
+ buffer[99] = '\0';
+ const char * message = Toolkit::getStringTable()->getString(buffer);
+ // fprintf (stderr, "commands[%d]: {%s}, buffer: {%s}, message:
{%s}\n", i, commands[i], buffer, message);
+ shortcut_names.push_back (message);
+ shortcut_actions.push_back (commands[i]); }
+ // fprintf (stderr, "after loop\n");
editor_shortcut_names.push_back(Toolkit::getStringTable()->getString("[switch
to building view]"));
editor_shortcut_actions.push_back("switch to building view");
diff -ru ../../glob-virgin/glob2-0.8.23/src/Unit.cpp ./Unit.cpp
--- ../../glob-virgin/glob2-0.8.23/src/Unit.cpp 2007-04-17 22:48:06.000000000
+0100
+++ ./Unit.cpp 2007-04-29 06:06:27.000000000 +0100
@@ -720,6 +720,23 @@
void Unit::handleMedical(void)
{
+ /* Make sure explorers try to immediately feed after healing to
increase their range. */
+ if ((typeNum == EXPLORER)
+ && (displacement == DIS_EXITING_BUILDING)) {
+ medical=MED_FREE;
+ if ((destinationPurprose == HEAL)
+ && (hungry < ((HUNGRY_MAX * 9) / 10))) {
+ // fprintf (stderr, "forcing explorer hunger: gid: %d, hungry:
%d\n", gid, hungry);
+ needToRecheckMedical = 1;
+ medical = MED_HUNGRY;
+ return; }
+ else if ((destinationPurprose == FEED)
+ && (hp < (((performance[HP]) * 9) / 10))) {
+ // fprintf (stderr, "forcing explorer healing: gid: %d, hp: %d\n",
gid, hp);
+ needToRecheckMedical = 1;
+ medical = MED_DAMAGED;
+ return; }}
+
if ((displacement==DIS_ENTERING_BUILDING) || (displacement==DIS_INSIDE)
|| (displacement==DIS_EXITING_BUILDING))
return;
@@ -773,8 +790,15 @@
void Unit::handleActivity(void)
{
+ if ((displacement==DIS_EXITING_BUILDING)
+ && (typeNum == EXPLORER)) {
+ // fprintf (stderr, "exiting explorer: gid: %d, medical: %d,
destinationPurprose: %d\n", gid, medical, destinationPurprose);
+ }
+
// freeze unit health when inside a building
- if ((displacement==DIS_ENTERING_BUILDING) || (displacement==DIS_INSIDE)
|| (displacement==DIS_EXITING_BUILDING))
+ if ((displacement==DIS_ENTERING_BUILDING) || (displacement==DIS_INSIDE)
+ || ((displacement==DIS_EXITING_BUILDING)
+ && ! ((typeNum == EXPLORER) && (medical != MED_FREE))))
return;
if (verbose)
@@ -853,6 +877,10 @@
{
Building *b;
b=owner->findNearestFood(this);
+ if (typeNum == EXPLORER) {
+ // fprintf (stderr, "gid: %d, b: %x\n", gid, b);
+ }
+
if (b!=NULL)
{
Team *currentTeam=owner;
@@ -1464,6 +1492,12 @@
dxdyfromDirection();
movement = MOV_GOING_DXDY;
found = true;
+ /*
+ fprintf (stderr, "gid = %d;
changed direction: direction = %d, dx = %d, dy = %d; tab = {", gid, direction,
dx, dy);
+ for (int i = 0; i < 8; i++) {
+ fprintf (stderr, "%d%s",
tab[i], ((i < 7) ? ", " : "")); }
+ fprintf (stderr, "}\n");
+ */
break;
}
}
@@ -1471,16 +1505,25 @@
{
int scoreX = 0;
int scoreY = 0;
- for (int delta = -3; delta <= 3;
delta++)
- {
- scoreX +=
owner->map->getExplored(posX - 4, posY + delta, owner->teamNumber);
- scoreX -=
owner->map->getExplored(posX + 4, posY + delta, owner->teamNumber);
- scoreY +=
owner->map->getExplored(posX + delta, posY - 4, owner->teamNumber);
- scoreY -=
owner->map->getExplored(posX + delta, posY + 4, owner->teamNumber);
- }
+ /* The next line should really be
calculated only once per game. How to do this? The point is to avoid wrapping
around the torus in considering what area is closer to us. */
+ int maxRange =
(std::min(owner->map->getW(), owner->map->getH())) / 2;
+ /* We sample cells at various
+ distances to decide in what
+ direction there is more
+ unexplored territory. */
+ for (int range = 1; range <= maxRange;
range *= 2)
+ {
+ for (int delta = -3; delta <= 3;
delta++)
+ {
+ scoreX +=
owner->map->getExplored(posX - (4*range), posY + (delta*range),
owner->teamNumber);
+ scoreX -=
owner->map->getExplored(posX + (4*range), posY + (delta*range),
owner->teamNumber);
+ scoreY +=
owner->map->getExplored(posX + (delta*range), posY - (4*range),
owner->teamNumber);
+ scoreY -=
owner->map->getExplored(posX + (delta*range), posY + (4*range),
owner->teamNumber);
+ }
+ }
int cdx, cdy;
simplifyDirection(scoreX, scoreY, &cdx,
&cdy);
- //printf("score = (%2d, %2d), cd = (%d,
%d)\n", scoreX, scoreY, cdx, cdy);
+ // fprintf(stderr, "gid = %d, maxRange
= %d, score = (%2d, %2d), cd = (%d, %d)\n", gid, maxRange, scoreX, scoreY, cdx,
cdy);
if (cdx == 0 && cdy == 0)
movement = MOV_RANDOM_FLY;
else
@@ -2290,12 +2333,18 @@
else if (ldy<-(maph>>1))
ldy+=maph;
- if (abs(ldx)>(2*abs(ldy)))
+ /* We consider a cell to be vertical or horizontal in
+ direction (rather than diagonal) if it is 2.41 times more
+ vertical than horizontal, or vice versa. This is because
+ the halfway point between 45 degrees and 90 degrees is 67.5
+ degrees and sin(67.5 deg) / cos(67.5 deg) =
+ 2.41421356237. */
+ if ((100 * abs(ldx)) > (241 * abs(ldy)))
{
*cdx=SIGN(ldx);
*cdy=0;
}
- else if (abs(ldy)>(2*abs(ldx)))
+ else if ((100 * abs(ldy)) > (241 * abs(ldx)))
{
*cdx=0;
*cdy=SIGN(ldy);
data-gfx.tar.gz
Description: Binary data
- [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7),
Joe Wells <=
- Re: [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7), Leo Wandersleb, 2007/04/29
- Re: [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7), Leo Wandersleb, 2007/04/29
- Re: [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7), Bradley Arsenault, 2007/04/30
- Re: [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7), Bradley Arsenault, 2007/04/30
- [glob2-devel] all your bases are belong to Nicowar (was: patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7)), Joe Wells, 2007/04/30
- Re: [glob2-devel] all your bases are belong to Nicowar (was: patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7)), Bradley Arsenault, 2007/04/30
- Re: [glob2-devel] all your bases are belong to Nicowar, Joe Wells, 2007/04/30
Re: [glob2-devel] patch with improvements: brushes (6), fix AI cheating (2), explorers (4), other GUI (7), Leo Wandersleb, 2007/04/30