[UI] Build, Buy, CAS

- Build and buy mode are fully functional on residential lots. Some category icons still have to be drawn and included.
- Simless build mode on community lots is partially implemented
- You can now switch lots and close the game from the options mode. Alt-F4 and the close button bring up a dialog ingame that will let you save, when that is possible.
- CAS is partially implemented. You can create a sim, though you cannot browse existing families or save the sim.
- You can now browse through neighbourhoods when you are not playing a family.
- TS1 neighbourhoods are now copied to My Documents/Simitone. This folder also contains your mesh cache, and other temporary data.
- Now uses TS1 strings rather than TSO.
- Touch mode scroll now supports 3D pan as well. Will be enabled on windows tablets in time.
- Lots more.
This commit is contained in:
RHY3756547 2017-11-22 01:14:41 +00:00
parent 78460551a7
commit a7bc1a56f0
25 changed files with 806 additions and 117 deletions

View file

@ -28,15 +28,32 @@ namespace Simitone.Client
GameFacade.Screens.RemoveCurrent();
GameFacade.Screens.AddScreen(screen);
((LoadingScreen)last).Close();
var children = new List<UIElement>(last.GetChildren());
for (int i=0; i<children.Count; i++)
var load = (last as LoadingScreen);
if (load != null)
{
last.Remove(children[i]);
screen.Add(children[i]);
load.Close();
var children = new List<UIElement>(last.GetChildren());
for (int i = 0; i < children.Count; i++)
{
last.Remove(children[i]);
screen.Add(children[i]);
}
}
screen.Initialize(lotName, external);
});
}
public static void EnterCAS()
{
GameThread.NextUpdate((x) =>
{
var screen = new TS1CASScreen();
var last = GameFacade.Screens.CurrentUIScreen;
if (last is TS1GameScreen) ((TS1GameScreen)last).CleanupLastWorld();
GameFacade.Screens.RemoveCurrent();
GameFacade.Screens.AddScreen(screen);
});
}
}
}

View file

@ -59,12 +59,19 @@
<Compile Include="UI\Controls\UIValueBar.cs" />
<Compile Include="UI\Model\UIIconCache.cs" />
<Compile Include="UI\Model\UIStyle.cs" />
<Compile Include="UI\Panels\CAS\UIFamilyCASPanel.cs" />
<Compile Include="UI\Panels\CAS\UISimCASPanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\Catalog\UICatalogItem.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIButtonSubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIBuyBrowsePanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIRelationshipSubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIInventorySubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIPersonalitySubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIJobSubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UIMotiveSubpanel.cs" />
<Compile Include="UI\Panels\LiveSubpanels\UISubpanel.cs" />
<Compile Include="UI\Panels\LotControls\UIArchTouchHelper.cs" />
<Compile Include="UI\Panels\UI3DThumb.cs" />
<Compile Include="UI\Panels\UIClockPanel.cs" />
<Compile Include="UI\Panels\UICutawayPanel.cs" />
<Compile Include="UI\Panels\UIHouseSelectPanel.cs" />
@ -73,16 +80,22 @@
<Compile Include="UI\Panels\UILotControl.cs" />
<Compile Include="UI\Panels\UILotControlTouchHelper.cs" />
<Compile Include="UI\Panels\UIMobileAlert.cs" />
<Compile Include="UI\Panels\UIModeSwitcher.cs" />
<Compile Include="UI\Panels\UIMoneyPanel.cs" />
<Compile Include="UI\Panels\UINeighbourhoodSelectionPanel.cs" />
<Compile Include="UI\Panels\UIMainPanel.cs" />
<Compile Include="UI\Panels\UINeighbourhoodSwitcher.cs" />
<Compile Include="UI\Panels\UIObjectHolder.cs" />
<Compile Include="UI\Panels\UIPickupPanel.cs" />
<Compile Include="UI\Panels\UIPieMenu.cs" />
<Compile Include="UI\Panels\UIQueryPanel.cs" />
<Compile Include="UI\Panels\UIRotationAnimation.cs" />
<Compile Include="UI\Panels\UISimitoneFrontend.cs" />
<Compile Include="UI\Panels\UISwitchAvatarPanel.cs" />
<Compile Include="UI\Panels\WorldUI\UIHeadlineRenderer.cs" />
<Compile Include="UI\Panels\WorldUI\UIMoneyHeadline.cs" />
<Compile Include="UI\Screens\LoadingGameScreen.cs" />
<Compile Include="UI\Screens\TS1CASScreen.cs" />
<Compile Include="UI\Screens\TS1GameScreen.cs" />
</ItemGroup>
<ItemGroup>
@ -132,12 +145,108 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Content\uigraphics\cas\cas_adult.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_bio.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_bio_bg.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_cat_del.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_cat_edit.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_child.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_female.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_male.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_new_plus.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_per.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_rand.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_sim.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_skindrk.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_skinlgt.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\cas\cas_skinmed.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\common\btn_accept.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\common\btn_back.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\dialog\ngbh_outline.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\blank_blue.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_arch.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_door.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_fire.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_flor.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_objs.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_outs.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_roof.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_stai.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_terr.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_tree.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_wall.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_walp.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_watr.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_build_wind.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat\cat_cancel.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat_btn_base.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -273,6 +382,9 @@
<Content Include="Content\uigraphics\live\cat\cat_surf_tabl.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\cat_thumb_bg.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\clockinbg_pause.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -381,6 +493,15 @@
<Content Include="Content\uigraphics\live\modes\live_relationships.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\modes\opt_neigh.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\modes\opt_quit.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\modes\opt_save.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\money_bg.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -429,6 +550,9 @@
<Content Include="Content\uigraphics\live\pswitch_icon_sel.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\query_title.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\rel_all.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -471,6 +595,30 @@
<Content Include="Content\uigraphics\live\speedbtn_4.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_buy.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_cross.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_place.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_rotccw.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_rotcw.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_tool.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_toolc.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\live\touch\touch_tools.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\load\load_bar_bg.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -489,6 +637,27 @@
<Content Include="Content\uigraphics\live\motive_bg.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_back.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_cas.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_downt.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_magic.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_opt.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_studio.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\uigraphics\ngbh\ngbh_vacat.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Content\TS1Patch\PetGym_performance.piff">
@ -508,6 +677,11 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Content\cas.fsov">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -97,7 +97,7 @@ namespace Simitone.Client
FSO.LotView.WorldConfig.Current = new FSO.LotView.WorldConfig()
{
AdvancedLighting = settings.Lighting,
LightingMode = 3,
SmoothZoom = settings.SmoothZoom,
SurroundingLots = settings.SurroundingLotMode,
AA = settings.AntiAlias
@ -107,8 +107,9 @@ namespace Simitone.Client
PlatformID pid = os.Platform;
GameFacade.Linux = (pid == PlatformID.MacOSX || pid == PlatformID.Unix);
FSO.Content.Content.TS1Hybrid = GlobalSettings.Default.TS1HybridEnable;
FSO.Content.Content.Target = FSO.Content.FSOEngineMode.TS1;
FSO.Content.Content.TS1HybridBasePath = GlobalSettings.Default.TS1HybridPath;
if (FSOEnvironment.Enable3D) FSO.Files.RC.DGRP3DMesh.InitRCWorkers();
//FSO.Content.Content.Init(GlobalSettings.Default.StartupPath, GraphicsDevice);
base.Initialize();
@ -121,7 +122,7 @@ namespace Simitone.Client
GameFacade.GraphicsDevice = GraphicsDevice;
GameFacade.GraphicsDeviceManager = Graphics;
GameFacade.Cursor = new CursorManager(GraphicsDevice);
if (!GameFacade.Linux) GameFacade.Cursor.Init(GlobalSettings.Default.StartupPath);
if (!GameFacade.Linux) GameFacade.Cursor.Init(GlobalSettings.Default.TS1HybridPath, true);
/** Init any computed values **/
GameFacade.Init();
@ -134,6 +135,7 @@ namespace Simitone.Client
hit.SetMasterVolume(HITVolumeGroup.VOX, GlobalSettings.Default.VoxVolume / 10f);
hit.SetMasterVolume(HITVolumeGroup.AMBIENCE, GlobalSettings.Default.AmbienceVolume / 10f);
ContentStrings.TS1 = true;
GameFacade.Strings = new ContentStrings();
GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None };
@ -193,7 +195,6 @@ namespace Simitone.Client
/// </summary>
protected override void LoadContent()
{
Console.WriteLine("loadcontent");
Effect vitaboyEffect = null;
try
{
@ -229,6 +230,13 @@ namespace Simitone.Client
// TODO: Unload any non ContentManager content here
}
protected override void OnExiting(object sender, EventArgs args)
{
base.OnExiting(sender, args);
GameThread.Killed = true;
GameThread.OnKilled.Set();
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.

View file

@ -14,6 +14,7 @@ namespace Simitone.Client.UI.Controls
public class UICatButton : UIStencilButton
{
private Texture2D CatBase;
private Texture2D Replaced;
public UICatButton(Texture2D tex) : base(tex)
{
Alpha = 1f;
@ -21,8 +22,27 @@ namespace Simitone.Client.UI.Controls
CatBase = Content.Get().CustomUI.Get("cat_btn_base.png").Get(GameFacade.GraphicsDevice);
}
public void ReplaceImage(Texture2D tex)
{
if (Replaced == null)
{
Replaced = Texture;
}
Texture = tex;
}
public void RestoreImage()
{
if (Replaced != null)
{
Texture = Replaced;
Replaced = null;
}
}
public override void Draw(UISpriteBatch SBatch)
{
if (!Visible) return;
base.Draw(SBatch);
var frame = CurrentFrame;
if (Disabled)

View file

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FSO.Common.Rendering.Framework.Model;
namespace Simitone.Client.UI.Controls
{
@ -19,6 +20,7 @@ namespace Simitone.Client.UI.Controls
public UIDiagonalStripe Stripe;
public UIVertGrad Grad;
public event Action<int> OnCategorySelect;
public event Action OnOpen;
public int ActiveCategory;
public List<UICategory> Categories;
public List<UIStencilButton> CatSwitchButtons = new List<UIStencilButton>();
@ -117,6 +119,7 @@ namespace Simitone.Client.UI.Controls
{
Close(); return;
}
OnOpen?.Invoke();
GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary<string, float>() { { "CategoryExpand", 1f } }, TweenQuad.EaseOut);
}
@ -124,6 +127,11 @@ namespace Simitone.Client.UI.Controls
{
GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary<string, float>() { { "CategoryExpand", 0f } }, TweenQuad.EaseOut);
}
public override void Update(UpdateState state)
{
base.Update(state);
}
}
public class UICategory

View file

@ -68,6 +68,7 @@ namespace Simitone.Client.UI.Controls
public override void Draw(UISpriteBatch SBatch)
{
if (!Visible) return;
DrawLocalTexture(SBatch, Texture, new Vector2(Texture.Width, Texture.Height) / -2);
}
}

