198 lines
6.4 KiB
C#
198 lines
6.4 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
|
|
using CLRScriptFramework;
|
|
using NWScript;
|
|
using NWScript.ManagedInterfaceLayer.NWScriptManagedInterface;
|
|
|
|
using NWEffect = NWScript.NWScriptEngineStructure0;
|
|
using NWEvent = NWScript.NWScriptEngineStructure1;
|
|
using NWLocation = NWScript.NWScriptEngineStructure2;
|
|
using NWTalent = NWScript.NWScriptEngineStructure3;
|
|
using NWItemProperty = NWScript.NWScriptEngineStructure4;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
namespace CLRScript
|
|
{
|
|
using NWScript = nwn2ai_onmoduleload;
|
|
class Agent{
|
|
public uint objref;
|
|
|
|
public Agent(uint obj){
|
|
objref = obj;
|
|
}
|
|
|
|
public float facing{
|
|
get{
|
|
return _facing;
|
|
}
|
|
set{
|
|
_facing = value;
|
|
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.SetFacing(_facing, 1);});
|
|
}
|
|
}
|
|
|
|
public NWLocation loc{
|
|
get{
|
|
return _loc;
|
|
}
|
|
set{
|
|
_loc = value;
|
|
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.ActionForceMoveToLocation(_loc, 1, 6f);});
|
|
|
|
//Link effect
|
|
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);
|
|
}
|
|
}
|
|
|
|
//Detection
|
|
//=======================================================================
|
|
|
|
public bool hasWallFront(float distance=10f){
|
|
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 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 = NWScript.get.GetNearestCreature(
|
|
NWScript.CREATURE_TYPE_REPUTATION, NWScript.REPUTATION_TYPE_ENEMY,
|
|
objref, 1,
|
|
NWScript.CREATURE_TYPE_PERCEPTION, NWScript.PERCEPTION_SEEN_AND_HEARD,
|
|
NWScript.CREATURE_TYPE_IS_ALIVE, NWScript.CREATURE_ALIVE_TRUE);
|
|
|
|
|
|
float dist = NWScript.get.GetDistanceBetween(nearestEnemy, objref);
|
|
return JsonConvert.DeserializeObject<dynamic>("{"
|
|
+ "\"valid\":\""+(NWScript.get.GetIsObjectValid(nearestEnemy)==1 && dist<=distanceMax).ToString()+"\","
|
|
+ "\"id\":\""+(nearestEnemy).ToString()+"\","
|
|
+ "\"name\":\""+NWScript.get.GetName(nearestEnemy)+"\""
|
|
+ "\"distance\":\""+(dist).ToString()+"\","
|
|
+ "\"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 = NWScript.get.GetNearestCreature(NWScript.CREATURE_TYPE_PLAYER_CHAR, NWScript.PLAYER_CHAR_IS_PC, objref, 1, -1,-1,-1,-1);
|
|
|
|
float dist = NWScript.get.GetDistanceBetween(pc, objref);
|
|
return JsonConvert.DeserializeObject<dynamic>("{"
|
|
+ "\"valid\":\""+(NWScript.get.GetIsObjectValid(pc)==1 && dist<=distanceMax).ToString()+"\","
|
|
+ "\"id\":\""+(pc).ToString()+"\","
|
|
+ "\"name\":\""+NWScript.get.GetName(pc)+"\""
|
|
+ "\"distance\":\""+(dist).ToString()+"\","
|
|
+ "}");
|
|
}
|
|
|
|
//Actions
|
|
//=======================================================================
|
|
|
|
public bool moveForward(float distance=10f){
|
|
if(hasWallFront(distance))
|
|
return false;
|
|
|
|
//See NWN2DataLib.AreaSurfaceMesh.PathExists
|
|
|
|
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;
|
|
}
|
|
|
|
public bool attackNearest(float distanceMax=15f){
|
|
var nearest = getNearestEnemy(distanceMax);
|
|
if(!nearest.valid)
|
|
return false;
|
|
|
|
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.ActionAttack(nearest.id, 0);});
|
|
return true;
|
|
}
|
|
|
|
public bool turn(float angleDeg){
|
|
facing+=angleDeg;
|
|
return true;
|
|
}
|
|
|
|
public bool say(string message){
|
|
NWScript.get.AssignCommand(objref, ()=>{NWScript.get.SpeakString(message, NWScript.TALKVOLUME_TALK);});
|
|
|
|
return getNearestPlayer().valid;
|
|
}
|
|
|
|
public string callCommand(string command)
|
|
{
|
|
Regex regexMethod = new Regex(@"([a-zA-Z_]+?)\s*\((.*?)\)");
|
|
Regex regexParam = new Regex("(\".*?\"|[0-9\\.]+)");
|
|
|
|
string methodName;
|
|
List<string> unparsedParams = new List<string>();
|
|
|
|
MatchCollection matches = regexMethod.Matches(command);
|
|
if(matches.Count == 1){
|
|
//Match name
|
|
methodName = matches[0].Groups[1].ToString();
|
|
|
|
//March parameters
|
|
string methodParamList = matches[0].Groups[2].ToString();
|
|
MatchCollection paramMatches = regexParam.Matches(methodParamList);
|
|
foreach(var p in paramMatches){
|
|
unparsedParams.Add(p.ToString().Trim('"'));
|
|
}
|
|
}
|
|
else{
|
|
//Failed to parse command
|
|
return "";
|
|
}
|
|
|
|
MethodInfo method = this.GetType().GetMethod(methodName);
|
|
ParameterInfo[] methodParams = method.GetParameters();
|
|
|
|
if(methodParams.Length != unparsedParams.Count){
|
|
//Incorrect number of parameters
|
|
return "";
|
|
}
|
|
|
|
|
|
List<Object> parsedParams = new List<Object>();
|
|
for(int i=0 ; i<methodParams.Length ; i++){
|
|
//Handle defaults?
|
|
var typeConverter = TypeDescriptor.GetConverter(methodParams[i].ParameterType);
|
|
parsedParams.Add(typeConverter.ConvertFromString(unparsedParams[i]));
|
|
}
|
|
|
|
|
|
return method.Invoke(this, parsedParams.ToArray()).ToString();
|
|
}
|
|
|
|
|
|
|
|
|
|
private float _facing;
|
|
private NWLocation _loc;
|
|
|
|
private Vector3 Multiply(Vector3 v, float f) {
|
|
v.x*=f; v.y*=f; v.z*=f;
|
|
return v;
|
|
}
|
|
private Vector3 Add(Vector3 v, Vector3 w) {
|
|
v.x*=w.x; v.y*=w.y; v.z*=w.z;
|
|
return v;
|
|
}
|
|
}
|
|
}
|