Extending power fixed range

Started by amiroll999, April 01, 2020, 03:14:56 PM

Previous topic - Next topic

amiroll999

Hi guys. I'm new to assemblies modding and I only knew how to make .XML files.

Right now I'm trying to make a tesla coil generator mod. I know there is the Power++ mod but the wireless system gave me a headache plus with the power trading and incidents. So I tried making my own.

The tesla coil should generate let say 5000W in a radius of 25. I can edit the power generated in .XML. The problem for me is the radius. I've found the class for power connection:

using System;
using System.Collections.Generic;
using Verse;

namespace RimWorld
{
// Token: 0x020011CD RID: 4557
public static class PowerConnectionMaker
{
// Token: 0x06006268 RID: 25192
public static void ConnectAllConnectorsToTransmitter(CompPower newTransmitter)
{
foreach (CompPower compPower in PowerConnectionMaker.PotentialConnectorsForTransmitter(newTransmitter))
{
if (compPower.connectParent == null)
{
compPower.ConnectToTransmitter(newTransmitter, false);
}
}
}

// Token: 0x06006269 RID: 25193
public static void DisconnectAllFromTransmitterAndSetWantConnect(CompPower deadPc, Map map)
{
if (deadPc.connectChildren == null)
{
return;
}
for (int i = 0; i < deadPc.connectChildren.Count; i++)
{
CompPower compPower = deadPc.connectChildren[i];
compPower.connectParent = null;
CompPowerTrader compPowerTrader = compPower as CompPowerTrader;
if (compPowerTrader != null)
{
compPowerTrader.PowerOn = false;
}
map.powerNetManager.Notify_ConnectorWantsConnect(compPower);
}
}

// Token: 0x0600626A RID: 25194
public static void TryConnectToAnyPowerNet(CompPower pc, List<PowerNet> disallowedNets = null)
{
if (pc.connectParent != null)
{
return;
}
if (!pc.parent.Spawned)
{
return;
}
CompPower compPower = PowerConnectionMaker.BestTransmitterForConnector(pc.parent.Position, pc.parent.Map, disallowedNets);
if (compPower != null)
{
pc.ConnectToTransmitter(compPower, false);
return;
}
pc.connectParent = null;
}

// Token: 0x0600626B RID: 25195
public static void DisconnectFromPowerNet(CompPower pc)
{
if (pc.connectParent == null)
{
return;
}
if (pc.PowerNet != null)
{
pc.PowerNet.DeregisterConnector(pc);
}
if (pc.connectParent.connectChildren != null)
{
pc.connectParent.connectChildren.Remove(pc);
if (pc.connectParent.connectChildren.Count == 0)
{
pc.connectParent.connectChildren = null;
}
}
pc.connectParent = null;
}

// Token: 0x0600626C RID: 25196
private static IEnumerable<CompPower> PotentialConnectorsForTransmitter(CompPower b)
{
if (!b.parent.Spawned)
{
Log.Warning("Can't check potential connectors for " + b + " because it's unspawned.", false);
yield break;
}
CellRect rect = b.parent.OccupiedRect().ExpandedBy(6).ClipInsideMap(b.parent.Map);
int num;
for (int z = rect.minZ; z <= rect.maxZ; z = num + 1)
{
for (int x = rect.minX; x <= rect.maxX; x = num + 1)
{
IntVec3 c = new IntVec3(x, 0, z);
List<Thing> thingList = b.parent.Map.thingGrid.ThingsListAt(c);
for (int i = 0; i < thingList.Count; i = num + 1)
{
if (thingList[i].def.ConnectToPower)
{
yield return ((Building)thingList[i]).PowerComp;
}
num = i;
}
thingList = null;
num = x;
thingList = null;
thingList = null;
thingList = null;
thingList = null;
thingList = null;
thingList = null;
thingList = null;
}
num = z;
}
yield break;
}

// Token: 0x0600626D RID: 25197
public static CompPower BestTransmitterForConnector(IntVec3 connectorPos, Map map, List<PowerNet> disallowedNets = null)
{
CellRect cellRect = CellRect.SingleCell(connectorPos).ExpandedBy(6).ClipInsideMap(map);
cellRect.ClipInsideMap(map);
float num = 999999f;
CompPower result = null;
for (int i = cellRect.minZ; i <= cellRect.maxZ; i++)
{
for (int j = cellRect.minX; j <= cellRect.maxX; j++)
{
Building transmitter = new IntVec3(j, 0, i).GetTransmitter(map);
if (transmitter != null && !transmitter.Destroyed)
{
CompPower powerComp = transmitter.PowerComp;
if (powerComp != null && powerComp.TransmitsPowerNow && (transmitter.def.building == null || transmitter.def.building.allowWireConnection) && (disallowedNets == null || !disallowedNets.Contains(powerComp.transNet)))
{
float num2 = (float)(transmitter.Position - connectorPos).LengthHorizontalSquared;
if (num2 < num)
{
num = num2;
result = powerComp;
}
}
}
}
}
return result;
}

// Token: 0x040040CB RID: 16587
private const int ConnectMaxDist = 6;
}
}