View file

@ -18,6 +18,8 @@ namespace Simitone.Client.UI.Controls
public int ItemWidth;
public Texture2D ScrollEdgeL;
public Texture2D ScrollEdgeR;
public bool DrawBounds = true;
public int Margin;
private UIMouseEventRef HitTest;
@ -42,6 +44,7 @@ namespace Simitone.Client.UI.Controls
private int MouseDownID = -1;
private Point MouseDownAt;
private bool InScroll;
private UITSContainer LastSelected;
private List<float> ScrollVelocityHistory = new List<float>();
public void MouseEvents(UIMouseEventType type, UpdateState state)
@ -58,7 +61,7 @@ namespace Simitone.Client.UI.Controls
case UIMouseEventType.MouseUp:
if (!InScroll)
{
Select(MouseDownAt);
Select(GlobalPoint(MouseDownAt.ToVector2()).ToPoint());
}
else
{
@ -86,7 +89,14 @@ namespace Simitone.Client.UI.Controls
public void Select(Point at)
{
var item = (int)(at.X + Scroll) / ItemWidth;
if (item >= LengthProvider()) return;
var rItem = GetOrPrepare(item);
if (rItem != null)
{
LastSelected?.Deselected();
rItem.Selected();
LastSelected = rItem;
}
}
public UITSContainer GetOrPrepare(int id)
@ -138,7 +148,7 @@ namespace Simitone.Client.UI.Controls
Scroll += ScrollVelocity;
ScrollVelocity *= 0.9f;
Scroll = Math.Max(0, Math.Min(length * ItemWidth - Size.X, Scroll));
Scroll = Math.Max(-Margin, Math.Min(length * ItemWidth - Size.X + Margin, Scroll));
//update children positions.
//delete ones that are not
@ -149,6 +159,7 @@ namespace Simitone.Client.UI.Controls
var e = b + (Size.X + (ItemWidth - 1)) / ItemWidth;
for (int i=b; i<e; i++)
{
if (i < 0) continue;
if (i >= length) break;
var item = GetOrPrepare(i);
untouched.Remove(item);
@ -164,11 +175,19 @@ namespace Simitone.Client.UI.Controls
Invalidate();
}
public void SetScroll(float value)
{
Scroll = value;
}
public override void Draw(UISpriteBatch batch)
{
base.Draw(batch);
DrawLocalTexture(batch, ScrollEdgeL, new Vector2(0, Size.Y / 2 - 64));
DrawLocalTexture(batch, ScrollEdgeR, new Vector2(Size.X-15, Size.Y / 2 - 64));
if (DrawBounds)
{
DrawLocalTexture(batch, ScrollEdgeL, new Vector2(0, Size.Y / 2 - 64));
DrawLocalTexture(batch, ScrollEdgeR, new Vector2(Size.X - 15, Size.Y / 2 - 64));
}
}
public void Reset()
@ -178,6 +197,7 @@ namespace Simitone.Client.UI.Controls
{
Remove(child);
}
LastSelected = null;
}
}
@ -188,5 +208,10 @@ namespace Simitone.Client.UI.Controls
{
}
public virtual void Deselected()
{
}
}
}

View file

@ -57,6 +57,7 @@ namespace Simitone.Client.UI.Model
var pos2 = m_Head.Skeleton.GetBone("HEAD").AbsolutePosition;
pos2.Y += 0.1f;
HeadCamera.Position = new Vector3(0, pos2.Y, 12.5f);
HeadCamera.FOV = (float)Math.PI / 3f;
HeadCamera.Target = pos2;
HeadCamera.ProjectionOrigin = new Vector2(74/2, 74/2);

View file

