Split action_buil{d,t}.cpp
remove empty action_returngoods.cpp, action_stand.cpp
This commit is contained in:
parent
d3c2041d27
commit
c6b336bc73
5 changed files with 357 additions and 458 deletions
|
@ -42,6 +42,7 @@ set(action_SRCS
|
|||
src/action/action_attack.cpp
|
||||
src/action/action_board.cpp
|
||||
src/action/action_build.cpp
|
||||
src/action/action_built.cpp
|
||||
src/action/action_die.cpp
|
||||
src/action/action_follow.cpp
|
||||
src/action/action_move.cpp
|
||||
|
@ -49,14 +50,12 @@ set(action_SRCS
|
|||
src/action/action_repair.cpp
|
||||
src/action/action_research.cpp
|
||||
src/action/action_resource.cpp
|
||||
src/action/action_returngoods.cpp
|
||||
src/action/actions.cpp
|
||||
src/action/action_spellcast.cpp
|
||||
src/action/action_stand.cpp
|
||||
src/action/action_still.cpp
|
||||
src/action/action_train.cpp
|
||||
src/action/action_unload.cpp
|
||||
src/action/action_upgradeto.cpp
|
||||
src/action/actions.cpp
|
||||
src/action/command.cpp
|
||||
)
|
||||
source_group(action FILES ${action_SRCS})
|
||||
|
|
|
@ -38,22 +38,19 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "actions.h"
|
||||
#include "unittype.h"
|
||||
#include "animation.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "sound.h"
|
||||
#include "actions.h"
|
||||
#include "map.h"
|
||||
#include "ai.h"
|
||||
#include "pathfinder.h"
|
||||
#include "construct.h"
|
||||
#include "iolib.h"
|
||||
#include "script.h"
|
||||
|
||||
extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
State_Start = 0,
|
||||
|
@ -414,315 +411,4 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Action_built
|
||||
//////////////////////////
|
||||
|
||||
/* virtual */ void COrder_Built::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-built\", ");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
CConstructionFrame *cframe = unit.Type->Construction->Frames;
|
||||
int frame = 0;
|
||||
while (cframe != this->Frame) {
|
||||
cframe = cframe->Next;
|
||||
++frame;
|
||||
}
|
||||
if (this->Worker == NULL) {
|
||||
file.printf("\"worker\", \"%s\", ", UnitReference(this->Worker).c_str());
|
||||
}
|
||||
file.printf("\"progress\", %d, \"frame\", %d", this->ProgressCounter, frame);
|
||||
if (this->IsCancelled) {
|
||||
file.printf(", \"cancel\"");
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Built::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "worker")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->Worker = CclGetUnitFromRef(l);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "progress")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->ProgressCounter = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "cancel")) {
|
||||
this->IsCancelled = true;
|
||||
} else if (!strcmp(value, "frame")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
int frame = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
CConstructionFrame *cframe = unit.Type->Construction->Frames;
|
||||
while (frame--) {
|
||||
cframe = cframe->Next;
|
||||
}
|
||||
this->Frame = cframe;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void CancelBuilt(COrder_Built &order, CUnit &unit)
|
||||
{
|
||||
Assert(unit.CurrentOrder() == &order);
|
||||
CUnit *worker = order.GetWorkerPtr();
|
||||
|
||||
// Drop out unit
|
||||
if (worker != NULL) {
|
||||
worker->ClearAction();
|
||||
|
||||
// HACK: make sure the sight is updated correctly
|
||||
// unit.CurrentSightRange = 1;
|
||||
DropOutOnSide(*worker, LookingW, &unit);
|
||||
// unit.CurrentSightRange = 0;
|
||||
}
|
||||
// Player gets back 75% of the original cost for a building.
|
||||
unit.Player->AddCostsFactor(unit.Stats->Costs, CancelBuildingCostsFactor);
|
||||
// Cancel building
|
||||
LetUnitDie(unit);
|
||||
}
|
||||
|
||||
static void Finish(COrder_Built &order, CUnit& unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
CPlayer &player = *unit.Player;
|
||||
|
||||
DebugPrint("%d: Building %s(%s) ready.\n" _C_ player.Index _C_ type.Ident.c_str() _C_ type.Name.c_str() );
|
||||
|
||||
// HACK: the building is ready now
|
||||
player.UnitTypesCount[type.Slot]++;
|
||||
unit.Constructed = 0;
|
||||
if (unit.Frame < 0) {
|
||||
unit.Frame = -1;
|
||||
} else {
|
||||
unit.Frame = 0;
|
||||
}
|
||||
CUnit *worker = order.GetWorkerPtr();
|
||||
|
||||
if (worker != NULL) {
|
||||
if (type.BuilderLost) {
|
||||
// Bye bye worker.
|
||||
LetUnitDie(*worker);
|
||||
worker = NULL;
|
||||
} else { // Drop out the worker.
|
||||
worker->ClearAction();
|
||||
|
||||
DropOutOnSide(*worker, LookingW, &unit);
|
||||
|
||||
// If we can harvest from the new building, do it.
|
||||
if (worker->Type->ResInfo[type.GivesResource]) {
|
||||
CommandResource(*worker, unit, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type.GivesResource && type.StartingResources != 0) {
|
||||
// Has StartingResources, Use those
|
||||
unit.ResourcesHeld = type.StartingResources;
|
||||
}
|
||||
|
||||
player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y, _("New %s done"), type.Name.c_str());
|
||||
if (&player == ThisPlayer) {
|
||||
if (type.Sound.Ready.Sound) {
|
||||
PlayUnitSound(unit, VoiceReady);
|
||||
} else if (worker) {
|
||||
PlayUnitSound(*worker, VoiceWorkCompleted);
|
||||
} else {
|
||||
PlayUnitSound(unit, VoiceBuilding);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.AiEnabled) {
|
||||
/* Worker can be NULL */
|
||||
AiWorkComplete(worker, unit);
|
||||
}
|
||||
|
||||
// FIXME: Vladi: this is just a hack to test wall fixing,
|
||||
// FIXME: also not sure if the right place...
|
||||
// FIXME: Johns: hardcoded unit-type wall / more races!
|
||||
if (&type == UnitTypeOrcWall || &type == UnitTypeHumanWall) {
|
||||
Map.SetWall(unit.tilePos, &type == UnitTypeHumanWall);
|
||||
unit.Remove(NULL);
|
||||
UnitLost(unit);
|
||||
UnitClearOrders(unit);
|
||||
unit.Release();
|
||||
return ;
|
||||
}
|
||||
|
||||
UpdateForNewUnit(unit, 0);
|
||||
|
||||
// Set the direction of the building if it supports them
|
||||
if (type.NumDirections > 1) {
|
||||
if (type.Wall) { // Special logic for walls
|
||||
CorrectWallDirections(unit);
|
||||
CorrectWallNeighBours(unit);
|
||||
} else {
|
||||
unit.Direction = (MyRand() >> 8) & 0xFF; // random heading
|
||||
}
|
||||
UnitUpdateHeading(unit);
|
||||
}
|
||||
|
||||
if (IsOnlySelected(unit) || &player == ThisPlayer) {
|
||||
SelectedUnitChanged();
|
||||
}
|
||||
MapUnmarkUnitSight(unit);
|
||||
unit.CurrentSightRange = unit.Stats->Variables[SIGHTRANGE_INDEX].Max;
|
||||
MapMarkUnitSight(unit);
|
||||
order.Finished = true;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Built::Execute(CUnit &unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
|
||||
int amount;
|
||||
if (type.BuilderOutside) {
|
||||
amount = type.AutoBuildRate;
|
||||
} else {
|
||||
// FIXME: implement this below:
|
||||
// this->Data.Worker->Type->BuilderSpeedFactor;
|
||||
amount = 100;
|
||||
}
|
||||
this->Progress(unit, amount);
|
||||
|
||||
// Check if construction should be canceled...
|
||||
if (this->IsCancelled || this->ProgressCounter < 0) {
|
||||
DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index _C_ unit.Type->Name.c_str());
|
||||
|
||||
CancelBuilt(*this, unit);
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
const int maxProgress = type.Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// Check if building ready. Note we can both build and repair.
|
||||
if (!unit.Anim.Unbreakable && this->ProgressCounter >= maxProgress) {
|
||||
Finish(*this, unit);
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::Cancel(CUnit &unit)
|
||||
{
|
||||
this->IsCancelled = true;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::UpdateUnitVariables(CUnit &unit) const
|
||||
{
|
||||
Assert(unit.CurrentOrder() == this);
|
||||
|
||||
unit.Variable[BUILD_INDEX].Value = this->ProgressCounter;
|
||||
unit.Variable[BUILD_INDEX].Max = unit.Type->Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// This should happen when building unit with several peons
|
||||
// Maybe also with only one.
|
||||
// FIXME : Should be better to fix it in action_{build,repair}.c ?
|
||||
if (unit.Variable[BUILD_INDEX].Value > unit.Variable[BUILD_INDEX].Max) {
|
||||
// assume value is wrong.
|
||||
unit.Variable[BUILD_INDEX].Value = unit.Variable[BUILD_INDEX].Max;
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::FillSeenValues(CUnit &unit) const
|
||||
{
|
||||
unit.Seen.State = 1;
|
||||
unit.Seen.CFrame = this->Frame;
|
||||
}
|
||||
|
||||
/** Called when unit is killed.
|
||||
** warn the AI module.
|
||||
*/
|
||||
void COrder_Built::AiUnitKilled(CUnit& unit)
|
||||
{
|
||||
DebugPrint("%d: %d(%s) killed, under construction!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str());
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, *unit.Type);
|
||||
}
|
||||
|
||||
|
||||
static const CConstructionFrame *FindCFramePercent(const CConstructionFrame &cframe, int percent)
|
||||
{
|
||||
const CConstructionFrame *prev = &cframe;
|
||||
|
||||
for (const CConstructionFrame *it = cframe.Next; it; it = it->Next) {
|
||||
if (percent < it->Percent) {
|
||||
return prev;
|
||||
}
|
||||
prev = it;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
** Update construction frame
|
||||
**
|
||||
** @param unit The building under construction.
|
||||
*/
|
||||
void COrder_Built::UpdateConstructionFrame(CUnit &unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
const int percent = this->ProgressCounter / (type.Stats[unit.Player->Index].Costs[TimeCost] * 6);
|
||||
const CConstructionFrame *cframe = FindCFramePercent(*type.Construction->Frames, percent);
|
||||
|
||||
Assert(cframe != NULL);
|
||||
|
||||
if (cframe != this->Frame) {
|
||||
this->Frame = cframe;
|
||||
if (unit.Frame < 0) {
|
||||
unit.Frame = -cframe->Frame - 1;
|
||||
} else {
|
||||
unit.Frame = cframe->Frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void COrder_Built::Progress(CUnit &unit, int amount)
|
||||
{
|
||||
Boost(unit, amount, HP_INDEX);
|
||||
Boost(unit, amount, SHIELD_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * SpeedBuild;
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
void COrder_Built::ProgressHp(CUnit &unit, int amount)
|
||||
{
|
||||
Boost(unit, amount, HP_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * SpeedBuild;
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
|
||||
void COrder_Built::Boost(CUnit &building, int amount, int varIndex) const
|
||||
{
|
||||
Assert(building.CurrentOrder() == this);
|
||||
|
||||
const int costs = building.Stats->Costs[TimeCost] * 600;
|
||||
const int progress = this->ProgressCounter;
|
||||
const int newProgress = progress + amount * SpeedBuild;
|
||||
const int maxValue = building.Variable[varIndex].Max;
|
||||
|
||||
int ¤tValue = building.Variable[varIndex].Value;
|
||||
|
||||
// damageValue is the current damage taken by the unit.
|
||||
const int damageValue = (progress * maxValue) / costs - currentValue;
|
||||
|
||||
// Keep the same level of damage while increasing Value.
|
||||
currentValue = (newProgress * maxValue) / costs - damageValue;
|
||||
currentValue = std::min(currentValue, maxValue);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
353
src/action/action_built.cpp
Normal file
353
src/action/action_built.cpp
Normal file
|
@ -0,0 +1,353 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_build.cpp - The build building action. */
|
||||
//
|
||||
// (c) Copyright 1998-2012 by Lutz Sammer, Jimmy Salmon, and
|
||||
// Russell Smith
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "actions.h"
|
||||
#include "unittype.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "sound.h"
|
||||
#include "map.h"
|
||||
#include "ai.h"
|
||||
#include "construct.h"
|
||||
#include "iolib.h"
|
||||
#include "script.h"
|
||||
|
||||
extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
||||
|
||||
/* virtual */ void COrder_Built::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-built\", ");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
CConstructionFrame *cframe = unit.Type->Construction->Frames;
|
||||
int frame = 0;
|
||||
while (cframe != this->Frame) {
|
||||
cframe = cframe->Next;
|
||||
++frame;
|
||||
}
|
||||
if (this->Worker == NULL) {
|
||||
file.printf("\"worker\", \"%s\", ", UnitReference(this->Worker).c_str());
|
||||
}
|
||||
file.printf("\"progress\", %d, \"frame\", %d", this->ProgressCounter, frame);
|
||||
if (this->IsCancelled) {
|
||||
file.printf(", \"cancel\"");
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Built::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "worker")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->Worker = CclGetUnitFromRef(l);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "progress")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->ProgressCounter = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "cancel")) {
|
||||
this->IsCancelled = true;
|
||||
} else if (!strcmp(value, "frame")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
int frame = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
CConstructionFrame *cframe = unit.Type->Construction->Frames;
|
||||
while (frame--) {
|
||||
cframe = cframe->Next;
|
||||
}
|
||||
this->Frame = cframe;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void CancelBuilt(COrder_Built &order, CUnit &unit)
|
||||
{
|
||||
Assert(unit.CurrentOrder() == &order);
|
||||
CUnit *worker = order.GetWorkerPtr();
|
||||
|
||||
// Drop out unit
|
||||
if (worker != NULL) {
|
||||
worker->ClearAction();
|
||||
|
||||
DropOutOnSide(*worker, LookingW, &unit);
|
||||
}
|
||||
// Player gets back 75% of the original cost for a building.
|
||||
unit.Player->AddCostsFactor(unit.Stats->Costs, CancelBuildingCostsFactor);
|
||||
// Cancel building
|
||||
LetUnitDie(unit);
|
||||
}
|
||||
|
||||
static void Finish(COrder_Built &order, CUnit& unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
CPlayer &player = *unit.Player;
|
||||
|
||||
DebugPrint("%d: Building %s(%s) ready.\n" _C_ player.Index _C_ type.Ident.c_str() _C_ type.Name.c_str() );
|
||||
|
||||
// HACK: the building is ready now
|
||||
player.UnitTypesCount[type.Slot]++;
|
||||
unit.Constructed = 0;
|
||||
if (unit.Frame < 0) {
|
||||
unit.Frame = -1;
|
||||
} else {
|
||||
unit.Frame = 0;
|
||||
}
|
||||
CUnit *worker = order.GetWorkerPtr();
|
||||
|
||||
if (worker != NULL) {
|
||||
if (type.BuilderLost) {
|
||||
// Bye bye worker.
|
||||
LetUnitDie(*worker);
|
||||
worker = NULL;
|
||||
} else { // Drop out the worker.
|
||||
worker->ClearAction();
|
||||
|
||||
DropOutOnSide(*worker, LookingW, &unit);
|
||||
|
||||
// If we can harvest from the new building, do it.
|
||||
if (worker->Type->ResInfo[type.GivesResource]) {
|
||||
CommandResource(*worker, unit, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type.GivesResource && type.StartingResources != 0) {
|
||||
// Has StartingResources, Use those
|
||||
unit.ResourcesHeld = type.StartingResources;
|
||||
}
|
||||
|
||||
player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y, _("New %s done"), type.Name.c_str());
|
||||
if (&player == ThisPlayer) {
|
||||
if (type.Sound.Ready.Sound) {
|
||||
PlayUnitSound(unit, VoiceReady);
|
||||
} else if (worker) {
|
||||
PlayUnitSound(*worker, VoiceWorkCompleted);
|
||||
} else {
|
||||
PlayUnitSound(unit, VoiceBuilding);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.AiEnabled) {
|
||||
/* Worker can be NULL */
|
||||
AiWorkComplete(worker, unit);
|
||||
}
|
||||
|
||||
// FIXME: Vladi: this is just a hack to test wall fixing,
|
||||
// FIXME: also not sure if the right place...
|
||||
// FIXME: Johns: hardcoded unit-type wall / more races!
|
||||
if (&type == UnitTypeOrcWall || &type == UnitTypeHumanWall) {
|
||||
Map.SetWall(unit.tilePos, &type == UnitTypeHumanWall);
|
||||
unit.Remove(NULL);
|
||||
UnitLost(unit);
|
||||
UnitClearOrders(unit);
|
||||
unit.Release();
|
||||
return ;
|
||||
}
|
||||
|
||||
UpdateForNewUnit(unit, 0);
|
||||
|
||||
// Set the direction of the building if it supports them
|
||||
if (type.NumDirections > 1) {
|
||||
if (type.Wall) { // Special logic for walls
|
||||
CorrectWallDirections(unit);
|
||||
CorrectWallNeighBours(unit);
|
||||
} else {
|
||||
unit.Direction = (MyRand() >> 8) & 0xFF; // random heading
|
||||
}
|
||||
UnitUpdateHeading(unit);
|
||||
}
|
||||
|
||||
if (IsOnlySelected(unit) || &player == ThisPlayer) {
|
||||
SelectedUnitChanged();
|
||||
}
|
||||
MapUnmarkUnitSight(unit);
|
||||
unit.CurrentSightRange = unit.Stats->Variables[SIGHTRANGE_INDEX].Max;
|
||||
MapMarkUnitSight(unit);
|
||||
order.Finished = true;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Built::Execute(CUnit &unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
|
||||
int amount;
|
||||
if (type.BuilderOutside) {
|
||||
amount = type.AutoBuildRate;
|
||||
} else {
|
||||
// FIXME: implement this below:
|
||||
// this->Data.Worker->Type->BuilderSpeedFactor;
|
||||
amount = 100;
|
||||
}
|
||||
this->Progress(unit, amount);
|
||||
|
||||
// Check if construction should be canceled...
|
||||
if (this->IsCancelled || this->ProgressCounter < 0) {
|
||||
DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index _C_ unit.Type->Name.c_str());
|
||||
|
||||
CancelBuilt(*this, unit);
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
const int maxProgress = type.Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// Check if building ready. Note we can both build and repair.
|
||||
if (!unit.Anim.Unbreakable && this->ProgressCounter >= maxProgress) {
|
||||
Finish(*this, unit);
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::Cancel(CUnit &unit)
|
||||
{
|
||||
this->IsCancelled = true;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::UpdateUnitVariables(CUnit &unit) const
|
||||
{
|
||||
Assert(unit.CurrentOrder() == this);
|
||||
|
||||
unit.Variable[BUILD_INDEX].Value = this->ProgressCounter;
|
||||
unit.Variable[BUILD_INDEX].Max = unit.Type->Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// This should happen when building unit with several peons
|
||||
// Maybe also with only one.
|
||||
// FIXME : Should be better to fix it in action_{build,repair}.c ?
|
||||
if (unit.Variable[BUILD_INDEX].Value > unit.Variable[BUILD_INDEX].Max) {
|
||||
// assume value is wrong.
|
||||
unit.Variable[BUILD_INDEX].Value = unit.Variable[BUILD_INDEX].Max;
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::FillSeenValues(CUnit &unit) const
|
||||
{
|
||||
unit.Seen.State = 1;
|
||||
unit.Seen.CFrame = this->Frame;
|
||||
}
|
||||
|
||||
/** Called when unit is killed.
|
||||
** warn the AI module.
|
||||
*/
|
||||
void COrder_Built::AiUnitKilled(CUnit& unit)
|
||||
{
|
||||
DebugPrint("%d: %d(%s) killed, under construction!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str());
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, *unit.Type);
|
||||
}
|
||||
|
||||
|
||||
static const CConstructionFrame *FindCFramePercent(const CConstructionFrame &cframe, int percent)
|
||||
{
|
||||
const CConstructionFrame *prev = &cframe;
|
||||
|
||||
for (const CConstructionFrame *it = cframe.Next; it; it = it->Next) {
|
||||
if (percent < it->Percent) {
|
||||
return prev;
|
||||
}
|
||||
prev = it;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
** Update construction frame
|
||||
**
|
||||
** @param unit The building under construction.
|
||||
*/
|
||||
void COrder_Built::UpdateConstructionFrame(CUnit &unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
const int percent = this->ProgressCounter / (type.Stats[unit.Player->Index].Costs[TimeCost] * 6);
|
||||
const CConstructionFrame *cframe = FindCFramePercent(*type.Construction->Frames, percent);
|
||||
|
||||
Assert(cframe != NULL);
|
||||
|
||||
if (cframe != this->Frame) {
|
||||
this->Frame = cframe;
|
||||
if (unit.Frame < 0) {
|
||||
unit.Frame = -cframe->Frame - 1;
|
||||
} else {
|
||||
unit.Frame = cframe->Frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void COrder_Built::Progress(CUnit &unit, int amount)
|
||||
{
|
||||
Boost(unit, amount, HP_INDEX);
|
||||
Boost(unit, amount, SHIELD_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * SpeedBuild;
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
void COrder_Built::ProgressHp(CUnit &unit, int amount)
|
||||
{
|
||||
Boost(unit, amount, HP_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * SpeedBuild;
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
|
||||
void COrder_Built::Boost(CUnit &building, int amount, int varIndex) const
|
||||
{
|
||||
Assert(building.CurrentOrder() == this);
|
||||
|
||||
const int costs = building.Stats->Costs[TimeCost] * 600;
|
||||
const int progress = this->ProgressCounter;
|
||||
const int newProgress = progress + amount * SpeedBuild;
|
||||
const int maxValue = building.Variable[varIndex].Max;
|
||||
|
||||
int ¤tValue = building.Variable[varIndex].Value;
|
||||
|
||||
// damageValue is the current damage taken by the unit.
|
||||
const int damageValue = (progress * maxValue) / costs - currentValue;
|
||||
|
||||
// Keep the same level of damage while increasing Value.
|
||||
currentValue = (newProgress * maxValue) / costs - damageValue;
|
||||
currentValue = std::min(currentValue, maxValue);
|
||||
}
|
||||
|
||||
//@}
|
|
@ -1,94 +0,0 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_returngoods.cpp - The return goods action. */
|
||||
//
|
||||
// (c) Copyright 1998-2005 by Lutz Sammer and Jimmy Salmon
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Include
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "unittype.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "pathfinder.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
/**
|
||||
** Return goods to gold/wood deposit.
|
||||
**
|
||||
** @param unit pointer to unit.
|
||||
**
|
||||
** @todo FIXME: move this into action_resource?
|
||||
*/
|
||||
void HandleActionReturnGoods(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(unit.Type->Harvester);
|
||||
|
||||
// Select target to return goods.
|
||||
if (!unit.CurrentResource || unit.ResourcesHeld == 0 ||
|
||||
(unit.ResourcesHeld != unit.Type->ResInfo[unit.CurrentResource]->ResourceCapacity &&
|
||||
unit.Type->ResInfo[unit.CurrentResource]->LoseResources)) {
|
||||
DebugPrint("Unit can't return resources, it doesn't carry any.\n");
|
||||
unit.Player->Notify(NotifyYellow, unit.tilePos.x, unit.tilePos.y, _("No Resources to Return."));
|
||||
|
||||
ResourceGiveUp(unit);
|
||||
return;
|
||||
}
|
||||
|
||||
// If depot was destroyed search for another one.
|
||||
if (!order.HasGoal()) {
|
||||
CUnit *destu;
|
||||
|
||||
if (!(destu = FindDeposit(unit, 1000, unit.CurrentResource))) {
|
||||
ResourceGiveUp(unit);
|
||||
return;
|
||||
}
|
||||
order.SetGoal(destu);
|
||||
}
|
||||
|
||||
order.Action = UnitActionResource;
|
||||
// Somewhere on the way the loaded worker could have change Arg1
|
||||
// Bummer, go get the closest resource to the depot
|
||||
//FIXME!!!!!!!!!!!!!!!!!!!!
|
||||
//unit.CurrentOrder()->Arg1.ResourcePos = -1;
|
||||
|
||||
order.NewResetPath();
|
||||
order.SubAction.Res = /* SUB_MOVE_TO_DEPOT */ 70; // FIXME : Define value.
|
||||
}
|
||||
#endif
|
||||
//@}
|
|
@ -1,45 +0,0 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_stand.cpp - The stand ground action. */
|
||||
//
|
||||
// (c) Copyright 2000-2006 by Lutz Sammer and Jimmy Salmon
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
//@}
|
Loading…
Reference in a new issue