aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs')
-rw-r--r--OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs484
1 files changed, 484 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs b/OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs
new file mode 100644
index 0000000..0135e26
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/Simulator/Avatar.cs
@@ -0,0 +1,484 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Text;
32using libsecondlife;
33using libsecondlife.Packets;
34using OpenSim.Physics.Manager;
35using OpenSim.Framework.Inventory;
36using OpenSim.Framework.Interfaces;
37using OpenSim.RegionServer.Client;
38
39using Axiom.MathLib;
40
41namespace OpenSim.RegionServer.Simulator
42{
43 public partial class Avatar : Entity
44 {
45 public static bool PhysicsEngineFlying = false;
46 public static AvatarAnimations Animations;
47 public string firstname;
48 public string lastname;
49 public ClientView ControllingClient;
50 public LLUUID current_anim;
51 public int anim_seq;
52 private static libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate;
53 private bool updateflag = false;
54 private byte movementflag = 0;
55 private List<NewForce> forcesList = new List<NewForce>();
56 private short _updateCount = 0;
57 private Axiom.MathLib.Quaternion bodyRot;
58 private LLObject.TextureEntry avatarAppearanceTexture = null;
59 private byte[] visualParams;
60 private AvatarWearable[] Wearables;
61 private LLVector3 positionLastFrame = new LLVector3(0, 0, 0);
62 private LLVector3 positionFrameBeforeLast = new LLVector3(0, 0, 0);
63
64 private int positionRoundedX = 0;
65 private int positionRoundedY = 0;
66
67 private int positionParcelHoverLocalID = -1; //Local ID of the last parcel they were over
68 private int parcelUpdateSequenceIncrement = 1;
69 private ulong m_regionHandle;
70 //private Dictionary<uint, ClientView> m_clientThreads;
71 private string m_regionName;
72 private ushort m_regionWaterHeight;
73 private bool m_regionTerraform;
74 private bool childAvatar = false;
75
76 public Avatar(ClientView TheClient, World world, string regionName, Dictionary<uint, ClientView> clientThreads, ulong regionHandle, bool regionTerraform, ushort regionWater)
77 {
78 m_world = world;
79 // m_clientThreads = clientThreads;
80 m_regionName = regionName;
81 m_regionHandle = regionHandle;
82 m_regionTerraform = regionTerraform;
83 m_regionWaterHeight = regionWater;
84
85 OpenSim.Framework.Console.MainConsole.Instance.Verbose("Avatar.cs - Loading details from grid (DUMMY)");
86 ControllingClient = TheClient;
87 localid = 8880000 + (this.m_world._localNumber++);
88 Pos = ControllingClient.startpos;
89 visualParams = new byte[218];
90 for (int i = 0; i < 218; i++)
91 {
92 visualParams[i] = 100;
93 }
94 Wearables = new AvatarWearable[13]; //should be 13 of these
95 for (int i = 0; i < 13; i++)
96 {
97 Wearables[i] = new AvatarWearable();
98 }
99 this.Wearables[0].AssetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
100 this.Wearables[0].ItemID = LLUUID.Random();
101
102 this.avatarAppearanceTexture = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
103
104 //register for events
105 ControllingClient.OnRequestWearables += new ClientView.GenericCall(this.SendOurAppearance);
106 ControllingClient.OnSetAppearance += new SetAppearance(this.SetAppearance);
107 ControllingClient.OnCompleteMovementToRegion += new ClientView.GenericCall2(this.CompleteMovement);
108 ControllingClient.OnCompleteMovementToRegion += new ClientView.GenericCall2(this.SendInitialPosition);
109 ControllingClient.OnAgentUpdate += new ClientView.GenericCall3(this.HandleAgentUpdate);
110 ControllingClient.OnStartAnim += new StartAnim(this.SendAnimPack);
111 ControllingClient.OnChildAgentStatus += new ClientView.StatusChange(this.ChildStatusChange);
112
113 }
114
115 public PhysicsActor PhysActor
116 {
117 set
118 {
119 this._physActor = value;
120 }
121 get
122 {
123 return _physActor;
124 }
125 }
126
127 public void ChildStatusChange(bool status)
128 {
129 this.childAvatar = status;
130
131 if (this.childAvatar == true)
132 {
133 this._physActor.Velocity = new PhysicsVector(0, 0, 0);
134 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
135 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
136 terse.RegionData.RegionHandle = m_regionHandle; // FIXME
137 terse.RegionData.TimeDilation = 64096;
138 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
139 terse.ObjectData[0] = terseBlock;
140 List<Avatar> avList = this.m_world.RequestAvatarList();
141 foreach (Avatar client in avList)
142 {
143 client.SendPacketToViewer(terse);
144 }
145 }
146 else
147 {
148 LLVector3 startp = ControllingClient.StartPos;
149 lock (m_world.LockPhysicsEngine)
150 {
151 this._physActor.Position = new PhysicsVector(startp.X, startp.Y, startp.Z);
152 }
153 }
154 }
155
156 public override void addForces()
157 {
158 lock (this.forcesList)
159 {
160 if (this.forcesList.Count > 0)
161 {
162 for (int i = 0; i < this.forcesList.Count; i++)
163 {
164 NewForce force = this.forcesList[i];
165 PhysicsVector phyVector = new PhysicsVector(force.X, force.Y, force.Z);
166 lock (m_world.LockPhysicsEngine)
167 {
168 this._physActor.Velocity = phyVector;
169 }
170 this.updateflag = true;
171 this.velocity = new LLVector3(force.X, force.Y, force.Z); //shouldn't really be doing this
172 // but as we are setting the velocity (rather than using real forces) at the moment it is okay.
173 }
174 for (int i = 0; i < this.forcesList.Count; i++)
175 {
176 this.forcesList.RemoveAt(0);
177 }
178 }
179 }
180 }
181
182 public static void SetupTemplate(string name)
183 {
184 FileInfo fInfo = new FileInfo(name);
185 long numBytes = fInfo.Length;
186 FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
187 BinaryReader br = new BinaryReader(fStream);
188 byte[] data1 = br.ReadBytes((int)numBytes);
189 br.Close();
190 fStream.Close();
191
192 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
193
194 SetDefaultPacketValues(objdata);
195 objdata.TextureEntry = data1;
196 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
197 objdata.PathCurve = 16;
198 objdata.ProfileCurve = 1;
199 objdata.PathScaleX = 100;
200 objdata.PathScaleY = 100;
201 objdata.ParentID = 0;
202 objdata.OwnerID = LLUUID.Zero;
203 objdata.Scale = new LLVector3(1, 1, 1);
204 objdata.PCode = 47;
205 System.Text.Encoding enc = System.Text.Encoding.ASCII;
206 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
207 pos.X = 100f;
208 objdata.ID = 8880000;
209 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
210 libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
211 //objdata.FullID=user.AgentID;
212 byte[] pb = pos.GetBytes();
213 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
214
215 Avatar.AvatarTemplate = objdata;
216 }
217
218 protected static void SetDefaultPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
219 {
220 objdata.PSBlock = new byte[0];
221 objdata.ExtraParams = new byte[1];
222 objdata.MediaURL = new byte[0];
223 objdata.NameValue = new byte[0];
224 objdata.Text = new byte[0];
225 objdata.TextColor = new byte[4];
226 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
227 objdata.JointPivot = new LLVector3(0, 0, 0);
228 objdata.Material = 4;
229 objdata.TextureAnim = new byte[0];
230 objdata.Sound = LLUUID.Zero;
231 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
232 objdata.TextureEntry = ntex.ToBytes();
233 objdata.State = 0;
234 objdata.Data = new byte[0];
235
236 objdata.ObjectData = new byte[76];
237 objdata.ObjectData[15] = 128;
238 objdata.ObjectData[16] = 63;
239 objdata.ObjectData[56] = 128;
240 objdata.ObjectData[61] = 102;
241 objdata.ObjectData[62] = 40;
242 objdata.ObjectData[63] = 61;
243 objdata.ObjectData[64] = 189;
244
245
246 }
247
248 public void CompleteMovement()
249 {
250 OpenSim.Framework.Console.MainConsole.Instance.Verbose("Avatar.cs:CompleteMovement() - Constructing AgentMovementComplete packet");
251 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
252 mov.AgentData.SessionID = this.ControllingClient.SessionID;
253 mov.AgentData.AgentID = this.ControllingClient.AgentID;
254 mov.Data.RegionHandle = this.m_regionHandle;
255 // TODO - dynamicalise this stuff
256 mov.Data.Timestamp = 1172750370;
257 mov.Data.Position = this.ControllingClient.startpos;
258 mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
259
260 ControllingClient.OutPacket(mov);
261 }
262
263 public void HandleAgentUpdate(Packet pack)
264 {
265 this.HandleUpdate((AgentUpdatePacket)pack);
266 }
267
268 public void HandleUpdate(AgentUpdatePacket pack)
269 {
270 if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY) != 0)
271 {
272 if (this._physActor.Flying == false)
273 {
274 this.current_anim = Animations.AnimsLLUUID["FLY"];
275 this.anim_seq = 1;
276 this.SendAnimPack();
277 }
278 this._physActor.Flying = true;
279
280 }
281 else
282 {
283 if (this._physActor.Flying == true)
284 {
285 this.current_anim = Animations.AnimsLLUUID["STAND"];
286 this.anim_seq = 1;
287 this.SendAnimPack();
288 }
289 this._physActor.Flying = false;
290 }
291 if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
292 {
293 Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
294 if (((movementflag & 1) == 0) || (q != this.bodyRot))
295 {
296
297 if (((movementflag & 1) == 0) && (!this._physActor.Flying))
298 {
299 this.current_anim = Animations.AnimsLLUUID["WALK"];
300 this.anim_seq = 1;
301 this.SendAnimPack();
302 }
303
304
305 //we should add a new force to the list
306 // but for now we will deal with velocities
307 NewForce newVelocity = new NewForce();
308 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
309 Axiom.MathLib.Vector3 direc = q * v3;
310 direc.Normalize();
311
312 //work out velocity for sim physics system
313 direc = direc * ((0.03f) * 128f);
314 if (this._physActor.Flying)
315 direc *= 4;
316
317 newVelocity.X = direc.x;
318 newVelocity.Y = direc.y;
319 newVelocity.Z = direc.z;
320 this.forcesList.Add(newVelocity);
321 movementflag = 1;
322 this.bodyRot = q;
323 }
324 }
325 else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_POS) != 0) && (PhysicsEngineFlying))
326 {
327 if (((movementflag & 2) == 0) && this._physActor.Flying)
328 {
329 //we should add a new force to the list
330 // but for now we will deal with velocities
331 NewForce newVelocity = new NewForce();
332 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, 1);
333 Axiom.MathLib.Vector3 direc = v3;
334 direc.Normalize();
335
336 //work out velocity for sim physics system
337 direc = direc * ((0.03f) * 128f * 2);
338 newVelocity.X = direc.x;
339 newVelocity.Y = direc.y;
340 newVelocity.Z = direc.z;
341 this.forcesList.Add(newVelocity);
342 movementflag = 2;
343 }
344 }
345 else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && (PhysicsEngineFlying))
346 {
347 if (((movementflag & 4) == 0) && this._physActor.Flying)
348 {
349 //we should add a new force to the list
350 // but for now we will deal with velocities
351 NewForce newVelocity = new NewForce();
352 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, -1);
353 //Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
354 Axiom.MathLib.Vector3 direc = v3;
355 direc.Normalize();
356
357 //work out velocity for sim physics system
358 direc = direc * ((0.03f) * 128f * 2);
359 newVelocity.X = direc.x;
360 newVelocity.Y = direc.y;
361 newVelocity.Z = direc.z;
362 this.forcesList.Add(newVelocity);
363 movementflag = 4;
364 }
365 }
366 else if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_AT_NEG) != 0)
367 {
368 Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
369 if (((movementflag & 8) == 0) || (q != this.bodyRot))
370 {
371 //we should add a new force to the list
372 // but for now we will deal with velocities
373 NewForce newVelocity = new NewForce();
374 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(-1, 0, 0);
375 Axiom.MathLib.Vector3 direc = q * v3;
376 direc.Normalize();
377
378 //work out velocity for sim physics system
379 direc = direc * ((0.03f) * 128f);
380 if (this._physActor.Flying)
381 direc *= 2;
382
383 newVelocity.X = direc.x;
384 newVelocity.Y = direc.y;
385 newVelocity.Z = direc.z;
386 this.forcesList.Add(newVelocity);
387 movementflag = 8;
388 this.bodyRot = q;
389 }
390 }
391 else
392 {
393 if (movementflag == 16)
394 {
395 movementflag = 0;
396 }
397 if ((movementflag) != 0)
398 {
399 NewForce newVelocity = new NewForce();
400 newVelocity.X = 0;
401 newVelocity.Y = 0;
402 newVelocity.Z = 0;
403 this.forcesList.Add(newVelocity);
404 movementflag = 0;
405 // We're standing still, so make it show!
406 if (this._physActor.Flying == false)
407 {
408 this.current_anim = Animations.AnimsLLUUID["STAND"];
409 this.anim_seq = 1;
410 this.SendAnimPack();
411 }
412 this.movementflag = 16;
413
414 }
415 }
416 }
417
418 //really really should be moved somewhere else (RegionInfo.cs ?)
419 public void SendRegionHandshake(World regionInfo)
420 {
421 OpenSim.Framework.Console.MainConsole.Instance.Verbose("Avatar.cs:SendRegionHandshake() - Creating empty RegionHandshake packet");
422 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
423 RegionHandshakePacket handshake = new RegionHandshakePacket();
424
425 OpenSim.Framework.Console.MainConsole.Instance.Verbose("Avatar.cs:SendRegionhandshake() - Filling in RegionHandshake details");
426 handshake.RegionInfo.BillableFactor = 0;
427 handshake.RegionInfo.IsEstateManager = false;
428 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.m_regInfo.TerrainHeightRange00;
429 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.m_regInfo.TerrainHeightRange01;
430 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.m_regInfo.TerrainHeightRange10;
431 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.m_regInfo.TerrainHeightRange11;
432 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.m_regInfo.TerrainStartHeight00;
433 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.m_regInfo.TerrainStartHeight01;
434 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.m_regInfo.TerrainStartHeight10;
435 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.m_regInfo.TerrainStartHeight11;
436 handshake.RegionInfo.SimAccess = 13;
437 handshake.RegionInfo.WaterHeight = m_regionWaterHeight;
438 uint regionFlags = 72458694;
439 if (this.m_regionTerraform)
440 {
441 regionFlags -= 64;
442 }
443 handshake.RegionInfo.RegionFlags = regionFlags;
444 handshake.RegionInfo.SimName = _enc.GetBytes(m_regionName + "\0");
445 handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
446 handshake.RegionInfo.TerrainBase0 = regionInfo.m_regInfo.TerrainBase0;
447 handshake.RegionInfo.TerrainBase1 = regionInfo.m_regInfo.TerrainBase1;
448 handshake.RegionInfo.TerrainBase2 = regionInfo.m_regInfo.TerrainBase2;
449 handshake.RegionInfo.TerrainBase3 = regionInfo.m_regInfo.TerrainBase3;
450 handshake.RegionInfo.TerrainDetail0 = regionInfo.m_regInfo.TerrainDetail0;
451 handshake.RegionInfo.TerrainDetail1 = regionInfo.m_regInfo.TerrainDetail1;
452 handshake.RegionInfo.TerrainDetail2 = regionInfo.m_regInfo.TerrainDetail2;
453 handshake.RegionInfo.TerrainDetail3 = regionInfo.m_regInfo.TerrainDetail3;
454 handshake.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37");
455
456 OpenSim.Framework.Console.MainConsole.Instance.Verbose("Avatar.cs:SendRegionHandshake() - Sending RegionHandshake packet");
457 this.ControllingClient.OutPacket(handshake);
458 }
459
460 public static void LoadAnims()
461 {
462 Avatar.Animations = new AvatarAnimations();
463 Avatar.Animations.LoadAnims();
464 }
465
466 public override void LandRenegerated()
467 {
468 Pos = new LLVector3(100.0f, 100.0f, m_world.Terrain[(int)Pos.X, (int)Pos.Y] + 50.0f);
469 }
470 }
471
472 public class NewForce
473 {
474 public float X;
475 public float Y;
476 public float Z;
477
478 public NewForce()
479 {
480
481 }
482 }
483
484}