magico13

[1.4.1] ScrapYard - The Common Part Inventory - 1.1.0.107 (2018-03-18)

Recommended Posts

3 hours ago, jlcarneiro said:

I assumed with ScrapYard installed, StageRecovery should be deleted. Should I?

ScrapYard and StageRecovery serve two completely different purposes, so you should keep both. ScrapYard is just like KCT's old part inventory (but better) and just lets you reduce build times and such. StageRecovery recovers funds for stages that you drop and the dev builds of StageRecovery work with ScrapYard so that stages recovered this way will be added to the inventory as well.

Keep both, they serve different purposes!

 

Edit: @severedsolo please try the latest version. There were a few things that combined to make it so forbidden templates weren't matching correctly. I think I got those taken care of, so things should be kept out of the inventory properly now.

Note that I've got some plans to get string comparisons into MagiCore's math parser soon, I just haven't gotten a chance to implement it yet. It might be limited to if statements and I'm trying to decide if I should create new operators specifically for checking string equality, or if I should always test string equality before I test numerical equality. The former is simpler and less error prone, but the latter is a bit more general since you can check both as needed and seems cleaner from a user perspective.

Hopefully I can get to that tomorrow, I've got a big landscaping project going on right now because we've had water enter our house due to our poorly set up yard, and as a result we've got to regrade part of the yard, get a wall repaired, and replace 300 square feet of flooring (we could just replace a corner of carpeting, but we didn't like the carpet anyway). So that's where my daylight hours after work are being spent lately :P

Edited by magico13

Share this post


Link to post
Share on other sites
11 hours ago, magico13 said:

 please try the latest version. There were a few things that combined to make it so forbidden templates weren't matching correctly. I think I got those taken care of, so things should be kept out of the inventory properly now.

Seems to work perfectly, thanks very much!

For anyone else who wants to try this, what I've done is created a blank part module that doesn't actually do anything, and set up a SY_FORBIDDEN_MODULE that's looking for that module. When I don't want SY to store the part, I am adding that module to the part using part.AddModule. At that point SY then ignores it when the vessel is recovered.

Need to test that parts where I don't add that module are still added to the inventory, but I don't forsee any problems with that.

Edited by severedsolo

Share this post


Link to post
Share on other sites
10 hours ago, severedsolo said:

For anyone else who wants to try this, what I've done is created a blank part module that doesn't actually do anything, and set up a SY_FORBIDDEN_MODULE that's looking for that module. When I don't want SY to store the part, I am adding that module to the part using part.AddModule. At that point SY then ignores it when the vessel is recovered.

Do you have an existing module and does it have a clear status of "broken"? If so, you should be able to avoid all of this and just add a "requirement" to the forbidden template so that it only triggers in the broken case, although that may be dependent on me getting the string comparisons set up in MagiCore. If you do have an existing module I'd love to see examples of the "regular" and "broken" cases, if they exist.

Share this post


Link to post
Share on other sites

 

1 hour ago, magico13 said:

Do you have an existing module and does it have a clear status of "broken"?

