Jump to content

.20 And mods


DYJ

Recommended Posts

Not sure if this is entirely new with 0.20, but I found a static GameEvent class that lets you register delegates for a whole ton of events.

https://gist.github.com/Cilph/baab143258211f852dfe

That's a very useful list!

I used one of them before, the onGamePause. Be warned that if you assign these events a function in a part module, and that part is destroyed, it will mess up all other actions that are supposed to happen on game pause, like stopping physics.

So remember to assign a remove of the event action on the part's OnDestroy()

edit:

example:

public void OnStart()
{
GameEvents.onGamePause.Add(new EventVoid.OnEvent(this.OnPause));
}

void OnPause()
{
Debug.Log("Game Paused");
}

OnDestroy()
{
GameEvents.onGamePause.Remove(new EventVoid.OnEvent(this.OnPause));
}

Edited by Snjo
Link to comment
Share on other sites

That's a very useful list!

I used one of them before, the onGamePause. Be warned that if you assign these events a function in a part module, and that part is destroyed, it will mess up all other actions that are supposed to happen on game pause, like stopping physics.

If you're using a PartModule subclass or other Monobehaviour derived class then why not use OnApplicationPause instead?

Link to comment
Share on other sites

So solution for the custom sound's here. Anyone?

I'm making my own engine sound handler that loads sounds from the game database and plays it according to thrust.

For the very simple sound loading code/test, check this thread, otherwise full code:

plugin


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

