public ItemBox(ThingBlock block, ThingDefinition def, string _itemName) : base(block, def) { LKernel.GetG<CollisionReporter>().AddEvent(PonykartCollisionGroups.Karts, PonykartCollisionGroups.Default, OnCol); //contents = LKernel.GetG<ItemManager>().SpawnItem(null, _itemName); itemName = _itemName; }
/// <summary> /// For sounds! /// </summary> /// <param name="lthing">The Thing this component is attached to</param> /// <param name="template">The template from the Thing</param> /// <param name="block">The block we're creating this component from</param> public SoundComponent(LThing lthing, ThingBlock template, SoundBlock block) { Name = block.GetStringProperty("name", template.ThingName); owner = lthing; var soundMain = LKernel.GetG<SoundMain>(); ISoundSource source = soundMain.GetSource(block.GetStringProperty("File", null)); bool looping = block.GetBoolProperty("looping", true); bool sfx = block.GetBoolProperty("SpecialEffects", false); relativePosition = block.GetVectorProperty("position", Vector3.ZERO); bool startPaused = block.GetBoolProperty("StartPaused", true); Sound = soundMain.Play3D(source, relativePosition, looping, startPaused, sfx); if(Sound != null) { Sound.PlaybackSpeed = block.GetFloatProperty("Speed", 1); float volume; if (block.FloatTokens.TryGetValue("volume", out volume)) Sound.Volume = volume; Sound.MinDistance = block.GetFloatProperty("mindistance", soundMain.Engine.Default3DSoundMinDistance); // TODO: effects, if we end up using any of them Update(); Sound.Paused = false; } soundMain.AddSoundComponent(this); }
/// <summary> /// For ribbons! /// </summary> /// <param name="lthing">The Thing this component is attached to</param> /// <param name="template">The template from the Thing</param> /// <param name="block">The block we're creating this component from</param> public RibbonComponent(LThing lthing, ThingBlock template, RibbonBlock block) { ID = IDs.Incremental; var sceneMgr = LKernel.GetG<SceneManager>(); Name = block.GetStringProperty("name", template.ThingName); // if ribbons are disabled, don't bother creating anything if (!Options.GetBool("Ribbons")) return; Ribbon = LKernel.GetG<SceneManager>().CreateRibbonTrail(Name + ID + "Ribbon"); // set up some properties Ribbon.SetMaterialName(block.GetStringProperty("material", "ribbon")); Ribbon.TrailLength = block.GetFloatProperty("length", 5f); Ribbon.MaxChainElements = (uint) block.GetFloatProperty("elements", 10f); Ribbon.SetInitialWidth(0, block.GetFloatProperty("width", 1f)); Ribbon.SetInitialColour(0, block.GetQuatProperty("colour", new Quaternion(1, 1, 1, 1)).ToColourValue()); Ribbon.SetColourChange(0, block.GetQuatProperty("colourchange", new Quaternion(0, 0, 0, 3)).ToColourValue()); Ribbon.SetWidthChange(0, block.GetFloatProperty("widthchange", 1f)); // attach it to the node RibbonNode = LKernel.GetG<SceneManager>().RootSceneNode.CreateChildSceneNode(Name + ID + "RibbonNode"); TrackedRibbonNode = lthing.RootNode.CreateChildSceneNode(Name + ID + "TrackedRibbonNode"); Ribbon.AddNode(TrackedRibbonNode); RibbonNode.AttachObject(Ribbon); TrackedRibbonNode.Position = block.GetVectorProperty("position", null); }
public Player(LevelChangedEventArgs eventArgs, int id, bool isComputerControlled) { // don't want to create a player if it's ID isn't valid if (id < 0 || id >= Settings.Default.NumberOfPlayers) throw new ArgumentOutOfRangeException("id", "ID number specified for kart spawn position is not valid!"); Launch.Log("[Loading] Player with ID " + id + " created"); this.IsComputerControlled = isComputerControlled; // set up the spawn position/orientation Vector3 spawnPos = eventArgs.NewLevel.Definition.GetVectorProperty("KartSpawnPosition" + id, null); Quaternion spawnOrient = eventArgs.NewLevel.Definition.GetQuatProperty("KartSpawnOrientation" + id, Quaternion.IDENTITY); ThingBlock block = new ThingBlock("TwiCutlass", spawnPos, spawnOrient); string driverName, kartName; switch (eventArgs.Request.CharacterNames[id]) { case "Twilight Sparkle": driverName = "Twilight"; kartName = "TwiCutlass"; break; case "Rainbow Dash": driverName = "RainbowDash"; kartName = "DashJavelin"; break; case "Applejack": driverName = "Applejack"; kartName = "AJKart"; break; case "Rarity": driverName = "Rarity"; kartName = "TwiCutlass"; break; case "Fluttershy": driverName = "Fluttershy"; kartName = "TwiCutlass"; break; case "Pinkie Pie": driverName = "PinkiePie"; kartName = "TwiCutlass"; break; default: throw new ArgumentException("Invalid character name!", "eventArgs"); } Kart = LKernel.GetG<Spawner>().SpawnKart(kartName, block); Driver = LKernel.GetG<Spawner>().SpawnDriver(driverName, block); Driver.AttachToKart(Kart, Vector3.ZERO); Kart.Player = this; Driver.Player = this; Character = eventArgs.Request.CharacterNames[id]; Kart.OwnerID = id; ID = id; }
/// <summary> /// Adds all of the geometry used by a model component to the static geometry. /// This is used by the ModelComponent. /// </summary> public void Add(ModelComponent mc, ThingBlock template, ModelBlock block, ThingDefinition def) { // if the model detail option is low and this model wants imposters, don't even make any static geometry of it if (Options.ModelDetail == ModelDetailOption.Low) { if (def.GetBoolProperty("Imposters", false)) return; } var sceneMgr = LKernel.GetG<SceneManager>(); string meshName = block.GetStringProperty("mesh", null); // map region goes first string sgeomName = template.GetStringProperty("MapRegion", "(Default)"); // static group can override map region sgeomName = block.GetStringProperty("StaticGroup", sgeomName); Entity ent; // get our entity if it already exists if (!ents.TryGetValue(meshName, out ent)) { // getting the entity was not successful, so we have to create it ent = sceneMgr.CreateEntity(meshName + mc.ID, meshName); string material; if (block.StringTokens.TryGetValue("material", out material)) ent.SetMaterialName(material); ents.Add(meshName, ent); } Vector3 pos; // two ways to get the position // inherit it from the lthing, the default (if we were using nodes, this would be the default too) if (block.GetBoolProperty("InheritOrientation", true)) { pos = (mc.Owner.SpawnOrientation * block.GetVectorProperty("position", Vector3.ZERO)) + template.VectorTokens["position"]; } // or we can choose not to inherit it for whatever reason else { pos = block.GetVectorProperty("position", Vector3.ZERO) + template.VectorTokens["position"]; } Quaternion orient = block.GetQuatProperty("orientation", Quaternion.IDENTITY) * template.GetQuatProperty("orientation", Quaternion.IDENTITY); Vector3 sca = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); StaticGeometry sg; if (!sgeoms.TryGetValue(sgeomName, out sg)) { sg = LKernel.GetG<SceneManager>().CreateStaticGeometry(sgeomName); sg.RegionDimensions = regionDimensions; sg.RenderingDistance = 300 / 5f; sgeoms.Add(sgeomName, sg); } sg.AddEntity(ent, pos, orient, sca); }
public TwiCutlass(ThingBlock block, ThingDefinition def) : base(block, def) { // sounds soundMain = LKernel.GetG<SoundMain>(); idleSound = SoundComponents[0].Sound; fullSound = SoundComponents[1].Sound; // convert from linear velocity to KPH topSpeedKmHour = DefaultMaxSpeed * 3.6f; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
public void Add(ModelComponent mc, ThingBlock template, ModelBlock block, ThingDefinition def) { // if the model detail option is low and this model wants imposters, don't even make any instanced geometry of it if (Options.ModelDetail == ModelDetailOption.Low) { if (def.GetBoolProperty("Imposters", false)) return; } var sceneMgr = LKernel.GetG<SceneManager>(); string meshName = block.GetStringProperty("mesh", null); string mapRegion = template.GetStringProperty("MapRegion", string.Empty); string key = mapRegion + meshName; // create our entity if it doesn't exist if (!ents.ContainsKey(key)) { Entity ent = sceneMgr.CreateEntity(mc.Name + mc.ID, meshName); ent.SetMaterialName(block.GetStringProperty("Material", string.Empty)); // then add it to our dictionary ents.Add(key, ent); } // get our transforms Vector3 pos; // two ways to get the position // inherit it from the lthing, the default (if we were using nodes, this would be the default too) if (block.GetBoolProperty("InheritOrientation", true)) { pos = (mc.Owner.SpawnOrientation * block.GetVectorProperty("position", Vector3.ZERO)) + template.VectorTokens["position"]; } // or we can choose not to inherit it for whatever reason else { pos = block.GetVectorProperty("position", Vector3.ZERO) + template.VectorTokens["position"]; } Quaternion orient = block.GetQuatProperty("orientation", Quaternion.IDENTITY) * template.GetQuatProperty("orientation", Quaternion.IDENTITY); Vector3 sca = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); // put them in one class Transform trans = new Transform { Position = pos, Orientation = orient, Scale = sca, }; // if the transforms dictionary doesn't contain the mesh yet, add a new one if (!transforms.ContainsKey(key)) { transforms.Add(key, new List<Transform>()); } // then put our transform into the dictionary transforms[key].Add(trans); }
public Kart(ThingBlock block, ThingDefinition def) : base(block, def) { DefaultMaxSpeed = MaxSpeed = def.GetFloatProperty("maxspeed", 180f); MaxReverseSpeed = def.GetFloatProperty("maxreversespeed", 4f); MaxSpeedSquared = MaxSpeed * MaxSpeed; MaxReverseSpeedSquared = MaxReverseSpeed * MaxReverseSpeed; IsInAir = false; FrontDriftAngle = new Degree(def.GetFloatProperty("FrontDriftAngle", 46)).ValueRadians; BackDriftAngle = new Degree(def.GetFloatProperty("BackDriftAngle", 55)).ValueRadians; DriftTransitionAngle = new Degree(def.GetFloatProperty("DriftTransitionAngle", 40)); }
public Derpy(ThingBlock block, ThingDefinition def) : base(block, def) { bodyComponent = ModelComponents[0]; flagComponent = ModelComponents[1]; startLightComponent = ModelComponents[2]; bodyFacing = new Euler(0, 0, 0); neckFacing = new Euler(0, 0, 0); Skeleton skeleton = bodyComponent.Entity.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; blinkState = bodyComponent.Entity.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1f; blinkState.AddTime(ID); neckBone = skeleton.GetBone("Neck"); neckBone.SetManuallyControlled(true); foreach (var state in bodyComponent.Entity.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckBone.Handle, 0f); } neckBone.InheritOrientation = false; blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); LKernel.GetG<AnimationManager>().Add(blinkState); interpNode = LKernel.GetG<SceneManager>().RootSceneNode.CreateChildSceneNode("DerpyInterpNode" + ID, Vector3.ZERO); anim = DerpyAnimation.Hover1; }
/// <summary> /// Constructor woo! /// </summary> /// <param name="template"> /// This is the part that comes from the .muffin file (if we used one) or somewhere else in the program. It has basic information needed for constructing this /// lthing, such as where it should be in the world, its rotation, etc. /// </param> /// <param name="def"> /// This is the part that comes from the .thing file. It's got all of the properties that specifies what this lthing is, what it should look like, and /// information about all of its components. /// </param> public LThing(ThingBlock template, ThingDefinition def) { ID = IDs.Incremental; Name = template.ThingName; // get our three basic transforms SpawnPosition = template.GetVectorProperty("position", null); SpawnOrientation = template.GetQuatProperty("orientation", Quaternion.IDENTITY); if (SpawnOrientation == Quaternion.IDENTITY) SpawnOrientation = template.GetVectorProperty("rotation", Vector3.ZERO).DegreeVectorToGlobalQuaternion(); SpawnScale = template.GetVectorProperty("scale", Vector3.UNIT_SCALE); // and start setting up this thing! PreSetup(template, def); SetupMogre(template, def); InitialiseComponents(template, def); RootNode.Position = SpawnPosition; RootNode.Orientation = SpawnOrientation; // only scale up the root node if it doesn't have any physics things attached - bullet really does not like scaling. // Need a few variations of identical objects with different scales? Gonna have to make different .things for them. // Though it might be easier to just have one general .thing for them, and all it does is run a script that randomly // gets one of the others. if (ShapeComponents == null) RootNode.Scale(SpawnScale); RootNode.SetInitialState(); PostInitialiseComponents(template, def); SetupPhysics(template, def); // get our script token and run it, if it has one and if this thing was created on the fly instead // of through a .muffin file string script; if (def.StringTokens.TryGetValue("script", out script)) { this.Script = script; RunScript(); } DisposeIfStaticOrInstanced(def); }
public DashJavelin(ThingBlock block, ThingDefinition def) : base(block, def) { ModelComponent chassis = ModelComponents[0]; // first get rid of the existing animation blender it creates automatically LKernel.GetG<AnimationManager>().Remove(chassis.AnimationBlender); chassis.AnimationBlender = null; Entity chassisEnt = chassis.Entity; // get our two animation states jetMax = chassisEnt.GetAnimationState("JetMax"); jetMax.Enabled = true; jetMax.Weight = 0f; jetMin = chassisEnt.GetAnimationState("JetMin"); jetMin.Enabled = true; jetMin.Weight = 1f; // we want the two animations to blend together, not add to each other chassisEnt.Skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_AVERAGE; jetRibbon = RibbonComponents[0].Ribbon; // sounds soundMain = LKernel.GetG<SoundMain>(); idleSound = SoundComponents[0].Sound; fullSound = SoundComponents[1].Sound; revDownSound = soundMain.GetSource("RD_Kart_Rev_Down.ogg"); revUpSound = soundMain.GetSource("RD_Kart_Rev_Up.ogg"); // convert from linear velocity to KPH topSpeedKmHour = DefaultMaxSpeed * 3.6f; idleState = true; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
/// <summary> /// Woo billboards! These are pretty dissimilar from ogre entities - they only have a size and material, and no mesh or anything /// </summary> /// <param name="lthing">The Thing this component is attached to</param> /// <param name="template">The template from the Thing</param> /// <param name="block">The block we're creating this component from</param> public BillboardSetComponent(LThing lthing, ThingBlock template, BillboardSetBlock block) { ID = IDs.Incremental; Name = block.GetStringProperty("name", template.ThingName); var sceneMgr = LKernel.GetG<SceneManager>(); // set it up BillboardSet = sceneMgr.CreateBillboardSet(Name + ID + "BillboardSet", (uint) block.BillboardBlocks.Count); BillboardSet.SetMaterialName(block.GetStringProperty("material", null)); BillboardSet.CastShadows = false; //block.GetBoolProperty("CastsShadows", false); BillboardSet.SetDefaultDimensions(block.GetFloatProperty("width", 1), block.GetFloatProperty("height", 1)); // billboard type ThingEnum type = block.GetEnumProperty("Type", ThingEnum.Point); switch (type) { case ThingEnum.Point: BillboardSet.BillboardType = BillboardType.BBT_POINT; break; case ThingEnum.OrientedCommon: BillboardSet.BillboardType = BillboardType.BBT_ORIENTED_COMMON; break; case ThingEnum.OrientedSelf: BillboardSet.BillboardType = BillboardType.BBT_ORIENTED_SELF; break; case ThingEnum.PerpendicularCommon: BillboardSet.BillboardType = BillboardType.BBT_PERPENDICULAR_COMMON; break; case ThingEnum.PerpendicularSelf: BillboardSet.BillboardType = BillboardType.BBT_PERPENDICULAR_SELF; break; } Vector3 vec; if (block.VectorTokens.TryGetValue("upvector", out vec)) BillboardSet.CommonUpVector = vec; // sort transparent stuff BillboardSet.SortingEnabled = block.GetBoolProperty("Sort", true); // make them point the right way BillboardSet.CommonDirection = block.GetVectorProperty("Direction", Vector3.UNIT_Y); // rotation type BillboardSet.BillboardRotationType = block.GetBoolProperty("UseVertexRotation", false) ? BillboardRotationType.BBR_VERTEX : BillboardRotationType.BBR_TEXCOORD; // origin ThingEnum originToken = block.GetEnumProperty("Origin", ThingEnum.Center); switch (originToken) { case ThingEnum.TopLeft: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_TOP_LEFT; break; case ThingEnum.TopCenter: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_TOP_CENTER; break; case ThingEnum.TopRight: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_TOP_RIGHT; break; case ThingEnum.CenterLeft: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_CENTER_LEFT; break; case ThingEnum.Center: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_CENTER; break; case ThingEnum.CenterRight: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_CENTER_RIGHT; break; case ThingEnum.BottomLeft: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_BOTTOM_LEFT; break; case ThingEnum.BottomCenter: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_BOTTOM_CENTER; break; case ThingEnum.BottomRight: BillboardSet.BillboardOrigin = BillboardOrigin.BBO_BOTTOM_RIGHT; break; } BillboardSet.RenderingDistance = block.GetFloatProperty("RenderingDistance", 120); // texture coordinates Quaternion rectQ; if (block.QuatTokens.TryGetValue("texturecoords", out rectQ)) { unsafe { var rect = new FloatRect(rectQ.x, rectQ.y, rectQ.z, rectQ.w); BillboardSet.SetTextureCoords(&rect, 1); } } // stacks/slices if (block.FloatTokens.ContainsKey("texturestacks") && block.FloatTokens.ContainsKey("textureslices")) { BillboardSet.SetTextureStacksAndSlices((byte) block.GetFloatProperty("TextureStacks", 1), (byte) block.GetFloatProperty("TextureSlices", 1)); } // and then go through each billboard block and create a billboard from it foreach (BillboardBlock bbblock in block.BillboardBlocks) CreateBillboard(bbblock); // setup attachment, if it needs one if (block.GetBoolProperty("Attached", false)) { string boneName = block.GetStringProperty("AttachBone", null); int modelComponentID = (int) block.GetFloatProperty("AttachComponentID", null); Quaternion offsetQuat = block.GetQuatProperty("AttachOffsetOrientation", Quaternion.IDENTITY); Vector3 offsetVec = block.GetVectorProperty("AttachOffsetPosition", Vector3.ZERO); lthing.ModelComponents[modelComponentID].Entity.AttachObjectToBone(boneName, BillboardSet, offsetQuat, offsetVec); } // if not, just attach it to the root node else { Vector3 pos = block.GetVectorProperty("Position", Vector3.ZERO); SceneNode attachNode; if (pos != Vector3.ZERO) { LocalNode = lthing.RootNode.CreateChildSceneNode(pos); attachNode = LocalNode; } else { attachNode = lthing.RootNode; } attachNode.AttachObject(BillboardSet); } }
/// <summary> /// Make some nodes for us to attach wheel particles to /// </summary> protected override void PostInitialiseComponents(ThingBlock template, ThingDefinition def) { Vector3 frontleft = def.GetVectorProperty("FrontLeftWheelPosition", null); Vector3 frontright = def.GetVectorProperty("FrontRightWheelPosition", null); Vector3 backleft = def.GetVectorProperty("BackLeftWheelPosition", null); Vector3 backright = def.GetVectorProperty("BackRightWheelPosition", null); LeftParticleNode = RootNode.CreateChildSceneNode(frontleft.MidPoint(backleft)); RightParticleNode = RootNode.CreateChildSceneNode(frontright.MidPoint(backright)); }
protected virtual void PostInitialiseComponents(ThingBlock template, ThingDefinition def) { }
/// <summary> /// Sets up mogre stuff, like our root scene node /// </summary> private void SetupMogre(ThingBlock template, ThingDefinition def) { var sceneMgr = LKernel.GetG<SceneManager>(); // create our root node // need to check for map regions string mapRegion = template.GetStringProperty("MapRegion", string.Empty); if (string.IsNullOrEmpty(mapRegion)) { // no map region, continue on as normal this.RootNode = sceneMgr.RootSceneNode.CreateChildSceneNode(Name + ID); } else { string mapRegionNodeName = mapRegion + "Node"; // there is a map region, make our root node a child of a node with the region's name // first check to see if that node exists already if (sceneMgr.HasSceneNode(mapRegionNodeName)) { // if it does, just attach our node to it this.RootNode = sceneMgr.GetSceneNode(mapRegionNodeName).CreateChildSceneNode(Name + ID); } else { // if it doesn't, create it first, then attach our node to it SceneNode newSceneNode = sceneMgr.RootSceneNode.CreateChildSceneNode(mapRegionNodeName); this.RootNode = newSceneNode.CreateChildSceneNode(Name + ID); } } }
/// <summary> /// Use this method if you need some more stuff to happen before the constructor starts setting everything up. /// For example if you need to get more things out of the ThingTemplate, you can use this for that. /// </summary> protected virtual void PreSetup(ThingBlock template, ThingDefinition def) { }
private void SetupPhysics(ThingBlock template, ThingDefinition def) { // if we have no shape components then we don't set up physics if (ShapeComponents == null) return; PreSetUpBodyInfo(def); SetUpBodyInfo(def); PostSetUpBodyInfo(def); CreateBody(def); PostCreateBody(def); SetBodyUserObject(); }
public Lyra(ThingBlock block, ThingDefinition def) : base(block, def) { foreach (ModelComponent mc in ModelComponents) { if (mc.Name.EndsWith("Body")) bodyComponent = mc; else if (mc.Name.EndsWith("Mane")) maneComponent = mc; else if (mc.Name.EndsWith("Tail")) tailComponent = mc; } // make sure our animations add their weights and don't just average out. The AnimationBlender already handles averaging between two anims. Skeleton skeleton = bodyComponent.Entity.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; // set up the blink animation state with some stuff blinkState = bodyComponent.Entity.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1; blinkState.AddTime(ID); // set up all of the animation states to not use the neck bone neckbone = skeleton.GetBone("Neck"); neckbone.SetManuallyControlled(true); foreach (var state in bodyComponent.Entity.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckbone.Handle, 0f); } neckbone.InheritOrientation = false; neckFacing = new Euler(0, 0, 0); // set up a blend mask so only the eyebrow bones have any effect on the blink animation blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); // add the blink state to the animation manager so it has time added to it LKernel.GetG<AnimationManager>().Add(blinkState); // set up some timers to handle animation changing random = new Random(IDs.Random); animTimer = new System.Threading.Timer(new TimerCallback(AnimTimerTick), null, random.Next(ANIMATION_TIMESPAN_MINIMUM, ANIMATION_TIMESPAN_MAXIMUM), Timeout.Infinite); // add a bit of time to things so the animations aren't all synced at the beginning float rand = (float) random.NextDouble(); bodyComponent.AnimationBlender.AddTime(rand); tailComponent.AnimationState.AddTime(rand); followKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
public Driver(ThingBlock block, ThingDefinition def) : base(block, def) { }
/// <summary> /// Shape blocks /// </summary> void ParseBlock(MuffinDefinition worldDef, RuleInstance block) { Token nameTok = (block.Children[0] as RuleInstance).Children[0] as Token; ThingBlock thingBlock = new ThingBlock(nameTok.Image, worldDef); for (int a = 2; a < block.Children.Length - 1; a++) { RuleInstance rule = block.Children[a] as RuleInstance; if (rule.Type == NodeType.Rule_Property) ParseProperty(thingBlock, rule.Children[0] as RuleInstance); } worldDef.ThingBlocks.Add(thingBlock); }
/// <summary> /// Make our components /// </summary> protected virtual void InitialiseComponents(ThingBlock template, ThingDefinition def) { // ogre stuff if (def.ModelBlocks.Count > 0) { ModelComponents = new List<ModelComponent>(def.ModelBlocks.Count); foreach (var mblock in def.ModelBlocks) ModelComponents.Add(new ModelComponent(this, template, mblock, def)); } // bullet stuff if (def.ShapeBlocks.Count > 0) { ShapeComponents = new List<ShapeComponent>(def.ShapeBlocks.Count); foreach (var sblock in def.ShapeBlocks) ShapeComponents.Add(new ShapeComponent(this, sblock)); } // ribbons if (def.RibbonBlocks.Count > 0) { RibbonComponents = new List<RibbonComponent>(def.RibbonBlocks.Count); foreach (var rblock in def.RibbonBlocks) RibbonComponents.Add(new RibbonComponent(this, template, rblock)); } // billboard sets if (def.BillboardSetBlocks.Count > 0) { BillboardSetComponents = new List<BillboardSetComponent>(def.BillboardSetBlocks.Count); foreach (var bblock in def.BillboardSetBlocks) BillboardSetComponents.Add(new BillboardSetComponent(this, template, bblock)); } // sounds if (def.SoundBlocks.Count > 0) { SoundComponents = new List<SoundComponent>(def.SoundBlocks.Count); foreach (var sblock in def.SoundBlocks) SoundComponents.Add(new SoundComponent(this, template, sblock)); } }
/// <summary> /// Creates a model component for a Thing. /// </summary> /// <param name="lthing">The Thing this component is attached to</param> /// <param name="template">The template from the Thing</param> /// <param name="block">The block we're creating this component from</param> public ModelComponent(LThing lthing, ThingBlock template, ModelBlock block, ThingDefinition def) { ID = IDs.Incremental; Owner = lthing; var sceneMgr = LKernel.GetG<SceneManager>(); Name = block.GetStringProperty("name", template.ThingName); // set these up here because static/instanced geometry might need them // position SpawnPosition = block.GetVectorProperty("position", Vector3.ZERO); // orientation SpawnOrientation = block.GetQuatProperty("orientation", Quaternion.IDENTITY); // if orientation was not found, we fall back to rotation if (SpawnOrientation == Quaternion.IDENTITY) { Vector3 rot = block.GetVectorProperty("rotation", Vector3.ZERO); if (rot != Vector3.ZERO) SpawnOrientation = rot.DegreeVectorToGlobalQuaternion(); } // scale SpawnScale = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); ThingEnum shad = block.GetEnumProperty("CastsShadows", ThingEnum.Some); // if we're static, set up the static geometry // don't set up static geometry if we want to cast shadows though, since static geometry doesn't work with shadows if ((block.GetBoolProperty("static", false) || def.GetBoolProperty("static", false)) // make static if we never want shadows && (shad == ThingEnum.None // or if the mesh has "some" shadows but we don't want any || (shad == ThingEnum.Some && Options.ShadowDetail == ShadowDetailOption.None) // or if the mesh has "many" shadows but we only want those with "some" || (shad == ThingEnum.Many && Options.ShadowDetail != ShadowDetailOption.Many))) { LKernel.GetG<StaticGeometryManager>().Add(this, template, block, def); Entity = null; } else if (block.GetBoolProperty("instanced", false) || def.GetBoolProperty("instanced", false)) { LKernel.GetG<InstancedGeometryManager>().Add(this, template, block, def); Entity = null; } // for attachments else if (block.GetBoolProperty("Attached", false)) { SetupEntity(sceneMgr, block); SetupAnimation(block); string boneName = block.GetStringProperty("AttachBone", null); int modelComponentID = (int) block.GetFloatProperty("AttachComponentID", null); Quaternion offsetQuat = block.GetQuatProperty("AttachOffsetOrientation", Quaternion.IDENTITY); Vector3 offsetVec = block.GetVectorProperty("AttachOffsetPosition", Vector3.ZERO); lthing.ModelComponents[modelComponentID].Entity.AttachObjectToBone(boneName, Entity, offsetQuat, offsetVec); } // otherwise continue as normal else { Node = lthing.RootNode.CreateChildSceneNode(Name + "Node" + ID); Node.Position = SpawnPosition; Node.Orientation = SpawnOrientation; Node.Scale(SpawnScale); Node.InheritScale = block.GetBoolProperty("InheritScale", true); Node.InheritOrientation = block.GetBoolProperty("InheritOrientation", true); Node.SetInitialState(); // make our entity SetupEntity(sceneMgr, block); SetupAnimation(block); // then attach it to the node! Node.AttachObject(Entity); } }
public BackgroundPony(string bgPonyName, ThingBlock block, ThingDefinition def) : base(block, def) { AnimPose = Pose.Standing; if (bgPonyName == null) nameOfPonyCharacter = loader.GetRandomLine(); else nameOfPonyCharacter = bgPonyName; // get a line to parse string _line; if (!loader.BackgroundPonyDict.TryGetValue(nameOfPonyCharacter, out _line)) { // if the line doesn't exist, make a random one _line = loader.GetRandomLine(); Launch.Log("[WARNING] The specified background pony (" + nameOfPonyCharacter + ") does not exist, using random one instead..."); } // split up the data string[] _data = _line.Split(' '); // get our hairstyle ID number int hairstyleID = int.Parse(_data[1], culture); // set the pony type if (_data[2] == "pegasus") PonyType = Type.Pegasus; else if (_data[2] == "flyingpegasus") PonyType = Type.FlyingPegasus; else if (_data[2] == "earth") PonyType = Type.Earth; else if (_data[2] == "unicorn") PonyType = Type.Unicorn; // create nodes and stuff var sceneMgr = LKernel.Get<SceneManager>(); #region creation bodyEnt = sceneMgr.CreateEntity("BgPonyBody.mesh"); RootNode.AttachObject(bodyEnt); eyesEnt = sceneMgr.CreateEntity("BgPonyEyes.mesh"); if (PonyType == Type.Unicorn) hornEnt = sceneMgr.CreateEntity("BgPonyHorn.mesh"); else if (PonyType == Type.FlyingPegasus) wingsEnt = sceneMgr.CreateEntity("BgPonyWings.mesh"); else if (PonyType == Type.Pegasus) foldedWingsEnt = sceneMgr.CreateEntity("BgPonyWingsFolded.mesh"); // create hair hairEnt = sceneMgr.CreateEntity("BgPonyHair" + hairstyleID + ".mesh"); maneEnt = sceneMgr.CreateEntity("BgPonyMane" + hairstyleID + ".mesh"); tailEnt = sceneMgr.CreateEntity("BgPonyTail" + hairstyleID + ".mesh"); // attach stuff bodyEnt.AttachObjectToBone("Eyes", eyesEnt); bodyEnt.AttachObjectToBone("Hair", hairEnt); bodyEnt.AttachObjectToBone("Mane", maneEnt); bodyEnt.AttachObjectToBone("Tail", tailEnt); if (PonyType == Type.Unicorn) bodyEnt.AttachObjectToBone("Horn", hornEnt); else if (PonyType == Type.Pegasus) bodyEnt.AttachObjectToBone("Wings", foldedWingsEnt); else if (PonyType == Type.FlyingPegasus) bodyEnt.AttachObjectToBone("Wings", wingsEnt); #endregion #region setting up colors in materials // body colour { ColourValue bodyColour = new ColourValue(float.Parse(_data[3], culture), float.Parse(_data[4], culture), float.Parse(_data[5], culture)); ColourValue bodyAOColour = new ColourValue(float.Parse(_data[6], culture), float.Parse(_data[7], culture), float.Parse(_data[8], culture)); MaterialPtr bodyMat = SetBodyPartMaterialColours("BgPony", bodyColour, bodyAOColour); bodyMat.GetTechnique(0).GetPass(1).GetTextureUnitState(1).SetTextureName(_data[18].Substring(1, _data[18].Length - 2)); bodyEnt.SetMaterial(bodyMat); // extra body parts if (PonyType == Type.Unicorn) { bodyMat = SetBodyPartMaterialColours("BgPonyHorn", bodyColour, bodyAOColour); hornEnt.SetMaterial(bodyMat); } else if (PonyType == Type.Pegasus) { bodyMat = SetBodyPartMaterialColours("BgPonyWingsFolded", bodyColour, bodyAOColour); foldedWingsEnt.SetMaterial(bodyMat); } else if (PonyType == Type.FlyingPegasus) { bodyMat = SetBodyPartMaterialColours("BgPonyWings", bodyColour, bodyAOColour); wingsEnt.SetMaterial(bodyMat); } } // eye colours { ColourValue eyeColour1 = new ColourValue(float.Parse(_data[9], culture), float.Parse(_data[10], culture), float.Parse(_data[11], culture)); ColourValue eyeColour2 = new ColourValue(float.Parse(_data[12], culture), float.Parse(_data[13], culture), float.Parse(_data[14], culture)); ColourValue eyeHighlightColour = new ColourValue(float.Parse(_data[15], culture), float.Parse(_data[16], culture), float.Parse(_data[17], culture)); MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyEyes"); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyEyes" + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyEyes" + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(0).GetFragmentProgramParameters(); ps.SetNamedConstant("TopIrisColour", eyeColour1); ps.SetNamedConstant("BottomIrisColour", eyeColour2); ps.SetNamedConstant("HighlightColour", eyeHighlightColour); newMat.GetTechnique(0).GetPass(0).SetFragmentProgramParameters(ps); } eyesEnt.SetMaterial(newMat); } // hair colours { ColourValue hairColour1 = new ColourValue(float.Parse(_data[20], culture), float.Parse(_data[21], culture), float.Parse(_data[22], culture)); ColourValue hairAOColour1 = new ColourValue(float.Parse(_data[23], culture), float.Parse(_data[24], culture), float.Parse(_data[25], culture)); // two hair colours if (bool.Parse(_data[19])) { ColourValue hairColour2 = new ColourValue(float.Parse(_data[26], culture), float.Parse(_data[27], culture), float.Parse(_data[28], culture)); ColourValue hairAOColour2 = new ColourValue(float.Parse(_data[29], culture), float.Parse(_data[30], culture), float.Parse(_data[31], culture)); MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyHair_Double_" + hairstyleID); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyHair_Double_" + hairstyleID + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyHair_Double_" + hairstyleID + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(1).GetFragmentProgramParameters(); ps.SetNamedConstant("HairColour1", hairColour1); ps.SetNamedConstant("AOColour1", hairAOColour1); ps.SetNamedConstant("HairColour2", hairColour2); ps.SetNamedConstant("AOColour2", hairAOColour2); newMat.GetTechnique(0).GetPass(1).SetFragmentProgramParameters(ps); if (int.Parse(_data[32], culture) == 2) SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour2); else if (int.Parse(_data[32], culture) == 1) SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour1); } hairEnt.SetMaterial(newMat); maneEnt.SetMaterial(newMat); tailEnt.SetMaterial(newMat); } // one colour else { MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyHair_Single_" + hairstyleID); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyHair_Single_" + hairstyleID + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyHair_Single_" + hairstyleID + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(1).GetFragmentProgramParameters(); ps.SetNamedConstant("HairColour", hairColour1); ps.SetNamedConstant("AOColour", hairAOColour1); newMat.GetTechnique(0).GetPass(1).SetFragmentProgramParameters(ps); SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour1); } hairEnt.SetMaterial(newMat); maneEnt.SetMaterial(newMat); tailEnt.SetMaterial(newMat); } } #endregion #region animation // make sure our animations add their weights and don't just average out. The AnimationBlender already handles averaging between two anims. Skeleton skeleton = bodyEnt.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; // set up the blink animation state with some stuff blinkState = bodyEnt.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1; blinkState.AddTime(ID); // set up all of the animation states to not use the neck bone neckbone = skeleton.GetBone("Neck"); neckbone.SetManuallyControlled(true); foreach (var state in bodyEnt.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckbone.Handle, 0f); } neckbone.InheritOrientation = false; neckFacing = new Euler(0, 0, 0); // set up a blend mask so only the eyebrow bones have any effect on the blink animation blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); // add the blink state to the animation manager so it has time added to it AnimationManager animMgr = LKernel.GetG<AnimationManager>(); animMgr.Add(blinkState); // set up other animated things bodyBlender = new AnimationBlender(bodyEnt); bodyBlender.Init("Stand1", true); animMgr.Add(bodyBlender); maneBlender = new AnimationBlender(maneEnt); maneBlender.Init("Stand1", true); animMgr.Add(maneBlender); tailBlender = new AnimationBlender(tailEnt); tailBlender.Init("Stand1", true); animMgr.Add(tailBlender); if (PonyType == Type.FlyingPegasus) { wingsBlender = new AnimationBlender(wingsEnt); wingsBlender.Init("Flap1", true); animMgr.Add(wingsBlender); } // set up some timers to handle animation changing animTimer = new Timer(new TimerCallback(AnimTimerTick), null, random.Next(ANIMATION_TIMESPAN_MINIMUM, ANIMATION_TIMESPAN_MAXIMUM), Timeout.Infinite); // add a bit of time to things so the animations aren't all synced at the beginning AddTimeToBodyManeAndTail(); #endregion followKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; LKernel.GetG<Root>().FrameStarted += FrameStarted; }