At the moment I just have a "hasFailed" bool that fires the "broken" event every FixedUpdate() (in my test case, I am just shutting down an engine, and I want to make sure the player doesn't turn it back on again) - most of the PartModule is based around deciding whether or not the part is going to fail, rolling dice etc. so it would depend on whether the requirements could read a bool. There is probably a better way to do it, but this is my first time working with PartModules.

I suspect my "broken" module is probably the easier way anyway, as I will be using different part modules for different "types" of part failure, which all extend the BaseFailureModule (the base module is never actually added to any parts). Seems easier to me to have one broken module template, than define an individual template for all modules. (If you know something I don't please correct me, I am still very new at this).

As you asked to see the code:

namespace Untitled_Part_Failure_Mod
{
    class BaseFailureModule : PartModule
    {
        System.Random r = new System.Random();
        bool willFail = false;
        [KSPField(isPersistant = true, guiActive = false)]
        bool firstLoaded = false;
        [KSPField(isPersistant = true, guiActive = true)]
        public bool hasFailed = false;
        [KSPField(isPersistant = true, guiActive = false)]
        float expectedLifetime = 20;
        ModuleSYPartTracker SYP;
        float chanceOfFailure = 50.0f;
        [KSPField(isPersistant = true, guiActive = true)]
        int generation = 1;
        double failureTime = 0;

        private void Start()
        {
            SYP = part.FindModuleImplementing<ModuleSYPartTracker>();
            if (FailCheck())
            {
                failureTime = Planetarium.GetUniversalTime() + r.Next(1, 1800);
                willFail = true;
            }
        }

        protected virtual void FailPart() { }
        private void FixedUpdate()
        {
            if (hasFailed)
            {
                FailPart();
                return;
            }
            if (!willFail) return;
            if (Planetarium.GetUniversalTime() < failureTime) return;
            FailPart();
            hasFailed = true;
            part.AddModule("Broken");
        }

        bool FailCheck()
        {
            int score = r.Next(1, 100);
            chanceOfFailure = chanceOfFailure / generation;
            if (SYP.TimesRecovered > 0) chanceOfFailure = chanceOfFailure * ((SYP.TimesRecovered / expectedLifetime) * 100);
            if (score < chanceOfFailure) return true;
            return false;
        }
    }
}

I just need to work on getting "generations" sorted and then I will probably have something to put a dev thread up for. I'm also considering using the "used" tracker, instead of how many times it's been recovered when determining failure rates.

Which leads me to another question: From looking at the way SY works, I think the "builds" in the part tracker are tracking every time a part is built, regardless of if it's from the inventory or not? Is there any way to pull "new builds" only? If not, I can write something (I already have the start of a class to handle that, but I thought I'd ask before I put too much effort into it).

Share this post


Link to post
Share on other sites
6 minutes ago, severedsolo said:

Seems easier to me to have one broken module template, than define an individual template for all modules.

This is my first real foray into PartModules as well, I typically only write plugins that just listen to events/run during Update and forcibly inject themselves into Squad's stuff in ways they aren't supposed to :P But, if all of your modules follow a typical naming scheme then you can use the fact that the "name" field of the module template supports Regex. So assuming you have BaseFailureModule, EngineFailureModule, FuelTankFailureModule, etc you could set "name" to something like "name = .*FailureModule" which would match all of those, then have a requirement of "requirement = if([hasFailed] == "true" ? 1 : 0)" (once I make MagiCore work with strings that is...). That would work without you having to do anything special on your side.

I should probably also let requirement = true/false natively instead of using numbers (it was easier since I already had MagiCore handling numbers), in which case you could just replace all that with "requirement = [hasFailed]".

You are correct that the part tracker tracks all builds and uses of a part. I should be able to very easily add in something that only tracks new builds and new uses, so then you could get new builds/uses and all builds/uses. Since the "build" tracker only counts once per build for any number of copies of a part, it'd be incremented if you had any new copies on the craft, but the number of "reused" builds should be counted too if you have any copied of a part from the inventory. I'll probably break it out into all three possibilities then:

- Total builds/uses of a part

- New builds/uses of a part

- Inventoried builds/uses of a part

 

It looks like you're requiring a hard dependency on ScrapYard. Is that what you want to do, or do you want it to work without ScrapYard as well? If you want a soft dependency, let me know and I can help you with that. You can find the times recovered on the module without any access to the ModuleSYPartTracker class itself if you go through the ConfigNode.

Also, I recommend not using ints for determining chance of something happening. The standard is to use a random number between 0 and 1, where 1 means 100% and 0 means 0%. So if something has a 50% chance of failure, just do "if (r.NextDouble() < 0.5) { FAIL } else { NOT FAIL }"

Share this post


Link to post
Share on other sites
36 minutes ago, magico13 said:

It looks like you're requiring a hard dependency on ScrapYard. Is that what you want to do, or do you want it to work without ScrapYard as well?

DangIt! already has the "non ScrapYard based part failure mod" market covered, and alot of what I want to do probably wouldn't work without SY, so the plan is to make a hard dependency.

The plan (as far as I have one) is to do something that sits between DangIt! and TestFlight - the first use of a part will have a relatively high failure rate, but subsequent "first uses" (ie, a new guid) of that part will be slightly lower (each generation will get more reliable). After the first (test) flight, that individual parts failure rate will be determined by the "lifetime" of that part. Essentially how many times it's been re-used. So a part that's only been flown twice will be much less likely to fail than a part that's flown 20 times.

36 minutes ago, magico13 said:

it'd be incremented if you had any new copies on the craft, but the number of "reused" builds should be counted too if you have any copied of a part from the inventory. I'll probably break it out into all three possibilities then:

That sounds like exactly what I would want. To clarify, I gather from this bit:

Quote

Since the "build" tracker only counts once per build for any number of copies of a part

that if a player launched 4 new (non-inventoried) LV-45 engines on their rocket, that would only increment the "new build" counter by 1, if I'm understanding you correctly? (this is the behaviour I would like)

Edited by severedsolo

Share this post


Link to post
Share on other sites
9 hours ago, severedsolo said:

that if a player launched 4 new (non-inventoried) LV-45 engines on their rocket, that would only increment the "new build" counter by 1, if I'm understanding you correctly?

Correct. There's "builds" and "uses". Builds go up by one for any number of copies on a craft while uses count every copy individually. For instance, a "ship" comprised of 20 of the same fuel tank only counts as 1 "build" of that fuel tank, but 20 "uses" of it. That's already how it works, but it dosen't differentiate between new builds versus parts taken from the inventory.

Instead I will provide all three variants of "builds" and "uses": new/fresh instances of the part, reused/inventoried instances of the part, and total instances of the part.

Take that ship consisting of 20 of the same fuel tank. Say 7 of them were pulled out of the inventory but the other 13 are new, and that previously a single ship containing 7 fuel tanks was launched and recovered (to get us those 7 pulled out of the inventory). Before this build:

Total (builds/uses): 1/7 New (builds/uses): 1/7 Inventoried (builds/uses): 0/0

After building the 20 part blob of fuel tanks:

Total (builds/uses): 2/27 New (builds/uses): 2/20 Inventoried (builds/uses): 1/7

Note that the total number of uses is the sum of the new uses and inventoried uses, but the total number of builds is not just the sum of new+inventoried, which is why I have to provide all three options separately.

 

Sound good? Your plan sounds great to me and is probably something I'll add to my own save. I like how TestFlight takes actual flight experience into play, but I also pretty much play stock (vs RO) and like simple things over realism sometimes. Yours will probably meet match my desires pretty well :)

 

Edit: there's a new build on the build server (#46) but I haven't fully tested it and I'm too tired to do a real beta release. It adds some cool stuff. MagiCore theoretically supports strings using "seq" and "sneq" for equality and inequality. It also lets you use "true" and "false" instead of 1 and 0 (they're just replaced by 1 and 0 internally).

Example: "if( [myVar] seq testing ? true : false)" would theoretically check if that value of myVar was equal to the string "testing" (sneq would check if they're different). If the same, it returns "true" which is mapped to 1. If different then it returns "false" or 0. The absolute latest MagiCore should also trim the left and right side of that comparison so that whitespace won't affect it, but the one in the build is one build older and doesn't have that.

Also, the part tracker stuff was updated. It had some bugs, I think I squashed them, but it might still have a few hiccups. It'll try to convert the old stuff over, but only the "buildsTotal" and "usesTotal" will carry over. You might just want to reset the whole part tracker by deleting everything.

Edited by magico13

Share this post


Link to post
Share on other sites

ThatThat@magico13

Christ I hate this mobile forum so much. Yes that all sounds great, I've got the framework written now, so once I can pull the "new builds" through that should finish off what's needed for the base module.

I've just about finished writing the EngineFailureModule, so once that's been tested, I should be able to put an early beta up.

Thanks for all your help, I'm sure I'll need more further down the line, but I've learnt alot just from writing these two classes

Share this post


Link to post
Share on other sites

hey @DMagic awesome mod and it has a lot of potential :)

Just throwing here an idea (probably for far future): what about giving an identifier for an inventory, so a player can have different inventories of parts, i.e. 1st inventory = KSC, 2nd inventory = island center etc.

As for why - I was thinking of giving planes a purpose to transport certain (larger?) parts to KSC first (i.e. from island runway) so they can be assembled into final rocket. This would probably need a separate mod to function. For example it could be cheaper / faster / only possible to produce larger parts on island center and then have them moved by a plane to KSC than to do everything in KSC.

obligatory photo:

Energiya%20fly-in-lowres.JPG

 

Share this post


Link to post
Share on other sites
3 hours ago, severedsolo said:

Christ I hate this mobile forum so much. Yes that all sounds great, I've got the framework written now, so once I can pull the "new builds" through that should finish off what's needed for the base module.

There was a period of time where I couldn't post anything using my phone because it copied in a bunch of text+quotes that I was completely unable to delete. It magically went away one day, but yeah, I almost only use mobile for reading anymore...

Feel free to grab the latest dev build and try that out, it should do what you want. I'll get an actual beta up tonight most likely.

1 hour ago, riocrokite said:

hey @DMagic awesome mod and it has a lot of potential :)

Just throwing here an idea (probably for far future): what about giving an identifier for an inventory, so a player can have different inventories of parts, i.e. 1st inventory = KSC, 2nd inventory = island center etc.

I think you've got the wrong magic man tagged up there :wink: (actually not the first time that's happened)

The overall scope of what you're suggesting is outside of this mod, but there's no reason another mod couldn't build off of ScrapYard to provide that functionality (I'd recommend that mod require Kerbal Konstructs or KSC Switcher along with ScrapYard. That way you can launch from the island runway or wherever). In fact, with the way ScrapYard is setup, someone who references it directly can already create an entirely separate inventory and not have to do much, if any, work. The only limitations are that you can't currently override ScrapYard's listener for vessel recovery, but that should be easy enough for me to make an option, and you'd have to handle processing (and saving info to the save file) manually since you can't go through the simplified ScrapYard methods that do everything for you. Although there are intermediate methods for working with the inventory/part tracker/saving data that are still really simple to use, so it really wouldn't be tough using the existing infrastructure.

It's a cool idea that should already be mostly supported by ScrapYard, but someone else will probably have to do it since I likely won't have time. If someone does want to try doing that, let me know and I can provide some pointers (I also have experience working with Kerbal Konstructs and KSC Switcher).

Share this post


Link to post
Share on other sites
9 hours ago, magico13 said:

There was a period of time where I couldn't post anything using my phone because it copied in a bunch of text+quotes that I was completely unable to delete. It magically went away one day, but yeah, I almost only use mobile for reading anymore...

Feel free to grab the latest dev build and try that out, it should do what you want. I'll get an actual beta up tonight most likely.

I think you've got the wrong magic man tagged up there :wink: (actually not the first time that's happened)

The overall scope of what you're suggesting is outside of this mod, but there's no reason another mod couldn't build off of ScrapYard to provide that functionality (I'd recommend that mod require Kerbal Konstructs or KSC Switcher along with ScrapYard. That way you can launch from the island runway or wherever). In fact, with the way ScrapYard is setup, someone who references it directly can already create an entirely separate inventory and not have to do much, if any, work. The only limitations are that you can't currently override ScrapYard's listener for vessel recovery, but that should be easy enough for me to make an option, and you'd have to handle processing (and saving info to the save file) manually since you can't go through the simplified ScrapYard methods that do everything for you. Although there are intermediate methods for working with the inventory/part tracker/saving data that are still really simple to use, so it really wouldn't be tough using the existing infrastructure.

It's a cool idea that should already be mostly supported by ScrapYard, but someone else will probably have to do it since I likely won't have time. If someone does want to try doing that, let me know and I can provide some pointers (I also have experience working with Kerbal Konstructs and KSC Switcher).

Cool beans, and yah sorry for pinging the wrong man. If no one give it a go, I'll probably try to do it (probably in a few months time) when I finish my current mods pipeline and learn a bit more about coding (so surface and deep core mining mods).

Share this post


Link to post
Share on other sites

Oooh. Didn't realise this already had its own release thread!
 

Probably a stupid question, but which versions of KCT, MagiCore and StageRecovery is it compatible with? Haven't quite kept up with the development of them lately - am I best off just grabbing the latest dev versions of each from the Jenkins page? And should it be safe to install on an existing career save?

EDIT: Whoops, didn't see this;

Quote

I guess this serves as a warning. If you're gonna use KCT with ScrapYard, please make sure you're updated to the latest version of the KCT dev builds! Things break otherwise!

 

Edited by baldamundo

Share this post


Link to post
Share on other sites
11 hours ago, baldamundo said:

which versions of KCT, MagiCore and StageRecovery is it compatible with? Haven't quite kept up with the development of them lately - am I best off just grabbing the latest dev versions of each from the Jenkins page? And should it be safe to install on an existing career save?

Yeah, right now (especially with KCT and StageRecovery) it's best to grab the latest versions. The MagiCore shipped with ScrapYard should almost always be the latest one so that's usually safe. If you're using the last release of StageRecovery it just won't do anything with ScrapYard, which is also safe, but if you've got a dev build you'll want to make sure you keep it up to date since the ScrapYard API has had a few breaking changes. Once ScrapYard is fully released I am going to try to not make any breaking changes, so you can always wait until then (but that might be a month from now depending on what I try to get done before "release").

As for existing saves, it should be ok to add onto an existing save, but make backups whenever you update just in case.

Edit: Posted 0.9.3.48, which should have the new changes for the part tracker and a new icon that I made from some stuff I found at flaticon.com (totally stole that idea from @severedsolo). It's a crane picking up a rocket, which is better than some text, but I'll happily accept a different one :P

 

icon.png

Edited by magico13

Share this post


Link to post
Share on other sites

Minor bug report:

When moving from the VAB to the Flight Scene (in stock - haven't tested with KCT) -  ScrapYardWrapper.GetBuildCount(part, ScrapYardWrapper.TrackType.NEW) returns one lower than it should do. Ie, it isn't taking into account the build you are doing at the point you hit "launch" in the VAB. If you revert to launch, it then reports the correct number.

Just in case it's me calling it too early - I am calling this function in Start() (I doubt it though, because it is returning a number, it's just the wrong one)

22 hours ago, magico13 said:

totally stole that idea from @severedsolo

It's a brilliant site. My artistic skills are non-existant, so that's saved me many times.

Edited by severedsolo

Share this post


Link to post
Share on other sites

@severedsolo the build doesn't get added until the OnVesselRollout event is fired, which probably happens after Start. If I fire an event when a build happens, would that work for you? I should probably be firing one for that anyway.

Share this post


Link to post
Share on other sites
32 minutes ago, magico13 said:

@severedsolo the build doesn't get added until the OnVesselRollout event is fired, which probably happens after Start. If I fire an event when a build happens, would that work for you? I should probably be firing one for that anyway.

Works for me. No rush though, it's not a deal breaker

Share this post


Link to post
Share on other sites

The latest beta release adds a few new changes. The first is a new event called OnSYTrackerUpdated that is fired when the part tracker has a new build tracked. It also passes the list of updated InventoryParts, but you still have to request the new values yourself.

The other changes focus on the "Override Funds" option. Firstly, it should be available even in modes other than career. Additionally, with it active it should cause the current cost of the ship to appear as what you would actually pay overall (ie, a mk1pod costs 600 but only costs 12 when pulled from the inventory and has full monoprop). Note that the way the overriding of funds works right now, you have to pay full price first and then you're refunded later, so if you're low on funds it might be a bit misleading. And finally, you can now sell/discard parts by applying the inventory, then grabbing the stack of parts you want to sell and clicking on the ScrapYard icon. It'll prompt you to check that you're sure you want to sell them, and the message also confirms the number of inventory parts in the stack and the total amount of funds you'll get for selling them. (Example, if you have a stack of 3 mk1pods and two of them are from the inventory, then trying to sell them will list that there are two inventory parts and a total sale price of 1176 funds).

That method of selling things still kinda sucks, but that's just because you can't see everything in the inventory yet and choose things that way. I'm going to be starting on that UI this week.

Edited by magico13

Share this post


Link to post
Share on other sites
On 13/05/2017 at 7:42 PM, magico13 said:

@severedsolo the build doesn't get added until the OnVesselRollout event is fired, which probably happens after Start.

Looks like this was indeed the issue - the new event is firing just after Start() finishes.

Share this post


Link to post
Share on other sites

I am so incredibly pleased that this is seeing the light of day. Not having time to pursue ksp mod ideas is one of the things I really regret :/

Share this post


Link to post
Share on other sites

An odd question that might be better served in a different thread.

I was trying to use Scrapyard the FMRS (@linuxgurugamer's recovery mod). When I land the first stage of my stockalike Falcon 9, FMRS says that the parts are recovered but ScrapYard doesn't show them in its inventory. Is getting these two mods to work together a possibility (I realise you two have worked together on Stage Recovery/FMRS recently).

Share this post


Link to post
Share on other sites
38 minutes ago, Daelkyr said:

An odd question that might be better served in a different thread.

I was trying to use Scrapyard the FMRS (@linuxgurugamer's recovery mod). When I land the first stage of my stockalike Falcon 9, FMRS says that the parts are recovered but ScrapYard doesn't show them in its inventory. Is getting these two mods to work together a possibility (I realise you two have worked together on Stage Recovery/FMRS recently).

FMRS might not be triggering the standard recovery event, in which case it'll need to go through ScrapYard's API to add the parts manually (which is what StageRecovery does). Post over in the FMRS thread about it. There's a chance I'll write it up and submit a PR to FMRS myself since LGG sounds like he's pretty busy right now.

Share this post


Link to post
Share on other sites
17 minutes ago, magico13 said:

FMRS might not be triggering the standard recovery event, in which case it'll need to go through ScrapYard's API to add the parts manually (which is what StageRecovery does). Post over in the FMRS thread about it. There's a chance I'll write it up and submit a PR to FMRS myself since LGG sounds like he's pretty busy right now.

What recovery event?

It may be a problem, since FMRS works by using multiple save files, and restores.

Share this post


Link to post
Share on other sites
13 minutes ago, linuxgurugamer said:

What recovery event?

It may be a problem, since FMRS works by using multiple save files, and restores.

GameEvents.onVesselRecovered. You can just feed ScrapYard a list of either Parts or Part ConfigNodes through the API (or a list of ProtoPartSnapshots if referencing SY directly, but the wrapper doesn't expose that right now since nobody needs it) to have parts added to the inventory, so even if you just make a big list of parts that were recovered and feed them through later then that would work. You've got to be adding funds, science, and Kerbals at some point so you can just do it then. If you fire onVesselRecovered then ScrapYard will handle stuff automatically, but that's all stored in the save and might get lost when FMRS changes stuff.

Share this post


Link to post
Share on other sites

Do you have some example code showing me how to contact scrapyard?

As you said, im busy right now woth the Suicide Burn mod, but this could be a nice break.

Share this post


Link to post
Share on other sites
22 minutes ago, linuxgurugamer said:

Do you have some example code showing me how to contact scrapyard?

Sure, start by adding the wrapper to your mod. You probably will only need to call AddPartsToInventory and you will want to pass "true" for incrementRecovery since you're doing a regular recovery. You can use either the IEnumerable<Part> or IEnumerable<ConfigNode> version depending on what you have available. Don't worry about checking for availability first since the wrapper will handle that.

Here are a few examples: StageRecovery adding parts on recovery and KCT adding parts when scrapping

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.