public class FSengineSounds : PartModule
{
[KSPField]
public string engage;
[KSPField]
public string running;
[KSPField]
public string power;
[KSPField]
public string disengage;
[KSPField]
public string flameout;
[KSPField]
public string warning;
[KSPField]
public float powerFadeInSpeed = 0.02f;
[KSPField]
public float powerFadeInDelay = 0.0f;
[KSPField]
public float powerVolume = 1.0f;
[KSPField]
public float engageVolume = 1.0f;

[KSPField]
public float powerPitchBase = 0.8f;
[KSPField]
public float thrustAddedToPowerPitch = 0.3f;

[KSPField]
public bool useDebug = false;
[KSPField]
public bool showVolumeDebug = false;

private ModuleEngines engine;
private bool oldIgnitionState;
private bool oldFlameOutState;
private float currentPowerFadeIn;
private float currentPowerDelay;

private string doesExist = "...";

public FXGroup engageGroup;
public bool engageAssigned;
public FXGroup runningGroup;
public bool runningAssigned;
public FXGroup powerGroup;
public bool powerAssigned;
public FXGroup disengageGroup;
public bool disengageAssigned;
public FXGroup flameoutGroup;
public bool flameoutAssigned;
public FXGroup warningGroup;
public bool warningAssigned;

/// <summary>
/// Fills an FXGroup with sound values
/// </summary>
/// <param name="group">The group that will receive a new sound</param>
/// <param name="name">The name of the sound in the game database. No file extensions. e.g. Firespitter\Sounds\sound_fspropidle</param>
/// <param name="loop">Does the sound loop by default?</param>
/// <returns></returns>
public bool createGroup(FXGroup group, string name, bool loop)
{
if (name != string.Empty)
{
if (!GameDatabase.Instance.ExistsAudioClip(name))
return false;
group.audio = gameObject.AddComponent<AudioSource>();
group.audio.volume = GameSettings.SHIP_VOLUME;
group.audio.rolloffMode = AudioRolloffMode.Logarithmic;
group.audio.dopplerLevel = 0f;
group.audio.panLevel = 1f;
group.audio.clip = GameDatabase.Instance.GetAudioClip(name);
group.audio.loop = loop;
group.audio.playOnAwake = false;
return true;
}
return false;
}

private void OnDestroy()
{
GameEvents.onGamePause.Remove(new EventVoid.OnEvent(this.FSOnPause));
GameEvents.onGameUnpause.Remove(new EventVoid.OnEvent(this.FSOnUnPause));
}

private void FSOnPause()
{
powerGroup.audio.volume = 0f;
}

private void FSOnUnPause()
{
powerGroup.audio.volume = GameSettings.SHIP_VOLUME;
}

public override void OnStart(PartModule.StartState state)
{
base.OnStart(state);

engageAssigned = createGroup(engageGroup, engage, false);
runningAssigned = createGroup(runningGroup, running, true);
powerAssigned = createGroup(powerGroup, power, true);
disengageAssigned = createGroup(disengageGroup, disengage, true);
flameoutAssigned = createGroup(flameoutGroup, flameout, false);
warningAssigned = createGroup(warningGroup, warning, false);

engine = part.GetComponent<ModuleEngines>();

GameEvents.onGamePause.Add(new EventVoid.OnEvent(this.FSOnPause));
GameEvents.onGameUnpause.Add(new EventVoid.OnEvent(this.FSOnUnPause));

/*public string engage;
public string running;
public string power;
public string disengage;
public string flameout;
public string warning;*/

/* powerGroup.audio = gameObject.AddComponent<AudioSource>();
powerGroup.audio.volume = 1;
powerGroup.audio.Stop();*/
}

public override void OnFixedUpdate()
{
base.OnFixedUpdate();
if (engine != null)
{
if (TimeWarp.WarpMode == TimeWarp.Modes.HIGH && TimeWarp.CurrentRate > 1.1f)
{
if (powerAssigned)
powerGroup.audio.volume = 0f;
}
else
{
// power/running sound
if (engine.getIgnitionState && !engine.getFlameoutState)
{
if (currentPowerDelay > 0f)
currentPowerDelay -= Time.deltaTime;

float adjustedThrustPitch = ((engine.finalThrust / engine.maxThrust) * thrustAddedToPowerPitch) + powerPitchBase;
if (powerAssigned && currentPowerDelay <= 0f)
{
if (currentPowerFadeIn < 1f)
{
currentPowerFadeIn += powerFadeInSpeed;
if (currentPowerFadeIn > 1f)
currentPowerFadeIn = 1f;
}
powerGroup.audio.volume = GameSettings.SHIP_VOLUME * currentPowerFadeIn * powerVolume;
if (!powerGroup.audio.isPlaying)
powerGroup.audio.Play();
powerGroup.audio.pitch = adjustedThrustPitch;
}
}
else
{
if (powerAssigned)
{
if (powerGroup.audio.isPlaying)
powerGroup.audio.Stop();
currentPowerFadeIn = 0f;
currentPowerDelay = powerFadeInDelay;
}
}

// engage sound
if (engageAssigned)
{
if (engine.getIgnitionState && !oldIgnitionState)
{
if (!engine.getFlameoutState)
{
engageGroup.audio.volume = GameSettings.SHIP_VOLUME * engageVolume;
engageGroup.audio.Play();
}
}
oldIgnitionState = engine.getIgnitionState;
}

}

//if (part.temperature > part.maxTemp * warningSound)
//{
// if (timeCounter == 0)
// {
// heatDing.Play();
// }
// timeCounter++;
// if (timeCounter >= 100)
// {
// timeCounter = 0;
// }
//}
//else
//{
// timeCounter = 0;
//}
}
}

public void OnGUI()
{
if (showVolumeDebug)
GUI.Label(new Rect(250f, 300f, 200f, 30f), "engine volume: " + currentPowerFadeIn);
if (useDebug)
{
Rect menuItemRect = new Rect(250f, 200f, 300f, 150f);
Vector2 buttonSize = new Vector2(30f, 30f);
Vector2 menuItemSize = new Vector2(200f, 35f);
if (GUI.Button(new Rect(menuItemRect.x, menuItemRect.y, buttonSize.x, buttonSize.y), "OK"))
{
doesExist = "" + GameDatabase.Instance.ExistsAudioClip(power);
}

if (GUI.Button(new Rect(menuItemRect.x + buttonSize.x + 10f, menuItemRect.y, buttonSize.x, buttonSize.y), "C"))
{
doesExist = "clear";
}

if (GUI.Button(new Rect(menuItemRect.x + ((buttonSize.x + 10f) * 2), menuItemRect.y, buttonSize.x, buttonSize.y), ">"))
{
//powerGroup.audio.clip = GameDatabase.Instance.GetAudioClip(soundName);
//source.PlayOneShot(clip);
powerGroup.audio.Play();
}

GUI.Label(new Rect(menuItemRect.x + ((buttonSize.x + 10f) * 3), menuItemRect.y, menuItemSize.x - buttonSize.x - 10f, buttonSize.y),
"exists: " + doesExist);
menuItemRect.y += 30;
power = GUI.TextField(new Rect(menuItemRect.x + buttonSize.x + 10f, menuItemRect.y, menuItemSize.x - buttonSize.x - 10f, buttonSize.y), power);
}
}
}

