Skip to content

Commit ad0b65e

Browse files
committed
Fix broken horse traits, fix color name support
Missing new horse traits have been added added wrapper getColourName(trait) changed some wrappers to CallbackApi
1 parent 8e2d808 commit ad0b65e

File tree

1 file changed

+102
-27
lines changed
  • modules/modlauncher/src/main/java/org/gotti/wurmunlimited/modsupport/creatures

1 file changed

+102
-27
lines changed

modules/modlauncher/src/main/java/org/gotti/wurmunlimited/modsupport/creatures/ModCreatures.java

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Optional;
1010

1111
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
12+
import org.gotti.wurmunlimited.modloader.callbacks.CallbackApi;
1213
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
1314
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
1415
import org.gotti.wurmunlimited.modloader.classhooks.InvocationHandlerFactory;
@@ -18,6 +19,7 @@
1819
import com.wurmonline.server.creatures.Creature;
1920
import com.wurmonline.server.creatures.CreatureTemplate;
2021
import com.wurmonline.server.creatures.Traits;
22+
import com.wurmonline.shared.util.StringUtilities;
2123

2224
import javassist.CannotCompileException;
2325
import javassist.ClassPool;
@@ -66,11 +68,11 @@ public String getTraitName() {
6668
return name();
6769
}
6870
}
69-
71+
7072
private static List<ModCreature> creatures = new LinkedList<>();
7173
private static Map<Integer, ModCreature> creaturesById = new HashMap<>();
7274
private static boolean inited;
73-
75+
7476
public static void init() {
7577
if (inited)
7678
return;
@@ -159,21 +161,19 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
159161
});
160162

