Jump to content

Need help developing a science station mod


CiberX15

Recommended Posts

Ok, I am working on a mod where I am attempting to make space stations more valuable in career mode. What I am doing is creating a new part/module that consumes electrical energy and a new resource "Snacks" to gain science. The way it works is it calculates how long it has been running + the amount of kerbals - their stupidity. My aim is for it to generate roughly +100 science per Kerbin year in high Kerbin orbit (should be somewhat more if players manage to get it into orbit around other celestial bodies). The idea is that players could use it as a little surplus of science in-between interplanetary missions but not spam it. Requiring "Snacks" also means players will have to do some station upkeep without resorting to hard mode methods like food and oxygen supply that kill kerbals.

Now I have this 80% working already, even have custom models and everything but I am having problems with two things. One, the module is extended from theModuleScienceExperiment and simply sets the experiment basevalue, science cap, and datascale depending on how much "research" has been done when the player activates the experiment. Part of my problem is I don't know how these values actually control the science. For example if I want the science gained to be exactly +24 how would I manipulate the variables to reflect that?

Secondly, once the experiment has been transmitted, it losses scientific value, that's fine for normal experiments but I need this one to be reset each time because it represents scientists doing different research projects each time. For example if the player has had the station in orbit for a year and sends +100 data back to Kerbin, then waits another Kerbin year, rather than getting another +100 like I want them to, they would get +0 or +50 since so far as the game is concerned the experiment has already been done. I need it to consistently return 100% of the science regardless of repeat experiments.

Thank you in advance for anyone who can help me figure this out : )

code below


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;



/// <summary>
/// My first part!
/// </summary>
public class ScienceTrickle : ModuleScienceExperiment
{
[KSPField(isPersistant = true, guiActive = false)]
protected float last_active_time;

[KSPField(isPersistant = true, guiActive = true)]
protected bool IsEnabled;

[KSPField(isPersistant = true, guiActive = false)]
protected float ResearchTime;

[KSPField(isPersistant = true, guiActive = true)]
protected string CurrentPaper;

protected float crew_capacity_ratio;

[KSPField(isPersistant = true, guiActive = false)]
protected double StoredScience;

[KSPField(isPersistant = true, guiActive = true)]
protected float RecordedData;

protected float LastCheckTime = 5;
/// <summary>
/// Called when the part is started by Unity.
/// </summary>
public override void OnStart(StartState state)
{
base.OnStart(state);

// Check our crew
crew_capacity_ratio = ((float)part.protoModuleCrew.Count) / ((float)part.CrewCapacity);

//make sure we check the science when we startup
LastCheckTime = 5;

}

//Begin Research Button
[KSPEvent(guiActive = true, guiName = "Begin Research", active = true)]
public void BeginResearch()
{
if (crew_capacity_ratio == 0) { return; }
last_active_time = (float)Planetarium.GetUniversalTime();
StoredScience = 0;
RecordedData = 0;
IsEnabled = true;
}

//Stop Research Button
[KSPEvent(guiActive = true, guiName = "Stop Research", active = true)]
public void StopActivity()
{
IsEnabled = false;
}

public void CheckFindings()
{
/*
//find time passed
double now = Planetarium.GetUniversalTime();
double time_diff = Math.Round(now - last_active_time);
//correct negitive time (wait what does that even mean?!)
if(time_diff < 0) time_diff = 0;
*/
//set altitude mod
float altitude_multiplier = (float)(vessel.altitude / (vessel.mainBody.Radius));
altitude_multiplier = Math.Max (altitude_multiplier, 1);

//crew mod
float CrewMod = 0;

//calculate crew contributions
foreach (ProtoCrewMember proto_crew_member in part.protoModuleCrew)
{
CrewMod += 1 - proto_crew_member.stupidity;

}

//compute science gain (should gain ~100 science per crew per kerbin year if in orbit around kerbin)
double science_to_add = /*time_diff*/ CrewMod;

//add collected science
StoredScience += science_to_add;

RecordedData = Mathf.Round((float)StoredScience);
base.experiment.baseValue = (float)RecordedData;
base.experiment.scienceCap = (float)RecordedData;
base.experiment.dataScale = (float)RecordedData;
}

//Always Update
public override void OnUpdate()
{
//if the modual is suposed to be making science!
if(IsEnabled)
{
float ResourceDraw = part.protoModuleCrew.Count;
if(ResourceDraw > 0 && part.RequestResource("ElectricCharge", ResourceDraw * 0.25f) >= ResourceDraw * 0.25f)
{
ResearchTime += (float)Planetarium.GetUniversalTime() - (float)last_active_time;
float Percent = (ResearchTime / 864000) * 100;
CurrentPaper = 0.01 * Math.Round(Percent * 100) + "%";

if(ResearchTime >= 864000)
{
if(part.RequestResource("Snacks", ResourceDraw) >= ResourceDraw)
{
ResearchTime = 0;
last_active_time = (float)Planetarium.GetUniversalTime();
CheckFindings();
}
else
{
//shutdown if out of snacks
IsEnabled = false;
print ("Not enough snacks, shutting down");
}
}
}
else
{
//shutdown if out of power
IsEnabled = false;
print ("Not enough power, shutting down");
}
}

base.OnUpdate();
}


//In Game Update
public override void OnFixedUpdate()
{
//last_active_time = (float)Planetarium.GetUniversalTime ();

base.OnUpdate();
}
}


