add a simple explore action
flies around randomly, much room for improvement
This commit is contained in:
parent
9f36458389
commit
accaaf56e1
15 changed files with 347 additions and 0 deletions
|
@ -65,6 +65,7 @@ set(action_SRCS
|
|||
src/action/action_built.cpp
|
||||
src/action/action_defend.cpp
|
||||
src/action/action_die.cpp
|
||||
src/action/action_explore.cpp
|
||||
src/action/action_follow.cpp
|
||||
src/action/action_move.cpp
|
||||
src/action/action_patrol.cpp
|
||||
|
|
204
src/action/action_explore.cpp
Normal file
204
src/action/action_explore.cpp
Normal file
|
@ -0,0 +1,204 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_explore.cpp - The explore action. */
|
||||
//
|
||||
// (c) Copyright 1998-2019 by Lutz Sammer, Jimmy Salmon and Talas
|
||||
//
|
||||
// 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; only version 2 of the License.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "action/action_explore.h"
|
||||
|
||||
#include "animation.h"
|
||||
#include "iolib.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
#include "script.h"
|
||||
#include "tile.h"
|
||||
#include "ui.h"
|
||||
#include "unit.h"
|
||||
#include "unittype.h"
|
||||
#include "video.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
static void GetExplorationTarget(const CUnit &unit, Vec2i &dest)
|
||||
{
|
||||
int triesLeft = Map.NoFogOfWar ? 0 : 3;
|
||||
CMapField *field;
|
||||
const CPlayer &player = *unit.Player;
|
||||
dest.x = SyncRand(Map.Info.MapWidth - 1) + 1;
|
||||
dest.y = SyncRand(Map.Info.MapHeight - 1) + 1;
|
||||
|
||||
while (triesLeft > 0) {
|
||||
field = Map.Field(dest);
|
||||
if (field && !field->playerInfo.IsExplored(player))
|
||||
return; // unexplored, go here!
|
||||
dest.x = SyncRand(Map.Info.MapWidth - 1) + 1;
|
||||
dest.y = SyncRand(Map.Info.MapHeight - 1) + 1;
|
||||
--triesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ COrder *COrder::NewActionExplore(const CUnit &unit)
|
||||
{
|
||||
Vec2i dest;
|
||||
GetExplorationTarget(unit, dest);
|
||||
Assert(Map.Info.IsPointOnMap(dest));
|
||||
|
||||
COrder_Explore *order = new COrder_Explore();
|
||||
|
||||
order->goalPos = dest;
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Explore::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-explore\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
|
||||
if (this->WaitingCycle != 0) {
|
||||
file.printf(" \"waiting-cycle\", %d,", this->WaitingCycle);
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Explore::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "waiting-cycle")) {
|
||||
++j;
|
||||
this->WaitingCycle = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "range")) {
|
||||
++j;
|
||||
this->Range = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "tile")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
CclGetPos(l, &this->goalPos.x , &this->goalPos.y);
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Explore::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ PixelPos COrder_Explore::Show(const CViewport &vp, const PixelPos &lastScreenPos) const
|
||||
{
|
||||
const PixelPos pos1 = vp.TilePosToScreen_Center(this->goalPos);
|
||||
|
||||
Video.DrawLineClip(ColorGreen, lastScreenPos, pos1);
|
||||
Video.FillCircleClip(ColorBlue, pos1, 2);
|
||||
return pos1;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Explore::UpdatePathFinderData(PathFinderInput &input)
|
||||
{
|
||||
input.SetMinRange(0);
|
||||
input.SetMaxRange(this->Range);
|
||||
const Vec2i tileSize(0, 0);
|
||||
input.SetGoal(this->goalPos, tileSize);
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Explore::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
if (!unit.Waiting) {
|
||||
unit.Waiting = 1;
|
||||
unit.WaitBackup = unit.Anim;
|
||||
}
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Still);
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
if (unit.Waiting) {
|
||||
unit.Anim = unit.WaitBackup;
|
||||
unit.Waiting = 0;
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) {
|
||||
case PF_FAILED:
|
||||
this->WaitingCycle = 0;
|
||||
break;
|
||||
case PF_UNREACHABLE:
|
||||
// Increase range and try again
|
||||
this->WaitingCycle = 1;
|
||||
this->Range++;
|
||||
break;
|
||||
|
||||
case PF_REACHED:
|
||||
{
|
||||
this->WaitingCycle = 1;
|
||||
this->Range = 0;
|
||||
// pick a new place to explore
|
||||
GetExplorationTarget(unit, this->goalPos);
|
||||
}
|
||||
break;
|
||||
case PF_WAIT:
|
||||
{
|
||||
// Wait for a while then give up
|
||||
this->WaitingCycle++;
|
||||
if (this->WaitingCycle == 5) {
|
||||
this->WaitingCycle = 0;
|
||||
this->Range = 0;
|
||||
// pick a new place to explore
|
||||
GetExplorationTarget(unit, this->goalPos);
|
||||
|
||||
unit.pathFinderData->output.Cycles = 0; //moving counter
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // moving
|
||||
this->WaitingCycle = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (AutoAttack(unit) || AutoRepair(unit) || AutoCast(unit)) {
|
||||
this->Finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
|
@ -46,6 +46,7 @@
|
|||
#include "action/action_built.h"
|
||||
#include "action/action_defend.h"
|
||||
#include "action/action_die.h"
|
||||
#include "action/action_explore.h"
|
||||
#include "action/action_follow.h"
|
||||
#include "action/action_move.h"
|
||||
#include "action/action_patrol.h"
|
||||
|
@ -200,6 +201,8 @@ void CclParseOrder(lua_State *l, CUnit &unit, COrderPtr *orderPtr)
|
|||
*orderPtr = new COrder_Defend;
|
||||
} else if (!strcmp(actiontype, "action-die")) {
|
||||
*orderPtr = new COrder_Die;
|
||||
} else if (!strcmp(actiontype, "action-explore")) {
|
||||
*orderPtr = new COrder_Explore;
|
||||
} else if (!strcmp(actiontype, "action-follow")) {
|
||||
*orderPtr = new COrder_Follow;
|
||||
} else if (!strcmp(actiontype, "action-move")) {
|
||||
|
|
|
@ -499,6 +499,33 @@ void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int fl
|
|||
ClearSavedAction(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
** Send a unit exploring
|
||||
**
|
||||
** @param unit pointer to unit.
|
||||
** @param flush if true, flush command queue.
|
||||
*/
|
||||
void CommandExplore(CUnit &unit, int flush)
|
||||
{
|
||||
if (IsUnitValidForNetwork(unit) == false) {
|
||||
return ;
|
||||
}
|
||||
COrderPtr *order;
|
||||
|
||||
if (!unit.CanMove()) {
|
||||
ClearNewAction(unit);
|
||||
order = &unit.NewOrder;
|
||||
} else {
|
||||
order = GetNextOrder(unit, flush);
|
||||
if (order == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
*order = COrder::NewActionExplore(unit);
|
||||
|
||||
ClearSavedAction(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
** Cancel the building construction, or kill a unit.
|
||||
**
|
||||
|
|
|
@ -850,6 +850,8 @@ static void DoNextReplay()
|
|||
SendCommandUnload(*unit, pos, dunit, flags);
|
||||
} else if (!strcmp(action, "build")) {
|
||||
SendCommandBuildBuilding(*unit, pos, *UnitTypeByIdent(val), flags);
|
||||
} else if (!strcmp(action, "explore")) {
|
||||
SendCommandExplore(*unit, flags);
|
||||
} else if (!strcmp(action, "dismiss")) {
|
||||
SendCommandDismiss(*unit);
|
||||
} else if (!strcmp(action, "resource-loc")) {
|
||||
|
|
65
src/include/action/action_explore.h
Normal file
65
src/include/action/action_explore.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_explore.h - The actions headerfile. */
|
||||
//
|
||||
// (c) Copyright 1998-2019 by Lutz Sammer, Jimmy Salmon and Talas
|
||||
//
|
||||
// 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; only version 2 of the License.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
#ifndef __ACTION_EXPLORE_H__
|
||||
#define __ACTION_EXPLORE_H__
|
||||
|
||||
#include "actions.h"
|
||||
|
||||
//@{
|
||||
|
||||
class COrder_Explore : public COrder
|
||||
{
|
||||
friend COrder *COrder::NewActionExplore(const CUnit &unit);
|
||||
public:
|
||||
COrder_Explore() : COrder(UnitActionExplore), WaitingCycle(0), Range(0)
|
||||
{
|
||||
goalPos.x = -1;
|
||||
goalPos.y = -1;
|
||||
}
|
||||
|
||||
virtual COrder_Explore *Clone() const { return new COrder_Explore(*this); }
|
||||
|
||||
virtual bool IsValid() const;
|
||||
|
||||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
private:
|
||||
unsigned int WaitingCycle; /// number of cycle pathfinder wait.
|
||||
int Range;
|
||||
Vec2i goalPos;
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__ACTION_EXPLORE_H__
|
|
@ -70,6 +70,7 @@ enum UnitAction {
|
|||
UnitActionUnload, /// unit leaving transporter
|
||||
UnitActionPatrol, /// unit paroling area
|
||||
UnitActionBuild, /// unit builds building
|
||||
UnitActionExplore, /// unit explores map
|
||||
|
||||
UnitActionRepair, /// unit repairing
|
||||
UnitActionResource, /// unit harvesting resources
|
||||
|
@ -133,6 +134,7 @@ public:
|
|||
static COrder *NewActionBuilt(CUnit &builder, CUnit &unit);
|
||||
static COrder *NewActionDefend(CUnit &dest);
|
||||
static COrder *NewActionDie();
|
||||
static COrder *NewActionExplore(const CUnit &unit);
|
||||
static COrder *NewActionFollow(CUnit &dest);
|
||||
static COrder *NewActionMove(const Vec2i &pos);
|
||||
static COrder *NewActionPatrol(const Vec2i ¤tPos, const Vec2i &dest);
|
||||
|
|
|
@ -84,6 +84,8 @@ extern void CommandBoard(CUnit &unit, CUnit &dest, int flush);
|
|||
extern void CommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush);
|
||||
/// Prepare command build
|
||||
extern void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &, int flush);
|
||||
/// Prepare command explore
|
||||
extern void CommandExplore(CUnit &unit, int flush);
|
||||
/// Prepare command dismiss
|
||||
extern void CommandDismiss(CUnit &unit);
|
||||
/// Prepare command resource location
|
||||
|
@ -152,6 +154,8 @@ extern void SendCommandBoard(CUnit &unit, CUnit &dest, int flush);
|
|||
extern void SendCommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush);
|
||||
/// Send build building command
|
||||
extern void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush);
|
||||
/// Send explore command
|
||||
extern void SendCommandExplore(CUnit &unit, int flush);
|
||||
/// Send cancel building command
|
||||
extern void SendCommandDismiss(CUnit &unit);
|
||||
/// Send harvest location command
|
||||
|
|
|
@ -63,6 +63,7 @@ enum ButtonCmd {
|
|||
ButtonHarvest, /// order harvest
|
||||
ButtonBuild, /// order build
|
||||
ButtonPatrol, /// order patrol
|
||||
ButtonExplore, /// order explore
|
||||
ButtonAttackGround, /// order attack ground
|
||||
ButtonSpellCast, /// order cast spell
|
||||
ButtonUnload, /// order unload unit
|
||||
|
|
|
@ -299,6 +299,7 @@ enum _message_type_ {
|
|||
MessageCommandBoard, /// Unit command board
|
||||
MessageCommandUnload, /// Unit command unload
|
||||
MessageCommandBuild, /// Unit command build building
|
||||
MessageCommandExplore, /// Unit command explore
|
||||
MessageCommandDismiss, /// Unit command dismiss unit
|
||||
MessageCommandResourceLoc, /// Unit command resource location
|
||||
MessageCommandResource, /// Unit command resource
|
||||
|
|
|
@ -288,6 +288,7 @@ private:
|
|||
void DoClicked_Unload(int button);
|
||||
void DoClicked_SpellCast(int button);
|
||||
void DoClicked_Repair(int button);
|
||||
void DoClicked_Explore();
|
||||
void DoClicked_Return();
|
||||
void DoClicked_Stop();
|
||||
void DoClicked_StandGround();
|
||||
|
|
|
@ -271,6 +271,22 @@ void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, in
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Send command: Unit explores the map.
|
||||
**
|
||||
** @param unit pointer to unit.
|
||||
** @param flush Flag flush all pending commands.
|
||||
*/
|
||||
void SendCommandExplore(CUnit &unit, int flush)
|
||||
{
|
||||
if (!IsNetworkGame()) {
|
||||
CommandLog("explore", &unit, flush, -1, -1, NoUnitP, NULL, -1);
|
||||
CommandExplore(unit, flush);
|
||||
} else {
|
||||
NetworkSendCommand(MessageCommandExplore, unit, 0, 0, NoUnitP, 0, flush);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Send command: Cancel this building construction.
|
||||
**
|
||||
|
@ -668,6 +684,10 @@ void ExecCommand(unsigned char msgnr, UnitRef unum,
|
|||
CommandLog("build", &unit, status, pos.x, pos.y, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), -1);
|
||||
CommandBuildBuilding(unit, pos, *UnitTypes[dstnr], status);
|
||||
break;
|
||||
case MessageCommandExplore:
|
||||
CommandLog("explore", &unit, status, -1, -1, NoUnitP, NULL, -1);
|
||||
CommandExplore(unit, status);
|
||||
break;
|
||||
case MessageCommandDismiss:
|
||||
CommandLog("dismiss", &unit, FlushCommands, -1, -1, NULL, NULL, -1);
|
||||
CommandDismiss(unit);
|
||||
|
|
|
@ -249,6 +249,9 @@ static int GetButtonStatus(const ButtonAction &button, int UnderCursor)
|
|||
case ButtonPatrol:
|
||||
action = UnitActionPatrol;
|
||||
break;
|
||||
case ButtonExplore:
|
||||
action = UnitActionExplore;
|
||||
break;
|
||||
case ButtonHarvest:
|
||||
case ButtonReturn:
|
||||
action = UnitActionResource;
|
||||
|
@ -884,6 +887,7 @@ bool IsButtonAllowed(const CUnit &unit, const ButtonAction &buttonaction)
|
|||
res = unit.Type->RepairRange > 0;
|
||||
break;
|
||||
case ButtonPatrol:
|
||||
case ButtonExplore:
|
||||
res = unit.CanMove();
|
||||
break;
|
||||
case ButtonHarvest:
|
||||
|
@ -1203,6 +1207,13 @@ void CButtonPanel::DoClicked_Repair(int button)
|
|||
DoClicked_SelectTarget(button);
|
||||
}
|
||||
|
||||
void CButtonPanel::DoClicked_Explore()
|
||||
{
|
||||
for (size_t i = 0; i != Selected.size(); ++i) {
|
||||
SendCommandExplore(*Selected[i], !(KeyModifiers & ModifierShift));
|
||||
}
|
||||
}
|
||||
|
||||
void CButtonPanel::DoClicked_Return()
|
||||
{
|
||||
for (size_t i = 0; i != Selected.size(); ++i) {
|
||||
|
@ -1420,6 +1431,7 @@ void CButtonPanel::DoClicked(int button)
|
|||
case ButtonUnload: { DoClicked_Unload(button); break; }
|
||||
case ButtonSpellCast: { DoClicked_SpellCast(button); break; }
|
||||
case ButtonRepair: { DoClicked_Repair(button); break; }
|
||||
case ButtonExplore: { DoClicked_Explore(); break; }
|
||||
case ButtonMove: // Follow Next
|
||||
case ButtonPatrol: // Follow Next
|
||||
case ButtonHarvest: // Follow Next
|
||||
|
|
|
@ -492,6 +492,8 @@ static PopupConditionPanel *ParsePopupConditions(lua_State *l)
|
|||
condition->ButtonAction = ButtonTrain;
|
||||
} else if (!strcmp(value, "patrol")) {
|
||||
condition->ButtonAction = ButtonPatrol;
|
||||
} else if (!strcmp(value, "explore")) {
|
||||
condition->ButtonAction = ButtonExplore;
|
||||
} else if (!strcmp(value, "stand-ground")) {
|
||||
condition->ButtonAction = ButtonStandGround;
|
||||
} else if (!strcmp(value, "attack-ground")) {
|
||||
|
|
|
@ -1006,6 +1006,8 @@ static int CclDefineButton(lua_State *l)
|
|||
ba.Action = ButtonTrain;
|
||||
} else if (!strcmp(value, "patrol")) {
|
||||
ba.Action = ButtonPatrol;
|
||||
} else if (!strcmp(value, "explore")) {
|
||||
ba.Action = ButtonExplore;
|
||||
} else if (!strcmp(value, "stand-ground")) {
|
||||
ba.Action = ButtonStandGround;
|
||||
} else if (!strcmp(value, "attack-ground")) {
|
||||
|
|
Loading…
Reference in a new issue