@@ -37,11 +37,9 @@ public class Werewolf20Extractor {
37
37
RiteLocations .DATA ,
38
38
FetishLocations .DATA ,
39
39
TalenLocations .DATA ,
40
- new WeaponLocations (
41
- new Paragraph (303 , makeRect (121 , 129 , 263 , 280 )),
42
- new Paragraph (303 , makeRect (0 , 0 , 0 , 0 )),
43
- new Paragraph (304 , makeRect (0 , 0 , 0 , 0 ))
44
- ),
40
+ MeleeWeaponLocations .DATA .get (0 ),
41
+ ThrownWeaponLocations .DATA .get (0 ),
42
+ RangedWeaponLocations .DATA .get (0 ),
45
43
Collections .emptyList (),
46
44
MeritAndFlawLocations .DATA
47
45
);
@@ -56,7 +54,9 @@ private record Book(
56
54
List <RiteLocation > rites ,
57
55
List <FetishLocation > fetishes ,
58
56
List <TalenLocation > talens ,
59
- WeaponLocations weapons ,
57
+ MeleeWeaponLocation meleeWeapons ,
58
+ ThrownWeaponLocation thrownWeapons ,
59
+ RangedWeaponLocation rangedWeapons ,
60
60
List <SpiritLocation > spirits ,
61
61
List <MeritAndFlawLocation > meritsAndFlaws
62
62
) {}
@@ -280,7 +280,7 @@ public List<BookEntry> process() {
280
280
281
281
processTribes ();
282
282
283
- processMeleeWeapons ();
283
+ processWeapons ();
284
284
285
285
processBackgrounds ();
286
286
@@ -435,10 +435,10 @@ private void processTribes() {
435
435
}
436
436
}
437
437
438
- private void processMeleeWeapons () {
438
+ private void processWeapons () {
439
439
entries .add (new MeleeWeapon (
440
440
"Bite - Crinos, Hispo, Lupus" ,
441
- getText (parser , new Paragraph (297 , makeRect (304 , 213 , 245 , 77 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Bite:\\ s*" , "" ),
441
+ Collections . singletonList ( new StringEntry ( getText (parser , new Paragraph (297 , makeRect (304 , 213 , 245 , 77 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Bite:\\ s*" , "" )) ),
442
442
5 ,
443
443
1 ,
444
444
DamageTypes .AGGRAVATED ,
@@ -453,7 +453,7 @@ private void processMeleeWeapons() {
453
453
454
454
entries .add (new MeleeWeapon (
455
455
"Claw - Crinos, Hispo" ,
456
- getText (parser , new Paragraph (297 , makeRect (304 , 335 , 246 , 52 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Claw:\\ s*" , "" ),
456
+ Collections . singletonList ( new StringEntry ( getText (parser , new Paragraph (297 , makeRect (304 , 335 , 246 , 52 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Claw:\\ s*" , "" )) ),
457
457
6 ,
458
458
2 ,
459
459
DamageTypes .AGGRAVATED ,
@@ -468,7 +468,7 @@ private void processMeleeWeapons() {
468
468
469
469
entries .add (new MeleeWeapon (
470
470
"Claw - Glabro, Lupus" ,
471
- getText (parser , new Paragraph (297 , makeRect (304 , 335 , 246 , 52 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Claw:\\ s*" , "" ),
471
+ Collections . singletonList ( new StringEntry ( getText (parser , new Paragraph (297 , makeRect (304 , 335 , 246 , 52 ))).get (0 ).replaceAll ("^\\ s*•?\\ s*Claw:\\ s*" , "" )) ),
472
472
6 ,
473
473
2 ,
474
474
DamageTypes .BASHING ,
@@ -482,29 +482,152 @@ private void processMeleeWeapons() {
482
482
));
483
483
484
484
log .info ("Extracting Melee weapons" );
485
+ Map <String , String > meleeNotes = new HashMap <>();
486
+
487
+ var notePattern = Pattern .compile ("^\\ s*(\\ *+)\\ s*(.*)$" );
488
+ for (var line : getTextAsLines (parser , BOOK_DETAILS .meleeWeapons ().textLocation ())) {
489
+ var matcher = notePattern .matcher (line );
490
+ if (matcher .matches ()) {
491
+ meleeNotes .put (matcher .group (1 ), matcher .group (2 ));
492
+ }
493
+ }
494
+
485
495
var meleeWeaponPattern = Pattern .compile ("([\\ w\\ s]+)(\\ **)?\\ s*(\\ d+)(\\ **)?\\ s*Strength(\\ s*\\ +\\ s*(\\ d+))?/([BLA])(\\ **)?\\ s*([PJTN])\\ s*" );
486
- for (var line : getTextAsLines (parser , BOOK_DETAILS .weapons ().meleeWeapons ())) {
496
+ for (var line : getTextAsLines (parser , BOOK_DETAILS .meleeWeapons ().textLocation ())) {
487
497
log .trace ("Processing weapon line" );
488
498
var matcher = meleeWeaponPattern .matcher (line );
489
499
if (matcher .matches ()) {
490
500
log .trace ("Weapon matches" );
501
+ var description = new ArrayList <TextEntry >();
502
+ boolean canEntangle = matcher .group (4 ) != null && matcher .group (4 ).trim ().equals ("*" );
503
+ if (canEntangle ) {
504
+ description .add (new StringEntry (fixText (meleeNotes .get ("*" ))));
505
+ }
506
+ boolean breaksAfterUse = matcher .group (8 ) != null && matcher .group (8 ).trim ().equals ("**" );
507
+ if (breaksAfterUse ) {
508
+ description .add (new StringEntry (fixText (meleeNotes .get ("**" ))));
509
+ }
510
+ boolean twoHanded = matcher .group (2 ) != null && matcher .group (2 ).trim ().equals ("***" );
511
+ if (twoHanded ) {
512
+ description .add (new StringEntry (fixText (meleeNotes .get ("***" ))));
513
+ }
514
+ boolean silver = matcher .group (2 ) != null && matcher .group (2 ).trim ().equals ("****" );
515
+ if (silver ) {
516
+ description .add (new StringEntry (fixText (meleeNotes .get ("****" ))));
517
+ }
518
+ boolean selfDamage = matcher .group (8 ) != null && matcher .group (8 ).trim ().equals ("*****" );
519
+ if (selfDamage ) {
520
+ description .add (new StringEntry (fixText (meleeNotes .get ("*****" ))));
521
+ }
491
522
entries .add (new MeleeWeapon (
492
523
matcher .group (1 ).trim (),
493
- "" ,
524
+ description ,
494
525
Integer .parseInt (matcher .group (3 ).trim ()),
495
526
matcher .group (6 ) == null ? 0 : Integer .parseInt (matcher .group (6 ).trim ()),
496
527
DamageTypes .parse (matcher .group (7 ).trim ()),
497
528
WeaponConcealment .parse (matcher .group (9 ).trim ()),
498
- matcher . group ( 4 ) != null && matcher . group ( 4 ). trim (). equals ( "*" ) ,
499
- matcher . group ( 8 ) != null && matcher . group ( 8 ). trim (). equals ( "**" ) ,
500
- matcher . group ( 2 ) != null && matcher . group ( 2 ). trim (). equals ( "***" ) ,
501
- matcher . group ( 2 ) != null && matcher . group ( 2 ). trim (). equals ( "****" ) ,
502
- matcher . group ( 8 ) != null && matcher . group ( 8 ). trim (). equals ( "*****" ) ,
529
+ canEntangle ,
530
+ breaksAfterUse ,
531
+ twoHanded ,
532
+ silver ,
533
+ selfDamage ,
503
534
false
504
535
));
505
536
log .trace ("Weapon processed" );
506
537
} else {
507
- log .warn ("Line {} doesn't match against weapon regex" , line );
538
+ log .debug ("Line {} doesn't match against weapon regex" , line );
539
+ }
540
+ }
541
+
542
+ log .info ("Extracting Throw weapons" );
543
+ var thrownWeaponPattern = Pattern .compile ("([A-Za-z\\ s,-]+)\\ s*(\\ d+)\\ s*(Strength)?(\\ s*\\ +\\ s*)?(\\ d+)?/([BLA])\\ s*([PJTN]|varies)\\ s*" );
544
+ for (var line : getTextAsLines (parser , BOOK_DETAILS .thrownWeapons ().textLocation ())) {
545
+ log .trace ("Processing throw line" );
546
+ var matcher = thrownWeaponPattern .matcher (line );
547
+ if (matcher .matches ()) {
548
+ log .trace ("Weapon matches" );
549
+ entries .add (new ThrownWeapon (
550
+ matcher .group (1 ).trim (),
551
+ Collections .emptyList (),
552
+ Integer .parseInt (matcher .group (2 ).trim ()),
553
+ matcher .group (3 ) != null ,
554
+ matcher .group (5 ) == null ? 0 : Integer .parseInt (matcher .group (5 ).trim ()),
555
+ DamageTypes .parse (matcher .group (6 ).trim ()),
556
+ WeaponConcealment .parse (matcher .group (7 ).trim ())
557
+ ));
558
+ log .trace ("Weapon processed" );
559
+ } else {
560
+ log .debug ("Line {} doesn't match against thrown weapon regex" , line );
561
+ }
562
+ }
563
+
564
+ log .info ("Extracting ranged weapons" );
565
+ Map <String , String > rangedNotes = new HashMap <>();
566
+
567
+ var prevLineMatched = false ;
568
+ var prevKey = "" ;
569
+ for (var line : getTextAsLines (parser , BOOK_DETAILS .rangedWeapons ().textLocation ())) {
570
+ var matcher = notePattern .matcher (line );
571
+ if (matcher .matches ()) {
572
+ prevKey = matcher .group (1 ).trim ();
573
+ rangedNotes .put (prevKey , matcher .group (2 ).trim ());
574
+ prevLineMatched = true ;
575
+ } else if (prevLineMatched ) {
576
+ rangedNotes .put (prevKey , rangedNotes .get (prevKey ).trim () + " " + line .trim ());
577
+ prevLineMatched = false ;
578
+ prevKey = null ;
579
+ }
580
+ }
581
+
582
+ var rangedWeaponPattern = Pattern .compile ("(?<name>[A-Za-z\\ s.,-]+)(?<namestars>\\ **)?\\ s*(?<damage>\\ d+)\\ s*(?<range>\\ d+)\\ s*(?<rate>\\ d+|\\ *)\\ s*(?<clip>\\ d+)(\\ +\\ s*(?<clipbonus>\\ d))?\\ s*(?<conceal>[PJTN])(?<concealstars>\\ **)\\ s*" );
583
+ for (var line : getTextAsLines (parser , BOOK_DETAILS .rangedWeapons ().textLocation ())) {
584
+ log .trace ("Processing weapon line" );
585
+ var matcher = rangedWeaponPattern .matcher (line );
586
+ if (matcher .matches ()) {
587
+ log .trace ("Weapon matches" );
588
+ var description = new ArrayList <TextEntry >();
589
+ var nameStars = matcher .group ("namestars" );
590
+ var bursty = false ;
591
+ var damageType = DamageTypes .LETHAL ;
592
+ if ("*" .equals (nameStars )) {
593
+ bursty = true ;
594
+ description .add (new StringEntry (fixText (rangedNotes .get (nameStars ).trim ())));
595
+ }
596
+ if ("**" .equals (nameStars ) || line .contains ("Bow" ) || line .contains ("bow" )) {
597
+ description .add (new StringEntry (fixText (rangedNotes .get ("**" ).trim ())));
598
+ }
599
+ if ("****" .equals (nameStars )) {
600
+ damageType = DamageTypes .BASHING ;
601
+ description .add (new StringEntry (fixText (rangedNotes .get (nameStars ).trim ())));
602
+ }
603
+
604
+ var concealStars = matcher .group ("concealstars" );
605
+ if ("***" .equals (concealStars )) {
606
+ description .add (new StringEntry (fixText (rangedNotes .get (concealStars ).trim ())));
607
+ }
608
+
609
+ Integer rate = matcher .group ("rate" ).equals ("*" ) ? null : Integer .parseInt (matcher .group ("rate" ));
610
+ int clip = Integer .parseInt (matcher .group ("clip" ));
611
+ if (matcher .group ("clipbonus" ) != null ) {
612
+ clip += Integer .parseInt (matcher .group ("clipbonus" ));
613
+ }
614
+ entries .add (new RangedWeapon (
615
+ matcher .group ("name" ).trim (),
616
+ description ,
617
+ Integer .parseInt (matcher .group ("damage" ).trim ()),
618
+ damageType ,
619
+ WeaponConcealment .parse (matcher .group ("conceal" ).trim ()),
620
+ Integer .parseInt (matcher .group ("range" )),
621
+ rate ,
622
+ clip ,
623
+ false ,
624
+ bursty ,
625
+ bursty ,
626
+ bursty
627
+ ));
628
+ log .trace ("Weapon processed" );
629
+ } else {
630
+ log .debug ("Line {} doesn't match against weapon regex" , line );
508
631
}
509
632
}
510
633
}
0 commit comments