forked from Mirrors/openclonk
defense goal: clean up wave control
Merge this into enemy control, which did handle most of the control stuff already.alut-include-path
parent
487fcc362d
commit
2be444c297
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -8,4 +8,7 @@ EnemyBallooner=Fallschirmspringer
|
|||
EnemyRocketeer=Raketenreiter
|
||||
EnemyBomber=Bomber
|
||||
EnemyAirshipPilot=Pilot
|
||||
EnemyAirshipCrew=Luftmatrose
|
||||
EnemyAirshipCrew=Luftmatrose
|
||||
|
||||
MsgWave=Welle %d: %s| |
|
||||
WaveBreak=Pause
|
|
@ -8,4 +8,7 @@ EnemyBallooner=Parachutist
|
|||
EnemyRocketeer=Rocketeer
|
||||
EnemyBomber=Bomber
|
||||
EnemyAirshipPilot=Pilot
|
||||
EnemyAirshipCrew=Airsailor
|
||||
EnemyAirshipCrew=Airsailor
|
||||
|
||||
MsgWave=Wave %d: %s| |
|
||||
WaveBreak=Break
|
|
@ -1,5 +0,0 @@
|
|||
[DefCore]
|
||||
id=DefenseWave
|
||||
Version=8,0
|
||||
Category=C4D_StaticBack
|
||||
HideInCreator=true
|
|
@ -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}]
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
MsgWave=Welle %d: %s| |
|
||||
|
||||
WaveBreak=Pause
|
||||
WaveBoomAttack=Raketengeschwader
|
||||
WaveRapidBoomAttack=Rasches Raketengeschwader
|
||||
WaveBallooner=Fallschirmabwurf
|
||||
WaveRocketeers=Raketenreiter
|
|
@ -1,7 +0,0 @@
|
|||
MsgWave=Wave %d: %s| |
|
||||
|
||||
WaveBreak=Break
|
||||
WaveBoomAttack=Rocket squadron
|
||||
WaveRapidBoomAttack=Rapid rocket squadron
|
||||
WaveBallooner=Parachute drop
|
||||
WaveRocketeers=Rocketeers
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue