Skip to content

Commit b38936f

Browse files
committed
Add new TS1 lot loader, fix FSO lighting
Still need to inherit neighbours on lot load, figure out what happens with vacation saves. FSO lighting for windows has been kind of broken for a while, this should fix it.
1 parent 36d55ed commit b38936f

File tree

16 files changed

+879
-96
lines changed

16 files changed

+879
-96
lines changed

TSOClient/FSO.IDE/EntityInspector.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void GetEntityList(List<InspectorEntityMeta> list)
6262
Entity = entity,
6363
ID = entity.ObjectID,
6464
Name = entity.ToString(),
65-
MultitileLead = entity.MultitileGroup.BaseObject.ObjectID,
65+
MultitileLead = entity.MultitileGroup.BaseObject?.ObjectID ?? 0,
6666
Container = (entity.Container == null) ? (short)0 : entity.Container.ObjectID,
6767
Slot = entity.ContainerSlot
6868
});

TSOClient/FSO.IDE/Utils/HouseSpy.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ private ListViewItem GetInteraction(string type, OBJMInteraction action)
184184
action.Priority.ToString(),
185185
action.ActionTreeID.ToString(),
186186
action.Attenuation.ToString(),
187-
action.Flags.ToString(),
187+
((int)action.Flags).ToString(),
188188
});
189189

190190
if (type == "#")
@@ -267,7 +267,7 @@ public void RedrawSelectedPerson()
267267
motiveChangeList.Items.Add(new ListViewItem(new string[]
268268
{
269269
((VMMotive)delta.Motive).ToString(),
270-
(delta.TickDelta * 18000).ToString(),
270+
(delta.TickDelta * 1800).ToString(),
271271
delta.StopAt.ToString()
272272
}));
273273
}

TSOClient/tso.files/Formats/IFF/Chunks/OBJM.cs

+35-19
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public OBJMFootprint(IffFieldEncode iop)
5858
public struct OBJMMotiveDelta
5959
{
6060
public int Motive;
61-
public float TickDelta; // 30 ticks per minute, 60 ticks per hour
61+
public float TickDelta; // 30 ticks per minute, 60 minutes per hour
6262
public float StopAt;
6363

6464
public OBJMMotiveDelta(IffFieldEncode iop)
@@ -69,6 +69,31 @@ public OBJMMotiveDelta(IffFieldEncode iop)
6969
}
7070
}
7171

