diff --git a/scripts/object/mobile/tusken_raider.py b/scripts/object/mobile/tusken_raider.py index ccad8904..37e94fa4 100644 --- a/scripts/object/mobile/tusken_raider.py +++ b/scripts/object/mobile/tusken_raider.py @@ -1,4 +1,17 @@ import sys def setup(core, object): + + lootSpecification = [ + [ + ['Junk',90], + ['Rifles',70], + ['ParentProbability',60] + ], + [ + ['Colorcrystal',100], + ['ParentProbability',50] + ] + ] + object.setLootSpecification(lootSpecification) return \ No newline at end of file diff --git a/src/resources/objects/loot/LootDrop.java b/src/resources/objects/loot/LootDrop.java new file mode 100644 index 00000000..211fdca3 --- /dev/null +++ b/src/resources/objects/loot/LootDrop.java @@ -0,0 +1,21 @@ +package resources.objects.loot; + +import java.util.ArrayList; +import java.util.List; + +public class LootDrop { + + private List elements = new ArrayList(); + + public LootDrop(){ + + } + + public void addElement(String element){ + elements.add(element); + } + + public List getElements(){ + return elements; + } +} diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index dce95545..6639ac5f 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -23,12 +23,17 @@ package resources.objects.tangible; import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.Vector; import javax.xml.bind.DatatypeConverter; @@ -54,7 +59,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -@Persistent(version=1) +@Persistent(version=2) public class TangibleObject extends SWGObject { // TODO: Thread safety @@ -77,6 +82,8 @@ public class TangibleObject extends SWGObject { private int respawnTime = 0; private Point3D spawnCoordinates = new Point3D(0, 0, 0); + private TreeSet> lootSpecification = new TreeSet>(); + @NotPersistent private TangibleObject killer = null; @@ -444,6 +451,15 @@ public class TangibleObject extends SWGObject { } } + public TreeSet> getLootSpecification() { + return lootSpecification; + } + + public void setLootSpecification( + TreeSet> lootSpecification) { + this.lootSpecification = lootSpecification; + } + @Override public void sendBaselines(Client destination) { @@ -467,5 +483,4 @@ public class TangibleObject extends SWGObject { } - } diff --git a/src/services/DevService.java b/src/services/DevService.java index 0cde2b83..2ce2c1f6 100644 --- a/src/services/DevService.java +++ b/src/services/DevService.java @@ -991,6 +991,9 @@ public class DevService implements INetworkDispatch { solarSurveyTool.setCustomName("Solar Survey Device"); inventory.add(solarSurveyTool); + + core.staticService.spawnObject("object/mobile/shared_tusken_raider.iff", "tatooine", 0L, 3522F, 4F, -4801F, 0.70F, 0.71F); + break; } } diff --git a/src/services/LootService.java b/src/services/LootService.java new file mode 100644 index 00000000..bfa233aa --- /dev/null +++ b/src/services/LootService.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * 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 services; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.TreeMap; +import java.util.TreeSet; + +import resources.objects.creature.CreatureObject; +import resources.objects.group.GroupObject; +import resources.objects.loot.LootDrop; +import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; +import resources.objects.tool.SurveyTool; +import main.NGECore; +import engine.resources.objects.SWGObject; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +/** + * @author Charon + */ + +public class LootService implements INetworkDispatch { + + private NGECore core; + + public LootService(NGECore core) { + this.core = core; + //core.commandService.registerCommand(""); + } + + @Override + public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + + } + + @Override + public void shutdown() { + + } + + public void handleLootRequest(CreatureObject requester, TangibleObject lootedObject) { + + String lootedObjectType = "Tangible"; + if (lootedObject instanceof CreatureObject) + lootedObjectType = "Creature"; + + // Credit drop is depending on the CL of the looted CreatureObject + // or if explicitely assigned in the .py script + int lootedCredits = 0; + if (lootedObjectType.equals("Creature")){ + CreatureObject lootedCreature = (CreatureObject) lootedObject; + int creatureCL = lootedCreature.getLevel(); + int minimalCredits = 40 * creatureCL; // Predetermined factor of 40 per CL + int spanOfCredits = 15 * creatureCL; // Predetermined factor of 15 per CL + lootedCredits = minimalCredits + new Random().nextInt(spanOfCredits); + } + + if (lootedObjectType.equals("Tangible")){ + // This is for chests etc. + // Check the py script + } + + + List lootDrops = new ArrayList(); + List lootElements = new ArrayList(); + + TreeSet> lootSpec = lootedObject.getLootSpecification(); + Iterator> iterator = lootSpec.iterator(); + + while (iterator.hasNext()){ + TreeMap lootPool = iterator.next(); + int poolProbability = lootPool.lastEntry().getValue(); + int lootPoolRoll = new Random().nextInt(100); + if (lootPoolRoll <= poolProbability){ + lootElements = handleLootPool(lootPool); //this lootPool will drop + } + } + + // Now handle the chosen pools and determine the according items + + for (String element : lootElements){ + lootDrops = handleLootPoolElement(element); + } + + // ********** Phase 1 complete, loot items determined ********** + + // Distribute the loot drops according to group loot rules + + + // For now just spawn items into requester's inventory + for (LootDrop dropElem : lootDrops){ + PlayerObject requesterObj = (PlayerObject) requester.getSlottedObject("ghost"); + SWGObject requesterInventory = requesterObj.getSlottedObject("inventory"); + List elementList = dropElem.getElements(); + for (String template : elementList){ + TangibleObject droppedItem = (TangibleObject) core.objectService.createObject(template, requester.getPlanet()); + requesterInventory.add(droppedItem); + } + } + + + // ToDo: Group loot settings etc. + + // [20:35] <@_Light> your actual loot chance was lootgroupchance*lootchance + long leaderGroupId = requester.getGroupId(); + GroupObject group = (GroupObject) core.objectService.getObject(leaderGroupId); + if(group.getMemberList().size() == 1) { + // looter is alone + } + } + + + private List handleLootPool(TreeMap lootPool){ + List lootElements = new ArrayList(); + for(Map.Entry entry : lootPool.entrySet()) { + String poolElementName = entry.getKey(); + int poolElementProbability = entry.getValue(); + int lootPoolElementRoll = new Random().nextInt(100); + if (lootPoolElementRoll <= poolElementProbability){ + lootElements.add(poolElementName); + } + } + + return lootElements; + } + + private List handleLootPoolElement(String element){ + List lootDropList = new ArrayList(); + // This is just a random element from the python + + return lootDropList; + } +}