Browse Source

some actions works correctly

master
Crom (Thibaut CHARLES) 7 years ago
parent
commit
bb5cdb6f56
  1. 21
      TestingAI.d
  2. 54
      nwn2ai_onmoduleload/Agent.cs
  3. 91
      nwn2ai_onmoduleload/nwn2ai_onmoduleload.cs

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;
}

54
nwn2ai_onmoduleload/Agent.cs

@ -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;
}

91
nwn2ai_onmoduleload/nwn2ai_onmoduleload.cs

@ -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 {
if (!sockClients.ContainsKey((string)json.target)) {
sockClients.Add((string)json.target, socket);
try {
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);
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…
Cancel
Save