@ -24,7 +24,14 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
Game = game;
}
public void Kill()
public override void GameResized()
{
var screenWidth = UIScreen.Current.ScreenWidth;
Size = new Vector2(screenWidth - 342, 128);
base.GameResized();
}
public virtual void Kill()
{
GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary<string, float>() { { "Opacity", 0f } });
GameThread.SetTimeout(() =>

View file

@ -48,6 +48,7 @@ namespace Simitone.Client.UI.Panels
public bool Expand;
public VM VM;
public bool Hidden;
public UIClockPanel(VM vm) : base()
{
@ -130,8 +131,8 @@ namespace Simitone.Client.UI.Panels
}
MouseEvent.Region = OuterBg.GetBounds();
var speed = RemapSpeed[VM.SpeedMultiplier];
var speed = RemapSpeed[Math.Max(0, VM.SpeedMultiplier)];
if (speed != LastSpeed)
{
if (speed == 4) InnerBg.Texture = Content.Get().CustomUI.Get("clockinbg_pause.png").Get(GameFacade.GraphicsDevice);
@ -153,6 +154,7 @@ namespace Simitone.Client.UI.Panels
public void SwitchSpeed(int speed)
{
if (VM.SpeedMultiplier == -1) return;
switch (VM.SpeedMultiplier)
{
case 0:
@ -237,6 +239,7 @@ namespace Simitone.Client.UI.Panels
public void SetExpanded(bool expand)
{
if (Hidden) return;
var time = 0.3f;
GameFacade.Screens.Tween.To(OuterBg, time, new Dictionary<string, float>() { { "X", (expand) ? 0f : 138f }, { "Width", (expand) ? 334f : 196f } }, TweenQuad.EaseOut);
GameFacade.Screens.Tween.To(InnerBg, time, new Dictionary<string, float>() { { "X", (expand) ? 10f : 148f } }, TweenQuad.EaseOut);
@ -249,5 +252,13 @@ namespace Simitone.Client.UI.Panels
GameFacade.Screens.Tween.To(Btns[i], time, new Dictionary<string, float>() { { "X", (expand) ? (151f+46*i) : 289f } }, TweenQuad.EaseOut);
Expand = expand;
}
public void SetHidden(bool hidden)
{
if (hidden == Hidden) return;
Hidden = hidden;
if (hidden) SetExpanded(false);
//GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary<string, float>() { { "Y", hidden? (-55f):15f } }, TweenQuad.EaseOut);
}
}
}

View file

@ -14,7 +14,6 @@ using FSO.SimAntics.Engine;
using FSO.SimAntics;
using FSO.HIT;
using FSO.SimAntics.NetPlay.Model.Commands;
using FSO.Client.UI.Controls;
using FSO.Common;
using Simitone.Client.UI.Controls;
using FSO.Client;
@ -140,7 +139,7 @@ namespace Simitone.Client.UI.Panels
Active = (i == 0)
};
itemui.UI.Position = itemui.SourcePos;
itemui.UI.OnMouseEvent += new ButtonClickDelegate(InteractionClicked);
itemui.UI.OnMouseEvent += new FSO.Client.UI.Controls.ButtonClickDelegate(InteractionClicked);
itemui.UI.OnInteractionResult += InteractionResult;
itemui.UI.ParentEntry = itemui;
itemui.Name = elem.Name;

View file

@ -32,13 +32,16 @@ using FSO.Content;
using FSO.Client.Debug;
using Simitone.Client.UI.Screens;
using FSO.LotView.RC;
using Simitone.Client.UI.Panels.LotControls;
using FSO.Client.UI.Panels.LotControls;
using FSO.UI.Panels.LotControls;
namespace Simitone.Client.UI.Panels
{
/// <summary>
/// Generates pie menus when the player clicks on objects.
/// </summary>
public class UILotControl : UIContainer
public class UILotControl : UIContainer, ILotControl
{
private UIMouseEventRef MouseEvt;
public bool MouseIsOn;
@ -50,8 +53,8 @@ namespace Simitone.Client.UI.Panels
private Texture2D RMBCursor;
public FSO.SimAntics.VM vm;
public FSO.LotView.World World;
public VMEntity ActiveEntity;
public FSO.LotView.World World { get; set; }
public VMEntity ActiveEntity { get; set; }
public uint SelectedSimID
{
get
@ -66,6 +69,7 @@ namespace Simitone.Client.UI.Panels
public bool LiveMode = true;
public bool PanelActive = false;
public UILotControlTouchHelper Touch;
public UIArchTouchHelper ArchTouch;
public int WallsMode = 1;
@ -100,6 +104,11 @@ namespace Simitone.Client.UI.Panels
private int LastWallMode = -1; //invalidates last roomcuts
private bool LastRectCutNotable = false; //set if the last rect cut made a noticable change to the cuts array. If true refresh regardless of new cut effect.
public UIObjectHolder ObjectHolder;
public UICustomLotControl CustomControl;
public UIQueryPanel QueryPanel;
public UIPickupPanel PickupPanel;
/// <summary>
/// Creates a new UILotControl instance.
/// </summary>
@ -109,17 +118,18 @@ namespace Simitone.Client.UI.Panels
{
this.vm = vm;
this.World = World;
ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar);
MouseEvt = this.ListenForMouse(new Microsoft.Xna.Framework.Rectangle(0, 0,
GlobalSettings.Default.GraphicsWidth, GlobalSettings.Default.GraphicsHeight), OnMouse);
Queue = new UIInteractionQueue(ActiveEntity, vm);
this.Add(Queue);
//ObjectHolder = new UIObjectHolder(vm, World, this);
ObjectHolder = new UIObjectHolder(vm, World, this);
Touch = new UILotControlTouchHelper(this);
Add(Touch);
ArchTouch = new UIArchTouchHelper(this);
Add(ArchTouch);
SetupQuery();
@ -131,25 +141,22 @@ namespace Simitone.Client.UI.Panels
public void SetupQuery()
{
/*
UIContainer parent = null;
/*UIContainer parent = null;
if (QueryPanel?.Parent?.Parent != null)
{
parent = QueryPanel.Parent;
}
}*/
QueryPanel = new UIQueryPanel(World);
QueryPanel.OnSellBackClicked += ObjectHolder.SellBack;
QueryPanel.OnInventoryClicked += ObjectHolder.MoveToInventory;
QueryPanel.OnAsyncBuyClicked += ObjectHolder.AsyncBuy;
QueryPanel.OnAsyncSaleClicked += ObjectHolder.AsyncSale;
QueryPanel.OnAsyncPriceClicked += ObjectHolder.AsyncSale;
QueryPanel.OnAsyncSaleCancelClicked += ObjectHolder.AsyncCancelSale;
QueryPanel.X = 0;
QueryPanel.Y = -114;
if (parent != null) parent.Add(QueryPanel);
*/
PickupPanel = new UIPickupPanel();
PickupPanel.OnResponse += (resp) =>
{
if (resp) ObjectHolder.SellBack(null);
else ObjectHolder.Cancel();
};
}
public override void GameResized()
@ -158,7 +165,7 @@ namespace Simitone.Client.UI.Panels
MouseEvt.Region.Width = GlobalSettings.Default.GraphicsWidth;
MouseEvt.Region.Height = GlobalSettings.Default.GraphicsHeight;
SetupQuery();
//SetupQuery();
}
@ -302,7 +309,7 @@ namespace Simitone.Client.UI.Panels
if (type == UIMouseEventType.MouseOver)
{
//if (QueryPanel.Mode == 1) QueryPanel.Active = false;
if (QueryPanel.Mode == 1) QueryPanel.SetShown(false);
MouseIsOn = true;
}
else if (type == UIMouseEventType.MouseOut)
@ -313,16 +320,28 @@ namespace Simitone.Client.UI.Panels
}
else if (type == UIMouseEventType.MouseDown)
{
if (!FSOEnvironment.SoftwareKeyboard)
{
if (!LiveMode)
{
if (CustomControl != null) CustomControl.MouseDown(state);
else ObjectHolder.MouseDown(state);
return;
}
}
Touch.MiceDown.Add(state.CurrentMouseID);
}
else if (type == UIMouseEventType.MouseUp)
{
Touch.MiceDown.Remove(state.CurrentMouseID);
if (!LiveMode)
if (!FSOEnvironment.SoftwareKeyboard)
{
//if (CustomControl != null) CustomControl.MouseUp(state);
//else ObjectHolder.MouseUp(state);
return;
if (!LiveMode)
{
if (CustomControl != null) CustomControl.MouseUp(state);
else ObjectHolder.MouseUp(state);
return;
}
}
state.UIState.TooltipProperties.Show = false;
state.UIState.TooltipProperties.Opacity = 0;
@ -331,12 +350,42 @@ namespace Simitone.Client.UI.Panels
}
}
public void SimulateMD(UpdateState state)
{
if (CustomControl != null) CustomControl.MouseDown(state);
else ObjectHolder.MouseDown(state);
}
public void SimulateMU(UpdateState state)
{
if (CustomControl != null) CustomControl.MouseUp(state);
else ObjectHolder.MouseUp(state);
}
public void AddModifier(UILotControlModifiers mod)
{
if (CustomControl != null)
CustomControl.Modifiers |= mod;
}
public void RemoveModifier(UILotControlModifiers mod)
{
if (CustomControl != null)
CustomControl.Modifiers &= ~mod;
}
public void ShowPieMenu(Point pt, UpdateState state)
{
if (!LiveMode)
{
//if (CustomControl != null) CustomControl.MouseDown(state);
//else ObjectHolder.MouseDown(state);
/*
if (CustomControl != null) CustomControl.MouseDown(state);
else ObjectHolder.MouseDown(state);
*/
if (FSOEnvironment.SoftwareKeyboard && ObjectHolder.Holding == null)
{
ObjectHolder.MouseDown(state);
}
return;
}
if (PieMenu == null && ActiveEntity != null)
@ -628,7 +677,7 @@ namespace Simitone.Client.UI.Panels
if (ActiveEntity == null || ActiveEntity.Dead || ActiveEntity.PersistID != SelectedSimID)
{
ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar && x.PersistID == SelectedSimID); //try and hook onto a sim if we have none selected.
if (ActiveEntity == null) ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar);
//if (ActiveEntity == null) ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar);
if (!FoundMe && ActiveEntity != null)
{
@ -719,15 +768,46 @@ namespace Simitone.Client.UI.Panels
RMBScroll = false;
}
if (!LiveMode && PieMenu != null)
{
PieMenu.RemoveSimScene();
this.Remove(PieMenu);
PieMenu = null;
}
if (LiveMode) LiveModeUpdate(state, scrolled);
//else if (CustomControl != null) CustomControl.Update(state, scrolled);
//else ObjectHolder.Update(state, scrolled);
else if (CustomControl != null)
{
if (FSOEnvironment.SoftwareKeyboard) CustomControl.MousePosition = new Point(UIScreen.Current.ScreenWidth / 2, UIScreen.Current.ScreenHeight / 2);
else
{
CustomControl.Modifiers = 0;
if (state.CtrlDown) CustomControl.Modifiers |= UILotControlModifiers.CTRL;
if (state.ShiftDown) CustomControl.Modifiers |= UILotControlModifiers.SHIFT;
CustomControl.MousePosition = state.MouseState.Position;
}
CustomControl.Update(state, scrolled);
}
else ObjectHolder.Update(state, scrolled);
//set cutaway around mouse
UpdateCutaway(state);
if (RMBScrollX == int.MinValue) Dummy(); //cannon fodder for mono AOT compilation: never called but gives these constructors a meaning in life
}
}
private void Dummy()
{
CustomControl = new UIWallPlacer(vm, World, this, new List<int>());
CustomControl = new UIFloorPainter(vm, World, this, new List<int>());
CustomControl = new UIWallPainter(vm, World, this, new List<int>());
CustomControl = new UIGrassPaint(vm, World, this, new List<int>());
CustomControl = new UIRoofer(vm, World, this, new List<int>());
CustomControl = new UITerrainFlatten(vm, World, this, new List<int>());
CustomControl = new UITerrainRaiser(vm, World, this, new List<int>());
}
private void UpdateCutaway(UpdateState state)
{
if (vm.Context.Blueprint != null)

View file

@ -191,7 +191,8 @@ namespace Simitone.Client.UI.Panels
ScrollVelocity = (newTap - TapPoint).ToVector2();
TapPoint = newTap;
Master.TargetZoom = (vector.Length() / BaseVector.Length()) * StartScale;
var zoom = (vector.Length() / BaseVector.Length()) * StartScale;
if (!float.IsNaN(zoom))Master.TargetZoom = zoom;
//clockwise if dot product b against a rotated 90 degrees clockwise is positive
var a = BaseVector;
@ -203,8 +204,16 @@ namespace Simitone.Client.UI.Panels
if (_3d)
{
if (LastAngleX != null) ((WorldStateRC)Master.World.State).RotationX -= (float)DirectionUtils.Difference(RotateAngle, LastAngleX.Value);
var rcState = ((WorldStateRC)Master.World.State);
if (LastAngleX != null)
{
float rot = rcState.RotationX - (float)DirectionUtils.Difference(RotateAngle, LastAngleX.Value);
if (!float.IsNaN(rot))
rcState.RotationX = rot;
}
LastAngleX = RotateAngle;
rcState.RotationY += ScrollVelocity.Y / 200;
ScrollVelocity = Vector2.Zero;
} else {
if (Math.Abs(RotateAngle) > Math.PI / 8) Master.TargetZoom = StartScale;
}

View file

@ -52,6 +52,10 @@ namespace Simitone.Client.UI.Panels
public UISwitchAvatarPanel SwitchAvatar;
public bool PanelActive;
public UIMainPanelMode Mode;
public event Action OnEndSelect;
public event Action<UIMainPanelMode> ModeChanged;
public string[] FloorNames = new string[]
{
@ -72,6 +76,31 @@ namespace Simitone.Client.UI.Panels
new UICategory() { ID = 4, IconName = "live_inventory.png" }
};
private List<UICategory> BuyCategories = new List<UICategory>()
{
new UICategory() { ID = 0, IconName = "cat_seat.png" },
new UICategory() { ID = 1, IconName = "cat_surf.png" },
new UICategory() { ID = 2, IconName = "cat_appl.png" },
new UICategory() { ID = 3, IconName = "cat_elec.png" },
new UICategory() { ID = 4, IconName = "cat_plum.png" },
new UICategory() { ID = 5, IconName = "cat_deco.png" },
new UICategory() { ID = 6, IconName = "cat_misc.png" },
new UICategory() { ID = 7, IconName = "cat_ligt.png" },
};
private List<UICategory> BuildCategories = new List<UICategory>()
{
new UICategory() { ID = 0, IconName = "cat_build_arch.png" },
new UICategory() { ID = 1, IconName = "cat_build_outs.png" },
new UICategory() { ID = 2, IconName = "cat_build_objs.png" },
};
private List<UICategory> OptionsCategories = new List<UICategory>()
{
new UICategory() { ID = 0, IconName = "cat_build_arch.png" },
};
public UIMainPanel(TS1GameScreen game) : base()
{
Game = game;
@ -122,6 +151,7 @@ namespace Simitone.Client.UI.Panels
Switcher.Position = new Vector2(164, 0);
Switcher.InitCategories(LiveCategories);
Switcher.OnCategorySelect += Switcher_OnCategorySelect;
Switcher.OnOpen += Switcher_OnOpen;
Add(Switcher);
foreach (var fade in GetFadeables())
@ -129,28 +159,110 @@ namespace Simitone.Client.UI.Panels
fade.Opacity = 0;
}
Game.LotControl.QueryPanel.Position = new Vector2(53, -5);
Add(Game.LotControl.QueryPanel);
Game.LotControl.PickupPanel.Opacity = 0;
Add(Game.LotControl.PickupPanel);
CurWidth = 0;
}
public void Switcher_OnCategorySelect(int obj)
private void Switcher_OnOpen()
{
var panel = SubPanel as UIBuyBrowsePanel;
if (panel != null)
{
panel.Reset();
}
}
public void SetMode(UIMainPanelMode mode)
{
if (mode == Mode) return;
Mode = mode;
Game.LotControl.World.State.BuildMode = 0;
switch (mode)
{
case UIMainPanelMode.LIVE:
Switcher.InitCategories(LiveCategories);
break;
case UIMainPanelMode.BUY:
Switcher.InitCategories(BuyCategories);
Game.LotControl.World.State.BuildMode = 1;
break;
case UIMainPanelMode.BUILD:
Switcher.InitCategories(BuildCategories);
Game.LotControl.World.State.BuildMode = 2;
break;
case UIMainPanelMode.OPTIONS:
Switcher.InitCategories(OptionsCategories);
break;
}
var live = (mode == UIMainPanelMode.LIVE);
Game.LotControl.LiveMode = live;
HideButton.Visible = live;
ModeChanged?.Invoke(mode);
}
public void Switcher_OnCategorySelect(int obj)
{
UISubpanel panel = null;
switch (obj)
switch (Mode)
{
case 0:
panel = new UIMotiveSubpanel(Game); break;
case 1:
panel = new UIJobSubpanel(Game); break;
case 2:
panel = new UIPersonalitySubpanel(Game); break;
case 3:
panel = new UIRelationshipSubpanel(Game); break;
case 4:
panel = new UIInventorySubpanel(Game); break;
case UIMainPanelMode.LIVE:
switch (obj)
{
case 0:
panel = new UIMotiveSubpanel(Game); break;
case 1:
panel = new UIJobSubpanel(Game); break;
case 2:
panel = new UIPersonalitySubpanel(Game); break;
case 3:
panel = new UIRelationshipSubpanel(Game); break;
case 4:
panel = new UIInventorySubpanel(Game); break;
}
break;
case UIMainPanelMode.BUY:
panel = new UIBuyBrowsePanel(Game, (sbyte)obj, GetLotType(false));
break;
case UIMainPanelMode.BUILD:
panel = new UIBuyBrowsePanel(Game, (sbyte)obj, UICatalogMode.Build);
break;
case UIMainPanelMode.OPTIONS:
panel = new UIButtonSubpanel(Game, new UICatFunc[] {
new UICatFunc(GameFacade.Strings.GetString("145", "3"), "opt_save.png", () => { Game.Save(); }),
new UICatFunc(GameFacade.Strings.GetString("145", "1"), "opt_neigh.png", () => { Game.ReturnToNeighbourhood(); }),
new UICatFunc(GameFacade.Strings.GetString("145", "5"), "opt_quit.png", () => { Game.CloseAttempt(); }),
});
break;
}
SetSubpanel(panel);
}
public UICatalogMode GetLotType(bool music)
{
UICatalogMode mode;
var house = Game.vm.GetGlobalValue(10);
var zones = Content.Get().Neighborhood.ZoningDictionary;
short result = 1;
zones.TryGetValue(house, out result);
var community = result == 1;
if (house >= 21 && house <= 31) mode = UICatalogMode.Downtown;
else if (house >= 40 && house <= 49) mode = UICatalogMode.Vacation;
else if (house >= 81 && house <= 90) mode = UICatalogMode.Studiotown;
else if (house >= 90 && house <= 99 && (music || community)) mode = UICatalogMode.Magictown;
else if (community) mode = UICatalogMode.Community;
else mode = (music && Game.vm.GetGlobalValue(32) > 0)?UICatalogMode.Downtown:UICatalogMode.Normal;
return mode;
}
public void SetSubpanel(UISubpanel sub)
{
if (SubPanel != null)
@ -165,6 +277,15 @@ namespace Simitone.Client.UI.Panels
}
}
public void SetSubpanelPickup(float opacity)
{
//used to hide subpanels to make way for the PickupPanel
if (SubPanel != null) GameFacade.Screens.Tween.To(SubPanel, 0.3f, new Dictionary<string, float>() { { "Opacity", opacity } }, TweenQuad.EaseOut);
GameFacade.Screens.Tween.To(Switcher.MainButton, 0.3f, new Dictionary<string, float>() { { "Opacity", opacity } }, TweenQuad.EaseOut);
GameFacade.Screens.Tween.To(Game.LotControl.PickupPanel, 0.3f, new Dictionary<string, float>() { { "Opacity", 1-opacity } }, TweenQuad.EaseOut);
if (opacity == 0) Switcher.Close();
}
private void UpdateWidth()
{
//prepanel width is 167
@ -234,6 +355,16 @@ namespace Simitone.Client.UI.Panels
FloorDownBtn.Disabled = LastFloor == 1;
FloorUpBtn.Disabled = LastFloor == 5;
}
Game.LotControl.PickupPanel.Visible = Game.LotControl.PickupPanel.Opacity > 0;
if (Mode != UIMainPanelMode.LIVE)
{
Game.vm.SpeedMultiplier = -1;
} else if (Game.vm.SpeedMultiplier < 0)
{
Game.vm.SpeedMultiplier = 0;
}
}
public void Open()
@ -282,6 +413,7 @@ namespace Simitone.Client.UI.Panels
Switcher_OnCategorySelect(Switcher.ActiveCategory);
SwitchAvatar = null;
ShowingSelect = false;
OnEndSelect?.Invoke();
};
}
@ -292,4 +424,12 @@ namespace Simitone.Client.UI.Panels
HideButton.X = Game.ScreenWidth - (50 + 64 + 15);
}
}
public enum UIMainPanelMode
{
LIVE,
BUY,
BUILD,
OPTIONS
}
}