/*

if (active_mode == 0) { // Science persistence



ResearchAndDevelopment.Instance.Science = ResearchAndDevelopment.Instance.Science + (float)StoredScience;

*/

Edited by CiberX15
Link to comment
Share on other sites

Hey there! That sounds interesting, because the mod I will be making is adding cargo spaces in command pods so that player can decide how much "snack" and oxygen will be stored in the space ship. My goal was to make space station resupply missions have a purpose. I cannot help with coding though, since I am newly learning C# . However, after you solve the problem and release your mod, my mod will be compatible with yours! :)

Link to comment
Share on other sites

At the moment I am setting all of the values to the same number, this seems to return predictable numbers the first time I submit the data. It would really help if someone could explain what each variable does : { Can I assume The science value cap is the maximum amount of science that can be gained from an experiment at a given location/altitude?

If so that would actually work out alright since it would force players to eventually build stations further and further into space, but only after having exhausted an area.

Link to comment
Share on other sites

Ok I think I have it working Acceptably based on the above (Thanks DMagic).

I set the science cap to 5000 so (assuming I was correct above) the maximum science that can be mined from any given location/altitude is 5000. For balance I will may lower this to 1000 to encourage players to build new stations around other celestial bodies and give players a valid reason to de-orbit their space stations (which is arguably more fun than putting them up in the first place).

Also, for anyone having similar issues I changed the lines:


RecordedData = Mathf.Round((float)StoredScience);
base.experiment.baseValue = (float)RecordedData;
base.experiment.scienceCap = (float)RecordedData;
base.experiment.dataScale = (float)RecordedData;

to


RecordedData = Mathf.Round((float)StoredScience);
base.experiment.baseValue = (float)RecordedData;

which seems to have solved my unpredictable science returns issue.

It's 12:30am here so I am going to head to bed, but with these issues resolved you will probably see the mod going up sometime tomorrow(today). Ill post a link here when I have one : )

Link to comment
Share on other sites

found another bug that I could use some help solving 8 0

The system works fine as long as there is only one Lab in use at any given time. But because an active lab changes the Experiment.BaseValue all other labs besides the first lab act very strangely. I think perhaps I need to have each lab dynamically generate its own uniquely named Experiments at run time. There only needs to be one experiment definition per lab since each lab would overwrite the data each time they record their findings, but they need to be separate so that lab B does not read lab A's experiment definition.

Thanks In advance...

...Again 8 P

Edited by CiberX15
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...