Skip to content

Commit

Permalink
implemented extra compontents selection for vehicles, based on Vehicl…
Browse files Browse the repository at this point in the history
…eDef.CompRules

fix flickering textures on vehicles, containing extra components in0finite#86
  • Loading branch information
GoverLabs committed Jul 17, 2022
1 parent 6f0605f commit d25b6c7
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 6 deletions.
168 changes: 165 additions & 3 deletions Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,15 @@ public enum DoorAlignment
LeftRear,
}

private static VehicleDef[] _sRandomSpawnable;
public enum VehicleComponentsRules
{
ALLOW_ALWAYS = 1,
ONLY_WHEN_RAINING = 2,
MAYBE_HIDE = 3,
FULL_RANDOM = 4,
}

private static VehicleDef[] _sRandomSpawnable;
private static int _sMaxSpawnableIndex;

private static VehicleDef[] GetRandomSpawnableDefs(out int maxIndex)
Expand Down Expand Up @@ -287,9 +295,11 @@ public bool IsDriver

private readonly List<Wheel> _wheels = new List<Wheel>();
private readonly List<Seat> _seats = new List<Seat>();
private readonly List<Frame> _extras = new List<Frame>();

public List<Wheel> Wheels { get { return _wheels; } }
public List<Wheel> Wheels { get { return _wheels; } }
public List<Seat> Seats { get { return _seats; } }
public List<Frame> Extras { get { return _extras; } }

private WheelAlignment GetWheelAlignment(string frameName)
{
Expand Down Expand Up @@ -405,6 +415,11 @@ private void Initialize(VehicleDef def, int[] colors = null)

foreach (var frame in _frames)
{
if (frame.Name.StartsWith("extra"))
{
_extras.Add(frame);
}

if (!frame.Name.StartsWith("wheel_")) continue;
if (!frame.Name.EndsWith("_dummy")) continue;

Expand Down Expand Up @@ -463,6 +478,8 @@ private void Initialize(VehicleDef def, int[] colors = null)
}
}

SelectExtras();

InitializePhysics();

this.Health = this.MaxHealth = Mathf.Pow(this.HandlingData.Mass, VehicleManager.Instance.massToHealthExponent);
Expand Down Expand Up @@ -618,5 +635,150 @@ void SetupDoorsHingeJoints()
hinge.connectedBody = gameObject.GetComponent<Rigidbody>();
}
}
}

private void SelectExtras()
{
int firstExtraIdx = -1;
int secondExtraIdx = -1;

VehicleDef.CompRulesUnion compsUnion = Definition.CompRules;
if (compsUnion.HasExtraOne())
{
firstExtraIdx = ChooseComponent(Definition.CompRules.nExtraARule, compsUnion.nExtraAComp);
}

if (compsUnion.HasExtraTwo())
{
firstExtraIdx = ChooseComponent(compsUnion.nExtraBRule, compsUnion.nExtraBComp);
}

foreach (var extra in Extras)
{
Boolean isFirstExtra = extra.Name == ("extra" + firstExtraIdx.ToString());
Boolean isSecondExtra = extra.Name == ("extra" + secondExtraIdx.ToString());

extra.gameObject.SetActive(isFirstExtra || isSecondExtra);
}
}

private int ChooseComponent(int rule, int comps)
{
VehicleDef.CompRulesUnion compsUnion = Definition.CompRules;

if ((rule != 0) && IsValidCompRule(rule))
{
return ChooseComponentInternal(rule, comps);
}
else if (UnityEngine.Random.Range(0, 3) < 2)
{
int[] anVariations = new int[6];
int numComps = GetListOfComponentsNotUsedByRules(Extras.Count, anVariations);
if (numComps > 0)
return anVariations[UnityEngine.Random.Range(0, numComps)];
}

return -1;
}

private bool IsValidCompRule(int nRule)
{
// TODO add weather checking, when weather is implemented.
Boolean isRainingNow = false;

return (nRule != (int)VehicleComponentsRules.ONLY_WHEN_RAINING)
|| isRainingNow
;
}

private int ChooseComponentInternal(int rule, int comps)
{
int component = -1;
if (rule == (int)VehicleComponentsRules.ALLOW_ALWAYS ||
rule == (int)VehicleComponentsRules.ONLY_WHEN_RAINING)
{
int iNumComps = CountCompsInRule(comps);
int rand = UnityEngine.Random.Range(0, iNumComps);
component = (comps >> (4 * rand)) & 0xF;
}
else if (rule == (int)VehicleComponentsRules.MAYBE_HIDE)
{
int iNumComps = CountCompsInRule(comps);
int rand = UnityEngine.Random.Range(-1, iNumComps);
if (rand != -1)
component = (comps >> (4 * rand)) & 0xF;
}
else if (rule == (int)VehicleComponentsRules.FULL_RANDOM)
{
component = UnityEngine.Random.Range(0, 5);
}

return component;
}

