defense goal: clean up wave control

Merge this into enemy control, which did handle most of the control stuff already.
alut-include-path
Maikel de Vries 2017-02-04 14:29:49 +01:00
parent 487fcc362d
commit 2be444c297
9 changed files with 92 additions and 124 deletions

View File

@ -65,7 +65,8 @@ protected func InitializePlayer(int plr)
public func GetAttackWave(int nr)
{
// The round starts with a short phase to prepare.
if (nr == 1) return new DefenseWave.Break { Duration = 120 };
if (nr == 1)
return new DefenseEnemy.BreakWave { Duration = 120 };
// Attack positions.
var pos_land = {X = LandscapeWidth(), Y = 760, Exact = true};
@ -73,7 +74,7 @@ public func GetAttackWave(int nr)
var pos_above = {X = 200, Y = 0};
// Automatically build waves that become stronger.
var wave =
var wave = new DefenseEnemy.DefaultWave
{
Name = "$MsgWave$",
// Waves last shorter as the number increases.

View File

@ -1,5 +1,6 @@
/**
Defense Enemy
Defines standard enemies which attack the player or its base. The enemy is a list of properties, the main ones are:
* Type (id) - The type of enemy (defaults to Clonk).
* Amount (int) - The amount of this type of enemy (use to create large groups).
@ -14,6 +15,13 @@
* VehicleHP - Hitpoints for the enemy vehicle, can be made stronger.
* IsCrew - Is part of a crew of the AI that is controlling the vehicle.
This also defines standard waves which attack the player or its base. The wave is a list of properties, the main ones are:
* Name (string) - The name of the attack wave.
* Duration (int) - Duration of the wave in seconds, if nil the next wave is only launched when this is fully eliminated.
* Bounty (int) - The amount of clunkers received for beating the wave.
* Score (int) - The amount of points obtained for beating this wave.
* Enemies (array) - Array of enemies, see DefenseEnemy for more information.
@author Maikel
*/
@ -23,6 +31,9 @@
// Definition call which can be used to launch an enemy.
public func LaunchEnemy(proplist prop_enemy, int wave_nr, int enemy_plr)
{
if (GetType(this) != C4V_Def)
Log("WARNING: LaunchEnemy(%v, %d, %d) not called from definition context but from %v.", prop_enemy, wave_nr, enemy_plr, this);
// Don't launch the enemy when amount equals zero.
if (!prop_enemy || prop_enemy.Amount <= 0)
return;
@ -133,7 +144,8 @@ private func LaunchEnemyAt(proplist prop_enemy, int wave_nr, int enemy_plr, prop
if (prop_enemy.VehicleHP)
vehicle.HitPoints = prop_enemy.VehicleHP;
// Add the enemy vehicle to no friendly fire rule (must be done by hand, noFF rule is for crew only be default).
GameCallEx("OnCreationRuleNoFF", vehicle);
if (vehicle)
GameCallEx("OnCreationRuleNoFF", vehicle);
}
// Move crew members onto their vehicles.
if (prop_enemy.IsCrew && prop_enemy.Vehicle)
@ -200,7 +212,7 @@ static const CSKIN_Default = 0,
CSKIN_Farmer = 3;
// Default enemy, all other enemies inherit from this.
static const DefaultEnemy =
local DefaultEnemy =
{
Type = nil,
Inventory = nil,
@ -331,4 +343,45 @@ local AirshipCrew = new DefaultEnemy
Skin = CSKIN_Farmer,
Vehicle = Airship,
IsCrew = true
};
};
/*-- Wave Launching --*/
// Definition call which can be used to launch an attack wave.
public func LaunchWave(proplist prop_wave, int wave_nr, int enemy_plr)
{
if (GetType(this) != C4V_Def)
Log("WARNING: LaunchWave(%v, %d, %d) not called from definition context but from %v.", prop_wave, wave_nr, enemy_plr, this);
// Create count down until next wave and play wave start sound.
GUI_Clock->CreateCountdown(prop_wave.Duration);
CustomMessage(Format("$MsgWave$", wave_nr, prop_wave.Name));
Sound("UI::Ding");
// Launch enemies.
if (prop_wave.Enemies)
for (var enemy in prop_wave.Enemies)
this->LaunchEnemy(enemy, wave_nr, enemy_plr);
return;
}
/*-- Waves --*/
// Default wave, all other waves inherit from this.
local DefaultWave =
{
Name = nil,
Duration = nil,
Bounty = nil,
Score = nil,
Enemies = nil
};
// A wave with no enemies: either at the start or to allow for a short break.
local BreakWave = new DefaultWave
{
Name = "$WaveBreak$",
Duration = 60
};

View File

@ -8,4 +8,7 @@ EnemyBallooner=Fallschirmspringer
EnemyRocketeer=Raketenreiter
EnemyBomber=Bomber
EnemyAirshipPilot=Pilot
EnemyAirshipCrew=Luftmatrose
EnemyAirshipCrew=Luftmatrose
MsgWave=Welle %d: %s| |
WaveBreak=Pause

View File

@ -8,4 +8,7 @@ EnemyBallooner=Parachutist
EnemyRocketeer=Rocketeer
EnemyBomber=Bomber
EnemyAirshipPilot=Pilot
EnemyAirshipCrew=Airsailor
EnemyAirshipCrew=Airsailor
MsgWave=Wave %d: %s| |
WaveBreak=Break

View File

@ -1,5 +0,0 @@
[DefCore]
id=DefenseWave
Version=8,0
Category=C4D_StaticBack
HideInCreator=true

View File

@ -1,89 +0,0 @@
/**
Defense Wave
Defines standard waves which attack the player or its base. The wave is a list of properties, the main ones are:
* Name (string) - The name of the attack wave.
* Duration (int) - Duration of the wave in seconds.
* Bounty (int) - The amount of clunkers received for beating the wave.
* Score (int) - The amount of points obtained for beating this wave.
* Enemies (array) - Array of enemies, see DefenseEnemy for more information.
@author Maikel
*/
/*-- Wave Launching --*/
// Definition call which can be used to launch an attack wave.
public func LaunchWave(proplist prop_wave, int wave_nr, int enemy_plr)
{
// Create count down until next wave and play wave start sound.
GUI_Clock->CreateCountdown(prop_wave.Duration);
CustomMessage(Format("$MsgWave$", wave_nr, prop_wave.Name));
Sound("UI::Ding");
// Launch enemies.
if (prop_wave.Enemies)
for (var enemy in prop_wave.Enemies)
DefenseEnemy->LaunchEnemy(enemy, wave_nr, enemy_plr);
return;
}
/*-- Waves --*/
// Default wave, all other waves inherit from this.
static const DefaultWave =
{
Name = nil,
Duration = 0,
Bounty = nil,
Score = nil,
Enemies = nil
};
// A wave with no enemies: either at the start or to allow for a short break.
local Break = new DefaultWave
{
Name = "$WaveBreak$",
Duration = 60
};
// A group of rockets who move to a target.
local BoomAttack = new DefaultWave
{
Name = "$WaveBoomAttack$",
Duration = 60,
Bounty = 50,
Score = 100,
Enemies = [new DefenseEnemy.BoomAttack {Amount = 10}]
};
// A group of rockets who move to a target.
local RapidBoomAttack = new DefaultWave
{
Name = "$WaveRapidBoomAttack$",
Duration = 60,
Bounty = 50,
Score = 100,
Enemies = [new DefenseEnemy.RapidBoomAttack {Amount = 10}]
};
// A group of parachutists from above.
local Ballooner = new DefaultWave
{
Name = "$WaveBallooner$",
Duration = 60,
Bounty = 25,
Score = 100,
Enemies = [new DefenseEnemy.Ballooner {Amount = 10}]
};
// A group of rocketeers.
local Rocketeers = new DefaultWave
{
Name = "$WaveRocketeers$",
Duration = 60,
Bounty = 25,
Score = 100,
Enemies = [new DefenseEnemy.Rocketeer {Amount = 10}]
};

View File

@ -1,7 +0,0 @@
MsgWave=Welle %d: %s| |
WaveBreak=Pause
WaveBoomAttack=Raketengeschwader
WaveRapidBoomAttack=Rasches Raketengeschwader
WaveBallooner=Fallschirmabwurf
WaveRocketeers=Raketenreiter

View File

@ -1,7 +0,0 @@
MsgWave=Wave %d: %s| |
WaveBreak=Break
WaveBoomAttack=Rocket squadron
WaveRapidBoomAttack=Rapid rocket squadron
WaveBallooner=Parachute drop
WaveRocketeers=Rocketeers

View File

@ -171,7 +171,7 @@ local FxWaveControl = new Effect
Timer = func(int time)
{
// Start new wave if duration of previous wave has passed.
if (!this.wave || this.time_passed >= this.wave.Duration)
if (!this.wave || (this.wave.Duration != nil && this.time_passed >= this.wave.Duration))
{
this.wave = GameCall("GetAttackWave", this.wave_nr);
// Check if this was the last wave.
@ -180,7 +180,7 @@ local FxWaveControl = new Effect
Log("WARNING: wave not specified for wave number %d. Using default wave of defense goal instead.", this.wave_nr);
this.wave = Target->GetDefaultWave(this.wave_nr);
}
DefenseWave->LaunchWave(this.wave, this.wave_nr, this.enemy);
DefenseEnemy->LaunchWave(this.wave, this.wave_nr, this.enemy);
// Track the wave.
Target->CreateEffect(Target.FxTrackWave, 100, nil, this.wave_nr, this.wave);
// Reset passed time and increase wave number for next wave.
@ -192,6 +192,14 @@ local FxWaveControl = new Effect
return FX_OK;
},
OnWaveCompleted = func(int wave_nr)
{
// Set current wave to nil if it has been completed and has no duration in order to start new one.
if (wave_nr + 1 == this.wave_nr && this.wave.Duration == nil)
this.wave = nil;
return;
},
GetCurrentWave = func()
{
return this.wave;
@ -216,7 +224,7 @@ local FxWaveControl = new Effect
public func GetDefaultWave(int wave_nr)
{
// Just launch some rockets as the default wave and increase the amount and their speed with every wave.
var wave = new DefaultWave
var wave = new DefenseEnemy.DefaultWave
{
Name = "$WaveFallBack$",
Duration = 2 * 60,
@ -240,7 +248,7 @@ local FxTrackWave = new Effect
},
OnEnemyInit = func(object enemy)
{
PushBack(this.enemies, enemy);
PushBack(this.enemies, enemy);
},
OnEnemyEliminated = func(object enemy)
{
@ -255,7 +263,7 @@ local FxTrackWave = new Effect
}
if (this.wave.Score != nil && !Target->IsFulfilled())
Target->DoScore(this.wave.Score);
Target->IncreaseCompletedWaves();
Target->OnWaveCompleted(this.wave_nr);
Sound("UI::NextWave");
this->Remove();
}
@ -279,10 +287,14 @@ public func OnEnemyElimination(object enemy)
return;
}
public func IncreaseCompletedWaves()
public func OnWaveCompleted(int wave_nr)
{
// Increase number of completed waves and update achievements.
completed_waves++;
CheckAchievement();
// Let wave control effect know a wave has been completed.
if (fx_wave_control)
fx_wave_control->OnWaveCompleted(wave_nr);
return;
}
@ -351,7 +363,9 @@ public func CheckAchievement()
public func ConvertWaveToAchievement(int wave_nr)
{
// Get the number of waves needed for achieving stars.
var data = GameCall("GetWaveToAchievement");
// By default the stars are awarded for 5, 10 and 25 completed waves.
if (!data)
data = [5, 10, 25];
SortArray(data);
@ -387,7 +401,8 @@ public func GetDescription(int plr)
{
wave_msg = Format("$MsgCurrentWave$", fx_wave_control->GetCurrentWave());
for (var enemy in enemies)
wave_msg = Format("%s%dx %s\n", wave_msg, enemy.Amount, enemy.Name);
if (enemy.Amount > 0)
wave_msg = Format("%s%dx %s\n", wave_msg, enemy.Amount, enemy.Name);
}
// Show enemies of next wave.
var next_enemies = fx_wave_control->GetNextWave().Enemies;
@ -395,7 +410,8 @@ public func GetDescription(int plr)
{
wave_msg = Format("%s\n$MsgNextWave$", wave_msg);
for (var enemy in next_enemies)
wave_msg = Format("%s%dx %s\n", wave_msg, enemy.Amount, enemy.Name);
if (enemy.Amount > 0)
wave_msg = Format("%s%dx %s\n", wave_msg, enemy.Amount, enemy.Name);
}
}
// Add score.
@ -411,7 +427,7 @@ public func TestWave(int nr)
var wave = GameCall("GetAttackWave", nr);
if (!wave || !fx_wave_control)
return;
DefenseWave->LaunchWave(wave, nr, fx_wave_control->GetEnemy());
DefenseEnemy->LaunchWave(wave, nr, fx_wave_control->GetEnemy());
return;
}