View file

@ -70,16 +70,16 @@ namespace Simitone.Client.UI.Panels
switch (button.Type)
{
case UIAlertButtonType.OK:
buttonText = GameFacade.Strings.GetString("142", "ok button");
buttonText = GameFacade.Strings.GetString("142", "0");
break;
case UIAlertButtonType.Yes:
buttonText = GameFacade.Strings.GetString("142", "yes button");
buttonText = GameFacade.Strings.GetString("142", "2");
break;
case UIAlertButtonType.No:
buttonText = GameFacade.Strings.GetString("142", "no button");
buttonText = GameFacade.Strings.GetString("142", "3");
break;
case UIAlertButtonType.Cancel:
buttonText = GameFacade.Strings.GetString("142", "cancel button");
buttonText = GameFacade.Strings.GetString("142", "1");
break;
}
}

View file

@ -71,6 +71,7 @@ namespace Simitone.Client.UI.Panels
public override void Update(UpdateState state)
{
base.Update(state);
Visible = Game.LotControl.ActiveEntity != null;
var money = GetMoney();
if (LastMoney != money)
{
@ -82,6 +83,7 @@ namespace Simitone.Client.UI.Panels
public override void Draw(UISpriteBatch batch)
{
if (!Visible) return;
DrawLocalTexture(batch, Bg, new Rectangle(0, 0, 12, 24), Vector2.Zero, Vector2.One, UIStyle.Current.Bg);
DrawLocalTexture(batch, Bg, new Rectangle(12, 0, 12, 24), new Vector2(12, 0), new Vector2(8.666667f, 1), UIStyle.Current.Bg);
DrawLocalTexture(batch, Bg, new Rectangle(24, 0, 12, 24), new Vector2(116, 0), Vector2.One, UIStyle.Current.Bg);

View file

@ -174,7 +174,6 @@ namespace Simitone.Client.UI.Panels
for (int i = 0; i < locations.Length; i++)
{
Console.WriteLine(locations.GetString(i));
var loc = locations.GetString(i).Split(',');
var num = int.Parse(loc[0].TrimStart());
var button = new UINeighborhoodHouseButton(num, SelectHouse, config.Scale);
@ -235,7 +234,7 @@ namespace Simitone.Client.UI.Panels
LastHS.OnSelected += (h) =>
{
OnHouseSelect?.Invoke(h);
HITVM.Get().PlaySoundEvent("bkground_fade");
//HITVM.Get().PlaySoundEvent("bkground_fade");
};
}
}
@ -353,7 +352,6 @@ namespace Simitone.Client.UI.Panels
switch (evt)
{
case UIMouseEventType.MouseUp:
Console.WriteLine("mup");
HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.NeighborhoodClick);
selectionCallback(houseNumber); break;
case UIMouseEventType.MouseOver:
@ -361,7 +359,6 @@ namespace Simitone.Client.UI.Panels
HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.NeighborhoodRollover);
Hovered = true; break;
case UIMouseEventType.MouseOut:
Console.WriteLine("mout");
GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary<string, float>() { { "AlphaTime", 0f } });
Hovered = false; break;
}

