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 { class Agent : CLRScriptBase{ public uint objref; public Agent(uint obj){ objref = obj; } public float facing{ get{ return _facing; } set{ _facing = value; AssignCommand(objref, ()=>{SetFacing(_facing, TRUE);}); } } public NWLocation loc{ get{ return _loc; } set{ _loc = value; AssignCommand(objref, ()=>{ActionForceMoveToLocation(_loc, TRUE, 6f);}); //Link effect RemoveSEFFromObject(objref, "nwai_beam_loc"); ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNWN2SpecialEffectFile("nwai_beam_loc", OBJECT_INVALID, GetPositionFromLocation(_loc)), objref, -1f); } } //Detection //======================================================================= public bool hasWallFront(float distance=10f){ Vector3 pointFront = Add(GetPositionFromLocation(loc), Multiply(AngleToVector(facing), distance)); return LineOfSightVector(GetPosition(objref), pointFront)==1; } public bool isInCombat(){ return 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, objref, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN_AND_HEARD, CREATURE_TYPE_IS_ALIVE, CREATURE_ALIVE_TRUE); float dist = GetDistanceBetween(nearestEnemy, objref); return JsonConvert.DeserializeObject("{" + "\"valid\":\""+(GetIsObjectValid(nearestEnemy)==TRUE && dist<=distanceMax).ToString()+"\"," + "\"id\":\""+(nearestEnemy).ToString()+"\"," + "\"name\":\""+GetName(nearestEnemy)+"\"" + "\"distance\":\""+(dist).ToString()+"\"," + "\"difficulty\":\""+GetChallengeRating(nearestEnemy)+"\"" + "\"hp\":\""+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); float dist = GetDistanceBetween(pc, objref); return JsonConvert.DeserializeObject("{" + "\"valid\":\""+(GetIsObjectValid(pc)==TRUE && dist<=distanceMax).ToString()+"\"," + "\"id\":\""+(pc).ToString()+"\"," + "\"name\":\""+GetName(pc)+"\"" + "\"distance\":\""+(dist).ToString()+"\"," + "}"); } //Actions //======================================================================= public bool moveForward(float distance=10f){ if(hasWallFront(distance)) return false; //See NWN2DataLib.AreaSurfaceMesh.PathExists Vector3 pointFront = Add(GetPositionFromLocation(loc), Multiply(AngleToVector(facing), distance)); loc = Location(GetAreaFromLocation(loc), pointFront, facing); return true; } public bool attackNearest(float distanceMax=15f){ var nearest = getNearestEnemy(distanceMax); if(!nearest.valid) return false; AssignCommand(objref, ()=>{ActionAttack(nearest.id, FALSE);}); return true; } public bool turn(float angleDeg){ facing+=angleDeg; return true; } public bool say(string message){ AssignCommand(objref, ()=>{SpeakString(message, 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 unparsedParams = new List(); 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 parsedParams = new List(); for(int i=0 ; i