some actions works correctly
This commit is contained in:
parent
2a887f5142
commit
bb5cdb6f56
21
TestingAI.d
21
TestingAI.d
|
@ -6,6 +6,7 @@ import std.socket;
|
|||
import std.conv;
|
||||
import std.utf;
|
||||
import std.string;
|
||||
import std.array;
|
||||
|
||||
string receiveWait(Socket sock){
|
||||
bool blocking = sock.blocking;
|
||||
|
@ -33,17 +34,27 @@ void sendWait(Socket sock, string data){
|
|||
}
|
||||
|
||||
void main() {
|
||||
writeln("Start");
|
||||
writeln("Start");stdout.flush;
|
||||
auto sock = new TcpSocket;
|
||||
sock.blocking = true;
|
||||
sock.connect(new InternetAddress("127.0.0.1", 8080));
|
||||
writeln("Connected");
|
||||
writeln("Connected");stdout.flush;
|
||||
|
||||
sock.sendWait(`{"action":"bind","target":"testnpc"}`);
|
||||
sock.sendWait(`{"type":"bind","target":"testnpc"}`);
|
||||
writeln(sock.receiveWait);
|
||||
|
||||
Thread.sleep(dur!"seconds"(1));
|
||||
sock.shutdown(SocketShutdown.BOTH);
|
||||
while(1){
|
||||
write(">");stdout.flush;
|
||||
auto cmd = stdin.readln().strip;
|
||||
if(cmd == "")break;
|
||||
|
||||
writeln("==>",`{"type":"command","cmd":["`~cmd.replace(`"`,`\"`)~`"]}`);stdout.flush();
|
||||
sock.sendWait(`{"type":"command","cmd":["`~cmd.replace(`"`,`\"`)~`"]}`);
|
||||
//writeln(sock.receiveWait);
|
||||
}
|
||||
|
||||
writeln("Close");stdout.flush;
|
||||
sock.shutdown(SocketShutdown.BOTH);
|
||||
Thread.sleep(dur!"seconds"(1));
|
||||
writeln("Exit");stdout.flush;
|
||||
}
|
|
@ -18,7 +18,8 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace CLRScript
|
||||
{
|
||||
class Agent : CLRScriptBase{
|
||||
using NWScript = nwn2ai_onmoduleload;
|
||||
class Agent{
|
||||
public uint objref;
|
||||
|
||||
public Agent(uint obj){
|
||||
|
@ -31,7 +32,7 @@ namespace CLRScript
|
|||
}
|
||||
set{
|
||||
_facing = value;
|
||||
AssignCommand(objref, ()=>{SetFacing(_facing, TRUE);});
|
||||
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.SetFacing(_facing, 1);});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,11 +42,14 @@ namespace CLRScript
|
|||
}
|
||||
set{
|
||||
_loc = value;
|
||||
AssignCommand(objref, ()=>{ActionForceMoveToLocation(_loc, TRUE, 6f);});
|
||||
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.ActionForceMoveToLocation(_loc, 1, 6f);});
|
||||
|
||||
//Link effect
|
||||
RemoveSEFFromObject(objref, "nwai_beam_loc");
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNWN2SpecialEffectFile("nwai_beam_loc", OBJECT_INVALID, GetPositionFromLocation(_loc)), objref, -1f);
|
||||
NWScript.get.RemoveSEFFromObject(objref, "nwai_beam_loc");
|
||||
NWScript.get.ApplyEffectToObject(
|
||||
NWScript.DURATION_TYPE_PERMANENT,
|
||||
NWScript.get.EffectNWN2SpecialEffectFile("nwai_beam_loc", NWScript.OBJECT_INVALID, NWScript.get.GetPositionFromLocation(_loc)),
|
||||
objref, -1f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,45 +57,45 @@ namespace CLRScript
|
|||
//=======================================================================
|
||||
|
||||
public bool hasWallFront(float distance=10f){
|
||||
Vector3 pointFront = Add(GetPositionFromLocation(loc), Multiply(AngleToVector(facing), distance));
|
||||
return LineOfSightVector(GetPosition(objref), pointFront)==1;
|
||||
Vector3 pointFront = Add(NWScript.get.GetPositionFromLocation(loc), Multiply(NWScript.get.AngleToVector(facing), distance));
|
||||
return NWScript.get.LineOfSightVector(NWScript.get.GetPosition(objref), pointFront)==1;
|
||||
}
|
||||
|
||||
public bool isInCombat(){
|
||||
return GetIsInCombat(objref)==1;
|
||||
return NWScript.get.GetIsInCombat(objref)==1;
|
||||
}
|
||||
|
||||
//Json containing
|
||||
// {"valid":"true", "id":"366642", "name":"Goblin", "distance":"13.37", "difficulty":"13", "hp":"12"}
|
||||
public dynamic getNearestEnemy(float distanceMax=15f){
|
||||
uint nearestEnemy = GetNearestCreature(
|
||||
CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY,
|
||||
uint nearestEnemy = NWScript.get.GetNearestCreature(
|
||||
NWScript.CREATURE_TYPE_REPUTATION, NWScript.REPUTATION_TYPE_ENEMY,
|
||||
objref, 1,
|
||||
CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN_AND_HEARD,
|
||||
CREATURE_TYPE_IS_ALIVE, CREATURE_ALIVE_TRUE);
|
||||
NWScript.CREATURE_TYPE_PERCEPTION, NWScript.PERCEPTION_SEEN_AND_HEARD,
|
||||
NWScript.CREATURE_TYPE_IS_ALIVE, NWScript.CREATURE_ALIVE_TRUE);
|
||||
|
||||
|
||||
float dist = GetDistanceBetween(nearestEnemy, objref);
|
||||
float dist = NWScript.get.GetDistanceBetween(nearestEnemy, objref);
|
||||
return JsonConvert.DeserializeObject<dynamic>("{"
|
||||
+ "\"valid\":\""+(GetIsObjectValid(nearestEnemy)==TRUE && dist<=distanceMax).ToString()+"\","
|
||||
+ "\"valid\":\""+(NWScript.get.GetIsObjectValid(nearestEnemy)==1 && dist<=distanceMax).ToString()+"\","
|
||||
+ "\"id\":\""+(nearestEnemy).ToString()+"\","
|
||||
+ "\"name\":\""+GetName(nearestEnemy)+"\""
|
||||
+ "\"name\":\""+NWScript.get.GetName(nearestEnemy)+"\""
|
||||
+ "\"distance\":\""+(dist).ToString()+"\","
|
||||
+ "\"difficulty\":\""+GetChallengeRating(nearestEnemy)+"\""
|
||||
+ "\"hp\":\""+GetCurrentHitPoints(nearestEnemy)+"\""
|
||||
+ "\"difficulty\":\""+NWScript.get.GetChallengeRating(nearestEnemy)+"\""
|
||||
+ "\"hp\":\""+NWScript.get.GetCurrentHitPoints(nearestEnemy)+"\""
|
||||
+ "}");
|
||||
}
|
||||
|
||||
//Json containing
|
||||
// {"valid":"true", "id":"366642", "name":"Guethenoc", "distance":"13.37"}
|
||||
public dynamic getNearestPlayer(float distanceMax=15f){
|
||||
uint pc = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, objref, 1, -1,-1,-1,-1);
|
||||
uint pc = NWScript.get.GetNearestCreature(NWScript.CREATURE_TYPE_PLAYER_CHAR, NWScript.PLAYER_CHAR_IS_PC, objref, 1, -1,-1,-1,-1);
|
||||
|
||||
float dist = GetDistanceBetween(pc, objref);
|
||||
float dist = NWScript.get.GetDistanceBetween(pc, objref);
|
||||
return JsonConvert.DeserializeObject<dynamic>("{"
|
||||
+ "\"valid\":\""+(GetIsObjectValid(pc)==TRUE && dist<=distanceMax).ToString()+"\","
|
||||
+ "\"valid\":\""+(NWScript.get.GetIsObjectValid(pc)==1 && dist<=distanceMax).ToString()+"\","
|
||||
+ "\"id\":\""+(pc).ToString()+"\","
|
||||
+ "\"name\":\""+GetName(pc)+"\""
|
||||
+ "\"name\":\""+NWScript.get.GetName(pc)+"\""
|
||||
+ "\"distance\":\""+(dist).ToString()+"\","
|
||||
+ "}");
|
||||
}
|
||||
|
@ -105,8 +109,8 @@ namespace CLRScript
|
|||
|
||||
//See NWN2DataLib.AreaSurfaceMesh.PathExists
|
||||
|
||||
Vector3 pointFront = Add(GetPositionFromLocation(loc), Multiply(AngleToVector(facing), distance));
|
||||
loc = Location(GetAreaFromLocation(loc), pointFront, facing);
|
||||
Vector3 pointFront = Add(NWScript.get.GetPositionFromLocation(loc), Multiply(NWScript.get.AngleToVector(facing), distance));
|
||||
loc = NWScript.get.Location(NWScript.get.GetAreaFromLocation(loc), pointFront, facing);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -115,7 +119,7 @@ namespace CLRScript
|
|||
if(!nearest.valid)
|
||||
return false;
|
||||
|
||||
AssignCommand(objref, ()=>{ActionAttack(nearest.id, FALSE);});
|
||||
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.ActionAttack(nearest.id, 0);});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,7 +129,7 @@ namespace CLRScript
|
|||
}
|
||||
|
||||
public bool say(string message){
|
||||
AssignCommand(objref, ()=>{SpeakString(message, TALKVOLUME_TALK);});
|
||||
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.SpeakString(message, NWScript.TALKVOLUME_TALK);});
|
||||
|
||||
return getNearestPlayer().valid;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,15 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace CLRScript
|
||||
{
|
||||
|
||||
public partial class nwn2ai_onmoduleload : CLRScriptBase, ICLRScriptImplementation, IGeneratedScriptProgram
|
||||
{
|
||||
public static nwn2ai_onmoduleload get;
|
||||
|
||||
public nwn2ai_onmoduleload([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
|
||||
{
|
||||
InitScript(Intrinsics, Host);
|
||||
get = this;
|
||||
}
|
||||
|
||||
private nwn2ai_onmoduleload([In] nwn2ai_onmoduleload Other)
|
||||
|
@ -42,6 +45,7 @@ namespace CLRScript
|
|||
InitScript(Other);
|
||||
|
||||
LoadScriptGlobals(Other.SaveScriptGlobals());
|
||||
get = this;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -59,7 +63,7 @@ namespace CLRScript
|
|||
Debug("====================================> Start");
|
||||
|
||||
sockBufferIn = new Queue<Tuple<string,Socket>>();
|
||||
sockClients = new Dictionary<string,Socket>();
|
||||
sockClients = new Dictionary<Socket, Agent>();
|
||||
SocketConfigure();
|
||||
|
||||
AssignCommand(OBJECT_SELF, delegate() { ActionSpeakString("Start!", TALKVOLUME_TALK); });
|
||||
|
@ -80,38 +84,64 @@ namespace CLRScript
|
|||
Tuple<string, Socket> req = sockBufferIn.Dequeue();
|
||||
var socket = req.Item2;
|
||||
|
||||
var json = JsonConvert.DeserializeObject<dynamic>(req.Item1);
|
||||
//TODO: check if json correctly parsed
|
||||
switch ((string)json.action) {
|
||||
case "bind": {
|
||||
Debug("Bind request to '"+json.target+"'");
|
||||
try {
|
||||
|
||||
try {
|
||||
if (!sockClients.ContainsKey((string)json.target)) {
|
||||
var json = JsonConvert.DeserializeObject<dynamic>(req.Item1);
|
||||
//TODO: check if json correctly parsed
|
||||
switch ((string)json.type) {
|
||||
case "bind": {
|
||||
Debug("Bind request to '"+json.target+"'");
|
||||
string npcTag = (string)json.target;
|
||||
uint npcID = GetObjectByTag(npcTag, 0);
|
||||
|
||||
sockClients.Add((string)json.target, socket);
|
||||
try {
|
||||
try{
|
||||
var res = sockClients.First((kvp)=>kvp.Value.objref==npcID);
|
||||
//Will continue if the socket is already registered
|
||||
socket.Send(Encoding.UTF8.GetBytes(
|
||||
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Socket already binded with this NPC\"}"
|
||||
));
|
||||
}
|
||||
catch (Exception e) {
|
||||
//Will go here if the socket is nbot registered
|
||||
Agent npc = new Agent(npcID);
|
||||
sockClients.Add(socket, npc);
|
||||
socket.Send(Encoding.UTF8.GetBytes(
|
||||
"{\"action\":\"bindack\", \"result\":\"ok\"}"
|
||||
));
|
||||
|
||||
//handle env recording
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
socket.Send(Encoding.UTF8.GetBytes(
|
||||
"{\"action\":\"bindack\", \"result\":\"ok\"}"
|
||||
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Thrown exception: "+e.ToString().Replace("\"","\\\"")+"\"}"
|
||||
));
|
||||
|
||||
//handle env
|
||||
}
|
||||
}break;
|
||||
case "command": {
|
||||
Debug("command");
|
||||
if (sockClients.ContainsKey(socket)) {
|
||||
Agent npc = sockClients[socket];
|
||||
foreach(var cmd in json.cmd){
|
||||
Debug("exec "+(string)cmd);
|
||||
try {
|
||||
npc.callCommand((string)cmd);
|
||||
}
|
||||
catch(Exception e){
|
||||
Debug(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
socket.Send(Encoding.UTF8.GetBytes(
|
||||
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Socket already binded with this NPC\"}"
|
||||
));
|
||||
Debug("Commands must be executed on a binded NPC");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
socket.Send(Encoding.UTF8.GetBytes(
|
||||
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Thrown exception: "+e.ToString().Replace("\"","\\\"")+"\"}"
|
||||
));
|
||||
}
|
||||
}break;
|
||||
case "decision": {
|
||||
|
||||
|
||||
}break;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
catch(Exception e){
|
||||
Debug("Heartbeat Thrown exception: "+e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +191,7 @@ namespace CLRScript
|
|||
|
||||
//Remove stored bind
|
||||
Debug("EXIT");
|
||||
var sock = sockClients.First(kvp => kvp.Value==sockClient);
|
||||
sockClients.Remove(sock.Key);
|
||||
sockClients.Remove(sockClient);
|
||||
|
||||
}
|
||||
public static bool IsSocketConnected(Socket socket)
|
||||
|
@ -174,7 +203,7 @@ namespace CLRScript
|
|||
Socket sockServer;
|
||||
Queue<Tuple<string,Socket>> sockBufferIn;//Request & client
|
||||
|
||||
Dictionary<string, Socket> sockClients;//PNJ tag => Client socket
|
||||
Dictionary<Socket, Agent> sockClients;//Client socket=>NPC ref
|
||||
|
||||
private void Debug(string msg){
|
||||
debugFile.WriteLine(DateTime.Now.ToLongTimeString()+": "+msg);
|
||||
|
|
Loading…
Reference in New Issue