View file

@ -11,6 +11,7 @@ using FSO.Common.Rendering.Framework.Model;
using FSO.Client;
using Microsoft.Xna.Framework;
using Simitone.Client.UI.Panels.LiveSubpanels;
using FSO.Client.UI.Model;
namespace Simitone.Client.UI.Panels
{
@ -23,7 +24,7 @@ namespace Simitone.Client.UI.Panels
public UIMoneyPanel Money;
public UIMainPanel MainPanel;
public UIStencilButton ExtendPanelBtn;
public UILiveButton LiveButton;
public UIModeSwitcher ModeSwitcher;
public bool PanelActive;
public int LastCut = 0;
@ -49,25 +50,82 @@ namespace Simitone.Client.UI.Panels
Add(Money);
MainPanel = new UIMainPanel(screen);
MainPanel.OnEndSelect += OnEndSelect;
MainPanel.ModeChanged += ModeChanged;
Add(MainPanel);
ExtendPanelBtn = new UIStencilButton(ui.Get("panel_expand.png").Get(GameFacade.GraphicsDevice));
ExtendPanelBtn.OnButtonClick += ExpandClicked;
Add(ExtendPanelBtn);
var btn = new UILiveButton(screen);
btn.MotiveLevel = 0.5f;
btn.Position = new Vector2(64 + 15, screen.ScreenHeight - (64 + 15));
btn.OnButtonClick += LiveButtonClicked;
Add(btn);
LiveButton = btn;
ExtendPanelBtn.Position = new Vector2(btn.X + 54, btn.Y - 50);
var mode = new UIModeSwitcher(screen);
mode.Position = new Vector2(64 + 15, screen.ScreenHeight - (64 + 15));
mode.OnModeClick += LiveButtonClicked;
Add(mode);
ModeSwitcher = mode;
ExtendPanelBtn.Position = new Vector2(mode.X + 54, mode.Y - 50);
MainPanel.X = 64 + 15;
MainPanel.Y = btn.Y - 64;
MainPanel.Y = mode.Y - 64;
MainPanel.Visible = false;
if (Game.vm.GetGlobalValue(32) > 0)
{
MainPanel.SetMode(UIMainPanelMode.BUY);
ModeSwitcher.EndSwitch(MainPanel.Mode);
MainPanel.Open();
} else
{
FSO.HIT.HITVM.Get().PlaySoundEvent(UIMusic.None);
}
}
private void ModeChanged(UIMainPanelMode obj)
{
Clock.SetHidden(obj != UIMainPanelMode.LIVE);
var lotType = MainPanel.GetLotType(true);
var hit = FSO.HIT.HITVM.Get();
switch (obj)
{
case UIMainPanelMode.LIVE:
case UIMainPanelMode.OPTIONS:
hit.PlaySoundEvent(UIMusic.None); break;
case UIMainPanelMode.BUY:
switch (lotType)
{
case UICatalogMode.Downtown:
hit.PlaySoundEvent(UIMusic.Downtown); break;
case UICatalogMode.Vacation:
hit.PlaySoundEvent(UIMusic.Vacation); break;
case UICatalogMode.Community:
hit.PlaySoundEvent(UIMusic.Unleashed); break;
case UICatalogMode.Studiotown:
hit.PlaySoundEvent(UIMusic.SuperstarTransition); break;
case UICatalogMode.Magictown:
hit.PlaySoundEvent(UIMusic.MagictownBuy); break;
default:
hit.PlaySoundEvent(UIMusic.Buy); break;
}
break;
case UIMainPanelMode.BUILD:
switch (lotType)
{
case UICatalogMode.Downtown:
hit.PlaySoundEvent(UIMusic.Downtown); break;
case UICatalogMode.Vacation:
hit.PlaySoundEvent(UIMusic.Vacation); break;
case UICatalogMode.Community:
hit.PlaySoundEvent(UIMusic.Unleashed); break;
case UICatalogMode.Studiotown:
hit.PlaySoundEvent(UIMusic.SuperstarTransition); break;
case UICatalogMode.Magictown:
hit.PlaySoundEvent(UIMusic.MagictownBuild); break;
default:
hit.PlaySoundEvent(UIMusic.Build); break;
}
break;
}
}
private void ExpandClicked(UIElement button)
@ -76,19 +134,40 @@ namespace Simitone.Client.UI.Panels
MainPanel.Switcher_OnCategorySelect(MainPanel.Switcher.ActiveCategory);
}
private void LiveButtonClicked(UIElement button)
private bool LiveButtonClicked(UIMainPanelMode mode)
{
if (MainPanel.PanelActive)
{
if (MainPanel.ShowingSelect) MainPanel.SwitchAvatar.Kill();
else MainPanel.ShowSelect();
if (MainPanel.ShowingSelect)
{
//switch to the target mode
MainPanel.SetMode(mode);
MainPanel.SwitchAvatar.Kill();
return false;
}
else
{
StartSelect();
return true;
}
} else
{
MainPanel.Open();
MainPanel.ShowSelect();
StartSelect();
return true;
}
}
private void StartSelect()
{
MainPanel.ShowSelect();
}
private void OnEndSelect()
{
ModeSwitcher.EndSwitch(MainPanel.Mode);
}
private void CutButton(UIElement button)
{
if (CutPanel != null)
@ -112,7 +191,7 @@ namespace Simitone.Client.UI.Panels
CutBtn.Selected = false;
Game.LotControl.World.State.DrawRoofs = (obj == 3);
Game.LotControl.WallsMode = obj;
CutPanel.Kill();
CutPanel?.Kill();
CutPanel = null;
}
@ -142,7 +221,7 @@ namespace Simitone.Client.UI.Panels
CutBtn.X = Game.ScreenWidth - (256 + (138f * ClockTween) + 15);
if (CutPanel != null) CutPanel.X = CutBtn.X - 39;
}
LiveButton.Switching = MainPanel.ShowingSelect;
ModeSwitcher.LiveButton.Switching = MainPanel.ShowingSelect;
ExtendPanelBtn.Visible = !MainPanel.PanelActive;
}
@ -155,10 +234,10 @@ namespace Simitone.Client.UI.Panels
Clock.Y = 15;
Money.Position = new Vector2(15, Game.ScreenHeight - 172);
var btn = LiveButton;
btn.Position = new Vector2(64 + 15, Game.ScreenHeight - (64 + 15));
ExtendPanelBtn.Position = new Vector2(btn.X + 54, btn.Y - 50);
MainPanel.Y = btn.Y - 64;
var mode = ModeSwitcher;
mode.Position = new Vector2(64 + 15, Game.ScreenHeight - (64 + 15));
ExtendPanelBtn.Position = new Vector2(mode.X + 54, mode.Y - 50);
MainPanel.Y = mode.Y - 64;
}
}
}

