From 968f46cd391c4b6adbf0b4343a7529487f429243 Mon Sep 17 00:00:00 2001 From: mstoppelli Date: Tue, 11 Dec 2018 03:05:52 -0500 Subject: [PATCH] Schematics basics finished, schematics are added in the item creation entry part, schematics are auto-created and assigned afterwards. --- .../items/ItemBonusRechargeAction.java | 2 +- .../items/PermafrostTemperatureAction.java | 4 + .../actions/items/ReadSchematicAction.java | 115 +++++++++++++++++ src/main/java/mod/sin/creatures/Gremlin.java | 7 +- .../java/mod/sin/items/CrystalPermaFrost.java | 5 +- .../java/mod/sin/items/HolidaySpirit.java | 3 +- .../java/mod/sin/items/WandPermaFrost.java | 9 +- .../items/schematicitems/SchematicItems.java | 49 ++++++++ src/main/java/mod/sin/wyvern/ItemMod.java | 9 +- src/main/java/mod/sin/wyvern/WyvernMods.java | 2 + .../wyvern/schematics/SchematicWrapper.java | 17 +++ .../mod/sin/wyvern/schematics/Schematics.java | 119 ++++++++++++++---- 12 files changed, 309 insertions(+), 32 deletions(-) create mode 100644 src/main/java/mod/sin/actions/items/PermafrostTemperatureAction.java create mode 100644 src/main/java/mod/sin/actions/items/ReadSchematicAction.java create mode 100644 src/main/java/mod/sin/items/schematicitems/SchematicItems.java create mode 100644 src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java diff --git a/src/main/java/mod/sin/actions/items/ItemBonusRechargeAction.java b/src/main/java/mod/sin/actions/items/ItemBonusRechargeAction.java index f5e3c0a..56f11ff 100644 --- a/src/main/java/mod/sin/actions/items/ItemBonusRechargeAction.java +++ b/src/main/java/mod/sin/actions/items/ItemBonusRechargeAction.java @@ -57,7 +57,7 @@ public class ItemBonusRechargeAction implements ModAction, BehaviourProvider, Ac } if (counter == 1.0f) { performer.getCommunicator().sendNormalServerMessage("You begin recharging the " + target.getName()); - final int time = 15000; + final int time = 150; performer.getCurrentAction().setTimeLeft(time); performer.sendActionControl("Recharging...", true, time); } diff --git a/src/main/java/mod/sin/actions/items/PermafrostTemperatureAction.java b/src/main/java/mod/sin/actions/items/PermafrostTemperatureAction.java new file mode 100644 index 0000000..e979ad5 --- /dev/null +++ b/src/main/java/mod/sin/actions/items/PermafrostTemperatureAction.java @@ -0,0 +1,4 @@ +package mod.sin.actions.items; + +public class PermafrostTemperatureAction { +} diff --git a/src/main/java/mod/sin/actions/items/ReadSchematicAction.java b/src/main/java/mod/sin/actions/items/ReadSchematicAction.java new file mode 100644 index 0000000..dbd9687 --- /dev/null +++ b/src/main/java/mod/sin/actions/items/ReadSchematicAction.java @@ -0,0 +1,115 @@ +package mod.sin.actions.items; + +import com.wurmonline.server.Items; +import com.wurmonline.server.Server; +import com.wurmonline.server.behaviours.Action; +import com.wurmonline.server.behaviours.ActionEntry; +import com.wurmonline.server.behaviours.NoSuchActionException; +import com.wurmonline.server.creatures.Creature; +import com.wurmonline.server.items.Item; +import com.wurmonline.server.items.ItemTemplateFactory; +import com.wurmonline.server.players.Player; +import mod.sin.wyvern.schematics.SchematicWrapper; +import mod.sin.wyvern.schematics.Schematics; +import org.gotti.wurmunlimited.modsupport.actions.ActionPerformer; +import org.gotti.wurmunlimited.modsupport.actions.BehaviourProvider; +import org.gotti.wurmunlimited.modsupport.actions.ModAction; +import org.gotti.wurmunlimited.modsupport.actions.ModActions; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ReadSchematicAction implements ModAction, BehaviourProvider, ActionPerformer { + private static Logger logger = Logger.getLogger(ReadSchematicAction.class.getName()); + + private final short actionId; + private final ActionEntry actionEntry; + + public ReadSchematicAction() { + logger.log(Level.WARNING, "ReadSchematicAction()"); + + actionId = (short) ModActions.getNextActionId(); + actionEntry = ActionEntry.createEntry( + actionId, + "Read schematic", + "reading", + new int[] { 6 } + //new int[] { 6 /* ACTION_TYPE_NOMOVE */ } // 6 /* ACTION_TYPE_NOMOVE */, 48 /* ACTION_TYPE_ENEMY_ALWAYS */, 36 /* ACTION_TYPE_ALWAYS_USE_ACTIVE_ITEM */ + ); + ModActions.registerAction(actionEntry); + } + + @Override + public List getBehavioursFor(Creature performer, Item source, Item object) + { + return this.getBehavioursFor(performer, object); + } + + // Menu without activated object + @Override + public List getBehavioursFor(Creature performer, Item object) + { + if(performer instanceof Player && object != null && Schematics.isASchematic(object)) { + return Collections.singletonList(actionEntry); + } + + return null; + } + + @Override + public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter) + { + return this.action(act, performer, target, action, counter); + } + + @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) { + performer.getCommunicator().sendNormalServerMessage("You cannot read that right now."); + return true; + } + if(counter == 1.0f) { + if(Schematics.playerKnowsSchematic(performer, wrapper.product)) { + performer.getCommunicator().sendNormalServerMessage("You already know how to make that item."); + return true; + } + performer.getCommunicator().sendNormalServerMessage("You begin reading the schematic..."); + Server.getInstance().broadCastAction(performer.getName() + " begins reading a schematic.", performer, 5); + final int time = 150; + performer.getCurrentAction().setTimeLeft(time); + performer.sendActionControl("Reading schematic", true, time); + } + else { + int time = performer.getCurrentAction().getTimeLeft(); + + 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)); + return true; + } + } + return false; + } catch (NoSuchActionException e) { + e.printStackTrace(); + return true; + } catch (SQLException e) { + performer.getCommunicator().sendNormalServerMessage("Something went wrong. Alert a GM as soon as possible."); + logger.info("SQL Error with schematic"); + e.printStackTrace(); + return true; + } + } + + @Override + public short getActionId() { + return actionId; + } +} diff --git a/src/main/java/mod/sin/creatures/Gremlin.java b/src/main/java/mod/sin/creatures/Gremlin.java index 3b5ee46..9756a97 100644 --- a/src/main/java/mod/sin/creatures/Gremlin.java +++ b/src/main/java/mod/sin/creatures/Gremlin.java @@ -62,14 +62,15 @@ public class Gremlin implements ModCreature, CreatureTypes { @Override public void addEncounters() { - if (templateId == 0 ) { return; } + // enable encounters when ready for event - new EncounterBuilder(Tiles.Tile.TILE_TREE.id) + + /** new EncounterBuilder(Tiles.Tile.TILE_TREE.id) .addCreatures(templateId, 5) - .build(1); + .build(1);**/ } } diff --git a/src/main/java/mod/sin/items/CrystalPermaFrost.java b/src/main/java/mod/sin/items/CrystalPermaFrost.java index 39e6d75..8a08ba3 100644 --- a/src/main/java/mod/sin/items/CrystalPermaFrost.java +++ b/src/main/java/mod/sin/items/CrystalPermaFrost.java @@ -21,7 +21,8 @@ public class CrystalPermaFrost implements MiscConstants, ItemTypes { ItemTypes.ITEM_TYPE_MAGIC, ItemTypes.ITEM_TYPE_FULLPRICE, ItemTypes.ITEM_TYPE_NOSELLBACK, - ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE + ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE, + ItemTypes.ITEM_TYPE_NO_IMPROVE }); itemBuilder.imageNumber((short) 859); itemBuilder.behaviourType((short) 1); @@ -31,7 +32,7 @@ public class CrystalPermaFrost implements MiscConstants, ItemTypes { itemBuilder.primarySkill((int) NOID); itemBuilder.bodySpaces(EMPTY_BYTE_PRIMITIVE_ARRAY); itemBuilder.modelName("model.valrei."); - itemBuilder.difficulty(5.0f); + itemBuilder.difficulty(50.0f); itemBuilder.weightGrams(2000); itemBuilder.material(Materials.MATERIAL_CRYSTAL); itemBuilder.value(0); diff --git a/src/main/java/mod/sin/items/HolidaySpirit.java b/src/main/java/mod/sin/items/HolidaySpirit.java index 0ff32c4..43a83a2 100644 --- a/src/main/java/mod/sin/items/HolidaySpirit.java +++ b/src/main/java/mod/sin/items/HolidaySpirit.java @@ -22,7 +22,8 @@ public class HolidaySpirit implements ItemTypes, MiscConstants { ItemTypes.ITEM_TYPE_MAGIC, ItemTypes.ITEM_TYPE_FULLPRICE, ItemTypes.ITEM_TYPE_NOSELLBACK, - ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE + ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE, + ItemTypes.ITEM_TYPE_NO_IMPROVE }); itemBuilder.imageNumber((short) 859); itemBuilder.behaviourType((short) 1); diff --git a/src/main/java/mod/sin/items/WandPermaFrost.java b/src/main/java/mod/sin/items/WandPermaFrost.java index 651ab7a..c90a654 100644 --- a/src/main/java/mod/sin/items/WandPermaFrost.java +++ b/src/main/java/mod/sin/items/WandPermaFrost.java @@ -3,6 +3,8 @@ package mod.sin.items; import com.wurmonline.server.MiscConstants; import com.wurmonline.server.items.*; import com.wurmonline.server.skills.SkillList; +import mod.sin.wyvern.schematics.SchematicWrapper; +import mod.sin.wyvern.schematics.Schematics; import org.gotti.wurmunlimited.modsupport.ItemTemplateBuilder; import java.io.IOException; @@ -23,21 +25,22 @@ public class WandPermaFrost implements MiscConstants { ItemTypes.ITEM_TYPE_NOSELLBACK, ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE }); - itemBuilder.imageNumber((short) 859); + itemBuilder.imageNumber((short) 400); 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.valrei."); - itemBuilder.difficulty(5.0f); + itemBuilder.modelName("model.magic.wand.nature."); + itemBuilder.difficulty(70.0f); itemBuilder.weightGrams(3000); itemBuilder.material(Materials.MATERIAL_CRYSTAL); itemBuilder.value(0); ItemTemplate template = itemBuilder.build(); templateId = template.getTemplateId(); + Schematics.schematics.add(new SchematicWrapper(templateId, 0, false, 0, 0)); 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 new file mode 100644 index 0000000..32c0dcc --- /dev/null +++ b/src/main/java/mod/sin/items/schematicitems/SchematicItems.java @@ -0,0 +1,49 @@ +package mod.sin.items.schematicitems; + +import com.wurmonline.server.MiscConstants; +import com.wurmonline.server.items.ItemTemplate; +import com.wurmonline.server.items.ItemTemplateFactory; +import com.wurmonline.server.items.ItemTypes; +import com.wurmonline.server.items.Materials; +import mod.sin.wyvern.schematics.SchematicWrapper; +import mod.sin.wyvern.schematics.Schematics; +import org.gotti.wurmunlimited.modsupport.ItemTemplateBuilder; + +import java.io.IOException; +import java.util.logging.Logger; + +public class SchematicItems implements ItemTypes, MiscConstants { + public static Logger logger = Logger.getLogger(SchematicItems.class.getName()); + 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); + + ItemTemplate template = itemBuilder.build(); + templateId = template.getTemplateId(); + logger.info(name + " TemplateID: " + templateId); + wrapper.schematicTemplateId = templateId; + } + } +} diff --git a/src/main/java/mod/sin/wyvern/ItemMod.java b/src/main/java/mod/sin/wyvern/ItemMod.java index a5dd3a0..1ced4c1 100644 --- a/src/main/java/mod/sin/wyvern/ItemMod.java +++ b/src/main/java/mod/sin/wyvern/ItemMod.java @@ -11,6 +11,8 @@ import java.util.logging.Logger; import com.wurmonline.server.Servers; import com.wurmonline.server.behaviours.Action; +import com.wurmonline.server.combat.ArmourTemplate; +import mod.sin.items.schematicitems.SchematicItems; import mod.sin.lib.Util; import mod.sin.items.caches.*; import org.gotti.wurmunlimited.modloader.ReflectionUtil; @@ -111,6 +113,7 @@ public class ItemMod { public static HolidaySpirit HOLIDAY_SPIRIT = new HolidaySpirit(); public static WandPermaFrost WAND_PERMA_FROST = new WandPermaFrost(); public static CrystalPermaFrost CRYSTAL_PERMA_FROST = new CrystalPermaFrost(); + public static SchematicItems SCHEMATIC_ITEMS = new SchematicItems(); public static void createItems(){ logger.info("createItems()"); @@ -154,6 +157,9 @@ public class ItemMod { CRYSTAL_PERMA_FROST.createTemplate(); WAND_PERMA_FROST.createTemplate(); + // This must come after any schematic based items have already been created. + SCHEMATIC_ITEMS.createTemplate(); + // Arena Fragments KEY_FRAGMENT.createTemplate(); @@ -214,6 +220,7 @@ public class ItemMod { ModActions.registerAction(new StableContractAction()); ModActions.registerAction(new WoodEssenceAction()); ModActions.registerAction(new ItemBonusRechargeAction()); + ModActions.registerAction(new ReadSchematicAction()); } public static void initCreationEntries(){ @@ -285,7 +292,7 @@ public class ItemMod { logger.info("Beginning custom armour creation."); Map armours = ReflectionUtil.getPrivateField(null, ReflectionUtil.getField(Armour.class, "armours")); - armours.put(SpectralBoot.templateId, new ArmourTemplate(SpectralBoot.templateId, ArmourTemplate.ARMOUR_TYPE_LEATHER_DRAGON, 0.3f)); + armours.put(SpectralBoot.templateId, new ArmourTemplate(SpectralBoot.templateId, ArmourTemplate.ARMOUR_TYPE_LEATHER_DRAGON., 0.3f)); armours.put(SpectralCap.templateId, new Armour(SpectralCap.templateId, 0.003f, 0.3f)); armours.put(SpectralGlove.templateId, new Armour(SpectralGlove.templateId, 0.002f, 0.3f)); armours.put(SpectralHose.templateId, new Armour(SpectralHose.templateId, 0.0075f, 0.3f)); diff --git a/src/main/java/mod/sin/wyvern/WyvernMods.java b/src/main/java/mod/sin/wyvern/WyvernMods.java index 8756997..26ef0d4 100644 --- a/src/main/java/mod/sin/wyvern/WyvernMods.java +++ b/src/main/java/mod/sin/wyvern/WyvernMods.java @@ -266,6 +266,8 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea } catch (NoSuchTemplateException e) { throw new HookException(e); } + logger.info("Registering schematics..."); + Schematics.initSchematicList(); try { logger.info("Editing existing item templates."); ItemMod.modifyItems(); diff --git a/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java b/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java new file mode 100644 index 0000000..851fc5f --- /dev/null +++ b/src/main/java/mod/sin/wyvern/schematics/SchematicWrapper.java @@ -0,0 +1,17 @@ +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) { + 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 0e4a186..5de4631 100644 --- a/src/main/java/mod/sin/wyvern/schematics/Schematics.java +++ b/src/main/java/mod/sin/wyvern/schematics/Schematics.java @@ -2,6 +2,8 @@ package mod.sin.wyvern.schematics; 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 javassist.ClassPool; import javassist.CtClass; import javassist.NotFoundException; @@ -15,13 +17,13 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.logging.Logger; public class Schematics { - private static ArrayList schematics = new ArrayList<>(); + public static ArrayList schematics = new ArrayList<>(); + private static Logger logger = Logger.getLogger(Schematics.class.getName()); public static void preInit() { - initSchematicList(); - try { Util.setReason("Overriding difficulty check to check for creationentry requirements"); ClassPool classPool = HookManager.getInstance().getClassPool(); @@ -29,9 +31,9 @@ public class Schematics { String replace; CtClass ctCreationEntry = classPool.get("com.wurmonline.server.items.CreationEntry"); - replace = "boolean hasSchematic = " + Schematics.class.getName() + "checkSchematic($3, $0);" + + replace = "boolean hasSchematic = " + Schematics.class.getName() + ".checkSchematic($3, $0);" + "if(!hasSchematic) {" + - "return 0.0f" + + "return 0.0f;" + "}"; Util.insertBeforeDeclared(thisClass, ctCreationEntry, "getDifficultyFor", replace); } catch (NotFoundException e) { @@ -39,9 +41,12 @@ public class Schematics { } } - private static void initSchematicList() { - // Add items to schematic list here. These items will require the player to have read a schematic before - schematics.add(WandPermaFrost.templateId); + public static void initSchematicList() { + // Moved this. Items should be added to schematics in the file definition, after acquiring a templateid. + for(SchematicWrapper i : schematics) { + logger.info("Schematic registered for " + i.product + ItemTemplateFactory.getInstance().getTemplateName(i.product)); + } + } /** @@ -52,22 +57,94 @@ public class Schematics { */ public static boolean checkSchematic(Creature performer, CreationEntry ce) { int product = ce.getObjectCreated(); - if(schematics.contains(product)) { - try { - Connection dbcon = ModSupportDb.getModSupportDb(); - PreparedStatement ps = dbcon.prepareStatement("SELECT * FROM SchematicMap"); - ResultSet rs = ps.executeQuery(); - while (rs.next()) { - if (rs.getString("name").equals(performer.getName()) && rs.getInt("templateid") == product) { - return true; - } - } - } catch (SQLException e) { - throw new RuntimeException(e); + return checkSchematic(performer, product); + } + + public static boolean checkSchematic(Creature performer, int product) { + if(requiresASchematic(product)) { + if(!playerKnowsSchematic(performer, product)) { + performer.getCommunicator().sendNormalServerMessage("You don't know how to make that. Try finding a schematic for the item."); + logger.info("Player " + performer.getName() + " does not have schematic for " + ItemTemplateFactory.getInstance().getTemplateName(product)); + return false; } - return false; } return true; } + public static boolean playerKnowsSchematic(Creature performer, int product) { + try { + Connection dbcon = ModSupportDb.getModSupportDb(); + PreparedStatement ps = dbcon.prepareStatement("SELECT * FROM SchematicMap"); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + if (rs.getString("name").equals(performer.getName()) && rs.getInt("templateid") == product) { + logger.info("Player " + performer.getName() + " has schematic for " + ItemTemplateFactory.getInstance().getTemplateName(product)); + return true; + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + return false; + } + + /** + * Makes a player learn a schematic + * @param templateid schematic product + * @param name performer name + * @return if the schematic was learned + */ + public static boolean learnSchematic(int templateid, String name) throws SQLException { + try { + Connection dbcon = ModSupportDb.getModSupportDb(); + PreparedStatement ps = dbcon.prepareStatement("SELECT * FROM SchematicMap"); + ResultSet rs = ps.executeQuery(); + while(rs.next()) { + if(rs.getString("name").equals(name) && rs.getInt("templateid") == templateid) { + return false; + } + } + ps = dbcon.prepareStatement("INSERT INTO SchematicMap(name, templateid) VALUES(?, ?)"); + ps.setString(1, name); + ps.setInt(2, templateid); + ps.executeUpdate(); + return true; + } catch (SQLException e) { + e.printStackTrace(); + logger.info("ERROR: Failed to add schematic " + templateid + " to " + name + "."); + throw e; + } + } + + public static boolean requiresASchematic(int templateId) { + return getSchematicFor(templateId) != null; + } + + public static boolean isASchematic(Item item) { + for(SchematicWrapper wrapper : schematics) { + if(wrapper.schematicTemplateId == item.getTemplateId()) { + return true; + } + } + return false; + } + + public static SchematicWrapper getSchematicFor(int product) { + for(SchematicWrapper wrapper : schematics) { + if(wrapper.product == product) { + return wrapper; + } + } + return null; + } + + public static SchematicWrapper getSchematicWrapper(int schematicId) { + for(SchematicWrapper wrapper : schematics) { + if(wrapper.schematicTemplateId == schematicId) { + return wrapper; + } + } + return null; + } + }