I tried changing ConnectMaxDist value to 25:

private const int ConnectMaxDist = 6;

but it doesn't do anything.


Then I tried changing ExpandedBy() value to 25:

public static CompPower BestTransmitterForConnector(IntVec3 connectorPos, Map map, List<PowerNet> disallowedNets = null)
{
CellRect cellRect = CellRect.SingleCell(connectorPos).ExpandedBy(6).ClipInsideMap(map);
cellRect.ClipInsideMap(map);
float num = 999999f;
CompPower result = null;
for (int i = cellRect.minZ; i <= cellRect.maxZ; i++)
{
for (int j = cellRect.minX; j <= cellRect.maxX; j++)
{
Building transmitter = new IntVec3(j, 0, i).GetTransmitter(map);
if (transmitter != null && !transmitter.Destroyed)
{
CompPower powerComp = transmitter.PowerComp;
if (powerComp != null && powerComp.TransmitsPowerNow && (transmitter.def.building == null || transmitter.def.building.allowWireConnection) && (disallowedNets == null || !disallowedNets.Contains(powerComp.transNet)))
{
float num2 = (float)(transmitter.Position - connectorPos).LengthHorizontalSquared;
if (num2 < num)
{
num = num2;
result = powerComp;
}
}
}
}
}
return result;
}


And it works! But it changes all of the generators range. So, I needed to make a new Comp to target only the tesla coil.

The problem is I don't really know how to create Comp.

Correct me if I'm wrong:

using System;
using RimWorld;
using UnityEngine;
using Verse;

namespace EnergyBeacon
{
[StaticConstructorOnStartup]
public class EB_CompPowerPlantPatch : CompPowerPlant
{
public override CompPower BestTransmitterForConnector(IntVec3 connectorPos, Map map, List<PowerNet> disallowedNets = null)
{
CellRect cellRect = CellRect.SingleCell(connectorPos).ExpandedBy(25).ClipInsideMap(map);
cellRect.ClipInsideMap(map);
float num = 999999f;
CompPower result = null;
for (int i = cellRect.minZ; i <= cellRect.maxZ; i++)
{
for (int j = cellRect.minX; j <= cellRect.maxX; j++)
{
Building transmitter = new IntVec3(j, 0, i).GetTransmitter(map);
if (transmitter != null && !transmitter.Destroyed)
{
CompPower powerComp = transmitter.PowerComp;
if (powerComp != null && powerComp.TransmitsPowerNow && (transmitter.def.building == null || transmitter.def.building.allowWireConnection) && (disallowedNets == null || !disallowedNets.Contains(powerComp.transNet)))
{
float num2 = (float)(transmitter.Position - connectorPos).LengthHorizontalSquared;
if (num2 < num)
{
num = num2;
result = powerComp;
}
}
}
}
}
return result;
}
}
}


The actual problem is my laptop only got Visual Studio 2005 and I can't seem to install Visual Studio 2015. I've been trying to make this mod for 2 weeks.

Here's a few question:

  • Can you make an assemblies without IDE?
  • Can anyone teach me how to make a functional Comp?


It would be much appreciated if someone could compile those for me. (If the code is correct I supposed)  ;D ;D ;D

ethouiche

