• Content count

  • Joined

  • Last visited

Community Reputation

1,078 Excellent


About xEvilReeperx

  • Rank
    Junior Rocket Scientist

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. xEvilReeperx

    PAW Event being disabled

    From easiest to most convoluted: Cheat by implementing a similarly-named KSPEvent (with different method name) and abusing GameObject.SendMessage Reimplement the method yourself (VesselRenameDialog looks interesting) Fix the cached reflected delegate data yourself. This will make things "just work", but it's a little hacky [KSPAddon(KSPAddon.Startup.MainMenu, true)] class FixSetVesselNamingIssue : MonoBehaviour { class SneakyWayIntoCachedReflectedData : BaseEventList { public SneakyWayIntoCachedReflectedData(Type nobodyCares) : base(nobodyCares) { EnsureDataExists<Part>(); // if ALL modules changed, might not be any cached data for Part EnsureDataExists<PartTapIn>(); // it's possible some MM failure didn't edit the parts as expected, so confirm here too // "reflectedAttributeCache" is part of BaseEventList and is why we derive from it -> to get access so // we can tweak it var partData = reflectedAttributeCache[typeof(Part)]; // <-- this has an event we want to copy var tapinData = reflectedAttributeCache[typeof(PartTapIn)]; // <-- this is where we'll copy it to // unfortunately the only way to tell the various attributes apart // is to examine their guiName, which is localized #autoLOC_8003140 var targetLocalizedName = Localizer.Format("#autoLOC_8003140"); var configureNamingAttr = partData.eventAttributes.Single(kspe => kspe.guiName.Equals(targetLocalizedName, StringComparison.Ordinal)); if (tapinData.eventAttributes.Any( kspe => kspe.guiName.Equals(targetLocalizedName, StringComparison.Ordinal))) { return; // clearly changes already made } // insert attribute into PartTapIn data tapinData.eventAttributes.Add(configureNamingAttr); // copy "SetVesselNaming" delegate from Part to PartTapIn // this'll work because it's technically part of PartTapIn as well // note: method name directly, no localization needed here var setVesselNamingFunc = partData.eventDelegates.Single(mi => "SetVesselNaming".Equals(mi.Name)); tapinData.eventDelegates.Add(setVesselNamingFunc); } private static void EnsureDataExists<T>() where T : MonoBehaviour { if (reflectedAttributeCache.ContainsKey(typeof(T))) return; // already cached // if we create an inactive GameObject, we can prevent stuff from triggering // (awake, start) var dummyGo = new GameObject("dummy"); dummyGo.SetActive(false); // suppress awake, start var target = dummyGo.AddComponent<T>(); var dummy = new BaseEventList(target); // force data to be cached UnityEngine.Object.Destroy(dummyGo.gameObject); } } private void Start() { try { new SneakyWayIntoCachedReflectedData( typeof(Part)); // we literally don't care about anything but getting this constructor to run } catch (Exception e) { Debug.LogError("Exception while trying to meddle with cached data: " + e); } finally { Destroy(gameObject); // done } } }
  2. The exception in the log was the first clue. I looked at the code and didn't see any reason why that would prevent a simple print statement made in Update from working, so I wrote another small addon that checked out KeyNode's state. There were three possibilities as to why Update wasn't running: the component had been destroyed due to the uncaught exception in Awake. I've never seen this before, but thought it could be something AddonLoader does on an unhandled exception the GameObject wasn't active the MonoBehaviour was disabled (by Unity?) Turns out #3 was your problem
  3. It throws an uncaught exception in Awake and its MonoBehaviour ends up getting disabled (MonoBehaviour.enabled = false) when initializing for the second+ time. That's why you don't see any output from Update on subsequent flight scenes ArgumentException: An element with the same key already exists in the dictionary. System.Collections.Generic.Dictionary`2[UnityEngine.KeyCode,Callback].Add (KeyCode key, .Callback value) KeyNode.KeyNode.Awake () UnityEngine.GameObject:AddComponent(Type) AddonLoader:StartAddon(LoadedAssembly, Type, KSPAddon, Startup) AddonLoader:StartAddons(Startup) AddonLoader:OnLevelLoaded(GameScenes) AddonLoader:OnSceneLoaded(Scene, LoadSceneMode) UnityEngine.SceneManagement.SceneManager:Internal_SceneLoaded(Scene, LoadSceneMode)
  4. What does the hierarchy of your part look like? Based on the stacktrace and name, I'd bet there's a bug in StrippedTaggedTransforms. Try making sure whatever element is tagged with Icon_Only is the very last child of its parent, wherever the tag appears
  5. xEvilReeperx

    KSP 1.4.1 Performance

    Follow the same instructions to get debugging working, and then use Unity's profiler with KSP
  6. xEvilReeperx

    KSP 1.4.1 Performance

    You're going to have a hard time writing code that doesn't generate unnecessary garbage if you don't understand the mechanisms that create it. Use the profiler to find problem spots. If you happen to use VS and have Resharper, the Heap Allocations Viewer extension is very useful
  7. xEvilReeperx

    KSP 1.4.1 Performance

    Don't do this, it has every drawback and no advantage. They will all be rendered anyways and any change to any element will still dirty its canvas and trigger a rebuild
  8. You've misunderstood my point: KSP's source code is not required to do any of these things, so I don't have any obligation to offer it.
  9. I don't have any source code to KSP or Assembly-CSharp. I'm able to generate, install, run, and modify mods. Am I a magician?
  10. xEvilReeperx

    Does KSP v1.4 really have spyware in it?

    RedShell is apparently sending information whenever the game is launched (and whether game is modded). While the CALL_HOME, SEND_PROGRESS_DATA, and DONT_SEND_IP settings still exist, they are no longer used and there's no way to opt out of this data collection. Sent data includes your IP address and some kind of user ID which I assume is unique. I couldn't find anything related to Ghostery
  11. xEvilReeperx

    Simple way to know if debug menu is open?

    If you're polling instead of an infrequent check, it might be best to add a little tracking component to DebugScreen that updates a visible flag whenever OnEnable or OnDisable get called on it. The FindObject(s) family are all fairly slow
  12. xEvilReeperx

    Clarifying Legal Boundaries

    Last time a similar question was asked, the answer was no because making any changes to the game files outside of GameData is a no-no, and a double no because you would need to distribute the patched assembly afterwards. Patch the method itself at runtime instead without making modifications to the file on disk. Of course, I'm not 100% sure that's technically allowed either...
  13. You could modify/replace Base[Action/Event] delegates to fire a custom GameEvent for you. That's how I'd do it
  14. The simplest way is the same way parts are loaded, by using PartTools to export to a .mu file. That'll be loaded by the game into GameDatabase.Instance.databaseModel. Parts are created when an appropriate config refers to the model in this list but you can use it for whatever purpose. The format does have some limitations though, so if you find you need more capability you can use an AssetBundle instead. In that case, you might find this thread to be a useful read