Jump to content

xEvilReeperx

Members
  • Posts

    894
  • Joined

  • Last visited

Everything posted by xEvilReeperx

  1. [EXC 10:20:09.150] XmlException: Document element did not appear. file:///C:/Program Files (x86)/Steam/steamapps/common/Kerbal Space Program/GameData/LaunchCountDown/Plugins/PluginData/LaunchCountDown/config.xml Line 1, position 1. Mono.Xml2.XmlTextReader.Read () System.Xml.XmlTextReader.Read () Mono.Xml.EntityResolvingXmlReader.Read () Mono.Xml.DTDValidatingReader.ReadContent () Mono.Xml.DTDValidatingReader.Read () Mono.Xml.Schema.XsdValidatingReader.Read () System.Xml.XmlValidatingReader.Read () System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) System.Xml.XmlDocument.ReadNode (System.Xml.XmlReader reader) System.Xml.XmlDocument.Load (System.Xml.XmlReader xmlReader) System.Xml.XmlDocument.Load (System.String filename) KSP.IO.PluginConfiguration.load () LaunchCountDown.LaunchUI.OnLoad (.ConfigNode node) PartModule.Load (.ConfigNode node) Part.AddModule (.ConfigNode node) PartLoader.ParsePart (.UrlConfig urlConfig, .ConfigNode node) PartLoader+.MoveNext () [EXC 10:20:09.159] NullReferenceException: Object reference not set to an instance of an object RenderingManager.AddToPostDrawQueue (Int32 queueSpot, .Callback drawFunction) LaunchCountDown.LaunchUI.OnStart (StartState state) Part.ModulesOnStart () Part+.MoveNext () Something appears to be wrong with LaunchCountDown's xml config
  2. @GregroxMun Here is a MM patch that simply removes this limitation: @PART[*]:HAS[@MODULE[ModuleEngines]] { @MODULE[ModuleEngines] { %shieldedCanActivate = true } } @PART[*]:HAS[@MODULE[ModuleEnginesFX]] { @MODULE[ModuleEngines] { %shieldedCanActivate = true } } Ten seconds of testing indicates it seems to work like it should. I don't know if thrusting against a fairing base results in zero thrust as my test craft's lower half promptly disintegrated attempting it so that's good enough in my book
  3. NullReferenceException: Object reference not set to an instance of an object at NearFutureElectrical.FissionReactor.GetInfo () [0x00000] in <filename unknown>:0 at PartLoader.CompilePartInfo (.AvailablePart newPartInfo, .Part part) [0x00000] in <filename unknown>:0 at PartLoader+ .MoveNext () [0x00000] in <filename unknown>:0 This is your problem. It doesn't look like NearFuture has been updated for 1.0.5 yet
  4. Depending on what you're working on, you could try my solution to this problem. I haven't had a lot of feedback on it so far but it's increased my turnaround time dramatically
  5. Sorry for being unclear. Even if the game did track interstage fairing status, sal's reference craft still would not count. Somehow the id of the interstage part has been lost inside the .craft. KSP will just blindly create the fairing mesh based on the saved cross sections and because the last one just happens to have exactly the right radius, it's interpreted as a hole. Here's a tweak of my first solution that will unshield non-vessel parts if the fairing has that hole: If you're still unsatisfied, the last thing that comes to mind would be to store the interstageID ourselves. The main disadvantage there is that it probably wouldn't retroactively apply to fairings already in flight if they too are missing that data
  6. You're right in that SA adds a fake transmitter but it's just used to capture all incoming ScienceData; transmission is then delegated to the best rated real transmitter. You might be using the version built for 1.0.4 still -- there's a patch a few posts above yours. I'm working on 2.0 still after having a little computer setback. Thank goodness for backups
  7. Yes, it's what I suspected. One or more of your vessels reference a resource called PunchCards that has no definition. It might be a legacy of an older MKS version. Find and delete all entries that look like this inside your sfs: RESOURCE { name = PunchCards amount = 0.0001 maxAmount = 200 flowState = True isTweakable = True hideFlow = False flowMode = Both } That should fix it
  8. Probably something is wrong with one of the resource definitions. If you upload the save, we might be able to track it down and fix it
  9. I honestly don't. You don't seem to agree with my simple solution because of the capture issue but I have two problems with that: How often is an intact fairing made such that you can capture something inside it and it is reasonable that it be shielded? I keep thinking of a "basket" type fairing to catch stuff and having the items in the open end completely shielded from the airstream seems unrealistic The capture mechanic is already broken in that should you end up in such a case as 1) and the fairing occlusion gets triggered, everything caught in the fairing will be shielded from the airstream and dragless/generate no lift even were it to fall out of the basket, until the catching Vessel triggers a new update I'm not a rocket wizard so there might be some unconventional way to use a fairing as a catching mitt that I haven't thought of, but I think trading the ability to catch stuff [edit:in an aerodynamic-efficient manner] with a fairing for the ability to use interstage fairings properly is worthwhile
  10. I don't think I suggested such a thing (although creating a convex trigger collider would be my preferred solution which does kind of fall under that umbrella)... As for your solution, it won't catch every case. The reference craft provided by sal looks like an interstage fairing but isn't for example
  11. ? The cargo bay already keeps track of parts it's shielded. It's not that it isn't triggering properly (see the delay in my proof of concept where I wait to make sure it's already run) but that it assumes everything it's shielding will stay shielded unless a significant event happens to its Vessel like being modified in some way (OnVesselWasModified, OnVesselPack/Unpack). There's no consideration for what might happen if the Parts it captured aren't part of the same Vessel... and since it ignores those events for every other Vessel you end up in a weird place where the only thing that can change whether your active ship engine is shielded is an event happening to the debris (containing the cargo bay) you just created. Take your reference craft into orbit, stage until the two small engines run. Give it a bit of thrust. Watch the log until the debris is packed (triggering new occlusion update). Poof, stowage issue gone. That's the problem
  12. I haven't come across this issue much myself (playtime :() but if the reference craft posted by sal_vager is representative of the problem, why not use OnVesselCreate? The problem with that craft isn't that the bay isn't updated but rather that at the moment the bay is decoupled from the rest of the ship, it captures (and shields) Parts belonging to the original ship and then doesn't ever check if they've moved out of range. Since its own update is now based on a separate ship (probably some debris), those incorrectly shielded Parts are now "stuck" unless that separate ship receives another event that triggers an update... One quick bandaid is to prevent bays from shielding parts not belonging to their own vessels. A cleverer solution might be to keep an eye on the distance between a Part and the bay that shields it whenever they belong to different Vessels, and then remove the shield if they exceed a certain distance. Here's my proof of concept: [KSPAddon(KSPAddon.Startup.Flight, false)] public class CargoBayStowageBandaid : MonoBehaviour { private void Start() { GameEvents.onVesselCreate.Add(OnVesselCreated); } private void OnDestroy() { GameEvents.onVesselCreate.Remove(OnVesselCreated); } private void OnVesselCreated(Vessel data) { if (!data.loaded) return; UpdateFairingShieldsForLoadedVessels(); } private void UpdateFairingShieldsForLoadedVessels() { foreach (var v in FlightGlobals.Vessels .Where(v => v.loaded && !v.packed) .Where(v => v.rootPart != null)) UpdateFairingShields(v); } private void UpdateFairingShields(Vessel vessel) { var fairingModules = vessel.FindPartModulesImplementing<ModuleProceduralFairing>() .Where(fm => fm.gameObject.GetComponent<ModuleCargoBay>() != null) .ToList(); if (!fairingModules.Any()) return; fairingModules.ForEach(fm => { var bay = fm.gameObject.GetComponent<ModuleCargoBay>(); var nearby = FindNearbyParts(bay).ToList(); if (!nearby.Any()) return; var partsWeShouldNotEnclose = FindPartsBelongingToOtherVessel(vessel, nearby); foreach (var p in partsWeShouldNotEnclose) StartCoroutine(WaitAndRemoveShield(bay, p)); }); } private static IEnumerable<Part> FindPartsBelongingToOtherVessel(Vessel vessel, IEnumerable<Part> parts) { return parts.Where(p => !ReferenceEquals(p.vessel, vessel)); } private static IEnumerable<Part> FindNearbyParts(ModuleCargoBay bay) { if (bay == null) throw new ArgumentNullException("bay"); var bayColliders = ModuleCargoBay.FindPartColliders(bay.part).Select(pc => pc.collider); var allNearbyParts = Physics.OverlapSphere(bay.transform.TransformPoint(bay.lookupCenter), bay.lookupRadius, 1 << 0) // Parts on layer 0 .Except(bayColliders) .Where(c => c.gameObject.GetComponentInParent<Part>() != null) .Select(c => c.gameObject.GetComponentInParent<Part>()) .ToList(); return allNearbyParts; } private static IEnumerator WaitAndRemoveShield(IAirstreamShield shield, Part part) { yield return new WaitForEndOfFrame(); print("Removing shield from " + part.partInfo.name); part.RemoveShield(shield); } }
  13. Actually I just double-checked and confused Destroy with Instantiate. Destroy on a Component will destroy only the component, while you're right that Instantiating will clone everything. Did you set the parent of the new clone to the same as the thrust pointer and did you give it a different value? It might have been working the whole time :blush:
  14. [quote name='wrcsubers']I'm trying to get a second Throttle Needle to show up in the Throttle Indicator next to the Navball. I'm instantiating a new Gauge by: [snip] I know the gauges are independent as I get different instanceIDs from each and hence I am able to manipulate the gauge independently by enabling/disabling the stock gauge and the 2nd gauge opposite one another. How can I get a 2nd needle to actually show up? Am I missing some GUI stuff?[/QUOTE] You only cloned the Gauge component and not any of its visual bits (the pointer itself is a child containing a MeshFilter and MeshRenderer). Just make sure you get it all [code][KSPAddon(KSPAddon.Startup.Flight, false)] public class SecondThrottleNeedle : MonoBehaviour { private Gauge _gauge; private void Start() { var source = FlightUIController.fetch.thr.gameObject; var clone = Object.Instantiate(source, source.transform.position, source.transform.rotation) as GameObject; _gauge = clone.GetComponent<Gauge>(); _gauge.setValue(0.5f); _gauge.transform.GetChild(0).renderer.material.color = Color.blue; clone.transform.parent = source.transform.parent; StartCoroutine(MoveGauge()); } private void OnDestroy() { _gauge.Do(g => Destroy(g.gameObject)); } private IEnumerator MoveGauge() { _gauge.minValue = 0f; _gauge.maxValue = 100f; while (true) { yield return new WaitForSeconds(1f); var newValue = (_gauge.maxValue - _gauge.minValue) * UnityEngine.Random.value + _gauge.minValue; _gauge.setValue(newValue); } } }[/code]
  15. I did a double-take on that line too, but I used my binoculars to write that method and that's how the game calculates it for some reason
  16. [quote name='Kobymaru']Hey guys, I have followed the instructions and I managed to get my KSP into Devmode, patched the Mono.cecil, created an MDB file for my mod. [snip] ... What do the numbers in "PlayerConnectionConfigFile" mean? I have such a file in <KSP>/Launcher_Data, but the number is 792067676 instead of 803286173, like in the OP.[/QUOTE] Did you create a PlayerConnectionConfigFile inside <KSP>/KSP_Data with the contents from the OP?
  17. You know, funny thing is that I haven't really messed with the mobile lab since before 1.0 and didn't even notice they changed things around on me. I don't know why those methods were left in, they seem to be returning placeholder values now This should do the trick (written for 1.0.5 but should work for 1.0.4): [code]private static float CalculateLabData(Vessel vessel, ScienceData data) { if (vessel == null) throw new ArgumentNullException("vessel"); if (data == null) throw new ArgumentNullException("data"); // note to self: apparently every lab returns same score, so I // guess it doesn't matter which we use? // // ps: the various multipliers are KSPFields so there's a potential for a best // candidate still if somebody tweaks them. Not going to deal with that now var lab = vessel.FindPartModulesImplementing<ModuleScienceLab>() .FirstOrDefault(); var subject = ResearchAndDevelopment.GetSubjectByID(data.subjectID); if (lab == null || subject == null) return 0f; var refValue = ResearchAndDevelopment.GetReferenceDataValue(data.dataAmount, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; return Mathf.Round(GetScienceLabMultiplier(lab, subject) * refValue); } private static float GetScienceLabMultiplier(ModuleScienceLab lab, ScienceSubject subject) { var multiplier = 1f; // lab can't process data twice if (lab.ExperimentData.Any(storedId => storedId == subject.id)) return 0f; if (lab.vessel.Landed) multiplier *= 1f + lab.SurfaceBonus; if (subject.id.Contains(lab.vessel.mainBody.bodyName)) multiplier *= 1f + lab.ContextBonus; if ((lab.vessel.Landed || lab.vessel.Splashed) && ReferenceEquals(FlightGlobals.GetHomeBody(), lab.vessel.mainBody)) multiplier *= lab.homeworldMultiplier; // lack of addition intended return multiplier; }[/code] Let me know if you find a bug in there, it looks eyeball right but I haven't tested it extensively yet
  18. KerbalFoundries has a [URL="http://forum.kerbalspaceprogram.com/threads/134654-Plugin-Parts-Kerbal-Foundries-Continuation-Latest-1-9g?p=2289983&viewfull=1#post2289983"]small bug[/URL] that causes this. My money's on that. If you look at or post your log, you can tell for sure
  19. The current version in the OP isn't compatible with 1.0.5; use the [URL="http://forum.kerbalspaceprogram.com/threads/76793-1-0-4-ScienceAlert-1-8-9-Experiment-availability-feedback-%28July-13%29?p=2293463&viewfull=1#post2293463"]user-patch[/URL] in the meantime. I couldn't help but uh tear everything down and rewrite. This was my very second project using C# and there comes a point where looking at your own code is demotivational ;.; The new version is coming along nicely, it's just been busy so I only get a few hours here and there to work on it
  20. That looks right to me. I'll fix it (horizontal scrollbar at least). Yes, window positions and size should persist so if they're not definitely let me know ... I'm using a lot of this window code in another project so you'd be doing me a double-favor ;)
  21. Which one(s)? The main window starts out as compact as it can be to be efficient. The main window and the plugin options window can both be resized by dragging the right or bottom edges of the window when you see the resize hint. They'll be scalable, too in a future update Edit: I should note it's possible there's some size bug happening here which is why I'm curious
  22. [quote name='Gaalidas']That's why I have made pleas to the community to help me nail this down.[/quote] [code] void OnPause() { isPaused = true; kfdustFx.particleEmitter.enabled = false; _[B]repLight[/B].enabled = false; } [/code] [code] public void SetupParticles(bool repulsor) { [snip] if ([B]repulsor[/B]) [B]SetupRepulsorLights[/B](); } void SetupRepulsorLights() { [snip] _[B]repLight [/B]= _kfRepLight.AddComponent<Light>();[/code] _repLight won't be created for non-repulsors so your OnPause and OnUnpause methods will always throw if there's a loaded wheel anywhere with dust enabled
  23. [quote name='AlphaAsh']Oh ugh. That's kludgy. The easier fix would be for the devs to have their new code ignore anything flagged as Static = True in a config. If that shows up in 1.1 then I'll be very happy.[/quote] Honestly, that is just as kludgy. The complete model information would then be in potentially two different files. Might be time to write your own loader. 99.9% of the stuff loaded by the Mu loader will be attached to rigidbodies, and concave colliders on dynamic bodies aren't allowed in 5.1. That's probably the root cause of this change
  24. [quote name='AlphaAsh']However, I'm fairly certain the issues are a result of changes to collider handling in KSP. That's some serious hard-code and considering the hacky nature of Kerbal Konstructs, I don't see a work-around. All I've been doing since 1.0.5 is try to fix the problems. It's not fun. I'm tired, fed up and Fallout 4 is calling me.[/quote] Yes, apparently the mu loader is now forcing all MeshColliders to convex which causes Unity to recompute them if they're not already (hamfisted change for Unity 5.1 maybe? I read something about concave collider support being removed). This is causing the odd problems. Unfortunately, there isn't any direct way to prevent the loader from ignoring the flag inside the mu format that I can find. One solution is to hijack the load process, parse the mu for the correct value and set it back before the collider is recomputed... and yes it's exactly as ugly as it sounds. Here's my prototype which appears to work. Note that you must rename all affected mu's to muks, so for example ksairstripv24.mu becomes ksairstripv24.muks. They'll look the same as any regular loaded mu so you shouldn't need to change any configs. [spoiler=MuksLoader][code][DatabaseLoaderAttrib(new [] { "muks" })] public class MuksLoader : DatabaseLoaderModel_MU { public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file) { Debug.Log("MuksLoader loading: " + urlFile.url); yield return GameDatabase.Instance.StartCoroutine(base.Load(urlFile, file)); if (obj == null) yield break; using (var fs = new FileStream(urlFile.fullPath, FileMode.Open)) using (var mr = new MuksReader(fs)) { var topNode = mr.LoadNodeTree(); var meshColliders = obj.GetComponentsInChildren<MeshCollider>(true); var convexEntries = CreateEntries(topNode); if (meshColliders.Length != convexEntries.Sum(kvp => kvp.Value.Count)) Debug.LogWarning("Number of MeshCollider convex nodes does not match number of MeshColliders!"); // whoops there's a bug! foreach (var mc in meshColliders) { var url = HierarchyUtil.CompileID(mc.transform, mc.transform.root.name); Queue<bool> convexFlagQueue; if (convexEntries.TryGetValue(url, out convexFlagQueue)) mc.convex = convexFlagQueue.Dequeue(); else Debug.LogWarning("Failed to get convex flag for " + url); } if (convexEntries.Sum(kvp => kvp.Value.Count) > 0) Debug.LogWarning("Unused convex entries for " + urlFile.url); } yield return 0; } /// This is probably a pretty crap way of doing this but because there can be multiple GameObjects with the /// same url and a MeshCollider component, we won't be able to tell their convex flags apart if they differ... /// I'm assuming we'll get the same MeshCollider order out as was created, so we'll just keep a list of what /// was used in the order it was used in and remove entries as they're used private static Dictionary<string, Queue<bool>> CreateEntries( MuksReader.Node tree, Dictionary<string, Queue<bool>> dictionary = null) { if (dictionary == null) dictionary = new Dictionary<string, Queue<bool>>(); if (tree.HasMeshCollider) AddToDictionary(dictionary, CreateNodeUrl(tree), tree.IsConvex); foreach (var ch in tree.Children) CreateEntries(ch, dictionary); return dictionary; } private static void AddToDictionary(Dictionary<string, Queue<bool>> dictionary, string url, bool value) { if (dictionary == null) throw new ArgumentNullException("dictionary"); if (url == null) throw new ArgumentNullException("url"); Queue<bool> entries; url = url.Replace(" ", string.Empty); if (!dictionary.TryGetValue(url, out entries)) { entries = new Queue<bool>(); dictionary.Add(url, entries); } entries.Enqueue(value); } private static string CreateNodeUrl(MuksReader.Node from) { if (@from == null) throw new ArgumentNullException("from"); if (@from.Parent == null) return @from.Name; return CreateNodeUrl(@from.Parent) + "/" + @from.Name; } }[/code][/spoiler] [spoiler=MuksReader][code]public class MuksReader : BinaryReader { private enum DataBlockType { Node = 0, Finished = 1, Animation = 2, MeshCollider = 3, SphereCollider = 4, CapsuleCollider = 5, BoxCollider = 6, MeshFilter = 7, MeshRenderer = 8, SkinnedMeshRenderer = 9, MaterialSet = 10, TextureSet = 12, Light = 23, TagAndLayer = 24, MeshColliderTrigger = 25, SphereColliderTrigger = 26, CapsuleColliderTrigger = 27, BoxColliderTrigger = 28, WheelColliderTrigger = 29, Camera = 30, Particles = 31, } public class Node { public string Name = string.Empty; public List<Node> Children = new List<Node>(); public bool HasMeshCollider = false; public bool IsConvex = true; public Node Parent; } struct MuFlags { public int FlagRelatedToMeshRendererAndTextures; public string UnknownString; } public class MaterialTextureCache { private readonly Dictionary<int, List<string>> _textures = new Dictionary<int, List<string>>(); public void Add(int textureIndex, string textureName) { if (textureIndex < 0) return; Insert(textureIndex, textureName); } private void Insert(int idx, string textureName) { List<string> list; if (!_textures.TryGetValue(idx, out list)) { list = new List<string>(); _textures.Add(idx, list); } if (!list.Contains(textureName)) list.Add(textureName); } public int GetMaterialCount() { return _textures.Keys.Count(); } } private const string MainTex = "_MainTex"; private const string BumpMapTex = "_BumpMap"; private const string EmissiveTex = "_Emissive"; public MuksReader(Stream input) : base(input) { } public MuksReader(Stream input, Encoding encoding) : base(input, encoding) { } public Node LoadNodeTree() { var fileType = ReadInt32(); var somehowMeshRendererRelated = ReadInt32(); var unknown2 = ReadString(); return ReadNode(null, new MaterialTextureCache(), new MuFlags { FlagRelatedToMeshRendererAndTextures = somehowMeshRendererRelated, UnknownString = unknown2 }); } private Node ReadNode(Node parent, MaterialTextureCache cache, MuFlags flags) { var nodeName = ReadString(); var node = new Node { Name = nodeName }; if (parent != null) parent.Children.Add(node); node.Parent = parent; DiscardVector3(); DiscardQuaternion(); DiscardVector3(); while (PeekChar() != -1) { var nextBlockType = (DataBlockType)ReadInt32(); switch (nextBlockType) { case DataBlockType.Node: ReadNode(node, cache, flags); break; case DataBlockType.Finished: return node; case DataBlockType.MeshCollider: ReadMeshCollider(node); break; case DataBlockType.MeshColliderTrigger: ReadMeshColliderTrigger(node); break; default: IgnoreBlock(nextBlockType, cache, flags); break; } } return node; } private void ReadMeshCollider(Node current) { if (current.HasMeshCollider) throw new Exception("This node already has a MeshCollider assigned so something has broken!"); current.HasMeshCollider = true; current.IsConvex = ReadBoolean(); DiscardMesh(); } private void ReadMeshColliderTrigger(Node current) { if (current.HasMeshCollider) throw new Exception("This node already has a MeshCollider assigned so something has broken!"); current.HasMeshCollider = true; var trigger = ReadBoolean(); current.IsConvex = ReadBoolean(); DiscardMesh(); } private void IgnoreBlock(DataBlockType type, MaterialTextureCache cache, MuFlags flags) { switch (type) { case DataBlockType.Animation: DiscardAnimation(); break; case DataBlockType.SphereCollider: DiscardSphereCollider(); break; case DataBlockType.CapsuleCollider: DiscardCapsuleCollider(); break; case DataBlockType.BoxCollider: DiscardBoxCollider(); break; case DataBlockType.MeshFilter: DiscardMeshFilter(); break; case DataBlockType.MeshRenderer: DiscardMeshRenderer(flags.FlagRelatedToMeshRendererAndTextures); break; case DataBlockType.SkinnedMeshRenderer: DiscardSkinnedMeshRenderer(); break; case DataBlockType.MaterialSet: DiscardMaterialSet(flags.FlagRelatedToMeshRendererAndTextures, cache); break; case DataBlockType.TextureSet: DiscardTextureSet(cache); break; case DataBlockType.Light: DiscardLight(flags.FlagRelatedToMeshRendererAndTextures); break; case DataBlockType.TagAndLayer: var tag = ReadString(); var layer = ReadInt32(); break; case DataBlockType.SphereColliderTrigger: DiscardSphereColliderTrigger(); break; case DataBlockType.CapsuleColliderTrigger: DiscardCapsuleColliderTrigger(); break; case DataBlockType.BoxColliderTrigger: DiscardBoxColliderTrigger(); break; case DataBlockType.WheelColliderTrigger: DiscardWheelColliderTrigger(); break; case DataBlockType.Camera: DiscardCamera(); break; case DataBlockType.Particles: DiscardParticles(); break; default: throw new NotImplementedException("Unrecognized data block type: " + type); } } private void DiscardVector2() { ReadSingle(); ReadSingle(); } private void DiscardVector3() { ReadSingle(); ReadSingle(); ReadSingle(); } private void DiscardVector4() { DiscardQuaternion(); } private void DiscardBounds() { DiscardVector3(); DiscardVector3(); } private void DiscardQuaternion() { ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); } private void DiscardMatrix() { for (var i = 0; i < 16; ++i) ReadSingle(); } private void DiscardColor() { DiscardVector4(); } private void DiscardAnimation() { var numClips = ReadInt32(); for (var clipIndex = 0; clipIndex < numClips; ++clipIndex) { ReadString(); DiscardBounds(); ReadInt32(); var unknownNum = ReadInt32(); for (var j = 0; j < unknownNum; ++j) { ReadString(); ReadString(); ReadInt32(); ReadInt32(); ReadInt32(); var keyframeCount = ReadInt32(); for (var i = 0; i < keyframeCount; i++) { ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadInt32(); } } } ReadString(); ReadBoolean(); } private void DiscardMesh() { var entryType = (EntryType)ReadInt32(); if (entryType != EntryType.MeshStart) throw new Exception("Malformed mesh?"); var numVertices = ReadInt32(); var unknown = ReadInt32(); while ((entryType = (EntryType)ReadInt32()) != EntryType.MeshEnd) { switch (entryType) { case EntryType.MeshVerts: case EntryType.MeshNormals: for (var i = 0; i < numVertices; ++i) DiscardVector3(); break; case EntryType.MeshUV: case EntryType.MeshUV2: for (var i = 0; i < numVertices; ++i) DiscardVector2(); break; case EntryType.MeshTangents: for (var i = 0; i < numVertices; ++i) DiscardVector4(); break; case EntryType.MeshTriangles: var numTriangles = ReadInt32(); for (var i = 0; i < numTriangles; ++i) ReadInt32(); break; case EntryType.MeshBoneWeights: ReadInt32(); ReadSingle(); ReadInt32(); ReadSingle(); ReadInt32(); ReadSingle(); ReadInt32(); ReadSingle(); break; case EntryType.MeshBindPoses: var poseCount = ReadInt32(); for (var i = 0; i < poseCount; ++i) DiscardMatrix(); break; } } } private void DiscardSphereCollider() { ReadSingle(); DiscardVector3(); } private void DiscardCapsuleCollider() { ReadSingle(); ReadInt32(); DiscardVector3(); } private void DiscardBoxCollider() { DiscardVector3(); DiscardVector3(); } private void DiscardMeshFilter() { DiscardMesh(); } private void DiscardMeshRenderer(int muFlag) { if (muFlag >= 1) { ReadBoolean(); ReadBoolean(); } var num = ReadInt32(); for (var i = 0; i < num; ++i) ReadInt32(); } private void DiscardSkinnedMeshRenderer() { var num = ReadInt32(); for (var i = 0; i < num; ++i) ReadInt32(); DiscardVector3(); DiscardVector3(); ReadInt32(); ReadBoolean(); var numStrings = ReadInt32(); for (var i = 0; i < numStrings; ++i) ReadString(); DiscardMesh(); } private void DiscardMaterial(MaterialTextureCache cache) { ReadString(); var shader = ReadInt32(); switch (shader) { case 1: // KSP/Diffuse DiscardMaterialTexture(MainTex, cache); break; case 2: // "KSP/Specular" DiscardMaterialTexture(MainTex, cache); DiscardColor(); ReadSingle(); break; case 3: // "KSP/Bumped" DiscardMaterialTexture(MainTex, cache); DiscardMaterialTexture(BumpMapTex, cache); break; case 4: // "KSP/Bumped Specular" DiscardMaterialTexture(MainTex, cache); DiscardMaterialTexture(BumpMapTex, cache); DiscardColor(); ReadSingle(); break; case 5: // "KSP/Emissive/Diffuse" DiscardMaterialTexture(MainTex, cache); DiscardMaterialTexture(EmissiveTex, cache); DiscardColor(); break; case 6: // "KSP/Emissive/Specular" DiscardMaterialTexture(MainTex, cache); DiscardColor(); ReadSingle(); DiscardMaterialTexture(EmissiveTex, cache); DiscardColor(); break; case 7: // "KSP/Emissive/Bumped Specular" DiscardMaterialTexture(MainTex, cache); DiscardMaterialTexture(BumpMapTex, cache); DiscardColor(); ReadSingle(); DiscardMaterialTexture(EmissiveTex, cache); DiscardColor(); break; case 8: // "KSP/Alpha/Cutoff" DiscardMaterialTexture(MainTex, cache); ReadSingle(); break; case 9: // "KSP/Alpha/Cutoff Bumped" DiscardMaterialTexture(MainTex, cache); DiscardMaterialTexture(BumpMapTex, cache); ReadSingle(); break; case 10: // "KSP/Alpha/Translucent" DiscardMaterialTexture(MainTex, cache); break; case 11: // "KSP/Alpha/Translucent Specular" DiscardMaterialTexture(MainTex, cache); ReadSingle(); DiscardColor(); ReadSingle(); break; case 12: // "KSP/Alpha/Unlit Transparent" DiscardMaterialTexture(MainTex, cache); DiscardColor(); break; case 13: // "KSP/Unlit" DiscardMaterialTexture(MainTex, cache); DiscardColor(); break; case 14: // "KSP/Particles/Alpha Blended" DiscardMaterialTexture(MainTex, cache); DiscardColor(); ReadSingle(); break; case 15: // "KSP/Particles/Additive" DiscardMaterialTexture(MainTex, cache); DiscardColor(); ReadSingle(); break; default: throw new NotImplementedException("Unrecognized value: " + shader); } } private void DiscardMaterialTexture(string textureName, MaterialTextureCache cache) { var texIndex = ReadInt32(); cache.Add(texIndex, textureName); DiscardVector2(); DiscardVector2(); } private void DiscardMaterial4(MaterialTextureCache cache) { ReadString(); ReadString(); var propertyCount = ReadInt32(); for (int i = 0; i < propertyCount; ++i) { var textureName = ReadString(); var propertyType = ReadInt32(); switch (propertyType) { case 0: DiscardColor(); break; case 1: DiscardVector4(); break; case 2: ReadSingle(); break; case 3: ReadSingle(); break; case 4: DiscardMaterialTexture(textureName, cache); break; default: throw new NotImplementedException("Unrecognized value for property type: " + propertyType); } } } private void DiscardMaterialSet(int muFlag, MaterialTextureCache cache) { var numTextures = ReadInt32(); for (var i = 0; i < numTextures; ++i) if (muFlag >= 4) DiscardMaterial4(cache); else DiscardMaterial(cache); } private void DiscardTextureSet(MaterialTextureCache cache) { var numTextures = ReadInt32(); if (numTextures != cache.GetMaterialCount()) { // stock mu loader errors out here if these don't match return; } for (var i = 0; i < numTextures; i++) { ReadString(); ReadInt32(); } } private void DiscardLight(int muFlag) { ReadInt32(); ReadSingle(); ReadSingle(); DiscardColor(); ReadInt32(); if (muFlag > 1) ReadSingle(); } private void DiscardSphereColliderTrigger() { ReadBoolean(); ReadSingle(); DiscardVector3(); } private void DiscardCapsuleColliderTrigger() { ReadBoolean(); ReadSingle(); ReadSingle(); ReadInt32(); DiscardVector3(); } private void DiscardBoxColliderTrigger() { ReadBoolean(); DiscardVector3(); DiscardVector3(); } private void DiscardWheelColliderTrigger() { ReadSingle(); ReadSingle(); ReadSingle(); DiscardVector3(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); } private void DiscardCamera() { ReadInt32(); DiscardColor(); ReadInt32(); ReadBoolean(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); } private void DiscardParticles() { ReadBoolean(); ReadInt32(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); DiscardColor(); ReadBoolean(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadInt32(); ReadInt32(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadBoolean(); ReadBoolean(); for (int i = 0; i < 5; i++) DiscardColor(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadSingle(); ReadBoolean(); ReadBoolean(); ReadSingle(); ReadSingle(); ReadSingle(); ReadInt32(); ReadInt32(); ReadInt32(); ReadInt32(); ReadInt32(); } }[/code][/spoiler]
×
×
  • Create New...