diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 187 |
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() |