part.cfg

PART
{
[...]

// --- general parameters ---
name = FScopterRotorMain
module = Part
author = Snjo

[...]

// --- FX definitions ---

//fx_exhaustLight_yellow = 0.0, -0.1, 0.0, 0.0, 0.0, 1.0, power
//fx_smokeTrail_light = 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, power
fx_exhaustSparks_flameout = 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, flameout

// --- Sound FX definition ---

//sound_fspropstart.wav = engage
//sound_fscoptermain.wav = power
sound_explosion_low = flameout

[...]

MODULE
{
name = FSengineSounds
useDebug = False
showVolumeDebug = True
engage = Firespitter/Sounds/sound_fspropstart
//running =
power = Firespitter/Sounds/sound_fscoptermain
//disengage =
//flameout =
warning = Firespitter/Sounds/sound_fsheatDing
powerPitchBase = 0.8
thrustAddedToPitch = 0.3
powerFadeInSpeed = 0.005
powerFadeInDelay = 1.0
powerVolume = 0.5
engageVolume = 1.5
}

MODULE
{
name = ModuleEngines
[...]
}

}

I'm building this for propeller engines, so I haven't implemented the minimum thrust threshold to stop the sound yet, like you would have with the jet engines.

And not all sounds are playing yet, but you get the idea hopefully.

Edited by Snjo
Link to comment
Share on other sites

No simple way to just put the wav name on part.cfg anymore???

OMG, to much code for a sound fx!!!

This will get fixed, but the way I understand it is, the engine stock sounds are loaded from unity, not from the folder structure into the game database.

The game database only contains other sounds. They ran into a bug where these sounds got loaded twice, so they removed the smarter method :)

In the old cfg parsing, all sounds were at some root level, now that that's no longer true, it doesn't parse that folder structure correctly, or we don't know how to write it in the cfg.

Most likely we will need to wait for a patch, and the write something new in the cfg file that includes the path in the game database.

Link to comment
Share on other sites

i think im just gonna disable the sounds in my mod for now, until this gets fixed. im calling this a bug (or an oversight) that will probibly be fixed in 0.20.1. it either didnt get implemented in the new system, or it did and the implementation didnt work, or it did work and there is something we need to do that we dont know about. really dont want to have to support sound effects with a plugin, especially since i only have one custom sound in my entire mod, and really dont want to use plugins at this time.

Link to comment
Share on other sites

If you're using a PartModule subclass or other Monobehaviour derived class then why not use OnApplicationPause instead?

KSP doesn't seem to trigger the OnApplicationPause event.

At least not when just throwing this in the plugin:

private void OnApplicationPause(bool pauseStatus)

{

Debug.Log("Paused: " + pauseStatus);

}

I was hoping for something like bool HighLogic.GameState.paused

But have come up empty so far.

Edited by Snjo
Link to comment
Share on other sites

I have a problem: I've added a few parts from .19 to the old "Parts" folder, and that resulted in the game not displaying any parts at all in the assembly screen (not even the stock parts that were in GameData/Squad/Parts folder). Removing the added parts made the stock ones reappear, but now I can't use any mods for .19. Is there any way to solve this problem?

Link to comment
Share on other sites

Try looking at the threads about the same problem, which forummembers have wrote exactly how to numerous times

