merge lp:stratagus
This commit is contained in:
commit
a7e147a480
92 changed files with 805 additions and 345 deletions
CMakeLists.txt
src
action
action_built.cppaction_follow.cppaction_research.cppaction_resource.cppaction_spellcast.cppaction_train.cppaction_upgradeto.cppcommand.cpp
ai
animation
animation.cppanimation_attack.cppanimation_die.cppanimation_exactframe.cppanimation_frame.cppanimation_goto.cppanimation_ifvar.cppanimation_label.cppanimation_luacallback.cppanimation_move.cppanimation_randomgoto.cppanimation_randomrotate.cppanimation_randomsound.cppanimation_randomwait.cppanimation_rotate.cppanimation_setplayervar.cppanimation_setvar.cppanimation_sound.cppanimation_spawnmissile.cppanimation_spawnunit.cppanimation_unbreakable.cppanimation_wait.cpp
include
animation.h
animation
animation_attack.hanimation_die.hanimation_exactframe.hanimation_frame.hanimation_goto.hanimation_ifvar.hanimation_label.hanimation_luacallback.hanimation_move.hanimation_randomgoto.hanimation_randomrotate.hanimation_randomsound.hanimation_randomwait.hanimation_rotate.hanimation_setplayervar.hanimation_setvar.hanimation_sound.hanimation_spawnmissile.hanimation_spawnunit.hanimation_unbreakable.hanimation_wait.h
particle.hspell
spells.hunit.hunit_find.hunittype.hwidgets.hmap
particle
sound
spell
tolua
ui
unit
video
tests/network
|
@ -90,6 +90,7 @@ set(animation_SRCS
|
|||
src/animation/animation_goto.cpp
|
||||
src/animation/animation_ifvar.cpp
|
||||
src/animation/animation_label.cpp
|
||||
src/animation/animation_luacallback.cpp
|
||||
src/animation/animation_move.cpp
|
||||
src/animation/animation_randomgoto.cpp
|
||||
src/animation/animation_randomrotate.cpp
|
||||
|
@ -475,6 +476,7 @@ set(stratagus_animation_HDRS
|
|||
src/include/animation/animation_goto.h
|
||||
src/include/animation/animation_ifvar.h
|
||||
src/include/animation/animation_label.h
|
||||
src/include/animation/animation_luacallback.h
|
||||
src/include/animation/animation_move.h
|
||||
src/include/animation/animation_randomgoto.h
|
||||
src/include/animation/animation_randomrotate.h
|
||||
|
|
|
@ -346,7 +346,7 @@ void COrder_Built::Progress(CUnit &unit, int amount)
|
|||
Boost(unit, amount, HP_INDEX);
|
||||
Boost(unit, amount, SHIELD_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * unit.Player->SpeedBuild / SPEEDUP_FACTOR;
|
||||
this->ProgressCounter += std::max(1, amount * unit.Player->SpeedBuild / SPEEDUP_FACTOR);
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ void COrder_Built::ProgressHp(CUnit &unit, int amount)
|
|||
{
|
||||
Boost(unit, amount, HP_INDEX);
|
||||
|
||||
this->ProgressCounter += amount * unit.Player->SpeedBuild / SPEEDUP_FACTOR;
|
||||
this->ProgressCounter += std::max(1, amount * unit.Player->SpeedBuild / SPEEDUP_FACTOR);
|
||||
UpdateConstructionFrame(unit);
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,7 @@ void COrder_Built::Boost(CUnit &building, int amount, int varIndex) const
|
|||
|
||||
const int costs = building.Stats->Costs[TimeCost] * 600;
|
||||
const int progress = this->ProgressCounter;
|
||||
const int newProgress = progress + amount * building.Player->SpeedBuild / SPEEDUP_FACTOR;
|
||||
const int newProgress = progress + std::max(1, amount * building.Player->SpeedBuild / SPEEDUP_FACTOR);
|
||||
const int maxValue = building.Variable[varIndex].Max;
|
||||
|
||||
int ¤tValue = building.Variable[varIndex].Value;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "action/action_follow.h"
|
||||
|
||||
#include "iolib.h"
|
||||
#include "missile.h"
|
||||
#include "pathfinder.h"
|
||||
#include "script.h"
|
||||
#include "ui.h"
|
||||
|
@ -168,6 +169,12 @@ enum {
|
|||
return ;
|
||||
}
|
||||
|
||||
// Don't follow after immobile units
|
||||
if (goal && goal->CanMove() == false) {
|
||||
this->Finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (goal->tilePos == this->goalPos) {
|
||||
// Move to the next order
|
||||
if (unit.Orders.size() > 1) {
|
||||
|
@ -204,42 +211,51 @@ enum {
|
|||
// Handle Teleporter Units
|
||||
// FIXME: BAD HACK
|
||||
// goal shouldn't be busy and portal should be alive
|
||||
if (goal->Type->Teleporter && goal->IsIdle() && goal->Goal
|
||||
&& goal->Goal->IsAlive() && unit.MapDistanceTo(*goal) <= 1) {
|
||||
// Teleport the unit
|
||||
unit.Remove(NULL);
|
||||
unit.tilePos = goal->Goal->tilePos;
|
||||
DropOutOnSide(unit, unit.Direction, NULL);
|
||||
#if 0
|
||||
// FIXME: SoundForName() should be called once
|
||||
PlayGameSound(SoundForName("invisibility"), MaxSampleVolume);
|
||||
// FIXME: MissileTypeByIdent() should be called once
|
||||
MakeMissile(MissileTypeByIdent("missile-normal-spell"),
|
||||
unit.GetMapPixelPosCenter(),
|
||||
unit.GetMapPixelPosCenter());
|
||||
#endif
|
||||
// FIXME: we must check if the units supports the new order.
|
||||
CUnit &dest = *goal->Goal;
|
||||
if (goal->Type->Teleporter && goal->Goal && goal->Goal->IsAlive() && unit.MapDistanceTo(*goal) <= 1) {
|
||||
if (!goal->IsIdle()) { // wait
|
||||
unit.Wait = 10;
|
||||
return;
|
||||
}
|
||||
// Check if we have enough mana
|
||||
if (goal->Goal->Type->TeleportCost > goal->Variable[MANA_INDEX].Value) {
|
||||
this->Finished = true;
|
||||
return;
|
||||
} else {
|
||||
goal->Variable[MANA_INDEX].Value -= goal->Goal->Type->TeleportCost;
|
||||
}
|
||||
// Everything is OK, now teleport the unit
|
||||
unit.Remove(NULL);
|
||||
if (goal->Type->TeleportEffect.Missile) {
|
||||
MakeMissile(*goal->Type->TeleportEffect.Missile, unit.GetMapPixelPosCenter(), unit.GetMapPixelPosCenter());
|
||||
}
|
||||
unit.tilePos = goal->Goal->tilePos;
|
||||
DropOutOnSide(unit, unit.Direction, NULL);
|
||||
|
||||
if (dest.NewOrder == NULL
|
||||
|| (dest.NewOrder->Action == UnitActionResource && !unit.Type->Harvester)
|
||||
|| (dest.NewOrder->Action == UnitActionAttack && !unit.Type->CanAttack)
|
||||
|| (dest.NewOrder->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand)) {
|
||||
this->Finished = true;
|
||||
return ;
|
||||
} else {
|
||||
if (dest.NewOrder->HasGoal()) {
|
||||
if (dest.NewOrder->GetGoal()->Destroyed) {
|
||||
delete dest.NewOrder;
|
||||
dest.NewOrder = NULL;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
// FIXME: we must check if the units supports the new order.
|
||||
CUnit &dest = *goal->Goal;
|
||||
if (dest.Type->TeleportEffect.Missile) {
|
||||
MakeMissile(*dest.Type->TeleportEffect.Missile, unit.GetMapPixelPosCenter(), unit.GetMapPixelPosCenter());
|
||||
}
|
||||
|
||||
if (dest.NewOrder == NULL
|
||||
|| (dest.NewOrder->Action == UnitActionResource && !unit.Type->Harvester)
|
||||
|| (dest.NewOrder->Action == UnitActionAttack && !unit.Type->CanAttack)
|
||||
|| (dest.NewOrder->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand)) {
|
||||
this->Finished = true;
|
||||
return ;
|
||||
} else {
|
||||
if (dest.NewOrder->HasGoal()) {
|
||||
if (dest.NewOrder->GetGoal()->Destroyed) {
|
||||
delete dest.NewOrder;
|
||||
dest.NewOrder = NULL;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
unit.Orders.insert(unit.Orders.begin() + 1, dest.NewOrder->Clone());
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->goalPos = goal->tilePos;
|
||||
this->State = State_TargetReached;
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
}
|
||||
#endif
|
||||
CPlayer &player = *unit.Player;
|
||||
player.UpgradeTimers.Upgrades[upgrade.ID] += player.SpeedResearch / SPEEDUP_FACTOR;
|
||||
player.UpgradeTimers.Upgrades[upgrade.ID] += std::max(1, player.SpeedResearch / SPEEDUP_FACTOR);
|
||||
if (player.UpgradeTimers.Upgrades[upgrade.ID] >= upgrade.Costs[TimeCost]) {
|
||||
player.Notify(NotifyGreen, unit.tilePos, _("%s: research complete"), type.Name.c_str());
|
||||
if (&player == ThisPlayer) {
|
||||
|
|
|
@ -470,7 +470,7 @@ int COrder_Resource::StartGathering(CUnit &unit)
|
|||
#endif
|
||||
UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
|
||||
if (resinfo.WaitAtResource) {
|
||||
this->TimeToHarvest = resinfo.WaitAtResource / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId] * SPEEDUP_FACTOR;
|
||||
this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
|
||||
} else {
|
||||
this->TimeToHarvest = 1;
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ int COrder_Resource::StartGathering(CUnit &unit)
|
|||
goal->Resource.Active++;
|
||||
|
||||
if (resinfo.WaitAtResource) {
|
||||
this->TimeToHarvest = resinfo.WaitAtResource / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId] * SPEEDUP_FACTOR;
|
||||
this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
|
||||
} else {
|
||||
this->TimeToHarvest = 1;
|
||||
}
|
||||
|
@ -671,7 +671,7 @@ int COrder_Resource::GatherResource(CUnit &unit)
|
|||
while (!this->DoneHarvesting && this->TimeToHarvest < 0) {
|
||||
//FIXME: rb - how should it look for WaitAtResource == 0
|
||||
if (resinfo.WaitAtResource) {
|
||||
this->TimeToHarvest += resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId];
|
||||
this->TimeToHarvest += std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
|
||||
} else {
|
||||
this->TimeToHarvest += 1;
|
||||
}
|
||||
|
@ -954,7 +954,7 @@ int COrder_Resource::MoveToDepot(CUnit &unit)
|
|||
unit.CurrentResource = 0;
|
||||
|
||||
if (unit.Wait) {
|
||||
unit.Wait /= unit.Player->SpeedResourcesReturn[resinfo.ResourceId] / SPEEDUP_FACTOR;
|
||||
unit.Wait /= std::max(1, unit.Player->SpeedResourcesReturn[resinfo.ResourceId] / SPEEDUP_FACTOR);
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
}
|
||||
|
@ -1103,6 +1103,9 @@ bool COrder_Resource::ActionResourceInit(CUnit &unit)
|
|||
unit.DeAssignWorkerFromMine(*mine);
|
||||
this->Resource.Mine = NULL;
|
||||
}
|
||||
if (goal && goal->IsAlive() == false) {
|
||||
return false;
|
||||
}
|
||||
if (goal && goal->CurrentAction() != UnitActionBuilt) {
|
||||
unit.AssignWorkerToMine(*goal);
|
||||
this->Resource.Mine = goal;
|
||||
|
@ -1133,6 +1136,7 @@ void COrder_Resource::Execute(CUnit &unit)
|
|||
// Let's start mining.
|
||||
if (this->State == SUB_START_RESOURCE) {
|
||||
if (ActionResourceInit(unit) == false) {
|
||||
ResourceGiveUp(unit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
}
|
||||
// FALL THROUGH
|
||||
case 2: // Cast spell on the target.
|
||||
if (!spell.IsCasterOnly()) {
|
||||
if (!spell.IsCasterOnly() || spell.ForceUseAnimation) {
|
||||
AnimateActionSpellCast(unit, *this);
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return ;
|
||||
|
|
|
@ -183,7 +183,7 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
CPlayer &player = *unit.Player;
|
||||
const CUnitType &nType = *this->Type;
|
||||
const int cost = nType.Stats[player.Index].Costs[TimeCost];
|
||||
this->Ticks += player.SpeedTrain / SPEEDUP_FACTOR;
|
||||
this->Ticks += std::max(1, player.SpeedTrain / SPEEDUP_FACTOR);
|
||||
|
||||
if (this->Ticks < cost) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
|
|
|
@ -260,7 +260,7 @@ static void AnimateActionUpgradeTo(CUnit &unit)
|
|||
const CUnitType &newtype = *this->Type;
|
||||
const CUnitStats &newstats = newtype.Stats[player.Index];
|
||||
|
||||
this->Ticks += player.SpeedUpgrade / SPEEDUP_FACTOR;
|
||||
this->Ticks += std::max(1, player.SpeedUpgrade / SPEEDUP_FACTOR);
|
||||
if (this->Ticks < newstats.Costs[TimeCost]) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return ;
|
||||
|
|
|
@ -36,7 +36,10 @@
|
|||
#include "stratagus.h"
|
||||
|
||||
#include "actions.h"
|
||||
#include "action/action_built.h"
|
||||
#include "action/action_research.h"
|
||||
#include "action/action_train.h"
|
||||
#include "action/action_upgradeto.h"
|
||||
#include "commands.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
|
@ -63,8 +66,19 @@ static void ReleaseOrders(CUnit &unit)
|
|||
Assert(unit.Orders.empty() == false);
|
||||
|
||||
// Order 0 must be stopped in the action loop.
|
||||
for (size_t i = 1; i != unit.Orders.size(); ++i) {
|
||||
delete unit.Orders[i];
|
||||
for (size_t i = 0; i != unit.Orders.size(); ++i) {
|
||||
if (unit.Orders[i]->Action == UnitActionBuilt) {
|
||||
(dynamic_cast<COrder_Built *>(unit.Orders[i]))->Cancel(unit);
|
||||
} else if (unit.Orders[i]->Action == UnitActionResearch) {
|
||||
(dynamic_cast<COrder_Research *>(unit.Orders[i]))->Cancel(unit);
|
||||
} else if (unit.Orders[i]->Action == UnitActionTrain) {
|
||||
(dynamic_cast<COrder_Train *>(unit.Orders[i]))->Cancel(unit);
|
||||
} else if (unit.Orders[i]->Action == UnitActionUpgradeTo) {
|
||||
(dynamic_cast<COrder_UpgradeTo *>(unit.Orders[i]))->Cancel(unit);
|
||||
}
|
||||
if (i > 0) {
|
||||
delete unit.Orders[i];
|
||||
}
|
||||
}
|
||||
unit.Orders.resize(1);
|
||||
unit.Orders[0]->Finished = true;
|
||||
|
|
|
@ -670,7 +670,7 @@ void AiHelpMe(const CUnit *attacker, CUnit &defender)
|
|||
return;
|
||||
}
|
||||
// Summoned unit, don't help
|
||||
if (defender.GroupId == -1) {
|
||||
if (defender.Summoned) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -448,14 +448,14 @@ void AiForce::ReturnToHome()
|
|||
|
||||
AiForceManager::AiForceManager()
|
||||
{
|
||||
forces.resize(3);
|
||||
forces.resize(AI_MAX_FORCES);
|
||||
memset(script, -1, AI_MAX_FORCES * sizeof(char));
|
||||
}
|
||||
|
||||
unsigned int AiForceManager::FindFreeForce(AiForceRole role)
|
||||
unsigned int AiForceManager::FindFreeForce(AiForceRole role, int begin)
|
||||
{
|
||||
/* find free force */
|
||||
unsigned int f = 0;
|
||||
unsigned int f = begin;
|
||||
while (f < forces.size() && (forces[f].State > AiForceAttackingState_Free)) {
|
||||
++f;
|
||||
};
|
||||
|
@ -467,6 +467,30 @@ unsigned int AiForceManager::FindFreeForce(AiForceRole role)
|
|||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
** Find unit in force
|
||||
**
|
||||
** @param unit Unit to search for.
|
||||
**
|
||||
** @return Force number, or -1 if not found
|
||||
*/
|
||||
|
||||
int AiForceManager::GetForce(const CUnit &unit)
|
||||
{
|
||||
for (unsigned int i = 0; i < forces.size(); ++i) {
|
||||
AiForce &force = forces[i];
|
||||
|
||||
for (unsigned int j = 0; j < force.Units.size(); ++j) {
|
||||
CUnit &aiunit = *force.Units[j];
|
||||
|
||||
if (UnitNumber(unit) == UnitNumber(aiunit)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Cleanup units in forces.
|
||||
*/
|
||||
|
@ -591,7 +615,7 @@ void AiAttackWithForceAt(unsigned int force, int x, int y)
|
|||
{
|
||||
const Vec2i pos(x, y);
|
||||
|
||||
if (!(force < AI_MAX_FORCES)) {
|
||||
if (!(force < AI_MAX_FORCE_INTERNAL)) {
|
||||
DebugPrint("Force out of range: %d" _C_ force);
|
||||
return ;
|
||||
}
|
||||
|
@ -611,7 +635,7 @@ void AiAttackWithForceAt(unsigned int force, int x, int y)
|
|||
*/
|
||||
void AiAttackWithForce(unsigned int force)
|
||||
{
|
||||
if (!(force < AI_MAX_FORCES)) {
|
||||
if (!(force < AI_MAX_FORCE_INTERNAL)) {
|
||||
DebugPrint("Force out of range: %d" _C_ force);
|
||||
return ;
|
||||
}
|
||||
|
@ -620,7 +644,7 @@ void AiAttackWithForce(unsigned int force)
|
|||
// the first force, so we can reuse it
|
||||
if (!AiPlayer->Force[force].Defending) {
|
||||
unsigned int top;
|
||||
unsigned int f = AiPlayer->Force.FindFreeForce();
|
||||
unsigned int f = AiPlayer->Force.FindFreeForce(AiForceRoleDefault, AI_MAX_FORCE_INTERNAL);
|
||||
AiPlayer->Force[f].Reset();
|
||||
|
||||
AiPlayer->Force[f].Role = AiPlayer->Force[force].Role;
|
||||
|
@ -658,7 +682,7 @@ void AiAttackWithForces(int *forces)
|
|||
const Vec2i invalidPos(-1, -1);
|
||||
bool found = false;
|
||||
unsigned int top;
|
||||
unsigned int f = AiPlayer->Force.FindFreeForce();
|
||||
unsigned int f = AiPlayer->Force.FindFreeForce(AiForceRoleDefault, AI_MAX_FORCE_INTERNAL);
|
||||
|
||||
AiPlayer->Force[f].Reset();
|
||||
|
||||
|
|
|
@ -159,12 +159,12 @@ public:
|
|||
|
||||
void ReturnToHome();
|
||||
bool NewRallyPoint(const Vec2i &startPos, Vec2i *resultPos);
|
||||
void Insert(CUnit &unit);
|
||||
|
||||
private:
|
||||
void CountTypes(unsigned int *counter, const size_t len);
|
||||
bool IsBelongsTo(const CUnitType &type);
|
||||
void Insert(CUnit &unit);
|
||||
|
||||
|
||||
void Update();
|
||||
|
||||
static void InternalRemoveUnit(CUnit *unit);
|
||||
|
@ -186,7 +186,8 @@ public:
|
|||
};
|
||||
|
||||
// forces
|
||||
#define AI_MAX_FORCES 50 /// How many forces are supported
|
||||
#define AI_MAX_FORCES 50 /// How many forces are supported
|
||||
#define AI_MAX_FORCE_INTERNAL (AI_MAX_FORCES / 2) /// The forces after AI_MAX_FORCE_INTERNAL are for internal use
|
||||
|
||||
/**
|
||||
** AI force manager.
|
||||
|
@ -219,10 +220,11 @@ public:
|
|||
return script[index];
|
||||
}
|
||||
|
||||
int GetForce(const CUnit &unit);
|
||||
void RemoveDeadUnit();
|
||||
bool Assign(CUnit &unit);
|
||||
void Update();
|
||||
unsigned int FindFreeForce(AiForceRole role = AiForceRoleDefault);
|
||||
unsigned int FindFreeForce(AiForceRole role = AiForceRoleDefault, int begin = 0);
|
||||
void CheckUnits(int *counter);
|
||||
private:
|
||||
std::vector<AiForce> forces;
|
||||
|
|
|
@ -116,14 +116,14 @@ class WallFinder
|
|||
{
|
||||
public:
|
||||
WallFinder(const CUnit &unit, int maxDist, Vec2i *resultPos) :
|
||||
unit(unit),
|
||||
// unit(unit),
|
||||
maxDist(maxDist),
|
||||
movemask(unit.Type->MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)),
|
||||
resultPos(resultPos)
|
||||
{}
|
||||
VisitResult Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from);
|
||||
private:
|
||||
const CUnit &unit;
|
||||
// const CUnit &unit;
|
||||
int maxDist;
|
||||
int movemask;
|
||||
Vec2i *resultPos;
|
||||
|
@ -213,12 +213,12 @@ class ReachableTerrainMarker
|
|||
{
|
||||
public:
|
||||
ReachableTerrainMarker(const CUnit &unit) :
|
||||
unit(unit),
|
||||
// unit(unit),
|
||||
movemask(unit.Type->MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit))
|
||||
{}
|
||||
VisitResult Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from);
|
||||
private:
|
||||
const CUnit &unit;
|
||||
// const CUnit &unit;
|
||||
int movemask;
|
||||
};
|
||||
|
||||
|
|
|
@ -692,7 +692,7 @@ static int CclAiForce(lua_State *l)
|
|||
resetForce = LuaToBoolean(l, 3);
|
||||
}
|
||||
int force = LuaToNumber(l, 1);
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
LuaError(l, "Force out of range: %d" _C_ force);
|
||||
}
|
||||
AiForce &aiforce = AiPlayer->Force[AiPlayer->Force.getScriptForce(force)];
|
||||
|
@ -762,7 +762,7 @@ static int CclAiForceRole(lua_State *l)
|
|||
{
|
||||
LuaCheckArgs(l, 2);
|
||||
int force = LuaToNumber(l, 1);
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
LuaError(l, "Force %i out of range" _C_ force);
|
||||
}
|
||||
|
||||
|
@ -789,7 +789,7 @@ static int CclAiCheckForce(lua_State *l)
|
|||
{
|
||||
LuaCheckArgs(l, 1);
|
||||
int force = LuaToNumber(l, 1);
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
lua_pushfstring(l, "Force out of range: %d", force);
|
||||
}
|
||||
if (AiPlayer->Force[AiPlayer->Force.getScriptForce(force)].Completed) {
|
||||
|
@ -809,7 +809,7 @@ static int CclAiWaitForce(lua_State *l)
|
|||
{
|
||||
LuaCheckArgs(l, 1);
|
||||
int force = LuaToNumber(l, 1);
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
lua_pushfstring(l, "Force out of range: %d", force);
|
||||
}
|
||||
if (AiPlayer->Force[AiPlayer->Force.getScriptForce(force)].Completed) {
|
||||
|
@ -834,7 +834,7 @@ static int CclAiAttackWithForce(lua_State *l)
|
|||
{
|
||||
LuaCheckArgs(l, 1);
|
||||
int force = LuaToNumber(l, 1);
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
LuaError(l, "Force out of range: %d" _C_ force);
|
||||
}
|
||||
AiAttackWithForce(AiPlayer->Force.getScriptForce(force));
|
||||
|
@ -857,7 +857,7 @@ static int CclAiWaitForces(lua_State *l)
|
|||
for (int i = 0; i < args; ++i) {
|
||||
const int force = LuaToNumber(l, 1, i + 1);
|
||||
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
lua_pushfstring(l, "Force out of range: %d", force);
|
||||
}
|
||||
if (!AiPlayer->Force[AiPlayer->Force.getScriptForce(force)].Completed) {
|
||||
|
@ -876,7 +876,7 @@ static int CclAiWaitForces(lua_State *l)
|
|||
*/
|
||||
static int CclAiAttackWithForces(lua_State *l)
|
||||
{
|
||||
int Forces[AI_MAX_FORCES + 1];
|
||||
int Forces[AI_MAX_FORCE_INTERNAL + 1];
|
||||
|
||||
LuaCheckArgs(l, 1);
|
||||
if (!lua_istable(l, 1)) {
|
||||
|
@ -886,7 +886,7 @@ static int CclAiAttackWithForces(lua_State *l)
|
|||
for (int i = 0; i < args; ++i) {
|
||||
const int force = LuaToNumber(l, 1, i + 1);
|
||||
|
||||
if (force < 0 || force >= AI_MAX_FORCES) {
|
||||
if (force < 0 || force >= AI_MAX_FORCE_INTERNAL) {
|
||||
lua_pushfstring(l, "Force out of range: %d", force);
|
||||
}
|
||||
Forces[i] = AiPlayer->Force.getScriptForce(force);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "animation/animation_goto.h"
|
||||
#include "animation/animation_ifvar.h"
|
||||
#include "animation/animation_label.h"
|
||||
#include "animation/animation_luacallback.h"
|
||||
#include "animation/animation_move.h"
|
||||
#include "animation/animation_randomgoto.h"
|
||||
#include "animation/animation_randomrotate.h"
|
||||
|
@ -133,17 +134,17 @@ static int ParseAnimPlayer(const CUnit &unit, const char *parseint)
|
|||
** @return The parsed value.
|
||||
*/
|
||||
|
||||
int ParseAnimInt(const CUnit *unit, const char *parseint)
|
||||
int ParseAnimInt(const CUnit &unit, const char *parseint)
|
||||
{
|
||||
char s[100];
|
||||
const CUnit *goal = unit;
|
||||
const CUnit *goal = &unit;
|
||||
|
||||
strcpy(s, parseint);
|
||||
char *cur = &s[2];
|
||||
if ((s[0] == 'v' || s[0] == 't') && unit != NULL) { //unit variable detected
|
||||
if (s[0] == 'v' || s[0] == 't') { //unit variable detected
|
||||
if (s[0] == 't') {
|
||||
if (unit->CurrentOrder()->HasGoal()) {
|
||||
goal = unit->CurrentOrder()->GetGoal();
|
||||
if (unit.CurrentOrder()->HasGoal()) {
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
char *next = strchr(cur, '.');
|
||||
if (next == NULL) {
|
||||
fprintf(stderr, "Need also specify the variable '%s' tag \n", cur);
|
||||
Exit(1);
|
||||
ExitFatal(1);
|
||||
} else {
|
||||
*next = '\0';
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
return goal->Resource.Active;
|
||||
}
|
||||
fprintf(stderr, "Bad variable name '%s'\n", cur);
|
||||
Exit(1);
|
||||
ExitFatal(1);
|
||||
}
|
||||
if (!strcmp(next + 1, "Value")) {
|
||||
return goal->Variable[index].Value;
|
||||
|
@ -177,10 +178,10 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
return goal->Variable[index].Value * 100 / goal->Variable[index].Max;
|
||||
}
|
||||
return 0;
|
||||
} else if ((s[0] == 'b' || s[0] == 'g') && unit != NULL) { //unit bool flag detected
|
||||
} else if (s[0] == 'b' || s[0] == 'g') { //unit bool flag detected
|
||||
if (s[0] == 'g') {
|
||||
if (unit->CurrentOrder()->HasGoal()) {
|
||||
goal = unit->CurrentOrder()->GetGoal();
|
||||
if (unit.CurrentOrder()->HasGoal()) {
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -188,11 +189,10 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
const int index = UnitTypeVar.BoolFlagNameLookup[cur];// User bool flags
|
||||
if (index == -1) {
|
||||
fprintf(stderr, "Bad bool-flag name '%s'\n", cur);
|
||||
Exit(1);
|
||||
return 0;
|
||||
ExitFatal(1);
|
||||
}
|
||||
return goal->Type->BoolFlag[index].value;
|
||||
} else if ((s[0] == 's') && unit != NULL) { //spell type detected
|
||||
} else if (s[0] == 's') { //spell type detected
|
||||
Assert(goal->CurrentAction() == UnitActionSpellCast);
|
||||
const COrder_SpellCast &order = *static_cast<COrder_SpellCast *>(goal->CurrentOrder());
|
||||
const SpellType &spell = order.GetSpell();
|
||||
|
@ -200,11 +200,11 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else if (s[0] == 'p' && unit != NULL) { //player variable detected
|
||||
} else if (s[0] == 'p') { //player variable detected
|
||||
char *next = strchr(cur, '.');
|
||||
if (next == NULL) {
|
||||
fprintf(stderr, "Need also specify the %s player's property\n", cur);
|
||||
Exit(1);
|
||||
ExitFatal(1);
|
||||
} else {
|
||||
*next = '\0';
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
if (arg != NULL) {
|
||||
*arg = '\0';
|
||||
}
|
||||
return GetPlayerData(ParseAnimPlayer(*unit, cur), next + 1, arg + 1);
|
||||
return GetPlayerData(ParseAnimPlayer(unit, cur), next + 1, arg + 1);
|
||||
} else if (s[0] == 'r') { //random value
|
||||
char *next = strchr(cur, '.');
|
||||
if (next == NULL) {
|
||||
|
@ -223,12 +223,72 @@ int ParseAnimInt(const CUnit *unit, const char *parseint)
|
|||
return min + SyncRand(atoi(next + 1) - min + 1);
|
||||
}
|
||||
} else if (s[0] == 'l') { //player number
|
||||
return ParseAnimPlayer(*unit, cur);
|
||||
return ParseAnimPlayer(unit, cur);
|
||||
|
||||
}
|
||||
return atoi(parseint);
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse flags list in animation frame.
|
||||
**
|
||||
** @param unit Unit of the animation.
|
||||
** @param parseflag Flag list to parse.
|
||||
**
|
||||
** @return The parsed value.
|
||||
*/
|
||||
int ParseAnimFlags(const CUnit &unit, const char *parseflag)
|
||||
{
|
||||
char s[100];
|
||||
int flags = 0;
|
||||
|
||||
strcpy(s, parseflag);
|
||||
char *cur = s;
|
||||
char *next = s;
|
||||
while (next && *next) {
|
||||
next = strchr(cur, '.');
|
||||
if (next) {
|
||||
*next = '\0';
|
||||
++next;
|
||||
}
|
||||
if (unit.Anim.Anim->Type == AnimationSpawnMissile) {
|
||||
if (!strcmp(cur, "none")) {
|
||||
flags = SM_None;
|
||||
return flags;
|
||||
} else if (!strcmp(cur, "damage")) {
|
||||
flags |= SM_Damage;
|
||||
} else if (!strcmp(cur, "totarget")) {
|
||||
flags |= SM_ToTarget;
|
||||
} else if (!strcmp(cur, "pixel")) {
|
||||
flags |= SM_Pixel;
|
||||
} else if (!strcmp(cur, "reltarget")) {
|
||||
flags |= SM_RelTarget;
|
||||
} else if (!strcmp(cur, "ranged")) {
|
||||
flags |= SM_Ranged;
|
||||
} else if (!strcmp(cur, "setdirection")) {
|
||||
flags |= SM_SetDirection;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown animation flag: %s\n", cur);
|
||||
ExitFatal(1);
|
||||
}
|
||||
} else if (unit.Anim.Anim->Type == AnimationSpawnUnit) {
|
||||
if (!strcmp(cur, "none")) {
|
||||
flags = SU_None;
|
||||
return flags;
|
||||
} else if (!strcmp(cur, "summoned")) {
|
||||
flags |= SU_Summoned;
|
||||
} else if (!strcmp(cur, "jointoai")) {
|
||||
flags |= SU_JoinToAIForce;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown animation flag: %s\n", cur);
|
||||
ExitFatal(1);
|
||||
}
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Show unit animation.
|
||||
|
@ -479,10 +539,12 @@ static CAnimation *ParseAnimationFrame(lua_State *l, const char *str)
|
|||
anim = new CAnimation_Goto;
|
||||
} else if (op1 == "random-goto") {
|
||||
anim = new CAnimation_RandomGoto;
|
||||
} else if (op1 == "lua-callback") {
|
||||
anim = new CAnimation_LuaCallback;
|
||||
} else {
|
||||
LuaError(l, "Unknown animation: %s" _C_ op1.c_str());
|
||||
}
|
||||
anim->Init(extraArg.c_str());
|
||||
anim->Init(extraArg.c_str(), l);
|
||||
return anim;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ void CAnimation_Attack::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Attack::Init(const char *s, lua_State *)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
throw AnimationDie_Exception();
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Die::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Die::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->DeathType = s;
|
||||
}
|
||||
|
|
|
@ -45,14 +45,18 @@
|
|||
unit.Frame = ParseAnimInt(&unit);
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_ExactFrame::Init(const char *s)
|
||||
/* virtual */ void CAnimation_ExactFrame::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->frame = s;
|
||||
}
|
||||
|
||||
int CAnimation_ExactFrame::ParseAnimInt(const CUnit *unit) const
|
||||
{
|
||||
return ::ParseAnimInt(unit, this->frame.c_str());
|
||||
if (unit == NULL) {
|
||||
return atoi(this->frame.c_str());
|
||||
} else {
|
||||
return ::ParseAnimInt(*unit, this->frame.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -46,14 +46,18 @@
|
|||
UnitUpdateHeading(unit);
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Frame::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Frame::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->frame = s;
|
||||
}
|
||||
|
||||
int CAnimation_Frame::ParseAnimInt(const CUnit *unit) const
|
||||
{
|
||||
return ::ParseAnimInt(unit, this->frame.c_str());
|
||||
if (unit == NULL) {
|
||||
return atoi(this->frame.c_str());
|
||||
} else {
|
||||
return ::ParseAnimInt(*unit, this->frame.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
unit.Anim.Anim = this->gotoLabel;
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Goto::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Goto::Init(const char *s, lua_State *)
|
||||
{
|
||||
FindLabelLater(&this->gotoLabel, s);
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ static bool returnFalse(int, int) { return false; }
|
|||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
const int lop = ParseAnimInt(&unit, this->leftVar.c_str());
|
||||
const int rop = ParseAnimInt(&unit, this->rightVar.c_str());
|
||||
const int lop = ParseAnimInt(unit, this->leftVar.c_str());
|
||||
const int rop = ParseAnimInt(unit, this->rightVar.c_str());
|
||||
const bool cond = this->binOpFunc(lop, rop);
|
||||
|
||||
if (cond) {
|
||||
|
@ -73,7 +73,7 @@ static bool returnFalse(int, int) { return false; }
|
|||
/*
|
||||
** s = "leftOp Op rigthOp gotoLabel"
|
||||
*/
|
||||
/* virtual */ void CAnimation_IfVar::Init(const char *s)
|
||||
/* virtual */ void CAnimation_IfVar::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
Assert(unit.Anim.Anim == this);
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Label::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Label::Init(const char *s, lua_State *)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
84
src/animation/animation_luacallback.cpp
Normal file
84
src/animation/animation_luacallback.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name animation_luacallback.cpp - The animation LuaCallback. */
|
||||
//
|
||||
// (c) Copyright 2013 by cybermind
|
||||
//
|
||||
// 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 "animation/animation_luacallback.h"
|
||||
|
||||
#include "script.h"
|
||||
#include "unit.h"
|
||||
|
||||
|
||||
/* virtual */ void CAnimation_LuaCallback::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
|
||||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
Assert(cb);
|
||||
|
||||
cb->pushPreamble();
|
||||
for (std::vector<std::string>::const_iterator it = cbArgs.begin(); it != cbArgs.end(); ++it) {
|
||||
const std::string str = *it;
|
||||
|
||||
const int arg = ParseAnimInt(unit, str.c_str());
|
||||
cb->pushInteger(arg);
|
||||
}
|
||||
cb->run();
|
||||
}
|
||||
|
||||
/*
|
||||
** s = "cbName cbArg1 [cbArgN ...]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_LuaCallback::Init(const char *s, lua_State *l)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
||||
size_t begin = 0;
|
||||
size_t end = str.find(' ', begin);
|
||||
this->cbName.assign(str, begin, end - begin);
|
||||
|
||||
lua_getglobal(l, cbName.c_str());
|
||||
cb = new LuaCallback(l, -1);
|
||||
lua_pop(l, 1);
|
||||
|
||||
for (size_t begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
begin != std::string::npos;) {
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
|
||||
this->cbArgs.push_back(str.substr(begin, end - begin));
|
||||
begin = str.find_first_not_of(' ', end);
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
|
@ -44,10 +44,10 @@
|
|||
Assert(unit.Anim.Anim == this);
|
||||
Assert(!move);
|
||||
|
||||
move = ParseAnimInt(&unit, this->moveStr.c_str());
|
||||
move = ParseAnimInt(unit, this->moveStr.c_str());
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Move::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Move::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->moveStr = s;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
if (SyncRand() % 100 < ParseAnimInt(&unit, this->randomStr.c_str())) {
|
||||
if (SyncRand() % 100 < ParseAnimInt(unit, this->randomStr.c_str())) {
|
||||
unit.Anim.Anim = this->gotoLabel;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@
|
|||
/*
|
||||
** s : "percent label"
|
||||
*/
|
||||
/* virtual */ void CAnimation_RandomGoto::Init(const char *s)
|
||||
/* virtual */ void CAnimation_RandomGoto::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
|
|
@ -45,13 +45,13 @@
|
|||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
if ((SyncRand() >> 8) & 1) {
|
||||
UnitRotate(unit, -ParseAnimInt(&unit, this->rotateStr.c_str()));
|
||||
UnitRotate(unit, -ParseAnimInt(unit, this->rotateStr.c_str()));
|
||||
} else {
|
||||
UnitRotate(unit, ParseAnimInt(&unit, this->rotateStr.c_str()));
|
||||
UnitRotate(unit, ParseAnimInt(unit, this->rotateStr.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_RandomRotate::Init(const char *s)
|
||||
/* virtual */ void CAnimation_RandomRotate::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->rotateStr = s;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
/*
|
||||
** s = "Sound1 [SoundN ...]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_RandomSound::Init(const char *s)
|
||||
/* virtual */ void CAnimation_RandomSound::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
const int arg1 = ParseAnimInt(&unit, this->minWait.c_str());
|
||||
const int arg2 = ParseAnimInt(&unit, this->maxWait.c_str());
|
||||
const int arg1 = ParseAnimInt(unit, this->minWait.c_str());
|
||||
const int arg2 = ParseAnimInt(unit, this->maxWait.c_str());
|
||||
|
||||
unit.Anim.Wait = arg1 + SyncRand() % (arg2 - arg1 + 1);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
|||
/*
|
||||
** s = "minWait MaxWait"
|
||||
*/
|
||||
/* virtual */ void CAnimation_RandomWait::Init(const char *s)
|
||||
/* virtual */ void CAnimation_RandomWait::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
|
|
@ -66,11 +66,11 @@ void UnitRotate(CUnit &unit, int rotate)
|
|||
const Vec2i pos = target.tilePos + target.Type->GetHalfTileSize() - unit.tilePos;
|
||||
UnitHeadingFromDeltaXY(unit, pos);
|
||||
} else {
|
||||
UnitRotate(unit, ParseAnimInt(&unit, this->rotateStr.c_str()));
|
||||
UnitRotate(unit, ParseAnimInt(unit, this->rotateStr.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Rotate::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Rotate::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->rotateStr = s;
|
||||
}
|
||||
|
|
|
@ -42,13 +42,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
//Modify types
|
||||
#define MOD_ADD 1
|
||||
#define MOD_SUB 2
|
||||
#define MOD_MUL 3
|
||||
#define MOD_DIV 4
|
||||
#define MOD_MOD 5
|
||||
|
||||
/**
|
||||
** Gets the player data.
|
||||
**
|
||||
|
@ -185,34 +178,46 @@ static void SetPlayerData(const int player, const char *prop, const char *arg, i
|
|||
|
||||
const char *var = this->varStr.c_str();
|
||||
const char *arg = this->argStr.c_str();
|
||||
const int playerId = ParseAnimInt(&unit, this->playerStr.c_str());
|
||||
int rop = ParseAnimInt(&unit, this->valueStr.c_str());
|
||||
const int playerId = ParseAnimInt(unit, this->playerStr.c_str());
|
||||
int rop = ParseAnimInt(unit, this->valueStr.c_str());
|
||||
int data = GetPlayerData(playerId, var, arg);
|
||||
|
||||
switch (this->mod) {
|
||||
case MOD_ADD:
|
||||
case modAdd:
|
||||
data += rop;
|
||||
break;
|
||||
case MOD_SUB:
|
||||
case modSub:
|
||||
data -= rop;
|
||||
break;
|
||||
case MOD_MUL:
|
||||
case modMul:
|
||||
data *= rop;
|
||||
break;
|
||||
case MOD_DIV:
|
||||
case modDiv:
|
||||
if (!rop) {
|
||||
fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n");
|
||||
Exit(1);
|
||||
}
|
||||
data /= rop;
|
||||
break;
|
||||
case MOD_MOD:
|
||||
case modMod:
|
||||
if (!rop) {
|
||||
fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n");
|
||||
Exit(1);
|
||||
}
|
||||
data %= rop;
|
||||
break;
|
||||
case modAnd:
|
||||
data &= rop;
|
||||
break;
|
||||
case modOr:
|
||||
data |= rop;
|
||||
break;
|
||||
case modXor:
|
||||
data ^= rop;
|
||||
break;
|
||||
case modNot:
|
||||
data = !data;
|
||||
break;
|
||||
default:
|
||||
data = rop;
|
||||
}
|
||||
|
@ -223,7 +228,7 @@ static void SetPlayerData(const int player, const char *prop, const char *arg, i
|
|||
/*
|
||||
** s = "player var mod value [arg2]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_SetPlayerVar::Init(const char *s)
|
||||
/* virtual */ void CAnimation_SetPlayerVar::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
@ -239,7 +244,29 @@ static void SetPlayerData(const int player, const char *prop, const char *arg, i
|
|||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
const std::string modStr(str, begin, end - begin);
|
||||
this->mod = atoi(modStr.c_str());
|
||||
if (modStr == "=") {
|
||||
this->mod = modSet;
|
||||
} else if (modStr == "+=") {
|
||||
this->mod = modAdd;
|
||||
} else if (modStr == "-=") {
|
||||
this->mod = modSub;
|
||||
} else if (modStr == "*=") {
|
||||
this->mod = modMul;
|
||||
} else if (modStr == "/=") {
|
||||
this->mod = modDiv;
|
||||
} else if (modStr == "%=") {
|
||||
this->mod = modMod;
|
||||
} else if (modStr == "&=") {
|
||||
this->mod = modAnd;
|
||||
} else if (modStr == "|=") {
|
||||
this->mod = modOr;
|
||||
} else if (modStr == "^=") {
|
||||
this->mod = modXor;
|
||||
} else if (modStr == "!") {
|
||||
this->mod = modNot;
|
||||
} else {
|
||||
this->mod = (SetVar_ModifyTypes)(atoi(modStr.c_str()));
|
||||
}
|
||||
|
||||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
|
|
|
@ -43,13 +43,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
//Modify types
|
||||
#define MOD_ADD 1
|
||||
#define MOD_SUB 2
|
||||
#define MOD_MUL 3
|
||||
#define MOD_DIV 4
|
||||
#define MOD_MOD 5
|
||||
|
||||
|
||||
/* virtual */ void CAnimation_SetVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
|
||||
{
|
||||
|
@ -102,7 +95,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
const int rop = ParseAnimInt(&unit, this->valueStr.c_str());
|
||||
const int rop = ParseAnimInt(unit, this->valueStr.c_str());
|
||||
int value = 0;
|
||||
if (!strcmp(next + 1, "Value")) {
|
||||
value = goal->Variable[index].Value;
|
||||
|
@ -116,16 +109,16 @@
|
|||
value = goal->Variable[index].Value * 100 / goal->Variable[index].Max;
|
||||
}
|
||||
switch (this->mod) {
|
||||
case MOD_ADD:
|
||||
case modAdd:
|
||||
value += rop;
|
||||
break;
|
||||
case MOD_SUB:
|
||||
case modSub:
|
||||
value -= rop;
|
||||
break;
|
||||
case MOD_MUL:
|
||||
case modMul:
|
||||
value *= rop;
|
||||
break;
|
||||
case MOD_DIV:
|
||||
case modDiv:
|
||||
if (!rop) {
|
||||
fprintf(stderr, "Division by zero in AnimationSetVar\n");
|
||||
Exit(1);
|
||||
|
@ -133,7 +126,7 @@
|
|||
}
|
||||
value /= rop;
|
||||
break;
|
||||
case MOD_MOD:
|
||||
case modMod:
|
||||
if (!rop) {
|
||||
fprintf(stderr, "Division by zero in AnimationSetVar\n");
|
||||
Exit(1);
|
||||
|
@ -141,6 +134,18 @@
|
|||
}
|
||||
value %= rop;
|
||||
break;
|
||||
case modAnd:
|
||||
value &= rop;
|
||||
break;
|
||||
case modOr:
|
||||
value |= rop;
|
||||
break;
|
||||
case modXor:
|
||||
value ^= rop;
|
||||
break;
|
||||
case modNot:
|
||||
value = !value;
|
||||
break;
|
||||
default:
|
||||
value = rop;
|
||||
}
|
||||
|
@ -161,7 +166,7 @@
|
|||
/*
|
||||
** s = "var mod value [unitSlot]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_SetVar::Init(const char *s)
|
||||
/* virtual */ void CAnimation_SetVar::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
@ -173,7 +178,30 @@
|
|||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
const std::string modStr(str, begin, end - begin);
|
||||
this->mod = atoi(modStr.c_str());
|
||||
|
||||
if (modStr == "=") {
|
||||
this->mod = modSet;
|
||||
} else if (modStr == "+=") {
|
||||
this->mod = modAdd;
|
||||
} else if (modStr == "-=") {
|
||||
this->mod = modSub;
|
||||
} else if (modStr == "*=") {
|
||||
this->mod = modMul;
|
||||
} else if (modStr == "/=") {
|
||||
this->mod = modDiv;
|
||||
} else if (modStr == "%=") {
|
||||
this->mod = modMod;
|
||||
} else if (modStr == "&=") {
|
||||
this->mod = modAnd;
|
||||
} else if (modStr == "|=") {
|
||||
this->mod = modOr;
|
||||
} else if (modStr == "^=") {
|
||||
this->mod = modXor;
|
||||
} else if (modStr == "!") {
|
||||
this->mod = modNot;
|
||||
} else {
|
||||
this->mod = (SetVar_ModifyTypes)(atoi(modStr.c_str()));
|
||||
}
|
||||
|
||||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Sound::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Sound::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->sound.Name = s;
|
||||
}
|
||||
|
|
|
@ -46,68 +46,17 @@
|
|||
#include "pathfinder.h"
|
||||
#include "unit.h"
|
||||
|
||||
//SpawnMissile flags
|
||||
#define ANIM_SM_DAMAGE 1
|
||||
#define ANIM_SM_TOTARGET 2
|
||||
#define ANIM_SM_PIXEL 4
|
||||
#define ANIM_SM_RELTARGET 8
|
||||
#define ANIM_SM_RANGED 16
|
||||
#define ANIM_SM_SETDIRECTION 32
|
||||
|
||||
/**
|
||||
** Parse flags list in animation frame.
|
||||
**
|
||||
** @param unit Unit of the animation.
|
||||
** @param parseflag Flag list to parse.
|
||||
**
|
||||
** @return The parsed value.
|
||||
*/
|
||||
static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
||||
{
|
||||
char s[100];
|
||||
int flags = 0;
|
||||
|
||||
strcpy(s, parseflag);
|
||||
char *cur = s;
|
||||
char *next = s;
|
||||
while (next) {
|
||||
next = strchr(cur, '.');
|
||||
if (next) {
|
||||
*next = '\0';
|
||||
++next;
|
||||
}
|
||||
if (unit.Anim.Anim->Type == AnimationSpawnMissile) {
|
||||
if (!strcmp(cur, "damage")) {
|
||||
flags |= ANIM_SM_DAMAGE;
|
||||
} else if (!strcmp(cur, "totarget")) {
|
||||
flags |= ANIM_SM_TOTARGET;
|
||||
} else if (!strcmp(cur, "pixel")) {
|
||||
flags |= ANIM_SM_PIXEL;
|
||||
} else if (!strcmp(cur, "reltarget")) {
|
||||
flags |= ANIM_SM_RELTARGET;
|
||||
} else if (!strcmp(cur, "ranged")) {
|
||||
flags |= ANIM_SM_RANGED;
|
||||
} else if (!strcmp(cur, "setdirection")) {
|
||||
flags |= ANIM_SM_SETDIRECTION;
|
||||
}
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void CAnimation_SpawnMissile::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
|
||||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
const int startx = ParseAnimInt(&unit, this->startXStr.c_str());
|
||||
const int starty = ParseAnimInt(&unit, this->startYStr.c_str());
|
||||
const int destx = ParseAnimInt(&unit, this->destXStr.c_str());
|
||||
const int desty = ParseAnimInt(&unit, this->destYStr.c_str());
|
||||
const int flags = ParseAnimFlags(unit, this->flagsStr.c_str());
|
||||
const int offsetnum = ParseAnimInt(&unit, this->offsetNumStr.c_str());
|
||||
const CUnit *goal = flags & ANIM_SM_RELTARGET ? unit.CurrentOrder()->GetGoal() : &unit;
|
||||
const int startx = ParseAnimInt(unit, this->startXStr.c_str());
|
||||
const int starty = ParseAnimInt(unit, this->startYStr.c_str());
|
||||
const int destx = ParseAnimInt(unit, this->destXStr.c_str());
|
||||
const int desty = ParseAnimInt(unit, this->destYStr.c_str());
|
||||
const SpawnMissile_Flags flags = (SpawnMissile_Flags)(ParseAnimFlags(unit, this->flagsStr.c_str()));
|
||||
const int offsetnum = ParseAnimInt(unit, this->offsetNumStr.c_str());
|
||||
const CUnit *goal = flags & SM_RelTarget ? unit.CurrentOrder()->GetGoal() : &unit;
|
||||
const int dir = ((goal->Direction + NextDirection / 2) & 0xFF) / NextDirection;
|
||||
const PixelPos moff = goal->Type->MissileOffsets[dir][!offsetnum ? 0 : offsetnum - 1];
|
||||
PixelPos start;
|
||||
|
@ -120,14 +69,14 @@ static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
|||
if (!goal || goal->Destroyed) {
|
||||
return;
|
||||
}
|
||||
if ((flags & ANIM_SM_PIXEL)) {
|
||||
if ((flags & SM_Pixel)) {
|
||||
start.x = goal->tilePos.x * PixelTileSize.x + goal->IX + moff.x + startx;
|
||||
start.y = goal->tilePos.y * PixelTileSize.y + goal->IY + moff.y + starty;
|
||||
} else {
|
||||
start.x = (goal->tilePos.x + startx) * PixelTileSize.x + PixelTileSize.x / 2 + moff.x;
|
||||
start.y = (goal->tilePos.y + starty) * PixelTileSize.y + PixelTileSize.y / 2 + moff.y;
|
||||
}
|
||||
if ((flags & ANIM_SM_TOTARGET)) {
|
||||
if ((flags & SM_ToTarget)) {
|
||||
CUnit *target = goal->CurrentOrder()->GetGoal();
|
||||
if (!target || target->Destroyed) {
|
||||
Assert(!mtype->AlwaysFire || mtype->Range);
|
||||
|
@ -143,14 +92,14 @@ static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
|||
COrder_SpellCast &order = *static_cast<COrder_SpellCast *>(goal->CurrentOrder());
|
||||
dest = Map.TilePosToMapPixelPos_Center(order.GetGoalPos());
|
||||
}
|
||||
if (flags & ANIM_SM_PIXEL) {
|
||||
if (flags & SM_Pixel) {
|
||||
dest.x += destx;
|
||||
dest.y += desty;
|
||||
} else {
|
||||
dest.x += destx * PixelTileSize.x;
|
||||
dest.y += desty * PixelTileSize.y;
|
||||
}
|
||||
} else if (flags & ANIM_SM_PIXEL) {
|
||||
} else if (flags & SM_Pixel) {
|
||||
dest.x = target->GetMapPixelPosCenter().x + destx;
|
||||
dest.y = target->GetMapPixelPosCenter().y + desty;
|
||||
} else {
|
||||
|
@ -159,7 +108,7 @@ static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
|||
dest += target->Type->GetPixelSize() / 2;
|
||||
}
|
||||
} else {
|
||||
if ((flags & ANIM_SM_PIXEL)) {
|
||||
if ((flags & SM_Pixel)) {
|
||||
dest.x = goal->GetMapPixelPosCenter().x + destx;
|
||||
dest.y = goal->GetMapPixelPosCenter().y + desty;
|
||||
} else {
|
||||
|
@ -170,22 +119,22 @@ static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
|||
}
|
||||
Vec2i destTilePos = Map.MapPixelPosToTilePos(dest);
|
||||
const int dist = goal->MapDistanceTo(destTilePos);
|
||||
if ((flags & ANIM_SM_RANGED) && !(flags & ANIM_SM_PIXEL)
|
||||
if ((flags & SM_Ranged) && !(flags & SM_Pixel)
|
||||
&& dist > goal->Stats->Variables[ATTACKRANGE_INDEX].Max
|
||||
&& dist < goal->Type->MinAttackRange) {
|
||||
} else {
|
||||
Missile *missile = MakeMissile(*mtype, start, dest);
|
||||
if (flags & ANIM_SM_SETDIRECTION) {
|
||||
if (flags & SM_SetDirection) {
|
||||
PixelPos posd;
|
||||
posd.x = Heading2X[goal->Direction / NextDirection];
|
||||
posd.y = Heading2Y[goal->Direction / NextDirection];
|
||||
missile->MissileNewHeadingFromXY(posd);
|
||||
}
|
||||
if (flags & ANIM_SM_DAMAGE) {
|
||||
if (flags & SM_Damage) {
|
||||
missile->SourceUnit = &unit;
|
||||
}
|
||||
CUnit *target = goal->CurrentOrder()->GetGoal();
|
||||
if (flags & ANIM_SM_TOTARGET && target && target->IsAlive()) {
|
||||
if (flags & SM_ToTarget && target && target->IsAlive()) {
|
||||
missile->TargetUnit = target;
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +143,7 @@ static int ParseAnimFlags(CUnit &unit, const char *parseflag)
|
|||
/*
|
||||
** s = "missileType startX startY destX destY [flag1[.flagN]] [missileoffset]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_SpawnMissile::Init(const char *s)
|
||||
/* virtual */ void CAnimation_SpawnMissile::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
|
||||
#include "animation/animation_spawnunit.h"
|
||||
|
||||
#include "../ai/ai_local.h"
|
||||
|
||||
#include "commands.h"
|
||||
#include "map.h"
|
||||
#include "unit.h"
|
||||
|
||||
|
@ -104,10 +107,12 @@ found:
|
|||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
|
||||
const int offX = ParseAnimInt(&unit, this->offXStr.c_str());
|
||||
const int offY = ParseAnimInt(&unit, this->offYStr.c_str());
|
||||
const int range = ParseAnimInt(&unit, this->rangeStr.c_str());
|
||||
const int playerId = ParseAnimInt(&unit, this->playerStr.c_str());
|
||||
const int offX = ParseAnimInt(unit, this->offXStr.c_str());
|
||||
const int offY = ParseAnimInt(unit, this->offYStr.c_str());
|
||||
const int range = ParseAnimInt(unit, this->rangeStr.c_str());
|
||||
const int playerId = ParseAnimInt(unit, this->playerStr.c_str());
|
||||
const SpawnUnit_Flags flags = (SpawnUnit_Flags)(ParseAnimFlags(unit, this->flagsStr.c_str()));
|
||||
|
||||
CPlayer &player = Players[playerId];
|
||||
const Vec2i pos(unit.tilePos.x + offX, unit.tilePos.y + offY);
|
||||
CUnitType *type = UnitTypeByIdent(this->unitTypeStr.c_str());
|
||||
|
@ -120,6 +125,17 @@ found:
|
|||
if (target != NULL) {
|
||||
target->tilePos = resPos;
|
||||
target->Place(resPos);
|
||||
if (flags & SU_Summoned) {
|
||||
target->Summoned = 1;
|
||||
}
|
||||
if ((flags & SU_JoinToAIForce) && unit.Player->AiEnabled) {
|
||||
int force = unit.Player->Ai->Force.GetForce(unit);
|
||||
if (force != -1) {
|
||||
unit.Player->Ai->Force[force].Insert(*target);
|
||||
target->GroupId = unit.GroupId;
|
||||
CommandDefend(*target, unit, FlushCommands);
|
||||
}
|
||||
}
|
||||
//DropOutOnSide(*target, LookingW, NULL);
|
||||
} else {
|
||||
DebugPrint("Unable to allocate Unit");
|
||||
|
@ -128,9 +144,9 @@ found:
|
|||
}
|
||||
|
||||
/*
|
||||
** s = "unitType offX offY range player"
|
||||
** s = "unitType offX offY range player [flags]"
|
||||
*/
|
||||
/* virtual */ void CAnimation_SpawnUnit::Init(const char *s)
|
||||
/* virtual */ void CAnimation_SpawnUnit::Init(const char *s, lua_State *)
|
||||
{
|
||||
const std::string str(s);
|
||||
const size_t len = str.size();
|
||||
|
@ -154,6 +170,12 @@ found:
|
|||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
this->playerStr.assign(str, begin, end - begin);
|
||||
|
||||
begin = std::min(len, str.find_first_not_of(' ', end));
|
||||
end = std::min(len, str.find(' ', begin));
|
||||
if (begin != end) {
|
||||
this->flagsStr.assign(str, begin, end - begin);
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
unit.Anim.Unbreakable = this->state;
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Unbreakable::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Unbreakable::Init(const char *s, lua_State *)
|
||||
{
|
||||
if (!strcmp(s, "begin")) {
|
||||
this->state = 1;
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
/* virtual */ void CAnimation_Wait::Action(CUnit &unit, int &/*move*/, int scale) const
|
||||
{
|
||||
Assert(unit.Anim.Anim == this);
|
||||
unit.Anim.Wait = ParseAnimInt(&unit, this->wait.c_str()) << scale >> 8;
|
||||
unit.Anim.Wait = ParseAnimInt(unit, this->wait.c_str()) << scale >> 8;
|
||||
if (unit.Variable[SLOW_INDEX].Value) { // unit is slowed down
|
||||
unit.Anim.Wait <<= 1;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* virtual */ void CAnimation_Wait::Init(const char *s)
|
||||
/* virtual */ void CAnimation_Wait::Init(const char *s, lua_State *)
|
||||
{
|
||||
this->wait = s;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,22 @@ enum AnimationType {
|
|||
AnimationIfVar,
|
||||
AnimationSetVar,
|
||||
AnimationSetPlayerVar,
|
||||
AnimationDie
|
||||
AnimationDie,
|
||||
AnimationLuaCallback
|
||||
};
|
||||
|
||||
//Modify types
|
||||
enum SetVar_ModifyTypes {
|
||||
modSet = 0, /// Set value to this
|
||||
modAdd, /// Addition
|
||||
modSub, /// Subtraction
|
||||
modMul, /// Multiplication
|
||||
modDiv, /// Division
|
||||
modMod, /// Modulo
|
||||
modAnd, /// Bitwise AND
|
||||
modOr, /// Bitwise OR
|
||||
modXor, /// Bitwise XOR
|
||||
modNot, /// Bitwise NOT
|
||||
};
|
||||
|
||||
class CAnimation
|
||||
|
@ -83,7 +98,7 @@ public:
|
|||
virtual ~CAnimation() {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const = 0;
|
||||
virtual void Init(const char *s) {}
|
||||
virtual void Init(const char *s, lua_State *l = NULL) {}
|
||||
|
||||
const AnimationType Type;
|
||||
CAnimation *Next;
|
||||
|
@ -152,7 +167,8 @@ extern int UnitShowAnimationScaled(CUnit &unit, const CAnimation *anim, int scal
|
|||
extern int UnitShowAnimation(CUnit &unit, const CAnimation *anim);
|
||||
|
||||
|
||||
extern int ParseAnimInt(const CUnit *unit, const char *parseint);
|
||||
extern int ParseAnimInt(const CUnit &unit, const char *parseint);
|
||||
extern int ParseAnimFlags(const CUnit &unit, const char *parseflag);
|
||||
|
||||
extern void FindLabelLater(CAnimation **anim, const std::string &name);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Attack() : CAnimation(AnimationAttack) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Die() : CAnimation(AnimationDie) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string DeathType;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_ExactFrame() : CAnimation(AnimationExactFrame) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
int ParseAnimInt(const CUnit *unit) const;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Frame() : CAnimation(AnimationFrame) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
int ParseAnimInt(const CUnit *unit) const;
|
||||
private:
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Goto() : CAnimation(AnimationGoto), gotoLabel(NULL) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
CAnimation *gotoLabel;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_IfVar() : CAnimation(AnimationIfVar), binOpFunc(NULL), gotoLabel(NULL) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
typedef bool BinOpFunc(int lhs, int rhs);
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
CAnimation_Label() : CAnimation(AnimationLabel) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
};
|
||||
|
||||
//@}
|
||||
|
|
57
src/include/animation/animation_luacallback.h
Normal file
57
src/include/animation/animation_luacallback.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name animation_luacallback.h - The animation LuaCallback headerfile. */
|
||||
//
|
||||
// (c) Copyright 2013 by cybermind
|
||||
//
|
||||
// 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 ANIMATION_LUACALLBACK_H
|
||||
#define ANIMATION_LUACALLBACK_H
|
||||
|
||||
//@{
|
||||
|
||||
#include <string>
|
||||
#include "animation.h"
|
||||
|
||||
#include "luacallback.h"
|
||||
|
||||
class CAnimation_LuaCallback : public CAnimation
|
||||
{
|
||||
public:
|
||||
CAnimation_LuaCallback() : CAnimation(AnimationLuaCallback), cb(NULL) {}
|
||||
~CAnimation_LuaCallback() { delete cb; }
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
LuaCallback *cb;
|
||||
std::string cbName;
|
||||
std::vector<std::string> cbArgs;
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
#endif // ANIMATION_LUACALLBACK_H
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Move() : CAnimation(AnimationMove) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string moveStr;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_RandomGoto() : CAnimation(AnimationRandomGoto), gotoLabel(NULL) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string randomStr;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_RandomRotate() : CAnimation(AnimationRandomRotate) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string rotateStr;
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
CAnimation_RandomSound() : CAnimation(AnimationRandomSound) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
void MapSound();
|
||||
private:
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_RandomWait() : CAnimation(AnimationRandomWait) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string minWait;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Rotate() : CAnimation(AnimationRotate) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string rotateStr;
|
||||
|
|
|
@ -41,10 +41,10 @@ public:
|
|||
CAnimation_SetPlayerVar() : CAnimation(AnimationSetPlayerVar) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
int mod;
|
||||
SetVar_ModifyTypes mod;
|
||||
std::string playerStr;
|
||||
std::string varStr;
|
||||
std::string argStr;
|
||||
|
|
|
@ -41,10 +41,10 @@ public:
|
|||
CAnimation_SetVar() : CAnimation(AnimationSetVar) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
int mod;
|
||||
SetVar_ModifyTypes mod;
|
||||
std::string varStr;
|
||||
std::string valueStr;
|
||||
std::string unitSlotStr;
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
CAnimation_Sound() : CAnimation(AnimationSound) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
void MapSound();
|
||||
|
||||
|
|
|
@ -35,13 +35,25 @@
|
|||
#include <string>
|
||||
#include "animation.h"
|
||||
|
||||
//SpawnMissile flags
|
||||
enum SpawnMissile_Flags {
|
||||
SM_None = 0, /// Clears all flags
|
||||
SM_Damage = 1, /// Missile deals damage to units
|
||||
SM_ToTarget = 2, /// Missile is directed to unit's target
|
||||
SM_Pixel = 4, /// Missile's offsets are calculated in pixels rather than tiles
|
||||
SM_RelTarget = 8, /// All calculations are relative to unit's target
|
||||
SM_Ranged = 16, /// Missile can't be shot if current range between unit and it's target
|
||||
/// is bigger than unit's attack range
|
||||
SM_SetDirection = 32 /// Missile takes the same direction as spawner
|
||||
};
|
||||
|
||||
class CAnimation_SpawnMissile : public CAnimation
|
||||
{
|
||||
public:
|
||||
CAnimation_SpawnMissile() : CAnimation(AnimationSpawnMissile) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string missileTypeStr;
|
||||
|
|
|
@ -35,13 +35,20 @@
|
|||
#include <string>
|
||||
#include "animation.h"
|
||||
|
||||
//SpawnUnit flags
|
||||
enum SpawnUnit_Flags {
|
||||
SU_None = 0, /// Clears all flags
|
||||
SU_Summoned = 1, /// Unit is marked as "summoned"
|
||||
SU_JoinToAIForce = 2 /// Unit is included into spawner's AI force, if available
|
||||
};
|
||||
|
||||
class CAnimation_SpawnUnit : public CAnimation
|
||||
{
|
||||
public:
|
||||
CAnimation_SpawnUnit() : CAnimation(AnimationSpawnUnit) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string unitTypeStr;
|
||||
|
@ -49,6 +56,7 @@ private:
|
|||
std::string offYStr;
|
||||
std::string rangeStr;
|
||||
std::string playerStr;
|
||||
std::string flagsStr;
|
||||
};
|
||||
|
||||
//@}
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Unbreakable() : CAnimation(AnimationUnbreakable), state(0) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
int state;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
CAnimation_Wait() : CAnimation(AnimationWait) {}
|
||||
|
||||
virtual void Action(CUnit &unit, int &move, int scale) const;
|
||||
virtual void Init(const char *s);
|
||||
virtual void Init(const char *s, lua_State *l);
|
||||
|
||||
private:
|
||||
std::string wait;
|
||||
|
|
|
@ -77,8 +77,8 @@ public:
|
|||
class CParticle
|
||||
{
|
||||
public:
|
||||
CParticle(CPosition position) :
|
||||
pos(position), destroyed(false)
|
||||
CParticle(CPosition position, int drawlevel = 0) :
|
||||
pos(position), destroyed(false), drawLevel(drawlevel)
|
||||
{}
|
||||
virtual ~CParticle() {}
|
||||
|
||||
|
@ -91,16 +91,20 @@ public:
|
|||
|
||||
virtual CParticle *clone() = 0;
|
||||
|
||||
int getDrawLevel() const { return drawLevel; }
|
||||
void setDrawLevel(int value) { drawLevel = value; }
|
||||
|
||||
protected:
|
||||
CPosition pos;
|
||||
bool destroyed;
|
||||
int drawLevel;
|
||||
};
|
||||
|
||||
|
||||
class StaticParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
StaticParticle(CPosition position, GraphicAnimation *flame);
|
||||
StaticParticle(CPosition position, GraphicAnimation *flame, int drawlevel = 0);
|
||||
virtual ~StaticParticle();
|
||||
|
||||
virtual bool isVisible(const CViewport &vp) const;
|
||||
|
@ -120,13 +124,17 @@ public:
|
|||
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
||||
GraphicAnimation *destroyAnimation,
|
||||
int minVelocity = 0, int maxVelocity = 400,
|
||||
int minTrajectoryAngle = 77, int maxTTL = 0);
|
||||
int minTrajectoryAngle = 77, int maxTTL = 0, int drawlevel = 0);
|
||||
virtual ~CChunkParticle();
|
||||
|
||||
virtual bool isVisible(const CViewport &vp) const;
|
||||
virtual void draw();
|
||||
virtual void update(int ticks);
|
||||
virtual CParticle *clone();
|
||||
int getSmokeDrawLevel() const { return smokeDrawLevel; }
|
||||
int getDestroyDrawLevel() const { return destroyDrawLevel; }
|
||||
void setSmokeDrawLevel(int value) { smokeDrawLevel = value; }
|
||||
void setDestroyDrawLevel(int value) { destroyDrawLevel = value; }
|
||||
|
||||
protected:
|
||||
CPosition initialPos;
|
||||
|
@ -140,6 +148,8 @@ protected:
|
|||
int maxVelocity;
|
||||
int minTrajectoryAngle;
|
||||
float height;
|
||||
int smokeDrawLevel;
|
||||
int destroyDrawLevel;
|
||||
GraphicAnimation *debrisAnimation;
|
||||
GraphicAnimation *smokeAnimation;
|
||||
GraphicAnimation *destroyAnimation;
|
||||
|
@ -155,7 +165,7 @@ protected:
|
|||
class CSmokeParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0f);
|
||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0f, int drawlevel = 0);
|
||||
virtual ~CSmokeParticle();
|
||||
|
||||
virtual bool isVisible(const CViewport &vp) const;
|
||||
|
@ -174,7 +184,7 @@ protected:
|
|||
class CRadialParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed);
|
||||
CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed, int drawlevel = 0);
|
||||
virtual ~CRadialParticle();
|
||||
|
||||
virtual bool isVisible(const CViewport &vp) const;
|
||||
|
@ -199,7 +209,9 @@ public:
|
|||
static void init();
|
||||
static void exit();
|
||||
|
||||
void draw(const CViewport &vp);
|
||||
void prepareToDraw(const CViewport &vp, std::vector<CParticle *> &table);
|
||||
void endDraw();
|
||||
|
||||
void update();
|
||||
|
||||
void add(CParticle *particle);
|
||||
|
|
|
@ -41,13 +41,14 @@
|
|||
class Spell_Capture : public SpellActionType
|
||||
{
|
||||
public:
|
||||
Spell_Capture() : SacrificeEnable(0), Damage(0), DamagePercent(0) {};
|
||||
Spell_Capture() : SacrificeEnable(false), JoinToAIForce(false), Damage(0), DamagePercent(0) {};
|
||||
virtual int Cast(CUnit &caster, const SpellType &spell,
|
||||
CUnit *target, const Vec2i &goalPos);
|
||||
virtual void Parse(lua_State *l, int startIndex, int endIndex);
|
||||
|
||||
private:
|
||||
char SacrificeEnable; /// true if the caster dies after casting.
|
||||
bool SacrificeEnable; /// true if the caster dies after casting.
|
||||
bool JoinToAIForce; /// if true, captured unit is joined into caster's AI force, if available
|
||||
int Damage; /// damage the spell does if unable to caputre
|
||||
int DamagePercent; /// percent the target must be damaged for a
|
||||
/// capture to suceed.
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
class Spell_Summon : public SpellActionType
|
||||
{
|
||||
public:
|
||||
Spell_Summon() : SpellActionType(1), UnitType(NULL), TTL(0), RequireCorpse(0) {};
|
||||
Spell_Summon() : SpellActionType(1), UnitType(NULL), TTL(0),
|
||||
RequireCorpse(false), JoinToAiForce(false) {};
|
||||
virtual int Cast(CUnit &caster, const SpellType &spell,
|
||||
CUnit *target, const Vec2i &goalPos);
|
||||
virtual void Parse(lua_State *l, int startIndex, int endIndex);
|
||||
|
@ -50,6 +51,7 @@ private:
|
|||
CUnitType *UnitType; /// Type of unit to be summoned.
|
||||
int TTL; /// Time to live for summoned unit. 0 means infinite
|
||||
int RequireCorpse; /// Corpse consumed while summoning.
|
||||
bool JoinToAiForce; /// if true, captured unit is joined into caster's AI force, if available
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,15 +40,10 @@
|
|||
class Spell_Teleport : public SpellActionType
|
||||
{
|
||||
public:
|
||||
Spell_Teleport() : SpellActionType(1), UnitType(NULL), TTL(0), RequireCorpse(0) {};
|
||||
Spell_Teleport() : SpellActionType(0) {}
|
||||
virtual int Cast(CUnit &caster, const SpellType &spell,
|
||||
CUnit *target, const Vec2i &goalPos);
|
||||
virtual void Parse(lua_State *l, int startIndex, int endIndex);
|
||||
|
||||
private:
|
||||
CUnitType *UnitType; /// Type of unit to be summoned.
|
||||
int TTL; /// Time to live for summoned unit. 0 means infinite
|
||||
int RequireCorpse; /// Corpse consumed while summoning.
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ public:
|
|||
bool IsCasterOnly() const {
|
||||
return !Range && Target == TargetSelf;
|
||||
}
|
||||
bool ForceUseAnimation;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -339,21 +339,23 @@ public:
|
|||
int ResourcesHeld; /// Resources Held by a unit
|
||||
|
||||
unsigned char DamagedType; /// Index of damage type of unit which damaged this unit
|
||||
unsigned long Attacked; /// gamecycle unit was last attacked
|
||||
unsigned Blink : 3; /// Let selection rectangle blink
|
||||
unsigned Moving : 1; /// The unit is moving
|
||||
unsigned ReCast : 1; /// Recast again next cycle
|
||||
unsigned AutoRepair : 1; /// True if unit tries to repair on still action.
|
||||
unsigned long Attacked; /// gamecycle unit was last attacked
|
||||
unsigned Blink : 3; /// Let selection rectangle blink
|
||||
unsigned Moving : 1; /// The unit is moving
|
||||
unsigned ReCast : 1; /// Recast again next cycle
|
||||
unsigned AutoRepair : 1; /// True if unit tries to repair on still action.
|
||||
|
||||
unsigned Burning : 1; /// unit is burning
|
||||
unsigned Destroyed : 1; /// unit is destroyed pending reference
|
||||
unsigned Removed : 1; /// unit is removed (not on map)
|
||||
unsigned Selected : 1; /// unit is selected
|
||||
unsigned Burning : 1; /// unit is burning
|
||||
unsigned Destroyed : 1; /// unit is destroyed pending reference
|
||||
unsigned Removed : 1; /// unit is removed (not on map)
|
||||
unsigned Selected : 1; /// unit is selected
|
||||
|
||||
unsigned Constructed : 1; /// Unit is in construction
|
||||
unsigned Active : 1; /// Unit is active for AI
|
||||
unsigned Boarded : 1; /// Unit is on board a transporter.
|
||||
unsigned CacheLock : 1; /// Unit is on lock by unitcache operations.
|
||||
unsigned CacheLock : 1; /// Unit is on lock by unitcache operations.
|
||||
|
||||
unsigned Summoned : 1; /// Unit is summoned using spells.
|
||||
|
||||
unsigned TeamSelected; /// unit is selected by a team member.
|
||||
CPlayer *RescuedFrom; /// The original owner of a rescued unit.
|
||||
|
@ -417,13 +419,15 @@ class CPreference
|
|||
public:
|
||||
CPreference() : ShowSightRange(false), ShowReactionRange(false),
|
||||
ShowAttackRange(false), ShowMessages(true),
|
||||
BigScreen(false), ShowOrders(0), ShowNameDelay(0), ShowNameTime(0) {};
|
||||
BigScreen(false), PauseOnLeave(true), ShowOrders(0), ShowNameDelay(0),
|
||||
ShowNameTime(0) {};
|
||||
|
||||
bool ShowSightRange; /// Show sight range.
|
||||
bool ShowReactionRange; /// Show reaction range.
|
||||
bool ShowAttackRange; /// Show attack range.
|
||||
bool ShowMessages; /// Show messages.
|
||||
bool BigScreen; /// If true, shows the big screen(without panels)
|
||||
bool PauseOnLeave; /// If true, game pauses when cursor is gone
|
||||
|
||||
int ShowOrders; /// How many second show orders of unit on map.
|
||||
int ShowNameDelay; /// How many cycles need to wait until unit's name popup will appear.
|
||||
|
|
|
@ -281,7 +281,7 @@ extern CUnit *FindIdleWorker(const CPlayer &player, const CUnit *last);
|
|||
extern bool FindTerrainType(int movemask, int resmask, int range,
|
||||
const CPlayer &player, const Vec2i &startPos, Vec2i *pos);
|
||||
|
||||
extern void FindUnitsByType(const CUnitType &type, std::vector<CUnit *> &units);
|
||||
extern void FindUnitsByType(const CUnitType &type, std::vector<CUnit *> &units, bool everybody = false);
|
||||
|
||||
/// Find all units of this type of the player
|
||||
extern void FindPlayerUnitsByType(const CPlayer &player, const CUnitType &type, std::vector<CUnit *> &units);
|
||||
|
|
|
@ -467,6 +467,10 @@ public:
|
|||
LuaCallback *OnHit; /// lua function called when unit is hit
|
||||
LuaCallback *OnEachCycle; /// lua function called every cycle
|
||||
LuaCallback *OnEachSecond; /// lua function called every second
|
||||
LuaCallback *OnInit; /// lua function called on unit init
|
||||
|
||||
int TeleportCost; /// mana used for teleportation
|
||||
MissileConfig TeleportEffect; /// missile created when teleported
|
||||
|
||||
mutable std::string DamageType; /// DamageType (used for extra death animations and impacts)
|
||||
|
||||
|
|
|
@ -294,8 +294,6 @@ public:
|
|||
int getPercent() const;
|
||||
|
||||
private:
|
||||
int width; /// width of the widget.
|
||||
int height; /// height of the widget.
|
||||
std::string caption; /// caption of the widget.
|
||||
unsigned int percent; /// percent value of the widget.
|
||||
};
|
||||
|
|
|
@ -332,25 +332,68 @@ void CViewport::Draw() const
|
|||
|
||||
CurrentViewport = this;
|
||||
{
|
||||
// Now we need to sort units, missiles, particles by draw level and draw them
|
||||
std::vector<CUnit *> unittable;
|
||||
std::vector<Missile *> missiletable;
|
||||
std::vector<CParticle *> particletable;
|
||||
|
||||
// We find and sort units after draw level.
|
||||
FindAndSortUnits(*this, unittable);
|
||||
const size_t nunits = unittable.size();
|
||||
FindAndSortMissiles(*this, missiletable);
|
||||
const size_t nmissiles = missiletable.size();
|
||||
ParticleManager.prepareToDraw(*this, particletable);
|
||||
const size_t nparticles = particletable.size();
|
||||
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
size_t k = 0;
|
||||
|
||||
while (i < nunits && j < nmissiles) {
|
||||
if (unittable[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
|
||||
unittable[i]->Draw(*this);
|
||||
++i;
|
||||
} else {
|
||||
missiletable[j]->DrawMissile(*this);
|
||||
++j;
|
||||
}
|
||||
|
||||
while ((i < nunits && j < nmissiles) || (i < nunits && k < nparticles)
|
||||
|| (j < nmissiles && k < nparticles)) {
|
||||
if (i == nunits) {
|
||||
if (missiletable[j]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||
missiletable[j]->DrawMissile(*this);
|
||||
++j;
|
||||
} else {
|
||||
particletable[k]->draw();
|
||||
++k;
|
||||
}
|
||||
} else if (j == nmissiles) {
|
||||
if (unittable[i]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||
unittable[i]->Draw(*this);
|
||||
++i;
|
||||
} else {
|
||||
particletable[k]->draw();
|
||||
++k;
|
||||
}
|
||||
} else if (k == nparticles) {
|
||||
if (unittable[i]->Type->DrawLevel < missiletable[j]->Type->DrawLevel) {
|
||||
unittable[i]->Draw(*this);
|
||||
++i;
|
||||
} else {
|
||||
missiletable[j]->DrawMissile(*this);
|
||||
++j;
|
||||
}
|
||||
} else {
|
||||
if (unittable[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
|
||||
if (unittable[i]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||
unittable[i]->Draw(*this);
|
||||
++i;
|
||||
} else {
|
||||
particletable[k]->draw();
|
||||
++k;
|
||||
}
|
||||
} else {
|
||||
if (missiletable[j]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||
missiletable[j]->DrawMissile(*this);
|
||||
++j;
|
||||
} else {
|
||||
particletable[k]->draw();
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < nunits; ++i) {
|
||||
unittable[i]->Draw(*this);
|
||||
|
@ -358,10 +401,12 @@ void CViewport::Draw() const
|
|||
for (; j < nmissiles; ++j) {
|
||||
missiletable[j]->DrawMissile(*this);
|
||||
}
|
||||
for (; k < nparticles; ++k) {
|
||||
particletable[k]->draw();
|
||||
}
|
||||
ParticleManager.endDraw();
|
||||
}
|
||||
|
||||
ParticleManager.draw(*this);
|
||||
|
||||
this->DrawMapFogOfWar();
|
||||
|
||||
//
|
||||
|
|
|
@ -46,8 +46,8 @@ static inline float deg2rad(int degrees)
|
|||
|
||||
CChunkParticle::CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
||||
GraphicAnimation *destroyAnimation,
|
||||
int minVelocity, int maxVelocity, int minTrajectoryAngle, int maxTTL) :
|
||||
CParticle(position), initialPos(position), maxTTL(maxTTL), nextSmokeTicks(0),
|
||||
int minVelocity, int maxVelocity, int minTrajectoryAngle, int maxTTL, int drawlevel) :
|
||||
CParticle(position, drawlevel), initialPos(position), maxTTL(maxTTL), nextSmokeTicks(0),
|
||||
age(0), height(0.f)
|
||||
{
|
||||
float radians = deg2rad(MyRand() % 360);
|
||||
|
@ -112,7 +112,7 @@ void CChunkParticle::update(int ticks)
|
|||
if (destroyAnimation) {
|
||||
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
||||
GraphicAnimation *destroyanimation = destroyAnimation->clone();
|
||||
StaticParticle *destroy = new StaticParticle(p, destroyanimation);
|
||||
StaticParticle *destroy = new StaticParticle(p, destroyanimation, destroyDrawLevel);
|
||||
ParticleManager.add(destroy);
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ void CChunkParticle::update(int ticks)
|
|||
if (age > nextSmokeTicks) {
|
||||
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
||||
GraphicAnimation *smokeanimation = smokeAnimation->clone();
|
||||
CSmokeParticle *smoke = new CSmokeParticle(p, smokeanimation);
|
||||
CSmokeParticle *smoke = new CSmokeParticle(p, smokeanimation, 0, -22.0f, smokeDrawLevel);
|
||||
ParticleManager.add(smoke);
|
||||
|
||||
nextSmokeTicks += MyRand() % randSmokeTicks + minSmokeTicks;
|
||||
|
@ -151,7 +151,10 @@ void CChunkParticle::update(int ticks)
|
|||
|
||||
CParticle *CChunkParticle::clone()
|
||||
{
|
||||
return new CChunkParticle(pos, smokeAnimation, debrisAnimation, destroyAnimation, minVelocity, maxVelocity, minTrajectoryAngle, maxTTL);
|
||||
CChunkParticle *particle = new CChunkParticle(pos, smokeAnimation, debrisAnimation, destroyAnimation, minVelocity, maxVelocity, minTrajectoryAngle, maxTTL, drawLevel);
|
||||
particle->smokeDrawLevel = smokeDrawLevel;
|
||||
particle->destroyDrawLevel = destroyDrawLevel;
|
||||
return particle;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "ui.h"
|
||||
#include "video.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
CParticleManager ParticleManager;
|
||||
|
||||
|
@ -70,17 +72,27 @@ void CParticleManager::clear()
|
|||
new_particles.clear();
|
||||
}
|
||||
|
||||
void CParticleManager::draw(const CViewport &vp)
|
||||
static inline bool DrawLevelCompare(const CParticle *lhs, const CParticle *rhs)
|
||||
{
|
||||
return lhs->getDrawLevel() < rhs->getDrawLevel();
|
||||
}
|
||||
|
||||
void CParticleManager::prepareToDraw(const CViewport &vp, std::vector<CParticle *> &table)
|
||||
{
|
||||
this->vp = &vp;
|
||||
|
||||
std::vector<CParticle *>::iterator i;
|
||||
for (i = particles.begin(); i != particles.end(); ++i) {
|
||||
if ((*i)->isVisible(vp)) {
|
||||
(*i)->draw();
|
||||
for (std::vector<CParticle *>::iterator it = particles.begin(); it != particles.end(); ++it) {
|
||||
CParticle &particle = **it;
|
||||
if (particle.isVisible(vp)) {
|
||||
table.push_back(&particle);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(table.begin(), table.end(), DrawLevelCompare);
|
||||
}
|
||||
|
||||
void CParticleManager::endDraw()
|
||||
{
|
||||
this->vp = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include "stratagus.h"
|
||||
#include "particle.h"
|
||||
|
||||
CRadialParticle::CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed) :
|
||||
CParticle(position)
|
||||
CRadialParticle::CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed, int drawlevel) :
|
||||
CParticle(position, drawlevel)
|
||||
{
|
||||
Assert(animation);
|
||||
this->animation = animation->clone();
|
||||
|
@ -76,7 +76,7 @@ void CRadialParticle::update(int ticks)
|
|||
|
||||
CParticle *CRadialParticle::clone()
|
||||
{
|
||||
CParticle *p = new CRadialParticle(pos, animation, maxSpeed);
|
||||
CParticle *p = new CRadialParticle(pos, animation, maxSpeed, drawLevel);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
|
||||
CSmokeParticle::CSmokeParticle(CPosition position, GraphicAnimation *smoke,
|
||||
float speedx, float speedy) :
|
||||
CParticle(position)
|
||||
float speedx, float speedy, int drawlevel) :
|
||||
CParticle(position, drawlevel)
|
||||
{
|
||||
Assert(smoke);
|
||||
this->puff = smoke->clone();
|
||||
|
@ -77,7 +77,7 @@ void CSmokeParticle::update(int ticks)
|
|||
|
||||
CParticle *CSmokeParticle::clone()
|
||||
{
|
||||
return new CSmokeParticle(pos, puff, speedVector.x, speedVector.y);
|
||||
return new CSmokeParticle(pos, puff, speedVector.x, speedVector.y, drawLevel);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
#include "particle.h"
|
||||
|
||||
|
||||
StaticParticle::StaticParticle(CPosition position, GraphicAnimation *animation) :
|
||||
CParticle(position)
|
||||
StaticParticle::StaticParticle(CPosition position, GraphicAnimation *animation, int drawlevel) :
|
||||
CParticle(position, drawlevel)
|
||||
{
|
||||
Assert(animation);
|
||||
this->animation = animation->clone();
|
||||
|
@ -66,7 +66,7 @@ void StaticParticle::update(int ticks)
|
|||
|
||||
CParticle *StaticParticle::clone()
|
||||
{
|
||||
CParticle *p = new StaticParticle(pos, animation);
|
||||
CParticle *p = new StaticParticle(pos, animation, drawLevel);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,14 +438,7 @@ int SetChannelStereo(int channel, int stereo)
|
|||
stereo = Channels[channel].Stereo;
|
||||
} else {
|
||||
SDL_LockAudio();
|
||||
|
||||
if (stereo > 127) {
|
||||
stereo = 127;
|
||||
} else if (stereo < -128) {
|
||||
stereo = -128;
|
||||
}
|
||||
Channels[channel].Stereo = stereo;
|
||||
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
return stereo;
|
||||
|
|
|
@ -333,6 +333,9 @@ static int CclDefineSpell(lua_State *l)
|
|||
} else if (!strcmp(value, "repeat-cast")) {
|
||||
spell->RepeatCast = 1;
|
||||
--i;
|
||||
} else if (!strcmp(value, "force-use-animation")) {
|
||||
spell->ForceUseAnimation = true;
|
||||
--i;
|
||||
} else if (!strcmp(value, "target")) {
|
||||
value = LuaToString(l, i + 1);
|
||||
if (!strcmp(value, "self")) {
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
|
||||
#include "spell/spell_capture.h"
|
||||
|
||||
#include "../ai/ai_local.h"
|
||||
|
||||
#include "commands.h"
|
||||
#include "game.h"
|
||||
#include "script.h"
|
||||
#include "unit.h"
|
||||
|
@ -44,7 +47,9 @@
|
|||
const char *value = LuaToString(l, -1, j + 1);
|
||||
++j;
|
||||
if (!strcmp(value, "sacrifice")) {
|
||||
this->SacrificeEnable = 1;
|
||||
this->SacrificeEnable = true;
|
||||
} else if (!strcmp(value, "join-to-ai-force")) {
|
||||
this->JoinToAIForce = true;
|
||||
} else if (!strcmp(value, "damage")) {
|
||||
this->Damage = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "percent")) {
|
||||
|
@ -79,8 +84,7 @@
|
|||
if (this->SacrificeEnable) {
|
||||
// No corpse.
|
||||
caster.Remove(NULL);
|
||||
UnitLost(caster);
|
||||
UnitClearOrders(caster);
|
||||
caster.Release();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -103,15 +107,24 @@
|
|||
caster.Variable[KILL_INDEX].Enable = 1;
|
||||
}
|
||||
target->ChangeOwner(*caster.Player);
|
||||
UnitClearOrders(*target);
|
||||
if (this->JoinToAIForce && caster.Player->AiEnabled) {
|
||||
int force = caster.Player->Ai->Force.GetForce(caster);
|
||||
if (force != -1) {
|
||||
caster.Player->Ai->Force[force].Insert(*target);
|
||||
target->GroupId = caster.GroupId;
|
||||
CommandDefend(*target, caster, FlushCommands);
|
||||
}
|
||||
}
|
||||
if (this->SacrificeEnable) {
|
||||
// No corpse.
|
||||
caster.Remove(NULL);
|
||||
UnitLost(caster);
|
||||
UnitClearOrders(caster);
|
||||
caster.Release();
|
||||
} else {
|
||||
caster.Variable[MANA_INDEX].Value -= spell.ManaCost;
|
||||
}
|
||||
UnitClearOrders(*target);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
} else {
|
||||
portal = MakeUnitAndPlace(goalPos, *this->PortalType,
|
||||
CurrentPlayer ? caster.Player : &Players[PlayerNumNeutral]);
|
||||
portal->Summoned = 1;
|
||||
}
|
||||
portal->TTL = GameCycle + this->TTL;
|
||||
// Goal is used to link to destination circle of power
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#include "spell/spell_summon.h"
|
||||
|
||||
#include "../ai/ai_local.h"
|
||||
|
||||
#include "actions.h"
|
||||
#include "commands.h"
|
||||
#include "script.h"
|
||||
|
@ -57,7 +59,10 @@
|
|||
} else if (!strcmp(value, "time-to-live")) {
|
||||
this->TTL = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "require-corpse")) {
|
||||
this->RequireCorpse = 1;
|
||||
this->RequireCorpse = true;
|
||||
--j;
|
||||
} else if (!strcmp(value, "join-to-ai-force")) {
|
||||
this->JoinToAiForce = true;
|
||||
--j;
|
||||
} else {
|
||||
LuaError(l, "Unsupported summon tag: %s" _C_ value);
|
||||
|
@ -124,6 +129,8 @@ public:
|
|||
if (target != NULL) {
|
||||
target->tilePos = pos;
|
||||
DropOutOnSide(*target, LookingW, NULL);
|
||||
// To avoid defending summoned unit for AI
|
||||
target->Summoned = 1;
|
||||
//
|
||||
// set life span. ttl=0 results in a permanent unit.
|
||||
//
|
||||
|
@ -131,13 +138,13 @@ public:
|
|||
target->TTL = GameCycle + ttl;
|
||||
}
|
||||
|
||||
// To avoid defending summoned unit for AI
|
||||
if (caster.Player->AiEnabled) {
|
||||
if (caster.GroupId) {
|
||||
// Insert summoned unit to AI force so it will help them in battle
|
||||
if (this->JoinToAiForce && caster.Player->AiEnabled) {
|
||||
int force = caster.Player->Ai->Force.GetForce(caster);
|
||||
if (force != -1) {
|
||||
caster.Player->Ai->Force[force].Insert(*target);
|
||||
target->GroupId = caster.GroupId;
|
||||
CommandDefend(*target, caster, FlushCommands);
|
||||
} else {
|
||||
target->GroupId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -485,7 +485,7 @@ SpellType::SpellType(int slot, const std::string &ident) :
|
|||
Ident(ident), Slot(slot), Target(), Action(),
|
||||
Range(0), ManaCost(0), RepeatCast(0),
|
||||
DependencyId(-1), Condition(NULL),
|
||||
AutoCast(NULL), AICast(NULL)
|
||||
AutoCast(NULL), AICast(NULL), ForceUseAnimation(false)
|
||||
{
|
||||
memset(Costs, 0, sizeof(Costs));
|
||||
}
|
||||
|
|
|
@ -16,30 +16,35 @@ class GraphicAnimation
|
|||
class CParticle
|
||||
{
|
||||
virtual CParticle* clone();
|
||||
void setDrawLevel(int value);
|
||||
};
|
||||
|
||||
class StaticParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
StaticParticle(CPosition position, GraphicAnimation *animation);
|
||||
StaticParticle(CPosition position, GraphicAnimation *animation, int drawlevel = 0);
|
||||
};
|
||||
|
||||
class CChunkParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation, GraphicAnimation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0);
|
||||
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation, GraphicAnimation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0, int drawlevel = 0);
|
||||
int getSmokeDrawLevel() const;
|
||||
int getDestroyDrawLevel() const;
|
||||
void setSmokeDrawLevel(int value);
|
||||
void setDestroyDrawLevel(int value);
|
||||
};
|
||||
|
||||
class CSmokeParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0);
|
||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0, int drawlevel = 0);
|
||||
};
|
||||
|
||||
class CRadialParticle : public CParticle
|
||||
{
|
||||
public:
|
||||
CRadialParticle(CPosition position, GraphicAnimation *smokeAnimation, int maxSpeed);
|
||||
CRadialParticle(CPosition position, GraphicAnimation *smokeAnimation, int maxSpeed, int drawlevel = 0);
|
||||
};
|
||||
|
||||
class CParticleManager
|
||||
|
|
|
@ -22,6 +22,7 @@ class CPreference
|
|||
bool ShowAttackRange;
|
||||
bool ShowMessages;
|
||||
bool BigScreen;
|
||||
bool PauseOnLeave;
|
||||
|
||||
unsigned int ShowOrders;
|
||||
unsigned int ShowNameDelay;
|
||||
|
|
|
@ -847,14 +847,17 @@ void UpdateStatusLineForButton(const ButtonAction &button)
|
|||
*/
|
||||
bool IsButtonAllowed(const CUnit &unit, const ButtonAction &buttonaction)
|
||||
{
|
||||
bool res = false;
|
||||
if (buttonaction.Allowed) {
|
||||
return buttonaction.Allowed(unit, buttonaction);
|
||||
res = buttonaction.Allowed(unit, buttonaction);
|
||||
if (!res) {
|
||||
return false;
|
||||
} else {
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
// FIXME: we have to check and if these unit buttons are available
|
||||
// i.e. if button action is ButtonTrain for example check if
|
||||
// required unit is not restricted etc...
|
||||
// Check button-specific cases
|
||||
switch (buttonaction.Action) {
|
||||
case ButtonStop:
|
||||
case ButtonStandGround:
|
||||
|
|
|
@ -153,7 +153,7 @@ static void UiDrawLifeBar(const CUnit &unit, int x, int y)
|
|||
}
|
||||
|
||||
f = (f * (unit.Type->Icon.Icon->G->Width)) / 100;
|
||||
Video.FillRectangleClip(color, x + 1, y + 1, f - 2, 5);
|
||||
Video.FillRectangleClip(color, x + 1, y + 1, f > 1 ? f - 2 : 0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -377,6 +377,9 @@ static int CclUnit(lua_State *l)
|
|||
} else if (!strcmp(value, "selected")) {
|
||||
unit->Selected = 1;
|
||||
--j;
|
||||
} else if (!strcmp(value, "summoned")) {
|
||||
unit->Summoned = 1;
|
||||
--j;
|
||||
} else if (!strcmp(value, "rescued-from")) {
|
||||
unit->RescuedFrom = &Players[LuaToNumber(l, 2, j + 1)];
|
||||
} else if (!strcmp(value, "seen-by-player")) {
|
||||
|
|
|
@ -551,6 +551,11 @@ static int CclDefineUnitType(lua_State *l)
|
|||
type->ExplodeWhenKilled = 1;
|
||||
type->Explosion.Name = LuaToString(l, -1);
|
||||
type->Explosion.Missile = NULL;
|
||||
} else if (!strcmp(value, "TeleportCost")) {
|
||||
type->TeleportCost = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(value, "TeleportEffect")) {
|
||||
type->TeleportEffect.Name = LuaToString(l, -1);
|
||||
type->TeleportEffect.Missile = NULL;
|
||||
} else if (!strcmp(value, "DeathExplosion")) {
|
||||
type->DeathExplosion = new LuaCallback(l, -1);
|
||||
} else if (!strcmp(value, "OnHit")) {
|
||||
|
@ -559,6 +564,8 @@ static int CclDefineUnitType(lua_State *l)
|
|||
type->OnEachCycle = new LuaCallback(l, -1);
|
||||
} else if (!strcmp(value, "OnEachSecond")) {
|
||||
type->OnEachSecond = new LuaCallback(l, -1);
|
||||
} else if (!strcmp(value, "OnInit")) {
|
||||
type->OnInit = new LuaCallback(l, -1);
|
||||
} else if (!strcmp(value, "Type")) {
|
||||
value = LuaToString(l, -1);
|
||||
if (!strcmp(value, "land")) {
|
||||
|
|
|
@ -453,6 +453,7 @@ void CUnit::Init()
|
|||
Moving = 0;
|
||||
ReCast = 0;
|
||||
CacheLock = 0;
|
||||
Summoned = 0;
|
||||
memset(&Anim, 0, sizeof(Anim));
|
||||
CurrentResource = 0;
|
||||
Orders.clear();
|
||||
|
@ -738,6 +739,12 @@ CUnit *MakeUnit(const CUnitType &type, CPlayer *player)
|
|||
unit->AssignToPlayer(*player);
|
||||
}
|
||||
|
||||
if (unit->Type->OnInit) {
|
||||
unit->Type->OnInit->pushPreamble();
|
||||
unit->Type->OnInit->pushInteger(UnitNumber(*unit));
|
||||
unit->Type->OnInit->run();
|
||||
}
|
||||
|
||||
// fancy buildings: mirror buildings (but shadows not correct)
|
||||
if (type.Building && FancyBuildings
|
||||
&& unit->Type->NoRandomPlacing == false && (MyRand() & 1) != 0) {
|
||||
|
|
|
@ -310,7 +310,6 @@ public:
|
|||
resinfo(*worker.Type->ResInfo[resource]),
|
||||
deposit(deposit),
|
||||
movemask(worker.Type->MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)),
|
||||
resource(resource),
|
||||
maxRange(maxRange),
|
||||
check_usage(check_usage),
|
||||
res_finder(resource, 1),
|
||||
|
@ -348,7 +347,6 @@ private:
|
|||
const ResourceInfo &resinfo;
|
||||
const CUnit *deposit;
|
||||
unsigned int movemask;
|
||||
int resource;
|
||||
int maxRange;
|
||||
bool check_usage;
|
||||
CResourceFinder res_finder;
|
||||
|
@ -511,15 +509,16 @@ CUnit *FindIdleWorker(const CPlayer &player, const CUnit *last)
|
|||
/**
|
||||
** Find all units of type.
|
||||
**
|
||||
** @param type type of unit requested
|
||||
** @param units array in which we have to store the units
|
||||
** @param type type of unit requested
|
||||
** @param units array in which we have to store the units
|
||||
** @param everybody if true, include all units
|
||||
*/
|
||||
void FindUnitsByType(const CUnitType &type, std::vector<CUnit *> &units)
|
||||
void FindUnitsByType(const CUnitType &type, std::vector<CUnit *> &units, bool everybody)
|
||||
{
|
||||
for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) {
|
||||
CUnit &unit = **it;
|
||||
|
||||
if (unit.Type == &type && !unit.IsUnusable()) {
|
||||
if (unit.Type == &type && !unit.IsUnusable(everybody)) {
|
||||
units.push_back(&unit);
|
||||
}
|
||||
}
|
||||
|
@ -1008,9 +1007,7 @@ private:
|
|||
}
|
||||
|
||||
// don't consider small damages...
|
||||
if (sgood < 20) {
|
||||
sgood = 20;
|
||||
}
|
||||
sgood = std::max(sgood, 20);
|
||||
|
||||
int cost = sbad / sgood;
|
||||
if (cost > best_cost) {
|
||||
|
|
|
@ -177,6 +177,9 @@ void SaveUnit(const CUnit &unit, CFile &file)
|
|||
if (unit.Selected) {
|
||||
file.printf(" \"selected\",");
|
||||
}
|
||||
if (unit.Summoned) {
|
||||
file.printf(" \"summoned\",");
|
||||
}
|
||||
if (unit.RescuedFrom) {
|
||||
file.printf(" \"rescued-from\", %d,", unit.RescuedFrom->Index);
|
||||
}
|
||||
|
|
|
@ -611,7 +611,8 @@ CUnitType::CUnitType() :
|
|||
Slot(0), Width(0), Height(0), OffsetX(0), OffsetY(0), DrawLevel(0),
|
||||
ShadowWidth(0), ShadowHeight(0), ShadowOffsetX(0), ShadowOffsetY(0),
|
||||
Animations(NULL), StillFrame(0),
|
||||
DeathExplosion(NULL), OnHit(NULL), OnEachCycle(NULL), OnEachSecond(NULL),
|
||||
DeathExplosion(NULL), OnHit(NULL), OnEachCycle(NULL), OnEachSecond(NULL), OnInit(NULL),
|
||||
TeleportCost(0),
|
||||
CorpseType(NULL), Construction(NULL), RepairHP(0), TileWidth(0), TileHeight(0),
|
||||
BoxWidth(0), BoxHeight(0), BoxOffsetX(0), BoxOffsetY(0), NumDirections(0),
|
||||
MinAttackRange(0), ReactRangeComputer(0), ReactRangePerson(0), Priority(0),
|
||||
|
@ -649,6 +650,7 @@ CUnitType::~CUnitType()
|
|||
delete OnHit;
|
||||
delete OnEachCycle;
|
||||
delete OnEachSecond;
|
||||
delete OnInit;
|
||||
|
||||
BoolFlag.clear();
|
||||
|
||||
|
@ -1123,6 +1125,7 @@ void LoadUnitTypes()
|
|||
// Lookup missiles.
|
||||
type.Missile.MapMissile();
|
||||
type.Explosion.MapMissile();
|
||||
type.TeleportEffect.MapMissile();
|
||||
|
||||
// Lookup impacts
|
||||
for (int i = 0; i < ANIMATIONS_DEATHTYPES + 2; ++i) {
|
||||
|
|
|
@ -597,7 +597,7 @@ static void ApplyUpgradeModifier(CPlayer &player, const CUpgradeModifier *um)
|
|||
if (varModified) {
|
||||
std::vector<CUnit *> unitupgrade;
|
||||
|
||||
FindUnitsByType(*UnitTypes[z], unitupgrade);
|
||||
FindUnitsByType(*UnitTypes[z], unitupgrade, true);
|
||||
for (size_t j = 0; j != unitupgrade.size(); ++j) {
|
||||
CUnit &unit = *unitupgrade[j];
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
#include "sound_server.h"
|
||||
#include "translate.h"
|
||||
#include "ui.h"
|
||||
#include "unit.h"
|
||||
#include "video.h"
|
||||
#include "widgets.h"
|
||||
|
||||
|
@ -860,7 +861,7 @@ static void SdlDoEvent(const EventCallback &callbacks, SDL_Event &event)
|
|||
}
|
||||
InMainWindow = (event.active.gain != 0);
|
||||
}
|
||||
if (event.active.state & SDL_APPACTIVE || SDL_GetAppState() & SDL_APPACTIVE) {
|
||||
if (Preference.PauseOnLeave && (event.active.state & SDL_APPACTIVE || SDL_GetAppState() & SDL_APPACTIVE)) {
|
||||
static bool DoTogglePause = false;
|
||||
|
||||
if (IsSDLWindowVisible && !event.active.gain) {
|
||||
|
|
|
@ -53,6 +53,7 @@ void FillCustomValue(CServerSetup *obj)
|
|||
obj->GameTypeOption = 52;
|
||||
obj->Difficulty = 54;
|
||||
obj->MapRichness = 56;
|
||||
obj->Opponents = 58;
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
obj->CompOpt[i] = i + 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue