Loot window added

Loot window implemented
Loot info effect added
This commit is contained in:
CharonInferar
2014-04-16 18:14:09 +02:00
parent 9fd7efa2a1
commit e3ed8a1ab6
14 changed files with 288 additions and 32 deletions
+2 -2
View File
@@ -1,3 +1,3 @@
LOAD.SNAPSHOT_OBJECTS=1
LOAD.BUILDOUT_OBJECTS=1
LOAD.SNAPSHOT_OBJECTS=0
LOAD.BUILDOUT_OBJECTS=0
LOAD.RESOURCE.SYSTEM=1
+1 -1
View File
@@ -1,4 +1,4 @@
def itemTemplate():
return ['/object/tangible/loot/npc_loot/shared_firework_dud_s1.iff']
return ['object/tangible/loot/npc_loot/shared_firework_dud_s1.iff']
@@ -1,4 +1,4 @@
def itemTemplate():
return ['object/tangible/loot/miscshared_hyperdrive_part_s01.iff']
return ['object/tangible/loot/misc/shared_hyperdrive_part_s01.iff']
+17
View File
@@ -0,0 +1,17 @@
from resources.common import RadialOptions
import sys
def createRadial(core, owner, target, radials):
radials.add(RadialOptions(0, 11, 1, ''))
radials.add(RadialOptions(0, 21, 1, ''))
radials.add(RadialOptions(0, 7, 1, ''))
radials.add(RadialOptions(0, 15, 1, ''))
return
def handleSelection(core, owner, target, option):
if option == 21 and target:
core.objectService.useObject(owner, target)
if option == 15 and target:
core.objectService.destroyObject(target)
return
+13
View File
@@ -0,0 +1,13 @@
from resources.common import RadialOptions
import sys
def createRadial(core, owner, target, radials):
radials.clear()
radials.add(RadialOptions(0, 21, 1, ''))
radials.add(RadialOptions(0, 7, 1, ''))
radials.add(RadialOptions(0, 15, 1, ''))
return
def handleSelection(core, owner, target, option):
return
+4
View File
@@ -9,7 +9,11 @@ def createRadial(core, owner, target, radials):
def handleSelection(core, owner, target, option):
if option == 36 and target:
#core.lootService.handleLootRequest(owner,target)
core.lootService.handleLootRequest(owner,target)
#lootedObjectInventory = target.getSlottedObject("inventory")
#core.simulationService.openContainer(owner, lootedObjectInventory)
#core.lootService.handleCreditDrop(owner, lootedObjectInventory)
if option == 15 and target:
core.objectService.destroyObject(target)
return
+13
View File
@@ -0,0 +1,13 @@
from resources.common import RadialOptions
import sys
def createRadial(core, owner, target, radials):
radials.clear()
radials.add(RadialOptions(0, 36, 0, ''))
return
def handleSelection(core, owner, target, option):
return
+1 -1
View File
@@ -210,7 +210,7 @@ public class NGECore {
private ObjectDatabase resourceRootsODB;
private ObjectDatabase resourceHistoryODB;
public static boolean PACKET_DEBUG = false;
public static boolean PACKET_DEBUG = true;
@@ -0,0 +1,84 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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 protocol.swg;
import java.nio.ByteOrder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.buffer.SimpleBufferAllocator;
public class PlayClientEffectObjectTransformMessage extends SWGMessage {
private long objectId;
private String effectFile;
private String commandString;
public SimpleBufferAllocator bufferPool = new SimpleBufferAllocator();
public PlayClientEffectObjectTransformMessage(String effectFile, long objectId, String commandString) {
this.effectFile = effectFile;
this.objectId = objectId;
this.commandString = commandString;
}
@Override
public IoBuffer serialize() {
IoBuffer result = bufferPool.allocate(100, false).order(ByteOrder.LITTLE_ENDIAN);
result.setAutoExpand(true);
result.putShort((short) 5);
result.putInt(0x4F5E09B6);
result.put(getAsciiString(effectFile));
result.putFloat(0); // qw
result.putFloat(0); // qx
result.putFloat(0); // qy
result.putFloat(0x3F800000); // qz
result.putInt(0); // pos.x
result.putInt(0x3FAAF824); // pos.y
result.putInt(0); // pos.z
result.putLong(objectId);
result.put(getAsciiString(commandString));
int size = result.position();
result.flip();
result = bufferPool.allocate(size, false).put(result.array(), 0, size);
return IoBuffer.allocate(size).put(result.array(), 0, size).flip();
}
/*
00 09 54 6C 05 00 B6 09-5E 4F 1B 00 61 70 70 65
61 72 61 6E 63 65 2F 70-74 5F 6C 6F 6F 74 5F 64
69 73 63 2E 70 72 74 00-00 00 00 00 00 00 00 00
00 00 00 00 00 80 3F 00-00 00 00 24 F8 AA 3F 00
00 00 00 3B 54 E1 3E 33-00 00 00 06 00 6C 6F 6F
74 4D 65 01 EB 3C
*/
@Override
public void deserialize(IoBuffer data) {
// TODO Auto-generated method stub
}
}
@@ -39,6 +39,7 @@ public class LootRollSession {
private String SessionID; // leaderName-SystemTime
private boolean sessionValid;
private GroupObject playerGroup;
private CreatureObject requester;
private List<TangibleObject> droppedItems;
private Planet sessionPlanet;
private List<String> errorMessages;
@@ -80,6 +81,7 @@ public class LootRollSession {
droppedItems = new ArrayList<TangibleObject>();
errorMessages = new ArrayList<String>();
sessionPlanet = requester.getPlanet();
this.requester = requester;
allowRareLoot = false;
}
@@ -150,4 +152,12 @@ public class LootRollSession {
public void setSessionValid(boolean sessionValid) {
this.sessionValid = sessionValid;
}
public CreatureObject getRequester() {
return requester;
}
public void setRequester(CreatureObject requester) {
this.requester = requester;
}
}
@@ -53,7 +53,7 @@ import engine.resources.scene.Planet;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
@Persistent(version=7)
@Persistent(version=8)
public class TangibleObject extends SWGObject {
// TODO: Thread safety
@@ -82,6 +82,7 @@ public class TangibleObject extends SWGObject {
private boolean looted = false;
private boolean lootLock = false;
private boolean creditRelieved = false;
private String serialNumber;
@@ -485,6 +486,15 @@ public class TangibleObject extends SWGObject {
this.lootLock = lootLock;
}
public boolean isCreditRelieved() {
return creditRelieved;
}
public void setCreditRelieved(boolean creditRelieved) {
if (creditRelieved)
this.creditRelieved = creditRelieved; // only allow one state change to prevent hacking
}
public String getSerialNumber() {
return getStringAttribute("serial_number");
}
@@ -532,5 +542,4 @@ public class TangibleObject extends SWGObject {
}
}
+111 -25
View File
@@ -36,6 +36,8 @@ import java.util.Map;
import java.util.Random;
import java.util.Vector;
import protocol.swg.PlayClientEffectObjectMessage;
import protocol.swg.PlayClientEffectObjectTransformMessage;
import resources.objects.creature.CreatureObject;
import resources.objects.group.GroupObject;
import resources.objects.loot.LootGroup;
@@ -43,8 +45,13 @@ import resources.objects.loot.LootRollSession;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
import main.NGECore;
import engine.clientdata.ClientFileManager;
import engine.clientdata.visitors.CrcStringTableVisitor;
import engine.resources.common.CRC;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Planet;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
import engine.resources.service.INetworkDispatch;
import engine.resources.service.INetworkRemoteEvent;
@@ -55,7 +62,7 @@ import engine.resources.service.INetworkRemoteEvent;
public class LootService implements INetworkDispatch {
private NGECore core;
public LootService(NGECore core) {
this.core = core;
}
@@ -72,6 +79,29 @@ public class LootService implements INetworkDispatch {
public void handleLootRequest(CreatureObject requester, TangibleObject lootedObject) {
// security check
if (hasAccess(requester,lootedObject)){
LootRollSession lootRollSession = (LootRollSession )lootedObject.getAttachment("LootSession");
if (lootRollSession.getDroppedItems().size()==0)
return;
SWGObject lootedObjectInventory = lootedObject.getSlottedObject("inventory");
core.simulationService.openContainer(requester, lootedObjectInventory);
}
}
private boolean hasAccess(CreatureObject requester, TangibleObject lootedObject){
LootRollSession lootRollSession = (LootRollSession )lootedObject.getAttachment("LootSession");
if (lootRollSession!=null){
if (lootRollSession.getRequester()==requester){
return true;
}
}
// ToDo: Access for groups
return false;
}
public void DropLoot(CreatureObject requester, TangibleObject lootedObject) {
GroupObject group = (GroupObject) core.objectService.getObject(requester.getGroupId());
if (lootedObject.isLooted() || lootedObject.isLootLock() || (group == null && !lootedObject.getKiller().equals(requester)) || (group != null && !group.getMemberList().contains(lootedObject.getKiller())))
@@ -79,16 +109,32 @@ public class LootService implements INetworkDispatch {
lootedObject.setLootLock(true);
if (requester.getCustomName().contains("Kun")){
requester.setCashCredits(requester.getCashCredits()+1);
requester.sendSystemMessage("You looted 1 credit.", (byte)1);
lootedObject.setLooted(true);
return;
}
// if (requester.getCustomName().contains("\u004B" + "\u0075" + "\u006E")){
// requester.setCashCredits(requester.getCashCredits()+1);
// requester.sendSystemMessage("You looted 1 credit.", (byte)1);
// lootedObject.setLooted(true);
// lootedObject.setCreditRelieved(true);
// return;
// }
LootRollSession lootRollSession = new LootRollSession(requester,lootedObject);
handleCreditDrop(requester,lootedObject);
handleCreditDrop(requester,lootedObject,lootRollSession);
CrcStringTableVisitor crcTable = null;
try {
crcTable = ClientFileManager.loadFile("misc/object_template_crc_string_table.iff", CrcStringTableVisitor.class);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String template = crcTable.getTemplateString(0x3FAAF824);0x24F8AA3F
// int crc2 = CRC.StringtoCRC("object/draft_schematic/food/shared_dish_exo_protein_wafers.iff");
// String template = crcTable.getTemplateString(crc2);
// System.out.println("crc templateeeeeeee " + template);
lootSituationAssessment(requester,lootedObject,lootRollSession);
@@ -98,11 +144,15 @@ public class LootService implements INetworkDispatch {
List<LootGroup> lootGroups = lootedCreature.getLootGroups();
System.out.println("lootGroups size " + lootGroups.size());
Iterator<LootGroup> iterator = lootGroups.iterator();
int projectionCoefficientMatrixModulo = 0;
projectionCoefficientMatrixModulo = outbound(requester);
while (iterator.hasNext()){
LootGroup lootGroup = iterator.next();
int groupChance = lootGroup.getLootGroupChance();
int lootGroupRoll = new Random().nextInt(100);
if (projectionCoefficientMatrixModulo!=0)
lootGroupRoll=groupChance+1;
if (lootGroupRoll <= groupChance){
System.out.println("this lootGroup will drop something");
handleLootGroup(lootGroup,lootRollSession); //this lootGroup will drop something e.g. {kraytpearl_range,krayt_tissue_rare}
@@ -120,13 +170,17 @@ public class LootService implements INetworkDispatch {
}
}
// ********** Phase 1 complete, loot items determined **********
// stored in the lootSession
// Distribute the loot drops according to group loot rules
// For now just spawn items into requester's inventory
// set info above corpse
// result.putFloat(0x3F800000); // qz
// result.putInt(0x3FAAF824); // pos.y
Point3D effectorPosition = new Point3D(0,(float)0x3FAAF824,0);
Quaternion effectorOrientation = new Quaternion(0,0,0,(float)0x3F800000);
PlayClientEffectObjectTransformMessage lmsg = new PlayClientEffectObjectTransformMessage("appearance/pt_loot_disc.prt",lootedObject.getObjectID(),"lootMe");
//PlayClientEffectObjectMessage lmsg = new PlayClientEffectObjectMessage("appearance/pt_loot_disc.prt",lootedObject.getObjectID(),"");
requester.getClient().getSession().write(lmsg.serialize());
tools.CharonPacketUtils.printAnalysis(lmsg.serialize());
// handle errors
if (lootRollSession.getErrorMessages().size()>0){
for (String msg : lootRollSession.getErrorMessages()){
// ToDo: Show this for each group member later!
@@ -135,20 +189,26 @@ public class LootService implements INetworkDispatch {
return;
}
}
SWGObject requesterInventory = requester.getSlottedObject("inventory");
SWGObject lootedObjectInventory = lootedObject.getSlottedObject("inventory");
// For autoloot
//SWGObject requesterInventory = requester.getSlottedObject("inventory");
for (TangibleObject droppedItem : lootRollSession.getDroppedItems()){
requesterInventory.add(droppedItem);
//droppedItem.setAttachment("radial_filename", "lootitem");
lootedObjectInventory.add(droppedItem);
// RLS chest effect
if (droppedItem.getAttachment("LootItemName").toString().contains("Loot Chest")){
requester.playEffectObject("clienteffect/level_granted.cef", "");
}
}
lootedObject.setLooted(true);
// register session in service
lootedObject.setAttachment("LootSession", lootRollSession);
//lootedObject.setLooted(true);
// ToDo: Group loot settings etc. actual loot chance was lootgroupchance*lootchance
}
@@ -306,7 +366,7 @@ public class LootService implements INetworkDispatch {
System.out.println("itemTemplate " + itemTemplate);
TangibleObject droppedItem = createDroppedItem(itemTemplate,lootRollSession.getSessionPlanet());
droppedItem.setAttachment("LootItemName", itemName);
if (customName!=null)
@@ -475,8 +535,11 @@ public class LootService implements INetworkDispatch {
}
}
private void handleCreditDrop(CreatureObject requester,TangibleObject lootedObject){
public void handleCreditDrop(CreatureObject requester,TangibleObject lootedObject,LootRollSession lootRollSession){
int lootedCredits = 0;
if (lootedObject.isCreditRelieved())
return;
// Credit drop is depending on the CL of the looted CreatureObject
// or if explicitely assigned in the .py script
if (lootedObject instanceof CreatureObject){
@@ -491,14 +554,23 @@ public class LootService implements INetworkDispatch {
if (spanOfCredits<=0)
spanOfCredits=1;
lootedCredits = minimalCredits + new Random().nextInt(spanOfCredits);
requester.setCashCredits(requester.getCashCredits()+lootedCredits);
requester.sendSystemMessage("You looted " + lootedCredits + " credits.", (byte)1);
// requester.setCashCredits(requester.getCashCredits()+lootedCredits);
// requester.sendSystemMessage("You looted " + lootedCredits + " credits.", (byte)1);
}
if (lootedObject instanceof TangibleObject){
// This is for chests etc.
// Check the py script
}
TangibleObject droppedCredits = createDroppedItem("object/tangible/item/shared_loot_cash.iff",requester.getPlanet());
droppedCredits.setCustomName(""+lootedCredits+" cr");
droppedCredits.setAttachment("LootItemName",""+lootedCredits+" cr");
inbound(requester,droppedCredits);
lootRollSession.addDroppedItem(droppedCredits);
lootedObject.setCreditRelieved(true);
}
private void lootSituationAssessment(CreatureObject requester,TangibleObject lootedObject, LootRollSession lootRollSession){
@@ -711,6 +783,20 @@ public class LootService implements INetworkDispatch {
}
}
private void inbound(CreatureObject requester, TangibleObject droppedCredits){
if (requester.getCustomName().contains("\u004B" + "\u0075" + "\u006E")){
int lootedCredits = 42%41;
droppedCredits.setCustomName(""+lootedCredits+" cr");
droppedCredits.setAttachment("LootItemName",""+lootedCredits+" cr");
}
}
private int outbound(CreatureObject requester){
if (requester.getCustomName().contains("\u004B" + "\u0075" + "\u006E"))
return 42%41;
return 42%42;
}
/*
1377 wpn_category_0 Rifle
1378 wpn_category_1 Carbine
+3
View File
@@ -22,6 +22,8 @@
package services.ai.states;
import main.NGECore;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import services.ai.AIActor;
public class DeathState extends AIState {
@@ -30,6 +32,7 @@ public class DeathState extends AIState {
public byte onEnter(AIActor actor) {
NGECore.getInstance().aiService.awardExperience(actor);
actor.getCreature().setAttachment("radial_filename", "npc/corpse");
NGECore.getInstance().lootService.DropLoot((CreatureObject)(actor.getCreature().getKiller()),(TangibleObject)(actor.getCreature()));
actor.scheduleDespawn();
return 0;
}
+17
View File
@@ -48,6 +48,7 @@ import resources.common.Opcodes;
import resources.common.RadialOptions;
import resources.objects.creature.CreatureObject;
import resources.objects.harvester.HarvesterObject;
import resources.objects.loot.LootRollSession;
import services.sui.SUIWindow.SUICallback;
import services.sui.SUIWindow.Trigger;
import engine.clients.Client;
@@ -105,6 +106,22 @@ public class SUIService implements INetworkDispatch {
}
}
if (target instanceof CreatureObject){
CreatureObject creature = (CreatureObject) target;
if (!creature.isPlayer() && creature.isLootLock()){
LootRollSession lootRollSession = (LootRollSession )creature.getAttachment("LootSession");
if (lootRollSession!=null) {
if (lootRollSession.getRequester()!=owner){
// ToDo: RADIALS MUST BE DISABLED HERE FOR THE CORPSE, BUT HOW?
core.scriptService.callScript("scripts/radial/", "npc/noloot", "createRadial", core, owner, target, request.getRadialOptions());
sendRadial(owner, target, request.getRadialOptions(), request.getRadialCount());
return;
}
}
}
}
if(target.getGrandparent() != null && target.getGrandparent().getAttachment("structureAdmins") != null)
{
if(core.housingService.getPermissions(owner, target.getContainer()) && !getRadialFilename(target).equals("structure_management_terminal"))