161163
try {
164+
/**
165+
* Replace call for Traits.getTraitString() with a call to GmSetTraitsCallbacks.getTraitString()
166+
* where custom colors and custom traits are checked checked first before falling back to Traits.getTraitString()
167+
*/
168+
CtClass ctGmSetTraits = classPool.get("com.wurmonline.server.questions.GmSetTraits");
169+
HookManager.getInstance().addCallback(ctGmSetTraits, "modcreatures", new GmSetTraitsCallbacks());
170+
162171
// com.wurmonline.server.questions.GmSetTraits.sendQuestion()
163-
classPool.get("com.wurmonline.server.questions.GmSetTraits").getMethod("sendQuestion", "()V").instrument(new ExprEditor() {
172+
ctGmSetTraits.getMethod("sendQuestion", "()V").instrument(new ExprEditor() {
164173
@Override
165174
public void edit(MethodCall m) throws CannotCompileException {
166175
if (m.getClassName().equals("com.wurmonline.server.creatures.Traits") && m.getMethodName().equals("getTraitString")) {
167-
StringBuffer buffer = new StringBuffer();
168-
buffer.append("{\n");
169-
buffer.append("String name = null;\n");
170-
buffer.append("org.gotti.wurmunlimited.modsupport.creatures.ModCreature c = org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.getModCreature(creature.getTemplate().getTemplateId());\n");
171-
for (CustomTrait customTrait : CustomTrait.values()) {
172-
buffer.append("if (c != null && $1 == " + customTrait.getTraitNumber() + ") { name = c.getTraitName(" + customTrait.getTraitNumber() + "); $_ = name != null ? name : \"\"; } else \n");
173-
}
174-
buffer.append("$_ = $proceed($$);\n");
175-
buffer.append("}");
176-
m.replace(buffer.toString());
176+
m.replace("$_ = modcreatures.getTraitString(creature, $1);");
177177
}
178178
}
179179
});
@@ -184,24 +184,32 @@ public void edit(MethodCall m) throws CannotCompileException {
184184

185185
try {
186186
final CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
187+
HookManager.getInstance().addCallback(ctCreature, "modcreatures", new CreatureCallbacks());
187188

188189
{
189190
// com.wurmonline.server.creatures.Creature.getModelName()
190-
String code = "{ String name = org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.getModelName($0); if (name != null) { return name; }; }";
191+
String code = "{ String name = modcreatures.getModelName($0); if (name != null) { return name; }; }";
191192
ctCreature.getMethod("getModelName", Descriptor.ofMethod(classPool.get("java.lang.String"), new CtClass[0])).insertBefore(code);
192193
}
193194

194195
{
195196
// com.wurmonline.server.creatures.Creature.getColourName()
196-
String code = "{ String colour = org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.getColourName($0); if (colour != null) { return colour; }; }";
197+
String code = "{ String colour = modcreatures.getColourName($0); if (colour != null) { return colour; }; }";
197198
ctCreature.getMethod("getColourName", Descriptor.ofMethod(classPool.get("java.lang.String"), new CtClass[0])).insertBefore(code);
198199
}
199200

201+
{
202+
// com.wurmonline.server.creatures.Creature.getColourName(int trait)
203+
String code = "{ String colour = modcreatures.getColourName($0, $1); if (colour != null) { return colour; }; }";
204+
ctCreature.getMethod("getColourName", Descriptor.ofMethod(classPool.get("java.lang.String"), new CtClass[] { classPool.get("int") })).insertBefore(code);
205+
}
206+
207+
200208
ctCreature.getMethod("die", "(ZLjava/lang/String;)V").instrument(new ExprEditor() {
201209
@Override
202210
public void edit(FieldAccess f) throws CannotCompileException {
203211
if (f.getClassName().equals("com.wurmonline.server.creatures.CreatureTemplate") && f.getFieldName().equals("isHorse")) {
204-
f.replace("{ String name = org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.getTraitName(this); if (name != null) { corpse.setDescription(name); $_ = false; } else { $_ = $proceed($$); } }");
212+
f.replace("{ String name = modcreatures.getTraitName(this); if (name != null) { corpse.setDescription(name); $_ = false; } else { $_ = $proceed($$); } }");
205213
}
206214
}
207215

@@ -211,7 +219,7 @@ public void edit(FieldAccess f) throws CannotCompileException {
211219
@Override
212220
public void edit(MethodCall m) throws CannotCompileException {
213221
if (m.getClassName().equals("com.wurmonline.server.creatures.Traits") && m.getMethodName().equals("calcNewTraits") && m.getSignature().equals("(DZJJ)J")) {
214-
m.replace("$_ = org.gotti.wurmunlimited.modsupport.creatures.ModCreatures#calcNewTraits($1, $2, this, father);");
222+
m.replace("$_ = modcreatures.calcNewTraits($1, $2, this, father);");
215223
}
216224
}
217225
});
@@ -224,15 +232,7 @@ public void edit(MethodCall m) throws CannotCompileException {
224232
public void edit(MethodCall m) throws CannotCompileException {
225233
if (m.getClassName().equals("com.wurmonline.server.creatures.Creature") && m.getMethodName().equals("isHorse")) {
226234
StringBuffer code = new StringBuffer();
227-
228-
code.append("{");
229-
code.append("if (org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.hasTraits($0.getTemplate().getTemplateId())) { ");
230-
code.append("org.gotti.wurmunlimited.modsupport.creatures.ModCreatures.assignTraits($0);");
231-
code.append("$_ = false;");
232-
code.append("} else {");
233-
code.append("$_ = $proceed($$);");
234-
code.append("}");
235-
code.append("}");
235+
code.append("$_ = !modcreatures.assignTraits($0) && $proceed($$);");
236236
m.replace(code.toString());
237237
}
238238
}
@@ -248,7 +248,7 @@ public void edit(MethodCall m) throws CannotCompileException {
248248

249249
inited = true;
250250
}
251-
251+
252252
public static void addCreature(ModCreature creature) {
253253
if (!inited) {
254254
throw new RuntimeException("ModCreatures was not initied");
@@ -346,4 +346,79 @@ public static long calcNewTraits(final double breederSkill, final boolean inbred
346346

347347
return modMother.calcNewTraits(breederSkill, inbred, mothertraits, fathertraits);
348348
}
349+
350+
private static class GmSetTraitsCallbacks {
351+
@CallbackApi
352+
public String getTraitString(Creature creature, int trait) {
353+
ModCreature modCreature = ModCreatures.getModCreature(creature.getTemplate().getTemplateId());
354+
if (modCreature != null && isCustomTrait(trait)) {
355+
String colorName = modCreature.getColourName(trait);
356+
if (colorName != null)
357+
return StringUtilities.raiseFirstLetterOnly(colorName);
358+
359+
String traitName = modCreature.getTraitName(trait);
360+
if (traitName != null)
361+
return traitName;
362+
}
363+
364+
return Traits.getTraitString(trait);
365+
}
366+
}
367+
368+
private static class CreatureCallbacks {
369+
370+
@CallbackApi
371+
public String getModelName(Creature creature) {
372+
return ModCreatures.getModelName(creature);
373+
}
374+
375+
@CallbackApi
376+
public String getColourName(Creature creature) {
377+
return ModCreatures.getColourName(creature);
378+
}
379+
380+
@CallbackApi
381+
public String getColourName(Creature creature, int trait) {
382+
ModCreature c = ModCreatures.getModCreature(creature.getTemplate().getTemplateId());
383+
if (c != null && c.hasTraits()) {
384+
// The creature has traits. Return the color name or an empty string
385+
String color = c.getColourName(trait);
386+
if (color != null) {
387+
return color;
388+
}
389+
return "";
390+
}
391+
return null;
392+
}
393+
394+
395+
@CallbackApi
396+
public String getTraitName() {
397+
return ModCreatures.getTraitName(null);
398+
}
399+
400+
@CallbackApi
401+
public boolean hasTraits(int templateId) {
402+
return ModCreatures.hasTraits(templateId);
403+
}
404+
405+
@CallbackApi
406+
public long calcNewTraits(final double breederSkill, final boolean inbred, final Creature mother, final Creature father) {
407+
return ModCreatures.calcNewTraits(breederSkill, inbred, mother, father);
408+
}
409+
410+
/**
411+
* Assign traits if the creature has custom traits.
412+
* @return true if the creature has custom traits, false otherwise
413+
*/
414+
@CallbackApi
415+
public boolean assignTraits(Creature creature) {
416+
if (ModCreatures.hasTraits(creature.getTemplate().getTemplateId())) {
417+
ModCreatures.assignTraits(creature);
418+
return true;
419+
}
420+
return false;
421+
}
422+
423+
}
349424
}

0 commit comments

Comments
 (0)