[WIP] Pre 1.0 Testing Commit
Moving onto a more common commit cycle here - 2D CAS, family management, move in (even magic town with magicoins) - WIP Lot Saves - A ton of engine fixes (mostly in FreeSO project) - A ton of UI things, icons for all build/buy categories - Animation speed increase (consistent with TS1, 30 fps at 50 hz) - Cool transitions to cas 🆒 😎 - A lot more
BIN
.DS_Store
vendored
Normal file
BIN
Client/Simitone/Simitone.Client/Content/3D/TEX_0.png
Normal file
After Width: | Height: | Size: 340 B |
BIN
Client/Simitone/Simitone.Client/Content/3D/TEX_1.png
Normal file
After Width: | Height: | Size: 224 B |
BIN
Client/Simitone/Simitone.Client/Content/3D/arrow.fsom
Normal file
BIN
Client/Simitone/Simitone.Client/Content/3D/star.fsom
Normal file
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 570 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 886 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 846 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 670 B |
After Width: | Height: | Size: 920 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 922 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 575 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 889 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 1,005 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 873 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 808 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 700 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 813 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 727 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 683 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 787 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 815 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 608 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 482 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 436 B |
After Width: | Height: | Size: 959 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 8.5 KiB |
|
@ -23,7 +23,22 @@ namespace Simitone.Client
|
|||
{
|
||||
GameThread.NextUpdate((x) =>
|
||||
{
|
||||
var screen = new TS1GameScreen();
|
||||
var mode = NeighSelectionMode.Normal;
|
||||
if (lotName.Length > 1 && lotName[0] == '!')
|
||||
{
|
||||
switch (lotName[1])
|
||||
{
|
||||
case 'n':
|
||||
mode = NeighSelectionMode.MoveIn; break;
|
||||
case 'm':
|
||||
mode = NeighSelectionMode.MoveInMagic; break;
|
||||
}
|
||||
}
|
||||
var screen = new TS1GameScreen(mode);
|
||||
if (mode != NeighSelectionMode.Normal)
|
||||
{
|
||||
screen.StartMoveIn(int.Parse(lotName.Substring(2)));
|
||||
}
|
||||
var last = GameFacade.Screens.CurrentUIScreen;
|
||||
GameFacade.Screens.RemoveCurrent();
|
||||
GameFacade.Screens.AddScreen(screen);
|
||||
|
@ -46,14 +61,14 @@ namespace Simitone.Client
|
|||
|
||||
public static void EnterCAS()
|
||||
{
|
||||
GameThread.NextUpdate((x) =>
|
||||
{
|
||||
//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);
|
||||
});
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,11 +54,14 @@
|
|||
<Compile Include="UI\Controls\UIElasticButton.cs" />
|
||||
<Compile Include="UI\Controls\UISkillDisplay.cs" />
|
||||
<Compile Include="UI\Controls\UIStencilButton.cs" />
|
||||
<Compile Include="UI\Controls\UITouchListbox.cs" />
|
||||
<Compile Include="UI\Controls\UITouchScroll.cs" />
|
||||
<Compile Include="UI\Controls\UITwoStateButton.cs" />
|
||||
<Compile Include="UI\Controls\UIValueBar.cs" />
|
||||
<Compile Include="UI\Model\UIIconCache.cs" />
|
||||
<Compile Include="UI\Model\UIStyle.cs" />
|
||||
<Compile Include="UI\Panels\CAS\UIFamiliesCASPanel.cs" />
|
||||
<Compile Include="UI\Panels\CAS\UIFamilyCASItem.cs" />
|
||||
<Compile Include="UI\Panels\CAS\UIFamilyCASPanel.cs" />
|
||||
<Compile Include="UI\Panels\CAS\UISimCASPanel.cs" />
|
||||
<Compile Include="UI\Panels\LiveSubpanels\Catalog\UICatalogItem.cs" />
|
||||
|
@ -71,7 +74,7 @@
|
|||
<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\LotControls\UICallNeighborAlert.cs" />
|
||||
<Compile Include="UI\Panels\UIClockPanel.cs" />
|
||||
<Compile Include="UI\Panels\UICutawayPanel.cs" />
|
||||
<Compile Include="UI\Panels\UIHouseSelectPanel.cs" />
|
||||
|
@ -92,11 +95,13 @@
|
|||
<Compile Include="UI\Panels\UIRotationAnimation.cs" />
|
||||
<Compile Include="UI\Panels\UISimitoneFrontend.cs" />
|
||||
<Compile Include="UI\Panels\UISwitchAvatarPanel.cs" />
|
||||
<Compile Include="UI\Panels\UITransDialog.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" />
|
||||
<Compile Include="Utils\SimitoneNeighOBJExporter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.Net.WindowsGL.csproj">
|
||||
|
@ -145,6 +150,21 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\3D\TEX_0.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\3D\TEX_1.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\cas\btn_createfam.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\cas\btn_deletefam.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\cas\btn_movein.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\cas\cas_adult.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -196,6 +216,9 @@
|
|||
<Content Include="Content\uigraphics\common\btn_back.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\common\circle10px.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\dialog\ngbh_outline.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -247,6 +270,33 @@
|
|||
<Content Include="Content\uigraphics\live\cat\cat_cancel.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_dt_food.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_dt_out.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_dt_shop.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_dt_street.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_st_spa.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_st_studio.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_vac_amen.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_vac_lodg.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat\cat_vac_recr.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\live\cat_btn_base.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -658,6 +708,12 @@
|
|||
<Content Include="Content\uigraphics\ngbh\ngbh_vacat.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\trans\trans_cas.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\uigraphics\trans\trans_normal.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\TS1Patch\PetGym_performance.piff">
|
||||
|
@ -682,6 +738,16 @@
|
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\3D\arrow.fsom">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\3D\star.fsom">
|
||||
<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.
|
||||
|
|
|
@ -20,6 +20,7 @@ using Microsoft.Xna.Framework.Audio;
|
|||
using FSO.HIT.Model;
|
||||
using FSO.Client;
|
||||
using FSO.Files;
|
||||
using FSO.SimAntics;
|
||||
|
||||
namespace Simitone.Client
|
||||
{
|
||||
|
@ -35,12 +36,12 @@ namespace Simitone.Client
|
|||
public SimitoneGame() : base()
|
||||
{
|
||||
GameFacade.Game = this;
|
||||
ImageLoader.PremultiplyPNG = true;
|
||||
if (GameFacade.DirectX) TimedReferenceController.SetMode(CacheType.PERMANENT);
|
||||
Content.RootDirectory = FSOEnvironment.GFXContentDir;
|
||||
|
||||
TargetElapsedTime = new TimeSpan(10000000 / GlobalSettings.Default.TargetRefreshRate);
|
||||
FSOEnvironment.RefreshRate = GlobalSettings.Default.TargetRefreshRate;
|
||||
FSOEnvironment.TexCompress = false;
|
||||
|
||||
if (!FSOEnvironment.SoftwareKeyboard)
|
||||
{
|
||||
|
@ -91,8 +92,8 @@ namespace Simitone.Client
|
|||
var settings = GlobalSettings.Default;
|
||||
if (FSOEnvironment.DPIScaleFactor != 1 || FSOEnvironment.SoftwareDepth)
|
||||
{
|
||||
settings.GraphicsWidth = GraphicsDevice.Viewport.Width / FSOEnvironment.DPIScaleFactor;
|
||||
settings.GraphicsHeight = GraphicsDevice.Viewport.Height / FSOEnvironment.DPIScaleFactor;
|
||||
settings.GraphicsWidth = (int)(GraphicsDevice.Viewport.Width / FSOEnvironment.DPIScaleFactor);
|
||||
settings.GraphicsHeight = (int)(GraphicsDevice.Viewport.Height / FSOEnvironment.DPIScaleFactor);
|
||||
}
|
||||
|
||||
FSO.LotView.WorldConfig.Current = new FSO.LotView.WorldConfig()
|
||||
|
|
|
@ -69,7 +69,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);
|
||||
DrawLocalTexture(SBatch, Texture, null, new Vector2(Texture.Width, Texture.Height) / -2, Vector2.One, Color.White * (Disabled?0.5f:1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,15 @@ namespace Simitone.Client.UI.Controls
|
|||
GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary<string, float>() { { "InterpolatedAnimation", 1f} }, TweenQuad.EaseOut);
|
||||
}
|
||||
|
||||
public override void GameResized()
|
||||
{
|
||||
base.GameResized();
|
||||
TitleBg.SetSize(Width, 70);
|
||||
Width = GameFacade.Screens.CurrentUIScreen.ScreenWidth;
|
||||
ScrHeight = GameFacade.Screens.CurrentUIScreen.ScreenHeight;
|
||||
InterpolatedAnimation = InterpolatedAnimation;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!Closing)
|
||||
|
|
131
Client/Simitone/Simitone.Client/UI/Controls/UITouchListbox.cs
Normal file
|
@ -0,0 +1,131 @@
|
|||
using FSO.Client.UI.Controls;
|
||||
using FSO.Client.UI.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FSO.Client;
|
||||
using FSO.Content;
|
||||
using Simitone.Client.UI.Model;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using FSO.Common.Utils;
|
||||
|
||||
namespace Simitone.Client.UI.Controls
|
||||
{
|
||||
public class UITouchStringList : UIContainer
|
||||
{
|
||||
public UIImage Outline;
|
||||
public UITouchScroll ScrollElem;
|
||||
public event Action<int> OnSelectionChange;
|
||||
|
||||
private Vector2 _Size;
|
||||
public override Vector2 Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Size;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_Size = value;
|
||||
Outline.Width = value.X;
|
||||
Outline.Height = value.Y;
|
||||
ScrollElem.Size = new Vector2(value.X - 12, value.Y - 12);
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> BackingList = new List<string>();
|
||||
|
||||
public UITouchStringList()
|
||||
{
|
||||
var gd = GameFacade.GraphicsDevice;
|
||||
var ui = Content.Get().CustomUI;
|
||||
|
||||
ScrollElem = new UITouchScroll(GetLength, GetElemAt);
|
||||
ScrollElem.VerticalMode = true;
|
||||
ScrollElem.Position = new Vector2(6);
|
||||
ScrollElem.ItemWidth = 38;
|
||||
ScrollElem.DrawBounds = false;
|
||||
ScrollElem.Margin = 6;
|
||||
ScrollElem.SetScroll(-6);
|
||||
Add(ScrollElem);
|
||||
|
||||
Outline = new UIImage(ui.Get("cat_btn_base.png").Get(gd)).With9Slice(25, 25, 25, 25);
|
||||
Add(Outline);
|
||||
}
|
||||
|
||||
public void SelectionChanged(int id)
|
||||
{
|
||||
OnSelectionChange?.Invoke(id);
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
ScrollElem.Reset();
|
||||
}
|
||||
|
||||
public int GetLength()
|
||||
{
|
||||
return BackingList.Count;
|
||||
}
|
||||
|
||||
public UITSContainer GetElemAt(int i)
|
||||
{
|
||||
return new UITouchStringListItem(BackingList[i], new Point((int)Size.X-12, ScrollElem.ItemWidth), this);
|
||||
}
|
||||
}
|
||||
|
||||
public class UITouchStringListItem : UITSContainer
|
||||
{
|
||||
public string Value;
|
||||
public Point ESize;
|
||||
public bool Outlined;
|
||||
public UITouchStringList TParent;
|
||||
public UILabel Label;
|
||||
private Texture2D Px;
|
||||
public float SelectPct { get; set; }
|
||||
|
||||
public UITouchStringListItem(string value, Point esize, UITouchStringList parent)
|
||||
{
|
||||
TParent = parent;
|
||||
Value = value;
|
||||
ESize = esize;
|
||||
Px = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice);
|
||||
Label = new UILabel();
|
||||
Label.CaptionStyle = Label.CaptionStyle.Clone();
|
||||
Label.CaptionStyle.Size = 19;
|
||||
Label.CaptionStyle.Color = UIStyle.Current.Text;
|
||||
Label.Alignment = TextAlignment.Middle | TextAlignment.Left;
|
||||
Label.Caption = Label.CaptionStyle.TruncateToWidth(value, esize.X-20);
|
||||
Label.Size = esize.ToVector2();
|
||||
Label.X += 10;
|
||||
Add(Label);
|
||||
|
||||
SelectPct = SelectPct;
|
||||
}
|
||||
|
||||
public override void Selected()
|
||||
{
|
||||
Outlined = true;
|
||||
Label.CaptionStyle.Color = UIStyle.Current.Bg;
|
||||
GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary<string, float>() { { "SelectPct", 1f } }, TweenQuad.EaseOut);
|
||||
TParent.SelectionChanged(ItemID);
|
||||
}
|
||||
|
||||
public override void Deselected()
|
||||
{
|
||||
Label.CaptionStyle.Color = UIStyle.Current.Text;
|
||||
GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary<string, float>() { { "SelectPct", 0f } }, TweenQuad.EaseOut);
|
||||
Outlined = false;
|
||||
}
|
||||
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
DrawLocalTexture(batch, Px, null, Vector2.Zero, new Vector2(ESize.X*SelectPct, ESize.Y), UIStyle.Current.SecondaryText);
|
||||
base.Draw(batch);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ namespace Simitone.Client.UI.Controls
|
|||
public Texture2D ScrollEdgeR;
|
||||
public bool DrawBounds = true;
|
||||
public int Margin;
|
||||
public bool VerticalMode;
|
||||
|
||||
private UIMouseEventRef HitTest;
|
||||
|
||||
|
@ -86,9 +87,19 @@ namespace Simitone.Client.UI.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private int GetPAxis(Point p)
|
||||
{
|
||||
return (VerticalMode) ? p.Y : p.X;
|
||||
}
|
||||
|
||||
private float GetPAxis(Vector2 p)
|
||||
{
|
||||
return (VerticalMode) ? p.Y : p.X;
|
||||
}
|
||||
|
||||
public void Select(Point at)
|
||||
{
|
||||
var item = (int)(at.X + Scroll) / ItemWidth;
|
||||
var item = (int)(GetPAxis(at) + Scroll) / ItemWidth;
|
||||
if (item >= LengthProvider()) return;
|
||||
var rItem = GetOrPrepare(item);
|
||||
if (rItem != null)
|
||||
|
@ -107,6 +118,11 @@ namespace Simitone.Client.UI.Controls
|
|||
item = ElemProvider(id);
|
||||
item.Visible = false;
|
||||
item.ItemID = id;
|
||||
if (id == LastSelected?.ItemID)
|
||||
{
|
||||
item.Selected();
|
||||
LastSelected = item;
|
||||
}
|
||||
Add(item);
|
||||
}
|
||||
return item;
|
||||
|
@ -133,11 +149,11 @@ namespace Simitone.Client.UI.Controls
|
|||
var pos = lastMouse.MouseState.Position;
|
||||
if (!InScroll)
|
||||
{
|
||||
if (Math.Abs((pos - MouseDownAt).X) > 25) InScroll = true;
|
||||
if (Math.Abs(GetPAxis(pos - MouseDownAt)) > 25) InScroll = true;
|
||||
}
|
||||
if (InScroll)
|
||||
{
|
||||
ScrollVelocity = -(pos - MouseDownAt).X;
|
||||
ScrollVelocity = -GetPAxis(pos - MouseDownAt);
|
||||
MouseDownAt = pos;
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +164,7 @@ namespace Simitone.Client.UI.Controls
|
|||
|
||||
Scroll += ScrollVelocity;
|
||||
ScrollVelocity *= 0.9f;
|
||||
Scroll = Math.Max(-Margin, Math.Min(length * ItemWidth - Size.X + Margin, Scroll));
|
||||
Scroll = Math.Max(-Margin, Math.Min(length * ItemWidth - GetPAxis(Size) + Margin, Scroll));
|
||||
|
||||
//update children positions.
|
||||
//delete ones that are not
|
||||
|
@ -156,14 +172,15 @@ namespace Simitone.Client.UI.Controls
|
|||
var untouched = new HashSet<UIElement>(Children);
|
||||
|
||||
var b = (int)(Scroll / ItemWidth);
|
||||
var e = b + (Size.X + (ItemWidth - 1)) / ItemWidth;
|
||||
var e = b + (GetPAxis(Size) + (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);
|
||||
item.X = i * ItemWidth - Scroll;
|
||||
if (VerticalMode) item.Y = i * ItemWidth - Scroll;
|
||||
else item.X = i * ItemWidth - Scroll;
|
||||
item.Visible = true;
|
||||
}
|
||||
|
||||
|
@ -182,11 +199,20 @@ namespace Simitone.Client.UI.Controls
|
|||
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
if (!Visible) return;
|
||||
base.Draw(batch);
|
||||
if (DrawBounds)
|
||||
{
|
||||
DrawLocalTexture(batch, ScrollEdgeL, new Vector2(0, Size.Y / 2 - 64));
|
||||
DrawLocalTexture(batch, ScrollEdgeR, new Vector2(Size.X - 15, Size.Y / 2 - 64));
|
||||
if (VerticalMode)
|
||||
{
|
||||
DrawLocalTexture(batch, ScrollEdgeL, null, new Vector2(Size.X / 2 - 64, 0), Vector2.One, Color.White, (float)Math.PI/2f, new Vector2(0, ScrollEdgeL.Height));
|
||||
DrawLocalTexture(batch, ScrollEdgeR, null, new Vector2(Size.X / 2 - 64, Size.Y - 15), Vector2.One, Color.White, (float)Math.PI / 2f, new Vector2(0, ScrollEdgeL.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawLocalTexture(batch, ScrollEdgeL, new Vector2(0, Size.Y / 2 - 64));
|
||||
DrawLocalTexture(batch, ScrollEdgeR, new Vector2(Size.X - 15, Size.Y / 2 - 64));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FSO.Client.UI.Framework;
|
||||
|
||||
namespace Simitone.Client.UI.Controls
|
||||
{
|
||||
|
@ -14,5 +15,14 @@ namespace Simitone.Client.UI.Controls
|
|||
{
|
||||
ImageStates = 2;
|
||||
}
|
||||
|
||||
public override void Draw(UISpriteBatch SBatch)
|
||||
{
|
||||
var oldOpacity = Opacity;
|
||||
if (Disabled) Opacity = 0.5f;
|
||||
var col = BlendColor;
|
||||
base.Draw(SBatch);
|
||||
if (Disabled) Opacity = oldOpacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ namespace Simitone.Client.UI.Model
|
|||
if (obj is VMAvatar)
|
||||
{
|
||||
var ava = (VMAvatar)obj;
|
||||
var id = ava.HeadOutfit.Name +":"+ ava.HeadOutfit.OftData.TS1TextureID;
|
||||
var headname = ava.HeadOutfit.Name;
|
||||
if (headname == "") headname = ava.BodyOutfit.OftData.TS1TextureID;
|
||||
var id = headname +":"+ ava.HeadOutfit.OftData.TS1TextureID;
|
||||
|
||||
Texture2D result = null;
|
||||
if (!AvatarHeadCache.TryGetValue(id, out result))
|
||||
|
|
|
@ -42,5 +42,7 @@ namespace Simitone.Client.UI.Model
|
|||
public Color SkillInactive = new Color(99, 109, 242, 255);
|
||||
public Color SkillActive = new Color(0, 255, 255, 255);
|
||||
public Color SkillNeeded = new Color(255, 191, 0, 255);
|
||||
|
||||
public Color TransColor = new Color(0, 41, 69, 255);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
using FSO.Client;
|
||||
using FSO.Client.UI.Controls;
|
||||
using FSO.Client.UI.Framework;
|
||||
using FSO.Common.Utils;
|
||||
using FSO.Content;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using FSO.SimAntics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.UI.Panels.CAS
|
||||
{
|
||||
/// <summary>
|
||||
/// Lists all of the families that can be moved in or deleted.
|
||||
/// </summary>
|
||||
public class UIFamiliesCASPanel : UIContainer
|
||||
{
|
||||
public UITouchScroll FamilyList;
|
||||
public UILabel Title;
|
||||
public UITwoStateButton DeleteButton;
|
||||
public UITwoStateButton NewButton;
|
||||
|
||||
public event Action OnNewFamily;
|
||||
|
||||
public List<FAMI> Families = new List<FAMI>();
|
||||
private VM vm;
|
||||
private Texture2D WhitePx;
|
||||
|
||||
public int Selection;
|
||||
public float TitleI { get; set; }
|
||||
|
||||
public UIFamiliesCASPanel()
|
||||
{
|
||||
var gd = GameFacade.GraphicsDevice;
|
||||
var ui = Content.Get().CustomUI;
|
||||
var sh = UIScreen.Current.ScreenHeight;
|
||||
var sw = UIScreen.Current.ScreenWidth;
|
||||
FamilyList = new UITouchScroll(FamilyLength, FamilyProvider);
|
||||
FamilyList.VerticalMode = true;
|
||||
FamilyList.Size = new Vector2(810, sh);
|
||||
FamilyList.X = (sw - 810) / 2;
|
||||
FamilyList.ItemWidth = 180;
|
||||
FamilyList.Margin = 90;
|
||||
FamilyList.DrawBounds = false;
|
||||
Add(FamilyList);
|
||||
WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice);
|
||||
|
||||
Title = new UILabel();
|
||||
Title.NewStyle(UIStyle.Current.Text, 37);
|
||||
Title.Caption = "Select a Family";
|
||||
Title.Size = new Vector2(sw, 60);
|
||||
Title.Alignment = TextAlignment.Middle | TextAlignment.Center;
|
||||
Title.Y = -85;
|
||||
Add(Title);
|
||||
|
||||
DeleteButton = new UITwoStateButton(ui.Get("btn_deletefam.png").Get(gd));
|
||||
DeleteButton.Position = new Vector2(sw - 140, sh - 260);
|
||||
Add(DeleteButton);
|
||||
|
||||
NewButton = new UITwoStateButton(ui.Get("btn_createfam.png").Get(gd));
|
||||
NewButton.Position = new Vector2(sw - 140, sh - 380);
|
||||
Add(NewButton);
|
||||
NewButton.OnButtonClick += (btn) => OnNewFamily?.Invoke();
|
||||
|
||||
TitleI = TitleI;
|
||||
SetSelection(-1);
|
||||
}
|
||||
|
||||
public void SetSelection(int i)
|
||||
{
|
||||
Selection = i;
|
||||
DeleteButton.Disabled = Selection == -1;
|
||||
NewButton.Disabled = false;
|
||||
}
|
||||
|
||||
public override void GameResized()
|
||||
{
|
||||
var sh = UIScreen.Current.ScreenHeight;
|
||||
var sw = UIScreen.Current.ScreenWidth;
|
||||
FamilyList.Size = new Vector2(810, sh);
|
||||
FamilyList.X = (sw - 810) / 2;
|
||||
FamilyList.Reset();
|
||||
Title.Size = new Vector2(sw, 60);
|
||||
DeleteButton.Position = new Vector2(sw - 140, sh - 260);
|
||||
NewButton.Position = new Vector2(sw - 140, sh - 380);
|
||||
base.GameResized();
|
||||
}
|
||||
|
||||
public int FamilyLength()
|
||||
{
|
||||
return Families.Count;
|
||||
}
|
||||
|
||||
public UITSContainer FamilyProvider(int id)
|
||||
{
|
||||
var item = new UIFamilyCASItem(this, Families[id], vm);
|
||||
return item;
|
||||
}
|
||||
|
||||
public void UpdateFamilies(List<FAMI> families, VM vm)
|
||||
{
|
||||
this.vm = vm;
|
||||
Families = families;
|
||||
FamilyList.Reset();
|
||||
}
|
||||
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
var y = TitleI * 100 - 85;
|
||||
Title.Y = y;
|
||||
NewButton.X = UIScreen.Current.ScreenWidth - 140 * TitleI;
|
||||
DeleteButton.X = NewButton.X;
|
||||
|
||||
FamilyList.Opacity = TitleI;
|
||||
FamilyList.Visible = FamilyList.Opacity > 0;
|
||||
Title.Visible = false;
|
||||
base.Draw(batch);
|
||||
DrawLocalTexture(batch, WhitePx, null, new Vector2(0, y), new Vector2(UIScreen.Current.ScreenWidth, 60), UIStyle.Current.Bg);
|
||||
Title.Visible = true;
|
||||
Title.Draw(batch);
|
||||
}
|
||||
}
|
||||
}
|
125
Client/Simitone/Simitone.Client/UI/Panels/CAS/UIFamilyCASItem.cs
Normal file
|
@ -0,0 +1,125 @@
|
|||
using FSO.Client;
|
||||
using FSO.Client.UI.Controls;
|
||||
using FSO.Client.UI.Framework;
|
||||
using FSO.Common.Utils;
|
||||
using FSO.Content;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using FSO.LotView.Model;
|
||||
using FSO.SimAntics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.UI.Panels.CAS
|
||||
{
|
||||
public class UIFamilyCASItem : UITSContainer
|
||||
{
|
||||
public Texture2D PxWhite;
|
||||
public Texture2D Grad;
|
||||
public UIImage Background;
|
||||
public UIImage SelectedGrad;
|
||||
public UILabel FamilyTitle;
|
||||
public UIFamiliesCASPanel FParent;
|
||||
public List<UIAvatarSelectButton> Btns = new List<UIAvatarSelectButton>();
|
||||
|
||||
public int MaxWidth = 810;
|
||||
public int Width;
|
||||
public int TitleWidth;
|
||||
public float SelectPct { get; set; }
|
||||
|
||||
public UIFamilyCASItem(UIFamiliesCASPanel parent, FAMI family, VM vm)
|
||||
{
|
||||
FParent = parent;
|
||||
var ui = Content.Get().CustomUI;
|
||||
var gd = GameFacade.GraphicsDevice;
|
||||
|
||||
PxWhite = TextureGenerator.GetPxWhite(gd);
|
||||
Grad = ui.Get("dialog_title_grad.png").Get(gd);
|
||||
Background = new UIImage(ui.Get("circle10px.png").Get(gd)).With9Slice(19, 19, 19, 19);
|
||||
//set the width based on number of family members
|
||||
//30 margin on family thumbs
|
||||
Width = 100 * family.FamilyGUIDs.Length + 10;
|
||||
Background.SetSize(Width, 120);
|
||||
Background.Position = new Vector2((MaxWidth - Width) / 2, 40);
|
||||
Add(Background);
|
||||
|
||||
//max width is 100*8+10, 810
|
||||
|
||||
var fams = family.ChunkParent.Get<FAMs>(family.ChunkID);
|
||||
|
||||
FamilyTitle = new UILabel();
|
||||
FamilyTitle.CaptionStyle = FamilyTitle.CaptionStyle.Clone();
|
||||
FamilyTitle.CaptionStyle.Color = UIStyle.Current.Text;
|
||||
FamilyTitle.CaptionStyle.Size = 19;
|
||||
FamilyTitle.Size = new Vector2(MaxWidth, 40);
|
||||
FamilyTitle.Alignment = TextAlignment.Center | TextAlignment.Middle;
|
||||
FamilyTitle.Caption = fams?.GetString(0) ?? "";
|
||||
Add(FamilyTitle);
|
||||
|
||||
TitleWidth = (int)FamilyTitle.CaptionStyle.MeasureString(FamilyTitle.Caption).X + 30;
|
||||
|
||||
//display heads of all family members
|
||||
InitAvatarList(family.FamilyGUIDs, vm);
|
||||
SelectPct = SelectPct;
|
||||
}
|
||||
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
DrawLocalTexture(batch, PxWhite, null, new Vector2((MaxWidth - TitleWidth) / 2, 0), new Vector2(TitleWidth, 40), UIStyle.Current.Bg);
|
||||
Background.Visible = true;
|
||||
Background.Draw(batch);
|
||||
DrawLocalTexture(batch, Grad, null, new Vector2((MaxWidth - Width) / 2, 54), new Vector2((Width / (float)Grad.Width)*SelectPct, 66), Color.White);
|
||||
Background.Visible = false;
|
||||
base.Draw(batch);
|
||||
}
|
||||
|
||||
public void InitAvatarList(uint[] guids, VM vm)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var btn in Btns)
|
||||
{
|
||||
Remove(btn);
|
||||
}
|
||||
Btns.Clear();
|
||||
|
||||
i = 0;
|
||||
var baseX = MaxWidth / 2 - (guids.Length-1) * 50;
|
||||
foreach (var sim in guids)
|
||||
{
|
||||
var fam = vm.Context.CreateObjectInstance(sim, LotTilePos.OUT_OF_WORLD, Direction.NORTH).BaseObject;
|
||||
fam.Tick();
|
||||
var btn = new UIAvatarSelectButton(UIIconCache.GetObject(fam));
|
||||
btn.Opacity = 1f;
|
||||
var id = i;
|
||||
btn.Name = fam.Name;
|
||||
btn.X = baseX + (i++) * 100;
|
||||
btn.Y = 88;
|
||||
btn.DeregisterHandler();
|
||||
Btns.Add(btn);
|
||||
Add(btn);
|
||||
fam.Delete(true, vm.Context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Selected()
|
||||
{
|
||||
base.Selected();
|
||||
FamilyTitle.CaptionStyle.Color = UIStyle.Current.SecondaryText;
|
||||
GameFacade.Screens.Tween.To(this, 0.33f, new Dictionary<string, float>() { { "SelectPct", 1f } }, TweenQuad.EaseOut);
|
||||
FParent.SetSelection(ItemID);
|
||||
}
|
||||
|
||||
public override void Deselected()
|
||||
{
|
||||
base.Deselected();
|
||||
FamilyTitle.CaptionStyle.Color = UIStyle.Current.Text;
|
||||
GameFacade.Screens.Tween.To(this, 0.33f, new Dictionary<string, float>() { { "SelectPct", 0f } }, TweenQuad.EaseOut);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -369,7 +369,7 @@ namespace Simitone.Client.UI.Panels.CAS
|
|||
if (MouseOn)
|
||||
{
|
||||
//how much allowance do we have on this specifically
|
||||
var allowance = CAS.AllowedPoints - (CAS.TotalPoints - Points);
|
||||
var allowance = Math.Min(10, CAS.AllowedPoints - (CAS.TotalPoints - Points));
|
||||
var newPTs = Math.Max(0, Math.Min(allowance, (int)Math.Ceiling(GlobalPoint(state.MouseState.Position.ToVector2()).X / 24)));
|
||||
if (newPTs != Points)
|
||||
{
|
||||
|
|
|
@ -158,6 +158,122 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
},
|
||||
};
|
||||
|
||||
public static Dictionary<UICatalogMode, List<UICatalogSubcat>> DTCategories = new Dictionary<UICatalogMode, List<UICatalogSubcat>>()
|
||||
{
|
||||
{
|
||||
UICatalogMode.Downtown,
|
||||
new List<UICatalogSubcat>()
|
||||
{
|
||||
new UICatalogSubcat() { MaskBit = 0, StrTable = 150, StrInd = 16}, //food
|
||||
new UICatalogSubcat() { MaskBit = 1, StrTable = 150, StrInd = 17}, //shops
|
||||
new UICatalogSubcat() { MaskBit = 2, StrTable = 150, StrInd = 18}, //outside
|
||||
new UICatalogSubcat() { MaskBit = 3, StrTable = 150, StrInd = 19}, //street
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Community,
|
||||
new List<UICatalogSubcat>()
|
||||
{
|
||||
new UICatalogSubcat() { MaskBit = 0, StrTable = 150, StrInd = 32}, //food
|
||||
new UICatalogSubcat() { MaskBit = 1, StrTable = 150, StrInd = 33}, //shops
|
||||
new UICatalogSubcat() { MaskBit = 2, StrTable = 150, StrInd = 34}, //outside
|
||||
new UICatalogSubcat() { MaskBit = 3, StrTable = 150, StrInd = 35}, //street
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Vacation,
|
||||
new List<UICatalogSubcat>()
|
||||
{
|
||||
new UICatalogSubcat() { MaskBit = 0, StrTable = 150, StrInd = 24}, //lodging
|
||||
new UICatalogSubcat() { MaskBit = 1, StrTable = 150, StrInd = 25}, //shops
|
||||
new UICatalogSubcat() { MaskBit = 2, StrTable = 150, StrInd = 26}, //recreation
|
||||
new UICatalogSubcat() { MaskBit = 3, StrTable = 150, StrInd = 27}, //ameneties
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Studiotown,
|
||||
new List<UICatalogSubcat>()
|
||||
{
|
||||
new UICatalogSubcat() { MaskBit = 0, StrTable = 150, StrInd = 40}, //food
|
||||
new UICatalogSubcat() { MaskBit = 1, StrTable = 150, StrInd = 41}, //shops
|
||||
new UICatalogSubcat() { MaskBit = 2, StrTable = 150, StrInd = 42}, //studio
|
||||
new UICatalogSubcat() { MaskBit = 3, StrTable = 150, StrInd = 43}, //spa
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Magictown,
|
||||
new List<UICatalogSubcat>()
|
||||
{
|
||||
new UICatalogSubcat() { MaskBit = 0, StrTable = 150, StrInd = 16}, //food
|
||||
new UICatalogSubcat() { MaskBit = 1, StrTable = 150, StrInd = 17}, //shops
|
||||
new UICatalogSubcat() { MaskBit = 2, StrTable = 150, StrInd = 44}, //magico
|
||||
new UICatalogSubcat() { MaskBit = 3, StrTable = 150, StrInd = 18}, //outside
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
public static Dictionary<UICatalogMode, List<string>> DTIcons = new Dictionary<UICatalogMode, List<string>>()
|
||||
{
|
||||
{
|
||||
UICatalogMode.Downtown,
|
||||
new List<string>()
|
||||
{
|
||||
"dt_food", //food
|
||||
"dt_shop", //shops
|
||||
"dt_out", //outside
|
||||
"dt_street", //street
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Community,
|
||||
new List<string>()
|
||||
{
|
||||
"dt_food", //food
|
||||
"dt_shop", //shops
|
||||
"dt_out", //outside
|
||||
"dt_street", //street
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Vacation,
|
||||
new List<string>()
|
||||
{
|
||||
"vac_lodg", //food
|
||||
"dt_shop", //shops
|
||||
"vac_recr", //recreation
|
||||
"vac_amen", //amenities
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Studiotown,
|
||||
new List<string>()
|
||||
{
|
||||
"dt_food", //food
|
||||
"dt_shop", //shops
|
||||
"st_studio", //studio
|
||||
"st_spa", //spa
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
UICatalogMode.Magictown,
|
||||
new List<string>()
|
||||
{
|
||||
"dt_food", //food
|
||||
"dt_shop", //shops
|
||||
"misc_magi", //magic
|
||||
"dt_out", //outside
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static UIBuyBrowsePanel()
|
||||
{
|
||||
Categories = new List<List<UICatalogSubcat>>();
|
||||
|
@ -397,7 +513,32 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
|
||||
ChoosingSub = true;
|
||||
|
||||
var cats = (Mode == UICatalogMode.Build)?BuildCategories[category]:Categories[category];
|
||||
List<UICatalogSubcat> cats;
|
||||
if (Mode == UICatalogMode.Build) cats = BuildCategories[category];
|
||||
else if (Mode != UICatalogMode.Normal)
|
||||
{
|
||||
cats = DTCategories[Mode];
|
||||
if (cats.Count == 4) //haven't added other or all subcats yet
|
||||
{
|
||||
cats.Add(new UICatalogSubcat()
|
||||
{
|
||||
StrTable = 210,
|
||||
MaskBit = 7,
|
||||
StrInd = 1, //other
|
||||
});
|
||||
|
||||
cats.Add(new UICatalogSubcat()
|
||||
{
|
||||
StrTable = 210,
|
||||
MaskBit = 8,
|
||||
StrInd = 2, //all
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cats = Categories[category];
|
||||
}
|
||||
|
||||
var boff = CatContainer.Size.X/(cats.Count + 0.5f) / 2f;
|
||||
|
||||
|
@ -422,6 +563,11 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
if (Mode == UICatalogMode.Build) {
|
||||
name = BuildIcons[category][i];
|
||||
}
|
||||
else if (Mode != UICatalogMode.Normal) {
|
||||
if (cat.MaskBit == 7) name = "other";
|
||||
else if (cat.MaskBit == 8) name = "all";
|
||||
else name = DTIcons[Mode][cat.MaskBit];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cat.MaskBit == 7) name = "other";
|
||||
|
@ -434,6 +580,7 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
var subbutton = new UICatButton(Content.Get().CustomUI.Get("cat_"+name+".png").Get(GameFacade.GraphicsDevice));
|
||||
subbutton.OnButtonClick += (btn) => { InitSubcategory(cat); };
|
||||
subbutton.Position = new Vector2(boff * (1.5f + i * 2) - (65 / 2), 16);
|
||||
subbutton.Disabled = SubcatIsEmpty(cat);
|
||||
SelButtons.Add(subbutton);
|
||||
Add(subbutton);
|
||||
}
|
||||
|
@ -674,6 +821,24 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
}
|
||||
}
|
||||
|
||||
private bool SubcatIsEmpty(UICatalogSubcat cat)
|
||||
{
|
||||
var index = cat.MaskBit;
|
||||
if (Mode == UICatalogMode.Build)
|
||||
{
|
||||
return FullCategory.FirstOrDefault() == null;
|
||||
}
|
||||
else if (index == 8)
|
||||
{
|
||||
return !FullCategory.Any(x => (GetSubsort(x.Item)) > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
var mask = 1 << index;
|
||||
return !FullCategory.Any(x => (GetSubsort(x.Item) & mask) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitSubcategory(UICatalogSubcat cat)
|
||||
{
|
||||
var index = cat.MaskBit;
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace Simitone.Client.UI.Panels.LiveSubpanels
|
|||
if (sel == null) return;
|
||||
var neighbourhood = Content.Get().Neighborhood;
|
||||
var neighbour = sel.GetPersonData(VMPersonDataVariable.NeighborId);
|
||||
var inventory = neighbourhood.GetInventoryByNID(neighbour).Where(x => (CatSort == -1 && !HiddenCats.Contains(x.Type)) || CatSort == x.Type).ToList();
|
||||
var inventory = neighbourhood.GetInventoryByNID(neighbour)?.Where(x => (CatSort == -1 && !HiddenCats.Contains(x.Type)) || CatSort == x.Type)?.ToList() ?? new List<InventoryItem>();
|
||||
|
||||
bool difference = false;
|
||||
if (inventory.Count == Items.Count)
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
using FSO.Client.UI.Framework;
|
||||
using FSO.Content;
|
||||
using FSO.LotView.Model;
|
||||
using FSO.SimAntics;
|
||||
using FSO.SimAntics.Model;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.UI.Panels.LotControls
|
||||
{
|
||||
public class UICallNeighborAlert : UIMobileDialog
|
||||
{
|
||||
public UICallNeighborPanel NPanel;
|
||||
public short SelectedNeighbour
|
||||
{
|
||||
get
|
||||
{
|
||||
return NPanel.SelectedNeighbour;
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<int> OnResult;
|
||||
|
||||
public UICallNeighborAlert(short callerNID, VM vm)
|
||||
{
|
||||
Caption = "Call Neighbour";
|
||||
SetHeight(490);
|
||||
NPanel = new UICallNeighborPanel(callerNID, vm);
|
||||
NPanel.Position = new Microsoft.Xna.Framework.Vector2((Width - 1030) / 2, 110);
|
||||
NPanel.OnResult += (res) => { OnResult?.Invoke(res); Close(); };
|
||||
Add(NPanel);
|
||||
}
|
||||
}
|
||||
|
||||
public class UICallNeighborPanel : UIContainer
|
||||
{
|
||||
public Dictionary<short, List<short>> NeighborsByFamilyID = new Dictionary<short, List<short>>();
|
||||
public UITouchStringList FamilyList;
|
||||
public UITouchStringList NeighbourList;
|
||||
public UIAvatarSelectButton Icon;
|
||||
public UIBigButton CallButton;
|
||||
public int SelectedFamily = -1;
|
||||
public short SelectedNeighbour = -1;
|
||||
public VM VM;
|
||||
|
||||
public event Action<int> OnResult;
|
||||
|
||||
public UICallNeighborPanel(short callerNID, VM vm)
|
||||
{
|
||||
VM = vm;
|
||||
var nb = Content.Get().Neighborhood;
|
||||
var neigh = nb.GetNeighborByID(callerNID);
|
||||
var rels = neigh.Relationships.Keys;
|
||||
//var rels = nb.Neighbors.NeighbourByID.Keys;
|
||||
|
||||
foreach (var to in rels)
|
||||
{
|
||||
var tn = nb.GetNeighborByID((short)to);
|
||||
var family = tn.PersonData?.ElementAt((int)VMPersonDataVariable.TS1FamilyNumber) ?? 0;
|
||||
var gender = tn.PersonData?.ElementAt((int)VMPersonDataVariable.Gender) ?? 0; //can't call pets
|
||||
if (family != 0 && gender < 2)
|
||||
{
|
||||
List<short> famList = null;
|
||||
if (!NeighborsByFamilyID.TryGetValue(family, out famList))
|
||||
{
|
||||
famList = new List<short>();
|
||||
NeighborsByFamilyID[family] = famList;
|
||||
}
|
||||
|
||||
famList.Add((short)to);
|
||||
}
|
||||
}
|
||||
|
||||
FamilyList = new UITouchStringList();
|
||||
FamilyList.Size = new Microsoft.Xna.Framework.Vector2(320, 350);
|
||||
FamilyList.BackingList = NeighborsByFamilyID.Select(x => nb.GetFamilyString((ushort)x.Key).GetString(0)).ToList();
|
||||
FamilyList.Refresh();
|
||||
FamilyList.OnSelectionChange += FamilyList_OnSelectionChange;
|
||||
Add(FamilyList);
|
||||
|
||||
NeighbourList = new UITouchStringList();
|
||||
NeighbourList.Size = new Microsoft.Xna.Framework.Vector2(320, 350);
|
||||
NeighbourList.Position = new Microsoft.Xna.Framework.Vector2(370, 0);
|
||||
NeighbourList.OnSelectionChange += NeighbourList_OnSelectionChange;
|
||||
Add(NeighbourList);
|
||||
|
||||
var cancelButton = new UIBigButton(false);
|
||||
cancelButton.Caption = "Cancel";
|
||||
cancelButton.Position = new Microsoft.Xna.Framework.Vector2(370 + 385, 135);
|
||||
cancelButton.OnButtonClick += (btn) => { OnResult?.Invoke(-1); };
|
||||
cancelButton.Width = 275;
|
||||
Add(cancelButton);
|
||||
|
||||
CallButton = new UIBigButton(true);
|
||||
CallButton.Caption = "Call";
|
||||
CallButton.Position = new Microsoft.Xna.Framework.Vector2(370 + 385, 255);
|
||||
CallButton.OnButtonClick += (btn) => { OnResult?.Invoke(SelectedNeighbour); };
|
||||
CallButton.Width = 275;
|
||||
Add(CallButton);
|
||||
|
||||
NeighbourList_OnSelectionChange((NeighborsByFamilyID.Count==0)?-2:-1);
|
||||
|
||||
OnResult += (res) => { CallButton.Disabled = true; cancelButton.Disabled = true; };
|
||||
}
|
||||
|
||||
private void NeighbourList_OnSelectionChange(int obj)
|
||||
{
|
||||
if (Icon != null) { Remove(Icon); Icon = null; }
|
||||
if (obj == -1)
|
||||
{
|
||||
SelectedNeighbour = -1;
|
||||
CallButton.Disabled = true;
|
||||
} else
|
||||
{
|
||||
SelectedNeighbour = NeighborsByFamilyID.ElementAt(SelectedFamily).Value[obj];
|
||||
CallButton.Disabled = false;
|
||||
|
||||
var guid = Content.Get().Neighborhood.GetNeighborByID(SelectedNeighbour).GUID;
|
||||
var temp = VM.Context.CreateObjectInstance(guid, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true);
|
||||
Icon = new UIAvatarSelectButton(UIIconCache.GetObject(temp.BaseObject));
|
||||
Icon.Position = new Microsoft.Xna.Framework.Vector2(892, 60);
|
||||
Add(Icon);
|
||||
temp.Delete(VM.Context);
|
||||
}
|
||||
}
|
||||
|
||||
private void FamilyList_OnSelectionChange(int obj)
|
||||
{
|
||||
var nb = Content.Get().Neighborhood;
|
||||
//populate the rightmost list with the selected family
|
||||
NeighbourList.BackingList.Clear();
|
||||
if (obj != -1)
|
||||
{
|
||||
var people = NeighborsByFamilyID.ElementAt(obj).Value;
|
||||
NeighbourList.BackingList =
|
||||
people.Select(x => {
|
||||
var guid = nb.GetNeighborByID(x).GUID;
|
||||
var gobj = Content.Get().WorldObjects.Get(guid);
|
||||
if (gobj == null) return "Unknown";
|
||||
return gobj.Resource.Get<FSO.Files.Formats.IFF.Chunks.CTSS>(gobj.OBJ.CatalogStringsID)?.GetString(0) ?? "Unknown";
|
||||
}
|
||||
).ToList();
|
||||
}
|
||||
NeighbourList.Refresh();
|
||||
NeighbourList_OnSelectionChange(-1);
|
||||
SelectedFamily = obj;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
using FSO.Client;
|
||||
using FSO.Common.Rendering.Framework;
|
||||
using FSO.Common.Rendering.Framework.Camera;
|
||||
using FSO.Content;
|
||||
using FSO.LotView.Components;
|
||||
using FSO.LotView.Debug;
|
||||
using FSO.SimAntics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
public class UI3DThumb
|
||||
{
|
||||
public _3DTargetScene Scene;
|
||||
public BasicCamera Camera;
|
||||
public Texture2D Tex
|
||||
{
|
||||
get { return Scene.Target; }
|
||||
}
|
||||
|
||||
public float RotationSpeed = 0.20f;
|
||||
public float RotationX = -(float)Math.PI;
|
||||
public Vector3 Ctr;
|
||||
public float Size;
|
||||
|
||||
public List<Debug3DDGRPComponent> Comp3D;
|
||||
public UI3DThumb(VMEntity ent)
|
||||
{
|
||||
Camera = new BasicCamera(GameFacade.GraphicsDevice, new Vector3(3, 1, 0), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
|
||||
Camera.NearPlane = 0.001f;
|
||||
Scene = new _3DTargetScene(GameFacade.GraphicsDevice, Camera, new Point(150, 150), 0);
|
||||
Scene.Initialize(GameFacade.Scenes);
|
||||
|
||||
if (Comp3D != null)
|
||||
{
|
||||
foreach (var e in Comp3D)
|
||||
{
|
||||
e.Dispose();
|
||||
Scene.Remove(e);
|
||||
}
|
||||
}
|
||||
Comp3D = new List<Debug3DDGRPComponent>();
|
||||
|
||||
BoundingBox? total = null;
|
||||
var pos = ent.MultitileGroup.GetBasePositions();
|
||||
var i = 0;
|
||||
foreach (var obj in ent.MultitileGroup.Objects)
|
||||
{
|
||||
var c = new Debug3DDGRPComponent();
|
||||
var dgrp = ((ObjectComponent)obj.WorldUI).DGRP;
|
||||
c.Mesh = (dgrp == null) ? null : Content.Get().RCMeshes.Get(dgrp, obj.Object.OBJ); //new DGRP3DMesh(((ObjectComponent)obj.WorldUI).DGRP, obj.Object.OBJ, GameFacade.GraphicsDevice, null);
|
||||
Scene.Add(c);
|
||||
if (c.Mesh == null) continue;
|
||||
|
||||
var vp = pos[i++];
|
||||
c.Position = new Vector3((vp.X - 0.5f), vp.Z, (vp.Y - 0.5f));
|
||||
if (total == null) total = OffsetBox(c.Mesh.Bounds ?? new BoundingBox(), c.Position);
|
||||
else total = BoundingBox.CreateMerged(total.Value, OffsetBox(c.Mesh.Bounds ?? new BoundingBox(), c.Position));
|
||||
c.Initialize();
|
||||
Comp3D.Add(c);
|
||||
}
|
||||
|
||||
if (total != null)
|
||||
{
|
||||
Ctr = new Vector3((total.Value.Max.X + total.Value.Min.X) / 2, (total.Value.Max.Y + total.Value.Min.Y) / 2, (total.Value.Max.Z + total.Value.Min.Z) / 2);
|
||||
var diag = total.Value.Max - total.Value.Min;
|
||||
Size = diag.Length();
|
||||
}
|
||||
}
|
||||
|
||||
public BoundingBox OffsetBox(BoundingBox box, Vector3 off)
|
||||
{
|
||||
return new BoundingBox(box.Min + off, box.Max + off);
|
||||
}
|
||||
|
||||
public void RecalcBounds()
|
||||
{
|
||||
BoundingBox? total = null;
|
||||
foreach (var c in Comp3D)
|
||||
{
|
||||
if (total == null) total = OffsetBox(c.Mesh.Bounds ?? new BoundingBox(), c.Position);
|
||||
else total = BoundingBox.CreateMerged(total.Value, OffsetBox(c.Mesh.Bounds ?? new BoundingBox(), c.Position));
|
||||
}
|
||||
|
||||
if (total != null)
|
||||
{
|
||||
Ctr = new Vector3((total.Value.Max.X + total.Value.Min.X) / 2, (total.Value.Max.Y + total.Value.Min.Y) / 2, (total.Value.Max.Z + total.Value.Min.Z) / 2);
|
||||
var diag = total.Value.Max - total.Value.Min;
|
||||
Size = diag.Length();
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
RecalcBounds();
|
||||
RotationX += RotationSpeed;
|
||||
RotationSpeed += (0.01f - RotationSpeed) / 20;
|
||||
|
||||
var mat = Microsoft.Xna.Framework.Matrix.CreateRotationY(RotationX);
|
||||
Camera.Position = Ctr + Vector3.Transform(new Vector3(4, 3, 0)*(0.1f + Size*0.2f), mat);
|
||||
Camera.Target = Ctr + new Vector3(0, 0, 0);
|
||||
var old = GameFacade.GraphicsDevice.BlendState;
|
||||
GameFacade.GraphicsDevice.BlendState = BlendState.NonPremultiplied;
|
||||
Scene.Draw(GameFacade.GraphicsDevice);
|
||||
GameFacade.GraphicsDevice.BlendState = old;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Scene.Dispose();
|
||||
if (Comp3D != null)
|
||||
{
|
||||
foreach (var e in Comp3D) e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,9 +4,15 @@ using FSO.Client.UI.Framework;
|
|||
using FSO.Common.Utils;
|
||||
using FSO.Content;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using FSO.LotView.Model;
|
||||
using FSO.SimAntics;
|
||||
using FSO.SimAntics.Engine.TSOTransaction;
|
||||
using FSO.SimAntics.Model;
|
||||
using FSO.SimAntics.NetPlay.Drivers;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Model;
|
||||
using Simitone.Client.UI.Screens;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -23,6 +29,8 @@ namespace Simitone.Client.UI.Panels
|
|||
public UILabel StreetTitle;
|
||||
public UILabel LotTitle;
|
||||
public UILabel LotDescription;
|
||||
public UILabel SecondaryText;
|
||||
public UIHouseFamilyList FamilyDisplay;
|
||||
|
||||
public UIBigButton EnterLot;
|
||||
public UIBigButton More;
|
||||
|
@ -30,10 +38,54 @@ namespace Simitone.Client.UI.Panels
|
|||
public event Action<int> OnSelected;
|
||||
public int HouseID;
|
||||
|
||||
public List<UIBigButton> OptionButtons = new List<UIBigButton>();
|
||||
|
||||
private float _MoreTween;
|
||||
public float MoreTween
|
||||
{
|
||||
get
|
||||
{
|
||||
return _MoreTween;
|
||||
}
|
||||
set
|
||||
{
|
||||
var nonOptionButtons = new UIElement[]
|
||||
{
|
||||
LotDescription,
|
||||
SecondaryText,
|
||||
EnterLot,
|
||||
More,
|
||||
};
|
||||
|
||||
foreach (var btn in nonOptionButtons)
|
||||
{
|
||||
btn.Opacity = 1 - value;
|
||||
btn.Visible = btn.Opacity > 0;
|
||||
}
|
||||
|
||||
foreach (var btn in OptionButtons)
|
||||
{
|
||||
btn.Opacity = value;
|
||||
btn.Visible = btn.Opacity > 0;
|
||||
}
|
||||
var screen = UIScreen.Current;
|
||||
|
||||
var scale = Math.Max(2 / 3f, Math.Min(1, screen.ScreenWidth / 1704f));
|
||||
var space = (96 * scale) - 56;
|
||||
|
||||
if (FamilyDisplay != null)
|
||||
FamilyDisplay.X = (48 + space / 2) - value * screen.ScreenWidth / 2;
|
||||
|
||||
_MoreTween = value;
|
||||
}
|
||||
}
|
||||
|
||||
public UIHouseSelectPanel(int houseID)
|
||||
{
|
||||
HouseID = houseID;
|
||||
var screen = GameFacade.Screens.CurrentUIScreen;
|
||||
var extra = Math.Max(0, (screen.ScreenHeight - 640) / 128) * 64;
|
||||
HouseID = houseID;
|
||||
|
||||
Diag = new UIDiagonalStripe(new Point(screen.ScreenWidth / 2, screen.ScreenHeight + 16), UIDiagonalStripeSide.RIGHT, UIStyle.Current.Bg);
|
||||
Diag.Y = -16;
|
||||
Diag.ListenForMouse(Diag.GetBounds(), (e, s) => { });
|
||||
|
@ -41,58 +93,304 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
TitleStripe = new UIDiagonalStripe(new Point(screen.ScreenWidth / 2, 92 + 8 + 32), UIDiagonalStripeSide.RIGHT, UIStyle.Current.Bg);
|
||||
TitleStripe.StartOff = 8 + 32;
|
||||
TitleStripe.Y = 82 - 34;
|
||||
TitleStripe.Y = -16 + extra;
|
||||
Add(TitleStripe);
|
||||
|
||||
var house = Content.Get().Neighborhood.GetHouse(houseID);
|
||||
var neigh = Content.Get().Neighborhood;
|
||||
|
||||
var street = Content.Get().Neighborhood.StreetNames;
|
||||
var assignment = street.Get<STR>(2001).GetString(houseID-1);
|
||||
var house = neigh.GetHouse(houseID);
|
||||
|
||||
var street = neigh.StreetNames;
|
||||
var assignment = street.Get<STR>(2001).GetString(houseID - 1);
|
||||
|
||||
int streetName;
|
||||
if (int.TryParse(assignment, out streetName))
|
||||
{
|
||||
StreetTitle = new UILabel();
|
||||
StreetTitle.Position = new Vector2(30, 94);
|
||||
StreetTitle.Position = new Vector2(30, 94 + extra - 64);
|
||||
InitLabel(StreetTitle);
|
||||
StreetTitle.CaptionStyle.Color = UIStyle.Current.BtnActive;
|
||||
StreetTitle.Caption = street.Get<STR>(2000).GetString(streetName-1).Replace("%s", houseID.ToString());
|
||||
StreetTitle.Caption = street.Get<STR>(2000).GetString(streetName - 1).Replace("%s", houseID.ToString());
|
||||
}
|
||||
|
||||
var nameDesc = Content.Get().Neighborhood.GetHouseNameDesc(houseID);
|
||||
var nameDesc = neigh.GetHouseNameDesc(houseID);
|
||||
var name = nameDesc.Item1;
|
||||
if (name == "") name = "Unnamed House";
|
||||
if (name == "") name = StreetTitle.Caption;
|
||||
|
||||
LotTitle = new UILabel();
|
||||
LotTitle.Position = new Vector2(30, 122);
|
||||
LotTitle.Position = new Vector2(30, 122 + extra - 64);
|
||||
InitLabel(LotTitle);
|
||||
LotTitle.CaptionStyle.Size = 37;
|
||||
LotTitle.Caption = name;
|
||||
|
||||
var family = neigh.GetFamilyForHouse((short)houseID);
|
||||
|
||||
LotDescription = new UILabel();
|
||||
LotDescription.Position = new Vector2(30, 206);
|
||||
LotDescription.Position = new Vector2(30, 206 + extra);
|
||||
InitLabel(LotDescription);
|
||||
//LotDescription.CaptionStyle.Size = 15;
|
||||
LotDescription.Size = new Vector2(502, screen.ScreenHeight-415);
|
||||
LotDescription.Size = new Vector2(screen.ScreenWidth/2 - 60, screen.ScreenHeight - 415);
|
||||
LotDescription.Wrapped = true;
|
||||
LotDescription.Alignment = TextAlignment.Top | TextAlignment.Left;
|
||||
LotDescription.Caption = nameDesc.Item2;
|
||||
|
||||
SecondaryText = new UILabel();
|
||||
SecondaryText.Position = new Vector2(30, screen.ScreenHeight - (165 + extra));
|
||||
InitLabel(SecondaryText);
|
||||
SecondaryText.Size = new Vector2(screen.ScreenWidth / 2 - 60, 29);
|
||||
SecondaryText.Wrapped = true;
|
||||
SecondaryText.Alignment = TextAlignment.Bottom | TextAlignment.Right;
|
||||
SecondaryText.CaptionStyle.Color = UIStyle.Current.SecondaryText;
|
||||
|
||||
var moveInID = (UIScreen.Current as Screens.TS1GameScreen).MoveInFamily;
|
||||
var moveIn = (moveInID == null) ? null : Content.Get().Neighborhood.GetFamily((ushort)moveInID.Value);
|
||||
var buttonValid = true;
|
||||
|
||||
if (family != null)
|
||||
{
|
||||
var famUI = new UIHouseFamilyList(family);
|
||||
|
||||
var scale = Math.Max(2 / 3f, Math.Min(1, screen.ScreenWidth / 1704f));
|
||||
famUI.ScaleX = famUI.ScaleY = scale;
|
||||
var space = (96 * scale) - 56;
|
||||
LotDescription.Y += space;
|
||||
famUI.Position = new Vector2(48 + space / 2, 152 + extra + space / 2);
|
||||
Add(famUI);
|
||||
FamilyDisplay = famUI;
|
||||
|
||||
LotDescription.Caption = GameFacade.Strings.GetString("134", "0", new string[] {
|
||||
Content.Get().Neighborhood.MainResource.Get<FAMs>(family.ChunkID)?.GetString(0) ?? "?",
|
||||
"§" + (family.ValueInArch + family.Budget).ToString("##,#0"), //should include lot value eventually
|
||||
family.FamilyFriends.ToString()
|
||||
});
|
||||
|
||||
LotDescription.CaptionStyle.Color = UIStyle.Current.SecondaryText;
|
||||
|
||||
if (moveIn != null)
|
||||
{
|
||||
SecondaryText.Caption = GameFacade.Strings.GetString("132", "15"); //house occupied
|
||||
buttonValid = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
LotDescription.Y -= 64;
|
||||
LotDescription.Size = new Vector2(LotDescription.Size.X, LotDescription.Size.Y + 65);
|
||||
//LotDescription.Caption = new string(Enumerable.Range(1, 255).Select(x => 'a').ToArray());
|
||||
LotDescription.Caption = nameDesc.Item2;
|
||||
|
||||
//set up the secondary text
|
||||
var zones = neigh.ZoningDictionary;
|
||||
short result = 1;
|
||||
if (!zones.TryGetValue((short)houseID, out result))
|
||||
result = (short)((houseID >= 81 && houseID <= 89) ? 2 : 1);
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
//zone
|
||||
string str;
|
||||
if (moveIn != null)
|
||||
{
|
||||
str = GameFacade.Strings.GetString("134", "18").Substring(8); //is community, can't move in
|
||||
buttonValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = GameFacade.Strings.GetString("134", "17").Substring(8); //is community
|
||||
}
|
||||
SecondaryText.Caption = str;
|
||||
} else
|
||||
{
|
||||
//show price
|
||||
var price = house.Get<SIMI>(1)?.PurchaseValue ?? 0;
|
||||
string str;
|
||||
if (houseID >= 90 && houseID <= 92)
|
||||
{
|
||||
//also requires magicoins
|
||||
var magicoins = neigh.GetMagicoinsForFamily(family);
|
||||
var requiredMC = int.Parse(GameFacade.Strings.GetString("134", (32 + Math.Abs(91 - houseID)).ToString()));
|
||||
|
||||
if (moveIn != null)
|
||||
{
|
||||
if (magicoins >= requiredMC)
|
||||
{
|
||||
if (moveIn.Budget >= price)
|
||||
{
|
||||
str = GameFacade.Strings.GetString("134", "31", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
requiredMC.ToString()
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//missing simoleons
|
||||
str = GameFacade.Strings.GetString("134", "38", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
requiredMC.ToString(),
|
||||
moveIn.ChunkParent.Get<FAMs>(moveIn.ChunkID)?.GetString(0) ?? "",
|
||||
"§" +moveIn.Budget.ToString("##,#0")
|
||||
}).Substring(4);
|
||||
buttonValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moveIn.Budget >= price)
|
||||
{
|
||||
//missing magicoins
|
||||
str = GameFacade.Strings.GetString("134", "36", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
requiredMC.ToString(),
|
||||
moveIn.ChunkParent.Get<FAMs>(moveIn.ChunkID)?.GetString(0) ?? "",
|
||||
magicoins.ToString()
|
||||
}).Substring(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
//missing both
|
||||
str = GameFacade.Strings.GetString("134", "37", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
requiredMC.ToString(),
|
||||
moveIn.ChunkParent.Get<FAMs>(moveIn.ChunkID)?.GetString(0) ?? "",
|
||||
magicoins.ToString()
|
||||
}).Substring(4);
|
||||
buttonValid = false;
|
||||
}
|
||||
buttonValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//suggest move in
|
||||
str = GameFacade.Strings.GetString("134", "29", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
requiredMC.ToString()
|
||||
}).Substring(4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moveIn != null)
|
||||
{
|
||||
if (moveIn.Budget >= price)
|
||||
{
|
||||
str = GameFacade.Strings.GetString("134", "5", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
"§" +(moveIn.Budget - price).ToString("##,#0")
|
||||
}).Substring(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = GameFacade.Strings.GetString("134", "4", new string[] { "", "",
|
||||
"§" + price.ToString("##,#0"),
|
||||
moveIn.ChunkParent.Get<FAMs>(moveIn.ChunkID)?.GetString(0) ?? "",
|
||||
"§" +moveIn.Budget.ToString("##,#0")
|
||||
}).Substring(4);
|
||||
buttonValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//suggest move in
|
||||
str = GameFacade.Strings.GetString("134", "1", new string[] { "", "", "§" + price.ToString("##,#0") }).Substring(4);
|
||||
}
|
||||
}
|
||||
|
||||
SecondaryText.Caption = str;
|
||||
SecondaryText.CaptionStyle.Size = 15;
|
||||
}
|
||||
}
|
||||
|
||||
EnterLot = new UIBigButton(false);
|
||||
EnterLot.Caption = "Enter Lot";
|
||||
EnterLot.Width = 275;
|
||||
EnterLot.Position = new Vector2(30, screen.ScreenHeight - 160);
|
||||
EnterLot.Caption = (moveIn == null)?"Enter Lot":"Move In";
|
||||
EnterLot.Width = (moveIn == null)? (screen.ScreenWidth / 2 - 293) : (screen.ScreenWidth/2-60);
|
||||
EnterLot.Disabled = !buttonValid;
|
||||
EnterLot.Position = new Vector2(30, screen.ScreenHeight - (extra + 125));
|
||||
EnterLot.OnButtonClick += (b) => { OnSelected?.Invoke(houseID); Kill(); };
|
||||
Add(EnterLot);
|
||||
|
||||
More = new UIBigButton(true);
|
||||
More.Caption = "More";
|
||||
More.Width = 192;
|
||||
More.Position = new Vector2(330, screen.ScreenHeight - 160);
|
||||
Add(More);
|
||||
More.Width = 208;
|
||||
More.Position = new Vector2(screen.ScreenWidth / 2 - 238, screen.ScreenHeight - (extra + 125));
|
||||
More.OnButtonClick += (btn) => { ShowMore(true); };
|
||||
if (moveIn == null) Add(More);
|
||||
|
||||
var optionFunctions = new ButtonClickDelegate[]
|
||||
{
|
||||
(family==null)?null:(ButtonClickDelegate)((btn) => Evict(family)),
|
||||
null,
|
||||
null,
|
||||
(btn) => ShowMore(false)
|
||||
};
|
||||
var optionNames = new string[]
|
||||
{
|
||||
(family==null)?"Bulldoze":"Evict",
|
||||
"Rezone",
|
||||
"Export",
|
||||
"Back"
|
||||
};
|
||||
|
||||
var bY = extra+140;
|
||||
|
||||
for (int i=0; i<optionFunctions.Length; i++)
|
||||
{
|
||||
var btn = new UIBigButton(i == optionFunctions.Length-1);
|
||||
btn.Caption = optionNames[i];
|
||||
btn.Position = new Vector2(screen.ScreenWidth / 4 - btn.Width / 2, bY);
|
||||
btn.Disabled = optionFunctions[i] == null;
|
||||
btn.OnButtonClick += optionFunctions[i];
|
||||
Add(btn);
|
||||
bY += 120;
|
||||
OptionButtons.Add(btn);
|
||||
}
|
||||
|
||||
X = screen.ScreenWidth / -2;
|
||||
GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary<string, float>() { { "X", 0f } }, TweenQuad.EaseOut);
|
||||
MoreTween = MoreTween;
|
||||
}
|
||||
|
||||
public void Evict(FAMI family)
|
||||
{
|
||||
if (family == null) return;
|
||||
var familyName = family.ChunkParent.Get<FAMs>(family.ChunkID)?.GetString(0) ?? "selected";
|
||||
UIMobileAlert evictDialog = null;
|
||||
evictDialog = new UIMobileAlert(new UIAlertOptions()
|
||||
{
|
||||
Title = GameFacade.Strings.GetString("131", "2"),
|
||||
Message = GameFacade.Strings.GetString("131", "3", new string[] {
|
||||
familyName.ToString(),
|
||||
"§" + (family.ValueInArch + family.Budget).ToString("##,#0") }
|
||||
),
|
||||
Buttons = UIAlertButton.YesNo(
|
||||
(b) => { evictDialog.Close(); ((TS1GameScreen)UIScreen.Current).EvictLot(family, (short)HouseID); },
|
||||
(b) => { evictDialog.Close(); }
|
||||
)
|
||||
});
|
||||
UIScreen.GlobalShowDialog(evictDialog, true);
|
||||
}
|
||||
|
||||
public void ShowMore(bool more)
|
||||
{
|
||||
GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary<string, float>() { { "MoreTween", (more)?1f:0f } }, TweenQuad.EaseOut);
|
||||
/*
|
||||
var nonOptionButtons = new UIElement[]
|
||||
{
|
||||
LotDescription,
|
||||
SecondaryText,
|
||||
EnterLot,
|
||||
More
|
||||
};
|
||||
|
||||
foreach (var btn in nonOptionButtons)
|
||||
{
|
||||
var b = btn as UIButton;
|
||||
if (b != null) b.Disabled = more;
|
||||
}
|
||||
|
||||
foreach (var btn in OptionButtons)
|
||||
{
|
||||
btn.Disabled = !more;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void Kill()
|
||||
|
@ -112,4 +410,46 @@ namespace Simitone.Client.UI.Panels
|
|||
Add(label);
|
||||
}
|
||||
}
|
||||
|
||||
public class UIHouseFamilyList : UIContainer
|
||||
{
|
||||
public List<UIAvatarSelectButton> Btns = new List<UIAvatarSelectButton>();
|
||||
|
||||
public UIHouseFamilyList(FAMI family)
|
||||
{
|
||||
PopulateList(family);
|
||||
}
|
||||
|
||||
public void PopulateList(FAMI family)
|
||||
{
|
||||
var world = new FSO.LotView.World(GameFacade.GraphicsDevice);
|
||||
world.Initialize(GameFacade.Scenes);
|
||||
var context = new VMContext(world);
|
||||
var vm = new VM(context, new VMServerDriver(new VMTS1GlobalLinkStub()), new VMNullHeadlineProvider());
|
||||
vm.Init();
|
||||
var blueprint = new Blueprint(1, 1);
|
||||
|
||||
//world.InitBlueprint(blueprint);
|
||||
context.Blueprint = blueprint;
|
||||
context.Architecture = new VMArchitecture(1, 1, blueprint, vm.Context);
|
||||
|
||||
int i = 0;
|
||||
var baseX = 0;
|
||||
foreach (var sim in family.FamilyGUIDs)
|
||||
{
|
||||
var fam = vm.Context.CreateObjectInstance(sim, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).BaseObject;
|
||||
var btn = new UIAvatarSelectButton(UIIconCache.GetObject(fam));
|
||||
btn.Opacity = 1f;
|
||||
var id = i;
|
||||
btn.Name = fam.Name;
|
||||
btn.X = baseX + (i++) * 100;
|
||||
btn.Y = 0;
|
||||
btn.DeregisterHandler();
|
||||
Btns.Add(btn);
|
||||
Add(btn);
|
||||
fam.Delete(true, vm.Context);
|
||||
}
|
||||
world.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ using FSO.LotView.RC;
|
|||
using Simitone.Client.UI.Panels.LotControls;
|
||||
using FSO.Client.UI.Panels.LotControls;
|
||||
using FSO.UI.Panels.LotControls;
|
||||
using Simitone.Client.UI.Controls;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
|
@ -55,6 +56,11 @@ namespace Simitone.Client.UI.Panels
|
|||
public FSO.SimAntics.VM vm;
|
||||
public FSO.LotView.World World { get; set; }
|
||||
public VMEntity ActiveEntity { get; set; }
|
||||
public int Budget { get
|
||||
{
|
||||
return vm.TS1State.CurrentFamily?.Budget ?? int.MaxValue;
|
||||
}
|
||||
}
|
||||
public uint SelectedSimID
|
||||
{
|
||||
get
|
||||
|
@ -88,7 +94,7 @@ namespace Simitone.Client.UI.Panels
|
|||
// NOTE: Blocking dialog system assumes that nothing goes wrong with data transmission (which it shouldn't, because we're using TCP)
|
||||
// and that the code actually blocks further dialogs from appearing while waiting for a response.
|
||||
// If we are to implement controlling multiple sims, this must be changed.
|
||||
private UIMobileAlert BlockingDialog;
|
||||
private UIMobileDialog BlockingDialog;
|
||||
private UINeighborhoodSelectionPanel TS1NeighSelector;
|
||||
private ulong LastDialogID;
|
||||
|
||||
|
@ -174,11 +180,6 @@ namespace Simitone.Client.UI.Panels
|
|||
if (IDEHook.IDE != null) IDEHook.IDE.IDEBreakpointHit(vm, entity);
|
||||
}
|
||||
|
||||
public string GetLotTitle()
|
||||
{
|
||||
return vm.LotName + " - " + vm.Entities.Count(x => x is VMAvatar && x.PersistID != 0);
|
||||
}
|
||||
|
||||
void vm_OnDialog(FSO.SimAntics.Model.VMDialogInfo info)
|
||||
{
|
||||
if (info != null && ((info.DialogID == LastDialogID && info.DialogID != 0 && info.Block))) return;
|
||||
|
@ -245,7 +246,21 @@ namespace Simitone.Client.UI.Panels
|
|||
((TS1GameScreen)Parent).LotControl.Visible = false;
|
||||
TS1NeighSelector.OnHouseSelect += HouseSelected;
|
||||
return;
|
||||
|
||||
case VMDialogType.TS1PhoneBook:
|
||||
var phone = new UICallNeighborAlert(((VMAvatar)info.Caller).GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.NeighborId), vm);
|
||||
BlockingDialog = phone;
|
||||
UIScreen.GlobalShowDialog(phone, true);
|
||||
phone.OnResult += (result) =>
|
||||
{
|
||||
vm.SendCommand(new VMNetDialogResponseCmd
|
||||
{
|
||||
ActorUID = info.Caller.PersistID,
|
||||
ResponseCode = (byte)((result > 0) ? 1 : 0),
|
||||
ResponseText = result.ToString()
|
||||
});
|
||||
BlockingDialog = null;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
var alert = new UIMobileAlert(options);
|
||||
|
@ -291,14 +306,15 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
private void DialogResponse(byte code)
|
||||
{
|
||||
if (BlockingDialog == null || ActiveEntity == null) return;
|
||||
if (BlockingDialog == null || !(BlockingDialog is UIMobileAlert) || ActiveEntity == null) return;
|
||||
BlockingDialog.Close();
|
||||
var ma = (UIMobileAlert)BlockingDialog;
|
||||
LastDialogID = 0;
|
||||
vm.SendCommand(new VMNetDialogResponseCmd
|
||||
{
|
||||
ActorUID = ActiveEntity.PersistID,
|
||||
ResponseCode = code,
|
||||
ResponseText = (BlockingDialog.ResponseText == null) ? "" : BlockingDialog.ResponseText
|
||||
ResponseText = (ma.ResponseText == null) ? "" : ma.ResponseText
|
||||
});
|
||||
BlockingDialog = null;
|
||||
}
|
||||
|
@ -507,8 +523,8 @@ namespace Simitone.Client.UI.Panels
|
|||
{
|
||||
OldMX = state.MouseState.X;
|
||||
OldMY = state.MouseState.Y;
|
||||
var newHover = World.GetObjectIDAtScreenPos(state.MouseState.X / FSOEnvironment.DPIScaleFactor,
|
||||
state.MouseState.Y / FSOEnvironment.DPIScaleFactor,
|
||||
var newHover = World.GetObjectIDAtScreenPos(state.MouseState.X,
|
||||
state.MouseState.Y,
|
||||
GameFacade.GraphicsDevice);
|
||||
|
||||
if (ObjectHover != newHover)
|
||||
|
@ -672,8 +688,6 @@ namespace Simitone.Client.UI.Panels
|
|||
WorldConfig.Current.SmoothZoom = false;
|
||||
}
|
||||
|
||||
//Cheats.Update(state);
|
||||
//AvatarDS.Update();
|
||||
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.
|
||||
|
@ -690,6 +704,28 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
if (GotoObject == null) GotoObject = vm.Context.CreateObjectInstance(GOTO_GUID, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).Objects[0];
|
||||
|
||||
|
||||
//update plumbbob
|
||||
var plumb = Content.Get().RCMeshes.Get("arrow.fsom");
|
||||
foreach (VMAvatar avatar in vm.Context.ObjectQueries.Avatars)
|
||||
{
|
||||
if (avatar.Avatar == null) continue;
|
||||
var isActive = (avatar == ActiveEntity);
|
||||
if ((avatar.Avatar.HeadObject == plumb) != isActive)
|
||||
{
|
||||
avatar.Avatar.HeadObject = (avatar == ActiveEntity) ? plumb : null;
|
||||
avatar.Avatar.HeadObjectSpeedyVel = 0.2f;
|
||||
}
|
||||
avatar.Avatar.HeadObjectRotation += 3f / FSOEnvironment.RefreshRate;
|
||||
if (isActive)
|
||||
{
|
||||
avatar.Avatar.HeadObjectRotation += avatar.Avatar.HeadObjectSpeedyVel;
|
||||
avatar.Avatar.HeadObjectSpeedyVel *= 0.98f;
|
||||
} else if (avatar.GetValue(FSO.SimAntics.Model.VMStackObjectVariable.Category) == 87)
|
||||
{
|
||||
avatar.Avatar.HeadObject = Content.Get().RCMeshes.Get("star.fsom");
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (ActiveEntity != null && BlockingDialog != null)
|
||||
{
|
||||
|
@ -775,6 +811,21 @@ namespace Simitone.Client.UI.Panels
|
|||
PieMenu = null;
|
||||
}
|
||||
|
||||
if (state.NewKeys.Contains(Keys.F8))
|
||||
{
|
||||
UIMobileAlert alert = null;
|
||||
alert = new UIMobileAlert(new UIAlertOptions()
|
||||
{
|
||||
Title = "Debug Lot Thumbnail",
|
||||
Message = "Arch Value: "+VMArchitectureStats.GetArchValue(vm.Context.Architecture),
|
||||
Buttons = UIAlertButton.Ok((btn) => UIScreen.RemoveDialog(alert))
|
||||
});
|
||||
Texture2D roofless = null;
|
||||
var thumb = World.GetLotThumb(GameFacade.GraphicsDevice, (tex) => roofless = FSO.Common.Utils.TextureUtils.Decimate(tex, GameFacade.GraphicsDevice, 2, false));
|
||||
thumb = FSO.Common.Utils.TextureUtils.Decimate(thumb, GameFacade.GraphicsDevice, 2, false);
|
||||
alert.SetIcon(thumb, thumb.Width, thumb.Height);
|
||||
UIScreen.GlobalShowDialog(alert, true);
|
||||
}
|
||||
if (LiveMode) LiveModeUpdate(state, scrolled);
|
||||
else if (CustomControl != null)
|
||||
{
|
||||
|
|
|
@ -99,6 +99,12 @@ namespace Simitone.Client.UI.Panels
|
|||
RefreshSize();
|
||||
}
|
||||
|
||||
public override void GameResized()
|
||||
{
|
||||
base.GameResized();
|
||||
RefreshSize();
|
||||
}
|
||||
|
||||
public void RefreshSize()
|
||||
{
|
||||
var w = Width;
|
||||
|
@ -123,14 +129,7 @@ namespace Simitone.Client.UI.Panels
|
|||
h += 45;
|
||||
}
|
||||
|
||||
var btnX = (w - ((Buttons.Count-1) * 350)) / 2;
|
||||
var btnY = h - 125;
|
||||
foreach (UIButton button in Buttons)
|
||||
{
|
||||
button.Y = btnY;
|
||||
button.X = btnX - button.Width/2;
|
||||
btnX += 350;
|
||||
}
|
||||
h = ResetButtons(h, true);
|
||||
|
||||
if (Height != h)
|
||||
{
|
||||
|
@ -139,6 +138,47 @@ namespace Simitone.Client.UI.Panels
|
|||
//update bg with height
|
||||
}
|
||||
|
||||
private int ResetButtons(int h, bool setY)
|
||||
{
|
||||
var btnX = Width/2;
|
||||
var btnY = h - 125;
|
||||
var totalBtnWidth = Buttons.Sum(x => x.Width);
|
||||
int runningWidth = 0;
|
||||
int start = 0;
|
||||
int i = 0;
|
||||
for (i=0; i<Buttons.Count; i++)
|
||||
{
|
||||
var btn = Buttons[i];
|
||||
|
||||
if (runningWidth == 0 || (Width-50) - runningWidth > btn.Width)
|
||||
{
|
||||
btn.X = btnX + runningWidth;
|
||||
} else
|
||||
{
|
||||
btnY += 120;
|
||||
h += 120;
|
||||
//center buttons
|
||||
runningWidth -= 25;
|
||||
for (int j=start; j<i; j++)
|
||||
{
|
||||
Buttons[j].X -= runningWidth / 2;
|
||||
}
|
||||
|
||||
runningWidth = 0;
|
||||
start = i;
|
||||
btn.X = btnX + runningWidth;
|
||||
}
|
||||
runningWidth += (int)btn.Width + 25;
|
||||
if (setY) btn.Y = btnY;
|
||||
}
|
||||
runningWidth -= 25;
|
||||
for (int j = start; j < i; j++)
|
||||
{
|
||||
Buttons[j].X -= runningWidth / 2;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
private float TargetIX;
|
||||
|
||||
public void SetIcon(Texture2D img, int width, int height)
|
||||
|
@ -226,12 +266,11 @@ namespace Simitone.Client.UI.Panels
|
|||
{
|
||||
Icon.Visible = true;
|
||||
Icon.X = newIX;
|
||||
var btnX = (Width - ((Buttons.Count - 1) * 350)) / 2;
|
||||
foreach (UIButton button in Buttons)
|
||||
ResetButtons(Height, false);
|
||||
foreach (var btn in Buttons)
|
||||
{
|
||||
button.X = off + btnX - button.Width / 2;
|
||||
button.Visible = true;
|
||||
btnX += 350;
|
||||
btn.X += off;
|
||||
btn.Visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace Simitone.Client.UI.Panels
|
|||
BuildButton,
|
||||
OptionButton
|
||||
};
|
||||
UpdateBuildBuy();
|
||||
}
|
||||
|
||||
public override void Update(UpdateState state)
|
||||
|
@ -73,6 +74,13 @@ namespace Simitone.Client.UI.Panels
|
|||
}
|
||||
}
|
||||
|
||||
public void UpdateBuildBuy()
|
||||
{
|
||||
var bbEnable = Game.vm.Context.Architecture.BuildBuyEnabled;
|
||||
BuyButton.Disabled = !bbEnable;
|
||||
BuildButton.Disabled = !bbEnable;
|
||||
}
|
||||
|
||||
public void EndSwitch(UIMainPanelMode mode)
|
||||
{
|
||||
UIButton frontButton;
|
||||
|
|
|
@ -17,6 +17,10 @@ using FSO.Client;
|
|||
using FSO.Content;
|
||||
using FSO.Common.Utils;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.Utils;
|
||||
using FSO.Common;
|
||||
using System.IO;
|
||||
using FSO.Files.RC;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
|
@ -127,7 +131,6 @@ namespace Simitone.Client.UI.Panels
|
|||
GameResized();
|
||||
}
|
||||
|
||||
|
||||
public void UpdatePosition()
|
||||
{
|
||||
base.GameResized();
|
||||
|
@ -203,6 +206,7 @@ namespace Simitone.Client.UI.Panels
|
|||
Zoom = Zoom;
|
||||
CenterPositionX = CenterPositionX;
|
||||
CenterPositionY = CenterPositionY;
|
||||
//SimitoneNeighOBJExporter.SaveOBJ(Path.Combine(FSOEnvironment.UserDir, "NeighModel" + mode + "/"), locations);
|
||||
}
|
||||
|
||||
public void ResetZoom()
|
||||
|
@ -337,17 +341,26 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
public UINeighborhoodHouseButton(int houseNumber, Action<int> selectionCallback, float scale)
|
||||
{
|
||||
if (houseNumber == 71) { }
|
||||
AlphaTime = 0;
|
||||
var house = Content.Get().Neighborhood.GetHouse(houseNumber);
|
||||
HouseTex = house.Get<BMP>(513).GetTexture(GameFacade.GraphicsDevice);
|
||||
HouseOpenTex = house.Get<BMP>(512).GetTexture(GameFacade.GraphicsDevice);
|
||||
HouseTex = house.Get<BMP>(513)?.GetTexture(GameFacade.GraphicsDevice);
|
||||
if (HouseTex != null) {
|
||||
HouseOpenTex = house.Get<BMP>(512).GetTexture(GameFacade.GraphicsDevice);
|
||||
Offsets = house.Get<THMB>(512); //get offsets before scaling
|
||||
} else
|
||||
{
|
||||
HouseTex = house.Get<PNG>(513).GetTexture(GameFacade.GraphicsDevice);
|
||||
HouseOpenTex = house.Get<PNG>(512).GetTexture(GameFacade.GraphicsDevice);
|
||||
Offsets = new THMB() { Width = HouseTex.Width / 2, Height = HouseTex.Height / 2 };
|
||||
}
|
||||
|
||||
HouseScale = scale;
|
||||
Offsets = house.Get<THMB>(512); //get offsets before scaling
|
||||
|
||||
var w = (int)(HouseTex.Width / HouseScale);
|
||||
var h = (int)(HouseTex.Height / HouseScale);
|
||||
var clickHandler =
|
||||
ListenForMouse(new Rectangle(w / -2, h / -2, w, h), (evt, state) =>
|
||||
ListenForMouse(new Rectangle(w / -2, w / -4, w, h/2), (evt, state) =>
|
||||
{
|
||||
switch (evt)
|
||||
{
|
||||
|
@ -367,13 +380,13 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
var yOff = new Vector2(Offsets.XOff, Offsets.BaseYOff) / (HouseScale * 2f);
|
||||
var yOff = new Vector2(Offsets.XOff, -Offsets.BaseYOff) / HouseScale;
|
||||
var yOff2 = yOff;
|
||||
yOff2.Y -= Offsets.AddYOff / (HouseScale);
|
||||
DrawLocalTexture(batch, HouseTex, null, new Vector2(-HouseTex.Width, -HouseTex.Height) / (HouseScale * 2) + yOff, new Vector2(1f / HouseScale, 1f / HouseScale));
|
||||
DrawLocalTexture(batch, HouseTex, null, new Vector2(-Offsets.Width, -Offsets.Height)/ HouseScale + yOff, new Vector2(1f / HouseScale, 1f / HouseScale));
|
||||
if (AlphaTime > 0)
|
||||
{
|
||||
DrawLocalTexture(batch, HouseOpenTex, null, new Vector2(-HouseTex.Width, -HouseTex.Height) / (HouseScale * 2) + yOff2, new Vector2(1f / HouseScale, 1f / HouseScale), Color.White * AlphaTime);
|
||||
DrawLocalTexture(batch, HouseOpenTex, null, new Vector2(-Offsets.Width, -Offsets.Height)/ HouseScale + yOff2, new Vector2(1f / HouseScale, 1f / HouseScale), Color.White * AlphaTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,25 +17,33 @@ namespace Simitone.Client.UI.Panels
|
|||
public List<UIElasticButton> RightBtns = new List<UIElasticButton>();
|
||||
private UINeighborhoodSelectionPanel Panel;
|
||||
private ushort Mode;
|
||||
public bool MoveInMode;
|
||||
|
||||
public UINeighbourhoodSwitcher(UINeighborhoodSelectionPanel panel, ushort mode)
|
||||
public UINeighbourhoodSwitcher(UINeighborhoodSelectionPanel panel, ushort mode, bool moveIn)
|
||||
{
|
||||
Panel = panel;
|
||||
SetMode(mode);
|
||||
SetMode(mode, moveIn);
|
||||
}
|
||||
|
||||
public void SetMode(ushort mode)
|
||||
public void SetMode(ushort mode, bool moveIn)
|
||||
{
|
||||
MoveInMode = moveIn;
|
||||
foreach (var btn in LeftBtns) Remove(btn);
|
||||
foreach (var btn in RightBtns) Remove(btn);
|
||||
LeftBtns.Clear(); RightBtns.Clear();
|
||||
|
||||
AddBtn(LeftBtns, "ngbh_cas.png", (btn) => GameController.EnterCAS());
|
||||
AddBtn(LeftBtns, "ngbh_cas.png", (btn) =>
|
||||
{
|
||||
var transition = new UITransDialog("cas", () =>
|
||||
{
|
||||
GameController.EnterCAS();
|
||||
});
|
||||
});
|
||||
if (mode != 4) AddBtn(LeftBtns, "ngbh_back.png", (btn) => PopMode(4));
|
||||
|
||||
if (mode != 2) AddBtn(RightBtns, "ngbh_downt.png", (btn) => PopMode(2));
|
||||
if (mode != 3) AddBtn(RightBtns, "ngbh_vacat.png", (btn) => PopMode(3));
|
||||
if (mode != 5) AddBtn(RightBtns, "ngbh_studio.png", (btn) => PopMode(5));
|
||||
if (mode != 2 && !moveIn) AddBtn(RightBtns, "ngbh_downt.png", (btn) => PopMode(2));
|
||||
if (mode != 3 && !moveIn) AddBtn(RightBtns, "ngbh_vacat.png", (btn) => PopMode(3));
|
||||
if (mode != 5 && !moveIn) AddBtn(RightBtns, "ngbh_studio.png", (btn) => PopMode(5));
|
||||
if (mode != 7) AddBtn(RightBtns, "ngbh_magic.png", (btn) => PopMode(7));
|
||||
Mode = mode;
|
||||
|
||||
|
@ -45,7 +53,7 @@ namespace Simitone.Client.UI.Panels
|
|||
public void PopMode(ushort mode)
|
||||
{
|
||||
Panel.PopulateScreen(mode);
|
||||
SetMode(mode);
|
||||
SetMode(mode, MoveInMode);
|
||||
}
|
||||
|
||||
private void LayBtns()
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace Simitone.Client.UI.Panels
|
|||
//rotate through to try all configurations
|
||||
var dir = Holding.Dir;
|
||||
VMPlacementError status = VMPlacementError.Success;
|
||||
if (!Holding.IsBought && !vm.TSOState.CanPlaceNewUserObject(vm)) status = VMPlacementError.TooManyObjectsOnTheLot;
|
||||
if (!Holding.IsBought && !vm.PlatformState.CanPlaceNewUserObject(vm)) status = VMPlacementError.TooManyObjectsOnTheLot;
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
@ -164,7 +164,7 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
if (UseNet || !Holding.IsBought)
|
||||
{
|
||||
Holding.Group.Delete(vm.Context);
|
||||
RecursiveDelete(vm.Context, Holding.Group.BaseObject);
|
||||
} else
|
||||
{
|
||||
if (Holding.RealEnt == null) Holding.RealEnt = Holding.Group.BaseObject;
|
||||
|
@ -182,6 +182,27 @@ namespace Simitone.Client.UI.Panels
|
|||
vm.Tick();
|
||||
}
|
||||
|
||||
private void RecursiveDelete(VMContext context, VMEntity real)
|
||||
{
|
||||
var rgrp = real.MultitileGroup;
|
||||
for (int i = 0; i < rgrp.Objects.Count; i++)
|
||||
{
|
||||
var slots = rgrp.Objects[i].TotalSlots();
|
||||
var objs = new List<VMEntity>();
|
||||
for (int j = 0; j < slots; j++)
|
||||
{
|
||||
var slot = rgrp.Objects[i].GetSlot(j);
|
||||
if (slot != null)
|
||||
{
|
||||
objs.Add(slot);
|
||||
}
|
||||
|
||||
}
|
||||
foreach (var obj in objs) RecursiveDelete(context, obj);
|
||||
}
|
||||
rgrp.Delete(context);
|
||||
}
|
||||
|
||||
public void MouseDown(UpdateState state)
|
||||
{
|
||||
MouseIsDown = true;
|
||||
|
@ -357,7 +378,7 @@ namespace Simitone.Client.UI.Panels
|
|||
{
|
||||
MoveSelected(Holding.TilePos, Holding.Level);
|
||||
if (!Holding.IsBought && Holding.CanPlace == VMPlacementError.Success &&
|
||||
ParentControl.ActiveEntity != null && ParentControl.ActiveEntity.TSOState.Budget.Value < Holding.Price)
|
||||
ParentControl.ActiveEntity != null && ParentControl.Budget < Holding.Price)
|
||||
Holding.CanPlace = VMPlacementError.InsufficientFunds;
|
||||
if (Holding.CanPlace != VMPlacementError.Success)
|
||||
{
|
||||
|
@ -390,7 +411,7 @@ namespace Simitone.Client.UI.Panels
|
|||
else if (MouseClicked)
|
||||
{
|
||||
//not holding an object, but one can be selected
|
||||
var newHover = World.GetObjectIDAtScreenPos(state.MouseState.X / FSOEnvironment.DPIScaleFactor, state.MouseState.Y / FSOEnvironment.DPIScaleFactor, GameFacade.GraphicsDevice);
|
||||
var newHover = World.GetObjectIDAtScreenPos(state.MouseState.X, state.MouseState.Y, GameFacade.GraphicsDevice);
|
||||
if (MouseClicked && (newHover != 0) && (vm.GetObjectById(newHover) is VMGameObject))
|
||||
{
|
||||
var objGroup = vm.GetObjectById(newHover).MultitileGroup;
|
||||
|
|
|
@ -17,6 +17,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using FSO.Common.Rendering.Framework.Model;
|
||||
using FSO.Common.Rendering.Framework.IO;
|
||||
using FSO.UI.Panels;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using FSO.Common.Rendering.Framework.Model;
|
||||
using FSO.Common;
|
||||
using FSO.UI.Panels;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
|
@ -130,6 +131,8 @@ namespace Simitone.Client.UI.Panels
|
|||
|
||||
Title.Alignment = TextAlignment.Left | TextAlignment.Top;
|
||||
Body.Alignment = TextAlignment.Left | TextAlignment.Top;
|
||||
|
||||
InternalBefore = true;
|
||||
}
|
||||
|
||||
public override void Update(UpdateState state)
|
||||
|
|
|
@ -12,6 +12,10 @@ using FSO.Client;
|
|||
using Microsoft.Xna.Framework;
|
||||
using Simitone.Client.UI.Panels.LiveSubpanels;
|
||||
using FSO.Client.UI.Model;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using FSO.SimAntics;
|
||||
using FSO.SimAntics.NetPlay.Model.Commands;
|
||||
using FSO.HIT;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
|
@ -198,6 +202,22 @@ namespace Simitone.Client.UI.Panels
|
|||
public float ClockTween;
|
||||
public override void Update(UpdateState state)
|
||||
{
|
||||
if (state.NewKeys.Contains(Keys.Space))
|
||||
{
|
||||
var selected = Game.LotControl.ActiveEntity;
|
||||
var familyMembers = Game.vm.Context.ObjectQueries.Avatars.Where(x =>
|
||||
((VMAvatar)x).GetPersonData(
|
||||
FSO.SimAntics.Model.VMPersonDataVariable.TS1FamilyNumber) == (Game.vm.TS1State.CurrentFamily?.ChunkID)
|
||||
).ToList();
|
||||
var index = familyMembers.IndexOf(selected);
|
||||
if (familyMembers.Count > 0)
|
||||
{
|
||||
index = (index + 1) % (familyMembers.Count);
|
||||
HITVM.Get().PlaySoundEvent(UISounds.QueueAdd);
|
||||
Game.vm.SendCommand(new VMNetChangeControlCmd() { TargetID = familyMembers[index].ObjectID });
|
||||
}
|
||||
}
|
||||
|
||||
base.Update(state);
|
||||
if (LastCut != Game.LotControl.WallsMode)
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ 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.TS1State.CurrentFamily?.ChunkID));
|
||||
int i = 0;
|
||||
foreach (var fam in familyMembers)
|
||||
{
|
||||
|
|
99
Client/Simitone/Simitone.Client/UI/Panels/UITransDialog.cs
Normal file
|
@ -0,0 +1,99 @@
|
|||
using FSO.Client;
|
||||
using FSO.Client.UI.Framework;
|
||||
using FSO.Common.Utils;
|
||||
using FSO.Content;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.UI.Panels
|
||||
{
|
||||
public class UITransDialog : UIContainer
|
||||
{
|
||||
private float _TransPct;
|
||||
public float TransPct {
|
||||
get
|
||||
{
|
||||
return _TransPct;
|
||||
}
|
||||
set
|
||||
{
|
||||
Diag.X = Math.Max(0, (value - 1) * UIScreen.Current.ScreenWidth);
|
||||
Diag.BodySize = new Vector2(Math.Min(1, value) * UIScreen.Current.ScreenWidth, UIScreen.Current.ScreenHeight).ToPoint();
|
||||
Diag.DiagSide = (value <= 1) ? UIDiagonalStripeSide.RIGHT : UIDiagonalStripeSide.LEFT;
|
||||
if (value == 1 && !FiredTransition)
|
||||
{
|
||||
FiredTransition = true;
|
||||
GameThread.NextUpdate((u) =>
|
||||
{
|
||||
UIScreen.RemoveDialog(this);
|
||||
TransAction();
|
||||
UIScreen.GlobalShowDialog(this, true);
|
||||
GameThread.NextUpdate((u2) =>
|
||||
{
|
||||
if (!UIScreen.Current.GetChildren().Contains(this))
|
||||
{
|
||||
DrawsSince = 0;
|
||||
Parent = null;
|
||||
UIScreen.GlobalShowDialog(this, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
if (value == 2 && FiredTransition)
|
||||
{
|
||||
UIScreen.RemoveDialog(this);
|
||||
}
|
||||
_TransPct = value;
|
||||
}
|
||||
}
|
||||
public bool FiredTransition = false;
|
||||
|
||||
private UIDiagonalStripe Diag;
|
||||
private Texture2D TransImage;
|
||||
private Action TransAction;
|
||||
|
||||
public UITransDialog(string transType, Action transAction)
|
||||
{
|
||||
var ui = Content.Get().CustomUI;
|
||||
TransImage = ui.Get($"trans_{transType}.png").Get(GameFacade.GraphicsDevice);
|
||||
TransAction = transAction;
|
||||
|
||||
Diag = new UIDiagonalStripe(new Point(0,0), UIDiagonalStripeSide.RIGHT, UIStyle.Current.TransColor);
|
||||
Add(Diag);
|
||||
UIScreen.GlobalShowDialog(this, true);
|
||||
GameFacade.Screens.Tween.To(this, 0.2f, new Dictionary<string, float>() { { "TransPct", 1f } });
|
||||
|
||||
TransPct = TransPct;
|
||||
}
|
||||
|
||||
public override void Removed()
|
||||
{
|
||||
base.Removed();
|
||||
}
|
||||
|
||||
public int DrawsSince = 0;
|
||||
public override void Draw(UISpriteBatch batch)
|
||||
{
|
||||
base.Draw(batch);
|
||||
DrawLocalTexture(batch, TransImage, null,
|
||||
new Vector2(UIScreen.Current.ScreenWidth - TransImage.Width, UIScreen.Current.ScreenHeight - TransImage.Height) / 2,
|
||||
Vector2.One, Color.White * (1-Math.Abs(1-TransPct)));
|
||||
|
||||
if (FiredTransition && TransPct == 1)
|
||||
{
|
||||
if (DrawsSince++ == 2)
|
||||
{
|
||||
GameFacade.Screens.Tween.To(this, 0.2f, new Dictionary<string, float>() { { "TransPct", 2f } });
|
||||
}
|
||||
}
|
||||
if (TransPct > 1) { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,10 +23,19 @@ namespace Simitone.Client.UI.Panels.WorldUI
|
|||
{
|
||||
Style = TextStyle.DefaultLabel.Clone();
|
||||
Style.Size = 12;
|
||||
var value = (int)(headline.Operand.Flags2 | (ushort)(headline.Operand.Duration << 16));
|
||||
Text = (value > 0)?("§" + value):("-§"+ value);
|
||||
var value = (int)(headline.Operand.Flags2 | (headline.Operand.Duration << 16));
|
||||
if (value < -10000)
|
||||
{
|
||||
Text = (-10000-value).ToString();
|
||||
Style.Color = Model.UIStyle.Current.SecondaryText;
|
||||
}
|
||||
else
|
||||
{
|
||||
Text = (value > 0) ? ("§" + value) : ("-§" + value);
|
||||
Style.Color = Model.UIStyle.Current.Text;
|
||||
}
|
||||
var measure = Style.MeasureString(Text);
|
||||
Style.Color = Model.UIStyle.Current.Text;
|
||||
|
||||
|
||||
var GD = GameFacade.GraphicsDevice;
|
||||
MoneyTarget = new RenderTarget2D(GD, (int)measure.X+10, (int)measure.Y+30);
|
||||
|
|
|
@ -14,6 +14,7 @@ using Simitone.Client.UI.Controls;
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using FSO.Common.Utils;
|
||||
using FSO.SimAntics;
|
||||
|
||||
namespace Simitone.Client.UI.Screens
|
||||
{
|
||||
|
@ -94,6 +95,7 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
(new Thread(() => {
|
||||
FSO.Content.Content.Init(GlobalSettings.Default.StartupPath, GameFacade.GraphicsDevice);
|
||||
VMContext.InitVMConfig();
|
||||
lock (this)
|
||||
{
|
||||
LoadingComplete = true;
|
||||
|
|
|
@ -26,6 +26,11 @@ using FSO.Content.TS1;
|
|||
using Simitone.Client.UI.Panels.CAS;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using FSO.SimAntics.Model;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using Simitone.Client.UI.Panels;
|
||||
using FSO.Client.UI.Controls;
|
||||
using Simitone.Client.Utils;
|
||||
using FSO.SimAntics.Utils;
|
||||
|
||||
namespace Simitone.Client.UI.Screens
|
||||
{
|
||||
|
@ -35,6 +40,7 @@ namespace Simitone.Client.UI.Screens
|
|||
public FSO.SimAntics.VM vm { get; set; }
|
||||
public VMNetDriver Driver;
|
||||
public BasicCamera Cam;
|
||||
public bool Initialized;
|
||||
public VMAvatar[] HeadAvatars;
|
||||
public VMAvatar[] BodyAvatars;
|
||||
public List<string> ActiveHeads;
|
||||
|
@ -42,16 +48,19 @@ namespace Simitone.Client.UI.Screens
|
|||
public List<string> ActiveHeadTex;
|
||||
public List<string> ActiveHandgroupTex;
|
||||
public List<string> ActiveBodyTex;
|
||||
|
||||
public static int NeighTypeFrom = 4;
|
||||
private bool Dead;
|
||||
|
||||
private float _FamilySimInterp;
|
||||
private float _FamilySimInterp = -2;
|
||||
public float FamilySimInterp
|
||||
{
|
||||
set
|
||||
{
|
||||
CameraInterp(value);
|
||||
CASPanel.Position = new Vector2((ScreenWidth - 500) / 2, 10 - (282 * (1-value)));
|
||||
CASPanel.Position = new Vector2((Cam == null)?10:((ScreenWidth - 500) / 2), 10 - (282 * (1-value)));
|
||||
FamilyPanel.ShowI = 1-Math.Abs(value);
|
||||
FamiliesPanel.TitleI = 1 - Math.Abs(value+1);
|
||||
|
||||
_FamilySimInterp = value;
|
||||
}
|
||||
|
@ -75,6 +84,8 @@ namespace Simitone.Client.UI.Screens
|
|||
public string CurrentSkin = "lgt";
|
||||
private bool CurrentChild;
|
||||
|
||||
private int? MoveInFamily;
|
||||
|
||||
private UICASMode Mode = UICASMode.FamilyEdit;
|
||||
|
||||
public List<CASFamilyMember> WIPFamily = new List<CASFamilyMember>();
|
||||
|
@ -82,11 +93,13 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
public UISimCASPanel CASPanel;
|
||||
public UIFamilyCASPanel FamilyPanel;
|
||||
public UIFamiliesCASPanel FamiliesPanel;
|
||||
public UITwoStateButton BackButton;
|
||||
public UITwoStateButton AcceptButton;
|
||||
|
||||
public Vector3[] ModePositions = new Vector3[]
|
||||
{
|
||||
new Vector3(177.3843f, 150.92333f, 3.25105f),
|
||||
new Vector3(157.3843f, 28.92333f, 23.25105f),
|
||||
new Vector3(119.5611f, 6.122346f, 104.0364f),
|
||||
new Vector3(114.0793f, 10f, 64.67827f)
|
||||
|
@ -94,13 +107,23 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
public Vector3[] ModeTargets = new Vector3[]
|
||||
{
|
||||
new Vector3(177.3843f-7f, 130.92333f, 3.25105f+5f),
|
||||
new Vector3(150.3057f, 26.01005f, 29.6858f),
|
||||
new Vector3(111.7678f, 3.936443f, 98.164f),
|
||||
new Vector3(104.5736f, 6.896059f, 64.59684f)
|
||||
};
|
||||
|
||||
public Vector3[] Mode2D = new Vector3[]
|
||||
{
|
||||
new Vector3(104, 0, 57),
|
||||
new Vector3(104, 0, 57),
|
||||
new Vector3(103.5611f, 0, 92.0364f),
|
||||
new Vector3(84.0793f+6, 0, 64f-6)
|
||||
};
|
||||
|
||||
public Vector3[] SinTransitions = new Vector3[]
|
||||
{
|
||||
new Vector3(0, 0, 0),
|
||||
new Vector3(12f, 0, 0),
|
||||
new Vector3(-6f, 0, 0),
|
||||
new Vector3()
|
||||
|
@ -108,24 +131,44 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
public void CameraInterp(float value)
|
||||
{
|
||||
if (value < -1) return;
|
||||
var prev = (int)(value + 1);
|
||||
var next = (int)(Math.Ceiling(value) + 1);
|
||||
if (next > 2) next = 2;
|
||||
if (value < -2) value = -2;
|
||||
var prev = (int)(value + 2);
|
||||
var next = (int)(Math.Ceiling(value) + 2);
|
||||
if (next > 3) next = 3;
|
||||
|
||||
var pos1 = ModePositions[prev];
|
||||
var pos2 = ModePositions[next];
|
||||
var targ1 = ModeTargets[prev] - pos1;
|
||||
var targ2 = ModeTargets[next] - pos2;
|
||||
if (Cam == null)
|
||||
{
|
||||
//2d
|
||||
var pos1 = Mode2D[prev];
|
||||
var pos2 = Mode2D[next];
|
||||
|
||||
value = (float)DirectionUtils.PosMod(value, 1.0);
|
||||
var camvec = Vector3.Lerp(targ1, targ2, value);
|
||||
var campos = Vector3.Lerp(pos1, pos2, value);
|
||||
if (World != null) World.State.PreciseZoom = 1 + Math.Min(0, value*0.5f);
|
||||
value = (float)DirectionUtils.PosMod(value, 1.0);
|
||||
var campos = Vector3.Lerp(pos1, pos2, value);
|
||||
campos += (float)Math.Sin(value * Math.PI) * SinTransitions[prev];
|
||||
|
||||
campos += (float)Math.Sin(value * Math.PI) * SinTransitions[prev];
|
||||
|
||||
Cam.Position = campos;
|
||||
Cam.Target = campos + camvec;
|
||||
|
||||
if (World != null)
|
||||
World.State.CenterTile = new Vector2(campos.X, campos.Z) / 3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var pos1 = ModePositions[prev];
|
||||
var pos2 = ModePositions[next];
|
||||
var targ1 = ModeTargets[prev] - pos1;
|
||||
var targ2 = ModeTargets[next] - pos2;
|
||||
|
||||
value = (float)DirectionUtils.PosMod(value, 1.0);
|
||||
var camvec = Vector3.Lerp(targ1, targ2, value);
|
||||
var campos = Vector3.Lerp(pos1, pos2, value);
|
||||
|
||||
campos += (float)Math.Sin(value * Math.PI) * SinTransitions[prev];
|
||||
|
||||
Cam.Position = campos;
|
||||
Cam.Target = campos + camvec;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateSimType(string simtype)
|
||||
|
@ -135,8 +178,6 @@ namespace Simitone.Client.UI.Screens
|
|||
if (simtype[1] == 'c') simtype += "chd";
|
||||
var bodies = Content.Get().BCFGlobal.CollectionsByName["b"].ClothesByAvatarType[simtype];
|
||||
|
||||
//todo: search for textures
|
||||
|
||||
var tex = (TS1AvatarTextureProvider)Content.Get().AvatarTextures;
|
||||
var texnames = tex.GetAllNames();
|
||||
ActiveHeads = heads;
|
||||
|
@ -207,7 +248,7 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
var moving = 0;
|
||||
|
||||
if (state.MouseState.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
|
||||
if (state.MouseStates.Count > 0)
|
||||
{
|
||||
if (XLast == -1)
|
||||
{
|
||||
|
@ -396,6 +437,10 @@ namespace Simitone.Client.UI.Screens
|
|||
FamilyPanel.ModifySim = ModifySim;
|
||||
Add(FamilyPanel);
|
||||
|
||||
FamiliesPanel = new UIFamiliesCASPanel();
|
||||
FamiliesPanel.OnNewFamily += () => { SetMode(UICASMode.FamilyEdit); };
|
||||
Add(FamiliesPanel);
|
||||
|
||||
BackButton = new UITwoStateButton(ui.Get("btn_back.png").Get(gd));
|
||||
BackButton.Position = new Vector2(25, ScreenHeight - 140);
|
||||
Add(BackButton);
|
||||
|
@ -462,7 +507,7 @@ namespace Simitone.Client.UI.Screens
|
|||
}
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
CASPanel.Personalities[j].Points = sim.Personality[j];
|
||||
CASPanel.Personalities[j].Points = sim.Personality[j] / 100;
|
||||
}
|
||||
CurrentSkin = sim.SkinColor;
|
||||
|
||||
|
@ -492,6 +537,8 @@ namespace Simitone.Client.UI.Screens
|
|||
CASPanel.UpdateType();
|
||||
}
|
||||
|
||||
public UIMobileAlert ConfirmDialog;
|
||||
|
||||
private void Accept(UIElement button)
|
||||
{
|
||||
switch (Mode)
|
||||
|
@ -503,9 +550,27 @@ namespace Simitone.Client.UI.Screens
|
|||
case UICASMode.FamilyEdit:
|
||||
//add or replace the family in the neighbourhood
|
||||
//need to generate an actual FAMI and save it for this
|
||||
if (ConfirmDialog == null)
|
||||
{
|
||||
ConfirmDialog = new UIMobileAlert(new UIAlertOptions()
|
||||
{
|
||||
Title = GameFacade.Strings.GetString("129", "13"),
|
||||
Message = GameFacade.Strings.GetString("129", "14"),
|
||||
Buttons = UIAlertButton.YesNo(
|
||||
(ybtn) => { ConfirmDialog.Close(); Accept(ybtn); ConfirmDialog = null; },
|
||||
(nbtn) => { ConfirmDialog.Close(); ConfirmDialog = null; }
|
||||
)
|
||||
});
|
||||
UIScreen.GlobalShowDialog(ConfirmDialog, true);
|
||||
return;
|
||||
} else
|
||||
{
|
||||
SaveFamily();
|
||||
}
|
||||
break;
|
||||
case UICASMode.FamilySelect:
|
||||
//accept button here is move in. notify the neighbourhood screen that we're moving in now.
|
||||
MoveInFamily = FamiliesPanel.Families[FamiliesPanel.Selection].ChunkID;
|
||||
break;
|
||||
}
|
||||
SetMode((UICASMode)(((int)Mode) - 1));
|
||||
|
@ -513,6 +578,27 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
private void GoBack(UIElement button)
|
||||
{
|
||||
if (Mode == UICASMode.FamilyEdit)
|
||||
{
|
||||
if (ConfirmDialog == null)
|
||||
{
|
||||
ConfirmDialog = new UIMobileAlert(new UIAlertOptions()
|
||||
{
|
||||
Title = GameFacade.Strings.GetString("129", "7"),
|
||||
Message = GameFacade.Strings.GetString("129", "8"),
|
||||
Buttons = UIAlertButton.YesNo(
|
||||
(ybtn) => { ConfirmDialog.Close(); GoBack(ybtn); ConfirmDialog = null; },
|
||||
(nbtn) => { ConfirmDialog.Close(); ConfirmDialog = null; }
|
||||
)
|
||||
});
|
||||
UIScreen.GlobalShowDialog(ConfirmDialog, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearFamily();
|
||||
}
|
||||
}
|
||||
SetMode((UICASMode)(((int)Mode) - 1));
|
||||
}
|
||||
|
||||
|
@ -521,13 +607,25 @@ namespace Simitone.Client.UI.Screens
|
|||
if (mode == UICASMode.ToNeighborhood)
|
||||
{
|
||||
//todo: animate into this
|
||||
CleanupLastWorld();
|
||||
|
||||
Dead = true;
|
||||
GameController.EnterGameMode("", false);
|
||||
var dialog = new UITransDialog("normal", () => {
|
||||
CleanupLastWorld();
|
||||
if (MoveInFamily == null)
|
||||
GameController.EnterGameMode("", false);
|
||||
else
|
||||
GameController.EnterGameMode("!"+((NeighTypeFrom == 7)?'m':'n')+MoveInFamily.Value.ToString(), false);
|
||||
});
|
||||
return;
|
||||
} else if (mode == UICASMode.FamilyEdit)
|
||||
{
|
||||
FamilyPanel.Reset();
|
||||
}
|
||||
|
||||
FamiliesPanel.SetSelection(-1);
|
||||
if (mode == UICASMode.FamilySelect) AcceptButton.Texture = Content.Get().CustomUI.Get("btn_movein.png").Get(GameFacade.GraphicsDevice);
|
||||
else AcceptButton.Texture = Content.Get().CustomUI.Get("btn_accept.png").Get(GameFacade.GraphicsDevice);
|
||||
|
||||
GameFacade.Screens.Tween.To(this, 1f, new Dictionary<string, float> { { "FamilySimInterp", (int)mode-1 } }, TweenQuad.EaseInOut);
|
||||
Mode = mode;
|
||||
}
|
||||
|
@ -553,25 +651,48 @@ namespace Simitone.Client.UI.Screens
|
|||
public override void Update(UpdateState state)
|
||||
{
|
||||
base.Update(state);
|
||||
ModePositions[2].Y = 11;
|
||||
ModeTargets[2].Y = 7.896059f;
|
||||
ModePositions[3].Y = 11;
|
||||
ModeTargets[3].Y = 7.896059f;
|
||||
if (Dead) return;
|
||||
if (vm == null) InitializeLot();
|
||||
vm.Update();
|
||||
if (World != null && Cam == null)
|
||||
if (World != null && !Initialized)
|
||||
{
|
||||
var rcs = (WorldStateRC)(World.State);
|
||||
Cam = (WorldCamera3D)rcs.Camera;
|
||||
rcs.FixedCam = true;
|
||||
rcs.CameraMode = true;
|
||||
SetMode(UICASMode.FamilyEdit);
|
||||
var rcs = (World.State as WorldStateRC);
|
||||
if (rcs != null)
|
||||
{
|
||||
Cam = (WorldCamera3D)rcs.Camera;
|
||||
rcs.FixedCam = true;
|
||||
rcs.CameraMode = true;
|
||||
}
|
||||
SetMode(UICASMode.FamilySelect);
|
||||
SetFamilies();
|
||||
Initialized = true;
|
||||
//FamilySimInterp = FamilySimInterp;
|
||||
}
|
||||
|
||||
if (World.State.Level != 2)
|
||||
if (World.State.PreciseZoom != 1) World.State.PreciseZoom = World.State.PreciseZoom;
|
||||
switch (Mode)
|
||||
{
|
||||
World.State.Level = 2;
|
||||
World.State.DrawRoofs = true;
|
||||
case UICASMode.FamilySelect:
|
||||
if (World.State.Level != 2)
|
||||
{
|
||||
World.State.Level = 2;
|
||||
World.State.DrawRoofs = true;
|
||||
vm.Context.Blueprint.Cutaway = new bool[vm.Context.Blueprint.Cutaway.Length];
|
||||
vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (World.State.Level != 1 && Cam == null)
|
||||
{
|
||||
World.State.Level = 1;
|
||||
World.State.DrawRoofs = false;
|
||||
vm.Context.Blueprint.Cutaway = VMArchitectureTools.GenerateRoomCut(vm.Context.Architecture, World.State.Level, World.State.CutRotation,
|
||||
new HashSet<uint>(vm.Context.RoomInfo.Where(x => x.Room.IsOutside == false).Select(x => (uint)x.Room.RoomID)));
|
||||
vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vm.Context.Clock.Minutes = 0;
|
||||
|
@ -588,11 +709,17 @@ namespace Simitone.Client.UI.Screens
|
|||
case UICASMode.SimEdit:
|
||||
if (CASPanel.FirstNameTextBox.CurrentText.Length == 0) disableAccept = true;
|
||||
break;
|
||||
case UICASMode.FamilySelect:
|
||||
if (FamiliesPanel.Selection == -1) disableAccept = true;
|
||||
break;
|
||||
case UICASMode.FamilyEdit:
|
||||
if (WIPFamily.Count == 0) disableAccept = true;
|
||||
break;
|
||||
}
|
||||
|
||||
AcceptButton.Disabled = disableAccept;
|
||||
AcceptButton.ForceState = disableAccept ? 0 : -1;
|
||||
AcceptButton.Opacity = disableAccept ? 0.5f : 1;
|
||||
//AcceptButton.ForceState = disableAccept ? 0 : -1;
|
||||
//AcceptButton.Opacity = disableAccept ? 0.5f : 1;
|
||||
|
||||
if (Mode == UICASMode.SimEdit)
|
||||
UpdateCarousel(state);
|
||||
|
@ -631,6 +758,15 @@ namespace Simitone.Client.UI.Screens
|
|||
}
|
||||
}
|
||||
|
||||
public void SetFamilies()
|
||||
{
|
||||
//get all families that don't have a house from neighbourhood, and populate the list
|
||||
//i think house number -1 is townies, so only select 0
|
||||
var all = Content.Get().Neighborhood.MainResource.List<FAMI>();
|
||||
var families = all.Where(x => (x.Unknown & 16) > 0 && x.HouseNumber == 0);
|
||||
FamiliesPanel.UpdateFamilies(families.ToList(), vm);
|
||||
}
|
||||
|
||||
public void SetFamilyMember(int index)
|
||||
{
|
||||
if (RepresentFamily.Count <= index)
|
||||
|
@ -684,6 +820,46 @@ namespace Simitone.Client.UI.Screens
|
|||
fam.HeadOutfit = new FSO.SimAntics.Model.VMOutfitReference(new Outfit() { TS1AppearanceID = data.Head+".apr", TS1TextureID = data.HeadTex });
|
||||
}
|
||||
|
||||
private SimTemplateCreateInfo CASToNeighGen(CASFamilyMember x)
|
||||
{
|
||||
var code = ((x.Gender & 1) == 0) ? "m" : "f";
|
||||
code += (x.Gender > 1) ? "c" : "a";
|
||||
var ind = x.Body.IndexOf("_");
|
||||
var bodyType = x.Body.Substring(ind - 3, 3);
|
||||
code += bodyType;
|
||||
var info = new SimTemplateCreateInfo(code, x.SkinColor);
|
||||
info.Name = x.Name;
|
||||
info.Bio = x.Bio;
|
||||
info.PersonalityPoints = x.Personality;
|
||||
|
||||
info.BodyStringReplace[1] = x.Body + ",BODY=" + x.BodyTex;
|
||||
info.BodyStringReplace[2] = x.Head + ",HEAD-HEAD=" + x.HeadTex;
|
||||
|
||||
var hand = (x.Gender > 1) ? "u" : ((x.Gender == 0) ? "m" : "f");
|
||||
info.BodyStringReplace[17] = "H" + hand + "LO,HAND=" + "huao" + x.HandgroupTex;
|
||||
info.BodyStringReplace[18] = "H" + hand + "RO,HAND=" + "huao" + x.HandgroupTex;
|
||||
info.BodyStringReplace[19] = "H" + hand + "LP,HAND=" + "huao" + x.HandgroupTex;
|
||||
info.BodyStringReplace[20] = "H" + hand + "RP,HAND=" + "huao" + x.HandgroupTex;
|
||||
info.BodyStringReplace[21] = "H" + hand + "LO,HAND=" + "huao" + x.HandgroupTex;
|
||||
info.BodyStringReplace[22] = "H" + hand + "RC,HAND=" + "huao" + x.HandgroupTex;
|
||||
return info;
|
||||
}
|
||||
|
||||
public void ClearFamily()
|
||||
{
|
||||
var count = WIPFamily.Count;
|
||||
FamilyPanel.SecondName.CurrentText = "";
|
||||
for (int i = count-1; i >= 0; i--)
|
||||
ModifySim(true, i);
|
||||
}
|
||||
|
||||
public void SaveFamily()
|
||||
{
|
||||
SimitoneNeighbourGenerator.CreateFamily(FamilyPanel.SecondName.CurrentText, WIPFamily.Count, WIPFamily.Select(CASToNeighGen).ToArray());
|
||||
SetFamilies();
|
||||
ClearFamily();
|
||||
}
|
||||
|
||||
public void AcceptMember()
|
||||
{
|
||||
var mem = BuildMember();
|
||||
|
@ -713,7 +889,7 @@ namespace Simitone.Client.UI.Screens
|
|||
Head = ActiveHeads[j],
|
||||
HeadTex = ActiveHeadTex[j],
|
||||
Gender = (short)(((CurrentCode[0] == 'm') ? 0 : 1) | ((CurrentCode[1] == 'c') ? 2 : 0)),
|
||||
Personality = CASPanel.Personalities.Select(x => (short)x.Points).ToArray(),
|
||||
Personality = CASPanel.Personalities.Select(x => (short)(x.Points * 100)).ToArray(),
|
||||
SkinColor = CurrentSkin
|
||||
};
|
||||
return sim;
|
||||
|
@ -746,7 +922,6 @@ namespace Simitone.Client.UI.Screens
|
|||
//clear our cache too, if the setting lets us do that
|
||||
TimedReferenceController.Clear();
|
||||
TimedReferenceController.Clear();
|
||||
VM.ClearAssembled();
|
||||
|
||||
vm.Context.Ambience.Kill();
|
||||
foreach (var ent in vm.Entities)
|
||||
|
@ -802,13 +977,11 @@ namespace Simitone.Client.UI.Screens
|
|||
vm.Tick();
|
||||
|
||||
vm.Context.Clock.Hours = 12;
|
||||
vm.TSOState.Size = (10) | (3 << 8);
|
||||
vm.Context.UpdateTSOBuildableArea();
|
||||
vm.MyUID = 1;
|
||||
vm.MyUID = uint.MaxValue;
|
||||
var settings = GlobalSettings.Default;
|
||||
var myClient = new VMNetClient
|
||||
{
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
RemoteIP = "local",
|
||||
AvatarState = new VMNetAvatarPersistState()
|
||||
{
|
||||
|
@ -816,7 +989,7 @@ namespace Simitone.Client.UI.Screens
|
|||
DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
|
||||
BodyOutfit = settings.DebugBody,
|
||||
HeadOutfit = settings.DebugHead,
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
SkinTone = (byte)settings.DebugSkin,
|
||||
Gender = (short)(settings.DebugGender ? 1 : 0),
|
||||
Permissions = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
|
||||
|
|
|
@ -8,19 +8,24 @@ using FSO.Common;
|
|||
using FSO.Common.Rendering.Framework;
|
||||
using FSO.Common.Utils;
|
||||
using FSO.Content;
|
||||
using FSO.Files.Formats.IFF;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using FSO.Files.RC;
|
||||
using FSO.HIT;
|
||||
using FSO.LotView;
|
||||
using FSO.SimAntics;
|
||||
using FSO.SimAntics.Engine.TSOTransaction;
|
||||
using FSO.SimAntics.Marshals;
|
||||
using FSO.SimAntics.Model;
|
||||
using FSO.SimAntics.NetPlay;
|
||||
using FSO.SimAntics.NetPlay.Drivers;
|
||||
using FSO.SimAntics.NetPlay.Model;
|
||||
using FSO.SimAntics.NetPlay.Model.Commands;
|
||||
using FSO.SimAntics.Utils;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Simitone.Client.UI.Controls;
|
||||
using Simitone.Client.UI.Panels;
|
||||
using Simitone.Client.UI.Panels.WorldUI;
|
||||
using System;
|
||||
|
@ -163,7 +168,7 @@ namespace Simitone.Client.UI.Screens
|
|||
}
|
||||
}
|
||||
|
||||
public TS1GameScreen() : base()
|
||||
public TS1GameScreen(NeighSelectionMode mode) : base()
|
||||
{
|
||||
Bg = new UISimitoneBg();
|
||||
Bg.Position = (new Vector2(ScreenWidth, ScreenHeight)) / 2;
|
||||
|
@ -174,25 +179,74 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
if (Content.Get().TS1)
|
||||
{
|
||||
NeighSelection();
|
||||
NeighSelection(mode);
|
||||
}
|
||||
}
|
||||
public int? MoveInFamily;
|
||||
|
||||
public void NeighSelection()
|
||||
public void StartMoveIn(int familyID)
|
||||
{
|
||||
TS1NeighPanel = new UINeighborhoodSelectionPanel(4);
|
||||
var switcher = new UINeighbourhoodSwitcher(TS1NeighPanel, 4);
|
||||
MoveInFamily = familyID;
|
||||
}
|
||||
|
||||
public void NeighSelection(NeighSelectionMode mode)
|
||||
{
|
||||
var nbd = (ushort)((mode == NeighSelectionMode.MoveInMagic) ? 7 : 4);
|
||||
TS1NeighPanel = new UINeighborhoodSelectionPanel(nbd);
|
||||
var switcher = new UINeighbourhoodSwitcher(TS1NeighPanel, nbd, mode != NeighSelectionMode.Normal);
|
||||
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);
|
||||
if (MoveInFamily != null)
|
||||
{
|
||||
//move them in first
|
||||
//confirm it
|
||||
UIMobileAlert confirmDialog = null;
|
||||
confirmDialog = new UIMobileAlert(new UIAlertOptions()
|
||||
{
|
||||
Title = GameFacade.Strings.GetString("132", "0"),
|
||||
Message = GameFacade.Strings.GetString("132", "1"),
|
||||
Buttons = UIAlertButton.YesNo((b) =>
|
||||
{
|
||||
confirmDialog.Close();
|
||||
MoveInAndPlay((short)house, MoveInFamily.Value, switcher);
|
||||
},
|
||||
(b) => confirmDialog.Close())
|
||||
});
|
||||
UIScreen.GlobalShowDialog(confirmDialog, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayHouse((short)house, switcher);
|
||||
}
|
||||
};
|
||||
Add(TS1NeighPanel);
|
||||
Add(switcher);
|
||||
}
|
||||
|
||||
public void PlayHouse(short house, UIElement switcher)
|
||||
{
|
||||
ActiveFamily = Content.Get().Neighborhood.GetFamilyForHouse((short)house);
|
||||
InitializeLot(Content.Get().Neighborhood.GetHousePath(house), false);// "UserData/Houses/House21.iff"
|
||||
Remove(TS1NeighPanel);
|
||||
if (switcher != null) Remove(switcher);
|
||||
}
|
||||
|
||||
public void MoveInAndPlay(short house, int family, UIElement switcher)
|
||||
{
|
||||
var neigh = Content.Get().Neighborhood;
|
||||
var fami = neigh.GetFamily((ushort)family);
|
||||
neigh.SetFamilyForHouse(house, fami, true);
|
||||
PlayHouse(house, switcher);
|
||||
}
|
||||
|
||||
public void EvictLot(FAMI family, short houseID)
|
||||
{
|
||||
family.Budget += family.ValueInArch;
|
||||
family.ValueInArch = 0;
|
||||
Content.Get().Neighborhood.MoveOut(houseID);
|
||||
TS1NeighPanel.SelectHouse(houseID);
|
||||
}
|
||||
|
||||
public override void GameResized()
|
||||
{
|
||||
base.GameResized();
|
||||
|
@ -284,9 +338,9 @@ namespace Simitone.Client.UI.Screens
|
|||
GameFacade.Game.IsMouseVisible = Visible;
|
||||
|
||||
base.Update(state);
|
||||
if (state.NewKeys.Contains(Keys.NumPad1)) ChangeSpeedTo(1);
|
||||
if (state.NewKeys.Contains(Keys.NumPad2)) ChangeSpeedTo(2);
|
||||
if (state.NewKeys.Contains(Keys.NumPad3)) ChangeSpeedTo(3);
|
||||
if (state.NewKeys.Contains(Keys.D1)) ChangeSpeedTo(1);
|
||||
if (state.NewKeys.Contains(Keys.D2)) ChangeSpeedTo(2);
|
||||
if (state.NewKeys.Contains(Keys.D3)) ChangeSpeedTo(3);
|
||||
if (state.NewKeys.Contains(Keys.P)) ChangeSpeedTo(0);
|
||||
|
||||
if (World != null)
|
||||
|
@ -306,7 +360,7 @@ namespace Simitone.Client.UI.Screens
|
|||
else
|
||||
{
|
||||
Downtown = true;
|
||||
InitializeLot(Path.Combine(Content.Get().TS1BasePath, "UserData/Houses/House" + SwitchLot.ToString().PadLeft(2, '0') + ".iff"), false);
|
||||
InitializeLot(Content.Get().Neighborhood.GetHousePath(SwitchLot), false);
|
||||
}
|
||||
SwitchLot = -1;
|
||||
}
|
||||
|
@ -329,7 +383,6 @@ namespace Simitone.Client.UI.Screens
|
|||
//clear our cache too, if the setting lets us do that
|
||||
TimedReferenceController.Clear();
|
||||
TimedReferenceController.Clear();
|
||||
VM.ClearAssembled();
|
||||
|
||||
if (ZoomLevel < 4) ZoomLevel = 5;
|
||||
vm.Context.Ambience.Kill();
|
||||
|
@ -401,15 +454,15 @@ namespace Simitone.Client.UI.Screens
|
|||
public void InitializeLot(VMMarshal marshal)
|
||||
{
|
||||
InitializeLot();
|
||||
vm.MyUID = 1;
|
||||
vm.MyUID = uint.MaxValue;
|
||||
vm.Load(marshal);
|
||||
|
||||
vm.ActivateFamily(ActiveFamily);
|
||||
vm.TS1State.ActivateFamily(vm, ActiveFamily);
|
||||
|
||||
var settings = GlobalSettings.Default;
|
||||
var myClient = new VMNetClient
|
||||
{
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
RemoteIP = "local",
|
||||
AvatarState = new VMNetAvatarPersistState()
|
||||
{
|
||||
|
@ -417,7 +470,7 @@ namespace Simitone.Client.UI.Screens
|
|||
DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
|
||||
BodyOutfit = settings.DebugBody,
|
||||
HeadOutfit = settings.DebugHead,
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
SkinTone = (byte)settings.DebugSkin,
|
||||
Gender = (short)(settings.DebugGender ? 1 : 0),
|
||||
Permissions = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
|
||||
|
@ -438,7 +491,7 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
public void InitializeLot(string lotName, bool external)
|
||||
{
|
||||
if (lotName == "") return;
|
||||
if (lotName == "" || lotName[0] == '!') return;
|
||||
InitializeLot();
|
||||
|
||||
if (!external)
|
||||
|
@ -446,17 +499,15 @@ namespace Simitone.Client.UI.Screens
|
|||
if (!Downtown && ActiveFamily != null)
|
||||
{
|
||||
ActiveFamily.SelectWholeFamily();
|
||||
vm.ActivateFamily(ActiveFamily);
|
||||
vm.TS1State.ActivateFamily(vm, ActiveFamily);
|
||||
}
|
||||
BlueprintReset(lotName);
|
||||
BlueprintReset(lotName, null);
|
||||
|
||||
vm.TSOState.Size = (10) | (3 << 8);
|
||||
vm.Context.UpdateTSOBuildableArea();
|
||||
vm.MyUID = 1;
|
||||
vm.MyUID = uint.MaxValue;
|
||||
var settings = GlobalSettings.Default;
|
||||
var myClient = new VMNetClient
|
||||
{
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
RemoteIP = "local",
|
||||
AvatarState = new VMNetAvatarPersistState()
|
||||
{
|
||||
|
@ -464,17 +515,36 @@ namespace Simitone.Client.UI.Screens
|
|||
DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
|
||||
BodyOutfit = settings.DebugBody,
|
||||
HeadOutfit = settings.DebugHead,
|
||||
PersistID = 1,
|
||||
PersistID = uint.MaxValue,
|
||||
SkinTone = (byte)settings.DebugSkin,
|
||||
Gender = (short)(settings.DebugGender ? 1 : 0),
|
||||
Permissions = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
|
||||
Budget = 1000000
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (Downtown)
|
||||
{
|
||||
var ngbh = Content.Get().Neighborhood;
|
||||
var crossData = ngbh.GameState;
|
||||
var neigh = ngbh.GetNeighborIDForGUID(crossData.DowntownSimGUID);
|
||||
if (neigh != null) {
|
||||
var inv = ngbh.GetInventoryByNID(neigh.Value);
|
||||
if (inv != null) {
|
||||
var hr = inv.FirstOrDefault(x => x.Type == 2 && x.GUID == 7)?.Count ?? 0;
|
||||
var min = inv.FirstOrDefault(x => x.Type == 2 && x.GUID == 8)?.Count ?? 0;
|
||||
Driver.SendCommand(new VMNetSetTimeCmd()
|
||||
{
|
||||
Hours = hr,
|
||||
Minutes = min,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var server = (VMServerDriver)Driver;
|
||||
server.ConnectClient(myClient);
|
||||
LoadSurrounding(short.Parse(lotName.Substring(lotName.Length - 6, 2)));
|
||||
|
||||
GameFacade.Cursor.SetCursor(CursorType.Normal);
|
||||
ZoomLevel = 1;
|
||||
|
@ -484,9 +554,48 @@ namespace Simitone.Client.UI.Screens
|
|||
this.Add(Frontend);
|
||||
}
|
||||
|
||||
public void BlueprintReset(string path)
|
||||
public void LoadSurrounding(short houseID)
|
||||
{
|
||||
return;
|
||||
var surrounding = new NBHm(new OBJ(File.OpenRead(@"C:\Users\Rhys\Desktop\nb2.obj")));
|
||||
NBHmHouse myH = null;
|
||||
var myHeight = vm.Context.Blueprint.InterpAltitude(new Vector3(0, 0, 0));
|
||||
if (!surrounding.Houses.TryGetValue(houseID, out myH)) return;
|
||||
foreach (var house in surrounding.Houses)
|
||||
{
|
||||
if (house.Key == houseID) continue;
|
||||
var h = house.Value;
|
||||
//let's make their lot as a surrounding lot
|
||||
var gd = World.State.Device;
|
||||
var subworld = World.MakeSubWorld(gd);
|
||||
subworld.Initialize(gd);
|
||||
var tempVM = new VM(new VMContext(subworld), new VMServerDriver(new VMTSOGlobalLinkStub()), new VMNullHeadlineProvider());
|
||||
tempVM.Init();
|
||||
BlueprintReset(Content.Get().Neighborhood.GetHousePath(house.Key), tempVM);
|
||||
subworld.State.Level = 5;
|
||||
var subHeight = tempVM.Context.Blueprint.InterpAltitude(new Vector3(0, 0, 0));
|
||||
tempVM.Context.Blueprint.BaseAlt = (int)Math.Round(((subHeight - myHeight) + myH.Position.Y - h.Position.Y) / tempVM.Context.Blueprint.TerrainFactor);
|
||||
subworld.GlobalPosition = new Vector2((myH.Position.X - h.Position.X), (myH.Position.Z - h.Position.Z));
|
||||
|
||||
foreach (var obj in tempVM.Entities)
|
||||
{
|
||||
obj.Position = obj.Position;
|
||||
}
|
||||
|
||||
vm.Context.Blueprint.SubWorlds.Add(subworld);
|
||||
}
|
||||
vm.Context.World.InitSubWorlds();
|
||||
}
|
||||
|
||||
public void BlueprintReset(string path, VM vm)
|
||||
{
|
||||
string filename = Path.GetFileName(path);
|
||||
bool isSurrounding = true;
|
||||
if (vm == null)
|
||||
{
|
||||
isSurrounding = false;
|
||||
vm = this.vm;
|
||||
}
|
||||
try
|
||||
{
|
||||
using (var file = new BinaryReader(File.OpenRead(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/") + filename.Substring(0, filename.Length - 4) + ".fsov")))
|
||||
|
@ -527,9 +636,11 @@ namespace Simitone.Client.UI.Screens
|
|||
});
|
||||
}
|
||||
|
||||
vm.SpeedMultiplier = -1;
|
||||
vm.Tick();
|
||||
vm.SpeedMultiplier = 1;
|
||||
|
||||
if (ActiveFamily == null)
|
||||
if (ActiveFamily == null && !isSurrounding)
|
||||
{
|
||||
vm.SetGlobalValue(32, 1);
|
||||
vm.SpeedMultiplier = -1;
|
||||
|
@ -539,7 +650,12 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
private void Vm_OnGenericVMEvent(VMEventType type, object data)
|
||||
{
|
||||
//hmm...
|
||||
switch (type)
|
||||
{
|
||||
case VMEventType.TS1BuildBuyChange:
|
||||
Frontend.ModeSwitcher.UpdateBuildBuy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void VMLotSwitch(uint lotId)
|
||||
|
@ -626,13 +742,74 @@ namespace Simitone.Client.UI.Screens
|
|||
|
||||
public void Save()
|
||||
{
|
||||
//save the house first
|
||||
var iff = new IffFile();
|
||||
vm.TS1State.UpdateSIMI(vm);
|
||||
var marshal = vm.Save();
|
||||
var fsov = new FSOV();
|
||||
fsov.ChunkLabel = "Simitone Lot Data";
|
||||
fsov.ChunkID = 1;
|
||||
fsov.ChunkProcessed = true;
|
||||
fsov.ChunkType = "FSOV";
|
||||
fsov.AddedByPatch = true;
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
marshal.SerializeInto(new BinaryWriter(stream));
|
||||
fsov.Data = stream.ToArray();
|
||||
}
|
||||
|
||||
iff.AddChunk(fsov);
|
||||
|
||||
var simi = vm.TS1State.SimulationInfo;
|
||||
simi.ChunkProcessed = true;
|
||||
simi.AddedByPatch = true;
|
||||
iff.AddChunk(simi);
|
||||
|
||||
Texture2D roofless = null;
|
||||
var thumb = World.GetLotThumb(GameFacade.GraphicsDevice, (tex) => roofless = FSO.Common.Utils.TextureUtils.Decimate(tex, GameFacade.GraphicsDevice, 2, false));
|
||||
thumb = FSO.Common.Utils.TextureUtils.Decimate(thumb, GameFacade.GraphicsDevice, 2, false);
|
||||
|
||||
var tPNG = GeneratePNG(thumb);
|
||||
tPNG.ChunkID = 513;
|
||||
iff.AddChunk(tPNG);
|
||||
|
||||
var rPNG = GeneratePNG(roofless);
|
||||
rPNG.ChunkID = 512;
|
||||
iff.AddChunk(rPNG);
|
||||
|
||||
Content.Get().Neighborhood.SaveHouse(vm.GetGlobalValue(10), iff);
|
||||
Content.Get().Neighborhood.SaveNeighbourhood(true);
|
||||
}
|
||||
|
||||
public PNG GeneratePNG(Texture2D data)
|
||||
{
|
||||
var png = new PNG();
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
data.SaveAsPng(stream, data.Width, data.Height);
|
||||
png.data = stream.ToArray();
|
||||
}
|
||||
|
||||
png.ChunkLabel = "Lot Thumbnail";
|
||||
png.ChunkProcessed = true;
|
||||
png.ChunkType = "PNG_";
|
||||
png.AddedByPatch = true;
|
||||
|
||||
return png;
|
||||
}
|
||||
|
||||
public void ExitLot()
|
||||
{
|
||||
CleanupLastWorld();
|
||||
NeighSelection();
|
||||
NeighSelection(NeighSelectionMode.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public enum NeighSelectionMode
|
||||
{
|
||||
Normal,
|
||||
MoveIn,
|
||||
MoveInMagic
|
||||
}
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
using FSO.Client;
|
||||
using FSO.Common;
|
||||
using FSO.Content;
|
||||
using FSO.Files.Formats.IFF.Chunks;
|
||||
using FSO.LotView;
|
||||
using FSO.LotView.Facade;
|
||||
using FSO.LotView.RC;
|
||||
using FSO.SimAntics;
|
||||
using FSO.SimAntics.Engine.TSOTransaction;
|
||||
using FSO.SimAntics.NetPlay.Drivers;
|
||||
using FSO.SimAntics.Utils;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Simitone.Client.UI.Panels.WorldUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simitone.Client.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports the entire neighbourhood in *.obj format
|
||||
/// </summary>
|
||||
public static class SimitoneNeighOBJExporter
|
||||
{
|
||||
public static void SaveOBJ(string destPath, STR locations)
|
||||
{
|
||||
|
||||
var exportedFlr = new HashSet<ushort>();
|
||||
var gd = GameFacade.GraphicsDevice;
|
||||
var mtlBuilder = new StringBuilder();
|
||||
Directory.CreateDirectory(destPath);
|
||||
|
||||
//var mtlMem = new MemoryStream();
|
||||
//var mtlIO = new StreamWriter(mtlMem);
|
||||
var mtlIO = new StreamWriter(new FileStream(Path.Combine(destPath, "neighbourhood.mtl"), FileMode.Create, FileAccess.Write, FileShare.None));
|
||||
|
||||
var path = Path.Combine(destPath, "neighbourhood.obj");
|
||||
var filename = Path.GetFileNameWithoutExtension(path);
|
||||
using (var io = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)))
|
||||
{
|
||||
io.WriteLine("# Generated by the Simitone Neighbourhood Exporter.");
|
||||
io.WriteLine("# The purpose is to allow users to mesh neighbourhood surroundings using");
|
||||
io.WriteLine("# the projected physical positions and terrain profiles of lots as a starting point.");
|
||||
|
||||
io.WriteLine("mtllib neighbourhood.mtl");
|
||||
io.WriteLine("s 1");
|
||||
|
||||
int indCount = 1;
|
||||
for (int i = 0; i < locations.Length; i++)
|
||||
{
|
||||
var loc = locations.GetString(i).Split(',');
|
||||
var num = int.Parse(loc[0].TrimStart());
|
||||
var pos2d = new Vector2(int.Parse(loc[1].TrimStart()), int.Parse(loc[2].TrimStart()));
|
||||
|
||||
var house = Content.Get().Neighborhood.GetHouse(num);
|
||||
|
||||
World world;
|
||||
if (FSOEnvironment.Enable3D)
|
||||
{
|
||||
world = new FSO.LotView.RC.WorldRC(GameFacade.GraphicsDevice);
|
||||
}
|
||||
else
|
||||
{
|
||||
world = new FSO.LotView.World(GameFacade.GraphicsDevice);
|
||||
}
|
||||
|
||||
world.Opacity = 1;
|
||||
GameFacade.Scenes.Add(world);
|
||||
|
||||
var globalLink = new VMTS1GlobalLinkStub();
|
||||
var driver = new VMServerDriver(globalLink);
|
||||
|
||||
var vm = new VM(new VMContext(world), driver, new UIHeadlineRendererProvider());
|
||||
vm.ListenBHAVChanges();
|
||||
vm.Init();
|
||||
|
||||
vm.SetGlobalValue(11, (short)num);
|
||||
|
||||
var activator = new VMTS1Activator(vm, vm.Context.World, (short)num);
|
||||
var blueprint = activator.LoadFromIff(house);
|
||||
|
||||
var floorVerts = blueprint.Terrain.GetVertices(gd);
|
||||
blueprint.FloorGeom.FullReset(gd, false);
|
||||
var groundfloor = blueprint.FloorGeom.Floors[0];
|
||||
|
||||
//we need to calculate the
|
||||
var minHeight = int.MaxValue;
|
||||
var heights = vm.Context.Architecture.Terrain.Heights;
|
||||
for (int j=0; j<heights.Length; j++)
|
||||
{
|
||||
if ((j % blueprint.Width) == 0 || (j % blueprint.Width) == blueprint.Width - 1 || j < blueprint.Width || j >= (blueprint.Height - 1) * blueprint.Width)
|
||||
continue;
|
||||
var h = heights[j];
|
||||
if (h != 0 && h < minHeight) minHeight = h;
|
||||
}
|
||||
if (minHeight == int.MaxValue) minHeight = 0;
|
||||
var scale = (locations.Length > 30 ? 1f : 2f) * 1.4142135623730950488016887242097f;
|
||||
var baseV = new Vector3(pos2d.X + pos2d.Y * 2, 0, pos2d.Y * 2 - pos2d.X) / scale;
|
||||
baseV.Y -= (minHeight * 3 / 160f) * 3;
|
||||
|
||||
var ctr = blueprint.GetFineBounds().Location.ToVector2() + blueprint.GetFineBounds().Size.ToVector2() / 2;
|
||||
|
||||
var voff = baseV + new Vector3(ctr.X, 0, ctr.Y) * 3f / -1;
|
||||
|
||||
voff.X = (int)(voff.X / 3) * 3;
|
||||
voff.Z = (int)(voff.Z / 3) * 3;
|
||||
|
||||
SetOutsideTime(GameFacade.GraphicsDevice, vm, world, 0.5f, false);
|
||||
world.State.PrepareLighting();
|
||||
var facade = new LotFacadeGenerator();
|
||||
facade.FLOOR_TILES = blueprint.Width;
|
||||
facade.GROUND_SUBDIV = blueprint.Width;
|
||||
facade.FLOOR_RES_PER_TILE = 4;
|
||||
facade.LotName = "p"+num.ToString();
|
||||
facade.Generate(GameFacade.GraphicsDevice, (WorldRC)world, blueprint);
|
||||
facade.AppendOBJ(io, filename, indCount, voff / 3);
|
||||
facade.AppendMTL(mtlIO, Path.GetDirectoryName(path));
|
||||
indCount = facade.LastIndex;
|
||||
|
||||
/*
|
||||
foreach (var group in groundfloor.GroupForTileType)
|
||||
{
|
||||
if (!exportedFlr.Contains(group.Key) && group.Key != 0 && group.Key < 65000)
|
||||
{
|
||||
//get and export this floor's texture. add it as a material as well.
|
||||
var floor = Content.Get().WorldFloors.Get(group.Key).Near.Frames[0].GetTexture(gd);
|
||||
using (var flrStream = new FileStream(Path.Combine(destPath, "flr_" + group.Key + ".png"), FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
floor.SaveAsPng(flrStream, floor.Width, floor.Height);
|
||||
|
||||
//add as material
|
||||
GenerateMTL("flr_" + group.Key, mtlBuilder);
|
||||
}
|
||||
//write out verts and indices.
|
||||
|
||||
|
||||
var indices = group.Value.BuildIndexData();
|
||||
var done = new Dictionary<int, int>(); //index remap
|
||||
|
||||
if (group.Key == 0)
|
||||
{
|
||||
//grass... export as grass colour
|
||||
io.WriteLine("usemtl " + "grass");
|
||||
io.WriteLine("o " + "lot_" + num + "_grass");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//export with floor textured material
|
||||
io.WriteLine("usemtl " + "flr_" + group.Key);
|
||||
io.WriteLine("o " + "lot_" + num + "_" + group.Key);
|
||||
}
|
||||
|
||||
var indexStr = new StringBuilder();
|
||||
indexStr.Append("f ");
|
||||
|
||||
for (int j = 0; j < indices.Length; j++)
|
||||
{
|
||||
var index = indices[j];
|
||||
int remapped = index;
|
||||
if (!done.TryGetValue(index, out remapped))
|
||||
{
|
||||
remapped = indCount;
|
||||
done.Add(index, indCount++);
|
||||
//append a vertex
|
||||
var vert = floorVerts[index];
|
||||
vert.Position += voff;
|
||||
io.Write("v " + vert.Position.X.ToString(CultureInfo.InvariantCulture) + " " + vert.Position.Y.ToString(CultureInfo.InvariantCulture) + " " + vert.Position.Z.ToString(CultureInfo.InvariantCulture));
|
||||
io.WriteLine((group.Key == 0) ? " " + vert.Color.X.ToString(CultureInfo.InvariantCulture) + " " + vert.Color.Y.ToString(CultureInfo.InvariantCulture) + " " + vert.Color.Z.ToString(CultureInfo.InvariantCulture) : "");
|
||||
io.WriteLine("vt " + vert.GrassInfo.Y.ToString(CultureInfo.InvariantCulture) + " " + (1 - vert.GrassInfo.Z).ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
indexStr.Append(remapped + "/" + remapped);
|
||||
if (j % 3 == 2)
|
||||
{
|
||||
indexStr.AppendLine();
|
||||
if (j != indices.Length - 1) indexStr.Append("f ");
|
||||
}
|
||||
else indexStr.Append(" ");
|
||||
}
|
||||
|
||||
io.WriteLine(indexStr);
|
||||
}
|
||||
*/
|
||||
|
||||
GameFacade.Scenes.Remove(world);
|
||||
world.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
mtlIO.Close();
|
||||
}
|
||||
|
||||
private static void SetOutsideTime(GraphicsDevice gd, VM vm, World world, float time, bool lightsOn)
|
||||
{
|
||||
vm.Context.Architecture.SetTimeOfDay(time);
|
||||
world.Force2DPredraw(gd);
|
||||
vm.Context.Architecture.SetTimeOfDay();
|
||||
}
|
||||
|
||||
private static void GenerateMTL(string oname, StringBuilder str)
|
||||
{
|
||||
str.AppendLine("newmtl " + oname);
|
||||
str.AppendLine("Ka 1.000 1.000 1.000");
|
||||
str.AppendLine("Kd 1.000 1.000 1.000");
|
||||
str.AppendLine("Ks 0.000 0.000 0.000");
|
||||
|
||||
str.AppendLine("Ns 10.0000");
|
||||
str.AppendLine("illum 2");
|
||||
|
||||
str.AppendLine("map_Kd " + oname + ".png");
|
||||
str.AppendLine("map_d " + oname + ".png");
|
||||
}
|
||||
}
|
||||
}
|
BIN
Client/Simitone/Simitone.Windows/Icon.bmp
Normal file
After Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 50 KiB |
|
@ -24,7 +24,7 @@ namespace Simitone.Windows
|
|||
{
|
||||
var gameLocator = new WindowsLocator();
|
||||
|
||||
var useDX = false;
|
||||
var useDX = true;
|
||||
var path = gameLocator.FindTheSimsOnline();
|
||||
|
||||
if (useDX) GlobalSettings.Default.AntiAlias = false;
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Icon.bmp">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<Content Include="Icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -58,9 +61,9 @@
|
|||
<Project>{6d6009f4-0afb-4806-89d7-7945f20270f5}</Project>
|
||||
<Name>MonoGame.Framework.Net.WindowsGL</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.WindowsGL.csproj">
|
||||
<Project>{6d75e618-19ca-4c51-9546-f10965fbc0b8}</Project>
|
||||
<Name>MonoGame.Framework.WindowsGL</Name>
|
||||
<ProjectReference Include="..\..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.Windows.csproj">
|
||||
<Project>{7de47032-a904-4c29-bd22-2d235e8d91ba}</Project>
|
||||
<Name>MonoGame.Framework.Windows</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\FreeSO\Other\libs\mp3sharp\mp3sharp\Mp3Sharp.csproj">
|
||||
<Project>{834cab58-648d-47cc-ac6f-d01c08c809a4}</Project>
|
||||
|
@ -99,6 +102,9 @@
|
|||
<Name>Simitone.Client</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
|
4
Client/Simitone/Simitone.Windows/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MonoGame.Framework.WindowsDX" version="3.6.0.1625" targetFramework="net45" />
|
||||
</packages>
|
|
@ -445,8 +445,8 @@ Global
|
|||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
|
@ -477,8 +477,8 @@ Global
|
|||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
|
@ -629,8 +629,8 @@ Global
|
|||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
|
@ -661,8 +661,8 @@ Global
|
|||
{AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
|
|
2
FreeSO
|
@ -1 +1 @@
|
|||
Subproject commit 6385ba5cf5025b27b952b5e8a585bacf0af7af00
|
||||
Subproject commit b23f16c4de1792363bc25d94a4d34dc787d39899
|