@@ -96,7 +96,7 @@ private static Dictionary<string, string> BuildEffectLookup()
9696 return dict ;
9797 }
9898
99- private static string newId ( int length = 16 ) {
99+ public static string newId ( int length = 16 ) {
100100 StringBuilder builder = new StringBuilder ( ) ;
101101 Random rnd = new Random ( ) ;
102102 for ( int i = 0 ; i < length ; i ++ )
@@ -252,7 +252,58 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
252252 resultPower . data . attack . isAttack = true ;
253253 resultPower . data . hit . isDamage = true ;
254254
255- // check to see if it was an elemental damage type, if not we fall back tp physcal
255+ ProcessAttackDamageAndRange ( resultPower , errors , power . Details , power . Damage , power . Attack . Defence ,
256+ power . Attack . Bonus , power . Range ) ;
257+
258+ powerData . level = powerData . basicAttack ? "B" : "" ;
259+
260+ if ( powerData . isMelee )
261+ {
262+ resultPower . img = powerData . basicAttack
263+ ? "modules/foundry-4e-tools/icons/melee-basic.svg"
264+ : "modules/foundry-4e-tools/icons/melee.svg" ;
265+ }
266+ else
267+ {
268+ switch ( powerData . rangeType )
269+ {
270+ case "melee" : // in theory should not hit this, but just in case
271+ case "reach" : resultPower . img = powerData . basicAttack
272+ ? "modules/foundry-4e-tools/icons/melee-basic.svg"
273+ : "modules/foundry-4e-tools/icons/melee.svg" ;
274+ break ;
275+ case "range" :
276+ resultPower . img = powerData . basicAttack
277+ ? "modules/foundry-4e-tools/icons/ranged-basic.svg"
278+ : "modules/foundry-4e-tools/icons/ranged.svg" ;
279+ break ;
280+ case "closeBurst" :
281+ case "closeBlast" :
282+ resultPower . img = "modules/foundry-4e-tools/icons/close-blast.svg" ;
283+ break ;
284+ case "rangeBurst" :
285+ case "rangeBlast" :
286+ case "wall" :
287+ resultPower . img = "modules/foundry-4e-tools/icons/area-burst.svg" ;
288+ break ;
289+ default :
290+ break ;
291+ }
292+ }
293+
294+ return resultPower ;
295+ }
296+
297+
298+ public static void ProcessAttackDamageAndRange ( FoundryPower foundryPower , List < string > errors ,
299+ string sourcePowerDetails ,
300+ string sourcePowerDamage ,
301+ DefenceType defenceType ,
302+ int attackBonus ,
303+ string range )
304+ {
305+ var powerData = foundryPower . data ;
306+ // check to see if it was an elemental damage type, if not we fall back tp physcal
256307 var shouldAddPhysicalDamage = true ;
257308 var keywordsHashSet = new HashSet < string > ( powerData . keywords . Select ( x => x . ToLowerInvariant ( ) ) ) ;
258309 if ( keywordsHashSet . Intersect ( ElementalDamageTypeSet ) . Any ( ) )
@@ -263,7 +314,7 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
263314 // parse the power text just in case they didn't add the damage type to the keywords
264315 // single type
265316 {
266- var damageTypeInPowerData = DamageTypeRegex1 . Match ( power . Details ) ;
317+ var damageTypeInPowerData = DamageTypeRegex1 . Match ( sourcePowerDetails ) ;
267318 if ( damageTypeInPowerData . Success )
268319 {
269320 var damageType = damageTypeInPowerData . Groups [ 1 ] . Value . ToLowerInvariant ( ) ;
@@ -273,7 +324,7 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
273324 }
274325 //multiple types
275326 {
276- var damageTypeInPowerData = DamageTypeRegex2 . Match ( power . Details ) ;
327+ var damageTypeInPowerData = DamageTypeRegex2 . Match ( sourcePowerDetails ) ;
277328 if ( damageTypeInPowerData . Success )
278329 {
279330 var damageType1 = damageTypeInPowerData . Groups [ 1 ] . Value . ToLowerInvariant ( ) ;
@@ -290,9 +341,9 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
290341 powerData . damageType [ "physical" ] = true ;
291342 }
292343
293- ProcessRangeAndWeapon ( power , powerData , errors ) ;
344+ ProcessRangeAndWeapon ( range , powerData , foundryPower . name , errors ) ;
294345 var def = "AC" ;
295- switch ( power . Attack . Defence )
346+ switch ( defenceType )
296347 {
297348 case DefenceType . Fortitude :
298349 def = "Fort" ;
@@ -307,20 +358,20 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
307358 }
308359
309360 powerData . attack . def = def . ToLowerInvariant ( ) ;
310- powerData . attack . formula = power . Attack . Bonus . ToString ( ) ;
311- powerData . description . chat += $ "{ power . Range } , { power . Attack . Bonus } vs { def } ";
361+ powerData . attack . formula = attackBonus . ToString ( ) ;
362+ powerData . description . chat += $ "{ range } , { attackBonus } vs { def } ";
312363
313364 // reminder that details is the entire block and that Damage is Masterplans attempt to parse it out
314- powerData . hit . detail = power . Details ;
315- var damage = CommonHelpers . parseDamageString ( power . Damage , errors , power . Name ) ;
365+ powerData . hit . detail = sourcePowerDetails ;
366+ var damage = CommonHelpers . parseDamageString ( sourcePowerDamage , errors , foundryPower . name ) ;
316367 powerData . hit . formula = damage . NumDice > 0
317368 ? damage . NumDice + "d" + damage . DiceSize + "+" + damage . Bonus
318369 : damage . Bonus . ToString ( ) ;
319370 powerData . hit . critFormula = damage . NumDice + "*" + damage . DiceSize + "+" + damage . Bonus ;
320371
321372 // attempt to get miss, effect and special out of the details.
322373 {
323- var match = MissRgx . Match ( power . Details ) ;
374+ var match = MissRgx . Match ( sourcePowerDetails ) ;
324375 if ( match . Success )
325376 {
326377 powerData . miss . detail = match . Groups [ 1 ] . Value ;
@@ -330,59 +381,22 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
330381 {
331382 // effect detail was set by trait call
332383 powerData . effect . detail = null ;
333- var match = EffectRgx . Match ( power . Details ) ;
384+ var match = EffectRgx . Match ( sourcePowerDetails ) ;
334385 if ( match . Success )
335386 {
336387 powerData . effect . detail = match . Groups [ 1 ] . Value ;
337388 powerData . hit . detail = powerData . hit . detail . Replace ( match . Value , "" ) ;
338389 }
339390 }
340391 {
341- var match = SpecialRgx . Match ( power . Details ) ;
392+ var match = SpecialRgx . Match ( sourcePowerDetails ) ;
342393 if ( match . Success )
343394 {
344395 powerData . special = match . Groups [ 1 ] . Value ;
345396 powerData . hit . detail = powerData . hit . detail . Replace ( match . Value , "" ) ;
346397 }
347398 }
348399 powerData . hit . detail = powerData . hit . detail . Replace ( "\r \n " , "" ) ;
349- powerData . level = powerData . basicAttack ? "B" : "" ;
350-
351- if ( powerData . isMelee )
352- {
353- resultPower . img = powerData . basicAttack
354- ? "modules/foundry-4e-tools/icons/melee-basic.svg"
355- : "modules/foundry-4e-tools/icons/melee.svg" ;
356- }
357- else
358- {
359- switch ( powerData . rangeType )
360- {
361- case "melee" : // in theory should not hit this, but just in case
362- case "reach" : resultPower . img = powerData . basicAttack
363- ? "modules/foundry-4e-tools/icons/melee-basic.svg"
364- : "modules/foundry-4e-tools/icons/melee.svg" ;
365- break ;
366- case "range" :
367- resultPower . img = powerData . basicAttack
368- ? "modules/foundry-4e-tools/icons/ranged-basic.svg"
369- : "modules/foundry-4e-tools/icons/ranged.svg" ;
370- break ;
371- case "closeBurst" :
372- case "closeBlast" :
373- resultPower . img = "modules/foundry-4e-tools/icons/close-blast.svg" ;
374- break ;
375- case "rangeBurst" :
376- case "rangeBlast" :
377- case "wall" :
378- resultPower . img = "modules/foundry-4e-tools/icons/area-burst.svg" ;
379- break ;
380- default :
381- break ;
382- }
383- }
384-
385- return resultPower ;
386400 }
387401
388402 private static readonly Regex AreaBurstRgx =
@@ -410,9 +424,8 @@ public static FoundryPower ProcessAttack(CreaturePower power, List<string> error
410424 private static readonly Regex Wall2Rgx =
411425 new Regex ( @"wall ([1-9][0-9]*)" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
412426
413- private static void ProcessRangeAndWeapon ( CreaturePower power , FoundryPowerData data , List < string > errors )
427+ private static void ProcessRangeAndWeapon ( string range , FoundryPowerData data , string powerName , List < string > errors )
414428 {
415- var range = power . Range ;
416429 var weapon = data . keywords . Contains ( "weapon" ) || data . keywords . Contains ( "Weapon" ) ;
417430 var implement = data . keywords . Contains ( "implement" ) || data . keywords . Contains ( "Implement" ) ;
418431 if ( implement )
@@ -545,19 +558,16 @@ private static void ProcessRangeAndWeapon(CreaturePower power, FoundryPowerData
545558 // try to work around unset ranges
546559 else if ( string . IsNullOrEmpty ( range ) )
547560 {
548- if ( ( power . Action . Use == PowerUseType . Basic ) || ( power . Attack != null ) )
549- {
550- data . rangeType = "melee" ;
551- data . rangePower = 1 ;
552- data . isMelee = true ;
553- errors . Add ( $ "Attack { power . Name } did not have range set, assuming melee") ;
554- }
561+ data . rangeType = "melee" ;
562+ data . rangePower = 1 ;
563+ data . isMelee = true ;
564+ errors . Add ( $ "Attack { powerName } did not have range set, assuming melee") ;
555565 }
556566 }
557567 }
558568 catch ( Exception e )
559569 {
560- errors . Add ( $ "Failed to Parse Range: '{ range } ' for power { power . Name } :" + e . Message ) ;
570+ errors . Add ( $ "Failed to Parse Range: '{ range } ' for power { powerName } :" + e . Message ) ;
561571 }
562572 }
563573 }
0 commit comments