#1
you need to create a ThingComp class like this :
https://github.com/goudaQuiche/LTF_CloneBay/blob/master/1.1/Source/RimWorld_ExampleProjectDLL/Comp_LTF_MeatGrinder.cs
You can also choose a power comp related to your problem and override some methods when needed.
You will still need an xml definition for your new building, specifying it uses the new comp you have created.

If you cant compile anything, it will be very hard to test.
cant you install this https://visualstudio.microsoft.com/fr/vs/community/ ?

amiroll999

Quote from: ethouiche on April 02, 2020, 07:12:19 AM
you need to create a ThingComp class like this :
https://github.com/goudaQuiche/LTF_CloneBay/blob/master/1.1/Source/RimWorld_ExampleProjectDLL/Comp_LTF_MeatGrinder.cs
You can also choose a power comp related to your problem and override some methods when needed.
You will still need an xml definition for your new building, specifying it uses the new comp you have created.

If you cant compile anything, it will be very hard to test.
cant you install this https://visualstudio.microsoft.com/fr/vs/community/ ?


I've finally finished my Visual Studio installation with a lot of errors but still usable I guess.
And that is one long code. I don't need to make it long like that if I just wanna change a single value, right?

Is that ExpandedBy() hardcoded?

I'll try making the Comp and see where it goes.

I wish I could make the tesla coil attract lightning then convert it into fuel and save the map from burning.

Moogie

You might be able to examine the existing "Lightning Rod" mod on the Steam workshop to see how they accomplished this. It doesn't create fuel but it does attract lightning and I think it might also feed the gathered power to batteries? Or maybe it just disperses it, I forget.

amiroll999

Quote from: Moogie on April 02, 2020, 11:51:30 AM
You might be able to examine the existing "Lightning Rod" mod on the Steam workshop to see how they accomplished this. It doesn't create fuel but it does attract lightning and I think it might also feed the gathered power to batteries? Or maybe it just disperses it, I forget.


Thanks for the suggestion. I didn't know about this mod until now. I'll try take a look.

My VS is taking too long to create a new project. 2 hours already. Is it supposed to take this long?

LWM

If VS is throwing errors or taking 2 hours to start a project?

Completely uninstall it and start over.  Which version are you using?  The Community version is free; there's links around here in the forum (I assume you're using Windows?) and it seems to work for ppl.

As far as your comp....what are you trying to accomplish?

Changing that 6 to 25 would change the length of wires things that draw power can use to connect to a grid, no?  I don't think that's the effect you want?


amiroll999

Quote from: LWM on April 02, 2020, 01:07:41 PM

If VS is throwing errors or taking 2 hours to start a project?

Completely uninstall it and start over.  Which version are you using?  The Community version is free; there's links around here in the forum (I assume you're using Windows?) and it seems to work for ppl.



I'm using VS 2015. I created new project Visual C# Class Library with Target .NET Framework 3.5. I can't use Class Library .NET Framework since I'm using VS 2015. It didn't throw me any errors but I already finished watching movie and it still 'creating project'.

Right now I'm trying to install VS 2017 hoping it would fix this and not burning up my laptop. My internet network is making fun of me by throwing me with only 25kb/s since the lockdown started. Its gonna take a while.


Quote from: LWM on April 02, 2020, 01:07:41 PM

Changing that 6 to 25 would change the length of wires things that draw power can use to connect to a grid, no?  I don't think that's the effect you want?



By changing the ExpandedBy() value, the radius for power supplies changes. It only alters the PowerConnectionMaker afaik. For the wire thingy, there's some coding that draws the wire. I could change the code to make it invisible without affecting PowerConnectionMaker. So, it would look like the power is transmitted wirelessly.


Quote from: LWM on April 02, 2020, 01:07:41 PM

As far as your comp....what are you trying to accomplish?


I'm trying to make a Comp copies of CompPower_Properties/CompPowerPlant but only changes the ExpandedBy value from PowerConnectionMaker. I assume that it's related. Am I right?

Later I will try altering the code for the wire but right now I wanted to make sure that it's  functional. The wire didn't bother much since I turned off the power layout.

Moogie

I believe you need to be using .NET Framework 4.5 or later, the wiki is outdated in that respect.

LWM

Yes, it's .net framework 4.7.2 now.