int CountCompsInRule(int comps)
{
int result = 0;
while (comps != 0)
{
if ((comps & 0xF) != 0xF)
++result;

int a = comps / 16;
int b = comps >> 4;

comps >>= 4;
}

return result;
}

int GetListOfComponentsNotUsedByRules(int numExtras, int[] outList)
{
int[] iCompsList = new int[]{ 0, 1, 2, 3, 4, 5 };

VehicleDef.CompRulesUnion comps = Definition.CompRules;

if (comps.nExtraARule != 0 && IsValidCompRule(comps.nExtraARule))
{
if (comps.nExtraARule == (int)VehicleComponentsRules.FULL_RANDOM)
return 0;

if (comps.nExtraA_comp1 != 0xF)
iCompsList[comps.nExtraA_comp1] = 0xF;

if (comps.nExtraA_comp2 != 0xF)
iCompsList[comps.nExtraA_comp2] = 0xF;

if (comps.nExtraA_comp3 != 0xF)
iCompsList[comps.nExtraA_comp3] = 0xF;
}

if (comps.nExtraBRule != 0 && IsValidCompRule(comps.nExtraBRule))
{
if (comps.nExtraBRule == (int)VehicleComponentsRules.FULL_RANDOM)
return 0;

if (comps.nExtraB_comp1 != 0xF)
iCompsList[comps.nExtraA_comp1] = 0xF;

if (comps.nExtraB_comp2 != 0xF)
iCompsList[comps.nExtraA_comp2] = 0xF;

if (comps.nExtraB_comp3 != 0xF)
iCompsList[comps.nExtraA_comp3] = 0xF;
}

int iNumComps = 0;
for (int i = 0; i < numExtras; ++i)
{
if (iCompsList[i] == 0xF)
continue;

outList[iNumComps] = i;
++iNumComps;
}

return iNumComps;
}
}
}
55 changes: 52 additions & 3 deletions Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,56 @@ public enum VehicleType
[Section("cars")]
public class VehicleDef : Definition, IObjectDefinition
{
public readonly int Id;
public struct CompRulesUnion
{
public int nExtraA_comp1;
public int nExtraA_comp2;
public int nExtraA_comp3;

public int nExtraB_comp1;
public int nExtraB_comp2;
public int nExtraB_comp3;

public int nExtraAComp;
public int nExtraARule;
public int nExtraBComp;
public int nExtraBRule;

public int nExtraA;
public int nExtraB;

public CompRulesUnion(int value)
{
nExtraA = (value & 0x0000FFFF) >> 0;
nExtraB = (int)(value & 0xFFFF0000) >> 16;

nExtraAComp = (nExtraA & 0x0FFF) >> 0;
nExtraARule = (nExtraA & 0xF000) >> 12;

nExtraBComp = (nExtraB & 0x0FFF) >> 0;
nExtraBRule = (nExtraB & 0xF000) >> 12;

nExtraA_comp1 = (nExtraA & 0x000F) >> 0;
nExtraA_comp2 = (nExtraA & 0x00F0) >> 4;
nExtraA_comp3 = (nExtraA & 0x0F00) >> 8;

nExtraB_comp1 = (nExtraB & 0x000F) >> 0;
nExtraB_comp2 = (nExtraB & 0x00F0) >> 4;
nExtraB_comp3 = (nExtraB & 0x0F00) >> 8;
}

public Boolean HasExtraOne()
{
return nExtraA != 0;
}

public Boolean HasExtraTwo()
{
return nExtraB != 0;
}
}

public readonly int Id;

int IObjectDefinition.Id
{
Expand All @@ -39,7 +88,7 @@ int IObjectDefinition.Id

public readonly int Frequency;
public readonly int Flags;
public readonly int CompRules;
public readonly CompRulesUnion CompRules;

public readonly bool HasWheels;

Expand All @@ -65,7 +114,7 @@ public VehicleDef(string line) : base(line)

Frequency = GetInt(8);
Flags = GetInt(9);
CompRules = GetInt(10, NumberStyles.HexNumber);
CompRules = new CompRulesUnion(GetInt(10, NumberStyles.HexNumber));

HasWheels = Parts >= 15;

Expand Down

0 comments on commit d25b6c7

Please sign in to comment.