diff --git a/scripts/commands/transferitemmisc.py b/scripts/commands/transferitemmisc.py index e30072ba..16c98965 100644 --- a/scripts/commands/transferitemmisc.py +++ b/scripts/commands/transferitemmisc.py @@ -13,6 +13,10 @@ def run(core, actor, target, commandString): if container == None: return + if container.getTemplate().startswith("object/tangible/inventory/shared_lightsaber_inventory") or target.getContainer().getTemplate().startswith("object/tangible/inventory/shared_lightsaber_inventory"): + core.equipmentService.calculateLightsaberAttributes(actor, target, container) + return; + if target.getTemplate() == 'object/tangible/item/shared_loot_cash.iff': core.lootService.handleCreditPickUp(actor,target) core.objectService.destroyObject(target) diff --git a/scripts/object/weapon/melee/2h_sword/crafted_saber/sword_lightsaber_two_handed_gen5.py b/scripts/object/weapon/melee/2h_sword/crafted_saber/sword_lightsaber_two_handed_gen5.py index ccad8904..7f41b9a6 100644 --- a/scripts/object/weapon/melee/2h_sword/crafted_saber/sword_lightsaber_two_handed_gen5.py +++ b/scripts/object/weapon/melee/2h_sword/crafted_saber/sword_lightsaber_two_handed_gen5.py @@ -1,4 +1,13 @@ import sys +from engine.resources.container import CreaturePermissions def setup(core, object): + + inventory = core.objectService.createObject("object/tangible/inventory/shared_lightsaber_inventory_5.iff", object.getPlanet()) + inventory.setContainerPermissions(CreaturePermissions.CREATURE_PERMISSIONS); + + object.add(inventory) + + object.setAttachment('radial_filename', 'item/lightsaber') + return \ No newline at end of file diff --git a/scripts/object/weapon/melee/polearm/crafted_saber/sword_lightsaber_polearm_gen5.py b/scripts/object/weapon/melee/polearm/crafted_saber/sword_lightsaber_polearm_gen5.py index ccad8904..7f41b9a6 100644 --- a/scripts/object/weapon/melee/polearm/crafted_saber/sword_lightsaber_polearm_gen5.py +++ b/scripts/object/weapon/melee/polearm/crafted_saber/sword_lightsaber_polearm_gen5.py @@ -1,4 +1,13 @@ import sys +from engine.resources.container import CreaturePermissions def setup(core, object): + + inventory = core.objectService.createObject("object/tangible/inventory/shared_lightsaber_inventory_5.iff", object.getPlanet()) + inventory.setContainerPermissions(CreaturePermissions.CREATURE_PERMISSIONS); + + object.add(inventory) + + object.setAttachment('radial_filename', 'item/lightsaber') + return \ No newline at end of file diff --git a/scripts/object/weapon/melee/sword/crafted_saber/sword_lightsaber_one_handed_gen5.py b/scripts/object/weapon/melee/sword/crafted_saber/sword_lightsaber_one_handed_gen5.py index ccad8904..7f41b9a6 100644 --- a/scripts/object/weapon/melee/sword/crafted_saber/sword_lightsaber_one_handed_gen5.py +++ b/scripts/object/weapon/melee/sword/crafted_saber/sword_lightsaber_one_handed_gen5.py @@ -1,4 +1,13 @@ import sys +from engine.resources.container import CreaturePermissions def setup(core, object): + + inventory = core.objectService.createObject("object/tangible/inventory/shared_lightsaber_inventory_5.iff", object.getPlanet()) + inventory.setContainerPermissions(CreaturePermissions.CREATURE_PERMISSIONS); + + object.add(inventory) + + object.setAttachment('radial_filename', 'item/lightsaber') + return \ No newline at end of file diff --git a/scripts/radial/item/lightsaber.py b/scripts/radial/item/lightsaber.py new file mode 100644 index 00000000..c02dc502 --- /dev/null +++ b/scripts/radial/item/lightsaber.py @@ -0,0 +1,12 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + radials.add(RadialOptions(0, 21, 1, 'Open Lightsaber')) + return + +def handleSelection(core, owner, target, option): + if option == 21 and target: + core.simulationService.openContainer(owner, target.getSlottedObject("saber_inv")) + return + \ No newline at end of file diff --git a/scripts/radial/item/tunable.py b/scripts/radial/item/tunable.py index f226f86b..dc9eef3f 100644 --- a/scripts/radial/item/tunable.py +++ b/scripts/radial/item/tunable.py @@ -5,11 +5,22 @@ def createRadial(core, owner, target, radials): radials.clear() radials.add(RadialOptions(0, 7, 0, 'Examine')) radials.add(RadialOptions(0, 15, 0, 'Destroy')) - radials.add(RadialOptions(0, 19, 0, 'Tune')) + if target.getAttachment("tunerId") == None or target.getAttachment("tunerId") == 0: radials.add(RadialOptions(0, 19, 0, 'Tune')) return def handleSelection(core, owner, target, option): if option == 19 and target: if owner is not None: - owner.sendSystemMessage('You are not attuned enough with the force yet.',1) + #owner.sendSystemMessage('You are not attuned enough with the force yet.',1) + + if target.getAttachment("tunerId") == None or target.getAttachment("tunerId") == 0: + target.getAttributes().put("@obj_attr_n:crystal_owner", owner.getCustomName()) + target.setAttachment("tunerId", int(owner.getObjectId())) + + # Need to change this to generate valid numbers based on the quality and type ... stats found here: http://swg.wikia.com/wiki/Lightsaber_Crystal + if target.getAttributes().get("@obj_attr_n:color") is None: + target.getAttributes().put("@obj_attr_n:componentbonuslow", "23") + target.getAttributes().put("@obj_attr_n:componentbonushigh", "25") + else: + owner.sendSystemMessage("You cannot tune this crystal.",1) return diff --git a/src/resources/datatables/LightsaberColors.java b/src/resources/datatables/LightsaberColors.java new file mode 100644 index 00000000..7a8704f2 --- /dev/null +++ b/src/resources/datatables/LightsaberColors.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.datatables; + +import org.python.google.common.collect.BiMap; +import org.python.google.common.collect.HashBiMap; + +public final class LightsaberColors { + + public static BiMap map = HashBiMap.create(); + + static + { + // I put in the names of the really generic ones... I should be right up until Dark Purple... I'm unsure after Dark Purple. + map.put("Red", 0); + map.put("Dark Red", 1); + map.put("Light Green", 2); + map.put("Dark Green", 3); + map.put("Blue", 4); + map.put("Dark Blue", 5); + map.put("Yellow", 6); + map.put("Dark Yellow", 7); + map.put("Purple", 8); + map.put("Dark Purple", 9); + + map.put("Brown", 10); + map.put("Dark Brown", 11); + + map.put("color 12", 12); + map.put("color 13", 13); + map.put("color 14", 14); + map.put("color 15", 15); + map.put("color 16", 16); + + map.put("Bane's Heart", 17); + map.put("Sunrider's Destiny", 25); + + // Special crystals that have seperate shaders - the 256 is for a hacky way to set blade type and color without more code + map.put("Lava", 256 + 1); + map.put("Permafrost", 256 + 2); + map.put("Blackwing", 256 + 3); + } + + public static int getByName(String colorName) + { + return map.get(colorName); + } + + public static String get(int index) + { + return map.inverse().get(index); + } + + +} diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 6b9f01a2..d10499ec 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -297,6 +297,13 @@ public class TangibleObject extends SWGObject implements Serializable { } } + public Byte getCustomizationVariable(String type) + { + if(customizationVariables.containsKey(type)) return customizationVariables.get(type); + System.err.println("Error: object doesn't have customization variable " + type); + return null; + } + public void setCustomizationVariable(String type, byte value) { if(customizationVariables.containsKey(type)) customizationVariables.replace(type, value); diff --git a/src/services/DevService.java b/src/services/DevService.java index 3a8d08ea..845af82b 100644 --- a/src/services/DevService.java +++ b/src/services/DevService.java @@ -130,6 +130,7 @@ public class DevService implements INetworkDispatch { suiOptions.put((long) 90, "(Light) Jedi Robe"); suiOptions.put((long) 91, "(Dark) Jedi Robe"); suiOptions.put((long) 92, "Belt of Master Bodo Baas"); + suiOptions.put((long) 93, "Lightsaber Crystals"); break; case 10: // [Items] Jedi Items suiOptions.put((long) 111, "Harvesters"); @@ -992,6 +993,48 @@ public class DevService implements INetworkDispatch { case 92: // Belt of Master Bodo Baas inventory.add(core.objectService.createObject("object/tangible/wearables/backpack/shared_fannypack_s01.iff", planet)); return; + case 93: // Lightsaber Crystals + TangibleObject kraytPearl = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_krayt_dragon_pearl.iff", planet); + kraytPearl.setAttachment("LootItemName", "kraytpearl_flawless"); + core.lootService.handleSpecialItems(kraytPearl, "kraytpearl"); + inventory.add(kraytPearl); + + TangibleObject kraytPearl2 = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_krayt_dragon_pearl.iff", planet); + kraytPearl2.setAttachment("LootItemName", "kraytpearl_flawless"); + core.lootService.handleSpecialItems(kraytPearl2, "kraytpearl"); + inventory.add(kraytPearl2); + + TangibleObject kraytPearl3 = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_krayt_dragon_pearl.iff", planet); + kraytPearl3.setAttachment("LootItemName", "kraytpearl_flawless"); + core.lootService.handleSpecialItems(kraytPearl3, "kraytpearl"); + inventory.add(kraytPearl3); + + TangibleObject kraytPearl4 = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_krayt_dragon_pearl.iff", planet); + kraytPearl4.setAttachment("LootItemName", "kraytpearl_flawless"); + core.lootService.handleSpecialItems(kraytPearl4, "kraytpearl"); + inventory.add(kraytPearl4); + + TangibleObject kraytPearl5 = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_krayt_dragon_pearl.iff", planet); + kraytPearl5.setAttachment("LootItemName", "kraytpearl_flawless"); + core.lootService.handleSpecialItems(kraytPearl5, "kraytpearl"); + inventory.add(kraytPearl5); + + TangibleObject colorCrystal = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_force_crystal.iff", planet); + colorCrystal.getAttributes().put("@obj_attr_n:condition", "100/100"); + colorCrystal.getAttributes().put("@obj_attr_n:crystal_owner", "\\#D1F56F UNTUNED \\#FFFFFF "); + colorCrystal.setAttachment("radial_filename", "item/tunable"); + core.lootService.setCustomization(colorCrystal, "colorcrystal"); + inventory.add(colorCrystal); + + TangibleObject lavaCrystal = (TangibleObject) core.objectService.createObject("object/tangible/component/weapon/lightsaber/shared_lightsaber_module_lava_crystal.iff", planet); + lavaCrystal.getAttributes().put("@obj_attr_n:condition", "100/100"); + lavaCrystal.getAttributes().put("@obj_attr_n:crystal_owner", "\\#D1F56F UNTUNED \\#FFFFFF "); + lavaCrystal.getAttributes().put("@obj_attr_n:color", "Lava"); + lavaCrystal.setAttachment("radial_filename", "item/tunable"); + inventory.add(lavaCrystal); + + return; + case 110: SurveyTool mineralSurveyTool = (SurveyTool) core.objectService.createObject("object/tangible/survey_tool/shared_survey_tool_mineral.iff", planet); mineralSurveyTool.setCustomName("Mineral Survey Device"); diff --git a/src/services/EquipmentService.java b/src/services/EquipmentService.java index be901fc7..029edcdf 100644 --- a/src/services/EquipmentService.java +++ b/src/services/EquipmentService.java @@ -41,10 +41,13 @@ import org.python.core.PyObject; import resources.datatables.FactionStatus; import resources.objects.creature.CreatureObject; import main.NGECore; +import engine.resources.container.Traverser; import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; +import resources.objects.weapon.WeaponObject; import services.equipment.BonusSetTemplate; public class EquipmentService implements INetworkDispatch { @@ -120,6 +123,12 @@ public class EquipmentService implements INetworkDispatch { return false; } + if(item.getAttachment("hasColorCrystal") != null && (Boolean) item.getAttachment("hasColorCrystal") == false) + { + actor.sendSystemMessage("You may not equip a light saber that has no color crystal!", (byte) 0); + return false; + } + return result; } @@ -290,6 +299,90 @@ public class EquipmentService implements INetworkDispatch { } } + public void calculateLightsaberAttributes(CreatureObject actor, TangibleObject item, SWGObject targetContainer) + { + WeaponObject lightsaber = null; + TangibleObject lightsaberInventory = null; + long tunerId = 0; + + // Get our lightsaber weapon object + if(item.getContainer().getTemplate().startsWith("object/tangible/inventory/shared_lightsaber_inventory")) lightsaber = (WeaponObject) item.getGrandparent(); + else if(targetContainer.getTemplate().startsWith("object/tangible/inventory/shared_lightsaber_inventory")) lightsaber = (WeaponObject) targetContainer.getContainer(); + lightsaberInventory = (TangibleObject) lightsaber.getSlottedObject("saber_inv"); + + if(lightsaber.getAttachment("weaponBaseDamageMin") == null) lightsaber.setAttachment("weaponBaseDamageMin", lightsaber.getMinDamage()); + if(lightsaber.getAttachment("weaponBaseDamageMax") == null) lightsaber.setAttachment("weaponBaseDamageMax", lightsaber.getMaxDamage()); + + // Check if item is a lightsaber component + if(lightsaber == null) return; + if(lightsaberInventory == null) return; + if(lightsaber.getContainer() instanceof CreatureObject) return; + + if(!item.getTemplate().startsWith("object/tangible/component/weapon/lightsaber/")) return; + if(lightsaber.getAttachment("hasColorCrystal") == null) lightsaber.setAttachment("hasColorCrystal", false); + if(item.getAttributes().containsKey("@obj_attr_n:color") && (Boolean) lightsaber.getAttachment("hasColorCrystal")) return; + + // Find our tuner + if(item.getAttachment("tunerId") == null) item.setAttachment("tunerId", 0); + tunerId = (int) item.getAttachment("tunerId"); + + // Check if player tuned the crystal + if(tunerId != actor.getObjectId()) + { + actor.sendSystemMessage("You did not tune this crystal.", (byte) 0); + return; + } + else item.getContainer().transferTo(actor, targetContainer, item); + + // Calculate attributes + lightsaberInventory.viewChildren(lightsaberInventory, false, false, new Traverser() + { + WeaponObject saber; + TangibleObject saberInv; + + int minDamageBonus = 0; + int maxDamageBonus = 0; + Boolean hasColorCrystal = false; + + public void process(SWGObject item) + { + saber = (WeaponObject) item.getGrandparent(); + saberInv = (TangibleObject) saber.getSlottedObject("saber_inv"); + + if(item.getAttributes().get("@obj_attr_n:color") != null) // "Blade Color Modification" + { + int crystalColorIndex = resources.datatables.LightsaberColors.getByName((String) item.getAttributes().get("@obj_attr_n:color")); + + byte bladeType = crystalColorIndex > 256 ? (byte) (crystalColorIndex % 256) : 0x00; + byte bladeColor = crystalColorIndex > 256 ? (byte) 0x00 : (byte) crystalColorIndex; + + saber.setCustomizationVariable("private/alternate_shader_blade", bladeType); + saber.setCustomizationVariable("/private/index_color_blade", bladeColor); + + // System.out.println("bladeColorName: " + item.getAttributes().get("@obj_attr_n:color")); + // System.out.println("bladeColor: " + bladeColor); + // System.out.println("bladeType: " + bladeType); + // System.out.println(); + + hasColorCrystal = true; + } + else + { + minDamageBonus += Integer.parseInt(item.getAttributes().get("@obj_attr_n:componentbonuslow")); // "Min Damage Modified" + maxDamageBonus += Integer.parseInt(item.getAttributes().get("@obj_attr_n:componentbonushigh")); // "Max Damage Modified"" + } + + int saberBaseDamageMin = (int) saber.getAttachment("weaponBaseDamageMin"); + int saberBaseDamageMax = (int) saber.getAttachment("weaponBaseDamageMax"); + + saber.setMinDamage(saberBaseDamageMin + minDamageBonus); + saber.setMaxDamage(saberBaseDamageMax + maxDamageBonus); + + saber.setAttachment("hasColorCrystal", hasColorCrystal); + } + }); + } + private int getWeaponCriticalChance(CreatureObject actor, SWGObject item) { int weaponCriticalChance = 0; String weaponCriticalSkillMod = (core.scriptService.getMethod("scripts/equipment/", "weapon_critical", "weap_" + item.getStringAttribute("cat_wpn_damage.wpn_category").replace("@obj_attr_n:wpn_category_", "")).__call__().asString()); diff --git a/src/services/LootService.java b/src/services/LootService.java index a23d367b..84038d1b 100644 --- a/src/services/LootService.java +++ b/src/services/LootService.java @@ -533,12 +533,16 @@ public class LootService implements INetworkDispatch { } - private void setCustomization(TangibleObject droppedItem,String itemName) { + public void setCustomization(TangibleObject droppedItem,String itemName) { // Example color crystal if (itemName.contains("colorcrystal")) { System.out.println("colorcrystal"); - droppedItem.setCustomizationVariable("/private/index_color_1", (byte) new Random().nextInt(11)); + + int crystalColor = new Random().nextInt(11); + + droppedItem.setCustomizationVariable("/private/index_color_1", (byte) crystalColor); + droppedItem.getAttributes().put("@obj_attr_n:color", resources.datatables.LightsaberColors.get(crystalColor)); } // Example power crystal @@ -558,7 +562,7 @@ public class LootService implements INetworkDispatch { // } } - private void handleSpecialItems(TangibleObject droppedItem,String itemName) { + public void handleSpecialItems(TangibleObject droppedItem,String itemName) { if (itemName.contains("kraytpearl")){ handleKraytPearl(droppedItem); }