What effect in the game are you looking for?  Wireless power from the generator?  Can wire pick up that power? Or do you only want buildings that are within 25 distance from the generator to work?

The VS situation sounds awful; I hope it gets easier for you  :-\  I run Linux and am having good success with mono, so I haven't had to deal with the VS stuff much.

amiroll999

Quote from: LWM on April 02, 2020, 05:57:05 PM

The VS situation sounds awful; I hope it gets easier for you  :-\  I run Linux and am having good success with mono, so I haven't had to deal with the VS stuff much.


Done installing VS 2017 and still have the same problem. Created a new project and its already 2 hours. I'm so close to losing it.


Quote from: LWM on April 02, 2020, 05:57:05 PM

What effect in the game are you looking for?  Wireless power from the generator?  Can wire pick up that power? Or do you only want buildings that are within 25 distance from the generator to work?



I want a wireless power from the generator that only work if the building is within 25 radius.

Is there a tag for CompProperties_Power that can change the distance? I can't seem to find it thats why I'm trying to make a new Comp.

amiroll999


I think I'm wrong about the code. How can I extend the power fixed range? What I know is that the fixed range is directly from ExpandedBy(int) in the PowerConnectionMaker.BestTransmitterForConnector. I tried overriding ExpandedBy(int) but what I found out is that PowerConnectionMaker.BestTransmitterForConnector only read it once making it fixed. I maybe wrong about this. So, what I need to do is override the PowerConnectionMaker.BestTransmitterForConnector, right? So, how do I do this?

Here's the code:
public static CompPower BestTransmitterForConnector(IntVec3 connectorPos, Map map, List<PowerNet> disallowedNets = null)
{
CellRect cellRect = CellRect.SingleCell(connectorPos).ExpandedBy(6).ClipInsideMap(map);
cellRect.ClipInsideMap(map);
float num = 999999f;
CompPower result = null;
for (int i = cellRect.minZ; i <= cellRect.maxZ; i++)
{
for (int j = cellRect.minX; j <= cellRect.maxX; j++)
{
Building transmitter = new IntVec3(j, 0, i).GetTransmitter(map);
if (transmitter != null && !transmitter.Destroyed)
{
CompPower powerComp = transmitter.PowerComp;
if (powerComp != null && powerComp.TransmitsPowerNow && (transmitter.def.building == null || transmitter.def.building.allowWireConnection) && (disallowedNets == null || !disallowedNets.Contains(powerComp.transNet)))
{
float num2 = (float)(transmitter.Position - connectorPos).LengthHorizontalSquared;
if (num2 < num)
{
num = num2;
result = powerComp;
}
}
}
}
}
return result;
}




And even if I got it to work. Then the PowerConnectionMaker.BestTransmitterForConnector will still become fixed with the new value. I tried looking at Power++,Power Logic and ED-Prometheus but I can't understand their coding.


How can I override PowerConnectionMaker.BestTransmitterForConnector?


My VS is not working for me. Reinstalled 3 time still a no. So, I had to use the hard way. I'm currently compiling directly to Rimworld assembly using dnSpy.

LWM

My initial thought is that "this is tricky."  The connector looks for power grids, doesn't it?

I would see if you can either get VS - of some variety - working (maybe you have some outdated Windows files that don't work?) or....I highly recommend Mint Linux and monodevelop.  If you can manage to recompile dlls using DnSpy, you can manage a linux dual boot ;)  Or who knows, maybe there's a command-line mono for windows.

As far as the power connector question goes....heard of Harmony?

I think you would need to modify two functions from PowerConnectionMaker:
PotentialConnectorsForTransmitter - a Postfix() operation to add (to the top of your list, perhaps?) your Tesla generator if it's within 25 cells?  But you would want to check: is the new transmitter a CompPowerTransmitter with a power draw (only things that draw power, not conduits or other generators).
BestTransmitterForConnector - a bool Prefix() operation that checks if it's a CompPowerTransmitter as above, and if so, looks for your Tesla generator, and if it finds it, returns false, to override the vanilla operation.

Alternately, you could create a special wireless antenna to pick up the Tesla generator - make it derived from the vanilla power conduit, and give it a special connection to any Tesla generators it finds.  The generator would also have to look for them when it gets built.  This option might be easier.