diff --git a/build.gradle b/build.gradle index 69bcea3..e9af182 100644 --- a/build.gradle +++ b/build.gradle @@ -1,33 +1,22 @@ -plugins { - id 'java' -} - apply plugin: 'java' group "mod.sin" -version "1.1" +version "2.0" repositories { mavenCentral() maven { url "http://jcenter.bintray.com" } maven { url "http://gotti.no-ip.org/maven/repository" } - //maven { url "https://dl.bdew.net/agorepo/" } maven { url 'https://jitpack.io' } - - flatDir { - dirs 'libs' - } } dependencies { - compile 'com.github.Sindusk:sindusklibrary:v1.7' + compile 'org.gotti.wurmunlimited:server-modlauncher:0.43' + compile 'com.github.Sindusk:sindusklibrary:v2.3' + compile 'com.github.bdew-wurm:bdew_server_mod_tools:v1.0.0' compile 'com.github.Sindusk:DiscordRelay:v1.2' compile 'com.github.Sindusk:DUSKombat:v1.0' compile 'com.github.Sindusk:TreasureHunting:1.1.4' - compile 'org.gotti.wurmunlimited:server-modlauncher:0.40' - compile 'org.gotti.wurmunlimited:server:3127452' - compile name: 'kingdomoffices' - //compile name: 'server' } jar { @@ -45,25 +34,3 @@ task dist(type: Zip) { archiveName "${project.name}-${project.version}.zip" } -version '1.0-SNAPSHOT' - -sourceCompatibility = 1.8 - -repositories { - mavenCentral() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' -} -version '1.0-SNAPSHOT' - -sourceCompatibility = 1.8 - -repositories { - mavenCentral() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' -} diff --git a/src/main/java/com/wurmonline/server/questions/SorceryTitleQuestion.java b/src/main/java/com/wurmonline/server/questions/SorceryTitleQuestion.java new file mode 100644 index 0000000..121cc69 --- /dev/null +++ b/src/main/java/com/wurmonline/server/questions/SorceryTitleQuestion.java @@ -0,0 +1,256 @@ +package com.wurmonline.server.questions; + +import com.wurmonline.server.Items; +import com.wurmonline.server.NoSuchPlayerException; +import com.wurmonline.server.Players; +import com.wurmonline.server.Server; +import com.wurmonline.server.creatures.Creature; +import com.wurmonline.server.creatures.Creatures; +import com.wurmonline.server.creatures.NoSuchCreatureException; +import com.wurmonline.server.items.Item; +import com.wurmonline.server.items.ItemTemplateFactory; +import com.wurmonline.server.items.NoSuchTemplateException; +import com.wurmonline.server.players.Abilities; +import com.wurmonline.server.players.Achievement; +import com.wurmonline.server.players.Achievements; +import com.wurmonline.server.players.Player; +import com.wurmonline.server.skills.Affinities; +import com.wurmonline.server.skills.Affinity; +import com.wurmonline.server.skills.SkillSystem; +import net.coldie.tools.BmlForm; + +import java.util.HashMap; +import java.util.Properties; +import java.util.Random; + +public class SorceryTitleQuestion extends Question { + + public SorceryTitleQuestion(long aResponderid, String aTitle, String aQuestion, long aTarget) throws NoSuchPlayerException { + + super(Players.getInstance().getPlayer(aResponderid), aTitle, aQuestion, 79, aTarget); + } + + public HashMap sorceryMap = new HashMap<>(); + + @Override + public void answer(Properties answer) { + boolean accepted = answer.containsKey("accept") && answer.get("accept") == "true"; + if (accepted) { + logger.info("Accepted Sorcery Title Change"); + int entry = Integer.parseInt(answer.getProperty("stitle")); + int stitleID = sorceryMap.get(entry); + if(this.getResponder() instanceof Player) { + Player player = (Player) this.getResponder(); + //logger.info("Converting "+player.getName()+" to " + Deities.getDeityName(deity)); + String stitle = Abilities.getAbilityString(stitleID); + logger.info("Setting sorcery title to "+stitle+" at index + " + entry + " for "+player.getName()); + + player.setAbilityTitle(stitleID); + } + } + } + + public String getSorceries(){ + String builder = ""; + Player player = (Player)this.getResponder(); + sorceryMap.clear(); + int num = 0; + int red = 0; + int black = 0; + int rest = 0; + int index = 0; + Achievement[] ach = Achievements.getAchievements(player.getWurmId()); + for(Achievement a : ach) { + int title = getAchievementTitle(a.getAchievement()); + if(title != -1) { + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + } + for(int i=1;i<64;i++){ + if(Abilities.getAbilityString(i) != null) { + logger.info("Checking if player " + getResponder().getName() + " has sorcery title " + Abilities.getAbilityString(i)); + } + if(player.hasAbility(i)) { + logger.info("Player had " + Abilities.getAbilityString(i)); + builder = builder + Abilities.getAbilityString(i); + sorceryMap.put(index, i); + // Incrementing extra counts + black += isBlack(i) ? 1 : 0; + red += isRed(i) ? 1 : 0; + rest += isOther(i) ? 1 : 0; + num++; + // Done + index++; + if (i < 64) { + builder = builder + ","; + } + } + } + // Check for achievement titles + + // Do the rest of the checks for any interim titles being achieved + int sex = player.getSex(); + if(black >= 2) { + int title = sex == 1 ? 4 : 14; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + if(black >= 3) { + int title = sex == 1 ? 36 : 17; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + if(red >= 2) { + int title = 21; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + if(red >= 3) { + int title = 22; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + if(rest >= 2) { + int title = sex == 1 ? 5 : 28; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + builder = builder + ","; + } + if(num > 3) { + int title = 19; + builder = builder + Abilities.getAbilityString(title); + sorceryMap.put(index, title); + index++; + } + // return dropdown string + return builder; + } + + + int getAchievementTitle(int achID) { + switch(achID) { + case 328: return 40; + case 327: return 26; + case 331: return 18; + case 329: return 38; + case 332: return 25; + case 333: return 37; + } + return -1; + } + + // Copied sorcery checks here (shouldnt be doing this but I dont feel like messing with reflection, can clean it up later) + final boolean isBlack(final int ability) { + switch (ability) { + case 1: + case 2: + case 3: + case 13: + case 15: + case 16: { + return true; + } + default: { + return false; + } + } + } + + final boolean isRed(final int ability) { + switch (ability) { + case 6: + case 7: + case 8: + case 20: + case 24: + case 34: + case 35: + case 44: { + return true; + } + default: { + return false; + } + } + } + + final boolean isOther(int ability) { + switch (ability) { + case 9: + case 10: + case 11: + case 12: + case 27: + case 29: + case 30: + case 31: + case 32: + case 33: + case 41: + case 42: + case 43: { + return true; + } + default: { + return false; + } + } + } + + String getMissingSorceries() { + StringBuilder builder = new StringBuilder(); + // 795 - 810 + Player player = (Player)getResponder(); + for(int i=795; i<=810; i++) { + int stitle = Abilities.getAbilityForItem(i, player); + if(!(player.hasAbility(stitle))) { + try { + builder.append(ItemTemplateFactory.getInstance().getTemplate(i).getName()); + if (i < 810) { + builder.append(","); + } + } + catch(NoSuchTemplateException e) { + // do nothing + } + } + } + return builder.toString(); + } + + @Override + public void sendQuestion() { + Player player = (Player)this.getResponder(); + if(!player.hasAnyAbility()){ + this.getResponder().getCommunicator().sendNormalServerMessage("You must have a sorcery title to view this."); + return; + } + BmlForm f = new BmlForm(""); + f.addHidden("id", String.valueOf(this.id)); + f.addBoldText("Select the sorcery title you would like to use\n", new String[0]); + f.addRaw("harray{label{text='Select Sorcery:'}dropdown{id='stitle';options='"); + f.addRaw(getSorceries()); + f.addRaw("'}}"); + f.addText("\n\n"); + f.addRaw("harray{label{text='Missing Sorceries:'}dropdown{id='missing';options='"); + f.addRaw(getMissingSorceries()); + f.addRaw("'}}"); + f.addText("\n\n", new String[0]); + f.beginHorizontalFlow(); + f.addButton("Accept", "accept"); + f.endHorizontalFlow(); + this.getResponder().getCommunicator().sendBml(400, 300, true, true, f.toString(), 255, 255, 255, this.title); + } +} diff --git a/src/main/java/mod/sin/actions/items/ReadSchematicAction.java b/src/main/java/mod/sin/actions/items/ReadSchematicAction.java index dbd9687..5f3b284 100644 --- a/src/main/java/mod/sin/actions/items/ReadSchematicAction.java +++ b/src/main/java/mod/sin/actions/items/ReadSchematicAction.java @@ -69,13 +69,13 @@ public class ReadSchematicAction implements ModAction, BehaviourProvider, Action @Override public boolean action(Action act, Creature performer, Item target, short action, float counter) { try { - SchematicWrapper wrapper = Schematics.getSchematicWrapper(target.getTemplateId()); - if(!Schematics.isASchematic(target) || wrapper == null) { + int productID = target.getData1(); + if(!Schematics.isASchematic(target) || productID <= 0) { performer.getCommunicator().sendNormalServerMessage("You cannot read that right now."); return true; } if(counter == 1.0f) { - if(Schematics.playerKnowsSchematic(performer, wrapper.product)) { + if(Schematics.playerKnowsSchematic(performer, productID)) { performer.getCommunicator().sendNormalServerMessage("You already know how to make that item."); return true; } @@ -90,9 +90,9 @@ public class ReadSchematicAction implements ModAction, BehaviourProvider, Action if (counter * 10.0f > time) { Items.destroyItem(target.getWurmId()); - Schematics.learnSchematic(wrapper.product, performer.getName()); - performer.getCommunicator().sendNormalServerMessage("You learn the schematic for " + ItemTemplateFactory.getInstance().getTemplateName(wrapper.product) + "!"); - logger.info(performer.getName() + " learned the schematic for " + ItemTemplateFactory.getInstance().getTemplateName(wrapper.product)); + Schematics.learnSchematic(productID, performer.getName()); + performer.getCommunicator().sendNormalServerMessage("You learn the schematic for " + ItemTemplateFactory.getInstance().getTemplateName(productID) + "!"); + logger.info(performer.getName() + " learned the schematic for " + ItemTemplateFactory.getInstance().getTemplateName(productID)); return true; } } diff --git a/src/main/java/mod/sin/creatures/Gremlin.java b/src/main/java/mod/sin/creatures/Gremlin.java index 2266918..b295a2c 100644 --- a/src/main/java/mod/sin/creatures/Gremlin.java +++ b/src/main/java/mod/sin/creatures/Gremlin.java @@ -67,10 +67,11 @@ public class Gremlin implements ModCreature, CreatureTypes { return; } // enable encounters when ready for event - +/* new EncounterBuilder(Tiles.Tile.TILE_TREE.id) .addCreatures(templateId, 5) .build(5); + */ } } diff --git a/src/main/java/mod/sin/items/WandPermaFrost.java b/src/main/java/mod/sin/items/WandPermaFrost.java index 1d82484..390ee49 100644 --- a/src/main/java/mod/sin/items/WandPermaFrost.java +++ b/src/main/java/mod/sin/items/WandPermaFrost.java @@ -45,7 +45,7 @@ public class WandPermaFrost implements MiscConstants { ItemTemplate template = itemBuilder.build(); templateId = template.getTemplateId(); - Schematics.schematics.add(new SchematicWrapper(templateId, 0, false, 0, 0)); + Schematics.schematics.add(new SchematicWrapper(templateId, false, 0, 0)); MagicItemWrapper wrapper = MagicItems.registerMagicItem(templateId, true); logger.info(name + " TemplateID: " + templateId); } diff --git a/src/main/java/mod/sin/items/schematicitems/SchematicItems.java b/src/main/java/mod/sin/items/schematicitems/SchematicItems.java index 32c0dcc..5833e86 100644 --- a/src/main/java/mod/sin/items/schematicitems/SchematicItems.java +++ b/src/main/java/mod/sin/items/schematicitems/SchematicItems.java @@ -17,33 +17,30 @@ public class SchematicItems implements ItemTypes, MiscConstants { public static int templateId; public void createTemplate() throws IOException { - for(SchematicWrapper wrapper : Schematics.schematics) { - String productName = ItemTemplateFactory.getInstance().getTemplateName(wrapper.product); - String name = "schematic for " + productName; - ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.item.schematic." + productName); - itemBuilder.name(name, "schematics for " + productName, "A schematic. Looks like it might create a " + productName); - itemBuilder.itemTypes(new short[]{ - ItemTypes.ITEM_TYPE_FULLPRICE, - ItemTypes.ITEM_TYPE_NOSELLBACK, - ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE - }); - itemBuilder.imageNumber((short) 640); - itemBuilder.behaviourType((short) 1); - itemBuilder.combatDamage(0); - itemBuilder.decayTime(Long.MAX_VALUE); - itemBuilder.dimensions(1, 1, 1); - itemBuilder.primarySkill((int) NOID); - itemBuilder.bodySpaces(EMPTY_BYTE_PRIMITIVE_ARRAY); - itemBuilder.modelName("model.resource.sheet.papyrus."); - itemBuilder.difficulty(5.0f); - itemBuilder.weightGrams(100); - itemBuilder.material(Materials.MATERIAL_PAPER); - itemBuilder.value(0); + String name = "schematic"; + ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.item.schematic"); + itemBuilder.name(name, "schematics", "A schematic. Looks like it might help you create something."); + itemBuilder.itemTypes(new short[]{ + ItemTypes.ITEM_TYPE_FULLPRICE, + ItemTypes.ITEM_TYPE_NOSELLBACK, + ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE, + ItemTypes.ITEM_TYPE_HASDATA + }); + itemBuilder.imageNumber((short) 640); + itemBuilder.behaviourType((short) 1); + itemBuilder.combatDamage(0); + itemBuilder.decayTime(Long.MAX_VALUE); + itemBuilder.dimensions(1, 1, 1); + itemBuilder.primarySkill((int) NOID); + itemBuilder.bodySpaces(EMPTY_BYTE_PRIMITIVE_ARRAY); + itemBuilder.modelName("model.resource.sheet.papyrus."); + itemBuilder.difficulty(5.0f); + itemBuilder.weightGrams(100); + itemBuilder.material(Materials.MATERIAL_PAPER); + itemBuilder.value(0); - ItemTemplate template = itemBuilder.build(); - templateId = template.getTemplateId(); - logger.info(name + " TemplateID: " + templateId); - wrapper.schematicTemplateId = templateId; - } + ItemTemplate template = itemBuilder.build(); + templateId = template.getTemplateId(); + logger.info(name + " TemplateID: " + templateId); } } diff --git a/src/main/java/mod/sin/wyvern/AchievementChanges.java b/src/main/java/mod/sin/wyvern/AchievementChanges.java index ee9ae52..94c53f1 100644 --- a/src/main/java/mod/sin/wyvern/AchievementChanges.java +++ b/src/main/java/mod/sin/wyvern/AchievementChanges.java @@ -6,6 +6,7 @@ import com.wurmonline.server.players.Achievement; import com.wurmonline.server.players.AchievementTemplate; import com.wurmonline.server.players.Achievements; import com.wurmonline.server.players.Titles; +import mod.sin.wyvern.mastercraft.CustomTitles; import mod.sin.wyvern.mastercraft.Mastercraft; import org.gotti.wurmunlimited.modloader.ReflectionUtil; @@ -315,7 +316,7 @@ public class AchievementChanges { if(a.getTemplate() == gremlinSlayer) { logger.info("Achievement at " + count); if(count >= 100) { - return Titles.Title.getTitle(704); + return CustomTitles.GremlinSlayer; } } return null; diff --git a/src/main/java/mod/sin/wyvern/CombatChanges.java b/src/main/java/mod/sin/wyvern/CombatChanges.java index 34d4bb4..03edfbd 100644 --- a/src/main/java/mod/sin/wyvern/CombatChanges.java +++ b/src/main/java/mod/sin/wyvern/CombatChanges.java @@ -335,22 +335,9 @@ public class CombatChanges { Util.instrumentDescribed(thisClass, ctCombatHandler, "getDamage", desc2, "isThisAnEpicOrChallengeServer", replace); CtClass ctAttackAction = classPool.get("com.wurmonline.server.creatures.AttackAction"); - CtClass[] paramsWoa1 = { - ctAttackAction, - ctItem - }; - CtClass[] paramsWoa2 = { - ctItem - }; - String descWoa1 = Descriptor.ofMethod(CtClass.floatType, paramsWoa1); - String descWoa2 = Descriptor.ofMethod(CtClass.floatType, paramsWoa2); - Util.setReason("Adjust WoA effect on weapons to be more noticeable"); - replace = "$_ = $proceed($$) * 2;"; - Util.instrumentDescribedCount(thisClass, ctCombatHandler, "getSpeed", descWoa1,"getSpellSpeedBonus", 2, replace); - Util.instrumentDescribedCount(thisClass, ctCombatHandler, "getSpeed", descWoa2,"getSpellSpeedBonus", 2, replace); - Util.setReason("Adjust bloodthirst cap up to 17k from 10k"); - replace = "$1 = 17000;" + + Util.setReason("Adjust bloodthirst cap up to 20k from 10k"); + replace = "$1 = 20000;" + "$_ = $proceed($$);"; Util.instrumentDeclaredCount(thisClass, ctCombatHandler, "setDamage", "min", 5, replace); diff --git a/src/main/java/mod/sin/wyvern/ItemMod.java b/src/main/java/mod/sin/wyvern/ItemMod.java index 7890dbc..9829d1f 100644 --- a/src/main/java/mod/sin/wyvern/ItemMod.java +++ b/src/main/java/mod/sin/wyvern/ItemMod.java @@ -10,10 +10,12 @@ import java.util.logging.Logger; import com.wurmonline.server.Servers; import com.wurmonline.server.combat.ArmourTemplate; +import com.wurmonline.server.items.*; import mod.sin.actions.items.magicitems.MagicItemMenuProvider; import mod.sin.actions.items.magicitems.MagicItemRechargeAction; import mod.sin.items.schematicitems.SchematicItems; import mod.sin.items.caches.*; +import mod.sin.wyvern.util.ItemUtil; import org.gotti.wurmunlimited.modloader.ReflectionUtil; import org.gotti.wurmunlimited.modloader.classhooks.HookManager; import org.gotti.wurmunlimited.modloader.classhooks.InvocationHandlerFactory; @@ -22,11 +24,6 @@ import org.gotti.wurmunlimited.modsupport.actions.ModActions; import com.wurmonline.server.behaviours.ActionEntry; import com.wurmonline.server.combat.Weapon; import com.wurmonline.server.creatures.Creature; -import com.wurmonline.server.items.Item; -import com.wurmonline.server.items.ItemList; -import com.wurmonline.server.items.ItemTemplate; -import com.wurmonline.server.items.ItemTemplateFactory; -import com.wurmonline.server.items.NoSuchTemplateException; import javassist.CtClass; import javassist.bytecode.Descriptor; import mod.sin.actions.items.*; @@ -415,6 +412,15 @@ public class ItemMod { ReflectionUtil.setPrivateField(creatureCage, ReflectionUtil.getField(creatureCage.getClass(), "value"), 100000); ReflectionUtil.setPrivateField(creatureCage, ReflectionUtil.getField(creatureCage.getClass(), "fullprice"), true); + // Make all tools/weapons dyable + for(int template : ItemUtil.toolWeaponTemplates) { + ItemTemplate t = ItemTemplateFactory.getInstance().getTemplate(template); + t.assignTypes(new short[] {ItemTypes.ITEM_TYPE_COLORABLE}); + } + ItemTemplate warhammer = ItemTemplateFactory.getInstance().getTemplate(Warhammer.templateId); + warhammer.assignTypes(new short[] {ItemTypes.ITEM_TYPE_COLORABLE}); + + // Set transmutation rod to 2 gold instead of 50 silver. //ItemTemplate transmutationRod = ItemTemplateFactory.getInstance().getTemplate(668); //ReflectionUtil.setPrivateField(transmutationRod, ReflectionUtil.getField(transmutationRod.getClass(), "value"), 2000000); diff --git a/src/main/java/mod/sin/wyvern/MiscChanges.java b/src/main/java/mod/sin/wyvern/MiscChanges.java index da13934..2ed5103 100644 --- a/src/main/java/mod/sin/wyvern/MiscChanges.java +++ b/src/main/java/mod/sin/wyvern/MiscChanges.java @@ -18,8 +18,11 @@ import com.wurmonline.server.items.SimpleCreationEntry; import com.wurmonline.server.players.Player; import com.wurmonline.server.players.PlayerInfo; import com.wurmonline.server.players.PlayerInfoFactory; +import com.wurmonline.server.questions.GmSetEnchants; import com.wurmonline.server.skills.Skill; import com.wurmonline.server.skills.SkillList; +import com.wurmonline.server.spells.Spell; +import com.wurmonline.server.spells.SpellEffect; import com.wurmonline.server.villages.Village; import com.wurmonline.server.webinterface.WcKingdomChat; import com.wurmonline.server.zones.VolaTile; @@ -171,6 +174,44 @@ public class MiscChanges { } } + public static void uncappedEnchantSendQuestion(GmSetEnchants gmSetEnchants) { + Item item = null; + try { + item = ReflectionUtil.getPrivateField(gmSetEnchants, ReflectionUtil.getField(gmSetEnchants.getClass(), "item")); + Spell[] spells = ReflectionUtil.getPrivateField(gmSetEnchants, ReflectionUtil.getField(gmSetEnchants.getClass(), "spells")); + StringBuilder buf = new StringBuilder(); + buf.append((String) ReflectionUtil.callPrivateMethod(gmSetEnchants, ReflectionUtil.getMethod(gmSetEnchants.getClass(), "getBmlHeader"))); + if(gmSetEnchants.getResponder().getPower() >= 4) { + final byte itemEnch = item.enchantment; + buf.append("table{rows=\"" + spells.length + "\";cols=\"4\";label{text=\"\"};text{type=\"bold\";text=\"Power\"};text{type=\"bold\";text=\"Name\"};text{type=\"bold\";text=\"Description\"};"); + for (int x = 0; x < spells.length; ++x) { + byte ench = spells[x].getEnchantment(); + SpellEffect eff = item.getSpellEffect(ench); + boolean sel = false; + String pow = ""; + if (eff != null) { + sel = true; + pow = String.valueOf((int) eff.power); + } else if (ench == itemEnch) { + sel = true; + } + int maxChars = 5; + buf.append("checkbox{id=\"newsel" + x + "\";selected=\"" + sel + "\"};" + (spells[x].singleItemEnchant ? "text{type=\"italic\";text=\"(none)\"};" : ("input{id=\"newpow" + x + "\";maxchars=\"" + maxChars + "\";text=\"" + pow + "\"};")) + "label{text=\"" + spells[x].getName() + "\"};label{text=\"" + spells[x].getDescription() + "\"};"); + } + buf.append("}"); + buf.append("label{text=\"\"};"); + buf.append("text{type=\"bold\";text=\"--------------- Help -------------------\"}"); + buf.append("text{text=\"Can add or change or remove enchants to specific powers, it maybe necessary to remove an enchant before modifying its power. If the enchant requires a power, then if none is specified it will default to 50, also \"}"); + buf.append("text{text=\"Note: Checks to see if the item can have the enchantment are not performed.\"}"); + buf.append("text{text=\"If anything is changed, then once the change is applied it will show this screen again.\"}"); + buf.append((String) ReflectionUtil.callPrivateMethod(gmSetEnchants, ReflectionUtil.getMethod(gmSetEnchants.getClass(), "createOkAnswerButton"))); + gmSetEnchants.getResponder().getCommunicator().sendBml(500, 500, true, true, buf.toString(), 200, 200, 200, gmSetEnchants.getTitle()); + } + } catch (IllegalAccessException | NoSuchMethodException | NoSuchFieldException | InvocationTargetException e) { + e.printStackTrace(); + } + } + public static boolean checkMayorCommand(Item item, Creature creature){ if(Servers.localServer.PVPSERVER){ return false; @@ -200,48 +241,6 @@ public class MiscChanges { return food.getFoodComplexity()*mult; } - public static float boatSpeedBonus(Vehicle boat) { - try { - Player captain = Players.getInstance().getPlayer(boat.pilotId); - if (captain.getDeity().getNumber() != Deities.DEITY_VYNORA) { - return 1; - } - if (captain.isOffline()) { - return 1; - } else { - if (captain.getFaith() >= 60.0) { - return 1.2f; - } - return 1; - } - } catch (NoSuchPlayerException e) { - e.printStackTrace(); - return 1; - } - } - - public static void buffBoat(Vehicle boat, Item item) { - try { - Map newBoatSpeeds = new HashMap<>(); - newBoatSpeeds.put(ItemList.caravel, 20f); - if(!item.isBoat() || newBoatSpeeds.get(item.getTemplateId()) == null) { - return; - } - float newWindImpact = newBoatSpeeds.get(item.getTemplateId()); - logger.info("BoatBuff: Changing the wind impact of " + item.getName() + " from " + boat.getWindImpact() + " to " + newWindImpact + "."); - Class vehicleClass = boat.getClass(); - float newWindMultiplier = Math.abs(newWindImpact - boat.getWindImpact()) / 10; - float oldSpeed = ReflectionUtil.getPrivateField(boat, ReflectionUtil.getField(vehicleClass, "maxSpeed")); - ReflectionUtil.setPrivateField(boat, ReflectionUtil.getField(vehicleClass, "maxSpeed"), oldSpeed * newWindMultiplier); - ReflectionUtil.callPrivateMethod(boat, ReflectionUtil.getMethod(vehicleClass, "setWindImpact"), (byte)newWindImpact); - byte wi = ReflectionUtil.getPrivateField(boat, ReflectionUtil.getField(vehicleClass, "windImpact")); - float ns = ReflectionUtil.getPrivateField(boat, ReflectionUtil.getField(vehicleClass, "maxSpeed")); - logger.info("BoatBuff: The new max speed of " + item.getName() + " is " + ns + " and the new wind impact is " + wi); - } catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - public static long getBedBonus(long secs, long bed){ Optional beds = Items.getItemOptional(bed); if(beds.isPresent()) { @@ -716,16 +715,6 @@ public class MiscChanges { "}"; Util.instrumentDeclared(thisClass, ctTempStates, "checkForChange", "setName", replace); - CtClass[] params13 = { - ctItem - }; - String desc13 = Descriptor.ofMethod(ctVehicle, params13); - Util.setReason("Buffing caravels to be less based on wind"); - CtClass ctVehicles = classPool.get("com.wurmonline.server.behaviours.Vehicles"); - replace = "$_ = $proceed($1, $2);" + - "" + MiscChanges.class.getName() + ".buffBoat($2, $1);"; - Util.instrumentDescribed(thisClass, ctVehicles, "createVehicle", desc13, "setSettingsForVehicle", replace); - Util.setReason("Stop royal food decay."); // Item parent, int parentTemp, boolean insideStructure, boolean deeded, boolean saveLastMaintained, boolean inMagicContainer, boolean inTrashbin CtClass[] params11 = { @@ -777,6 +766,13 @@ public class MiscChanges { "$_ = $proceed((int)(this.sleep + secs2));"; Util.instrumentDeclared(thisClass, ctPlayerInfo, "calculateSleep", "setSleep", replace); + Util.setReason("Allow GMs to set 5 digit enchants on all enchantments"); + CtClass ctGmSetEnchants = classPool.get("com.wurmonline.server.questions.GmSetEnchants"); + replace = "{" + + MiscChanges.class.getName() + ".uncappedEnchantSendQuestion($0);" + + " }"; + Util.setBodyDeclared(thisClass, ctGmSetEnchants, "sendQuestion", replace); + Util.setReason("Fix intrateleport block bug."); replace = "if($6.contains(\"blocked\")){" + " logger.info(\"Detected a blocked movement, resetting position back to old.\");" + @@ -875,21 +871,6 @@ public class MiscChanges { //Util.setReason("Allow preists of vynora to gain 20% boat speed above 60 faith."); //replace = "$_ = $proceed($1, $2 * " + MiscChanges.class.getName() + ".boatSpeedBonus(Players.getInstance().getPlayer(this.pilotId)));"; - ctVehicle.getDeclaredMethod("calculateNewBoatSpeed").instrument(new ExprEditor() { - private boolean first = true; - - @Override - public void edit(MethodCall m) throws CannotCompileException { - if (m.getMethodName().equals("min")) { - if (first) { - first = false; - } else { - m.replace("$_ = $proceed($1, $2 * " + MiscChanges.class.getName() + ".boatSpeedBonus(this));"); - logger.info("Allowing preists of vynora to gain 20% boat speed above 60 faith."); - } - } - } - }); CtClass ctSimpleCreationEntry = classPool.get("com.wurmonline.server.items.SimpleCreationEntry"); ctSimpleCreationEntry.getDeclaredMethod("run").instrument(new ExprEditor() { @@ -980,6 +961,7 @@ public class MiscChanges { "}"; Util.setBodyDeclared(thisClass, ctSpellEffect, "improvePower", replace); + /** Util.setReason("Disable smelting pots from being used."); CtClass ctItemBehaviour = classPool.get("com.wurmonline.server.behaviours.ItemBehaviour"); CtClass[] params15 = { @@ -996,6 +978,7 @@ public class MiscChanges { " return true;" + "}"; Util.insertBeforeDescribed(thisClass, ctItemBehaviour, "action", desc15, replace); + **/ Util.setReason("Change fantastic items to red."); CtClass ctManageObjectList = classPool.get("com.wurmonline.server.questions.ManageObjectList"); @@ -1009,6 +992,7 @@ public class MiscChanges { "}"; Util.insertBeforeDeclared(thisClass, ctManageObjectList, "addRariryColour", replace); + } catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) { throw new HookException(e); } diff --git a/src/main/java/mod/sin/wyvern/TreasureChests.java b/src/main/java/mod/sin/wyvern/TreasureChests.java index 113a91b..3e3c1b7 100644 --- a/src/main/java/mod/sin/wyvern/TreasureChests.java +++ b/src/main/java/mod/sin/wyvern/TreasureChests.java @@ -148,9 +148,9 @@ public class TreasureChests { doItemSpawn(item, templateTypes, 70.0f, 30.0f, 1); // Generate seryll - if (Server.rand.nextBoolean()) { + /*if (Server.rand.nextBoolean()) { doItemSpawn(item, new int[]{ItemList.seryllBar}, 60.0f, 20.0f, 1); - } // if + } */// if /*// Generate meal if (Server.rand.nextBoolean()) { @@ -223,8 +223,8 @@ public class TreasureChests { doItemSpawn(item, templateTypes2, 80.0f, 20.0f, 2 + Server.rand.nextInt(2)); // Generate seryll - int[] templateTypes3 = new int[]{ItemList.seryllBar}; - doItemSpawn(item, templateTypes3, 80.0f, 20.0f, 1 + Server.rand.nextInt(3)); + /*int[] templateTypes3 = new int[]{ItemList.seryllBar}; + doItemSpawn(item, templateTypes3, 80.0f, 20.0f, 1 + Server.rand.nextInt(3));*/ /*// Generate meal if (Server.rand.nextBoolean()) { diff --git a/src/main/java/mod/sin/wyvern/WyvernMods.java b/src/main/java/mod/sin/wyvern/WyvernMods.java index 63085c2..e277217 100644 --- a/src/main/java/mod/sin/wyvern/WyvernMods.java +++ b/src/main/java/mod/sin/wyvern/WyvernMods.java @@ -13,20 +13,19 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; -import com.wurmonline.server.Message; -import com.wurmonline.server.Items; -import com.wurmonline.server.Server; -import com.wurmonline.server.creatures.Communicator; +import com.wurmonline.server.*; import com.wurmonline.server.creatures.Creature; -import com.wurmonline.server.deities.Deities; +import com.wurmonline.server.creatures.NoSuchCreatureException; import com.wurmonline.server.items.*; -import com.wurmonline.server.kingdom.Kingdoms; +import com.wurmonline.server.questions.SorceryTitleQuestion; +import com.wurmonline.server.zones.Dens; +import javassist.bytecode.BadBytecode; import mod.sin.actions.items.SorcerySplitAction; import javassist.bytecode.Descriptor; import mod.sin.items.*; -import mod.sin.kingdomoffices.ItemCreator; import mod.sin.lib.Util; import mod.sin.wyvern.bonusoverhaul.ItemBonusOverhaul; +import mod.sin.wyvern.mastercraft.CustomTitles; import mod.sin.wyvern.schematics.Schematics; import org.gotti.wurmunlimited.modloader.ReflectionUtil; import org.gotti.wurmunlimited.modloader.classhooks.HookException; @@ -37,7 +36,6 @@ import org.gotti.wurmunlimited.modsupport.actions.ModActions; import org.gotti.wurmunlimited.modsupport.creatures.ModCreatures; import org.gotti.wurmunlimited.modsupport.vehicles.ModVehicleBehaviours; -import com.wurmonline.server.TimeConstants; import com.wurmonline.server.players.Player; import javassist.CannotCompileException; @@ -57,7 +55,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea private static Logger logger = Logger.getLogger(WyvernMods.class.getName()); public static boolean espCounter = false; public static boolean enableDepots = false; - public static boolean xmas2018 = true; + public static boolean xmas2018 = false; boolean bDebug = false; @@ -68,7 +66,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea tempStringArr = new byte[byteBuffer.get() & 255]; byteBuffer.get(tempStringArr); //String title = new String(tempStringArr, "UTF-8"); - if(player.mayMute() && message.startsWith("!")){ + if(message.startsWith("!")){ logger.info("Player "+player.getName()+" used custom WyvernMods command: "+message); if(message.startsWith("!toggleESP") && player.getPower() >= 5){ espCounter = !espCounter; @@ -76,8 +74,22 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea }else if(message.startsWith("!toggleDepots") && player.getPower() >= 5){ enableDepots = !enableDepots; player.getCommunicator().sendSafeServerMessage("Arena depots for this server is now = "+enableDepots); - }else{ + } + else if(message.startsWith("!stitles")) { + try { + SorceryTitleQuestion sq = new SorceryTitleQuestion(player.getWurmId(), "Sorcery titles", "Which sorcery title will you enable?", player.getWurmId()); + sq.sendQuestion(); + } catch (NoSuchPlayerException e) { + e.printStackTrace(); + } + } + else if(message.startsWith("!unique") && player.getPower() >= 5){ + Dens.checkDens(true); + player.getCommunicator().sendSafeServerMessage("Attempted to spawn a unique..."); + } + else{ player.getCommunicator().sendSafeServerMessage("Custom command not found: "+message); + return false; } return true; } @@ -166,6 +178,8 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea Class thisClass = WyvernMods.class; ClassPool classPool = HookManager.getInstance().getClassPool(); + CustomTitles.register(classPool); + Util.setReason("Insert examine method."); CtClass ctItemBehaviour = classPool.get("com.wurmonline.server.behaviours.ItemBehaviour"); String replace = WyvernMods.class.getName() + ".handleExamine($2, $3);"; @@ -183,7 +197,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea } } }); - } catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) { + } catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException | BadBytecode e) { throw new HookException(e); } } diff --git a/src/main/java/mod/sin/wyvern/bonusoverhaul/ItemBonusOverhaul.java b/src/main/java/mod/sin/wyvern/bonusoverhaul/ItemBonusOverhaul.java index 3dcfc57..07a2730 100644 --- a/src/main/java/mod/sin/wyvern/bonusoverhaul/ItemBonusOverhaul.java +++ b/src/main/java/mod/sin/wyvern/bonusoverhaul/ItemBonusOverhaul.java @@ -36,7 +36,7 @@ public class ItemBonusOverhaul { */ public static void initializeBonuses() throws NoSuchTemplateException { itemBonuses.add(new ItemBonusWrapper(GlimmerscaleVest.templateId, SpellEffectsEnum.ITEM_RING_CR, false, 1.0f, false)); - itemBonuses.add(new ItemBonusWrapper(ArcaniteNecklaceFocus.templateId, SpellEffectsEnum.ITEM_NECKLACE_FOCUS, false, 20.0f, true)); + itemBonuses.add(new ItemBonusWrapper(ArcaniteNecklaceFocus.templateId, SpellEffectsEnum.ITEM_NECKLACE_FOCUS, false, 0.2f, true)); batteries = new Battery[] { new Battery(Soul.templateId, 30), diff --git a/src/main/java/mod/sin/wyvern/bounty/LootBounty.java b/src/main/java/mod/sin/wyvern/bounty/LootBounty.java index 733edfd..163ee20 100644 --- a/src/main/java/mod/sin/wyvern/bounty/LootBounty.java +++ b/src/main/java/mod/sin/wyvern/bounty/LootBounty.java @@ -24,11 +24,13 @@ import mod.sin.items.FriyanTablet; import mod.sin.items.HolidaySpirit; import mod.sin.items.WandPermaFrost; import mod.sin.items.caches.*; +import mod.sin.items.schematicitems.SchematicItems; import mod.sin.wyvern.*; import mod.sin.wyvern.schematics.SchematicWrapper; import mod.sin.wyvern.schematics.Schematics; import mod.sin.wyvern.util.ItemUtil; +import javax.xml.validation.Schema; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Random; @@ -404,13 +406,9 @@ public class LootBounty { } } if(random.nextInt(100) < 1) { - try { - SchematicWrapper wrapper = Schematics.getSchematicFor(WandPermaFrost.templateId); - Item wandSchematic = ItemFactory.createItem(wrapper != null ? wrapper.schematicTemplateId : ItemList.charcoal, 50f, (byte)1, "Santa Claus"); + Item wandSchematic = Schematics.createSchematicForItem(WandPermaFrost.templateId, (byte)1, "Santa Claus"); + if(wandSchematic != null) { corpse.insertItem(wandSchematic); - } catch (FailedException | NoSuchTemplateException | NullPointerException e) { - e.printStackTrace(); - logger.info("ERROR: Schematic roll successful but failed to create."); } } } diff --git a/src/main/java/mod/sin/wyvern/mastercraft/AchievementTitles.java b/src/main/java/mod/sin/wyvern/mastercraft/CustomTitles.java similarity index 62% rename from src/main/java/mod/sin/wyvern/mastercraft/AchievementTitles.java rename to src/main/java/mod/sin/wyvern/mastercraft/CustomTitles.java index bd571a8..e6667a2 100644 --- a/src/main/java/mod/sin/wyvern/mastercraft/AchievementTitles.java +++ b/src/main/java/mod/sin/wyvern/mastercraft/CustomTitles.java @@ -1,14 +1,15 @@ package mod.sin.wyvern.mastercraft; +import com.wurmonline.server.players.Titles; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.NotFoundException; import javassist.bytecode.BadBytecode; -public class AchievementTitles { - public static int gremlinSlayerTitleID = 704; +public class CustomTitles { + public static Titles.Title GremlinSlayer; public static void register(ClassPool cp) throws NotFoundException, BadBytecode, CannotCompileException { TitleInjector injector = new TitleInjector(cp); - injector.addTitle("GremlinSlayer", gremlinSlayerTitleID, "Gremlin Slayer", "Gremlin Slayer", -1, "NORMAL"); + injector.addTitle("GremlinSlayer", 704, "Gremlin Slayer", "Gremlin Slayer", -1, "NORMAL"); } } diff --git a/src/main/java/mod/sin/wyvern/mastercraft/TitleInjector.java b/src/main/java/mod/sin/wyvern/mastercraft/TitleInjector.java index 4e7d98c..490815f 100644 --- a/src/main/java/mod/sin/wyvern/mastercraft/TitleInjector.java +++ b/src/main/java/mod/sin/wyvern/mastercraft/TitleInjector.java @@ -80,7 +80,7 @@ public class TitleInjector { code.add(Bytecode.DUP); // Put instance into static field - this will use the second copy of our instance - //code.addPutstatic("net.bdew.wurm.halloween.titles.TitlesExtended", ident, "Lcom/wurmonline/server/players/Titles$Title;"); + code.addPutstatic("mod.sin.wyvern.mastercraft.CustomTitles", ident, "Lcom/wurmonline/server/players/Titles$Title;"); // And finally stick it into values array, this will use the duped array, ordinal and the final copy of our instance code.add(Bytecode.AASTORE); diff --git a/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java b/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java index 851fc5f..3d5a85d 100644 --- a/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java +++ b/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java @@ -2,14 +2,12 @@ package mod.sin.wyvern.schematics; public class SchematicWrapper { public int product; - public int schematicTemplateId; public boolean isSkillRequired; public int primarySkill; public int requiredSkillLevel; - public SchematicWrapper(int product, int schematicTemplateId, boolean isSkillRequired, int primarySkill, int requiredSkillLevel) { + public SchematicWrapper(int product, boolean isSkillRequired, int primarySkill, int requiredSkillLevel) { this.product = product; - this.schematicTemplateId = schematicTemplateId; this.isSkillRequired = isSkillRequired; this.primarySkill = primarySkill; this.requiredSkillLevel = requiredSkillLevel; diff --git a/src/main/java/mod/sin/wyvern/schematics/Schematics.java b/src/main/java/mod/sin/wyvern/schematics/Schematics.java index d4d556d..4eb538e 100644 --- a/src/main/java/mod/sin/wyvern/schematics/Schematics.java +++ b/src/main/java/mod/sin/wyvern/schematics/Schematics.java @@ -1,15 +1,16 @@ package mod.sin.wyvern.schematics; +import com.wurmonline.server.FailedException; import com.wurmonline.server.Items; import com.wurmonline.server.creatures.Creature; -import com.wurmonline.server.items.CreationEntry; -import com.wurmonline.server.items.Item; -import com.wurmonline.server.items.ItemTemplateFactory; +import com.wurmonline.server.items.*; import javassist.ClassPool; import javassist.CtClass; import javassist.NotFoundException; import mod.sin.items.WandPermaFrost; +import mod.sin.items.schematicitems.SchematicItems; import mod.sin.lib.Util; +import mod.sin.wyvern.ItemMod; import org.gotti.wurmunlimited.modloader.classhooks.HookManager; import org.gotti.wurmunlimited.modsupport.ModSupportDb; @@ -123,12 +124,20 @@ public class Schematics { } public static boolean isASchematic(Item item) { - for(SchematicWrapper wrapper : schematics) { - if(wrapper.schematicTemplateId == item.getTemplateId()) { - return true; - } + return item.getTemplate().getTemplateId() == SchematicItems.templateId; + } + + public static Item createSchematicForItem(int productID, byte rarity, String creator) { + try { + Item item = ItemFactory.createItem(SchematicItems.templateId, 50f, (byte)1, "Santa Claus"); + item.setData1(productID); + item.setDescription("A schematic. Looks like it can be used to create a " + ItemTemplateFactory.getInstance().getTemplateName(productID) + "."); + item.setName("schematic for " + ItemTemplateFactory.getInstance().getTemplateName(productID)); + return item; + } catch (FailedException | NoSuchTemplateException e) { + e.printStackTrace(); + return null; } - return false; } public static SchematicWrapper getSchematicFor(int product) { @@ -140,13 +149,4 @@ public class Schematics { return null; } - public static SchematicWrapper getSchematicWrapper(int schematicId) { - for(SchematicWrapper wrapper : schematics) { - if(wrapper.schematicTemplateId == schematicId) { - return wrapper; - } - } - return null; - } - }