aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs187
1 files changed, 157 insertions, 30 deletions
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 3cdd06d..2fdeeab 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -44,32 +44,119 @@ namespace OpenSim.Region.OptionalModules.World.NPC
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 // private const bool m_enabled = false; 47 private Dictionary<UUID, NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
48
49 private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
50 private Dictionary<UUID,AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
51 48
52 public void Initialise(Scene scene, IConfigSource source) 49 public void Initialise(Scene scene, IConfigSource source)
53 { 50 {
54 scene.RegisterModuleInterface<INPCModule>(this); 51 IConfig config = source.Configs["NPC"];
52
53 if (config != null && config.GetBoolean("Enabled", false))
54 {
55 scene.RegisterModuleInterface<INPCModule>(this);
56 scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
57 }
55 } 58 }
56 59
57 private AvatarAppearance GetAppearance(UUID target, Scene scene) 60 public void HandleOnSignificantClientMovement(ScenePresence presence)
58 { 61 {
59 if (m_appearanceCache.ContainsKey(target)) 62 lock (m_avatars)
60 return m_appearanceCache[target];
61
62 AvatarAppearance appearance = scene.AvatarService.GetAppearance(target);
63 if (appearance != null)
64 { 63 {
65 m_appearanceCache.Add(target, appearance); 64 if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget)
66 return appearance; 65 {
66 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
67// m_log.DebugFormat(
68// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}",
69// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
70
71 // Check the error term of the current position in relation to the target position
72 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
73 {
74 // We are close enough to the target
75 m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name);
76
77 presence.Velocity = Vector3.Zero;
78 presence.AbsolutePosition = presence.MoveToPositionTarget;
79 presence.ResetMoveToTarget();
80
81 if (presence.PhysicsActor.Flying)
82 {
83 // A horrible hack to stop the NPC dead in its tracks rather than having them overshoot
84 // the target if flying.
85 // We really need to be more subtle (slow the avatar as it approaches the target) or at
86 // least be able to set collision status once, rather than 5 times to give it enough
87 // weighting so that that PhysicsActor thinks it really is colliding.
88 for (int i = 0; i < 5; i++)
89 presence.PhysicsActor.IsColliding = true;
90
91// Vector3 targetPos = presence.MoveToPositionTarget;
92 if (m_avatars[presence.UUID].LandAtTarget)
93 presence.PhysicsActor.Flying = false;
94
95// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
96// if (targetPos.Z - terrainHeight < 0.2)
97// {
98// presence.PhysicsActor.Flying = false;
99// }
100 }
101
102// m_log.DebugFormat(
103// "[NPC MODULE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
104// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
105 }
106 else
107 {
108// m_log.DebugFormat(
109// "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}",
110// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
111
112 Vector3 agent_control_v3 = new Vector3();
113 presence.HandleMoveToTargetUpdate(ref agent_control_v3);
114 presence.AddNewMovement(agent_control_v3);
115 }
116//
117//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null);
118
119//
120//
121
122 }
67 } 123 }
124 }
125
126 public bool IsNPC(UUID agentId, Scene scene)
127 {
128 ScenePresence sp = scene.GetScenePresence(agentId);
129 if (sp == null || sp.IsChildAgent)
130 return false;
68 131
69 return new AvatarAppearance(); 132 lock (m_avatars)
133 return m_avatars.ContainsKey(agentId);
70 } 134 }
71 135
72 public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) 136 public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene)
137 {
138 ScenePresence sp = scene.GetScenePresence(agentId);
139 if (sp == null || sp.IsChildAgent)
140 return false;
141
142 lock (m_avatars)
143 if (!m_avatars.ContainsKey(agentId))
144 return false;
145
146 scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
147
148 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
149 sp.Appearance = npcAppearance;
150 scene.AttachmentsModule.RezAttachments(sp);
151
152 IAvatarFactory module = scene.RequestModuleInterface<IAvatarFactory>();
153 module.SendAppearance(sp.UUID);
154
155 return true;
156 }
157
158 public UUID CreateNPC(
159 string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance)
73 { 160 {
74 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); 161 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene);
75 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue); 162 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
@@ -84,12 +171,18 @@ namespace OpenSim.Region.OptionalModules.World.NPC
84 acd.lastname = lastname; 171 acd.lastname = lastname;
85 acd.ServiceURLs = new Dictionary<string, object>(); 172 acd.ServiceURLs = new Dictionary<string, object>();
86 173
87 AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene); 174 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
88 AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
89 acd.Appearance = npcAppearance; 175 acd.Appearance = npcAppearance;
90 176
177// for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++)
178// {
179// m_log.DebugFormat(
180// "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}",
181// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
182// }
183
91 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); 184 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
92 scene.AddNewClient(npcAvatar); 185 scene.AddNewClient(npcAvatar, PresenceType.Npc);
93 186
94 ScenePresence sp; 187 ScenePresence sp;
95 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) 188 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
@@ -97,13 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
97 m_log.DebugFormat( 190 m_log.DebugFormat(
98 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID); 191 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
99 192
100 // Shouldn't call this - temporary. 193 sp.CompleteMovement(npcAvatar, false);
101 sp.CompleteMovement(npcAvatar);
102
103// sp.SendAppearanceToAllOtherAgents();
104//
105// // Send animations back to the avatar as well
106// sp.Animator.SendAnimPack();
107 } 194 }
108 else 195 else
109 { 196 {
@@ -118,7 +205,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC
118 return npcAvatar.AgentId; 205 return npcAvatar.AgentId;
119 } 206 }
120 207
121 public void Autopilot(UUID agentID, Scene scene, Vector3 pos) 208 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget)
209 {
210 lock (m_avatars)
211 {
212 if (m_avatars.ContainsKey(agentID))
213 {
214 ScenePresence sp;
215 scene.TryGetScenePresence(agentID, out sp);
216
217 m_log.DebugFormat(
218 "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
219 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
220
221 m_avatars[agentID].LandAtTarget = landAtTarget;
222 sp.MoveToTarget(pos, noFly);
223
224 return true;
225 }
226 }
227
228 return false;
229 }
230
231 public bool StopMoveToTarget(UUID agentID, Scene scene)
122 { 232 {
123 lock (m_avatars) 233 lock (m_avatars)
124 { 234 {
@@ -126,32 +236,49 @@ namespace OpenSim.Region.OptionalModules.World.NPC
126 { 236 {
127 ScenePresence sp; 237 ScenePresence sp;
128 scene.TryGetScenePresence(agentID, out sp); 238 scene.TryGetScenePresence(agentID, out sp);
129 sp.DoAutoPilot(0, pos, m_avatars[agentID]); 239
240 sp.Velocity = Vector3.Zero;
241 sp.ResetMoveToTarget();
242
243 return true;
130 } 244 }
131 } 245 }
246
247 return false;
132 } 248 }
133 249
134 public void Say(UUID agentID, Scene scene, string text) 250 public bool Say(UUID agentID, Scene scene, string text)
135 { 251 {
136 lock (m_avatars) 252 lock (m_avatars)
137 { 253 {
138 if (m_avatars.ContainsKey(agentID)) 254 if (m_avatars.ContainsKey(agentID))
139 { 255 {
256 ScenePresence sp;
257 scene.TryGetScenePresence(agentID, out sp);
258
140 m_avatars[agentID].Say(text); 259 m_avatars[agentID].Say(text);
260
261 return true;
141 } 262 }
142 } 263 }
264
265 return false;
143 } 266 }
144 267
145 public void DeleteNPC(UUID agentID, Scene scene) 268 public bool DeleteNPC(UUID agentID, Scene scene)
146 { 269 {
147 lock (m_avatars) 270 lock (m_avatars)
148 { 271 {
149 if (m_avatars.ContainsKey(agentID)) 272 if (m_avatars.ContainsKey(agentID))
150 { 273 {
151 scene.RemoveClient(agentID); 274 scene.RemoveClient(agentID, false);
152 m_avatars.Remove(agentID); 275 m_avatars.Remove(agentID);
276
277 return true;
153 } 278 }
154 } 279 }
280
281 return false;
155 } 282 }
156 283
157 public void PostInitialise() 284 public void PostInitialise()