11package org .gotti .wurmunlimited .modsupport ;
22
33import java .io .IOException ;
4+ import java .lang .reflect .Field ;
45import java .lang .reflect .InvocationTargetException ;
6+ import java .lang .reflect .Method ;
57import java .util .HashMap ;
68import java .util .LinkedList ;
79import java .util .List ;
1012
1113import com .wurmonline .server .combat .ArmourTemplate ;
1214import org .gotti .wurmunlimited .modloader .ReflectionUtil ;
15+ import org .gotti .wurmunlimited .modloader .classhooks .HookException ;
1316
1417import com .wurmonline .server .creatures .AttackAction ;
1518import com .wurmonline .server .creatures .CreatureTemplate ;
1922import com .wurmonline .shared .constants .ItemMaterials ;
2023
2124public class CreatureTemplateBuilder {
22-
25+
26+ private static class RefHelper {
27+
28+ private final Field reputation ;
29+ private final Field hasHands ;
30+ private final Field isHorse ;
31+ private final Method createCreatureTemplate ;
32+ private final Method setAlignment ;
33+ private final Method setDenMaterial ;
34+ private final Method setDenName ;
35+ private final Method setMaxGroupAttackSize ;
36+ private final Method setBaseCombatRating ;
37+ private final Method setArmourType ;
38+ private final Method setMaxAge ;
39+ private final Method setKickDamString ;
40+
41+ public RefHelper () {
42+ try {
43+ reputation = ReflectionUtil .getField (CreatureTemplate .class , "reputation" );
44+ hasHands = ReflectionUtil .getField (CreatureTemplate .class , "hasHands" );
45+ isHorse = ReflectionUtil .getField (CreatureTemplate .class , "isHorse" );
46+ createCreatureTemplate = ReflectionUtil .getMethod (CreatureTemplateFactory .class , "createCreatureTemplate" );
47+ setAlignment = ReflectionUtil .getMethod (CreatureTemplate .class , "setAlignment" );
48+ setDenMaterial = ReflectionUtil .getMethod (CreatureTemplate .class , "setDenMaterial" );
49+ setDenName = ReflectionUtil .getMethod (CreatureTemplate .class , "setDenName" );
50+ setMaxGroupAttackSize = ReflectionUtil .getMethod (CreatureTemplate .class , "setMaxGroupAttackSize" );
51+ setBaseCombatRating = ReflectionUtil .getMethod (CreatureTemplate .class , "setBaseCombatRating" );
52+ setArmourType = ReflectionUtil .getMethod (CreatureTemplate .class , "setArmourType" );
53+ setMaxAge = ReflectionUtil .getMethod (CreatureTemplate .class , "setMaxAge" );
54+ setKickDamString = ReflectionUtil .getMethod (CreatureTemplate .class , "setKickDamString" );
55+ } catch (NoSuchFieldException | NoSuchMethodException e ) {
56+ throw new HookException (e );
57+ }
58+ }
59+ }
60+
61+ private static final RefHelper REFHELPER = new RefHelper ();
62+
2363 private int templateId ;
2464
2565 private Map <Integer , Float > skills = new HashMap <>();
@@ -142,6 +182,10 @@ public class CreatureTemplateBuilder {
142182
143183 private int eggTemplate ;
144184
185+ private int childTemplate ;
186+
187+ private byte daysOfPregnancy ;
188+
145189 private boolean hasHands ;
146190
147191 private boolean keepSex ;
@@ -202,6 +246,10 @@ public class CreatureTemplateBuilder {
202246
203247 private int leaderTemplateId = -1 ;
204248
249+ private float offZ ;
250+
251+ private int reputation = 100 ;
252+
205253 public CreatureTemplateBuilder (int id ) {
206254 this .templateId = id ;
207255 defaultSkills ();
@@ -388,6 +436,27 @@ public CreatureTemplateBuilder eggLayer(int eggTemplate) {
388436 this .eggTemplate = eggTemplate ;
389437 return this ;
390438 }
439+
440+ /**
441+ * Set days of pregnancy
442+ * @param daysOfPregnancy days of pregnancy
443+ * @return this
444+ */
445+ public CreatureTemplateBuilder daysOfPregnancy (byte daysOfPregnancy ) {
446+ this .daysOfPregnancy = daysOfPregnancy ;
447+ return this ;
448+ }
449+
450+ /**
451+ * Set child template id
452+ *
453+ * @param childTemplate child template id
454+ * @return this
455+ */
456+ public CreatureTemplateBuilder childTemplate (int childTemplate ) {
457+ this .childTemplate = childTemplate ;
458+ return this ;
459+ }
391460
392461 public CreatureTemplate build () {
393462 try {
@@ -406,41 +475,41 @@ public CreatureTemplate build() {
406475 temp .setHandDamString (handDamString );
407476
408477 if (this .kickDamString != null )
409- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setKickDamString" ) , kickDamString );
478+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setKickDamString , kickDamString );
410479
411480 if (this .headbuttDamString != null ) {
412481 temp .setHeadbuttDamString (headbuttDamString );
413482 }
414483
415484 if (maxAge > 0 )
416- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setMaxAge" ) , maxAge );
485+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setMaxAge , maxAge );
417486
418487 if (armourType != null )
419- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setArmourType" ) , armourType );
488+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setArmourType , armourType );
420489
421490 if (baseCombatRating > 0 )
422- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setBaseCombatRating" ) , baseCombatRating );
491+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setBaseCombatRating , baseCombatRating );
423492
424493 if (combatDamageType > 0 )
425494 temp .combatDamageType = combatDamageType ;
426495
427496 if (maxGroupAttackSize > 0 )
428- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setMaxGroupAttackSize" ) , maxGroupAttackSize );
497+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setMaxGroupAttackSize , maxGroupAttackSize );
429498
430499 if (denName != null )
431- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setDenName" ) , denName );
500+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setDenName , denName );
432501
433502 if (denMaterial > 0 )
434- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setDenMaterial" ) , denMaterial );
503+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setDenMaterial , denMaterial );
435504
436505 if (maxPercentOfCreatures > 0 )
437506 temp .setMaxPercentOfCreatures (maxPercentOfCreatures );
438507
439508 if (alignment != 0 )
440- ReflectionUtil .callPrivateMethod (temp , ReflectionUtil . getMethod ( CreatureTemplate . class , " setAlignment" ) , alignment );
509+ ReflectionUtil .callPrivateMethod (temp , REFHELPER . setAlignment , alignment );
441510
442511 if (isHorse )
443- ReflectionUtil .setPrivateField (temp , ReflectionUtil . getField ( CreatureTemplate . class , " isHorse" ) , isHorse );
512+ ReflectionUtil .setPrivateField (temp , REFHELPER . isHorse , isHorse );
444513
445514 if (usesNewAttacks )
446515 temp .setUsesNewAttacks (usesNewAttacks );
@@ -459,6 +528,8 @@ public CreatureTemplate build() {
459528 temp .setSizeModX (sizeModX );
460529 temp .setSizeModY (sizeModY );
461530 temp .setSizeModZ (sizeModZ );
531+
532+ temp .offZ = offZ ;
462533
463534 temp .setGlowing (glowing );
464535 if (onFire ) {
@@ -473,9 +544,17 @@ public CreatureTemplate build() {
473544 temp .setEggLayer (this .isEggLayer );
474545 temp .setEggTemplateId (this .eggTemplate );
475546 }
547+
548+ if (childTemplate != 0 ) {
549+ temp .setChildTemplateId (childTemplate );
550+ }
551+
552+ if (daysOfPregnancy != 0 ) {
553+ temp .setDaysOfPregnancy (daysOfPregnancy );
554+ }
476555
477556 if (hasHands ) {
478- ReflectionUtil .setPrivateField (temp , ReflectionUtil . getField ( CreatureTemplate . class , " hasHands" ) , hasHands );
557+ ReflectionUtil .setPrivateField (temp , REFHELPER . hasHands , hasHands );
479558 }
480559
481560 temp .setKeepSex (keepSex );
@@ -515,18 +594,24 @@ public CreatureTemplate build() {
515594 temp .internalVulnerability = internalVulnerability ;
516595
517596 temp .setLeaderTemplateId (leaderTemplateId );
597+
598+ if (this .reputation != 100 ) {
599+ ReflectionUtil .setPrivateField (temp , REFHELPER .reputation , reputation );
600+ }
601+
602+
518603
519604 return temp ;
520- } catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | ClassCastException | NoSuchFieldException e ) {
521- throw new RuntimeException (e );
605+ } catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassCastException e ) {
606+ throw new HookException (e );
522607 }
523608 }
524609
525610 private static CreatureTemplate createCreatureTemplate (final int id , final String name , final String plural , final String longDesc , final String modelName , final int [] types , final byte bodyType , final Skills skills , final short vision , final byte sex , final short centimetersHigh , final short centimetersLong ,
526611 final short centimetersWide , final String deathSndMale , final String deathSndFemale , final String hitSndMale , final String hitSndFemale , final float naturalArmour , final float handDam , final float kickDam , final float biteDam , final float headDam , final float breathDam ,
527- final float speed , final int moveRate , final int [] itemsButchered , final int maxHuntDist , final int aggress , final byte meatMaterial ) throws IOException , IllegalAccessException , IllegalArgumentException , InvocationTargetException , NoSuchMethodException {
612+ final float speed , final int moveRate , final int [] itemsButchered , final int maxHuntDist , final int aggress , final byte meatMaterial ) throws IOException , IllegalAccessException , IllegalArgumentException , InvocationTargetException {
528613
529- return ReflectionUtil .callPrivateMethod (CreatureTemplateFactory .getInstance (), ReflectionUtil . getMethod ( CreatureTemplateFactory . class , " createCreatureTemplate" ) , id , name , plural , longDesc , modelName , types , bodyType , skills , vision , sex , centimetersHigh , centimetersLong , centimetersWide ,
614+ return ReflectionUtil .callPrivateMethod (CreatureTemplateFactory .getInstance (), REFHELPER . createCreatureTemplate , id , name , plural , longDesc , modelName , types , bodyType , skills , vision , sex , centimetersHigh , centimetersLong , centimetersWide ,
530615 deathSndMale , deathSndFemale , hitSndMale , hitSndFemale , naturalArmour , handDam , kickDam , biteDam , headDam , breathDam , speed , moveRate , itemsButchered , maxHuntDist , aggress , meatMaterial );
531616 }
532617
@@ -658,6 +743,18 @@ public CreatureTemplateBuilder sizeModifier(int sizeModX, int sizeModY, int size
658743 this .sizeModZ = sizeModZ ;
659744 return this ;
660745 }
746+
747+ /**
748+ * Set z-offset.
749+ * The default is 0.0
750+ *
751+ * @param offZ z-offset
752+ * @return this
753+ */
754+ public CreatureTemplateBuilder offZ (float offZ ) {
755+ this .offZ = offZ ;
756+ return this ;
757+ }
661758
662759 /**
663760 * Set a custom color.
@@ -854,4 +951,9 @@ public CreatureTemplateBuilder leaderTemplateId(int leaderTemplateId) {
854951 this .leaderTemplateId = leaderTemplateId ;
855952 return this ;
856953 }
954+
955+ public CreatureTemplateBuilder reputation (int reputation ) {
956+ this .reputation = reputation ;
957+ return this ;
958+ }
857959}
0 commit comments