View file

@ -27,16 +27,17 @@ namespace Simitone.Client.UI.Panels
Game = screen;
Bg = Content.Get().CustomUI.Get("pswitch_bg.png").Get(GameFacade.GraphicsDevice);
var familyMembers = Game.vm.Context.ObjectQueries.Avatars.Where(x => ((VMAvatar)x).GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.TS1FamilyNumber) == (Game.vm.CurrentFamily.ChunkID));
var familyMembers = Game.vm.Context.ObjectQueries.Avatars.Where(x => ((VMAvatar)x).GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.TS1FamilyNumber) == (Game.vm.CurrentFamily?.ChunkID));
int i = 0;
foreach (var fam in familyMembers)
{
var btn = new UIAvatarSelectButton(UIIconCache.GetObject(fam));
btn.Name = fam.Name;
if (fam.PersistID > 0) btn.Outlined = true;
btn.Opacity = 0f;
var id = fam.ObjectID;
btn.OnButtonClick += (b) => { Select(id); };
btn.Y = 64;
btn.Y = 54;
GameFacade.Screens.Tween.To(btn, 0.3f, new Dictionary<string, float>() { { "X", 185 + (i++) * 100 }, { "Opacity", 1f } }, TweenQuad.EaseOut);
Add(btn);
}
@ -72,11 +73,15 @@ namespace Simitone.Client.UI.Panels
public Texture2D Icon;
public Texture2D Outline;
public bool Outlined;
public string Name;
public TextStyle Style;
public UIAvatarSelectButton(Texture2D icon) : base(Content.Get().CustomUI.Get("pswitch_icon_bg.png").Get(GameFacade.GraphicsDevice))
{
Icon = icon;
Outline = Content.Get().CustomUI.Get("pswitch_icon_sel.png").Get(GameFacade.GraphicsDevice);
Style = TextStyle.DefaultLabel.Clone();
Style.Color = Color.White;
}
public override void Draw(UISpriteBatch SBatch)
@ -84,6 +89,14 @@ namespace Simitone.Client.UI.Panels
DrawLocalTexture(SBatch, Texture, null, new Vector2(Texture.Width, Texture.Height) / -2, Vector2.One, new Color(104, 164, 184, 255));
if (Icon != null) DrawLocalTexture(SBatch, Icon, new Vector2(Icon.Width, Icon.Height) / -2);
if (Outlined) DrawLocalTexture(SBatch, Outline, null, new Vector2(Outline.Width, Outline.Height) / -2, Vector2.One, UIStyle.Current.ActiveSelection);
if (Name != null)
{
Style.Size = 10;
var size = Style.MeasureString(Name);
Style.Size = (int)Math.Min(15, Math.Max(8, (100 / size.X) * 10));
var name2 = Style.TruncateToWidth(Name, 100);
DrawLocalString(SBatch, name2, new Vector2(0, Texture.Height / 2 + 16), Style, new Rectangle(0, 0, 1, 1), TextAlignment.Center | TextAlignment.Middle);
}
}
}
}