This is a sticky for compiling information. Making a snarky comment when you could provide an answer in one or two sentences is marginal at the best of times and certainly isn't appropriate here.

Parts vanishing is caused by an error when constructing parts from configs, if the game comes across such an error it abandons the rest of that process and moves onto the next so only the parts loaded so far are created in game.

I've just hit it by forgetting to initialise a variable before using it in OnLoad in my plugin but I'd assume there are other problems that can cause it as well.

Link to comment
Share on other sites

ok...Im kinda new to KSP and honestly don't know the first thing about coding...im a metal worker by trade =P

but if I read all this right all I need to do to make a part 0.20 compatible is add {} to config and change scale to 1?

if this does work to I need to load them as legacy, or make game data folder like the mods that are already updated?

sorry for such a simple question, I know most of ya are probly having at laugh at me right now....and by all means have at it =)

Link to comment
Share on other sites

ok...Im kinda new to KSP and honestly don't know the first thing about coding...im a metal worker by trade =P

but if I read all this right all I need to do to make a part 0.20 compatible is add {} to config and change scale to 1?

if this does work to I need to load them as legacy, or make game data folder like the mods that are already updated?

sorry for such a simple question, I know most of ya are probly having at laugh at me right now....and by all means have at it =)

Add this to the top:

PART

{

And this to the bottom:

}

And if it's not there already, add the line

Scale = 1

You can put it in the GameData folder in a subfolder of your choosing. It would be good to replicate how the Squad folder is set up

Link to comment
Share on other sites

How hard is it really?

1 - For NEW mods (those that were specifically updated for 0.20), put the entire mod folder in GameData, next to the Squad folder.

2 - For LEGACY mods (the ones that you downloaded for previous versions), leave them in the same folders as they used to be. Don't change anything.

a - If you are having problems with attachment nodes, update the cfg files and add "scale = 1".

As a user, you should not have to worry about adding "Part { }" or moving existing mods around or editing configs, unless you are having attachment node problems.

Link to comment
Share on other sites

while sitting on my mod waiting for a sound fix to rear itself, i made use of the multi-part-per-file system and added larger versions of my more useful structural widgets to the mod, which has the added bonus of giving players additional options without adding expensive textures and models to the game database. of course now you have two identical parts and only the mouseover text to tell you any different. now im thinking it might be cool to make a fuel tank and have different versions of it with different fuels, but reusing the textures. for example give the tanks emmission maps for decals to identify their contents, and then just tweak the emmission color from unity and output a new model (but reuse the same textures). what would be even better is to be able to set the emmission color in the cfg, then one model and one set of textures will suffice for several different parts.

Link to comment
Share on other sites

I've created some batch scripts for Windows users to mass update part.cfg files to the new standard.

It also checks the "scale=" lines and warns you if it isn't present or contains anything other than "1.0" as a value.

So far, I've used it successfully on large packs, i.e. NovaPunch, KW Rocketry, MMI, etc...

See here:

http://forum.kerbalspaceprogram.com/showthread.php/31273-0-20-Part-cfg-Updater

Link to comment
Share on other sites

In case no one knew about this yet:

The attachpoint and scale problem for parts with "scale = 0.1" can be fixed by setting "scale = 1.0" in the part.cfg and dividing the "node_" entries by 10.

Link to comment
Share on other sites

Could you guy make please make an application that can do those modifications on every updates so conversion is faster since .cfg are kind of like .txt and changing file directory is coding basics ? I can't do it myself though. I would add in the cfg files :

PART

{

(No modifications)

}

and put all add ons in GameData

Thank for your replies :D

Edited by Jakey4159
Link to comment
Share on other sites

Could you guy make please make an application that can do those modifications on every updates so conversion is faster since .cfg are kind of like .txt and changing file directory is coding basics ? I can't do it myself though. I would add in the cfg files :

PART

{

(No modifications)

}

and put all add ons in GameData

Thank for your replies :D

Looks like this person made a ".bat" program to do just that.

Not sure how it works. But, the author claims to have successfully converted KW Rockets and NovaPunch.

Hope this helps.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...