/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
Filename : StateManager.cs
Version : 1.0.326
Author(s) : Natalia Portillo
Component : NatiBot
Revision : r326
Last change by : Natalia Portillo
Date : 2010/01/01
--[ License ] --------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
----------------------------------------------------------------------------
Copyright (C) 2008-2014 Claunia.com
****************************************************************************/
namespace bot
{
using bot.NetCom;
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Timers;
public class StateManager
{
private Timer agentUpdateTicker;
private bool alwaysrun;
private bool away;
private UUID awayAnimationID = new UUID("fd037134-85d4-f241-72c6-4f42164fedee");
private UUID beamID;
private bool busy;
private UUID busyAnimationID = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
private SecondLifeBot client;
private bool flying;
private float followDistance = 3f;
private bool following;
private string followName = string.Empty;
private NetCommunication netcom;
private UUID pointID;
private bool pointing;
private bool sitting;
private string statusMessage;
private bool typing;
private UUID typingAnimationID = new UUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9");
public event StatusMessageChangedCallback OnStatusMessageChanged;
public StateManager(SecondLifeBot client)
{
this.client = client;
this.netcom = this.client.Netcom;
this.statusMessage = "Offline";
this.AddNetcomEvents();
this.AddClientEvents();
this.InitializeAgentUpdateTimer();
}
private void AddClientEvents()
{
this.client.Objects.AvatarUpdate += new EventHandler(Objects_AvatarUpdate);
}
void Objects_AvatarUpdate(object sender, AvatarUpdateEventArgs e)
{
if (e.Avatar != null && this.following)
{
Avatar avatar;
this.client.Network.CurrentSim.ObjectsAvatars.TryGetValue(e.Avatar.LocalID, out avatar);
if ((avatar != null) && (avatar.Name == this.followName))
{
Vector3 position;
if (client.Self.SittingOn == 0)
{
position = avatar.Position;
}
else
{
Primitive primitive;
this.client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(client.Self.SittingOn, out primitive);
if (primitive == null)
{
position = this.client.Self.SimPosition;
}
else
{
position = primitive.Position + avatar.Position;
}
}
if (Vector3.Distance(position, this.client.Self.SimPosition) > this.followDistance)
{
int num = (int)(e.Simulator.Handle >> 0x20);
int num2 = (int)(e.Simulator.Handle & 0xffffffffL);
ulong globalX = (ulong)(position.X + num);
ulong globalY = (ulong)(position.Y + num2);
this.client.Self.AutoPilotCancel();
this.client.Self.AutoPilot(globalX, globalY, position.Z);
}
}
}
}
private void AddNetcomEvents()
{
this.netcom.ClientLoginStatus += new EventHandler(this.netcom_ClientLoginStatus);
this.netcom.ClientLoggedOut += new EventHandler(this.netcom_ClientLoggedOut);
}
private void agentUpdateTicker_Elapsed(object sender, ElapsedEventArgs e)
{
this.UpdateStatus();
}
public void Follow(string name)
{
this.followName = name;
this.following = !string.IsNullOrEmpty(this.followName);
}
private void InitializeAgentUpdateTimer()
{
this.agentUpdateTicker = new Timer(500.0);
this.agentUpdateTicker.Elapsed += new ElapsedEventHandler(this.agentUpdateTicker_Elapsed);
}
private void netcom_ClientLoggedOut(object sender, EventArgs e)
{
this.agentUpdateTicker.Enabled = false;
this.typing = this.away = this.busy = false;
}
private void netcom_ClientLoginStatus(object sender, ClientLoginEventArgs e)
{
if (e.Status == LoginStatus.Success)
{
this.agentUpdateTicker.Enabled = true;
}
}
public void SetAlwaysRun(bool alwaysrun)
{
this.client.Self.Movement.AlwaysRun = alwaysrun;
this.alwaysrun = alwaysrun;
}
public void SetAway(bool away)
{
Dictionary animations = new Dictionary();
animations.Add(this.awayAnimationID, away);
this.client.Self.Animate(animations, false);
this.away = away;
}
public void SetBusy(bool busy)
{
Dictionary animations = new Dictionary();
animations.Add(this.busyAnimationID, busy);
this.client.Self.Animate(animations, false);
this.busy = busy;
}
public void SetFlying(bool flying)
{
this.flying = flying;
}
public void SetPointing(bool pointing, UUID target)
{
this.pointing = pointing;
if (pointing)
{
this.pointID = UUID.Random();
this.beamID = UUID.Random();
this.client.Self.PointAtEffect(this.client.Self.AgentID, target, Vector3d.Zero, PointAtType.Select, this.pointID);
this.client.Self.BeamEffect(this.client.Self.AgentID, target, Vector3d.Zero, new Color4(0xff, 0xff, 0xff, 0), 60f, this.beamID);
}
else if ((!this.pointID.Equals(0)) && (!this.beamID.Equals(0)))
{
this.client.Self.PointAtEffect(UUID.Zero, UUID.Zero, Vector3d.Zero, PointAtType.Select, this.pointID);
this.client.Self.BeamEffect(UUID.Zero, UUID.Zero, Vector3d.Zero, new Color4(0xff, 0xff, 0xff, 0), 0f, this.beamID);
this.pointID = UUID.Zero;
this.beamID = UUID.Zero;
}
}
public void SetSitting(bool sitting, UUID target)
{
this.sitting = sitting;
if (sitting)
{
this.client.Self.RequestSit(target, Vector3.Zero);
this.client.Self.Sit();
}
else
{
this.client.Self.Stand();
}
}
public void SetTyping(bool typing)
{
Dictionary animations = new Dictionary();
animations.Add(this.typingAnimationID, typing);
this.client.Self.Animate(animations, false);
if (typing)
{
this.client.Self.Chat(string.Empty, 0, ChatType.StartTyping);
}
else
{
this.client.Self.Chat(string.Empty, 0, ChatType.StopTyping);
}
this.typing = typing;
}
private void UpdateStatus()
{
// DISLIKE HARDCODED VALUES -.-'' by Claunia
//this.client.Self.Movement.Camera.Far = 128f;
this.client.Self.Movement.Fly = this.flying;
this.client.Self.Movement.Away = this.away;
}
public UUID AwayAnimationID
{
get
{
return this.awayAnimationID;
}
set
{
this.awayAnimationID = value;
}
}
public UUID BusyAnimationID
{
get
{
return this.busyAnimationID;
}
set
{
this.busyAnimationID = value;
}
}
public float FollowDistance
{
get
{
return this.followDistance;
}
set
{
this.followDistance = value;
}
}
public string FollowName
{
get
{
return this.followName;
}
set
{
this.followName = value;
}
}
public bool IsAway
{
get
{
return this.away;
}
}
public bool IsBusy
{
get
{
return this.busy;
}
}
public bool IsFlying
{
get
{
return this.flying;
}
}
public bool IsFollowing
{
get
{
return this.following;
}
}
public bool IsPointing
{
get
{
return this.pointing;
}
}
public bool IsSitting
{
get
{
return this.sitting;
}
}
public bool IsTyping
{
get
{
return this.typing;
}
}
public string StatusMessage
{
get
{
return this.statusMessage;
}
set
{
if (this.OnStatusMessageChanged != null)
{
this.OnStatusMessageChanged();
}
this.statusMessage = value;
}
}
public UUID TypingAnimationID
{
get
{
return this.typingAnimationID;
}
set
{
this.typingAnimationID = value;
}
}
public delegate void StatusMessageChangedCallback();
}
}