@@ -2,7 +2,6 @@ use crate::action::{CombatAction, PlayActionCard};
2
2
use crate :: combat:: CombatModifier :: {
3
3
CancelFortressExtraDie , SteelWeaponsAttacker , SteelWeaponsDefender ,
4
4
} ;
5
- use crate :: content:: advances:: STEEL_WEAPONS ;
6
5
use crate :: content:: custom_phase_actions:: { start_siegecraft_phase, start_steel_weapons_phase} ;
7
6
use crate :: game:: GameState :: Playing ;
8
7
use crate :: game:: { Game , GameState } ;
@@ -13,6 +12,30 @@ use itertools::Itertools;
13
12
use serde:: { Deserialize , Serialize } ;
14
13
use std:: mem;
15
14
15
+ #[ derive( Clone , PartialEq ) ]
16
+ pub struct CombatStrength {
17
+ pub attacker : bool ,
18
+ pub player_index : usize ,
19
+ pub extra_dies : u8 ,
20
+ pub extra_combat_value : u8 ,
21
+ pub hit_cancels : u8 ,
22
+ pub roll_log : Vec < String > ,
23
+ }
24
+
25
+ impl CombatStrength {
26
+ #[ must_use]
27
+ pub fn new ( player_index : usize , attacker : bool ) -> Self {
28
+ Self {
29
+ player_index,
30
+ attacker,
31
+ extra_dies : 0 ,
32
+ extra_combat_value : 0 ,
33
+ hit_cancels : 0 ,
34
+ roll_log : vec ! [ ] ,
35
+ }
36
+ }
37
+ }
38
+
16
39
#[ derive( Serialize , Deserialize , Clone , PartialEq , Eq , Debug ) ]
17
40
pub enum CombatPhase {
18
41
PlayActionCard ( usize ) ,
@@ -259,90 +282,70 @@ fn remove_casualties(game: &mut Game, c: &mut Combat, units: Vec<u32>) -> Combat
259
282
resolve_combat ( game, c)
260
283
}
261
284
285
+ ///
286
+ /// # Panics
287
+ /// Panics if events are not set
262
288
pub fn combat_loop ( game : & mut Game , mut c : Combat ) {
263
289
loop {
264
290
game. add_info_log_item ( format ! ( "\n Combat round {}" , c. round) ) ;
265
291
//todo: go into tactics phase if either player has tactics card (also if they can not play it unless otherwise specified via setting)
266
292
267
- let steel_weapon_value = if game. get_player ( c. attacker ) . has_advance ( STEEL_WEAPONS )
268
- && game. get_player ( c. defender ) . has_advance ( STEEL_WEAPONS )
269
- {
270
- 1
271
- } else {
272
- 2
273
- } ;
274
- let mut steel_weapon_log = vec ! [ ] ;
275
293
let attacker_name = game. players [ c. attacker ] . get_name ( ) ;
276
294
let active_attackers = c. active_attackers ( game) ;
277
- let attacker_extra = if c. modifiers . contains ( & SteelWeaponsAttacker ) {
278
- steel_weapon_log. push ( format ! (
279
- "Attacker used steel weapons to add {steel_weapon_value} to their combat value"
280
- ) ) ;
281
- steel_weapon_value
282
- } else {
283
- 0
284
- } ;
295
+ let mut attacker_strength = CombatStrength :: new ( c. attacker , true ) ;
296
+ game. players [ c. attacker ]
297
+ . events
298
+ . as_ref ( )
299
+ . expect ( "events should be set" )
300
+ . on_combat_round
301
+ . trigger ( & mut attacker_strength, & c, game) ;
285
302
let mut attacker_log = vec ! [ ] ;
286
303
let attacker_rolls = roll (
287
304
game,
288
305
c. attacker ,
289
306
& active_attackers,
290
- 0 ,
291
- attacker_extra ,
307
+ attacker_strength . extra_dies ,
308
+ attacker_strength . extra_combat_value ,
292
309
& mut attacker_log,
293
310
) ;
294
311
let attacker_log_str = roll_log_str ( & attacker_log) ;
295
312
296
313
let active_defenders = active_defenders ( game, c. defender , c. defender_position ) ;
297
314
let defender_name = game. players [ c. defender ] . get_name ( ) ;
298
315
let mut defender_log = vec ! [ ] ;
299
- let mut fortress_log = vec ! [ ] ;
300
- let extra_defender_dies =
301
- if c. defender_fortress ( game) && !c. modifiers . contains ( & CancelFortressExtraDie ) {
302
- fortress_log. push ( "added one extra die" ) ;
303
- 1
304
- } else {
305
- 0
306
- } ;
307
- let defender_extra = if c. modifiers . contains ( & SteelWeaponsDefender ) {
308
- steel_weapon_log. push ( format ! (
309
- "Defender used steel weapons to add {steel_weapon_value} to their combat value"
310
- ) ) ;
311
- steel_weapon_value
312
- } else {
313
- 0
314
- } ;
316
+ let mut defender_strength = CombatStrength :: new ( c. defender , false ) ;
317
+ game. players [ c. defender ]
318
+ . events
319
+ . as_ref ( )
320
+ . expect ( "events should be set" )
321
+ . on_combat_round
322
+ . trigger ( & mut defender_strength, & c, game) ;
315
323
let defender_rolls = roll (
316
324
game,
317
325
c. defender ,
318
326
& active_defenders,
319
- extra_defender_dies ,
320
- defender_extra ,
327
+ defender_strength . extra_dies ,
328
+ defender_strength . extra_combat_value ,
321
329
& mut defender_log,
322
330
) ;
323
331
let defender_log_str = roll_log_str ( & defender_log) ;
324
332
let attacker_combat_value = attacker_rolls. combat_value ;
325
- let attacker_hit_cancels = attacker_rolls. hit_cancels ;
333
+ let attacker_hit_cancels = attacker_rolls. hit_cancels + attacker_strength . hit_cancels ;
326
334
let defender_combat_value = defender_rolls. combat_value ;
327
- let mut defender_hit_cancels = defender_rolls. hit_cancels ;
328
- if c. defender_fortress ( game)
329
- && !c
330
- . modifiers
331
- . contains ( & CombatModifier :: CancelFortressIgnoreHit )
332
- {
333
- defender_hit_cancels += 1 ;
334
- fortress_log. push ( "cancelled one hit" ) ;
335
- }
335
+ let defender_hit_cancels = defender_rolls. hit_cancels + defender_strength. hit_cancels ;
336
336
let attacker_hits = ( attacker_combat_value / 5 ) . saturating_sub ( defender_hit_cancels) ;
337
337
let defender_hits = ( defender_combat_value / 5 ) . saturating_sub ( attacker_hit_cancels) ;
338
338
game. add_info_log_item ( format ! ( "\t {attacker_name} rolled {attacker_log_str} for combined combat value of {attacker_combat_value} and gets {attacker_hits} hits against defending units. {defender_name} rolled {defender_log_str} for combined combat value of {defender_combat_value} and gets {defender_hits} hits against attacking units." ) ) ;
339
- if !steel_weapon_log. is_empty ( ) {
340
- game. add_info_log_item ( steel_weapon_log. join ( ", " ) ) ;
339
+ if !attacker_strength. roll_log . is_empty ( ) {
340
+ game. add_info_log_item ( format ! (
341
+ ". {attacker_name} used the following combat modifiers: {}" ,
342
+ attacker_strength. roll_log. join( ", " )
343
+ ) ) ;
341
344
}
342
- if !fortress_log . is_empty ( ) {
345
+ if !defender_strength . roll_log . is_empty ( ) {
343
346
game. add_info_log_item ( format ! (
344
- " {defender_name} has a fortress, which {}" ,
345
- fortress_log . join( ", " )
347
+ ". {defender_name} used the following combat modifiers: {}" ,
348
+ defender_strength . roll_log . join( ", " )
346
349
) ) ;
347
350
}
348
351
if attacker_hits < active_defenders. len ( ) as u8 && attacker_hits > 0 {
0 commit comments