[DataContract]
[EntityType]
[AssetSelector(AssetTypeName = "Entity", FilterType = typeof(EntityBase))]
[ContextMenuAction(MenuItemName = "Activate Action", ImageKey = "Play",
Order = 2, GetDropDownItemsMethod = "CreateActionsMenu", Visibility = ContextMenuActionVisibility.Scene)]
[ContextMenuAction(MenuItemName = "Deactivate Action", ImageKey = "Stop",
Order = 3, GetDropDownItemsMethod = "CreateActivatedActionsMenu", Visibility =
ContextMenuActionVisibility.Scene)]
[ContextMenuAction(MenuItemName = "Add New Action", ActionMethod = "AddNewAction",
ImageKey = "AIAction", Order = 4, ImageKey="ActiveBrush")]
[ContextMenuAction(MenuItemName = "Add New Event Trigger", ActionMethod =
"AddNewEventTrigger", ImageKey = "Trigger", Order = 5)]
[ContextMenuAction(MenuItemName = "Add New Ability", ActionMethod =
"AddNewAbility", ImageKey = "Ability", Order = 6)]
public class EntityBase : ActivatedComponent, IComponentOwner,
IFixedAttributeProvider, IActivated, Assets.IDetachmentSite, IAssetItem,
IEditableDesignObject
{
#region "Context Menu Actions and other logic for Design"
private IEnumerable<ContextMenuActionAttribute> CreateActionsMenu()
{
var result = new List<ContextMenuActionAttribute>();
int commandNum = 0;
foreach (var item in Components)
{
var action = item as ActionBase;
if (action == null)
continue;
var menuItem = new ContextMenuActionAttribute
{
MenuItemName = action.NameID,
Action = action.Activate,
ImageKey = "Play",
Order = commandNum++
};
result.Add(menuItem);
}
return result;
}
private IEnumerable<ContextMenuActionAttribute> CreateActivatedActionsMenu()
{
var result = new List<ContextMenuActionAttribute>();
int commandNum = 0;
foreach (var item in Components)
{
var action = item as ActionBase;
if (action == null)
continue;
if (!action.IsActive)
continue;
var menuItem = new ContextMenuActionAttribute
{
MenuItemName = action.NameID,
Action = action.Deactivate,
ImageKey = "Stop",
Order = commandNum++
};
result.Add(menuItem);
}
return result;
}
ComponentContainerProxy<object> _proxyForActions;
[PropertyCategory, Browsable]
[ComponentList(ShowFolder = false, ShowComponentGroupFolders = true, AreItemNamesUnique = true, UserLevel = UserLevel.Normal)]
public ComponentContainerProxy<object> Actions
{
get
{
if (_proxyForActions == null && Components != null)
_proxyForActions = new ComponentContainerProxy<object>(Components, obj => obj is ActionBase);
return _proxyForActions;
}
}
[Button]
[FirstProperty]
[Category("Actions"), DisplayName("Add New Action")]
private bool EditorAddNewAction
{
get { return true; }
set { AddNewAction(); }
}
[ReflectionUsed]
private void AddNewAction()
{
IAssetSelectorService assetSelector;
if (App.Services.HasService(out assetSelector))
{
var action = assetSelector.Show<ActionBase>(TypeConstraint.Create<ActionBase>(),
"Select Action...", true, InstancingMode.Instanced);
if (action != null)
{
AddAction(action);
IObjectSelectionService selectionService;
if (App.Services.HasService(out selectionService))
selectionService.SelectObjects(SelectionContext.WorldExplorer, new object[] { action });
BaseWorldApplication.NotifyComponentOwnerNeedsUpdating(this);
}
}
}
[Button]
[FirstProperty]
[Category("Actions"), DisplayName("Add New Event Trigger")]
private bool EditorAddNewEventTrigger
{
get { return true; }
set { AddNewEventTrigger(); }
}
[ReflectionUsed]
privatevoid AddNewEventTrigger()
{
IAssetSelectorService assetSelector;
if (App.Services.HasService(out assetSelector))
{
var evnt = assetSelector.Show<BaseEvent>(TypeConstraint.Create<BaseEvent>(),
"Select Event Trigger...", true, InstancingMode.Instanced);
if (evnt != null)
{
var trigger = new Trigger(evnt.Name + "Trigger", evnt);
AddAction(trigger);
IObjectSelectionService selectionService;
if (App.Services.HasService(out selectionService))
selectionService.SelectObjects(SelectionContext.WorldExplorer, new object[] { trigger });
BaseWorldApplication.NotifyComponentOwnerNeedsUpdating(this);
}
}
}
ComponentContainerProxy<object> _proxyForAbilities;
[PropertyCategory, Browsable]
[ComponentList(ShowFolder = false, ShowComponentGroupFolders = true, AreItemNamesUnique = true, UserLevel = UserLevel.Advanced)]
public ComponentContainerProxy<object> Abilities
{
get
{
if (_proxyForAbilities == null && Components != null)
_proxyForAbilities = new ComponentContainerProxy<object>(Components, obj => obj is Ability);
return _proxyForAbilities;
}
}
[Button]
[FirstProperty]
[Category("Abilities"), DisplayName("Add New Ability")]
private bool EditorAddNewAbility
{
get { return true; }
set { AddNewAbility(); }
}
[ReflectionUsed]
private void AddNewAbility()
{
IAssetSelectorService assetSelector;
if (App.Services.HasService(out assetSelector))
{
var ability = assetSelector.Show<Ability>(TypeConstraint.Create<Ability>(),
"Select Ability...", true, InstancingMode.Instanced);
if (ability != null)
{
Set(ability.ComponentTypeKey, ability);
IObjectSelectionService selectionService;
if (App.Services.HasService(out selectionService))
selectionService.SelectObjects(SelectionContext.WorldExplorer, new object[] { ability });
BaseWorldApplication.NotifyComponentOwnerNeedsUpdating(this);
}
}
}
static EntityBase()
{
...
AssetIconRegistry.AddIcon("ActiveBrush", Resources.LineColorHS);
AssetIconRegistry.AddIcon("InactiveBrush", Resources.Paintbrush2);
}
#endregion
}
using System;
using System.Collections.Generic;
using Visual3D.Demo.Actors;
using System.Runtime.Serialization;
using Visual3D.Design;
using Visual3D.Graphics3D.Animations;
using Microsoft.Xna.Framework;
using Visual3D.Physics;
using Visual3D.Scripting.Behaviors;
using Visual3D.Demo.SampleParticles;
using Visual3D.Scripting.Actions;
namespace Visual3D.Demo
{
[DataContract]
[DisplayName("Lizardman")]
[ContextMenuAction(ActionMethod="AddFire", MenuItemName = "Add Torch")] //shown in both toolset for developers and in-game context menu for players
[DesignAction(ActionMethod="RemoveFire", MenuItemName = "Remove Torch")] //shown only in toolset context menu right click context menu in the toolset
[UserAction(ActionMethod="RemoveFire", MenuItemName = "Drop Torch")] //shown only in in-game context menu for players
public class NewLizardman : CharacterBase
{
protected override int RequiredVersion
{
get { return base.RequiredVersion + 2; }
}
public NewLizardman()
{
}
protected override void OnConstructed()
{
base.OnConstructed();
ModelName = "Lizardman.mesh";
Model.CameraFocusOffset = new Vector3(0, 2, 0); // Need to save model.
var aset = Get<AnimationSet>();
if (aset != null)
{
aset.AllowBlending = true;
float animSpeed = 0.7f;
float runSpeed = 7.0f;
aset.ConfigureAnimations(true,
new Animation(AvatarCommands.Action1, "attack1", animSpeed, null, false),
new Animation(AvatarCommands.MoveForward, "run", animSpeed, new Acceleration.Linear(Vector3.UnitZ, runSpeed, 0, 0.05f, true)),
new Animation(AvatarCommands.MoveBackward, "run", -0.7f * animSpeed, new Acceleration.Linear(Vector3.UnitZ, -runSpeed, 0, 0.05f, true)),
new Animation(AvatarCommands.MoveLeft, "run", animSpeed, new Acceleration.Linear(Vec3.UnitX, 0.5f * runSpeed, 0, 0.05f, true)),
new Animation(AvatarCommands.MoveRight, "run", animSpeed, new Acceleration.Linear(Vec3.MinusUnitX, 0.5f * runSpeed, 0, 0.05f, true)),
new Animation(AvatarCommands.Idle, "idle", 1.0f, null),
new Animation(AvatarCommands.Jump, "stilljump", 1.0f, null, false, false)
);
}
ReplaceAction(Acceleration.CreateSpinYawFixed(Mobile.MotionName.Yaw, 2.0f, 0, 0.4f));
ReplaceAction(AvatarCommands.Action1, new Parallel(SuccessPolicy.One, new ActionBase[] {
new ActivationLimiter(1, new Delay(Units.msec(600), new WeaponAttack())),
new Animate(AvatarCommands.Action1)
}));
var aic = InputController as ActorInputController;
if (aic != null)
aic.DeactivateAction1IfMouseButtonReleased = false;
var inv = Get<Inventory>();
inv.MainWeapon = new ColdSteel()
{
//DamageDistance = 2,
Damage = 5
};
var combatant = Get<Combatant>();
combatant.AttackInterval = 1000;
var es = Get<ExplosionSupport>();
es.BodyMaterial = MaterialMakeupType.Flesh;
GetOrCreateDamagedTrigger();
}
public override void OnModelLoaded()
{
base.OnModelLoaded();
var mobile = GetOrCreate<Mobile, HumanoidMobile>();
mobile.ForwardMotionDegreesCutoff = 20f;
mobile.MinScaleForForwardMotion = 0f;
Vector3 size = (MathUtil.GetSize(Spatial.WorldBoundingBox));
size.Y = 0;
float min = 0.2f * size.Length();
mobile.LockOnDistanceRange = new FloatRange(min * min, min * min * 5f);
}
// for deserializarion
private void Damage(object ignoredArgs)
{
}
///<summary>Gets/Sets if this Lizardman has Fire at the end of his Spear.</summary>
[DataMember]
[Button, DisplayName("Has Torch"), Position(0), Category(PropertyCategoryName.Attachments)]
public bool HasFire
{
get { return (GetFire() != null); }
set
{
if (HasFire == value) return; // no change
if (value)
AddFire();
else
RemoveFire();
}
}
[Button, DisplayName("Add Torch"), Position(1), Category(PropertyCategoryName.Attachments)]
public bool AddTorch { get { return false; } set { AddFire(); } }
[Button, DisplayName("Remove Torch"), Position(2), Category(PropertyCategoryName.Attachments)]
public bool RemoveTorch { get { return false; } set { AddFire(); } }
const string MountPointName = "Stick";
[ReflectionUsed]
private Fire GetFire()
{
if (Actor == null)
return null;
var attachment = Actor.GetAttachment(MountPointName);
if (attachment != null)
return attachment.AttachedObject as Fire;
return null;
}
[ReflectionUsed]
//though ReflectionUsedAttribute is not required, its a good idea to use it to comment your method, especially if private, so its clear to others that it shouldn't be removed even if not used anywhere in the code
private void RemoveFire()
{
if (!IsInitialized)
return;
var fire = GetFire();
if (fire != null)
{
Actor.DetachObjectFromMountPoint(MountPointName);
fire.Dispose();
fire = null;
}
}
private void AddFire()
{
RemoveFire();
if (!IsInitialized)
return;
Fire fire = new Fire(Name + " Fire");
fire.IsLightSource = true;
fire.PrepareForUse();
Actor.AttachObjectToMountPoint(MountPointName, fire);
}
}
}