View file

@ -10,6 +10,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@ -60,8 +61,12 @@ namespace Simitone.Client.UI.Panels.WorldUI
{
if (Sprites == null)
{
Sprites = new FSO.Files.Formats.IFF.IffFile(FSO.Content.Content.Get().GetPath("objectdata/globals/sprites.iff"));
WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice);
var content = FSO.Content.Content.Get();
Sprites = new FSO.Files.Formats.IFF.IffFile(
content.TS1?
Path.Combine(content.TS1BasePath, "GameData/Sprites.iff") :
content.GetPath("objectdata/globals/sprites.iff")
);
}
if (Headline.Operand.Group != VMSetBalloonHeadlineOperandGroup.Algorithmic)
@ -71,7 +76,6 @@ namespace Simitone.Client.UI.Panels.WorldUI
BGSprite = Sprites.Get<SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon]+Headline.Operand.Type));
LastZoom = WorldZoom.Near;
RecalculateTarget();
}
public void RecalculateTarget()
@ -133,9 +137,10 @@ namespace Simitone.Client.UI.Panels.WorldUI
}
public override Texture2D DrawFrame(World world)
{
{
if (LastZoom != world.State.Zoom || Texture == null)
{
if (WhitePx == null) WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice);
Invalidated = true;
LastZoom = world.State.Zoom;
RecalculateTarget();

View file

@ -1,6 +1,7 @@

using FSO.Client;
using FSO.Client.Debug;
using FSO.Client.UI.Controls;
using FSO.Client.UI.Framework;
using FSO.Client.UI.Model;
using FSO.Common;
@ -76,7 +77,7 @@ namespace Simitone.Client.UI.Screens
else
{
var targ = (WorldZoom)(4 - value); //near is 3 for some reason... will probably revise
HITVM.Get().PlaySoundEvent(UIMusic.None);
//HITVM.Get().PlaySoundEvent(UIMusic.None);
LotControl.Visible = true;
Bg.Visible = false;
World.Visible = true;
@ -173,17 +174,25 @@ namespace Simitone.Client.UI.Screens
if (Content.Get().TS1)
{
TS1NeighPanel = new UINeighborhoodSelectionPanel(4);
TS1NeighPanel.OnHouseSelect += (house) =>
{
ActiveFamily = Content.Get().Neighborhood.GetFamilyForHouse((short)house);
InitializeLot(Path.Combine(Content.Get().TS1BasePath, "UserData/Houses/House" + house.ToString().PadLeft(2, '0') + ".iff"), false);// "UserData/Houses/House21.iff"
Remove(TS1NeighPanel);
};
Add(TS1NeighPanel);
NeighSelection();
}
}
public void NeighSelection()
{
TS1NeighPanel = new UINeighborhoodSelectionPanel(4);
var switcher = new UINeighbourhoodSwitcher(TS1NeighPanel, 4);
TS1NeighPanel.OnHouseSelect += (house) =>
{
ActiveFamily = Content.Get().Neighborhood.GetFamilyForHouse((short)house);
InitializeLot(Path.Combine(FSOEnvironment.UserDir, "UserData/Houses/House" + house.ToString().PadLeft(2, '0') + ".iff"), false);// "UserData/Houses/House21.iff"
Remove(TS1NeighPanel);
Remove(switcher);
};
Add(TS1NeighPanel);
Add(switcher);
}
public override void GameResized()
{
base.GameResized();
@ -208,6 +217,7 @@ namespace Simitone.Client.UI.Screens
//3 speed is 10x
if (vm == null) return;
if (vm.SpeedMultiplier == -1) return;
switch (vm.SpeedMultiplier)
{
@ -300,7 +310,10 @@ namespace Simitone.Client.UI.Screens
}
SwitchLot = -1;
}
//vm.Context.Clock.Hours = 12;
if (vm != null) vm.Update();
//SaveHouseButton_OnButtonClick(null);
}
public override void PreDraw(UISpriteBatch batch)
@ -359,7 +372,7 @@ namespace Simitone.Client.UI.Screens
World.Opacity = 1;
GameFacade.Scenes.Add(World);
var globalLink = new VMTSOGlobalLinkStub();
var globalLink = new VMTS1GlobalLinkStub();
Driver = new VMServerDriver(globalLink);
vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
@ -368,14 +381,7 @@ namespace Simitone.Client.UI.Screens
LotControl = new UILotControl(vm, World);
this.AddAt(0, LotControl);
Frontend = new UISimitoneFrontend(this);
this.Add(Frontend);
var time = DateTime.UtcNow;
var tsoTime = TSOTime.FromUTC(time);
vm.Context.Clock.Hours = tsoTime.Item1;
vm.Context.Clock.Minutes = tsoTime.Item2;
if (m_ZoomLevel > 3)
{
World.Visible = false;
@ -425,6 +431,9 @@ namespace Simitone.Client.UI.Screens
GameFacade.Cursor.SetCursor(CursorType.Normal);
ZoomLevel = 1;
Frontend = new UISimitoneFrontend(this);
this.Add(Frontend);
}
public void InitializeLot(string lotName, bool external)
@ -441,7 +450,6 @@ namespace Simitone.Client.UI.Screens
}
BlueprintReset(lotName);
vm.Context.Clock.Hours = 0;
vm.TSOState.Size = (10) | (3 << 8);
vm.Context.UpdateTSOBuildableArea();
vm.MyUID = 1;
@ -471,6 +479,9 @@ namespace Simitone.Client.UI.Screens
GameFacade.Cursor.SetCursor(CursorType.Normal);
ZoomLevel = 1;
}
Frontend = new UISimitoneFrontend(this);
this.Add(Frontend);
}
public void BlueprintReset(string path)
@ -515,7 +526,14 @@ namespace Simitone.Client.UI.Screens
TargetSize = targetSize
});
}
vm.Tick();
if (ActiveFamily == null)
{
vm.SetGlobalValue(32, 1);
vm.SpeedMultiplier = -1;
}
}
@ -546,14 +564,75 @@ namespace Simitone.Client.UI.Screens
if (vm == null) return;
var exporter = new VMWorldExporter();
exporter.SaveHouse(vm, GameFacade.GameFilePath("housedata/blueprints/house_00.xml"));
Directory.CreateDirectory(Path.Combine(FSOEnvironment.UserDir, "Blueprints/cas.xml"));
exporter.SaveHouse(vm, Path.Combine(FSOEnvironment.UserDir, "Blueprints/cas.xml"));
var marshal = vm.Save();
Directory.CreateDirectory(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/"));
using (var output = new FileStream(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/house_00.fsov"), FileMode.Create))
using (var output = new FileStream(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/cas.fsov"), FileMode.Create))
{
marshal.SerializeInto(new BinaryWriter(output));
}
if (vm.GlobalLink != null) ((VMTSOGlobalLinkStub)vm.GlobalLink).Database.Save();
}
private UIMobileAlert CloseAlert;
public override bool CloseAttempt()
{
GameThread.NextUpdate(x =>
{
if (CloseAlert == null)
{
var canSave = vm != null;
CloseAlert = new UIMobileAlert(new FSO.Client.UI.Controls.UIAlertOptions
{
Title = GameFacade.Strings.GetString("153", "1"), //quit?
Message = GameFacade.Strings.GetString("153", canSave?"6":"2"), //are you sure (2), save before quitting (3)
Buttons =
canSave?
UIAlertButton.YesNoCancel(
(b) => { Save(); GameFacade.Game.Exit(); },
(b) => { GameFacade.Game.Exit(); },
(b) => { CloseAlert.Close(); CloseAlert = null; }
)
:
UIAlertButton.YesNo(
(b) => { GameFacade.Game.Exit(); },
(b) => { CloseAlert.Close(); CloseAlert = null; }
)
});
GlobalShowDialog(CloseAlert, true);
}
});
return false;
}
public void ReturnToNeighbourhood()
{
if (CloseAlert == null)
{
CloseAlert = new UIMobileAlert(new FSO.Client.UI.Controls.UIAlertOptions
{
Title = GameFacade.Strings.GetString("153", "3"), //save
Message = GameFacade.Strings.GetString("153", "4"), //Do you want to save the game?
Buttons =
UIAlertButton.YesNoCancel(
(b) => { Save(); ExitLot(); CloseAlert.Close(); CloseAlert = null; },
(b) => { ExitLot(); CloseAlert.Close(); CloseAlert = null; },
(b) => { CloseAlert.Close(); CloseAlert = null; }
)
});
GlobalShowDialog(CloseAlert, true);
}
}
public void Save()
{
}
public void ExitLot()
{
CleanupLastWorld();
NeighSelection();
}
}
}

View file

@ -12,6 +12,7 @@ namespace Simitone.Windows.GameLocator
{
public string FindTheSimsOnline()
{
return "";
string Software = "";
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))

View file

@ -4,7 +4,9 @@ using FSO.LotView;
using Simitone.Client;
using Simitone.Windows.GameLocator;
using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace Simitone.Windows
{
@ -27,6 +29,7 @@ namespace Simitone.Windows
if (useDX) GlobalSettings.Default.AntiAlias = false;
FSOEnvironment.Enable3D = false;
bool ide = false;
#region User resolution parmeters
@ -65,6 +68,8 @@ namespace Simitone.Windows
{
FSOEnvironment.ContentDir = "Content/";
FSOEnvironment.GFXContentDir = "Content/" + (useDX ? "DX/" : "OGL/");
FSOEnvironment.UserDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Simitone/").Replace('\\', '/');
Directory.CreateDirectory(FSOEnvironment.UserDir);
FSOEnvironment.Linux = false;
FSOEnvironment.DirectX = useDX;
FSOEnvironment.GameThread = Thread.CurrentThread;
@ -83,10 +88,17 @@ namespace Simitone.Windows
if (ide) new FSO.IDE.VolcanicStartProxy().InitVolcanic();
SimitoneGame game = new SimitoneGame();
var form = (Form)Form.FromHandle(game.Window.Handle);
if (form != null) form.FormClosing += Form_FormClosing;
game.Run();
game.Dispose();
}
}
private static void Form_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = !(GameFacade.Screens.CurrentUIScreen?.CloseAttempt() ?? true);
}
}
#endif
}

View file

@ -47,6 +47,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>

2
FreeSO

@ -1 +1 @@
Subproject commit 6752ed394a8ae6d2a116cb6fcd1ea2cf6e39f998
Subproject commit 6385ba5cf5025b27b952b5e8a585bacf0af7af00