diff --git a/src/intents/radial/ObjectClickedIntent.java b/src/intents/radial/ObjectClickedIntent.java
new file mode 100644
index 000000000..4a2f0ff01
--- /dev/null
+++ b/src/intents/radial/ObjectClickedIntent.java
@@ -0,0 +1,36 @@
+package intents.radial;
+
+import resources.control.Intent;
+import resources.objects.SWGObject;
+import resources.objects.creature.CreatureObject;
+
+public class ObjectClickedIntent extends Intent {
+
+ public static final String TYPE = "ObjectClickedIntent";
+
+ private CreatureObject requestor;
+ private SWGObject target;
+
+ public ObjectClickedIntent(CreatureObject requestor, SWGObject target) {
+ super(TYPE);
+ setRequestor(requestor);
+ setTarget(target);
+ }
+
+ public void setRequestor(CreatureObject requestor) {
+ this.requestor = requestor;
+ }
+
+ public void setTarget(SWGObject target) {
+ this.target = target;
+ }
+
+ public CreatureObject getRequestor() {
+ return requestor;
+ }
+
+ public SWGObject getTarget() {
+ return target;
+ }
+
+}
diff --git a/src/network/PacketType.java b/src/network/PacketType.java
index 5c38464ce..def14c5d4 100644
--- a/src/network/PacketType.java
+++ b/src/network/PacketType.java
@@ -45,6 +45,8 @@ import network.packets.swg.zone.spatial.*;
import java.util.HashMap;
import java.util.Map;
+import resources.server_info.Log;
+
public enum PacketType {
// Both
@@ -222,8 +224,10 @@ public enum PacketType {
public static SWGPacket getForCrc(int crc) {
PacketType type = packetMap.get(crc);
- if (type == null)
+ if (type == null) {
+ Log.w("PacketType", "Unknown packet: %08X", crc);
return null;
+ }
Class extends SWGPacket> c = type.c;
try {
return c.newInstance();
diff --git a/src/network/packets/swg/zone/object_controller/IntendedTarget.java b/src/network/packets/swg/zone/object_controller/IntendedTarget.java
new file mode 100644
index 000000000..b3bb43094
--- /dev/null
+++ b/src/network/packets/swg/zone/object_controller/IntendedTarget.java
@@ -0,0 +1,64 @@
+/***********************************************************************************
+* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+* *
+* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+* Our goal is to create an emulator which will provide a server for players to *
+* continue playing a game similar to the one they used to play. We are basing *
+* it on the final publish of the game prior to end-game events. *
+* *
+* This file is part of Holocore. *
+* *
+* -------------------------------------------------------------------------------- *
+* *
+* Holocore is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Affero General Public License as *
+* published by the Free Software Foundation, either version 3 of the *
+* License, or (at your option) any later version. *
+* *
+* Holocore 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 Affero General Public License for more details. *
+* *
+* You should have received a copy of the GNU Affero General Public License *
+* along with Holocore. If not, see . *
+* *
+***********************************************************************************/
+package network.packets.swg.zone.object_controller;
+
+import java.nio.ByteBuffer;
+
+public class IntendedTarget extends ObjectController {
+
+ public static final int CRC = 0x04C5;
+
+ private long targetId;
+
+ public IntendedTarget(long objectId, long targetId) {
+ super(objectId, CRC);
+ setTargetId(targetId);
+ }
+
+ public IntendedTarget(ByteBuffer data) {
+ super(CRC);
+ decode(data);
+ }
+
+ public void decode(ByteBuffer data) {
+ decodeHeader(data);
+ targetId = getLong(data);
+ }
+
+ public ByteBuffer encode() {
+ ByteBuffer data = ByteBuffer.allocate(HEADER_LENGTH + 2);
+ encodeHeader(data);
+ addLong(data, targetId);
+ return data;
+ }
+
+ public long getTargetId() { return targetId; }
+
+ public void setTargetId(long targetId) { this.targetId = targetId; }
+
+}
diff --git a/src/network/packets/swg/zone/object_controller/ObjectController.java b/src/network/packets/swg/zone/object_controller/ObjectController.java
index 8e1982242..9a7f3c246 100644
--- a/src/network/packets/swg/zone/object_controller/ObjectController.java
+++ b/src/network/packets/swg/zone/object_controller/ObjectController.java
@@ -29,6 +29,7 @@ package network.packets.swg.zone.object_controller;
import java.nio.ByteBuffer;
+import resources.server_info.Log;
import network.packets.swg.SWGPacket;
public abstract class ObjectController extends SWGPacket {
@@ -88,14 +89,16 @@ public abstract class ObjectController extends SWGPacket {
return null;
int crc = data.getInt(10);
switch (crc) {
- case 0x00000071: return new DataTransform(data);
- case 0x000000F1: return new DataTransformWithParent(data);
- case 0x00000116: return new CommandQueueEnqueue(data);
- case 0x00000117: return new CommandQueueDequeue(data);
- case 0x0000012E: return new PlayerEmote(data);
- case 0x00000131: return new PostureUpdate(data);
- case 0x00000146: return new ObjectMenuRequest(data);
+ case 0x0071: return new DataTransform(data);
+ case 0x00F1: return new DataTransformWithParent(data);
+ case 0x0116: return new CommandQueueEnqueue(data);
+ case 0x0117: return new CommandQueueDequeue(data);
+ case 0x012E: return new PlayerEmote(data);
+ case 0x0131: return new PostureUpdate(data);
+ case 0x0146: return new ObjectMenuRequest(data);
+ case 0x04C5: return new IntendedTarget(data);
}
+ Log.w("ObjectController", "Unknown object controller: %08X", crc);
return null;
}
diff --git a/src/services/galaxy/terminals/TerminalService.java b/src/services/galaxy/terminals/TerminalService.java
index f630f5fe2..ebce30113 100644
--- a/src/services/galaxy/terminals/TerminalService.java
+++ b/src/services/galaxy/terminals/TerminalService.java
@@ -1,5 +1,6 @@
package services.galaxy.terminals;
+import intents.radial.ObjectClickedIntent;
import intents.radial.RadialRegisterIntent;
import intents.radial.RadialRequestIntent;
import intents.radial.RadialResponseIntent;
@@ -14,6 +15,7 @@ import java.util.Set;
import resources.control.Intent;
import resources.control.Service;
+import resources.radial.RadialItem;
import resources.radial.RadialOption;
import resources.radial.Radials;
import resources.server_info.Log;
@@ -41,6 +43,7 @@ public class TerminalService extends Service {
registerForIntent(RadialRequestIntent.TYPE);
registerForIntent(RadialSelectionIntent.TYPE);
+ registerForIntent(ObjectClickedIntent.TYPE);
}
@Override
@@ -93,6 +96,23 @@ public class TerminalService extends Service {
Radials.handleSelection(script, rsi.getPlayer(), rsi.getTarget(), rsi.getSelection());
}
break;
+ case ObjectClickedIntent.TYPE:
+ if (i instanceof ObjectClickedIntent) {
+ ObjectClickedIntent oci = (ObjectClickedIntent) i;
+ String script = lookupScript(oci.getTarget().getTemplate());
+ if (script == null) {
+ Log.w(this, "No script available!");
+ return;
+ }
+ List options = Radials.getRadialOptions(script, oci.getRequestor().getOwner(), oci.getTarget());
+ if (options.isEmpty()) {
+ Log.w(this, "Empty options list!");
+ return;
+ }
+ RadialItem item = RadialItem.getFromId(options.get(0).getId());
+ Radials.handleSelection(script, oci.getRequestor().getOwner(), oci.getTarget(), item);
+ }
+ break;
}
}
diff --git a/src/services/objects/RadialService.java b/src/services/objects/RadialService.java
index 45a51781f..bd99296bb 100644
--- a/src/services/objects/RadialService.java
+++ b/src/services/objects/RadialService.java
@@ -8,9 +8,11 @@ import resources.control.Intent;
import resources.control.Service;
import network.packets.Packet;
import network.packets.swg.zone.ObjectMenuSelect;
+import network.packets.swg.zone.object_controller.IntendedTarget;
import network.packets.swg.zone.object_controller.ObjectMenuRequest;
import network.packets.swg.zone.object_controller.ObjectMenuResponse;
import intents.network.GalacticPacketIntent;
+import intents.radial.ObjectClickedIntent;
import intents.radial.RadialRegisterIntent;
import intents.radial.RadialRequestIntent;
import intents.radial.RadialResponseIntent;
@@ -44,6 +46,8 @@ public class RadialService extends Service {
onRequest(gpi.getObjectManager(), (ObjectMenuRequest) p);
} else if (p instanceof ObjectMenuSelect) {
onSelection(gpi.getGalacticManager(), gpi.getNetworkId(), (ObjectMenuSelect) p);
+ } else if (p instanceof IntendedTarget) {
+ onObjectClicked(gpi.getObjectManager(), (IntendedTarget) p);
}
} else if (i instanceof RadialResponseIntent) {
onResponse((RadialResponseIntent) i);
@@ -61,11 +65,8 @@ public class RadialService extends Service {
private void onRequest(ObjectManager objectManager, ObjectMenuRequest request) {
SWGObject requestor = objectManager.getObjectById(request.getRequestorId());
SWGObject target = objectManager.getObjectById(request.getTargetId());
- if (target == null) {
- System.err.println(requestor + " requested a null target! ID: " + request.getTargetId());
- Log.w("RadialService", "%s requested a null target! ID: %d", requestor, request.getTargetId());
+ if (target == null)
return;
- }
if (!(requestor instanceof CreatureObject)) {
System.err.println("Requestor of target: " + target + " is not a creature object!");
Log.w("RadialService", "Requestor of target: %s is not a creature object! %s", target, requestor);
@@ -110,6 +111,29 @@ public class RadialService extends Service {
new RadialSelectionIntent(player, target, selection).broadcast();
}
+ private void onObjectClicked(ObjectManager objectManager, IntendedTarget it) {
+ SWGObject requestor = objectManager.getObjectById(it.getObjectId());
+ SWGObject target = objectManager.getObjectById(it.getTargetId());
+ if (target == null)
+ return;
+ if (!(requestor instanceof CreatureObject)) {
+ System.err.println("Requestor of target: " + target + " is not a creature object!");
+ Log.w("RadialService", "Requestor of target: %s is not a creature object! %s", target, requestor);
+ return;
+ }
+ Player player = requestor.getOwner();
+ if (player == null) {
+ System.err.println("Requestor of target: " + target + " does not have an owner!");
+ Log.w("RadialService", "Requestor of target: %s does not have an owner! %s", target, requestor);
+ return;
+ }
+ synchronized (templatesRegistered) {
+ if (templatesRegistered.contains(target.getTemplate())) {
+ new ObjectClickedIntent((CreatureObject) requestor, target).broadcast();
+ }
+ }
+ }
+
private void sendResponse(Player player, SWGObject target, List options, int counter) {
ObjectMenuResponse menuResponse = new ObjectMenuResponse(player.getCreatureObject().getObjectId());
menuResponse.setTargetId(target.getObjectId());