72+
[Flags]
73+
public enum OBJMInteractionFlags
74+
{
75+
AutoFirst = 1,
76+
PushHeadContinuation = 2,
77+
UserInitiated = 4, // Interaction is not autonomous. Can be 0 for primitive pushed interactions until they actually run.
78+
CanBeAuto = 8, // check tree succeeds with param 0 == 1
79+
// 16: appears on goto work, group meal (push interaction? inherited? custom icon? doesn't show on person to person...)
80+
Unknown16 = 16, // Something to do with interaction push
81+
Completed = 32,
82+
CarryNameOver = 64,
83+
// 128: unknown - when non-active chars get called to meals (or carpool) this flag is set
84+
Unknown128 = 128, // Something to do with interaction push
85+
UserInterrupted = 256 // When the interaction has the X over it.
86+
}
87+
88+
public enum OBJMRoutingState
89+
{
90+
None = 0,
91+
Stopped = 3,
92+
Turning = 4,
93+
Accelerating = 6,
94+
Walking = 9
95+
}
96+
7297
public struct OBJMInteraction
7398
{
7499
public int UID;
@@ -80,16 +105,13 @@ public struct OBJMInteraction
80105
public int Priority;
81106
public short ActionTreeID;
82107
public float Attenuation;
108+
public OBJMInteractionFlags Flags;
83109

84-
// 1: unknown
85-
// 2: appears on group meal continuation
86-
// 4: user initiated? also appears for social interactions from other sim, but those use push interaction
87-
// 8: seems to randomly disappear (not on mourn/go here, is on "sit")
88-
// 16: appears on goto work, group meal continuation
89-
// 32: appears when the interaction becomes a "last interaction"?
90-
// 64: appears on goto work
91-
// 256: manually interrupted (not just priority override)
92-
public int Flags;
110+
// called to group meal (28, prio 50) 4 + 8 + 16
111+
// picked up single meal (child) (30)
112+
// picked up single meal (adult) (158)
113+
// mama autos to group meal (129)
114+
// mama picked up group meal (158)
93115

94116
public OBJMInteraction(IffFieldEncode iop)
95117
{
@@ -114,7 +136,7 @@ public OBJMInteraction(IffFieldEncode iop)
114136
Priority = iop.ReadInt32();
115137
ActionTreeID = iop.ReadInt16();
116138
Attenuation = iop.ReadFloat();
117-
Flags = iop.ReadInt32();
139+
Flags = (OBJMInteractionFlags)iop.ReadInt32();
118140
}
119141

120142
public bool IsValid()
@@ -176,7 +198,7 @@ public struct OBJMPerson
176198
public string CarryAnimation; //
177199
public string BaseAnimation; //a2o-standing-loop;-10;1000;70;1000;1;1;1
178200

179-
public int RoutingState;
201+
public OBJMRoutingState RoutingState;
180202
public float[] FirstFloats;
181203
public float[] MotiveDataOld;
182204
public float[] MotiveData;
@@ -223,13 +245,7 @@ public OBJMPerson(uint version, IffFieldEncode iop)
223245
CarryAnimation = iop.ReadString(false); //a2o-rarm-carry-loop;10;0;1000;1000;0;1;1
224246
BaseAnimation = iop.ReadString(true); //a2o-standing-loop;-10;1000;525;1000;1;1;1
225247

226-
RoutingState = iop.ReadInt32();
227-
// Seems to be related to routing
228-
// 9: actively moving to dest?
229-
// 6: accelerating
230-
// 4: turning?
231-
// 3: stopped? this seems to linger when sims go to work
232-
// 0: no movement (maybe resets when scripted animation starts)
248+
RoutingState = (OBJMRoutingState)iop.ReadInt32();
233249

234250
FirstFloats = new float[9];
235251

TSOClient/tso.simantics/Engine/VMStackFrame.cs

+14-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
namespace FSO.SimAntics.Engine
66
{
7+
public enum VMSpecialResult
8+
{
9+
Normal,
10+
Interaction,
11+
Retry
12+
}
13+
714
/// <summary>
815
/// Holds information about the execution of a routine
916
/// </summary>
@@ -48,8 +55,11 @@ public short StackObjectID
4855
private VMEntity _StackObject;
4956
public short _StackObjectID;
5057

51-
/** If true, this stack frame is not a subroutine. Return with a continue. **/
52-
public bool DiscardResult;
58+
/**
59+
* Normally, returning true or false from a stack frame goes to the corresponding node on the parent frame.
60+
* This works differently for interactions, and for TS1 loaded trees. (no routing frames, needs to rerun the route primitive)
61+
*/
62+
public VMSpecialResult SpecialResult;
5363

5464
/** Indicates that the current stack frame is part of an action tree.
5565
** Set by "idle for input, allow push", when an interaction is selected.
@@ -137,7 +147,7 @@ public virtual VMStackFrameMarshal Save()
137147
CodeOwnerGUID = CodeOwner.OBJ.GUID,
138148
Locals = (short[])Locals?.Clone(),
139149
Args = (short[])Args?.Clone(),
140-
DiscardResult = DiscardResult,
150+
SpecialResult = SpecialResult,
141151
ActionTree = ActionTree,
142152
};
143153
}
@@ -165,7 +175,7 @@ public virtual void Load(VMStackFrameMarshal input, VMContext context)
165175
Locals = input.Locals;
166176
}
167177
Args = input.Args;
168-
DiscardResult = input.DiscardResult;
178+
SpecialResult = input.SpecialResult;
169179
ActionTree = input.ActionTree;
170180
}
171181

TSOClient/tso.simantics/Engine/VMThread.cs

+10-5
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public void TryRunImmediately()
236236
{
237237
Queue.Insert(ActiveQueueBlock+1, temp);
238238
var frame = temp.ToStackFrame(Entity);
239-
frame.DiscardResult = true;
239+
frame.SpecialResult = VMSpecialResult.Interaction;
240240
Push(frame);
241241
ActiveQueueBlock++; //both the run immediately interaction and the active interaction must be protected.
242242
break;
@@ -273,7 +273,7 @@ private void EndCurrentInteraction()
273273
public void AbortCurrentInteraction()
274274
{
275275
//go all the way back to the stack frame that Allow Push'd us.
276-
var returnTo = Stack.FindLast(x => x.DiscardResult);
276+
var returnTo = Stack.FindLast(x => x.SpecialResult == VMSpecialResult.Interaction);
277277
if (returnTo != null)
278278
{
279279
var ind = Stack.IndexOf(returnTo);
@@ -704,17 +704,22 @@ public void Breakpoint(VMStackFrame frame, string description)
704704

705705
public void Pop(VMPrimitiveExitCode result)
706706
{
707-
var discardResult = Stack[Stack.Count - 1].DiscardResult;
707+
var discardResult = Stack[Stack.Count - 1].SpecialResult;
708708
var contextSwitch = (Stack.Count > 1) && Stack.LastOrDefault().ActionTree != Stack[Stack.Count - 2].ActionTree;
709709
Stack.RemoveAt(Stack.Count - 1);
710710
LastStackExitCode = result;
711711

712-
if (discardResult) //interaction switching back to main (it cannot be the other way...)
712+
if (discardResult == VMSpecialResult.Interaction) //interaction switching back to main (it cannot be the other way...)
713713
{
714714
var interaction = Queue[ActiveQueueBlock];
715715
EndCurrentInteraction();
716716
result = (!interaction.Flags.HasFlag(TTABFlags.RunImmediately)) ? VMPrimitiveExitCode.CONTINUE_NEXT_TICK : VMPrimitiveExitCode.CONTINUE;
717717
}
718+
else if (discardResult == VMSpecialResult.Retry)
719+
{
720+
result = VMPrimitiveExitCode.CONTINUE;
721+
}
722+
718723
if (Stack.Count > 0)
719724
{
720725
if (result == VMPrimitiveExitCode.RETURN_TRUE)
@@ -869,7 +874,7 @@ private bool ExecuteAction(VMQueuedAction action)
869874
//set the new interaction's priority
870875
((VMAvatar)Entity).SetPersonData(VMPersonDataVariable.Priority, action.Priority);
871876
var frame = action.ToStackFrame(Entity);
872-
frame.DiscardResult = true;
877+
frame.SpecialResult = VMSpecialResult.Interaction;
873878
return Push(frame);
874879
}
875880

TSOClient/tso.simantics/Entities/VMAvatar.cs

+1
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ public void InheritNeighbor(Neighbour neigh, FAMI current)
958958
else SetPersonData(VMPersonDataVariable.PersonType, lastPersonType);
959959
SetPersonData(VMPersonDataVariable.VisitorSchedule, sched);
960960
SetPersonData(VMPersonDataVariable.GreetStatus, 0);
961+
SetPersonData(VMPersonDataVariable.IsGhost, GetPersonData(VMPersonDataVariable.IsGhost));
961962
}
962963

963964
public virtual short GetMotiveData(VMMotive variable) //needs special conditions for ones like Mood.

TSOClient/tso.simantics/FSO.SimAntics.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@
410410
<Compile Include="Utils\VMLotRotate.cs" />
411411
<Compile Include="Utils\VMLotTerrainRestoreTools.cs" />
412412
<Compile Include="Utils\VMTS1Activator.cs" />
413+
<Compile Include="Utils\VMTS1ActivatorNew.cs" />
413414
<Compile Include="Utils\VMTS1PurchasableOutfitHelper.cs" />
414415
<Compile Include="Utils\VMWorldActivator.cs" />
415416
<Compile Include="Utils\VMWorldExporter.cs" />

TSOClient/tso.simantics/Marshals/Threads/VMStackFrameMarshal.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using FSO.SimAntics.NetPlay.Model;
1+
using FSO.SimAntics.Engine;
2+
using FSO.SimAntics.NetPlay.Model;
23
using System.IO;
34

45
namespace FSO.SimAntics.Marshals.Threads
@@ -13,7 +14,7 @@ public class VMStackFrameMarshal : VMSerializable
1314
public uint CodeOwnerGUID;
1415
public short[] Locals;
1516
public short[] Args;
16-
public bool DiscardResult;
17+
public VMSpecialResult SpecialResult;
1718
public bool ActionTree;
1819

1920
public int Version;
@@ -44,7 +45,7 @@ public virtual void Deserialize(BinaryReader reader)
4445
for (int i = 0; i < argsN; i++) Args[i] = reader.ReadInt16();
4546
}
4647

47-
if (Version > 3) DiscardResult = reader.ReadBoolean();
48+
if (Version > 3) SpecialResult = (VMSpecialResult)reader.ReadByte();
4849
ActionTree = reader.ReadBoolean();
4950
}
5051

@@ -60,7 +61,7 @@ public virtual void SerializeInto(BinaryWriter writer)
6061
if (Locals != null) writer.Write(VMSerializableUtils.ToByteArray(Locals));
6162
writer.Write((Args == null) ? -1 : Args.Length);
6263
if (Args != null) writer.Write(VMSerializableUtils.ToByteArray(Args));
63-
writer.Write(DiscardResult);
64+
writer.Write((byte)SpecialResult);
6465
writer.Write(ActionTree);
6566
}
6667
}

TSOClient/tso.simantics/NetPlay/Model/Commands/VMBlueprintRestoreCmd.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public override bool Execute(VM vm)
5151
}
5252
else
5353
{
54-
var activator = new VMTS1Activator(vm, vm.Context.World, JobLevel);
54+
//var activator = new VMTS1Activator(vm, vm.Context.World, JobLevel);
55+
var activator = new VMTS1ActivatorNew(vm, JobLevel);
5556
activator.LoadFromIff(iff);
5657
}
5758

0 commit comments

Comments
 (0)