Extensive work on building, wearables, assets, inventory, attachments, serialization, etc.
Resolves #36
This commit is contained in:
@@ -1,25 +1,200 @@
|
||||
import { UUID } from '../UUID';
|
||||
|
||||
export class Avatar
|
||||
{
|
||||
constructor(private avatarKey: UUID, private firstName: string, private lastName: string)
|
||||
{
|
||||
|
||||
}
|
||||
getName(): string
|
||||
{
|
||||
return this.firstName + ' ' + this.lastName;
|
||||
}
|
||||
getFirstName(): string
|
||||
{
|
||||
return this.firstName;
|
||||
}
|
||||
getLastName(): string
|
||||
{
|
||||
return this.lastName;
|
||||
}
|
||||
getKey(): UUID
|
||||
{
|
||||
return this.avatarKey;
|
||||
}
|
||||
}
|
||||
import { AvatarQueryResult } from './AvatarQueryResult';
|
||||
import { GameObject } from './GameObject';
|
||||
import { Vector3 } from '../Vector3';
|
||||
import { Quaternion } from '../Quaternion';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { UUID } from '../UUID';
|
||||
import Timer = NodeJS.Timer;
|
||||
|
||||
export class Avatar extends AvatarQueryResult
|
||||
{
|
||||
private position: Vector3 = Vector3.getZero();
|
||||
private rotation: Quaternion = Quaternion.getIdentity();
|
||||
private title = '';
|
||||
|
||||
public onAvatarMoved: Subject<Avatar> = new Subject<Avatar>();
|
||||
public onTitleChanged: Subject<Avatar> = new Subject<Avatar>();
|
||||
public onLeftRegion: Subject<Avatar> = new Subject<Avatar>();
|
||||
public onAttachmentAdded: Subject<GameObject> = new Subject<GameObject>();
|
||||
public onAttachmentRemoved: Subject<GameObject> = new Subject<GameObject>();
|
||||
|
||||
private attachments: {[key: string]: GameObject} = {};
|
||||
|
||||
static fromGameObject(obj: GameObject): Avatar
|
||||
{
|
||||
let firstName = 'Unknown';
|
||||
let lastName = 'Avatar';
|
||||
|
||||
if (obj.NameValue['FirstName'] !== undefined)
|
||||
{
|
||||
firstName = obj.NameValue['FirstName'].value;
|
||||
}
|
||||
if (obj.NameValue['LastName'] !== undefined)
|
||||
{
|
||||
lastName = obj.NameValue['LastName'].value;
|
||||
}
|
||||
|
||||
const av = new Avatar(obj, firstName , lastName);
|
||||
if (obj.NameValue['Title'] !== undefined)
|
||||
{
|
||||
av.setTitle(obj.NameValue['Title'].value);
|
||||
}
|
||||
av.processObjectUpdate(obj);
|
||||
return av;
|
||||
}
|
||||
|
||||
constructor(private gameObject: GameObject, firstName: string, lastName: string)
|
||||
{
|
||||
super(gameObject.FullID, firstName, lastName);
|
||||
const objs: GameObject[] = this.gameObject.region.objects.getObjectsByParent(gameObject.ID);
|
||||
for (const attachment of objs)
|
||||
{
|
||||
this.gameObject.region.clientCommands.region.resolveObject(attachment, true, false).then(() =>
|
||||
{
|
||||
this.addAttachment(attachment);
|
||||
}).catch((err) =>
|
||||
{
|
||||
console.error('Failed to resolve attachment for avatar');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setTitle(newTitle: string)
|
||||
{
|
||||
if (newTitle !== this.title)
|
||||
{
|
||||
this.title = newTitle;
|
||||
this.onTitleChanged.next(this);
|
||||
}
|
||||
}
|
||||
|
||||
getTitle(): string
|
||||
{
|
||||
return this.title;
|
||||
}
|
||||
|
||||
getPosition(): Vector3
|
||||
{
|
||||
return new Vector3(this.position);
|
||||
}
|
||||
|
||||
getRotation(): Quaternion
|
||||
{
|
||||
return new Quaternion(this.rotation);
|
||||
}
|
||||
|
||||
processObjectUpdate(obj: GameObject)
|
||||
{
|
||||
if (obj.Position !== undefined && obj.Rotation !== undefined)
|
||||
{
|
||||
this.setGeometry(obj.Position, obj.Rotation);
|
||||
}
|
||||
if (obj.NameValue['Title'] !== undefined)
|
||||
{
|
||||
this.setTitle(obj.NameValue['Title'].value);
|
||||
}
|
||||
}
|
||||
|
||||
setGeometry(position: Vector3, rotation: Quaternion)
|
||||
{
|
||||
const oldPosition = this.position;
|
||||
const oldRotation = this.rotation;
|
||||
|
||||
this.position = new Vector3(position);
|
||||
this.rotation = new Quaternion(rotation);
|
||||
|
||||
const rotDist = new Quaternion(this.rotation).angleBetween(oldRotation);
|
||||
if (Vector3.distance(position, oldPosition) > 0.0001 || rotDist > 0.0001)
|
||||
{
|
||||
this.onAvatarMoved.next(this);
|
||||
}
|
||||
}
|
||||
|
||||
leftRegion()
|
||||
{
|
||||
this.onLeftRegion.next(this);
|
||||
}
|
||||
|
||||
getAttachment(itemID: UUID)
|
||||
{
|
||||
if (this.attachments[itemID.toString()] !== undefined)
|
||||
{
|
||||
return this.attachments[itemID.toString()];
|
||||
}
|
||||
throw new Error('Attachment not found');
|
||||
}
|
||||
|
||||
waitForAttachment(itemID: UUID | string, timeout: number = 30000)
|
||||
{
|
||||
return new Promise<GameObject>((resolve, reject) =>
|
||||
{
|
||||
if (typeof itemID === 'string')
|
||||
{
|
||||
itemID = new UUID(itemID);
|
||||
}
|
||||
try
|
||||
{
|
||||
const attach = this.getAttachment(itemID);
|
||||
resolve(attach);
|
||||
}
|
||||
catch (ignore)
|
||||
{
|
||||
let subs: Subscription | undefined = undefined;
|
||||
let timr: Timer | undefined = undefined;
|
||||
subs = this.onAttachmentAdded.subscribe((obj: GameObject) =>
|
||||
{
|
||||
if (obj.itemID.equals(itemID))
|
||||
{
|
||||
if (subs !== undefined)
|
||||
{
|
||||
subs.unsubscribe();
|
||||
subs = undefined;
|
||||
}
|
||||
if (timr !== undefined)
|
||||
{
|
||||
clearTimeout(timr);
|
||||
timr = undefined;
|
||||
}
|
||||
resolve(obj);
|
||||
}
|
||||
});
|
||||
timr = setTimeout(() =>
|
||||
{
|
||||
if (subs !== undefined)
|
||||
{
|
||||
subs.unsubscribe();
|
||||
subs = undefined;
|
||||
}
|
||||
if (timr !== undefined)
|
||||
{
|
||||
clearTimeout(timr);
|
||||
timr = undefined;
|
||||
}
|
||||
reject(new Error('WaitForAttachment timed out'));
|
||||
}, timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addAttachment(obj: GameObject)
|
||||
{
|
||||
if (obj.itemID !== undefined)
|
||||
{
|
||||
this.attachments[obj.itemID.toString()] = obj;
|
||||
this.onAttachmentAdded.next(obj);
|
||||
}
|
||||
}
|
||||
|
||||
removeAttachment(obj: GameObject)
|
||||
{
|
||||
if (obj.NameValue['AttachItemID'])
|
||||
{
|
||||
const itemID = new UUID(obj.NameValue['AttachItemID'].value);
|
||||
if (this.attachments[itemID.toString()] !== undefined)
|
||||
{
|
||||
this.onAttachmentRemoved.next(obj);
|
||||
delete this.attachments[itemID.toString()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user