diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1fa4d00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,244 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Xx]64/ +[Xx]86/ +[Bb]uild/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml + +# TODO: Un-comment the next line if you do not want to checkin +# your web deploy settings because they may include unencrypted +# passwords +#*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# LightSwitch generated files +GeneratedArtifacts/ +ModelManifest.xml + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ + +Client/Simitone/Simitone/ \ No newline at end of file diff --git a/Client/Simitone/Simitone.Client/Content/TS1Patch/NPC_Unleashed_SaxPlayer_infinite_loop.piff b/Client/Simitone/Simitone.Client/Content/TS1Patch/NPC_Unleashed_SaxPlayer_infinite_loop.piff new file mode 100644 index 0000000..46ca9a1 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/TS1Patch/NPC_Unleashed_SaxPlayer_infinite_loop.piff differ diff --git a/Client/Simitone/Simitone.Client/Content/TS1Patch/OpenMicSuperstar_objf.piff b/Client/Simitone/Simitone.Client/Content/TS1Patch/OpenMicSuperstar_objf.piff new file mode 100644 index 0000000..46fb618 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/TS1Patch/OpenMicSuperstar_objf.piff differ diff --git a/Client/Simitone/Simitone.Client/Content/TS1Patch/PetGym_performance.piff b/Client/Simitone/Simitone.Client/Content/TS1Patch/PetGym_performance.piff new file mode 100644 index 0000000..e898463 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/TS1Patch/PetGym_performance.piff differ diff --git a/Client/Simitone/Simitone.Client/Content/TS1Patch/PicnicBasketVacation_objf.piff b/Client/Simitone/Simitone.Client/Content/TS1Patch/PicnicBasketVacation_objf.piff new file mode 100644 index 0000000..bfb9552 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/TS1Patch/PicnicBasketVacation_objf.piff differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/bar.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/bar.png new file mode 100644 index 0000000..2a995ed Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/bar.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/barsmall.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/barsmall.png new file mode 100644 index 0000000..aacb612 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/barsmall.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/button.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/button.png new file mode 100644 index 0000000..cd1ae6d Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/button.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/diag.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/diag.png new file mode 100644 index 0000000..2a58968 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/diag.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/gradient.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/gradient.png new file mode 100644 index 0000000..cd13c22 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/gradient.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/common/greenbutton.png b/Client/Simitone/Simitone.Client/Content/uigraphics/common/greenbutton.png new file mode 100644 index 0000000..d29dcc5 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/common/greenbutton.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/dialog_title_grad.png b/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/dialog_title_grad.png new file mode 100644 index 0000000..f39d512 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/dialog_title_grad.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/ngbh_outline.png b/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/ngbh_outline.png new file mode 100644 index 0000000..f327f1a Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/dialog/ngbh_outline.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/blank_blue.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/blank_blue.png new file mode 100644 index 0000000..a0a2464 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/blank_blue.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_all.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_all.png new file mode 100644 index 0000000..6ba0870 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_all.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl.png new file mode 100644 index 0000000..130be21 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_frig.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_frig.png new file mode 100644 index 0000000..0b52b6b Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_frig.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_larg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_larg.png new file mode 100644 index 0000000..c5e8190 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_larg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_smal.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_smal.png new file mode 100644 index 0000000..b8dc003 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_smal.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_stov.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_stov.png new file mode 100644 index 0000000..7bf0f43 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_appl_stov.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco.png new file mode 100644 index 0000000..3e54502 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_pain.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_pain.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_pain.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_plan.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_plan.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_plan.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_rugs.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_rugs.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_rugs.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_scul.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_scul.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_deco_scul.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec.png new file mode 100644 index 0000000..9dcd05a Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_audi.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_audi.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_audi.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_ent.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_ent.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_ent.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_phon.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_phon.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_phon.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_vide.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_vide.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_elec_vide.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_hang.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_hang.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_hang.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_stan.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_stan.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_stan.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_tabl.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_tabl.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_tabl.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_wall.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_wall.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligh_wall.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligt.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligt.png new file mode 100644 index 0000000..69c9c2f Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_ligt.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc.png new file mode 100644 index 0000000..7524c12 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_crea.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_crea.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_crea.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_know.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_know.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_know.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_magi.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_magi.png new file mode 100644 index 0000000..88ac384 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_magi.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_pets.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_pets.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_pets.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_recr.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_recr.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_recr.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_ward.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_ward.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_misc_ward.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_other.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_other.png new file mode 100644 index 0000000..3c9ad47 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_other.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum.png new file mode 100644 index 0000000..bc4bb5d Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_hott.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_hott.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_hott.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_show.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_show.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_show.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_sink.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_sink.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_sink.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_toil.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_toil.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_plum_toil.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat.png new file mode 100644 index 0000000..057f76d Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_beds.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_beds.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_beds.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_dine.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_dine.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_dine.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_loun.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_loun.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_loun.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_sofa.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_sofa.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_seat_sofa.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf.png new file mode 100644 index 0000000..64651f7 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_count.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_count.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_count.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_desk.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_desk.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_desk.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_endt.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_endt.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_endt.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_tabl.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_tabl.png new file mode 100644 index 0000000..93899ad Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat/cat_surf_tabl.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat_btn_base.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat_btn_base.png new file mode 100644 index 0000000..ed54a24 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cat_btn_base.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockbg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockbg.png new file mode 100644 index 0000000..5f8aaf1 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockbg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg.png new file mode 100644 index 0000000..8fce2da Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg_pause.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg_pause.png new file mode 100644 index 0000000..a3d5dc6 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/clockinbg_pause.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_bg.png new file mode 100644 index 0000000..bf441b0 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_away.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_away.png new file mode 100644 index 0000000..a138ef6 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_away.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_down.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_down.png new file mode 100644 index 0000000..caf0a40 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_down.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_roof.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_roof.png new file mode 100644 index 0000000..ca4f017 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_roof.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_up.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_up.png new file mode 100644 index 0000000..5929b87 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_btn_up.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_away.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_away.png new file mode 100644 index 0000000..1bd9fbc Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_away.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_down.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_down.png new file mode 100644 index 0000000..05f381b Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_down.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_roof.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_roof.png new file mode 100644 index 0000000..067e4a3 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_roof.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_up.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_up.png new file mode 100644 index 0000000..25d4ea4 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/cut_stencil_up.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/divider.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/divider.png new file mode 100644 index 0000000..ab759d7 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/divider.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_bg.png new file mode 100644 index 0000000..e74e5b9 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_sel.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_sel.png new file mode 100644 index 0000000..42a8286 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_big_sel.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_cancel.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_cancel.png new file mode 100644 index 0000000..78e3d33 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_cancel.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_gohere.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_gohere.png new file mode 100644 index 0000000..b2ce767 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_gohere.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_small_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_small_bg.png new file mode 100644 index 0000000..65be9aa Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/int_small_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_ing_btn.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_ing_btn.png new file mode 100644 index 0000000..23ceb10 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_ing_btn.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_item.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_item.png new file mode 100644 index 0000000..435dfed Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_item.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_mag_btn.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_mag_btn.png new file mode 100644 index 0000000..1e0a0f2 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_mag_btn.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_other_btn.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_other_btn.png new file mode 100644 index 0000000..ffcd1c7 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/inv_other_btn.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_down.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_down.png new file mode 100644 index 0000000..c6c21ba Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_down.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_up.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_up.png new file mode 100644 index 0000000..a7f7a1c Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/level_up.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build.png new file mode 100644 index 0000000..65556cd Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build_disable.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build_disable.png new file mode 100644 index 0000000..46ad43d Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_build_disable.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy.png new file mode 100644 index 0000000..5273ab1 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy_disable.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy_disable.png new file mode 100644 index 0000000..76fbf92 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_buy_disable.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_live.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_live.png new file mode 100644 index 0000000..64480a5 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_live.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_options.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_options.png new file mode 100644 index 0000000..656ebb0 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/mode_options.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_inventory.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_inventory.png new file mode 100644 index 0000000..10e306a Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_inventory.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_job.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_job.png new file mode 100644 index 0000000..b069f05 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_job.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_motives.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_motives.png new file mode 100644 index 0000000..07a2b1d Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_motives.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_personality.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_personality.png new file mode 100644 index 0000000..43e5002 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_personality.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_relationships.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_relationships.png new file mode 100644 index 0000000..39f2acb Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/modes/live_relationships.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/money_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/money_bg.png new file mode 100644 index 0000000..ec8b455 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/money_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_arrow.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_arrow.png new file mode 100644 index 0000000..b67c887 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_arrow.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_bg.png new file mode 100644 index 0000000..5913033 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/motive_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_div.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_div.png new file mode 100644 index 0000000..cd2de75 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_div.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_expand.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_expand.png new file mode 100644 index 0000000..4666e74 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_expand.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_hide.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_hide.png new file mode 100644 index 0000000..7a05637 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/panel_hide.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_bg.png new file mode 100644 index 0000000..f7cd8bf Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_neg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_neg.png new file mode 100644 index 0000000..6d09bfe Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_neg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_plus.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_plus.png new file mode 100644 index 0000000..66d0263 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/plumb_plus.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_bg.png new file mode 100644 index 0000000..0790c4f Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_bg.png new file mode 100644 index 0000000..780682a Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_sel.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_sel.png new file mode 100644 index 0000000..cd61d94 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/pswitch_icon_sel.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_all.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_all.png new file mode 100644 index 0000000..adbd9cb Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_all.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fam.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fam.png new file mode 100644 index 0000000..80f5b57 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fam.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fame.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fame.png new file mode 100644 index 0000000..b1b7277 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_fame.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_friend.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_friend.png new file mode 100644 index 0000000..219dc74 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rel_friend.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_back.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_back.png new file mode 100644 index 0000000..9514c54 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_back.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_front.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_front.png new file mode 100644 index 0000000..ecfa157 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_arrow_front.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_seg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_seg.png new file mode 100644 index 0000000..3661604 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/rot_seg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_l.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_l.png new file mode 100644 index 0000000..861e62f Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_l.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_r.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_r.png new file mode 100644 index 0000000..a97a752 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/scroll_edge_r.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/skill.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/skill.png new file mode 100644 index 0000000..02ccdbc Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/skill.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_1.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_1.png new file mode 100644 index 0000000..7ee0607 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_1.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_2.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_2.png new file mode 100644 index 0000000..65d8c95 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_2.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_3.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_3.png new file mode 100644 index 0000000..4f33042 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_3.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_4.png b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_4.png new file mode 100644 index 0000000..52be124 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/live/speedbtn_4.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_bg.png new file mode 100644 index 0000000..550a9d0 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_bg.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_content.png b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_content.png new file mode 100644 index 0000000..91d9d76 Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_bar_content.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_logo.png b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_logo.png new file mode 100644 index 0000000..53c95ce Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_logo.png differ diff --git a/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_static_bg.png b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_static_bg.png new file mode 100644 index 0000000..7ecdb1b Binary files /dev/null and b/Client/Simitone/Simitone.Client/Content/uigraphics/load/load_static_bg.png differ diff --git a/Client/Simitone/Simitone.Client/GameController.cs b/Client/Simitone/Simitone.Client/GameController.cs new file mode 100644 index 0000000..486d7cb --- /dev/null +++ b/Client/Simitone/Simitone.Client/GameController.cs @@ -0,0 +1,42 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Common.Utils; +using Simitone.Client.UI.Screens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client +{ + public static class GameController + { + public static void EnterLoading() + { + var screen = new LoadingScreen(); + GameFacade.Screens.RemoveCurrent(); + GameFacade.Screens.AddScreen(screen); + } + + public static void EnterGameMode(string lotName, bool external) + { + GameThread.NextUpdate((x) => + { + var screen = new TS1GameScreen(); + var last = GameFacade.Screens.CurrentUIScreen; + GameFacade.Screens.RemoveCurrent(); + GameFacade.Screens.AddScreen(screen); + + ((LoadingScreen)last).Close(); + var children = new List(last.GetChildren()); + for (int i=0; i + + + + Debug + AnyCPU + {0F20013D-0610-4573-A346-1C5A461B0BA0} + Library + Properties + Simitone.Client + Simitone.Client + v4.5 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {6d6009f4-0afb-4806-89d7-7945f20270f5} + MonoGame.Framework.Net.WindowsGL + + + {7de47032-a904-4c29-bd22-2d235e8d91ba} + MonoGame.Framework.Windows + + + {73e2ad5b-720b-4ef3-9b7c-55931d0ec693} + FSO.UI + + + {c42962a1-8796-4f47-9dcd-79ed5904d8ca} + FSO.Common + + + {c0068df7-f2e8-4399-846d-556bf9a35c00} + FSO.Content + + + {18583453-a970-4ac5-83b1-2d6bfdf94c24} + FSO.Files + + + {5eddefd2-c850-49c1-812d-ddeff09125ef} + FSO.SimAntics + + + {072781d8-51ec-4143-9cae-daf50177d3ad} + FSO.HIT + + + {fd7957f7-a1e0-4d00-8f6c-3fa555eaa163} + FSO.Vitaboy.Engine + + + {9d9558a9-755e-43f9-8bb6-b26f365f5042} + FSO.Vitaboy + + + {b1a6e4c2-e080-4c34-a604-d11b5296a9b8} + FSO.LotView + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + + + + + PreserveNewest + + + + + \ No newline at end of file diff --git a/Client/Simitone/Simitone.Client/SimitoneGame.cs b/Client/Simitone/Simitone.Client/SimitoneGame.cs new file mode 100644 index 0000000..39c0a02 --- /dev/null +++ b/Client/Simitone/Simitone.Client/SimitoneGame.cs @@ -0,0 +1,255 @@ +/* +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System.Threading; +using LogThis; +using FSO.Common.Rendering.Framework; +using FSO.LotView; +using FSO.HIT; +using FSO.Client.UI; +using FSO.Client.GameContent; +using FSO.Common.Utils; +using FSO.Common; +using Microsoft.Xna.Framework.Audio; +using FSO.HIT.Model; +using FSO.Client; +using FSO.Files; + +namespace Simitone.Client +{ + /// + /// This is the main type for your game + /// + public class SimitoneGame : FSO.Common.Rendering.Framework.Game + { + public UILayer uiLayer; + public _3DLayer SceneMgr; + private bool HasUpdated; + + 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; + + if (!FSOEnvironment.SoftwareKeyboard) + { + Graphics.SynchronizeWithVerticalRetrace = true; + Graphics.PreferredBackBufferWidth = GlobalSettings.Default.GraphicsWidth; + Graphics.PreferredBackBufferHeight = GlobalSettings.Default.GraphicsHeight; + Graphics.HardwareModeSwitch = false; + Graphics.ApplyChanges(); + } + + this.Window.AllowUserResizing = true; + this.Window.ClientSizeChanged += new EventHandler(Window_ClientSizeChanged); + + Thread.CurrentThread.Name = "Game"; + } + + bool newChange = false; + void Window_ClientSizeChanged(object sender, EventArgs e) + { + if (newChange || !GlobalSettings.Default.Windowed || FSOEnvironment.SoftwareKeyboard) return; + if (Window.ClientBounds.Width == 0 || Window.ClientBounds.Height == 0) return; + newChange = true; + var width = Math.Max(1, Window.ClientBounds.Width); + var height = Math.Max(1, Window.ClientBounds.Height); + Graphics.PreferredBackBufferWidth = width; + Graphics.PreferredBackBufferHeight = height; + Graphics.ApplyChanges(); + + GlobalSettings.Default.GraphicsWidth = width; + GlobalSettings.Default.GraphicsHeight = height; + + newChange = false; + if (uiLayer?.CurrentUIScreen == null) return; + + uiLayer.SpriteBatch.ResizeBuffer(GlobalSettings.Default.GraphicsWidth, GlobalSettings.Default.GraphicsHeight); + uiLayer.CurrentUIScreen.GameResized(); + } + + /// + /// Allows the game to perform any initialization it needs to before starting to run. + /// This is where it can query for any required services and load any non-graphic + /// related content. Calling base.Initialize will enumerate through any components + /// and initialize them as well. + /// + protected override void Initialize() + { + + var settings = GlobalSettings.Default; + if (FSOEnvironment.DPIScaleFactor != 1 || FSOEnvironment.SoftwareDepth) + { + settings.GraphicsWidth = GraphicsDevice.Viewport.Width / FSOEnvironment.DPIScaleFactor; + settings.GraphicsHeight = GraphicsDevice.Viewport.Height / FSOEnvironment.DPIScaleFactor; + } + + FSO.LotView.WorldConfig.Current = new FSO.LotView.WorldConfig() + { + AdvancedLighting = settings.Lighting, + SmoothZoom = settings.SmoothZoom, + SurroundingLots = settings.SurroundingLotMode + }; + + OperatingSystem os = Environment.OSVersion; + PlatformID pid = os.Platform; + GameFacade.Linux = (pid == PlatformID.MacOSX || pid == PlatformID.Unix); + + FSO.Content.Content.TS1Hybrid = GlobalSettings.Default.TS1HybridEnable; + FSO.Content.Content.TS1HybridBasePath = GlobalSettings.Default.TS1HybridPath; + //FSO.Content.Content.Init(GlobalSettings.Default.StartupPath, GraphicsDevice); + base.Initialize(); + + GameFacade.GameThread = Thread.CurrentThread; + + SceneMgr = new _3DLayer(); + SceneMgr.Initialize(GraphicsDevice); + + GameFacade.Scenes = SceneMgr; + GameFacade.GraphicsDevice = GraphicsDevice; + GameFacade.GraphicsDeviceManager = Graphics; + GameFacade.Cursor = new CursorManager(GraphicsDevice); + if (!GameFacade.Linux) GameFacade.Cursor.Init(GlobalSettings.Default.StartupPath); + + /** Init any computed values **/ + GameFacade.Init(); + + //init audio now + HITVM.Init(); + var hit = HITVM.Get(); + hit.SetMasterVolume(HITVolumeGroup.FX, GlobalSettings.Default.FXVolume / 10f); + hit.SetMasterVolume(HITVolumeGroup.MUSIC, GlobalSettings.Default.MusicVolume / 10f); + hit.SetMasterVolume(HITVolumeGroup.VOX, GlobalSettings.Default.VoxVolume / 10f); + hit.SetMasterVolume(HITVolumeGroup.AMBIENCE, GlobalSettings.Default.AmbienceVolume / 10f); + + GameFacade.Strings = new ContentStrings(); + + GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None }; + + try + { + var audioTest = new SoundEffect(new byte[2], 44100, AudioChannels.Mono); //initialises XAudio. + audioTest.CreateInstance().Play(); + } + catch (Exception e) + { + //MessageBox.Show("Failed to initialize audio: \r\n\r\n" + e.StackTrace); + } + + this.IsFixedTimeStep = true; + + WorldContent.Init(this.Services, Content.RootDirectory); + base.Screen.Layers.Add(SceneMgr); + base.Screen.Layers.Add(uiLayer); + GameFacade.LastUpdateState = base.Screen.State; + + if (!GlobalSettings.Default.Windowed && !GameFacade.GraphicsDeviceManager.IsFullScreen) + { + GameFacade.GraphicsDeviceManager.ToggleFullScreen(); + } + } + + /// + /// Run this instance with GameRunBehavior forced as Synchronous. + /// + public new void Run() + { + Run(GameRunBehavior.Synchronous); + } + + /// + /// Only used on desktop targets. Use extensive reflection to AVOID linking on iOS! + /// + void AddTextInput() + { + this.Window.GetType().GetEvent("TextInput").AddEventHandler(this.Window, (EventHandler)GameScreen.TextInput); + } + + void RegainFocus(object sender, EventArgs e) + { + GameFacade.Focus = true; + } + + void LostFocus(object sender, EventArgs e) + { + GameFacade.Focus = false; + } + + /// + /// LoadContent will be called once per game and is the place to load + /// all of your content. + /// + protected override void LoadContent() + { + Console.WriteLine("loadcontent"); + Effect vitaboyEffect = null; + try + { + GameFacade.MainFont = new FSO.Client.UI.Framework.Font(); + GameFacade.MainFont.AddSize(12, Content.Load("Fonts/Mobile_15px")); + GameFacade.MainFont.AddSize(15, Content.Load("Fonts/Mobile_20px")); + GameFacade.MainFont.AddSize(19, Content.Load("Fonts/Mobile_25px")); + GameFacade.MainFont.AddSize(37, Content.Load("Fonts/Mobile_50px")); + + GameFacade.EdithFont = new FSO.Client.UI.Framework.Font(); + GameFacade.EdithFont.AddSize(12, Content.Load("Fonts/Trebuchet_12px")); + GameFacade.EdithFont.AddSize(14, Content.Load("Fonts/Trebuchet_14px")); + + vitaboyEffect = Content.Load("Effects/Vitaboy"+((FSOEnvironment.SoftwareDepth)?"iOS":"")); + uiLayer = new UILayer(this, Content.Load("Fonts/FreeSO_12px"), Content.Load("Fonts/FreeSO_16px")); + } + catch (Exception e) + { + //MessageBox.Windows.Forms.MessageBox.Show("Content could not be loaded. Make sure that the FreeSO content has been compiled! (ContentSrc/TSOClientContent.mgcb)"); + Console.WriteLine(e.ToString()); + Exit(); + } + + FSO.Vitaboy.Avatar.setVitaboyEffect(vitaboyEffect); + } + + /// + /// UnloadContent will be called once per game and is the place to unload + /// all content. + /// + protected override void UnloadContent() + { + // TODO: Unload any non ContentManager content here + } + + /// + /// Allows the game to run logic such as updating the world, + /// checking for collisions, gathering input, and playing audio. + /// + /// Provides a snapshot of timing values. + protected override void Update(GameTime gameTime) + { + if (!HasUpdated) + { + this.IsMouseVisible = true; + if (!FSOEnvironment.SoftwareKeyboard) AddTextInput(); + this.Window.Title = "Simitone"; + HasUpdated = true; + GameFacade.Screens = uiLayer; + GameController.EnterLoading(); + } + GameThread.UpdateExecuting = true; + + if (HITVM.Get() != null) HITVM.Get().Tick(); + + base.Update(gameTime); + GameThread.UpdateExecuting = false; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIBigButton.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIBigButton.cs new file mode 100644 index 0000000..308ba5a --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIBigButton.cs @@ -0,0 +1,24 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.Content; +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.Controls +{ + public class UIBigButton : UIButton + { + public UIBigButton(bool green) : base() + { + CaptionStyle = CaptionStyle.Clone(); + CaptionStyle.Size = 37; + CaptionStyle.Color = (green)?UIStyle.Current.GreenBtnTxt:UIStyle.Current.BtnTxt; + CaptionStyle.DisabledColor = UIStyle.Current.BtnDisable; + Texture = Content.Get().CustomUI.Get(green ? "greenbutton.png" : "button.png").Get(GameFacade.GraphicsDevice); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UICatButton.cs b/Client/Simitone/Simitone.Client/UI/Controls/UICatButton.cs new file mode 100644 index 0000000..0783131 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UICatButton.cs @@ -0,0 +1,54 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Content; +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.Controls +{ + public class UICatButton : UIStencilButton + { + private Texture2D CatBase; + public UICatButton(Texture2D tex) : base(tex) + { + Alpha = 1f; + ImageStates = 1; + CatBase = Content.Get().CustomUI.Get("cat_btn_base.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch SBatch) + { + base.Draw(SBatch); + var frame = CurrentFrame; + if (Disabled) + { + frame = 3; + } + if (Selected) + { + frame = 1; + } + if (ForceState > -1) frame = ForceState; + frame = Math.Min(3, frame); + + Color color; + switch (frame) + { + case 1: + color = ActiveColor; break; + case 2: + color = HoverColor; break; + case 3: + color = DisabledColor; break; + default: + color = Color; break; + } + DrawLocalTexture(SBatch, CatBase, null, new Vector2(-5), Vector2.One, color * Alpha); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UICategorySwitcher.cs b/Client/Simitone/Simitone.Client/UI/Controls/UICategorySwitcher.cs new file mode 100644 index 0000000..b5d0b2a --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UICategorySwitcher.cs @@ -0,0 +1,150 @@ +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.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Controls +{ + public class UICategorySwitcher : UIContainer + { + public UICatButton MainButton; + public UIDiagonalStripe Stripe; + public UIVertGrad Grad; + public event Action OnCategorySelect; + public int ActiveCategory; + public List Categories; + public List CatSwitchButtons = new List(); + + private float _ce; + public float CategoryExpand + { + get + { + return _ce; + } + set + { + var scrHeight = GameFacade.Screens.CurrentUIScreen.ScreenHeight; + var size = (scrHeight - (128 + 15)); + Stripe.Y = (-value) * size; + Stripe.BodySize = new Point(85, (int)(value*size)); + + var i = 0; + foreach (var btn in CatSwitchButtons) + { + btn.Y = i++ * -70 * value - 75; + btn.Opacity = value; + btn.Visible = value > 0; + } + + Grad.Visible = value > 0; + Grad.GSize = new Vector2(size, 75*value); + Stripe.Visible = value > 0; + _ce = value; + } + } + + public UICategorySwitcher() + { + Stripe = new UIDiagonalStripe(new Point(), UIDiagonalStripeSide.UP, UIStyle.Current.Bg); + Add(Stripe); + + Grad = new UIVertGrad(); + Grad.Position = new Vector2(43, 0); + Grad.Visible = false; + Add(Grad); + + MainButton = new UICatButton(TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice)); + MainButton.Position = new Microsoft.Xna.Framework.Vector2(10, 31); + MainButton.OnButtonClick += (b) => { Open(); }; + MainButton.Selected = true; + Add(MainButton); + + CategoryExpand = CategoryExpand; + } + + public void Select(int cat) + { + foreach (var item in CatSwitchButtons) + { + Remove(item); + } + CatSwitchButtons.Clear(); + foreach (var catG in Categories) + { + var id = catG.ID; + if (catG.ID == cat) + { + MainButton.Texture = Content.Get().CustomUI.Get(catG.IconName).Get(GameFacade.GraphicsDevice); + } + else + { + var btn = new UIStencilButton(Content.Get().CustomUI.Get(catG.IconName).Get(GameFacade.GraphicsDevice)); + btn.Shadow = true; + btn.X = 10; + btn.Visible = false; + btn.OnButtonClick += (b) => { Select(id); }; + Add(btn); + CatSwitchButtons.Add(btn); + } + } + if (CategoryExpand > 0) + { + CategoryExpand = CategoryExpand; + Close(); + } + OnCategorySelect?.Invoke(cat); + ActiveCategory = cat; + } + + public void InitCategories(List cats) + { + Categories = cats; + Select(Categories[0].ID); + } + + public void Open() + { + if (CategoryExpand > 0) + { + Close(); return; + } + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "CategoryExpand", 1f } }, TweenQuad.EaseOut); + } + + public void Close() + { + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "CategoryExpand", 0f } }, TweenQuad.EaseOut); + } + } + + public class UICategory + { + public int ID; + public string IconName; + } + + public class UIVertGrad : UIElement + { + public Texture2D Grad; + public Vector2 GSize; + + public UIVertGrad() : base() + { + Grad = Content.Get().CustomUI.Get("dialog_title_grad.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Grad, null, new Vector2(0, 0), new Vector2(GSize.X / Grad.Width, GSize.Y), Color.White, (float)Math.PI / -2, new Vector2(0, 0.5f)); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIDiagonalStripe.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIDiagonalStripe.cs new file mode 100644 index 0000000..3161725 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIDiagonalStripe.cs @@ -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 System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Controls +{ + public class UIDiagonalStripe : UIElement + { + public UIDiagonalStripeSide DiagSide; + public Point BodySize { get; set; } + public Color Color { get; set; } + public int StartOff; + private Texture2D Diag; + + public UIDiagonalStripe(Point size, UIDiagonalStripeSide diagSide, Color color) + { + BodySize = size; + Color = color; + DiagSide = diagSide; + Diag = Content.Get().CustomUI.Get("diag.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch batch) + { + if (!Visible) return; + var whitepx = TextureGenerator.GetPxWhite(batch.GraphicsDevice); + + DrawLocalTexture(batch, whitepx, null, new Vector2(0, StartOff), BodySize.ToVector2() - new Vector2(0, StartOff), Color); + + Rectangle lastRect; + Point start; + Point inc; + int total; + float rotate = 0; + + switch (DiagSide) + { + case UIDiagonalStripeSide.RIGHT: + start = new Point(BodySize.X, 0); + inc = new Point(0, 64); + total = (int)Math.Ceiling(BodySize.Y / 64f); + lastRect = new Rectangle(0, 0, 32, BodySize.Y % 64); + break; + case UIDiagonalStripeSide.BOTTOM: + start = new Point(BodySize.X, BodySize.Y); + inc = new Point(-64, 0); + total = (int)Math.Ceiling(BodySize.X / 64f); + lastRect = new Rectangle(0, 0, 32, BodySize.X % 64); + rotate = (float)(Math.PI / 2); + break; + case UIDiagonalStripeSide.LEFT: + start = new Point(0, BodySize.Y); + inc = new Point(0, -64); + total = (BodySize.Y + 63) / 64; + lastRect = new Rectangle(0, 0, 32, BodySize.Y % 64); + rotate = (float)(Math.PI); + break; + default: + start = new Point(0, 0); + inc = new Point(64, 0); + total = (int)Math.Ceiling(BodySize.X / 64f); + lastRect = new Rectangle(0, 0, 32, BodySize.X % 64); + rotate = (float)(Math.PI*3 / 2); + break; + } + if (lastRect.Width == 0) lastRect.Width = 64; + if (lastRect.Height == 0) lastRect.Height = 64; + for (int i=0; i() { { "ScaleX", 1.0f }, { "ScaleY", 1.0f } }, TweenElastic.EaseOut); + } + else + { + //hover (get slightly bigger) + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "ScaleX", 1.1f }, { "ScaleY", 1.1f } }, TweenQuad.EaseOut); + } + } + else if (CurrentFrame == 0) + { + //return to normal size + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "ScaleX", 1.0f }, { "ScaleY", 1.0f } }, TweenQuad.EaseOut); + } else if (CurrentFrame == 1) + { + //down (get smaller) + DownTime = 0; + GameFacade.Screens.Tween.To(this, 0.2f, new Dictionary() { { "ScaleX", 0.8f }, { "ScaleY", 0.8f } }, TweenQuad.EaseOut); + } else + { + ScaleX = ScaleY = 1; //disabled + } + LastState = CurrentFrame; + } + if (CurrentFrame != 1 && DownTime < 5) DownTime++; + } + + public override void Draw(UISpriteBatch SBatch) + { + DrawLocalTexture(SBatch, Texture, new Vector2(Texture.Width, Texture.Height) / -2); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIInteraction.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIInteraction.cs new file mode 100644 index 0000000..c81bc1f --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIInteraction.cs @@ -0,0 +1,145 @@ +/* +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Framework.Parser; +using FSO.Client.UI.Model; +using FSO.Common.Rendering.Framework.Model; +using FSO.Common.Rendering.Framework.IO; +using FSO.Client.Utils; +using FSO.SimAntics; +using FSO.Common.Utils; +using FSO.Client.UI.Controls; +using Simitone.Client.UI.Panels; +using FSO.Client; +using FSO.HIT; +using FSO.Content; + +namespace Simitone.Client.UI.Controls +{ + /// + /// Used to display an interaction. Will eventually have all features like the timer, big huge red x support for cancel etc. + /// + public class UIInteraction : UIContainer + { + public Texture2D Icon; + private UITooltipHandler m_TooltipHandler; + private Texture2D Background; + private Texture2D Overlay; + private Texture2D Rim; + private bool Active; + private UIMouseEventRef ClickHandler; + public event ButtonClickDelegate OnMouseEvent; + public delegate void InteractionResultDelegate(UIElement me, bool accepted); + public event InteractionResultDelegate OnInteractionResult; + public UIIQTrackEntry ParentEntry; + + public UIButton AcceptButton; + public UIButton DeclineButton; + + public float OverlayScale; + public float RimScale; + public bool Dead; + + public void SetCancelled() + { + OverlayScale = 2f; + Overlay = Content.Get().CustomUI.Get("int_cancel.png").Get(GameFacade.GraphicsDevice); + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "OverlayScale", 1f }}, TweenQuad.EaseOut); + } + + public void SetActive(bool active) + { + if (active) + { + Rim = Content.Get().CustomUI.Get("int_big_sel.png").Get(GameFacade.GraphicsDevice); + Background = Content.Get().CustomUI.Get("int_big_bg.png").Get(GameFacade.GraphicsDevice); + if (!Active) + { + ClickHandler.Region = new Rectangle(-55, -55, 110, 110); + ScaleX = ScaleY = 0.5f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "ScaleX", 1f }, { "ScaleY", 1f } }, TweenQuad.EaseOut); + + RimScale = 2f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "RimScale", 1f } }, TweenQuad.EaseOut); + } + } + else + { + Rim = null; + Background = Content.Get().CustomUI.Get("int_small_bg.png").Get(GameFacade.GraphicsDevice); + if (Active) + { + ClickHandler.Region = new Rectangle(-23, -23, 46, 46); + ScaleX = ScaleY = 2f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "ScaleX", 1f }, { "ScaleY", 1f } }, TweenQuad.EaseOut); + } + } + this.Active = active; + } + + public UIInteraction(bool Active) + { + ClickHandler = ListenForMouse(new Rectangle(-23, -23, 46, 46), new UIMouseEvent(MouseEvt)); + SetActive(Active); + m_TooltipHandler = UIUtils.GiveTooltip(this); + } + + + public void Kill() + { + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Y", -60f } }, TweenQuad.EaseIn); + GameThread.SetTimeout(() => Parent.Remove(this), 300); + Dead = true; + } + + /* + actionfaceselection = 0x1B200000001, + actionhappy = 0x1B300000001, + actionmad = 0x1B400000001, + actionneutral = 0x1B500000001, + actionsad = 0x1B600000001, + */ + + public void UpdateInteractionResult(sbyte result) + { + return; + } + + private void MouseEvt(UIMouseEventType type, UpdateState state) + { + if (Dead) return; + if (type == UIMouseEventType.MouseDown) OnMouseEvent(this); //pass to parents to handle + } + + public override void Draw(UISpriteBatch batch) + { + base.Draw(batch); + DrawLocalTexture(batch, Background, null, new Vector2(-Background.Width, -Background.Height)/2, Vector2.One, new Color(104, 164, 184, 255)); + var iconSize = (Active) ? 74f : 37f; + if (Icon != null) + { + if (Icon.Width/(float)Icon.Height < 1.1f) + { + DrawLocalTexture(batch, Icon, new Rectangle(0, 0, Icon.Width, Icon.Height), new Vector2(iconSize/-2, iconSize / -2), new Vector2(iconSize / Icon.Width, iconSize / Icon.Height)); + } + else DrawLocalTexture(batch, Icon, new Rectangle(0, 0, Icon.Width / 2, Icon.Height), new Vector2(iconSize / -2, iconSize / -2), new Vector2(iconSize / Icon.Height, iconSize / Icon.Height)); + } + if (Overlay != null) DrawLocalTexture(batch, Overlay, null, new Vector2(Overlay.Width, Overlay.Height) * (OverlayScale/-2), new Vector2(OverlayScale), Color.White * (2 - OverlayScale)); + if (Rim != null) DrawLocalTexture(batch, Rim, null, new Vector2(Rim.Width, Rim.Height) * (RimScale / -2), new Vector2(RimScale), Color.Yellow * (2-RimScale)); + } + + public override Rectangle GetBounds() + { + return new Rectangle(0, 0, ClickHandler.Region.Width, ClickHandler.Region.Height); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UILiveButton.cs b/Client/Simitone/Simitone.Client/UI/Controls/UILiveButton.cs new file mode 100644 index 0000000..c40fecb --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UILiveButton.cs @@ -0,0 +1,71 @@ +using FSO.Client; +using FSO.Content; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Client.UI.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using FSO.Common.Rendering.Framework.Model; +using Simitone.Client.UI.Screens; +using FSO.SimAntics; +using Simitone.Client.UI.Model; + +namespace Simitone.Client.UI.Controls +{ + public class UILiveButton : UIElasticButton + { + public float MotiveLevel; //-1 to 1; + private Texture2D PlumbPlus; + private Texture2D PlumbNeg; + private TS1GameScreen Game; + + private Texture2D AvatarHead; + private Texture2D SwitchIcon; + public bool Switching; + private VMAvatar Avatar; + + public UILiveButton(TS1GameScreen screen) : base(Content.Get().CustomUI.Get("plumb_bg.png").Get(GameFacade.GraphicsDevice)) + { + var ui = Content.Get().CustomUI; + PlumbPlus = ui.Get("plumb_plus.png").Get(GameFacade.GraphicsDevice); + PlumbNeg = ui.Get("plumb_neg.png").Get(GameFacade.GraphicsDevice); + SwitchIcon = ui.Get("mode_live.png").Get(GameFacade.GraphicsDevice); + Game = screen; + } + + public override void Update(UpdateState state) + { + base.Update(state); + var sel = Game.SelectedAvatar; + MotiveLevel = (sel?.GetMotiveData(FSO.SimAntics.Model.VMMotive.Mood) ?? 0) / 100f; + + if (Avatar != sel) + { + Avatar = sel; + AvatarHead = (Avatar == null)?null:UIIconCache.GenHeadTex(Avatar); + } + } + + public override void Draw(UISpriteBatch SBatch) + { + if (Switching) + { + DrawLocalTexture(SBatch, SwitchIcon, new Vector2(SwitchIcon.Width, SwitchIcon.Height) / -2); + } + else + { + base.Draw(SBatch); + DrawLocalTexture(SBatch, PlumbPlus, new Rectangle(0, 0, (int)(Math.Round(Math.Max(0, MotiveLevel * 22))), PlumbPlus.Height), new Vector2(30, -30), Vector2.One); + int negWidth = (int)Math.Round(Math.Max(0, MotiveLevel * -22)); + DrawLocalTexture(SBatch, PlumbNeg, new Rectangle(22 - negWidth, 0, negWidth, PlumbPlus.Height), new Vector2(-30 - negWidth, -30), Vector2.One); + if (AvatarHead != null) + { + DrawLocalTexture(SBatch, AvatarHead, new Vector2(AvatarHead.Width / -2, AvatarHead.Height / -2)); + } + } + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIMobileDialog.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIMobileDialog.cs new file mode 100644 index 0000000..3698c91 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIMobileDialog.cs @@ -0,0 +1,110 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.Client.UI.Framework; +using FSO.Content; +using Microsoft.Xna.Framework; +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.Controls +{ + public class UIMobileDialog : UIContainer + { + public UIDiagonalStripe BackStripe; + public UIDiagonalStripe FrontStripe; + + private UILabel TitleLabel; + private UIImage TitleBg; + + public string Caption + { + set { TitleLabel.Caption = value; } + } + + public int Width; + public int Height; + public int ScrHeight; + + private int BaseY + { + get { return (int)FrontStripe.Y; } + } + + protected bool Closing; + + private float _i; + public float InterpolatedAnimation + { + set + { + Position = new Vector2(0, (ScrHeight - Height) / 2); + BackStripe.X = (Closing)?0:(Width * (1 - value)); + BackStripe.BodySize = new Point((int)(value * Width), ScrHeight); + BackStripe.Y = -Position.Y; + + var t2 = Math.Max(0, value - 0.2f) / 0.8f; + FrontStripe.X = (Closing)?(Width * (1 - t2)):0; + FrontStripe.BodySize = new Point((int)(t2 * Width), Height); + + TitleBg.Y = 45 - 35 * t2; + TitleLabel.Y = 15; + TitleLabel.CaptionStyle.Color = UIStyle.Current.DialogTitle * t2; + TitleBg.SetSize(Width, 70 * t2); + _i = value; + if (value == 0f && Closing) UIScreen.RemoveDialog(this); + } + + get + { + return _i; + } + } + + public UIMobileDialog() : base() + { + Width = GameFacade.Screens.CurrentUIScreen.ScreenWidth; + ScrHeight = GameFacade.Screens.CurrentUIScreen.ScreenHeight; + + BackStripe = new UIDiagonalStripe(new Point(), UIDiagonalStripeSide.LEFT, new Color(0, 70, 140) * 0.33f); + Add(BackStripe); + FrontStripe = new UIDiagonalStripe(new Point(), UIDiagonalStripeSide.RIGHT, UIStyle.Current.DialogBg); + Add(FrontStripe); + + TitleBg = new UIImage(Content.Get().CustomUI.Get("dialog_title_grad.png").Get(GameFacade.GraphicsDevice)); + TitleBg.SetSize(Width, 70); + Add(TitleBg); + + TitleLabel = new UILabel(); + TitleLabel.X = 50; + TitleLabel.CaptionStyle = TitleLabel.CaptionStyle.Clone(); + TitleLabel.CaptionStyle.Size = 37; + TitleLabel.CaptionStyle.Color = UIStyle.Current.DialogTitle; + TitleLabel.Alignment = TextAlignment.Top | TextAlignment.Left; + Add(TitleLabel); + + InterpolatedAnimation = 0f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "InterpolatedAnimation", 1f} }, TweenQuad.EaseOut); + } + + public void Close() + { + if (!Closing) + { + Closing = true; + BackStripe.DiagSide = UIDiagonalStripeSide.RIGHT; + FrontStripe.DiagSide = UIDiagonalStripeSide.LEFT; + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "InterpolatedAnimation", 0f } }, TweenQuad.EaseIn); + } + } + + public void SetHeight(int height) + { + Height = height; + InterpolatedAnimation = _i; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UISkillDisplay.cs b/Client/Simitone/Simitone.Client/UI/Controls/UISkillDisplay.cs new file mode 100644 index 0000000..c464a6e --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UISkillDisplay.cs @@ -0,0 +1,62 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Content; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Simitone.Client.UI.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Common.Rendering.Framework.Model; + +namespace Simitone.Client.UI.Controls +{ + public class UISkillDisplay : UIElement + { + public Texture2D Skill; + + public UISkillDisplay() : base() + { + Skill = Content.Get().CustomUI.Get("skill.png").Get(GameFacade.GraphicsDevice); + } + + private int _Value; + public int Value { + get + { + return _Value; + } + set + { + if (value != _Value) Invalidate(); + _Value = value; + } + } + private int _Needed; + public int Needed + { + get + { + return _Needed; + } + set + { + if (value != _Needed) Invalidate(); + _Needed = value; + } + } + + public override void Draw(UISpriteBatch batch) + { + for (int i = 0; i < 10; i++) { + Color color; + if (i < Value) color = UIStyle.Current.SkillActive; + else if (i < Needed) color = UIStyle.Current.SkillNeeded; + else color = UIStyle.Current.SkillInactive; + DrawLocalTexture(batch, Skill, null, new Microsoft.Xna.Framework.Vector2(i * 8, 0), Vector2.One, color); + } + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIStencilButton.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIStencilButton.cs new file mode 100644 index 0000000..ee46190 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIStencilButton.cs @@ -0,0 +1,61 @@ +using FSO.Client.UI.Controls; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Client.UI.Framework; +using Microsoft.Xna.Framework; +using Simitone.Client.UI.Model; + +namespace Simitone.Client.UI.Controls +{ + public class UIStencilButton : UIButton + { + public Color Color = UIStyle.Current.BtnNormal; + public Color ActiveColor = UIStyle.Current.BtnActive; + public Color HoverColor = Color.Lerp(UIStyle.Current.BtnNormal, UIStyle.Current.BtnActive, 0.5f); + public Color DisabledColor = new Color(128, 128, 128, 255); + public bool Shadow; + public float Alpha { get; set; } + + public UIStencilButton(Texture2D tex) : base(tex) + { + Alpha = 1f; + ImageStates = 1; + } + + public override void Draw(UISpriteBatch SBatch) + { + if (!Visible) return; + var frame = CurrentFrame; + if (Disabled) + { + frame = 3; + } + if (Selected) + { + frame = 1; + } + if (ForceState > -1) frame = ForceState; + frame = Math.Min(3, frame); + + Color color; + switch (frame) + { + case 1: + color = ActiveColor; break; + case 2: + color = HoverColor; break; + case 3: + color = DisabledColor; break; + default: + color = Color; break; + } + if (Shadow) + DrawLocalTexture(SBatch, Texture, null, new Vector2(3f, 3f), Vector2.One, Color.Black * 0.25f * Alpha); + DrawLocalTexture(SBatch, Texture, null, Vector2.Zero, Vector2.One, color * Alpha); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UITouchScroll.cs b/Client/Simitone/Simitone.Client/UI/Controls/UITouchScroll.cs new file mode 100644 index 0000000..231fd5d --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UITouchScroll.cs @@ -0,0 +1,192 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Content; +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; +using FSO.Common.Rendering.Framework.Model; +using FSO.Common.Rendering.Framework.IO; + +namespace Simitone.Client.UI.Controls +{ + public class UITouchScroll : UICachedContainer + { + public int ItemWidth; + public Texture2D ScrollEdgeL; + public Texture2D ScrollEdgeR; + + private UIMouseEventRef HitTest; + + private float Scroll; + private float ScrollVelocity; + + private Func LengthProvider; + private Func ElemProvider; + + public UITouchScroll(Func lengthProvider, Func elemProvider) : base() + { + var ui = Content.Get().CustomUI; + ScrollEdgeL = ui.Get("scroll_edge_l.png").Get(GameFacade.GraphicsDevice); + ScrollEdgeR = ui.Get("scroll_edge_r.png").Get(GameFacade.GraphicsDevice); + HitTest = ListenForMouse(new Rectangle(0, 0, (int)Size.X, (int)Size.Y), new UIMouseEvent(MouseEvents)); + + LengthProvider = lengthProvider; + ElemProvider = elemProvider; + } + + private int MouseDownTime; + private int MouseDownID = -1; + private Point MouseDownAt; + private bool InScroll; + private List ScrollVelocityHistory = new List(); + + public void MouseEvents(UIMouseEventType type, UpdateState state) + { + switch (type) + { + case UIMouseEventType.MouseDown: + MouseDownID = state.CurrentMouseID; + MouseDownTime = 0; + MouseDownAt = state.MouseState.Position; + InScroll = false; + ScrollVelocity = 0; + break; + case UIMouseEventType.MouseUp: + if (!InScroll) + { + Select(MouseDownAt); + } + else + { + //calculate scroll velocity + if (ScrollVelocityHistory.Count > 1) + { + int total = 0; + ScrollVelocity = 0f; + for (int i = 1; i < ScrollVelocityHistory.Count; i++) + { + total++; + ScrollVelocity += ScrollVelocityHistory[i]; + } + ScrollVelocity /= total; + } + ScrollVelocityHistory.Clear(); + } + + InScroll = false; + MouseDownID = -1; + break; + } + } + + public void Select(Point at) + { + var item = (int)(at.X + Scroll) / ItemWidth; + + } + + public UITSContainer GetOrPrepare(int id) + { + var item = Children.Where(x => (x as UITSContainer)?.ItemID == id).FirstOrDefault() as UITSContainer; + if (item == null) + { + item = ElemProvider(id); + item.Visible = false; + item.ItemID = id; + Add(item); + } + return item; + } + + public override void Update(UpdateState state) + { + base.Update(state); + var sizeRect = new Rectangle(0, 0, (int)Size.X, (int)Size.Y); + if (!sizeRect.Equals(HitTest.Region)) + { + HitTest.Region = sizeRect; + } + + var length = LengthProvider(); + + //perform scroll and input management. + + if (MouseDownID != -1) + { + var lastMouse = state.MouseStates.FirstOrDefault(x => x.ID == MouseDownID); + if (lastMouse != null) + { + var pos = lastMouse.MouseState.Position; + if (!InScroll) + { + if (Math.Abs((pos - MouseDownAt).X) > 25) InScroll = true; + } + if (InScroll) + { + ScrollVelocity = -(pos - MouseDownAt).X; + MouseDownAt = pos; + } + } + } + + ScrollVelocityHistory.Insert(0, ScrollVelocity); + if (ScrollVelocityHistory.Count > 5) ScrollVelocityHistory.RemoveAt(ScrollVelocityHistory.Count - 1); + + Scroll += ScrollVelocity; + ScrollVelocity *= 0.9f; + Scroll = Math.Max(0, Math.Min(length * ItemWidth - Size.X, Scroll)); + + //update children positions. + //delete ones that are not + + var untouched = new HashSet(Children); + + var b = (int)(Scroll / ItemWidth); + var e = b + (Size.X + (ItemWidth - 1)) / ItemWidth; + for (int i=b; i= length) break; + var item = GetOrPrepare(i); + untouched.Remove(item); + item.X = i * ItemWidth - Scroll; + item.Visible = true; + } + + foreach (var child in untouched) + { + Children.Remove(child); + } + + Invalidate(); + } + + public override void Draw(UISpriteBatch batch) + { + base.Draw(batch); + DrawLocalTexture(batch, ScrollEdgeL, new Vector2(0, Size.Y / 2 - 64)); + DrawLocalTexture(batch, ScrollEdgeR, new Vector2(Size.X-15, Size.Y / 2 - 64)); + } + + public void Reset() + { + var children = new List(Children); + foreach (var child in children) + { + Remove(child); + } + } + } + + public class UITSContainer : UIContainer + { + public int ItemID; + public virtual void Selected() + { + + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UITwoStateButton.cs b/Client/Simitone/Simitone.Client/UI/Controls/UITwoStateButton.cs new file mode 100644 index 0000000..9d7e793 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UITwoStateButton.cs @@ -0,0 +1,18 @@ +using FSO.Client.UI.Controls; +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.Controls +{ + public class UITwoStateButton : UIButton + { + public UITwoStateButton(Texture2D tex) : base(tex) + { + ImageStates = 2; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Controls/UIValueBar.cs b/Client/Simitone/Simitone.Client/UI/Controls/UIValueBar.cs new file mode 100644 index 0000000..35ae642 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Controls/UIValueBar.cs @@ -0,0 +1,119 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Content; +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; +using FSO.Common.Rendering.Framework.Model; + +namespace Simitone.Client.UI.Controls +{ + public class UIValueBar : UIElement + { + public Texture2D BarBase; + public int Width; + public float Value; + + public UIValueBar (Texture2D tex) + { + BarBase = tex; + } + + public void DrawSlice(UISpriteBatch batch, int width, Color col, int drawFrom) + { + var w = BarBase.Width / 3; + if (width < w * 2) + { + if (drawFrom <= 0) DrawLocalTexture(batch, BarBase, new Rectangle(0, 0, width / 2, BarBase.Height), Vector2.Zero, Vector2.One, col); + DrawLocalTexture(batch, BarBase, new Rectangle(BarBase.Width-((width + 1) / 2), 0, (width+1) / 2, BarBase.Height), new Vector2(width/2, 0), Vector2.One, col); + } else + { + if (drawFrom <= 0) DrawLocalTexture(batch, BarBase, new Rectangle(0, 0, w, BarBase.Height), Vector2.Zero, Vector2.One, col); + if (drawFrom <= 1) DrawLocalTexture(batch, BarBase, new Rectangle(w, 0, w, BarBase.Height), new Vector2(w, 0), new Vector2((float)(width-2*w)/w, 1), col); + DrawLocalTexture(batch, BarBase, new Rectangle(w*2, 0, w, BarBase.Height), new Vector2(width - w, 0), Vector2.One, col); + } + } + + public override void Draw(UISpriteBatch batch) + { + var p = Value; + Color barcol = new Color((byte)(57 * (1 - p)), (byte)(213 * p + 97 * (1 - p)), (byte)(49 * p + 90 * (1 - p))); + Color bgcol = new Color((byte)(57 * p + 214 * (1 - p)), (byte)(97 * p), (byte)(90 * p)); + + DrawSlice(batch, Width, bgcol, 0); + + var activeWidth = (int)Math.Round(p * Width); + DrawSlice(batch, activeWidth, Color.White, 2); + DrawSlice(batch, activeWidth-2, barcol, 0); + } + } + + public class UIMotiveBar : UIValueBar + { + public int TargetArrow; + public int Arrow; + public int MotiveValue; + public int OldMotiveValue = -200; + private Queue ChangeBuffer = new Queue(); + + public Texture2D ArrowGfx; + + public float ArrowCycle; + + public UIMotiveBar() : base(Content.Get().CustomUI.Get("motive_bg.png").Get(GameFacade.GraphicsDevice)) + { + ArrowGfx = Content.Get().CustomUI.Get("motive_arrow.png").Get(GameFacade.GraphicsDevice); + Width = 150; + } + + public override void Update(UpdateState state) + { + base.Update(state); + + if (OldMotiveValue != -200) ChangeBuffer.Enqueue(MotiveValue- OldMotiveValue); + OldMotiveValue = MotiveValue; + + if (ChangeBuffer.Count > 240) ChangeBuffer.Dequeue(); + + int sum = 0; + foreach (var c in ChangeBuffer) sum += c; + + var diff = sum / 2.5; + if (diff < 0) diff = Math.Floor(diff); + else if (diff > 0) diff = Math.Ceiling(diff); + TargetArrow = Math.Max(Math.Min((int)diff, 5), -5) * 60; + + if (Arrow > TargetArrow) Arrow--; + if (Arrow < TargetArrow) Arrow++; + + Value = (MotiveValue+100) / 200f; + + ArrowCycle += Arrow / 240f; + if (ArrowCycle < 0) ArrowCycle += 14f; + ArrowCycle %= 14f; + } + + public override void Draw(UISpriteBatch batch) + { + if (!Visible) return; + base.Draw(batch); + var w = BarBase.Width / 3; + var spanw = (int)(Width * Value) - w * 2; + var arrows = spanw / 14; + var xStart = (Arrow > 0) ? 0 : (spanw); + var dir = (Arrow > 0) ? 1 : -1; + for (int i=0; i + /// Caches icons for objects missing them, eg. heads, some catalog objects.. + /// + public static class UIIconCache + { + //indexed as mesh:texture + private static Dictionary AvatarHeadCache = new Dictionary(); + + public static Texture2D GetObject(VMEntity obj) + { + if (obj is VMAvatar) + { + var ava = (VMAvatar)obj; + var id = ava.HeadOutfit.Name +":"+ ava.HeadOutfit.OftData.TS1TextureID; + + Texture2D result = null; + if (!AvatarHeadCache.TryGetValue(id, out result)) + { + result = GenHeadTex(ava); + AvatarHeadCache[id] = result; + } + return result; + } + else if (obj is VMGameObject) + { + if (obj.Object.OBJ.GUID == 0x000007C4) return Content.Get().CustomUI.Get("int_gohere.png").Get(GameFacade.GraphicsDevice); + else return obj.GetIcon(GameFacade.GraphicsDevice, 0); + } + return null; + } + + public static Texture2D GenHeadTex(VMAvatar ava) + { + var m_Head = new SimAvatar(ava.Avatar); //talk about confusing... + m_Head.StripAllButHead(); + + + var HeadCamera = new BasicCamera(GameFacade.GraphicsDevice, new Vector3(0.0f, 7.0f, -17.0f), Vector3.Zero, Vector3.Up); + + var pos2 = m_Head.Skeleton.GetBone("HEAD").AbsolutePosition; + pos2.Y += 0.1f; + HeadCamera.Position = new Vector3(0, pos2.Y, 12.5f); + HeadCamera.Target = pos2; + HeadCamera.ProjectionOrigin = new Vector2(74/2, 74/2); + + var HeadScene = new _3DTargetScene(GameFacade.GraphicsDevice, HeadCamera, new Point(74, 74), (GlobalSettings.Default.AntiAlias) ? 8 : 0); + HeadScene.ID = "UIPieMenuHead"; + + m_Head.Scene = HeadScene; + m_Head.Scale = new Vector3(1f); + + HeadCamera.Zoom = 13f; + + //rotate camera, similar to pie menu + + double xdir = Math.Atan(50 / 100.0); + double ydir = Math.Atan(-50 / 100.0); + + Vector3 off = new Vector3(0, 0, 13.5f); + Matrix mat = Microsoft.Xna.Framework.Matrix.CreateRotationY((float)xdir) * Microsoft.Xna.Framework.Matrix.CreateRotationX((float)ydir); + + HeadCamera.Position = new Vector3(0, pos2.Y, 0) + Vector3.Transform(off, mat); + + if (ava.IsPet) + { + HeadCamera.Zoom *= 1.5f; + } + //end rotate camera + + HeadScene.Initialize(GameFacade.Scenes); + HeadScene.Add(m_Head); + + HeadScene.Draw(GameFacade.GraphicsDevice); + return HeadScene.Target; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Model/UIStyle.cs b/Client/Simitone/Simitone.Client/UI/Model/UIStyle.cs new file mode 100644 index 0000000..e25c545 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Model/UIStyle.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Model +{ + public class UIStyle + { + public static UIStyle DARK = new UIStyle(); + + public static UIStyle Current = DARK; + + + //class definition + + public Color Bg = Color.Black * 0.75f; + public Color TitleBg = Color.Black * 0.85f; + + public Color BtnNormal = Color.White; + public Color BtnActive = new Color(0, 255, 128, 255); + public Color BtnDisable = new Color(128, 128, 128, 255); + + public Color ActiveSelection = Color.Yellow; + + public Color Text = Color.White; + public Color SecondaryText = new Color(0, 255, 128, 255); + + public Color DialogBg = Color.Black * 0.8f; + public Color DialogText = Color.White; + public Color DialogTitle = Color.Black; + + public Color BtnTxt = new Color(0, 31, 63); + public Color GreenBtnTxt = new Color(0, 63, 16); + public Color BtnTxtShadow = Color.White * 0.5f; + + public Color PosMoney = new Color(0, 255, 128, 255); + public Color NegMoney = new Color(255, 128, 0, 255); + + 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); + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIInventorySubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIInventorySubpanel.cs new file mode 100644 index 0000000..d5886f4 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIInventorySubpanel.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Simitone.Client.UI.Screens; +using FSO.Content; +using FSO.SimAntics.Model; +using FSO.Files.Formats.IFF.Chunks; +using FSO.Common.Rendering.Framework.Model; +using Simitone.Client.UI.Controls; +using Microsoft.Xna.Framework; +using FSO.SimAntics; +using Microsoft.Xna.Framework.Graphics; +using FSO.LotView.Model; +using FSO.Client; +using FSO.Client.UI.Framework; +using Simitone.Client.UI.Model; +using FSO.Client.UI.Controls; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UIInventorySubpanel : UISubpanel + { + public List Items = new List(); + public UITouchScroll ScrollView; + public int CatSort = -1; + + public UITwoStateButton MagicButton; + public UITwoStateButton IngButton; + public UITwoStateButton OtherButton; + + public HashSet HiddenCats = new HashSet() + { + //note: section 2 is hidden. guids 7 and 8 seem to contain downtown time in count. + 2, 6, 7, 8 + }; + + public UIInventorySubpanel(TS1GameScreen game) : base(game) + { + var ui = Content.Get().CustomUI; + ScrollView = new UITouchScroll(() => { return Items?.Count ?? 0; }, DisplayProvider); + ScrollView.X = 148; + ScrollView.ItemWidth = 90; + ScrollView.Size = new Vector2(582, 128); + Add(ScrollView); + + MagicButton = new UITwoStateButton(ui.Get("inv_mag_btn.png").Get(GameFacade.GraphicsDevice)); + MagicButton.Position = new Vector2(21, 9); + MagicButton.OnButtonClick += (b) => { ChangeCat(7); }; + Add(MagicButton); + IngButton = new UITwoStateButton(ui.Get("inv_ing_btn.png").Get(GameFacade.GraphicsDevice)); + IngButton.Position = new Vector2(81, 9); + IngButton.OnButtonClick += (b) => { ChangeCat(8); }; + Add(IngButton); + OtherButton = new UITwoStateButton(ui.Get("inv_other_btn.png").Get(GameFacade.GraphicsDevice)); + OtherButton.Position = new Vector2(21, 69); + OtherButton.OnButtonClick += (b) => { ChangeCat(-1); }; + Add(OtherButton); + + ChangeCat(-1); + } + + public void ChangeCat(int cat) + { + MagicButton.Selected = cat == 7; + IngButton.Selected = cat == 8; + OtherButton.Selected = cat == -1; + CatSort = cat; + } + + public UITSContainer DisplayProvider(int index) + { + return new UIInventoryDisplay(Items[index]); + } + + public override void Update(UpdateState state) + { + base.Update(state); + UpdateInventoryView(); + Invalidate(); + } + + public void UpdateInventoryView() + { + var sel = Game.SelectedAvatar; + 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(); + + bool difference = false; + if (inventory.Count == Items.Count) + { + for (int i = 0; i < inventory.Count; i++) + { + var i1 = inventory[i]; var i2 = Items[i]; + if (i1.Count != i2.Count || i1.GUID != i2.GUID || i1.Type != i2.Type) + { + difference = true; break; + } + } + } else + { + difference = true; + } + + if (difference) + { + Items.Clear(); + foreach (var item in inventory) + { + Items.Add(item.Clone()); + } + ScrollView.Reset(); + } + } + } + + public class UIInventoryDisplay : UITSContainer { + private UILabel NameLabel; + private UILabel CountLabel; + private Texture2D ItemBg; + private Texture2D Item; + public UIInventoryDisplay(InventoryItem item) : base() + { + NameLabel = new UILabel(); + NameLabel.CaptionStyle = NameLabel.CaptionStyle.Clone(); + NameLabel.CaptionStyle.Color = UIStyle.Current.Text; + NameLabel.CaptionStyle.Size = 10; + NameLabel.Wrapped = true; + NameLabel.Size = new Vector2(80, 33); + NameLabel.Position = new Vector2(5, 5); + NameLabel.Alignment = TextAlignment.Middle | TextAlignment.Center; + Add(NameLabel); + + CountLabel = new UILabel(); + CountLabel.CaptionStyle = NameLabel.CaptionStyle.Clone(); + CountLabel.CaptionStyle.Size = 15; + CountLabel.Size = new Vector2(80, 30); + CountLabel.Position = new Vector2(5, 90); + CountLabel.Alignment = TextAlignment.Middle | TextAlignment.Center; + Add(CountLabel); + + ItemBg = Content.Get().CustomUI.Get("inv_item.png").Get(GameFacade.GraphicsDevice); + + var obj = Content.Get().WorldObjects.Get(item.GUID); + if (obj != null) + { + Item = obj.Resource.Get(obj.OBJ.CatalogStringsID)?.GetTexture(GameFacade.GraphicsDevice); + NameLabel.Caption = obj.Resource.Get(obj.OBJ.CatalogStringsID)?.GetString(0) ?? obj.OBJ.ChunkLabel; + CountLabel.Caption = item.Count.ToString(); + } + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, ItemBg, null, new Vector2(20, 40), Vector2.One, new Color(104, 164, 184, 255)); + + if (Item != null) + { + DrawLocalTexture(batch, Item, new Rectangle(0, 0, Item.Width / 2, Item.Height), new Vector2(45 + 42 / -2, 65 + 42 / -2), new Vector2(42f / Item.Height, 42f / Item.Height)); + } + + base.Draw(batch); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIJobSubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIJobSubpanel.cs new file mode 100644 index 0000000..cffd1c4 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIJobSubpanel.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Simitone.Client.UI.Screens; +using Simitone.Client.UI.Model; +using Simitone.Client.UI.Controls; +using FSO.Client.UI.Controls; +using Microsoft.Xna.Framework; +using FSO.Content; +using FSO.Files.Formats.IFF.Chunks; +using FSO.SimAntics.Model; +using FSO.Common.Rendering.Framework.Model; +using FSO.Client; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UIJobSubpanel : UISubpanel + { + public UILabel PerformanceTitle; + public UIMotiveBar PerformanceBar; + public UILabel JobTitle; + public UILabel SalaryTitle; + public UITwoStateButton CareerButton; + + private JobLevel LastJobLevel; + + private UISkillDisplay[] Skills; + private string[] SkillNames = new string[] + { + "Cooking", + "Mechanical", + "Charisma", + "Body", + "Logic", + "Creativity" + }; + + private VMPersonDataVariable[] SkillInd = new VMPersonDataVariable[] + { + VMPersonDataVariable.CookingSkill, + VMPersonDataVariable.MechanicalSkill, + VMPersonDataVariable.CharismaSkill, + VMPersonDataVariable.BodySkill, + VMPersonDataVariable.LogicSkill, + VMPersonDataVariable.CreativitySkill + }; + + public UIJobSubpanel(TS1GameScreen game) : base(game) + { + PerformanceTitle = new UILabel(); + PerformanceTitle.Caption = "Performance"; + PerformanceTitle.Position = new Vector2(79, 16); + InitLabel(PerformanceTitle); + + PerformanceBar = new UIMotiveBar(); + PerformanceBar.Position = new Vector2(79, 41); + DynamicOverlay.Add(PerformanceBar); + + JobTitle = new UILabel(); + JobTitle.Caption = "Subway Musician"; + JobTitle.Position = new Vector2(18, 71); + InitLabel(JobTitle); + + SalaryTitle = new UILabel(); + SalaryTitle.Caption = "Salary: §90"; + SalaryTitle.Position = new Vector2(18, 94); + InitLabel(SalaryTitle); + SalaryTitle.CaptionStyle.Color = UIStyle.Current.BtnActive; + + CareerButton = new UITwoStateButton(Content.Get().CustomUI.Get("blank_blue.png").Get(GameFacade.GraphicsDevice)); + CareerButton.Position = new Vector2(20, 15); + Add(CareerButton); + + Skills = new UISkillDisplay[6]; + for (int i=0; i<6; i++) + { + Skills[i] = new UISkillDisplay(); + Skills[i].Position = new Vector2(334 + (i%3)*140, 35 + 60*(i/3)); + Add(Skills[i]); + + var name = new UILabel(); + name.Caption = SkillNames[i]; + name.Position = new Vector2(332 + (i % 3) * 140, 11 + 60 * (i / 3)); + InitLabel(name); + } + } + + public int LastPerformance; + + public override void Update(UpdateState state) + { + base.Update(state); + + if (Opacity < 1) + { + if (DynamicOverlay.GetChildren().Count > 0) + { + DynamicOverlay.Remove(PerformanceBar); + Add(PerformanceBar); + } + } else + { + if (DynamicOverlay.GetChildren().Count == 0) + { + Remove(PerformanceBar); + DynamicOverlay.Add(PerformanceBar); + } + } + var sel = Game.SelectedAvatar; + if (sel == null) return; + var type = sel.GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.JobType); + var level = sel.GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.JobPromotionLevel); + var performance = sel.GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.JobPerformance); + + var job = Content.Get().Jobs.GetJob((ushort)type); + if (job == null) + { + if (LastPerformance != -200) + { + JobTitle.Caption = "Unemployed"; + SalaryTitle.Caption = ""; + PerformanceBar.Visible = false; + PerformanceTitle.Visible = false; + + LastJobLevel = null; + LastPerformance = -200; + } + } + else + { + var myLevel = job.JobLevels[level]; + + if (myLevel != LastJobLevel) + { + JobTitle.Caption = myLevel.JobName; + SalaryTitle.Caption = "Salary: §" + myLevel.Salary + " (" + ToTime(myLevel.StartTime) + "-" + ToTime(myLevel.EndTime) + ")"; + + LastJobLevel = myLevel; + } + + if (LastPerformance != performance) + { + PerformanceBar.Visible = true; + PerformanceTitle.Visible = true; + PerformanceBar.MotiveValue = performance; + LastPerformance = performance; + } + for (int i = 0; i < 6; i++) + Skills[i].Needed = myLevel.MinRequired[i + 1] / 100; + } + + for (int i = 0; i < 6; i++) + { + Skills[i].Value = sel.GetPersonData(SkillInd[i]) / 100; + } + } + + private string ToTime(int time) + { + return ((time > 12) ? (time - 12) : time) + ((time >= 12) ? "pm" : "am"); + } + + private void InitLabel(UILabel label) + { + label.CaptionStyle = label.CaptionStyle.Clone(); + label.CaptionStyle.Color = UIStyle.Current.Text; + label.CaptionStyle.Size = 15; + Add(label); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIMotiveSubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIMotiveSubpanel.cs new file mode 100644 index 0000000..64e28ff --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIMotiveSubpanel.cs @@ -0,0 +1,86 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.SimAntics.Model; +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; +using System.Text; +using System.Threading.Tasks; +using FSO.Common.Rendering.Framework.Model; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UIMotiveSubpanel : UISubpanel + { + public UIMotiveBar[] MotiveDisplays; + + public UIMotiveSubpanel(TS1GameScreen game) : base (game) + { + MotiveDisplays = new UIMotiveBar[8]; + for (int i=0; i<8; i++) + { + var d = new UIMotiveBar(); + d.Position = new Vector2(17 + (i%4)*180, 36+(i/4) * 60); + Add(d); + MotiveDisplays[i] = d; + + var l = new UILabel(); + l.CaptionStyle = l.CaptionStyle.Clone(); + l.CaptionStyle.Size = 15; + l.CaptionStyle.Color = UIStyle.Current.Text; + l.Alignment = FSO.Client.UI.Framework.TextAlignment.Bottom; + l.Size = new Vector2(1); + l.Position = new Vector2(17 + (i % 4) * 180, 30 + (i / 4) * 60); + l.Caption = GameFacade.Strings.GetString("f102", (i+1).ToString()); + Add(l); + } + + } + + public override void Update(UpdateState state) + { + UpdateMotives(); + base.Update(state); + if (Opacity < 1) + { + if (DynamicOverlay.GetChildren().Count > 0) + { + foreach (var m in MotiveDisplays) + { + DynamicOverlay.Remove(m); + Add(m); + } + } + Invalidate(); + } else + { + if (DynamicOverlay.GetChildren().Count == 0) + { + foreach (var m in MotiveDisplays) + { + Remove(m); + DynamicOverlay.Add(m); + Invalidate(); + } + } + } + } + + private void UpdateMotives() + { + if (Game.SelectedAvatar == null) return; + MotiveDisplays[0].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Hunger); + MotiveDisplays[1].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Comfort); + MotiveDisplays[2].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Hygiene); + MotiveDisplays[3].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Bladder); + MotiveDisplays[4].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Energy); + MotiveDisplays[5].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Fun); + MotiveDisplays[6].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Social); + MotiveDisplays[7].MotiveValue = Game.SelectedAvatar.GetMotiveData(VMMotive.Room); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIPersonalitySubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIPersonalitySubpanel.cs new file mode 100644 index 0000000..f0731e0 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIPersonalitySubpanel.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Simitone.Client.UI.Screens; +using Simitone.Client.UI.Model; +using Simitone.Client.UI.Controls; +using FSO.Client.UI.Controls; +using Microsoft.Xna.Framework; +using FSO.Content; +using FSO.Files.Formats.IFF.Chunks; +using FSO.SimAntics.Model; +using FSO.Common.Rendering.Framework.Model; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UIPersonalitySubpanel : UISubpanel + { + private JobLevel LastJobLevel; + + private UISkillDisplay[] Skills; + private string[] SkillNames = new string[] + { + "Neat", + "Outgoing", + "Active", + "Playful", + "Nice", + }; + + private VMPersonDataVariable[] SkillInd = new VMPersonDataVariable[] + { + VMPersonDataVariable.NeatPersonality, + VMPersonDataVariable.OutgoingPersonality, + VMPersonDataVariable.ActivePersonality, + VMPersonDataVariable.PlayfulPersonality, + VMPersonDataVariable.NicePersonality + }; + + public UIPersonalitySubpanel(TS1GameScreen game) : base(game) + { + Skills = new UISkillDisplay[5]; + for (int i=0; i<5; i++) + { + Skills[i] = new UISkillDisplay(); + Skills[i].Position = new Vector2(334 + (i%3)*140, 35 + 60*(i/3)); + Add(Skills[i]); + + var name = new UILabel(); + name.Caption = SkillNames[i]; + name.Position = new Vector2(332 + (i % 3) * 140, 11 + 60 * (i / 3)); + InitLabel(name); + } + } + + public override void Update(UpdateState state) + { + base.Update(state); + var sel = Game.SelectedAvatar; + if (sel == null) return; + for (int i = 0; i < 5; i++) + { + Skills[i].Value = sel.GetPersonData(SkillInd[i]) / 100; + } + } + + private void InitLabel(UILabel label) + { + label.CaptionStyle = label.CaptionStyle.Clone(); + label.CaptionStyle.Color = UIStyle.Current.Text; + label.CaptionStyle.Size = 15; + Add(label); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIRelationshipSubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIRelationshipSubpanel.cs new file mode 100644 index 0000000..93651d9 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UIRelationshipSubpanel.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Simitone.Client.UI.Screens; +using FSO.Content; +using FSO.SimAntics.Model; +using FSO.Files.Formats.IFF.Chunks; +using FSO.Common.Rendering.Framework.Model; +using Simitone.Client.UI.Controls; +using Microsoft.Xna.Framework; +using FSO.SimAntics; +using Microsoft.Xna.Framework.Graphics; +using FSO.LotView.Model; +using FSO.Client; +using FSO.Client.UI.Framework; +using Simitone.Client.UI.Model; +using FSO.Client.UI.Controls; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UIRelationshipSubpanel : UISubpanel + { + public List> Items = new List>(); + public UITouchScroll ScrollView; + public int RelSort = -1; + + public UITwoStateButton FriendButton; + public UITwoStateButton FamButton; + public UITwoStateButton AllButton; + public UITwoStateButton FameButton; + + public UIRelationshipSubpanel(TS1GameScreen game) : base(game) + { + var ui = Content.Get().CustomUI; + ScrollView = new UITouchScroll(() => { return Items?.Count ?? 0; }, DisplayProvider); + ScrollView.X = 148; + ScrollView.ItemWidth = 90; + ScrollView.Size = new Vector2(582, 128); + Add(ScrollView); + + FriendButton = new UITwoStateButton(ui.Get("rel_friend.png").Get(GameFacade.GraphicsDevice)); + FriendButton.Position = new Vector2(21, 9); + FriendButton.OnButtonClick += (b) => { ChangeCat(0); }; + Add(FriendButton); + FamButton = new UITwoStateButton(ui.Get("rel_fam.png").Get(GameFacade.GraphicsDevice)); + FamButton.Position = new Vector2(81, 9); + FamButton.OnButtonClick += (b) => { ChangeCat(1); }; + Add(FamButton); + AllButton = new UITwoStateButton(ui.Get("rel_all.png").Get(GameFacade.GraphicsDevice)); + AllButton.Position = new Vector2(21, 69); + AllButton.OnButtonClick += (b) => { ChangeCat(-1); }; + Add(AllButton); + FameButton = new UITwoStateButton(ui.Get("rel_fame.png").Get(GameFacade.GraphicsDevice)); + FameButton.Position = new Vector2(81, 69); + FameButton.OnButtonClick += (b) => { ChangeCat(2); }; + Add(FameButton); + + ChangeCat(-1); + } + + public void ChangeCat(int cat) + { + FriendButton.Selected = cat == 0; + FamButton.Selected = cat == 1; + AllButton.Selected = cat == -1; + FameButton.Selected = cat == 2; + RelSort = cat; + } + + public UITSContainer DisplayProvider(int index) + { + return new UIRelationshipDisplay(Items[index].Item1, Items[index].Item2, Game.vm); + } + + public override void Update(UpdateState state) + { + base.Update(state); + UpdateRelView(); + Invalidate(); + } + + public void UpdateRelView() + { + var sel = Game.SelectedAvatar; + var neighbourhood = Content.Get().Neighborhood; + if (sel == null) return; + var neighbour = sel.GetPersonData(VMPersonDataVariable.NeighborId); + + var n = neighbourhood.GetNeighborByID(neighbour); + var rel = n.Relationships; + + var rItems = rel.Select(x => new Tuple(neighbour, x.Key)).ToList(); + + bool difference = false; + if (rItems.Count == Items.Count) + { + for (int i = 0; i < rItems.Count; i++) + { + if (!rItems[i].Equals(Items[i])) { + difference = true; break; + } + } + } else + { + difference = true; + } + + if (difference) + { + Items = rItems; + ScrollView.Reset(); + } + } + } + + public class UIRelationshipDisplay : UITSContainer { + private UILabel NameLabel; + private Texture2D ItemBg; + private Texture2D Item; + private UIMotiveBar Bar1; + private UIMotiveBar Bar2; + + private int NIDF; + private int NID; + public UIRelationshipDisplay(int nidFrom, int nid, VM curVM) : base() + { + NameLabel = new UILabel(); + NameLabel.CaptionStyle = NameLabel.CaptionStyle.Clone(); + NameLabel.CaptionStyle.Color = UIStyle.Current.Text; + NameLabel.CaptionStyle.Size = 10; + NameLabel.Wrapped = true; + NameLabel.Size = new Vector2(80, 33); + NameLabel.Position = new Vector2(5, 5); + NameLabel.Alignment = TextAlignment.Middle | TextAlignment.Center; + Add(NameLabel); + + Bar1 = new UIMotiveBar(); + Bar1.ScaleX = Bar1.ScaleY = 0.5f; + Bar1.Position = new Vector2(8, 94); + Add(Bar1); + + Bar2 = new UIMotiveBar(); + Bar2.ScaleX = Bar2.ScaleY = 0.5f; + Bar2.Position = new Vector2(8, 106); + Add(Bar2); + + ItemBg = Content.Get().CustomUI.Get("inv_item.png").Get(GameFacade.GraphicsDevice); + + var neighbourhood = Content.Get().Neighborhood; + var n = neighbourhood.GetNeighborByID((short)nid); + var obj = Content.Get().WorldObjects.Get(n.GUID); + if (obj != null) + { + var aobj = curVM.Context.CreateObjectInstance(n.GUID, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true); + Item = UIIconCache.GetObject(aobj.BaseObject); + aobj.Delete(curVM.Context); + var ctss = obj.Resource.Get(obj.OBJ.CatalogStringsID); + //todo: family name + NameLabel.Caption = ctss?.GetString(0) ?? obj.OBJ.ChunkLabel; + } + NIDF = nidFrom; + NID = nid; + } + + public override void Update(UpdateState state) + { + var neighbourhood = Content.Get().Neighborhood; + var n = neighbourhood.GetNeighborByID((short)NIDF); + var rel = n.Relationships; + + List values; + if (rel.TryGetValue(NID, out values)) + { + if (values.Count > 0) Bar1.MotiveValue = values[0]; + if (values.Count > 2) Bar2.MotiveValue = values[2]; + } + base.Update(state); + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, ItemBg, null, new Vector2(20, 40), Vector2.One, new Color(104, 164, 184, 255)); + + if (Item != null) + { + DrawLocalTexture(batch, Item, null, new Vector2(45 + 42 / -2, 65 + 42 / -2), new Vector2(42f / Item.Height, 42f / Item.Height)); + } + + base.Draw(batch); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UISubpanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UISubpanel.cs new file mode 100644 index 0000000..5465147 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/LiveSubpanels/UISubpanel.cs @@ -0,0 +1,36 @@ +using FSO.Client; +using FSO.Client.UI.Framework; +using FSO.Common.Utils; +using Microsoft.Xna.Framework; +using Simitone.Client.UI.Screens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Panels.LiveSubpanels +{ + public class UISubpanel : UICachedContainer + { + public TS1GameScreen Game; + + public UISubpanel(TS1GameScreen game) : base() + { + Opacity = 0; + var screenWidth = GameFacade.Screens.CurrentUIScreen.ScreenWidth; + Size = new Vector2(screenWidth-342, 128); + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Opacity", 1f } }); + Game = game; + } + + public void Kill() + { + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Opacity", 0f } }); + GameThread.SetTimeout(() => + { + Parent.Remove(this); + }, 300); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIClockPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIClockPanel.cs new file mode 100644 index 0000000..e2c0e02 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIClockPanel.cs @@ -0,0 +1,253 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Model; +using FSO.Common.Rendering.Framework.IO; +using FSO.Common.Rendering.Framework.Model; +using FSO.Content; +using FSO.HIT; +using FSO.SimAntics; +using Microsoft.Xna.Framework; +using Simitone.Client.UI.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Panels +{ + public class UIClockPanel : UICachedContainer + { + public UIImage OuterBg; + public UIImage InnerBg; + + public UILabel TimeLabel; + public UILabel TimeLabelShadow; + + public UIButton Speed1; + public UIButton Speed2; + public UIButton Speed3; + public UIButton SpeedP; + + public UIButton SpeedCurrent; + + public UIMouseEventRef MouseEvent; + + public static Dictionary RemapSpeed = new Dictionary() + { + {0, 4}, //pause + {1, 1}, //1 speed + {3, 2}, //2 speed + {10, 3}, //3 speed + }; + + public static Dictionary ReverseRemap = RemapSpeed.ToDictionary(x => x.Value, x => x.Key); + + public UIButton[] Btns; + + public bool Expand; + public VM VM; + + public UIClockPanel(VM vm) : base() + { + VM = vm; + OuterBg = new UIImage(Content.Get().CustomUI.Get("clockbg.png").Get(GameFacade.GraphicsDevice)) + .With9Slice(25, 25, 0, 0); + Add(OuterBg); + OuterBg.X = 138; + OuterBg.Size = new Point(196, 50); + OuterBg.Width = OuterBg.Width; + + MouseEvent = OuterBg.ListenForMouse(OuterBg.GetBounds(), HandleMouseEvent); + + InnerBg = new UIImage(Content.Get().CustomUI.Get("clockinbg.png").Get(GameFacade.GraphicsDevice)) + .With9Slice(19, 19, 0, 0); + Add(InnerBg); + InnerBg.X = 148; + InnerBg.Y = 6; + InnerBg.Size = new Point(133, 38); + + TimeLabel = new UILabel(); + TimeLabel.Alignment = TextAlignment.Middle | TextAlignment.Center; + TimeLabel.CaptionStyle = TimeLabel.CaptionStyle.Clone(); + TimeLabel.CaptionStyle.Size = 15; + TimeLabel.CaptionStyle.Color = Color.White; + TimeLabel.Size = new Vector2(133, 38); + TimeLabel.Position = InnerBg.Position; + + TimeLabelShadow = new UILabel(); + TimeLabelShadow.Alignment = TextAlignment.Middle | TextAlignment.Center; + TimeLabelShadow.CaptionStyle = TimeLabel.CaptionStyle.Clone(); + TimeLabelShadow.CaptionStyle.Color = Color.Black * 0.25f; + TimeLabelShadow.Size = new Vector2(133, 38); + TimeLabelShadow.Position = InnerBg.Position + new Vector2(2); + + Add(TimeLabelShadow); + Add(TimeLabel); + + Size = new Microsoft.Xna.Framework.Vector2(334, 50); + //full size is 334 wide + //small: 138 x offset at 196 + + Speed1 = new UITwoStateButton(Content.Get().CustomUI.Get("speedbtn_1.png").Get(GameFacade.GraphicsDevice)); + Speed2 = new UITwoStateButton(Content.Get().CustomUI.Get("speedbtn_2.png").Get(GameFacade.GraphicsDevice)); + Speed3 = new UITwoStateButton(Content.Get().CustomUI.Get("speedbtn_3.png").Get(GameFacade.GraphicsDevice)); + SpeedP = new UITwoStateButton(Content.Get().CustomUI.Get("speedbtn_4.png").Get(GameFacade.GraphicsDevice)); + + Btns = new UIButton[] { Speed1, Speed2, Speed3, SpeedP }; + for (int i=0; i<4; i++) + { + var btn = Btns[i]; + var speed = i; + btn.OnButtonClick += (b) => { if (!Expand) SetExpanded(true); else SwitchSpeed(speed+1); }; + btn.Position = new Vector2(289, 6); + btn.InflateHitbox(5, 15); + Add(btn); + } + + TweenHook = 0; + } + + public string LastClock = ""; + public int LastSpeed = -1; + public override void Update(UpdateState state) + { + var min = VM.Context.Clock.Minutes; + var hour = VM.Context.Clock.Hours; + + string suffix = (hour > 11) ? "PM" : "AM"; + hour %= 12; + if (hour == 0) hour = 12; + + var text = hour.ToString() + ":" + min.ToString().PadLeft(2, '0') + " " + suffix; + + if (text != LastClock) + { + LastClock = text; + TimeLabel.Caption = text; + TimeLabelShadow.Caption = text; + } + + MouseEvent.Region = OuterBg.GetBounds(); + + var speed = RemapSpeed[VM.SpeedMultiplier]; + if (speed != LastSpeed) + { + if (speed == 4) InnerBg.Texture = Content.Get().CustomUI.Get("clockinbg_pause.png").Get(GameFacade.GraphicsDevice); + else if (LastSpeed == 4) InnerBg.Texture = Content.Get().CustomUI.Get("clockinbg.png").Get(GameFacade.GraphicsDevice); + + for (int i=0; i<4; i++) + { + Btns[i].Selected = (i+1 == speed); + if (i+1 == speed) + { + SendToFront(Btns[i]); + } + if (TweenHook == 0) Btns[i].Visible = Btns[i].Selected; + } + LastSpeed = speed; + } + base.Update(state); + } + + public void SwitchSpeed(int speed) + { + switch (VM.SpeedMultiplier) + { + case 0: + switch (speed) + { + case 1: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo1); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo2); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo3); break; + } + break; + case 1: + switch (speed) + { + case 4: + HITVM.Get().PlaySoundEvent(UISounds.Speed1ToP); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.Speed1To2); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.Speed1To3); break; + } + break; + case 3: + switch (speed) + { + case 4: + HITVM.Get().PlaySoundEvent(UISounds.Speed2ToP); break; + case 1: + HITVM.Get().PlaySoundEvent(UISounds.Speed2To1); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.Speed2To3); break; + } + break; + case 10: + switch (speed) + { + case 4: + HITVM.Get().PlaySoundEvent(UISounds.Speed3ToP); break; + case 1: + HITVM.Get().PlaySoundEvent(UISounds.Speed3To1); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.Speed3To2); break; + } + break; + } + + switch (speed) + { + case 4: VM.SpeedMultiplier = 0; break; + case 1: VM.SpeedMultiplier = 1; break; + case 2: VM.SpeedMultiplier = 3; break; + case 3: VM.SpeedMultiplier = 10; break; + } + + if (Expand) SetExpanded(false); + } + + public void HandleMouseEvent(UIMouseEventType type, UpdateState state) + { + if (type == UIMouseEventType.MouseDown) + { + SetExpanded(!Expand); + } + } + + private float _TweenHook; + public float TweenHook + { + set + { + Invalidate(); + _TweenHook = value; + for (int i = 0; i < 4; i++) Btns[i].Visible = (value != 0) || i+1 == LastSpeed; + } + get + { + return _TweenHook; + } + } + + public void SetExpanded(bool expand) + { + var time = 0.3f; + GameFacade.Screens.Tween.To(OuterBg, time, new Dictionary() { { "X", (expand) ? 0f : 138f }, { "Width", (expand) ? 334f : 196f } }, TweenQuad.EaseOut); + GameFacade.Screens.Tween.To(InnerBg, time, new Dictionary() { { "X", (expand) ? 10f : 148f } }, TweenQuad.EaseOut); + + GameFacade.Screens.Tween.To(TimeLabelShadow, time, new Dictionary() { { "X", (expand) ? 12f : 150f } }, TweenQuad.EaseOut); + GameFacade.Screens.Tween.To(TimeLabel, time, new Dictionary() { { "X", (expand) ? 10f : 148f } }, TweenQuad.EaseOut); + GameFacade.Screens.Tween.To(this, time, new Dictionary() { { "TweenHook", (expand) ? 1f : 0f } }, TweenQuad.EaseOut); + + for (int i=0; i<4; i++) + GameFacade.Screens.Tween.To(Btns[i], time, new Dictionary() { { "X", (expand) ? (151f+46*i) : 289f } }, TweenQuad.EaseOut); + Expand = expand; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UICutawayPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UICutawayPanel.cs new file mode 100644 index 0000000..532b0af --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UICutawayPanel.cs @@ -0,0 +1,83 @@ +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 UICutawayPanel : UIContainer + { + public float BgAnim { get; set; } + public Texture2D Background; + + public UIStencilButton DownButton; + public UIStencilButton CutButton; + public UIStencilButton UpButton; + public UIStencilButton RoofButton; + + public event Action OnSelection; + + public UICutawayPanel(int cut) + { + BgAnim = 0; + var ui = Content.Get().CustomUI; + Background = ui.Get("cut_bg.png").Get(GameFacade.GraphicsDevice); + + DownButton = new UIStencilButton(ui.Get("cut_stencil_down.png").Get(GameFacade.GraphicsDevice)); + DownButton.Position = new Vector2(12, 64); + DownButton.Selected = (cut == 0); + DownButton.OnButtonClick += (b) => { OnSelection?.Invoke(0); }; + Add(DownButton); + CutButton = new UIStencilButton(ui.Get("cut_stencil_away.png").Get(GameFacade.GraphicsDevice)); + CutButton.Position = new Vector2(8, 128); + CutButton.Selected = (cut == 1); + CutButton.OnButtonClick += (b) => { OnSelection?.Invoke(1); }; + Add(CutButton); + UpButton = new UIStencilButton(ui.Get("cut_stencil_up.png").Get(GameFacade.GraphicsDevice)); + UpButton.OnButtonClick += (b) => { OnSelection?.Invoke(2); }; + UpButton.Selected = (cut == 2); + UpButton.Position = new Vector2(24, 196); + Add(UpButton); + RoofButton = new UIStencilButton(ui.Get("cut_stencil_roof.png").Get(GameFacade.GraphicsDevice)); + RoofButton.OnButtonClick += (b) => { OnSelection?.Invoke(3); }; + RoofButton.Selected = (cut == 3); + RoofButton.Position = new Vector2(54, 254); + Add(RoofButton); + + Opacity = 0f; + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Opacity", 1f }, { "BgAnim", 1f } }, TweenQuad.EaseOut); + foreach (var child in Children) + { + ((UIStencilButton)child).Alpha = 0f; + ((UIStencilButton)child).InflateHitbox(25, 5); + GameFacade.Screens.Tween.To(child, 0.3f, new Dictionary() { { "Alpha", 1f } }, TweenQuad.EaseOut); + } + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Background, null, new Vector2(264, 138), Vector2.One, UIStyle.Current.Bg * BgAnim, ((float)Math.PI / 3) * (1-BgAnim), new Vector2(263, 119)); + base.Draw(batch); + } + + public void Kill() + { + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Opacity", 0f }, { "BgAnim", 0f } }, TweenQuad.EaseOut); + foreach (var child in Children) + { + GameFacade.Screens.Tween.To(child, 0.3f, new Dictionary() { { "Alpha", 0f } }, TweenQuad.EaseOut); + } + + GameThread.SetTimeout(() => Parent.Remove(this), 300); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIHouseSelectPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIHouseSelectPanel.cs new file mode 100644 index 0000000..caff70b --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIHouseSelectPanel.cs @@ -0,0 +1,115 @@ +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 Microsoft.Xna.Framework; +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 UIHouseSelectPanel : UIContainer + { + public UIDiagonalStripe Diag; + public UIDiagonalStripe TitleStripe; + + public UILabel StreetTitle; + public UILabel LotTitle; + public UILabel LotDescription; + + public UIBigButton EnterLot; + public UIBigButton More; + + public event Action OnSelected; + public int HouseID; + + public UIHouseSelectPanel(int houseID) + { + HouseID = houseID; + var screen = GameFacade.Screens.CurrentUIScreen; + 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) => { }); + Add(Diag); + + TitleStripe = new UIDiagonalStripe(new Point(screen.ScreenWidth / 2, 92 + 8 + 32), UIDiagonalStripeSide.RIGHT, UIStyle.Current.Bg); + TitleStripe.StartOff = 8 + 32; + TitleStripe.Y = 82 - 34; + Add(TitleStripe); + + var house = Content.Get().Neighborhood.GetHouse(houseID); + + var street = Content.Get().Neighborhood.StreetNames; + var assignment = street.Get(2001).GetString(houseID-1); + + int streetName; + if (int.TryParse(assignment, out streetName)) + { + StreetTitle = new UILabel(); + StreetTitle.Position = new Vector2(30, 94); + InitLabel(StreetTitle); + StreetTitle.CaptionStyle.Color = UIStyle.Current.BtnActive; + StreetTitle.Caption = street.Get(2000).GetString(streetName-1).Replace("%s", houseID.ToString()); + } + + var nameDesc = Content.Get().Neighborhood.GetHouseNameDesc(houseID); + var name = nameDesc.Item1; + if (name == "") name = "Unnamed House"; + + LotTitle = new UILabel(); + LotTitle.Position = new Vector2(30, 122); + InitLabel(LotTitle); + LotTitle.CaptionStyle.Size = 37; + LotTitle.Caption = name; + + LotDescription = new UILabel(); + LotDescription.Position = new Vector2(30, 206); + InitLabel(LotDescription); + //LotDescription.CaptionStyle.Size = 15; + LotDescription.Size = new Vector2(502, screen.ScreenHeight-415); + LotDescription.Wrapped = true; + LotDescription.Alignment = TextAlignment.Top | TextAlignment.Left; + LotDescription.Caption = nameDesc.Item2; + + EnterLot = new UIBigButton(false); + EnterLot.Caption = "Enter Lot"; + EnterLot.Width = 275; + EnterLot.Position = new Vector2(30, screen.ScreenHeight - 160); + 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); + + X = screen.ScreenWidth / -2; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "X", 0f } }, TweenQuad.EaseOut); + } + + public void Kill() + { + EnterLot.Opacity = 0.99f; //force an unpressable state + More.Opacity = 0.99f; + var screen = GameFacade.Screens.CurrentUIScreen; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "X", (screen.ScreenWidth / -2) - 32 } }, TweenQuad.EaseIn); + GameThread.SetTimeout(() => { Parent.Remove(this); }, 500); + } + + private void InitLabel(UILabel label) + { + label.CaptionStyle = label.CaptionStyle.Clone(); + label.CaptionStyle.Color = UIStyle.Current.Text; + label.CaptionStyle.Size = 19; + Add(label); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIInteractionQueue.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIInteractionQueue.cs new file mode 100644 index 0000000..2e9f651 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIInteractionQueue.cs @@ -0,0 +1,268 @@ +/* +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Model; +using FSO.Common.Rendering.Framework.Model; +using FSO.SimAntics.Engine; +using FSO.SimAntics; +using FSO.HIT; +using FSO.SimAntics.NetPlay.Model.Commands; +using FSO.Client.UI.Controls; +using FSO.Common; +using Simitone.Client.UI.Controls; +using FSO.Client; +using Simitone.Client.UI.Model; + +namespace Simitone.Client.UI.Panels +{ + /// + /// The queue display for ingame. Includes queue animations and control. + /// + public class UIInteractionQueue : UIContainer + { + + private List QueueItems; + public VMEntity QueueOwner; + public VM vm; + public Vector2 PieMenuClickPos = new Vector2(-1, -1); + + public UIInteractionQueue(VMEntity QueueOwner, VM vm) + { + this.vm = vm; + this.QueueOwner = QueueOwner; + QueueItems = new List(); + } + + public override void Update(UpdateState state) + { + base.Update(state); + if (QueueOwner == null) return; + //detect any changes in the interaction queue. + + var queue = QueueOwner.Thread.Queue; + bool skipParentIdle; + for (int i = 0; i < QueueItems.Count; i++) + { + int position = 0; + var itemui = QueueItems[i]; + bool found = false; //is this interaction still in the queue? if not then ditch it. + skipParentIdle = false; + for (int j = 0; j < queue.Count; j++) + { + var elem = queue[j]; + if (elem == itemui.Interaction) + { + found = true; + if (position != itemui.QueuePosition) itemui.TweenToPosition(position); + if (elem.Cancelled && elem.Priority <= 0 && !itemui.Cancelled) + { + itemui.Cancelled = true; + itemui.UI.SetCancelled(); + } + + if (elem.Name != itemui.Name) + { + itemui.Name = elem.Name; + itemui.UI.Tooltip = itemui.Name; + } + if (j == 0 && !itemui.Active) + { + itemui.Active = true; + itemui.UI.SetActive(true); + } + if (j != 0 && itemui.Active) + { + itemui.Active = false; + itemui.UI.SetActive(false); + } + + if (itemui.IconOwner != elem.IconOwner) + { + itemui.IconOwner = elem.IconOwner; + itemui.UpdateInteractionIcon(); + } + + if (itemui.InteractionResult != elem.InteractionResult) + { + itemui.InteractionResult = elem.InteractionResult; + itemui.UpdateInteractionResult(); + } + break; + } + if (elem.Mode != VMQueueMode.Idle && (j == 0 || elem.Mode != VMQueueMode.ParentExit) && (!skipParentIdle || elem.Mode != VMQueueMode.ParentIdle)) position++; + if (elem.Mode == VMQueueMode.ParentIdle) skipParentIdle = true; + } + if (!found) + { + itemui.UI.Kill(); + QueueItems.RemoveAt(i--); //not here anymore + } + else itemui.Update(); + } + + //now detect if there are any interactions we're not displaying and add them. + + skipParentIdle = false; + for (int i = 0; i < queue.Count; i++) + { + int position = 0; + var elem = queue[i]; + + if (elem.Mode != VMQueueMode.Idle && (i == 0 || elem.Mode != VMQueueMode.ParentExit) && (!skipParentIdle || elem.Mode != VMQueueMode.ParentIdle)) + { + bool found = false; //is this interaction in the queue? if not, add it + for (int j = 0; j < QueueItems.Count; j++) + { + var itemui = QueueItems[j]; + if (elem == itemui.Interaction) + { + found = true; + break; + } + + } + if (!found) //new interaction!!! + { + var itemui = new UIIQTrackEntry() + { + Interaction = elem, + IconOwner = elem.IconOwner, + SourcePos = (PieMenuClickPos.X < 0) ? (new Vector2(30 + position * 50, 30)) : PieMenuClickPos, + TweenProgress = 0, + UI = new UIInteraction(i == 0), + Active = (i == 0) + }; + itemui.UI.Position = itemui.SourcePos; + itemui.UI.OnMouseEvent += new ButtonClickDelegate(InteractionClicked); + itemui.UI.OnInteractionResult += InteractionResult; + itemui.UI.ParentEntry = itemui; + itemui.Name = elem.Name; + itemui.UI.Tooltip = itemui.Name; + itemui.TweenToPosition(position); + itemui.UpdateInteractionIcon(); + itemui.Update(); + this.Add(itemui.UI); + QueueItems.Add(itemui); + + PieMenuClickPos = new Vector2(-1, -1); + } + position++; + } + if (elem.Mode == VMQueueMode.ParentIdle) skipParentIdle = true; + } + + } + + private void InteractionResult(UIElement ui, bool accepted) + { + if (QueueOwner == null) return; + UIInteraction item = (UIInteraction)ui; + var itemui = item.ParentEntry; + var queue = QueueOwner.Thread.Queue; + for (int i = 0; i < queue.Count; i++) + { + if (queue[i] == itemui.Interaction) + { + HITVM.Get().PlaySoundEvent(UISounds.CallSend); + if (!(itemui.Interaction.Cancelled && itemui.Interaction.Priority <= 0)) + { + vm.SendCommand(new VMNetInteractionResultCmd + { + ActionUID = itemui.Interaction.UID, + ActorUID = QueueOwner.PersistID, + Accepted = accepted + }); + } + break; + } + } + } + + private void InteractionClicked(UIElement ui) + { + if (QueueOwner == null) return; + UIInteraction item = (UIInteraction)ui; + var itemui = item.ParentEntry; + var queue = QueueOwner.Thread.Queue; + for (int i = 0; i < queue.Count; i++) + { + if (queue[i] == itemui.Interaction) + { + HITVM.Get().PlaySoundEvent(UISounds.QueueDelete); + if (!(itemui.Interaction.Cancelled && itemui.Interaction.Priority <= 0)) + { + vm.SendCommand(new VMNetInteractionCancelCmd + { + ActionUID = itemui.Interaction.UID, + ActorUID = QueueOwner.PersistID + }); + } + break; + } + } + } + } + + public class UIIQTrackEntry //this class basically keeps track of states to determine if things have changed. + { + public VMQueuedAction Interaction; + public UIInteraction UI; + public VMEntity IconOwner; + public int QueuePosition; + public bool Active; + public bool Cancelled; + public string Name; + + public sbyte InteractionResult = -1; + + public double TweenProgress; + public Vector2 TargetPos; + public Vector2 SourcePos; + public double MotionPerFrame = 1.0 / 25.0; //default to finishing in 25 frames + + public void TweenToPosition(int pos) + { + Vector2 realPos; + if (pos == 0) realPos = new Vector2(73, 73); + else realPos = new Vector2(37 + 68 + pos*60, 41.5f); + + GameFacade.Screens.Tween.To(UI, 0.5f, new Dictionary() { { "X", realPos.X }, { "Y", realPos.Y } }, TweenQuad.EaseOut); + QueuePosition = pos; + /* + SourcePos = GetTweenPosition(); + TargetPos = new Vector2(30 + pos * 50, 30); + TweenProgress = 0;*/ + } + + private Vector2 GetTweenPosition() + { + return TargetPos * (float)TweenProgress + SourcePos * (1 - (float)TweenProgress); + } + + public void Update() + { + if (TweenProgress < 1) + { + TweenProgress = Math.Min(TweenProgress + MotionPerFrame * (60.0 / FSOEnvironment.RefreshRate), 1); + UI.Position = GetTweenPosition(); + } + } + + public void UpdateInteractionIcon() + { + UI.Icon = UIIconCache.GetObject(IconOwner); + } + + public void UpdateInteractionResult() + { + UI.UpdateInteractionResult(InteractionResult); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UILoadProgress.cs b/Client/Simitone/Simitone.Client/UI/Panels/UILoadProgress.cs new file mode 100644 index 0000000..6151e77 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UILoadProgress.cs @@ -0,0 +1,97 @@ +using FSO.Client.UI.Framework; +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; +using FSO.Common.Rendering.Framework.Model; +using FSO.Common.Utils; +using FSO.Client; +using FSO.Content; + +namespace Simitone.Client.UI.Panels +{ + public class UILoadProgress : UIElement + { + public int[] Divisors = new int[] + { + 140, + 243, + 278, + 359, + 405, + 450, + 496, + 587, + 632, + 678, + 723, + 814, + 884 + }; + + public float OddTransition { get; set; } + public float EvenTransition { get; set; } + + public float OverallPercent; + + private int ActiveElem; + private bool CanFireNext = true; + + private Texture2D Back; + private Texture2D Front; + + public UILoadProgress() + { + var ui = Content.Get().CustomUI; + Back = ui.Get("load_bar_bg.png").Get(GameFacade.GraphicsDevice); + Front = ui.Get("load_bar_content.png").Get(GameFacade.GraphicsDevice); + } + + public override void Update(UpdateState state) + { + var targElem = (int)Math.Ceiling(OverallPercent * Divisors.Length); + Console.WriteLine(targElem); + if (targElem > ActiveElem && CanFireNext) + { + //fire the next + if (ActiveElem % 2 == 0) + { + //firing an odd + OddTransition = 1f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "OddTransition", 0f } }, TweenElastic.EaseOut); + } else + { + EvenTransition = 1f; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "EvenTransition", 0f } }, TweenElastic.EaseOut); + } + ActiveElem++; + CanFireNext = false; + GameThread.SetTimeout(() => { CanFireNext = true; }, 260); + } + base.Update(state); + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Back, Vector2.Zero); + for (int i=0; i ActiveElem) return; + float offset = 0; + if (i > ActiveElem-2) + { + if (i % 2 == 0) offset = EvenTransition; + else offset = OddTransition; + } + + var last = (i == 0) ? 0 : Divisors[i - 1]; + var t = Divisors[i]; + + DrawLocalTexture(batch, Front, new Rectangle(last, 0, t-last, 112), new Vector2(last, offset*(-100)), Vector2.One, Color.White*(1-offset)); + } + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UILotControl.cs b/Client/Simitone/Simitone.Client/UI/Panels/UILotControl.cs new file mode 100644 index 0000000..71e4e42 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UILotControl.cs @@ -0,0 +1,807 @@ +/* +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Controls; +using FSO.Client.UI.Model; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using FSO.Common.Rendering.Framework.Model; +using FSO.Common.Rendering.Framework.IO; +using FSO.Common.Rendering.Framework; +using FSO.HIT; + +using FSO.LotView; +using FSO.SimAntics; +using FSO.LotView.Components; +using Microsoft.Xna.Framework.Input; +using FSO.LotView.Model; +using FSO.SimAntics.Primitives; +using FSO.SimAntics.NetPlay.Model.Commands; +using FSO.SimAntics.Utils; +using FSO.Common; +using FSO.Client; +using FSO.Content; +using FSO.Client.Debug; +using Simitone.Client.UI.Screens; + +namespace Simitone.Client.UI.Panels +{ + /// + /// Generates pie menus when the player clicks on objects. + /// + public class UILotControl : UIContainer + { + private UIMouseEventRef MouseEvt; + public bool MouseIsOn; + + private UIPieMenu PieMenu; + + private bool ShowTooltip; + private bool TipIsError; + private Texture2D RMBCursor; + + public FSO.SimAntics.VM vm; + public FSO.LotView.World World; + public VMEntity ActiveEntity; + public uint SelectedSimID + { + get + { + return (vm == null) ? 0 : vm.MyUID; + } + } + public short ObjectHover; + public bool InteractionsAvailable; + public UIInteractionQueue Queue; + + public bool LiveMode = true; + public bool PanelActive = false; + public UILotControlTouchHelper Touch; + + public int WallsMode = 1; + + private int OldMX; + private int OldMY; + private bool FoundMe; //if false and avatar changes, center. Should center on join lot. + + public bool RMBScroll; + private int RMBScrollX; + private int RMBScrollY; + + //1 = near, 0.5 = med, 0.25 = far + //"target" because we rescale the game target to fit this zoom level. + public float TargetZoom = 1; + + // 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 UINeighborhoodSelectionPanel TS1NeighSelector; + private ulong LastDialogID; + + private static uint GOTO_GUID = 0x000007C4; + public VMEntity GotoObject; + + private Rectangle MouseCutRect = new Rectangle(-4, -4, 4, 4); + private List CutRooms = new List(); + private HashSet LastCutRooms = new HashSet(); //final rooms, including those outside. used to detect dirty. + public sbyte LastFloor = -1; + public WorldRotation LastRotation = WorldRotation.TopLeft; + private bool[] LastCuts; //cached roomcuts, to apply rect cut to. + private int LastWallMode = -1; //invalidates last roomcuts + private bool LastRectCutNotable = false; //set if the last rect cut made a noticable change to the cuts array. If true refresh regardless of new cut effect. + + /// + /// Creates a new UILotControl instance. + /// + /// A SimAntics VM instance. + /// A World instance. + public UILotControl(FSO.SimAntics.VM vm, FSO.LotView.World World) + { + this.vm = vm; + this.World = World; + + ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar); + MouseEvt = this.ListenForMouse(new Microsoft.Xna.Framework.Rectangle(0, 0, + GlobalSettings.Default.GraphicsWidth, GlobalSettings.Default.GraphicsHeight), OnMouse); + + Queue = new UIInteractionQueue(ActiveEntity, vm); + this.Add(Queue); + + //ObjectHolder = new UIObjectHolder(vm, World, this); + Touch = new UILotControlTouchHelper(this); + Add(Touch); + SetupQuery(); + + + RMBCursor = GetTexture(0x24B00000001); //exploreanchor.bmp + + vm.OnDialog += vm_OnDialog; + vm.OnBreakpoint += Vm_OnBreakpoint; + } + + public void SetupQuery() + { + /* + UIContainer parent = null; + if (QueryPanel?.Parent?.Parent != null) + { + parent = QueryPanel.Parent; + } + + QueryPanel = new UIQueryPanel(World); + QueryPanel.OnSellBackClicked += ObjectHolder.SellBack; + QueryPanel.OnInventoryClicked += ObjectHolder.MoveToInventory; + QueryPanel.OnAsyncBuyClicked += ObjectHolder.AsyncBuy; + QueryPanel.OnAsyncSaleClicked += ObjectHolder.AsyncSale; + QueryPanel.OnAsyncPriceClicked += ObjectHolder.AsyncSale; + QueryPanel.OnAsyncSaleCancelClicked += ObjectHolder.AsyncCancelSale; + QueryPanel.X = 0; + QueryPanel.Y = -114; + + if (parent != null) parent.Add(QueryPanel); + */ + } + + public override void GameResized() + { + base.GameResized(); + MouseEvt.Region.Width = GlobalSettings.Default.GraphicsWidth; + MouseEvt.Region.Height = GlobalSettings.Default.GraphicsHeight; + + SetupQuery(); + } + + + private void Vm_OnBreakpoint(VMEntity entity) + { + 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; + //return if same dialog as before, or not ours + if ((info == null || info.Block) && BlockingDialog != null) + { + //cancel current dialog because it's no longer valid + UIScreen.RemoveDialog(BlockingDialog); + LastDialogID = 0; + BlockingDialog = null; + } + if (info == null) return; //return if we're just clearing a dialog. + + var options = new UIAlertOptions + { + Title = info.Title, + Message = info.Message, + Width = 325 + (int)(info.Message.Length / 3.5f), + Alignment = TextAlignment.Left, + TextSize = 12 + }; + + var b0Event = (info.Block) ? new ButtonClickDelegate(DialogButton0) : null; + var b1Event = (info.Block) ? new ButtonClickDelegate(DialogButton1) : null; + var b2Event = (info.Block) ? new ButtonClickDelegate(DialogButton2) : null; + + VMDialogType type = (info.Operand == null) ? VMDialogType.Message : info.Operand.Type; + + switch (type) + { + default: + case VMDialogType.Message: + options.Buttons = new UIAlertButton[] { new UIAlertButton(UIAlertButtonType.OK, b0Event, info.Yes) }; + break; + case VMDialogType.YesNo: + options.Buttons = new UIAlertButton[] + { + new UIAlertButton(UIAlertButtonType.Yes, b0Event, info.Yes), + new UIAlertButton(UIAlertButtonType.No, b1Event, info.No), + }; + break; + case VMDialogType.YesNoCancel: + options.Buttons = new UIAlertButton[] + { + new UIAlertButton(UIAlertButtonType.Yes, b0Event, info.Yes), + new UIAlertButton(UIAlertButtonType.No, b1Event, info.No), + new UIAlertButton(UIAlertButtonType.Cancel, b2Event, info.Cancel), + }; + break; + case VMDialogType.TextEntry: + options.Buttons = new UIAlertButton[] { new UIAlertButton(UIAlertButtonType.OK, b0Event, info.Yes) }; + options.TextEntry = true; + break; + case VMDialogType.NumericEntry: + if (!vm.TS1) goto case VMDialogType.TextEntry; + else goto case VMDialogType.TS1Neighborhood; + case VMDialogType.TS1Vacation: + case VMDialogType.TS1Neighborhood: + case VMDialogType.TS1StudioTown: + case VMDialogType.TS1Magictown: + TS1NeighSelector = new UINeighborhoodSelectionPanel((ushort)VMDialogPrivateStrings.TypeToNeighID[type]); + Parent.Add(TS1NeighSelector); + ((TS1GameScreen)Parent).Bg.Visible = true; + ((TS1GameScreen)Parent).LotControl.Visible = false; + TS1NeighSelector.OnHouseSelect += HouseSelected; + return; + + } + + var alert = new UIMobileAlert(options); + + UIScreen.GlobalShowDialog(alert, true); + + if (info.Block) + { + BlockingDialog = alert; + LastDialogID = info.DialogID; + } + + var entity = info.Icon; + if (entity is VMGameObject) + { + var objects = entity.MultitileGroup.Objects; + ObjectComponent[] objComps = new ObjectComponent[objects.Count]; + for (int i = 0; i < objects.Count; i++) + { + objComps[i] = (ObjectComponent)objects[i].WorldUI; + } + var thumb = World.GetObjectThumb(objComps, entity.MultitileGroup.GetBasePositions(), GameFacade.GraphicsDevice); + alert.SetIcon(thumb, 256, 256); + } + } + + private void HouseSelected(int house) + { + if (ActiveEntity == null || TS1NeighSelector == null) return; + vm.SendCommand(new VMNetDialogResponseCmd + { + ActorUID = ActiveEntity.PersistID, + ResponseCode = (byte)((house > 0) ? 1 : 0), + ResponseText = house.ToString() + }); + Parent.Remove(TS1NeighSelector); + TS1NeighSelector = null; + } + + private void DialogButton0(UIElement button) { DialogResponse(0); } + private void DialogButton1(UIElement button) { DialogResponse(1); } + private void DialogButton2(UIElement button) { DialogResponse(2); } + + private void DialogResponse(byte code) + { + if (BlockingDialog == null || ActiveEntity == null) return; + BlockingDialog.Close(); + LastDialogID = 0; + vm.SendCommand(new VMNetDialogResponseCmd + { + ActorUID = ActiveEntity.PersistID, + ResponseCode = code, + ResponseText = (BlockingDialog.ResponseText == null) ? "" : BlockingDialog.ResponseText + }); + BlockingDialog = null; + } + + private void OnMouse(UIMouseEventType type, UpdateState state) + { + if (!vm.Ready) return; + + if (type == UIMouseEventType.MouseOver) + { + //if (QueryPanel.Mode == 1) QueryPanel.Active = false; + MouseIsOn = true; + } + else if (type == UIMouseEventType.MouseOut) + { + MouseIsOn = false; + GameFacade.Cursor.SetCursor(CursorType.Normal); + Tooltip = null; + } + else if (type == UIMouseEventType.MouseDown) + { + Touch.MiceDown.Add(state.CurrentMouseID); + } + else if (type == UIMouseEventType.MouseUp) + { + Touch.MiceDown.Remove(state.CurrentMouseID); + if (!LiveMode) + { + //if (CustomControl != null) CustomControl.MouseUp(state); + //else ObjectHolder.MouseUp(state); + return; + } + state.UIState.TooltipProperties.Show = false; + state.UIState.TooltipProperties.Opacity = 0; + ShowTooltip = false; + TipIsError = false; + } + } + + public void ShowPieMenu(Point pt, UpdateState state) + { + if (!LiveMode) + { + //if (CustomControl != null) CustomControl.MouseDown(state); + //else ObjectHolder.MouseDown(state); + return; + } + if (PieMenu == null && ActiveEntity != null) + { + VMEntity obj; + //get new pie menu, make new pie menu panel for it + var tilePos = World.EstTileAtPosWithScroll(new Vector2(pt.X, pt.Y) / FSOEnvironment.DPIScaleFactor); + + LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, World.State.Level); + if (vm.Context.SolidToAvatars(targetPos).Solid) targetPos = LotTilePos.OUT_OF_WORLD; + + GotoObject.SetPosition(targetPos, Direction.NORTH, vm.Context); + + var newHover = World.GetObjectIDAtScreenPos(pt.X, + pt.Y, + GameFacade.GraphicsDevice); + + ObjectHover = newHover; + + bool objSelected = ObjectHover > 0; + if (objSelected || (GotoObject.Position != LotTilePos.OUT_OF_WORLD && ObjectHover <= 0)) + { + if (objSelected) + { + obj = vm.GetObjectById(ObjectHover); + } + else + { + obj = GotoObject; + } + if (obj != null) + { + obj = obj.MultitileGroup.GetInteractionGroupLeader(obj); + if (obj is VMGameObject && ((VMGameObject)obj).Disabled > 0) + { + var flags = ((VMGameObject)obj).Disabled; + + if ((flags & VMGameObjectDisableFlags.ForSale) > 0) + { + //for sale + var retailPrice = obj.MultitileGroup.Price; //wrong... should get this from catalog + var salePrice = obj.MultitileGroup.SalePrice; + ShowErrorTooltip(state, 22, true, "$" + retailPrice.ToString("##,#0"), "$" + salePrice.ToString("##,#0")); + } + else if ((flags & VMGameObjectDisableFlags.LotCategoryWrong) > 0) + ShowErrorTooltip(state, 21, true); //category wrong + else if ((flags & VMGameObjectDisableFlags.TransactionIncomplete) > 0) + ShowErrorTooltip(state, 27, true); //transaction not yet complete + else if ((flags & VMGameObjectDisableFlags.ObjectLimitExceeded) > 0) + ShowErrorTooltip(state, 24, true); //object is temporarily disabled... todo: something more helpful + else if ((flags & VMGameObjectDisableFlags.PendingRoommateDeletion) > 0) + ShowErrorTooltip(state, 16, true); //pending roommate deletion + } + else + { + var menu = obj.GetPieMenu(vm, ActiveEntity, false, true); + if (menu.Count != 0) + { + HITVM.Get().PlaySoundEvent(UISounds.PieMenuAppear); + PieMenu = new UIPieMenu(menu, obj, ActiveEntity, this); + this.Add(PieMenu); + PieMenu.X = state.MouseState.X / FSOEnvironment.DPIScaleFactor; + PieMenu.Y = state.MouseState.Y / FSOEnvironment.DPIScaleFactor; + PieMenu.UpdateHeadPosition(state.MouseState.X, state.MouseState.Y); + } + } + } + + } + else + { + ShowErrorTooltip(state, 0, true); + } + } + else + { + if (PieMenu != null) PieMenu.RemoveSimScene(); + this.Remove(PieMenu); + PieMenu = null; + } + } + + private void ShowErrorTooltip(UpdateState state, uint id, bool playSound, params string[] args) + { + if (playSound) HITVM.Get().PlaySoundEvent(UISounds.Error); + state.UIState.TooltipProperties.Show = true; + state.UIState.TooltipProperties.Color = Color.Black; + state.UIState.TooltipProperties.Opacity = 1; + state.UIState.TooltipProperties.Position = new Vector2(state.MouseState.X, + state.MouseState.Y); + state.UIState.Tooltip = GameFacade.Strings.GetString("159", id.ToString(), args); + state.UIState.TooltipProperties.UpdateDead = false; + ShowTooltip = true; + TipIsError = true; + } + + public void ClosePie() + { + if (PieMenu != null) + { + PieMenu.RemoveSimScene(); + Queue.PieMenuClickPos = PieMenu.Position; + this.Remove(PieMenu); + PieMenu = null; + } + } + + public override Rectangle GetBounds() + { + return new Rectangle(0, 0, GlobalSettings.Default.GraphicsWidth, GlobalSettings.Default.GraphicsHeight); + } + + public void LiveModeUpdate(UpdateState state, bool scrolled) + { + if (MouseIsOn && !RMBScroll && ActiveEntity != null && !FSOEnvironment.SoftwareKeyboard) + { + + if (state.MouseState.X != OldMX || state.MouseState.Y != OldMY) + { + OldMX = state.MouseState.X; + OldMY = state.MouseState.Y; + var newHover = World.GetObjectIDAtScreenPos(state.MouseState.X / FSOEnvironment.DPIScaleFactor, + state.MouseState.Y / FSOEnvironment.DPIScaleFactor, + GameFacade.GraphicsDevice); + + if (ObjectHover != newHover) + { + ObjectHover = newHover; + if (ObjectHover > 0) + { + var obj = vm.GetObjectById(ObjectHover); + if (obj != null) + { + var menu = obj.GetPieMenu(vm, ActiveEntity, false, true); + InteractionsAvailable = (menu.Count > 0); + } + } + } + + if (!TipIsError) ShowTooltip = false; + if (ObjectHover > 0) + { + var obj = vm.GetObjectById(ObjectHover); + if (!TipIsError && obj != null) + { + if (obj is VMAvatar) + { + state.UIState.TooltipProperties.Show = true; + state.UIState.TooltipProperties.Color = Color.Black; + state.UIState.TooltipProperties.Opacity = 1; + state.UIState.TooltipProperties.Position = new Vector2(state.MouseState.X, + state.MouseState.Y); + state.UIState.Tooltip = GetAvatarString(obj as VMAvatar); + state.UIState.TooltipProperties.UpdateDead = false; + ShowTooltip = true; + } + else if (((VMGameObject)obj).Disabled > 0) + { + var flags = ((VMGameObject)obj).Disabled; + if ((flags & VMGameObjectDisableFlags.ForSale) > 0) + { + //for sale + //try to get catalog price + var guid = obj.MasterDefinition?.GUID ?? obj.Object.OBJ.GUID; + var item = Content.Get().WorldCatalog.GetItemByGUID(guid); + + var retailPrice = (int?)(item?.Price) ?? obj.MultitileGroup.Price; + var salePrice = obj.MultitileGroup.SalePrice; + ShowErrorTooltip(state, 22, false, "$" + retailPrice.ToString("##,#0"), "$" + salePrice.ToString("##,#0")); + TipIsError = false; + } + } + + } + } + if (!ShowTooltip) + { + state.UIState.TooltipProperties.Show = false; + state.UIState.TooltipProperties.Opacity = 0; + } + } + } + else + { + ObjectHover = 0; + } + + if (!scrolled) + { //set cursor depending on interaction availability + CursorType cursor; + + if (PieMenu == null && MouseIsOn) + { + if (ObjectHover == 0) + { + cursor = CursorType.LiveNothing; + } + else + { + if (InteractionsAvailable) + { + if (vm.GetObjectById(ObjectHover) is VMAvatar) cursor = CursorType.LivePerson; + else cursor = CursorType.LiveObjectAvail; + } + else + { + cursor = CursorType.LiveObjectUnavail; + } + } + } + else + { + + cursor = CursorType.Normal; + } + + CursorManager.INSTANCE.SetCursor(cursor); + } + + } + + private string GetAvatarString(VMAvatar ava) + { + return ava.ToString(); + } + + public void RefreshCut() + { + LastFloor = -1; + LastWallMode = -1; + + if (vm.Context.Blueprint != null && LastCuts != null) + { + vm.Context.Blueprint.Cutaway = LastCuts; + vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED)); + } + + //MouseCutRect = new Rectangle(0,0,0,0); + } + + public override void Draw(UISpriteBatch batch) + { + //DrawLocalTexture(batch, World.State.Light.LightMap, new Rectangle(0,0, World.State.Light.LightMap.Width/3, World.State.Light.LightMap.Height/2), new Vector2()); + if (RMBScroll) + { + DrawLocalTexture(batch, RMBCursor, new Vector2(RMBScrollX - RMBCursor.Width / 2, RMBScrollY - RMBCursor.Height / 2)); + } + base.Draw(batch); + } + + public override void Update(UpdateState state) + { + base.Update(state); + + if (!vm.Ready || vm.Context.Architecture == null) return; + + //handling smooth scaled zoom + float BaseScale; + WorldZoom targetZoom; + if (TargetZoom < 0.5f) + { + targetZoom = WorldZoom.Far; + BaseScale = 0.25f; + } else if (TargetZoom < 1f) + { + targetZoom = WorldZoom.Medium; + BaseScale = 0.5f; + } else + { + targetZoom = WorldZoom.Near; + BaseScale = 1f; + } + World.BackbufferScale = TargetZoom/BaseScale; + if (World.State.Zoom != targetZoom) World.State.Zoom = targetZoom; + 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. + if (ActiveEntity == null) ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar); + + if (!FoundMe && ActiveEntity != null) + { + vm.Context.World.State.CenterTile = new Vector2(ActiveEntity.VisualPosition.X, ActiveEntity.VisualPosition.Y); + vm.Context.World.State.ScrollAnchor = null; + FoundMe = true; + } + Queue.QueueOwner = ActiveEntity; + } + + if (GotoObject == null) GotoObject = vm.Context.CreateObjectInstance(GOTO_GUID, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).Objects[0]; + + /* + if (ActiveEntity != null && BlockingDialog != null) + { + //are we still waiting on a blocking dialog? if not, cancel. + if (ActiveEntity.Thread != null && (ActiveEntity.Thread.BlockingState == null || !(ActiveEntity.Thread.BlockingState is VMDialogResult))) + { + BlockingDialog.Close(); + LastDialogID = 0; + BlockingDialog = null; + } + }*/ + + if (Visible) + { + if (ShowTooltip) state.UIState.TooltipProperties.UpdateDead = false; + + bool scrolled = false; + if (RMBScroll) + { + World.State.ScrollAnchor = null; + Vector2 scrollBy = new Vector2(); + if (state.TouchMode) + { + scrollBy = new Vector2(RMBScrollX - state.MouseState.X, RMBScrollY - state.MouseState.Y); + RMBScrollX = state.MouseState.X; + RMBScrollY = state.MouseState.Y; + scrollBy /= 128f; + scrollBy /= FSOEnvironment.DPIScaleFactor; + } + else + { + scrollBy = new Vector2(state.MouseState.X - RMBScrollX, state.MouseState.Y - RMBScrollY); + scrollBy *= 0.0005f; + + var angle = (Math.Atan2(state.MouseState.X - RMBScrollX, (RMBScrollY - state.MouseState.Y) * 2) / Math.PI) * 4; + angle += 8; + angle %= 8; + + CursorType type = CursorType.ArrowUp; + switch ((int)Math.Round(angle)) + { + case 0: type = CursorType.ArrowUp; break; + case 1: type = CursorType.ArrowUpRight; break; + case 2: type = CursorType.ArrowRight; break; + case 3: type = CursorType.ArrowDownRight; break; + case 4: type = CursorType.ArrowDown; break; + case 5: type = CursorType.ArrowDownLeft; break; + case 6: type = CursorType.ArrowLeft; break; + case 7: type = CursorType.ArrowUpLeft; break; + } + GameFacade.Cursor.SetCursor(type); + } + World.Scroll(scrollBy * (60f / FSOEnvironment.RefreshRate)); + scrolled = true; + } + if (MouseIsOn) + { + if (state.MouseState.RightButton == ButtonState.Pressed) + { + if (RMBScroll == false) + { + RMBScroll = true; + RMBScrollX = state.MouseState.X; + RMBScrollY = state.MouseState.Y; + } + } + else + { + if (!scrolled && GlobalSettings.Default.EdgeScroll && !state.TouchMode) scrolled = World.TestScroll(state); + } + } + + if (state.MouseState.RightButton != ButtonState.Pressed) + { + if (RMBScroll) GameFacade.Cursor.SetCursor(CursorType.Normal); + RMBScroll = false; + } + + if (LiveMode) LiveModeUpdate(state, scrolled); + //else if (CustomControl != null) CustomControl.Update(state, scrolled); + //else ObjectHolder.Update(state, scrolled); + + //set cutaway around mouse + UpdateCutaway(state); + } + } + + private void UpdateCutaway(UpdateState state) + { + if (vm.Context.Blueprint != null) + { + World.State.DynamicCutaway = (WallsMode == 1); + //first we need to cycle the rooms that are being cutaway. Keep this up even if we're in all-cut mode. + var mouseTilePos = World.EstTileAtPosWithScroll(new Vector2(state.MouseState.X, state.MouseState.Y) / FSOEnvironment.DPIScaleFactor); + var roomHover = vm.Context.GetRoomAt(LotTilePos.FromBigTile((short)(mouseTilePos.X), (short)(mouseTilePos.Y), World.State.Level)); + var outside = (vm.Context.RoomInfo[roomHover].Room.IsOutside); + if (!outside && !CutRooms.Contains(roomHover)) + CutRooms.Add(roomHover); //outside hover should not persist like with other rooms. + while (CutRooms.Count > 3) CutRooms.Remove(CutRooms.ElementAt(0)); + + if (LastWallMode != WallsMode) + { + if (WallsMode == 0) //walls down + { + LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height]; + vm.Context.Blueprint.Cutaway = LastCuts; + vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED)); + for (int i = 0; i < LastCuts.Length; i++) LastCuts[i] = true; + } + else if (WallsMode == 1) + { + MouseCutRect = new Rectangle(); + LastCutRooms = new HashSet() { uint.MaxValue }; //must regenerate cuts + } + else //walls up or roof + { + LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height]; + vm.Context.Blueprint.Cutaway = LastCuts; + vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED)); + } + LastWallMode = WallsMode; + } + + if (WallsMode == 1) + { + HashSet finalRooms; + int recut = 0; + if (FSOEnvironment.SoftwareKeyboard) + { + finalRooms = new HashSet(); + foreach (var room in vm.Context.RoomInfo) + { + if (!room.Room.IsOutside && room.Room.Floor == World.State.Level-1) finalRooms.Add(room.Room.RoomID); + } + } + else + { + if (RMBScroll || !MouseIsOn) return; + finalRooms = new HashSet(CutRooms); + var newCut = new Rectangle((int)(mouseTilePos.X - 2.5), (int)(mouseTilePos.Y - 2.5), 5, 5); + newCut.X -= VMArchitectureTools.CutCheckDir[(int)World.State.Rotation][0] * 2; + newCut.Y -= VMArchitectureTools.CutCheckDir[(int)World.State.Rotation][1] * 2; + if (newCut != MouseCutRect) + { + MouseCutRect = newCut; + recut = 1; + } + } + + if (LastFloor != World.State.Level || LastRotation != World.State.Rotation || !finalRooms.SetEquals(LastCutRooms)) + { + LastCuts = VMArchitectureTools.GenerateRoomCut(vm.Context.Architecture, World.State.Level, World.State.Rotation, finalRooms); + recut = 2; + LastFloor = World.State.Level; + LastRotation = World.State.Rotation; + } + LastCutRooms = finalRooms; + + if (recut > 0) + { + var finalCut = new bool[LastCuts.Length]; + Array.Copy(LastCuts, finalCut, LastCuts.Length); + var notableChange = VMArchitectureTools.ApplyCutRectangle(vm.Context.Architecture, World.State.Level, finalCut, MouseCutRect); + if (recut > 1 || notableChange || LastRectCutNotable) + { + vm.Context.Blueprint.Cutaway = finalCut; + vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED)); + } + LastRectCutNotable = notableChange; + } + } + } + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UILotControlTouchHelper.cs b/Client/Simitone/Simitone.Client/UI/Panels/UILotControlTouchHelper.cs new file mode 100644 index 0000000..3151fae --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UILotControlTouchHelper.cs @@ -0,0 +1,295 @@ +using FSO.Client.UI.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Common.Rendering.Framework.Model; +using Microsoft.Xna.Framework; +using FSO.Client; +using FSO.Common; +using FSO.HIT; +using FSO.Client.UI.Model; +using Simitone.Client.UI.Screens; + +namespace Simitone.Client.UI.Panels +{ + public class UILotControlTouchHelper : UIElement + { + private UILotControl Master; + public HashSet MiceDown = new HashSet(); + private int UpdatesSinceDraw; + private Vector2 ScrollVelocity; + private Vector2 LastValidScrollVelocity; + private int MiceDownTimer; + private Point TapPoint; + private const int TAP_TIMER = 8; //current time for a tap to register is a third of a second. if + private const int TAP_POINT_DIST = 30; //current px distance for a tap to move to become a scroll. TODO: dpi scale? + private List ScrollVelocityHistory = new List(); + + private int Mode = 0; //-1: none, 0: touch, 1: scroll, 2: zoomscroll, 3: touched + //you can't revert back to touch after activating it + private Vector2 BaseVector; + private float StartScale; + private float RotateAngle; + + private UIRotationAnimation RotationAnim; + + private float[] SnapZooms = + { + 0.25f, + 0.5f, + 1f + }; + + public UILotControlTouchHelper(UILotControl master) + { + Master = master; + } + + private int LastMouseWheel; + private bool ScrollWheelInvalid; + private int ZoomFreezeTime; + public override void Update(UpdateState state) + { + base.Update(state); + bool rotated = false; + + if (!FSOEnvironment.SoftwareKeyboard) + { + if (!state.WindowFocused) ScrollWheelInvalid = true; + else if (ScrollWheelInvalid) + { + LastMouseWheel = state.MouseState.ScrollWheelValue; + ScrollWheelInvalid = false; + } + if (state.WindowFocused && state.MouseState.ScrollWheelValue != LastMouseWheel) + { + var diff = state.MouseState.ScrollWheelValue - LastMouseWheel; + Master.TargetZoom = Master.TargetZoom + diff / 1000f; + LastMouseWheel = state.MouseState.ScrollWheelValue; + Master.TargetZoom = Math.Max(0.25f, Math.Min(Master.TargetZoom, 2)); + ZoomFreezeTime = 10; + } + } + + MiceDown = new HashSet(MiceDown.Intersect(state.MouseStates.Select(x => x.ID))); + + int transitionTo = -2; + if (MiceDown.Count == 0) + { + if (Mode != -1) transitionTo = -1; + } else if (MiceDown.Count == 1) + { + if (Mode == -1) transitionTo = 0; + if (Mode == 2) transitionTo = 1; + } else if (MiceDown.Count >= 2) + { + //cannot possibly be a touch + if (Mode < 2) transitionTo = 2; + if (Mode == -1) Mode = 0; + } + + switch (Mode) + { + case -1: + if (transitionTo == 0) + { + var mouse = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.First()); + if (mouse != null) + { + TapPoint = new Point(mouse.MouseState.X, mouse.MouseState.Y); + MiceDownTimer = 0; + Mode = 0; + } + } + break; + case 0: + case 1: + if (transitionTo == 2) + { + //register the first distance between the two taps + var m1 = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.ElementAt(0)); + var m2 = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.ElementAt(1)); + BaseVector = (new Point(m2.MouseState.X, m2.MouseState.Y) - new Point(m1.MouseState.X, m1.MouseState.Y)).ToVector2(); + StartScale = Master.TargetZoom; + + //scroll anchor should change to center of two touches without drastically changing scroll + TapPoint = (new Point(m2.MouseState.X / 2, m2.MouseState.Y / 2) + new Point(m1.MouseState.X / 2, m1.MouseState.Y / 2)); + + Mode = 2; + } + else + { + if (Mode == 0) + { + ScrollVelocity = new Vector2(); + if (transitionTo == -1) Mode = -1; + else { + var mouse = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.First()); + if ((TapPoint - new Point(mouse.MouseState.X, mouse.MouseState.Y)).ToVector2().Length() > TAP_POINT_DIST) + { + Mode = 1; //become a scroll + } + else if (++MiceDownTimer > TAP_TIMER) + { + Mode = 3; + var screenMiddle = new Point(GameFacade.Screens.CurrentUIScreen.ScreenWidth / 2, GameFacade.Screens.CurrentUIScreen.ScreenHeight / 2); + Master.ShowPieMenu(((TapPoint - screenMiddle).ToVector2() / Master.World.BackbufferScale).ToPoint() + screenMiddle, state); + } + } + } + if (Mode == 1) + { + if (transitionTo == -1) + { + //release our scroll velocity + Mode = -1; + } else + { + var mouse = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.First()); + var newTap = new Point(mouse.MouseState.X, mouse.MouseState.Y); + ScrollVelocity = (newTap - TapPoint).ToVector2(); + TapPoint = newTap; + } + } + } + break; + case 2: + if (transitionTo != -2) + { + //release rotation gesture. todo. + } + if (transitionTo == 1) + { + //go back to being a normal scroll + //again, anchor should change to single point without drastic scroll change + var mouse = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.First()); + TapPoint = new Point(mouse.MouseState.X, mouse.MouseState.Y); + Mode = 1; + } else if (transitionTo == -1) + { + Mode = -1; + } else if (transitionTo == -2) + { + var m1 = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.ElementAt(0)); + var m2 = state.MouseStates.FirstOrDefault(x => x.ID == MiceDown.ElementAt(1)); + var vector = (new Point(m2.MouseState.X, m2.MouseState.Y) - new Point(m1.MouseState.X, m1.MouseState.Y)).ToVector2(); + var newTap = (new Point(m2.MouseState.X / 2, m2.MouseState.Y / 2) + new Point(m1.MouseState.X / 2, m1.MouseState.Y / 2)); + ScrollVelocity = (newTap - TapPoint).ToVector2(); + TapPoint = newTap; + + Master.TargetZoom = (vector.Length() / BaseVector.Length()) * StartScale; + + //clockwise if dot product b against a rotated 90 degrees clockwise is positive + var a = BaseVector; + var b = vector; + a.Normalize(); b.Normalize(); + var clockwise = ((-a.Y)*b.X + a.X*b.Y) > 0; + var angle = (float)Math.Acos(Vector2.Dot(a, b)); + RotateAngle = (clockwise) ? angle : -angle; + + if (Math.Abs(RotateAngle) > Math.PI / 8) Master.TargetZoom = StartScale; + } + break; + case 3: + if (transitionTo == -1) Mode = -1; + break; + } + if (Mode != 2 && RotateAngle != 0) + { + if (Math.Abs(RotateAngle) > Math.PI / 4) + { + //confirmed + var screen = ((TS1GameScreen)GameFacade.Screens.CurrentUIScreen); + if (RotateAngle > 0) + { + screen.Rotation = (screen.Rotation + 1) % 4; + } else + { + screen.Rotation = (screen.Rotation + 3) % 4; + } + + HITVM.Get().PlaySoundEvent(UISounds.ObjectRotate); + rotated = true; + } + RotateAngle = 0; + } + ScrollVelocityHistory.Insert(0, ScrollVelocity); + if (ScrollVelocityHistory.Count > 5) ScrollVelocityHistory.RemoveAt(ScrollVelocityHistory.Count - 1); + if (transitionTo == -1) + { + //ScrollVelocity = LastValidScrollVelocity / UpdatesSinceDraw; + if (ScrollVelocityHistory.Count > 1) + { + int total = 0; + ScrollVelocity = new Vector2(); + for (int i=1; i 0) + { + var move = snapZoom - Master.TargetZoom; + if (move != 0) { + if (move > 0) Master.TargetZoom += 0.01f; + else Master.TargetZoom -= 0.01f; + } + if (move * (snapZoom - Master.TargetZoom) < 0) Master.TargetZoom = snapZoom; + } + } + if (ZoomFreezeTime > 0) ZoomFreezeTime--; + } + if (ScrollVelocity.Length() > 0.001f) Master.World.Scroll(-ScrollVelocity / (Master.TargetZoom * 128), false); + + UpdatesSinceDraw++; + + if (Math.Abs(RotateAngle) > Math.PI / 8) //>20 degrees starts a rotation gesture. 40 degrees ends it. + { + if (RotationAnim == null) + { + RotationAnim = new UIRotationAnimation(); + RotationAnim.Position = new Vector2(GameFacade.Screens.CurrentUIScreen.ScreenWidth / 2 - 180, GameFacade.Screens.CurrentUIScreen.ScreenHeight / 2 - 180); + Master.Add(RotationAnim); + } + RotationAnim.Step = Math.Min(1, (Math.Abs(RotateAngle) / ((float)Math.PI / 8) - 1) * 0.8f); + RotationAnim.ScaleX = (RotateAngle > 0) ? 1f:-1f; + RotationAnim.Opacity = RotationAnim.Step; + } else + { + if (RotationAnim != null) + { + RotationAnim.Kill(rotated); + RotationAnim = null; + } + } + } + + public override void Draw(UISpriteBatch batch) + { + //todo: rotation graphic + UpdatesSinceDraw = 1; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIMainPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIMainPanel.cs new file mode 100644 index 0000000..880f96a --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIMainPanel.cs @@ -0,0 +1,288 @@ +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; +using FSO.Common.Rendering.Framework.Model; +using Simitone.Client.UI.Panels.LiveSubpanels; +using Simitone.Client.UI.Screens; +using FSO.Client.UI.Controls; + +namespace Simitone.Client.UI.Panels +{ + public class UIMainPanel : UIContainer + { + private float _CurWidth; + public float CurWidth + { + get + { + return _CurWidth; + } + set + { + _CurWidth = value; + UpdateWidth(); + } + } + + private Texture2D Div; + private Texture2D WhitePx; + private Rectangle DivRect; + private UIDiagonalStripe Diag; + public UISubpanel SubPanel; + public TS1GameScreen Game; + + public UIStencilButton FloorUpBtn; + public UIStencilButton FloorDownBtn; + public UILabel FloorLabel; + public UILabel FloorLabelShadow; + public UICategorySwitcher Switcher; + public UIImage Divider; + public UIStencilButton HideButton; + public bool ShowingSelect; + + public UISwitchAvatarPanel SwitchAvatar; + public bool PanelActive; + + public string[] FloorNames = new string[] + { + "1st", + "2nd", + "3rd", + "4th", + "5th" + }; + public int LastFloor = -1; + + private List LiveCategories = new List() + { + new UICategory() { ID = 0, IconName = "live_motives.png" }, + new UICategory() { ID = 1, IconName = "live_job.png" }, + new UICategory() { ID = 2, IconName = "live_personality.png" }, + new UICategory() { ID = 3, IconName = "live_relationships.png" }, + new UICategory() { ID = 4, IconName = "live_inventory.png" } + }; + + public UIMainPanel(TS1GameScreen game) : base() + { + Game = game; + Diag = new UIDiagonalStripe(new Point(0, 128), UIDiagonalStripeSide.RIGHT, UIStyle.Current.Bg); + Add(Diag); + WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice); + var ui = Content.Get().CustomUI; + Div = ui.Get("panel_div.png").Get(GameFacade.GraphicsDevice); + + FloorUpBtn = new UIStencilButton(ui.Get("level_up.png").Get(GameFacade.GraphicsDevice)); + FloorUpBtn.Position = new Vector2(80, 10); + FloorUpBtn.OnButtonClick += (b) => { if (Game.Level < 5) Game.Level++; }; + Add(FloorUpBtn); + + FloorDownBtn = new UIStencilButton(ui.Get("level_down.png").Get(GameFacade.GraphicsDevice)); + FloorDownBtn.Position = new Vector2(80, 68); + FloorDownBtn.OnButtonClick += (b) => { if (Game.Level > 1) Game.Level--; }; + Add(FloorDownBtn); + + FloorLabel = new UILabel(); + FloorLabel.CaptionStyle = FloorLabel.CaptionStyle.Clone(); + FloorLabel.CaptionStyle.Size = 15; + FloorLabel.CaptionStyle.Color = UIStyle.Current.Text; + FloorLabel.Alignment = TextAlignment.Middle | TextAlignment.Center; + FloorLabel.Position = new Vector2(80, 64); + FloorLabel.Size = new Vector2(51, 18); + + FloorLabelShadow = new UILabel(); + FloorLabelShadow.CaptionStyle = FloorLabel.CaptionStyle.Clone(); + FloorLabelShadow.Alignment = TextAlignment.Middle | TextAlignment.Center; + FloorLabelShadow.Position = new Vector2(83, 67); + FloorLabelShadow.Size = new Vector2(51, 18); + FloorLabelShadow.CaptionStyle.Color = Color.Black * 0.5f; + Add(FloorLabelShadow); + Add(FloorLabel); + + HideButton = new UIStencilButton(ui.Get("panel_hide.png").Get(GameFacade.GraphicsDevice)); + HideButton.X = Game.ScreenWidth - (50 + 64 + 15); + HideButton.Y = 26; + HideButton.OnButtonClick += (b) => { Close(); }; + Add(HideButton); + + Divider = new UIImage(ui.Get("divider.png").Get(GameFacade.GraphicsDevice)); + Divider.Position = new Vector2(146, 29); + Add(Divider); + + Switcher = new UICategorySwitcher(); + Switcher.Position = new Vector2(164, 0); + Switcher.InitCategories(LiveCategories); + Switcher.OnCategorySelect += Switcher_OnCategorySelect; + Add(Switcher); + + foreach (var fade in GetFadeables()) + { + fade.Opacity = 0; + } + + CurWidth = 0; + } + + public void Switcher_OnCategorySelect(int obj) + { + UISubpanel panel = null; + switch (obj) + { + case 0: + panel = new UIMotiveSubpanel(Game); break; + case 1: + panel = new UIJobSubpanel(Game); break; + case 2: + panel = new UIPersonalitySubpanel(Game); break; + case 3: + panel = new UIRelationshipSubpanel(Game); break; + case 4: + panel = new UIInventorySubpanel(Game); break; + } + SetSubpanel(panel); + } + + public void SetSubpanel(UISubpanel sub) + { + if (SubPanel != null) + { + SubPanel.Kill(); + } + SubPanel = sub; + if (sub != null) + { + SubPanel.Position = new Vector2(263, 0); + Add(SubPanel); + } + } + + private void UpdateWidth() + { + //prepanel width is 167 + //div width is 52 + + var iWidth = (int)CurWidth; + if (iWidth < 211) + { + Diag.X = 0; + Diag.BodySize = new Point(iWidth, 128); + DivRect = new Rectangle(); + } else if (iWidth < 211+52) + { + Diag.X = iWidth; + Diag.BodySize = new Point(0, 128); + DivRect = new Rectangle(0, 0, iWidth - 211, 128); + } else + { + Diag.X = 211 + 52; + Diag.BodySize = new Point(iWidth - (211 + 52), 128); + DivRect = new Rectangle(0, 0, 52, 128); + } + } + + public UIElement[] GetFadeables() + { + return new UIElement[] + { + FloorUpBtn, + FloorDownBtn, + FloorLabel, + FloorLabelShadow, + Switcher.MainButton, + Divider, + HideButton + }; + } + + public override void Draw(UISpriteBatch batch) + { + if (CurWidth > 211) + { + if (ShowingSelect) + { + DrawLocalTexture(batch, WhitePx, null, new Vector2(0, 0), new Vector2(211+52, 128), UIStyle.Current.Bg); + } + else + { + DrawLocalTexture(batch, WhitePx, null, new Vector2(0, 0), new Vector2(211, 128), UIStyle.Current.Bg); + DrawLocalTexture(batch, Div, DivRect, new Vector2(211, 0), Vector2.One, UIStyle.Current.Bg); + } + } + base.Draw(batch); + + } + + public override void Update(UpdateState state) + { + base.Update(state); + Visible = _CurWidth > 0; + + if (Game.Level != LastFloor) + { + LastFloor = Game.Level; + FloorLabel.Caption = FloorNames[LastFloor - 1]; + FloorLabelShadow.Caption = FloorNames[LastFloor - 1]; + FloorDownBtn.Disabled = LastFloor == 1; + FloorUpBtn.Disabled = LastFloor == 5; + } + } + + public void Open() + { + Visible = true; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "CurWidth", GameFacade.Screens.CurrentUIScreen.ScreenWidth-(64+15)} }, TweenQuad.EaseOut); + foreach (var fade in GetFadeables()) + { + GameFacade.Screens.Tween.To(fade, 0.3f, new Dictionary() { { "Opacity", 1f } }); + } + PanelActive = true; + } + + public void Close() + { + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "CurWidth", 0 } }, TweenQuad.EaseOut); + SetSubpanel(null); + foreach (var fade in GetFadeables()) + { + GameFacade.Screens.Tween.To(fade, 0.3f, new Dictionary() { { "Opacity", 0f } }); + } + if (Switcher.CategoryExpand > 0) Switcher.Close(); + + SwitchAvatar?.Kill(); + SwitchAvatar = null; + PanelActive = false; + } + + public void ShowSelect() + { + var add = new UISwitchAvatarPanel(Game); + Add(add); + + SetSubpanel(null); + foreach (var fade in GetFadeables()) + { + GameFacade.Screens.Tween.To(fade, 0.3f, new Dictionary() { { "Opacity", 0f } }); + } + if (Switcher.CategoryExpand > 0) Switcher.Close(); + ShowingSelect = true; + SwitchAvatar = add; + + add.OnEnd += () => + { + Open(); + Switcher_OnCategorySelect(Switcher.ActiveCategory); + SwitchAvatar = null; + ShowingSelect = false; + }; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIMobileAlert.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIMobileAlert.cs new file mode 100644 index 0000000..58559be --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIMobileAlert.cs @@ -0,0 +1,252 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.Client.UI.Framework; +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; +using FSO.Common.Rendering.Framework.Model; + +namespace Simitone.Client.UI.Panels +{ + public class UIMobileAlert : UIMobileDialog + { + private UIAlertOptions m_Options; + private TextRendererResult m_MessageText; + private TextStyle m_TextStyle; + + private UIImage Icon; + private Vector2 IconSpace; + + private List Buttons; + private UITextBox TextBox; + + public string ResponseText + { + get + { + return (TextBox == null) ? null : TextBox.CurrentText; + } + set + { + if (TextBox != null) TextBox.CurrentText = value; + } + } + + public UIMobileAlert(UIAlertOptions options) : base() + { + this.m_Options = options; + + m_TextStyle = TextStyle.DefaultLabel.Clone(); + m_TextStyle.Size = 19; + m_TextStyle.Color = Color.White; + + Caption = options.Title; + + Icon = new UIImage(); + Icon.Visible = false; + Icon.Position = new Vector2(32, 32); + Icon.SetSize(0, 0); + Add(Icon); + + /** Determine the size **/ + ComputeText(); + + /** Add buttons **/ + Buttons = new List(); + + foreach (var button in options.Buttons) + { + string buttonText = ""; + if (button.Text != null) buttonText = button.Text; + else + { + switch (button.Type) + { + case UIAlertButtonType.OK: + buttonText = GameFacade.Strings.GetString("142", "ok button"); + break; + case UIAlertButtonType.Yes: + buttonText = GameFacade.Strings.GetString("142", "yes button"); + break; + case UIAlertButtonType.No: + buttonText = GameFacade.Strings.GetString("142", "no button"); + break; + case UIAlertButtonType.Cancel: + buttonText = GameFacade.Strings.GetString("142", "cancel button"); + break; + } + } + var btnElem = AddButton(buttonText, button.Type, button.Handler == null); + Buttons.Add(btnElem); + if (button.Handler != null) btnElem.OnButtonClick += button.Handler; + } + + if (options.TextEntry) + { + TextBox = new UITextBox(); + TextBox.MaxChars = options.MaxChars; + this.Add(TextBox); + } + + /** Position buttons **/ + RefreshSize(); + } + + public void RefreshSize() + { + var w = Width; + var h = m_Options.Height; + + h = Math.Max(h, Math.Max((int)IconSpace.Y - 25, m_MessageText == null ? 0 : m_MessageText.BoundingBox.Height) + 105); + + if (Buttons.Count > 0) + { + h += 175; + } + else + { + h += 32; + } + + if (m_Options.TextEntry) + { + TextBox.X = 32; + TextBox.Y = h - 54; + TextBox.SetSize(w - 64, 25); + 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; + } + + if (Height != h) + { + SetHeight(h); + } + //update bg with height + } + + private float TargetIX; + + public void SetIcon(Texture2D img, int width, int height) + { + if (img.Height < 4) return; + Icon.Texture = img; + + float scale = Math.Min(3, Math.Min((float)height / (float)img.Height, (float)width / (float)img.Width)); + if (scale * img.Height + 20 < height) height = (int)(scale * img.Height + 20); + IconSpace = new Vector2(width + 30, height); + Icon.SetSize(img.Width * scale, img.Height * scale); + Icon.Position = new Vector2(50, 110) + new Vector2(width / 2 - (img.Width * scale / 2), height / 2 - (img.Height * scale / 2)); + TargetIX = Icon.Position.X; + + ComputeText(); + RefreshSize(); + } + + /// + /// Map of buttons attached to this message box. + /// + public Dictionary ButtonMap = new Dictionary(); + + /// + /// Adds a button to this message box. + /// + /// Label of the button. + /// Type of the button to be added. + /// Should the button's click be handled internally? + /// + private UIButton AddButton(string label, UIAlertButtonType type, bool InternalHandler) + { + var btn = new UIBigButton(type == UIAlertButtonType.OK || type == UIAlertButtonType.Yes); + btn.Visible = false; + btn.Caption = label; + if (btn.Width < 275) btn.Width = 275; + + if (InternalHandler) + btn.OnButtonClick += new ButtonClickDelegate(x => + { + HandleClose(); + }); + + ButtonMap.Add(type, btn); + + this.Add(btn); + return btn; + } + + private void HandleClose() + { + Close(); + } + + private bool m_TextDirty = false; + protected override void CalculateMatrix() + { + base.CalculateMatrix(); + m_TextDirty = true; + } + + private void ComputeText() + { + var margin = (IconSpace.X > 0) ? 50 : 80; + m_MessageText = TextRenderer.ComputeText(m_Options.Message, new TextRendererOptions + { + Alignment = TextAlignment.Left | TextAlignment.Top, + MaxWidth = Width - margin * 2, + Position = new Microsoft.Xna.Framework.Vector2(margin, 105), + Scale = _Scale, + TextStyle = m_TextStyle, + WordWrap = true, + TopLeftIconSpace = IconSpace + }, this); + + m_TextDirty = false; + } + + public override void Update(UpdateState state) + { + base.Update(state); + var off = ((Closing) ? 1 : -1) * (1 - InterpolatedAnimation) * Width; + var newIX = TargetIX + off; + if (Icon.X != newIX) + { + Icon.Visible = true; + Icon.X = newIX; + var btnX = (Width - ((Buttons.Count - 1) * 350)) / 2; + foreach (UIButton button in Buttons) + { + button.X = off + btnX - button.Width / 2; + button.Visible = true; + btnX += 350; + } + } + } + + public override void Draw(UISpriteBatch batch) + { + m_TextStyle.Color = UIStyle.Current.DialogText * InterpolatedAnimation; + base.Draw(batch); + + if (m_TextDirty) + { + ComputeText(); + } + + TextRenderer.DrawText(m_MessageText.DrawingCommands, this, batch); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIMoneyPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIMoneyPanel.cs new file mode 100644 index 0000000..b4f22b2 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIMoneyPanel.cs @@ -0,0 +1,91 @@ +using FSO.Client; +using FSO.Client.UI.Controls; +using FSO.Client.UI.Framework; +using FSO.Common.Utils; +using Simitone.Client.UI.Model; +using Simitone.Client.UI.Screens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Common.Rendering.Framework.Model; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using FSO.Content; + +namespace Simitone.Client.UI.Panels +{ + public class UIMoneyPanel : UIContainer + { + public int LastMoney = 0; + private TS1GameScreen Game; + private UILabel MoneyLabel; + private Texture2D Bg; + + public UIMoneyPanel(TS1GameScreen game) : base() + { + Game = game; + LastMoney = GetMoney(); + + MoneyLabel = new UILabel(); + MoneyLabel.CaptionStyle = MoneyLabel.CaptionStyle.Clone(); + MoneyLabel.CaptionStyle.Size = 15; + MoneyLabel.CaptionStyle.Color = UIStyle.Current.Text; + MoneyLabel.Alignment = FSO.Client.UI.Framework.TextAlignment.Center | FSO.Client.UI.Framework.TextAlignment.Middle; + MoneyLabel.Size = new Microsoft.Xna.Framework.Vector2(128, 24); + Add(MoneyLabel); + + Bg = Content.Get().CustomUI.Get("money_bg.png").Get(GameFacade.GraphicsDevice); + + UpdateMoneyDisplay(); + } + + public void DisplayChange(int change) + { + var newLabel = new UILabel(); + newLabel.Y = -20f; + newLabel.CaptionStyle = MoneyLabel.CaptionStyle.Clone(); + newLabel.CaptionStyle.Size = 15; + newLabel.CaptionStyle.Color = (change > 0) ? UIStyle.Current.PosMoney : UIStyle.Current.NegMoney; + newLabel.Alignment = FSO.Client.UI.Framework.TextAlignment.Right | FSO.Client.UI.Framework.TextAlignment.Middle; + newLabel.Size = new Microsoft.Xna.Framework.Vector2(128, 24); + + newLabel.Caption = ((change > 0) ? "+" : "-") + "§" + Math.Abs(change); + Add(newLabel); + + GameFacade.Screens.Tween.To(newLabel, 1.5f, new Dictionary() { { "Y", -50 }, { "Opacity", 0 } }); + GameThread.SetTimeout(() => { Remove(newLabel); }, 1500); + } + + private void UpdateMoneyDisplay() + { + MoneyLabel.Caption = "§" + LastMoney.ToString("##,#0"); + } + + private int GetMoney() + { + return Game.ActiveFamily?.Budget ?? 0; + } + + public override void Update(UpdateState state) + { + base.Update(state); + var money = GetMoney(); + if (LastMoney != money) + { + DisplayChange(money - LastMoney); + LastMoney = money; + UpdateMoneyDisplay(); + } + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Bg, new Rectangle(0, 0, 12, 24), Vector2.Zero, Vector2.One, UIStyle.Current.Bg); + DrawLocalTexture(batch, Bg, new Rectangle(12, 0, 12, 24), new Vector2(12, 0), new Vector2(8.666667f, 1), UIStyle.Current.Bg); + DrawLocalTexture(batch, Bg, new Rectangle(24, 0, 12, 24), new Vector2(116, 0), Vector2.One, UIStyle.Current.Bg); + base.Draw(batch); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UINeighbourhoodSelectionPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UINeighbourhoodSelectionPanel.cs new file mode 100644 index 0000000..4195107 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UINeighbourhoodSelectionPanel.cs @@ -0,0 +1,389 @@ +using FSO.Client.UI.Controls; +using FSO.Client.UI.Framework; +using FSO.Common.Rendering.Framework.IO; +using FSO.Content.Framework; +using FSO.Content.Model; +using FSO.Files.Formats.IFF.Chunks; +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; +using FSO.Common.Rendering.Framework.Model; +using FSO.HIT; +using FSO.Client; +using FSO.Content; +using FSO.Common.Utils; +using Simitone.Client.UI.Controls; + +namespace Simitone.Client.UI.Panels +{ + public class UINeighborhoodSelectionPanel : UIContainer + { + + public static NeighborhoodViewConfig[] Neighborhoods = new NeighborhoodViewConfig[] + { + new NeighborhoodViewConfig() + { + Graphic = "Nbhd\\NScreen.BMP", + Scale = 1f, + FullImageAnimations = new NeighborhoodImageAnim[] {new NeighborhoodImageAnim("Nbhd\\DiffN1-N2_8.bmp", "Nbhd\\DiffN1-N3_8.bmp", "Nbhd\\DiffN1-N4_8.bmp") } + }, + new NeighborhoodViewConfig() + { + Graphic = "Downtown\\DScreen.bmp", + Music = "station_dtnhood", + Scale = 1f, + FullImageAnimations = new NeighborhoodImageAnim[] {new NeighborhoodImageAnim("Downtown\\dscreen00.bmp", "Downtown\\dscreen01.bmp", "Downtown\\dscreen02.bmp", "Downtown\\dscreen03.bmp", "Downtown\\dscreen04.bmp") } + }, + new NeighborhoodViewConfig() + { + Graphic = "VIsland\\visland.bmp", + Music = "station_vacation", + Scale = 1f, + FullImageAnimations = new NeighborhoodImageAnim[] { + new NeighborhoodImageAnim("VIsland\\visland_waves001.bmp", "VIsland\\visland_waves002.bmp", "VIsland\\visland_waves003.bmp", "VIsland\\visland_waves004.bmp", "VIsland\\visland_waves005.bmp"), + new NeighborhoodImageAnim("VIsland\\visland_port.bmp"), + new NeighborhoodImageAnim("VIsland\\visland_trees.bmp"), + } //TODO: nessie + }, + new NeighborhoodViewConfig() + { + Graphic = "Community\\NScreen_unleashed.bmp", + Scale = 2f, + Pulsate = false, + FullImageAnimations = new NeighborhoodImageAnim[] {new NeighborhoodImageAnim("Community\\NScreen_unleashed_waves001.bmp", "Community\\NScreen_unleashed_waves002.bmp", "Community\\NScreen_unleashed_waves003.bmp", "Community\\NScreen_unleashed_waves004.bmp", "Community\\NScreen_unleashed_waves005.bmp", "Community\\NScreen_unleashed_waves006.bmp") }, + BGSound = "river_loop" + }, + new NeighborhoodViewConfig() + { + Graphic = "Studiotown\\DScreen.bmp", + Music = "station_superstar", + Scale = 1f, + FullImageAnimations = new NeighborhoodImageAnim[] {new NeighborhoodImageAnim("Studiotown\\DScreen_top_layer.bmp") } //TODO: cars + }, + new NeighborhoodViewConfig(), + new NeighborhoodViewConfig() + { + Graphic = "Magicland\\DScreen.bmp", + Pulsate = false, + Music = "music_magictown", + BGSound = "mt_river_loop", + Scale = 1f, + FullImageAnimations = new NeighborhoodImageAnim[] {new NeighborhoodImageAnim(new Vector2(0, 62), "Magicland\\DScreen_waves1.bmp", "Magicland\\DScreen_waves2.bmp", "Magicland\\DScreen_waves3.bmp", "Magicland\\DScreen_waves4.bmp", "Magicland\\DScreen_waves5.bmp", "Magicland\\DScreen_waves6.bmp") } //todo: blimp + }, + }; + + public TS1Provider Provider; + public event Action OnHouseSelect; + public HITSound BgSound; + public Dictionary HousePositions; + + private Vector2 _cp = new Vector2(800, 600) / 2; + public float CenterPositionX + { + get + { + return _cp.X; + } + set + { + _cp.X = value; + } + } + + public float CenterPositionY + { + get + { + return _cp.Y; + } + set + { + _cp.Y = value; + UpdatePosition(); + } + } + + private float _z = 1f; + public float Zoom + { + get + { + return _z; + } + set + { + _z = value; + } + } + + public UINeighborhoodSelectionPanel(ushort mode) + { + Provider = Content.Get().TS1Global; + PopulateScreen(mode); + GameResized(); + } + + + public void UpdatePosition() + { + base.GameResized(); + var scale = GlobalSettings.Default.GraphicsHeight / 600.0f; + ScaleX = ScaleY = scale * Zoom; + + X = (GlobalSettings.Default.GraphicsWidth) / 2 - _cp.X * ScaleX; + Y = (GlobalSettings.Default.GraphicsHeight) / 2 - _cp.Y * ScaleY; + } + + public override void GameResized() + { + UpdatePosition(); + } + + private Texture2D texture; + private int Mode; + + public void PopulateScreen(ushort mode) + { + var childClone = new List(Children); + var config = Neighborhoods[mode - 1]; + foreach (var child in childClone) Remove(child); + + var shad = new UIImage(Content.Get().CustomUI.Get("ngbh_outline.png").Get(GameFacade.GraphicsDevice)) + .With9Slice(24, 24, 24, 24); + shad.SetSize(800 + 48, 600 + 48); + shad.Position = new Vector2(-24); + Add(shad); + + var bg = new UIImage(((ITextureRef)Provider.Get(config.Graphic)).Get(GameFacade.GraphicsDevice)); + Add(bg); + bg.ListenForMouse((evt, state) => + { + if (evt == UIMouseEventType.MouseDown) ResetZoom(); + }); + + HousePositions = new Dictionary(); + var locationIff = Content.Get().Neighborhood.LotLocations; + var locations = locationIff.Get(mode); + if (locations == null) return; + + var buttons = new List(); + + for (int i = 0; i < locations.Length; i++) + { + Console.WriteLine(locations.GetString(i)); + var loc = locations.GetString(i).Split(','); + var num = int.Parse(loc[0].TrimStart()); + var button = new UINeighborhoodHouseButton(num, SelectHouse, config.Scale); + button.Position = new Vector2(int.Parse(loc[1].TrimStart()), int.Parse(loc[2].TrimStart())); + HousePositions[num] = button.Position; + buttons.Add(button); + } + + var ordered = buttons.OrderBy(x => x.Y); + foreach (var btn in ordered) Add(btn); + + foreach (var layer in config.FullImageAnimations) + { + var lelem = new UINeighborhoodAnimationLayer(layer, config.Pulsate, config.FrameDuration); + lelem.Position = layer.Position; + Add(lelem); + } + + BgSound?.RemoveOwner(-25); + if (config.Music != null) FSO.HIT.HITVM.Get().PlaySoundEvent(config.Music); + if (config.BGSound != null) + { + BgSound = HITVM.Get().PlaySoundEvent(config.BGSound); + BgSound.AddOwner(-25); + } + Mode = mode; + Zoom = Zoom; + CenterPositionX = CenterPositionX; + CenterPositionY = CenterPositionY; + } + + public void ResetZoom() + { + if (LastHS == null) return; + LastHS.Kill(); + LastHS = null; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "Zoom", 1f }, { "CenterPositionX", 400 }, { "CenterPositionY", 300 } }, TweenQuad.EaseOut); + } + + public UIHouseSelectPanel LastHS; + + public void SelectHouse(int house) + { + if (LastHS != null && LastHS.HouseID == house) + { + ResetZoom(); + } + else + { + LastHS?.Kill(); + LastHS = new UIHouseSelectPanel(house); + GameFacade.Screens.CurrentUIScreen.Add(LastHS); + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { + { "Zoom", (Mode==4)?3f:1.5f }, + { "CenterPositionX", HousePositions[house].X - ((Mode==4)?90f:180f) }, + { "CenterPositionY", HousePositions[house].Y } }, TweenQuad.EaseOut); + + LastHS.OnSelected += (h) => + { + OnHouseSelect?.Invoke(h); + HITVM.Get().PlaySoundEvent("bkground_fade"); + }; + } + } + + public override void Removed() + { + base.Removed(); + BgSound?.RemoveOwner(-25); + } + + public override void Draw(UISpriteBatch batch) + { + base.Draw(batch); + //DrawLocalTexture(batch, texture, new Vector2()); + } + + public override void Update(UpdateState state) + { + base.Update(state); + } + } + + public class UINeighborhoodAnimationLayer : UIElement + { + + public Texture2D[] Frames; + public int FrameNum; + public int SubFrame; + public int FrameTime; + private int TotalFrames; + public NeighborhoodImageAnim Anim; + + public UINeighborhoodAnimationLayer(NeighborhoodImageAnim anim, bool pulsate, int frameTime) + { + var provider = Content.Get().TS1Global; + Frames = anim.Frames.Select(x => ((ITextureRef)provider.Get(x)).Get(GameFacade.GraphicsDevice)).ToArray(); + SubFrame = frameTime; + FrameTime = frameTime; + FrameTime *= GlobalSettings.Default.TargetRefreshRate; + FrameTime /= 60; + TotalFrames = pulsate ? (Frames.Length * 2 - 2) : Frames.Length; + } + + public override void Update(UpdateState state) + { + base.Update(state); + if (--SubFrame <= 0) + { + SubFrame = FrameTime; + FrameNum++; + if (TotalFrames != 0) FrameNum %= TotalFrames; + } + } + + public override void Draw(UISpriteBatch batch) + { + var realFrame = (FrameNum >= Frames.Length) ? ((Frames.Length - 2) - (FrameNum - Frames.Length)) : FrameNum; + var fm2 = (TotalFrames != 0) ? ((FrameNum + 1) % TotalFrames) : 0; + var realFrame2 = (fm2 >= Frames.Length) ? ((Frames.Length - 2) - (fm2 - Frames.Length)) : fm2; + DrawLocalTexture(batch, Frames[Math.Max(0, realFrame)], Vector2.Zero); + DrawLocalTexture(batch, Frames[Math.Max(0, realFrame2)], null, Vector2.Zero, Vector2.One, Color.White * (1 - ((float)SubFrame / FrameTime))); + } + } + + public class NeighborhoodViewConfig + { + public string Graphic; + public float Scale; + public NeighborhoodImageAnim[] FullImageAnimations = new NeighborhoodImageAnim[0]; + public int FrameDuration = 15; + public bool Pulsate = true; + public string Music = "bkground_nhood1"; + public string BGSound; + } + + public class NeighborhoodImageAnim + { + public string[] Frames; + public Vector2 Position; + + public NeighborhoodImageAnim(params string[] frames) + { + Frames = frames; + } + + public NeighborhoodImageAnim(Vector2 position, params string[] frames) : this(frames) + { + Position = position; + } + } + + public class UINeighborhoodHouseButton : UIElement + { + private Texture2D HouseTex; + private Texture2D HouseOpenTex; + private float HouseScale; + private bool Hovered; + private THMB Offsets; + public float AlphaTime { get; set; } + + public UINeighborhoodHouseButton(int houseNumber, Action selectionCallback, float scale) + { + AlphaTime = 0; + var house = Content.Get().Neighborhood.GetHouse(houseNumber); + HouseTex = house.Get(513).GetTexture(GameFacade.GraphicsDevice); + HouseOpenTex = house.Get(512).GetTexture(GameFacade.GraphicsDevice); + HouseScale = scale; + Offsets = house.Get(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) => + { + switch (evt) + { + case UIMouseEventType.MouseUp: + Console.WriteLine("mup"); + HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.NeighborhoodClick); + selectionCallback(houseNumber); break; + case UIMouseEventType.MouseOver: + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "AlphaTime", 1f } }); + HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.NeighborhoodRollover); + Hovered = true; break; + case UIMouseEventType.MouseOut: + Console.WriteLine("mout"); + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "AlphaTime", 0f } }); + Hovered = false; break; + } + }); + } + + public override void Draw(UISpriteBatch batch) + { + var yOff = new Vector2(Offsets.XOff, Offsets.BaseYOff) / (HouseScale * 2f); + 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)); + 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); + } + } + + public override void Removed() + { + HouseTex?.Dispose(); + HouseOpenTex?.Dispose(); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIPieMenu.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIPieMenu.cs new file mode 100644 index 0000000..b8367f4 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIPieMenu.cs @@ -0,0 +1,396 @@ +/* +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Model; +using FSO.Client.UI.Controls; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using FSO.Client.Utils; +using FSO.SimAntics; +using FSO.HIT; +using FSO.Vitaboy; +using FSO.Common.Rendering.Framework.Camera; +using FSO.Common.Rendering.Framework; +using FSO.Common.Utils; +using FSO.SimAntics.NetPlay.Model.Commands; +using FSO.Common; +using FSO.Client; + +namespace Simitone.Client.UI.Panels +{ + public class UIPieMenu : UIContainer + { + public UIPieMenuItem m_PieTree; + public List m_PieButtons; + public UIPieMenuItem m_CurrentItem; + public VMEntity m_Obj; + public VMEntity m_Caller; + public UILotControl m_Parent; + public UIImage m_Bg; + + private _3DTargetScene HeadScene; + private BasicCamera HeadCamera; + private double m_BgGrow; + private float TrueScale; + + private bool ShiftDown; //shift activates IDE + + //This is a standard AdultVitaboyModel instance. Since nothing is needed but the head for pie menus, + //the other parts of the body will be stripped from it (see constructor). + private SimAvatar m_Head; + + private TextStyle ButtonStyle; + + public UIPieMenu(List pie, VMEntity obj, VMEntity caller, UILotControl parent) + { + if (FSOEnvironment.UIZoomFactor > 1.33f) ScaleX = ScaleY = FSOEnvironment.UIZoomFactor * 0.75f; + TrueScale = ScaleX * FSOEnvironment.DPIScaleFactor; + m_PieButtons = new List(); + this.m_Obj = obj; + this.m_Caller = caller; + this.m_Parent = parent; + this.ButtonStyle = new TextStyle + { + Font = GameFacade.MainFont, + Size = 12, + Color = new Color(0xA5, 0xC3, 0xD6), + SelectedColor = new Color(0x00, 0xFF, 0xFF), + CursorColor = new Color(255, 255, 255) + }; + + m_Bg = new UIImage(TextureGenerator.GetPieBG(GameFacade.GraphicsDevice)); + m_Bg.SetSize(0, 0); //is scaled up later + this.AddAt(0, m_Bg); + + m_PieTree = new UIPieMenuItem() + { + Category = true + }; + + for (int i = 0; i < pie.Count; i++) + { + string[] depth = (pie[i].Name == null) ? new string[] { "???" } : pie[i].Name.Split('/'); + + var category = m_PieTree; //set category to root + for (int j = 0; j < depth.Length - 1; j++) //iterate through categories + { + if (category.ChildrenByName.ContainsKey(depth[j])) + { + category = category.ChildrenByName[depth[j]]; + } + else + { + var newCat = new UIPieMenuItem() + { + Category = true, + Name = depth[j], + Parent = category + }; + category.Children.Add(newCat); + category.ChildrenByName[depth[j]] = newCat; + category = newCat; + } + } + //we are in the category, put the interaction in here; + + var item = new UIPieMenuItem() + { + Category = false, + Name = depth[depth.Length - 1], + ID = pie[i].ID, + Param0 = pie[i].Param0, + Global = pie[i].Global + }; + category.Children.Add(item); + category.ChildrenByName[item.Name] = item; + } + + m_CurrentItem = m_PieTree; + m_PieButtons = new List(); + RenderMenu(); + + VMAvatar Avatar = (VMAvatar)caller; + m_Head = new SimAvatar(Avatar.Avatar); //talk about confusing... + m_Head.StripAllButHead(); + + initSimHead(); + } + + private void initSimHead() + { + HeadCamera = new BasicCamera(GameFacade.GraphicsDevice, new Vector3(0.0f, 7.0f, -17.0f), Vector3.Zero, Vector3.Up); + + var pos2 = m_Head.Skeleton.GetBone("HEAD").AbsolutePosition; + + HeadCamera.Position = new Vector3(0, pos2.Y, 12.5f); + HeadCamera.Target = pos2; + + HeadScene = new _3DTargetScene(GameFacade.GraphicsDevice, HeadCamera, new Point((int)(200 * TrueScale), (int)(200 * TrueScale)), (GlobalSettings.Default.AntiAlias) ? 8 : 0); + HeadScene.ID = "UIPieMenuHead"; + + m_Head.Scene = HeadScene; + m_Head.Scale = new Vector3(1f); + + HeadCamera.Zoom = 0f; + HeadScene.Add(m_Head); + GameFacade.Scenes.AddExternal(HeadScene); //AddExternal(HeadScene); + } + + public void RotateHeadCam(Vector2 point) + { + double xdir = Math.Atan(-point.X / 100.0); + double ydir = Math.Atan(-point.Y / 100.0); + + Vector3 off = new Vector3(0, 0, 13.5f); + Matrix mat = Microsoft.Xna.Framework.Matrix.CreateRotationY((float)xdir) * Microsoft.Xna.Framework.Matrix.CreateRotationX((float)ydir); + + var pos2 = m_Head.Skeleton.GetBone("HEAD").AbsolutePosition; + HeadCamera.Position = new Vector3(0, pos2.Y, 0) + Vector3.Transform(off, mat); + } + + public void RemoveSimScene() + { + GameFacade.Scenes.RemoveExternal(HeadScene); + HeadScene.Target.Dispose(); + } + + public void UpdateHeadPosition(int x, int y) + { + HeadCamera.ProjectionOrigin = new Vector2(100, 100); + } + + public override void Update(FSO.Common.Rendering.Framework.Model.UpdateState state) + { + base.Update(state); + if (m_BgGrow < 1) + { + m_BgGrow += 1.0 / 30.0 * (60.0 / FSOEnvironment.RefreshRate); + HeadCamera.Zoom = (float)m_BgGrow * 5.12f; + + m_Bg.SetSize((float)m_BgGrow * 200, (float)m_BgGrow * 200); + m_Bg.X = (float)m_BgGrow * (-100); + m_Bg.Y = (float)m_BgGrow * (-100); + } + RotateHeadCam(GlobalPoint(new Vector2(state.MouseState.X, state.MouseState.Y))); + ShiftDown = state.ShiftDown; + } + + public void RenderMenu() + { + for (int i = 0; i < m_PieButtons.Count; i++) //remove previous buttons + { + this.Remove(m_PieButtons[i]); + } + m_PieButtons.Clear(); + + var elems = m_CurrentItem.Children; + int dirConfig; + if (elems.Count > 4) dirConfig = 8; + else if (elems.Count > 2) dirConfig = 4; + else dirConfig = 2; + + for (int i = 0; i < dirConfig; i++) + { + if (i >= elems.Count) break; + var elem = elems.ElementAt(i); + var but = new UIButton() + { + Caption = elem.Name + ((elem.Category) ? "..." : ""), + CaptionStyle = ButtonStyle, + ImageStates = 1, + Texture = TextureGenerator.GetPieButtonImg(GameFacade.GraphicsDevice) + }; + + double dir = (((double)i) / dirConfig) * Math.PI * 2; + but.AutoMargins = 4; + + if (i == 0) + { //top + but.X = (float)(Math.Sin(dir) * 60 - but.Width / 2); + but.Y = (float)((Math.Cos(dir) * -60) - but.Size.Y); + } + else if (i == dirConfig / 2) + { //bottom + but.X = (float)(Math.Sin(dir) * 60 - but.Width / 2); + but.Y = (float)((Math.Cos(dir) * -60)); + } + else if (i < dirConfig / 2) //on right side + { + but.X = (float)(Math.Sin(dir) * 60); + but.Y = (float)((Math.Cos(dir) * -60) - but.Size.Y / 2); + } + else //on left side + { + but.X = (float)(Math.Sin(dir) * 60 - but.Width); + but.Y = (float)((Math.Cos(dir) * -60) - but.Size.Y / 2); + } + + this.Add(but); + m_PieButtons.Add(but); + but.OnButtonClick += new ButtonClickDelegate(PieButtonClick); + but.OnButtonHover += new ButtonClickDelegate(PieButtonHover); + } + + bool top = true; + for (int i = 8; i < elems.Count; i++) + { + var elem = elems.ElementAt(i); + var but = new UIButton() + { + Caption = elem.Name + ((elem.Category) ? "..." : ""), + CaptionStyle = ButtonStyle, + ImageStates = 1, + Texture = TextureGenerator.GetPieButtonImg(GameFacade.GraphicsDevice) + }; + but.AutoMargins = 4; + + but.X = (float)(-but.Width / 2); + if (top) + { //top + but.Y = (float)(-60 - but.Size.Y * ((i - 8) / 2 + 2)); + } + else + { + but.Y = (float)(60 + but.Size.Y * ((i - 8) / 2 + 1)); + } + + this.Add(but); + m_PieButtons.Add(but); + but.OnButtonClick += new ButtonClickDelegate(PieButtonClick); + + top = !top; + } + + if (m_CurrentItem.Parent != null) + { + var but = new UIButton() + { + Caption = m_CurrentItem.Name, + CaptionStyle = ButtonStyle.Clone(), + ImageStates = 1, + Texture = TextureGenerator.GetPieButtonImg(GameFacade.GraphicsDevice) + }; + + but.CaptionStyle.Color = but.CaptionStyle.SelectedColor; + but.AutoMargins = 4; + but.X = (float)(-but.Width / 2); + but.Y = (float)(-but.Size.Y / 2); + this.Add(but); + m_PieButtons.Add(but); + but.OnButtonClick += new ButtonClickDelegate(BackButtonPress); + } + } + + void PieButtonHover(UIElement button) + { + int index = m_PieButtons.IndexOf((UIButton)button); + //todo, make sim look at button + HITVM.Get().PlaySoundEvent(UISounds.PieMenuHighlight); + } + + void BackButtonPress(UIElement button) + { + if (m_CurrentItem.Parent == null) return; //shouldn't ever be... + m_CurrentItem = m_CurrentItem.Parent; + HITVM.Get().PlaySoundEvent(UISounds.PieMenuSelect); + RenderMenu(); + } + + private void PieButtonClick(UIElement button) + { + int index = m_PieButtons.IndexOf((UIButton)button); + if (index == -1) return; //bail! this isn't meant to happen! + var action = m_CurrentItem.Children.ElementAt(index); + HITVM.Get().PlaySoundEvent(UISounds.PieMenuSelect); + + if (action.Category) + { + m_CurrentItem = action; + RenderMenu(); + } + else + { + + if (m_Obj == m_Parent.GotoObject) + { + m_Parent.vm.SendCommand(new VMNetGotoCmd + { + Interaction = action.ID, + ActorUID = m_Caller.PersistID, + x = m_Obj.Position.x, + y = m_Obj.Position.y, + level = m_Obj.Position.Level + }); + } + else + { + if (FSO.Client.Debug.IDEHook.IDE != null && ShiftDown) + { + if (m_Obj.TreeTable.InteractionByIndex.ContainsKey((uint)action.ID)) + { + var act = m_Obj.TreeTable.InteractionByIndex[(uint)action.ID]; + ushort ActionID = act.ActionFunction; + + var function = m_Obj.GetBHAVWithOwner(ActionID, m_Parent.vm.Context); + + FSO.Client.Debug.IDEHook.IDE.IDEOpenBHAV( + function.bhav, + m_Obj.Object + ); + } + } + else + { + m_Parent.vm.SendCommand(new VMNetInteractionCmd + { + Interaction = action.ID, + ActorUID = m_Caller.PersistID, + CalleeID = m_Obj.ObjectID, + Param0 = action.Param0, + Global = action.Global + }); + } + } + HITVM.Get().PlaySoundEvent(UISounds.QueueAdd); + m_Parent.ClosePie(); + + } + } + + public override void PreDraw(UISpriteBatch batch) + { + HeadScene.Draw(GameFacade.GraphicsDevice); + base.PreDraw(batch); + } + + public override void Draw(UISpriteBatch batch) + { + base.Draw(batch); + if (m_CurrentItem == m_PieTree) + { + var invScale = new Vector2(1 / TrueScale, 1 / TrueScale); + DrawLocalTexture(batch, HeadScene.Target, null, new Vector2(-100, -100) * invScale, invScale); + } //if we're top level, draw head! + } + } + + public class UIPieMenuItem + { + public bool Category; + public byte ID; + public short Param0; + public bool Global; + public string Name; + public List Children = new List(); + public Dictionary ChildrenByName = new Dictionary(); + public UIPieMenuItem Parent; + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UIRotationAnimation.cs b/Client/Simitone/Simitone.Client/UI/Panels/UIRotationAnimation.cs new file mode 100644 index 0000000..a4545d2 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UIRotationAnimation.cs @@ -0,0 +1,73 @@ +using FSO.Client.UI.Framework; +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; +using FSO.Common.Rendering.Framework.Model; +using FSO.Content; +using FSO.Client; +using FSO.Common.Utils; + +namespace Simitone.Client.UI.Panels +{ + public class UIRotationAnimation : UICachedContainer + { + public float Step; + public Texture2D ArrowBack; + public Texture2D Arrow; + public Texture2D Segment; + + public UIRotationAnimation() : base() + { + Opacity = 0; + Visible = false; + Size = new Vector2(360, 360); + + var ui = Content.Get().CustomUI; + ArrowBack = ui.Get("rot_arrow_back.png").Get(GameFacade.GraphicsDevice); + Arrow = ui.Get("rot_arrow_front.png").Get(GameFacade.GraphicsDevice); + Segment = ui.Get("rot_seg.png").Get(GameFacade.GraphicsDevice); + } + + public override void Update(UpdateState state) + { + base.Update(state); + Invalidate(); + Visible = true; + } + + public override void InternalDraw(UISpriteBatch batch) + { + base.Draw(batch); + for (int j = 0; j < 2; j++) + { + var baseRot = (float)(Math.PI / 12) * (2+(j*12)); + + DrawLocalTexture(batch, ArrowBack, null, new Vector2(165, 165), Vector2.One, Color.White, baseRot + (float)(Math.PI / 14) * Step * 12, new Vector2(51, 169)); + var ceil = Math.Ceiling(Step * 12); + for (int i = 0; i < ceil; i++) + { + var rotLevels = (i == ceil - 1 && i != 0) ? (Step * 12)-1 : i; + DrawLocalTexture(batch, Segment, null, new Vector2(165, 165), Vector2.One, Color.White, baseRot + (float)(Math.PI / 14) * rotLevels, new Vector2(38, 150)); + } + DrawLocalTexture(batch, Arrow, null, new Vector2(165, 165), Vector2.One, Color.White, baseRot + (float)(Math.PI / 14) * Step * 12, new Vector2(51, 169)); + } + } + + public void Kill(bool success) + { + if (success) Step = 1f; + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { + { "Opacity", 0f }, + { "ScaleX", ScaleX*(success?1.5f:0.8f) }, + { "ScaleY", (success ? 1.5f : 0.8f) }, + { "X", X + (180 - 180*(success ? 1.5f : 0.8f)) }, + { "Y", Y + (180 - 180*(success ? 1.5f : 0.8f)) } + }, TweenQuad.EaseIn); + GameThread.SetTimeout(() => Parent.Remove(this), 300); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UISimitoneFrontend.cs b/Client/Simitone/Simitone.Client/UI/Panels/UISimitoneFrontend.cs new file mode 100644 index 0000000..8c089f1 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UISimitoneFrontend.cs @@ -0,0 +1,158 @@ +using FSO.Client.UI.Framework; +using FSO.Content; +using Simitone.Client.UI.Controls; +using Simitone.Client.UI.Screens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Common.Rendering.Framework.Model; +using FSO.Client; +using Microsoft.Xna.Framework; +using Simitone.Client.UI.Panels.LiveSubpanels; + +namespace Simitone.Client.UI.Panels +{ + public class UISimitoneFrontend : UIContainer + { + public UIClockPanel Clock; + public UITwoStateButton CutBtn; + public UICutawayPanel CutPanel; + public TS1GameScreen Game; + public UIMoneyPanel Money; + public UIMainPanel MainPanel; + public UIStencilButton ExtendPanelBtn; + public UILiveButton LiveButton; + + public bool PanelActive; + public int LastCut = 0; + + public UISimitoneFrontend(TS1GameScreen screen) + { + var ui = Content.Get().CustomUI; + + CutBtn = new UITwoStateButton(ui.Get("cut_btn_down.png").Get(GameFacade.GraphicsDevice)); + CutBtn.X = screen.ScreenWidth - (256 + 15); + CutBtn.Y = 15; + CutBtn.OnButtonClick += CutButton; + Add(CutBtn); + + Clock = new UIClockPanel(screen.vm); + Clock.X = screen.ScreenWidth - (334 + 15); + Clock.Y = 15; + Game = screen; + Add(Clock); + + Money = new UIMoneyPanel(screen); + Money.Position = new Vector2(15, screen.ScreenHeight - 172); + Add(Money); + + MainPanel = new UIMainPanel(screen); + Add(MainPanel); + + ExtendPanelBtn = new UIStencilButton(ui.Get("panel_expand.png").Get(GameFacade.GraphicsDevice)); + ExtendPanelBtn.OnButtonClick += ExpandClicked; + Add(ExtendPanelBtn); + + var btn = new UILiveButton(screen); + btn.MotiveLevel = 0.5f; + btn.Position = new Vector2(64 + 15, screen.ScreenHeight - (64 + 15)); + btn.OnButtonClick += LiveButtonClicked; + Add(btn); + LiveButton = btn; + + ExtendPanelBtn.Position = new Vector2(btn.X + 54, btn.Y - 50); + + MainPanel.X = 64 + 15; + MainPanel.Y = btn.Y - 64; + MainPanel.Visible = false; + + } + + private void ExpandClicked(UIElement button) + { + MainPanel.Open(); + MainPanel.Switcher_OnCategorySelect(MainPanel.Switcher.ActiveCategory); + } + + private void LiveButtonClicked(UIElement button) + { + if (MainPanel.PanelActive) + { + if (MainPanel.ShowingSelect) MainPanel.SwitchAvatar.Kill(); + else MainPanel.ShowSelect(); + } else + { + MainPanel.Open(); + MainPanel.ShowSelect(); + } + } + + private void CutButton(UIElement button) + { + if (CutPanel != null) + { + CutBtn.Selected = false; + CutPanel.Kill(); + CutPanel = null; + } else + { + CutBtn.Selected = true; + CutPanel = new UICutawayPanel(LastCut); + CutPanel.X = CutBtn.X-39; + CutPanel.Y = 15; + CutPanel.OnSelection += CutPanel_OnSelection; + AddAt(0, CutPanel); + } + } + + private void CutPanel_OnSelection(int obj) + { + CutBtn.Selected = false; + Game.LotControl.World.State.DrawRoofs = (obj == 3); + Game.LotControl.WallsMode = obj; + CutPanel.Kill(); + CutPanel = null; + } + + public float ClockTween; + public override void Update(UpdateState state) + { + base.Update(state); + if (LastCut != Game.LotControl.WallsMode) + { + LastCut = Game.LotControl.WallsMode; + var ui = Content.Get().CustomUI; + string cutImg = "cut_btn_down.png"; + switch (LastCut) + { + case 1: + cutImg = "cut_btn_away.png"; break; + case 2: + cutImg = "cut_btn_up.png"; break; + case 3: + cutImg = "cut_btn_roof.png"; break; + } + CutBtn.Texture = ui.Get(cutImg).Get(GameFacade.GraphicsDevice); + } + if (Clock.TweenHook != ClockTween) + { + ClockTween = Clock.TweenHook; + CutBtn.X = Game.ScreenWidth - (256 + (138f * ClockTween) + 15); + if (CutPanel != null) CutPanel.X = CutBtn.X - 39; + } + LiveButton.Switching = MainPanel.ShowingSelect; + ExtendPanelBtn.Visible = !MainPanel.PanelActive; + } + + public override void GameResized() + { + base.GameResized(); + CutBtn.X = Game.ScreenWidth - (256 + (138f * ClockTween) + 15); + if (CutPanel != null) CutPanel.X = CutBtn.X - 39; + Clock.X = Game.ScreenWidth - (334 + 15); + Clock.Y = 15; + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/UISwitchAvatarPanel.cs b/Client/Simitone/Simitone.Client/UI/Panels/UISwitchAvatarPanel.cs new file mode 100644 index 0000000..03eaa54 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/UISwitchAvatarPanel.cs @@ -0,0 +1,89 @@ +using FSO.Client.UI.Framework; +using FSO.SimAntics; +using Simitone.Client.UI.Controls; +using Simitone.Client.UI.Screens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework.Graphics; +using FSO.Content; +using Simitone.Client.UI.Model; +using FSO.Client; +using Microsoft.Xna.Framework; +using FSO.SimAntics.NetPlay.Model.Commands; +using FSO.Common.Utils; + +namespace Simitone.Client.UI.Panels +{ + public class UISwitchAvatarPanel : UIContainer + { + private TS1GameScreen Game; + private Texture2D Bg; + public event Action OnEnd; + public UISwitchAvatarPanel(TS1GameScreen screen) + { + 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)); + int i = 0; + foreach (var fam in familyMembers) + { + var btn = new UIAvatarSelectButton(UIIconCache.GetObject(fam)); + if (fam.PersistID > 0) btn.Outlined = true; + btn.Opacity = 0f; + var id = fam.ObjectID; + btn.OnButtonClick += (b) => { Select(id); }; + btn.Y = 64; + GameFacade.Screens.Tween.To(btn, 0.3f, new Dictionary() { { "X", 185 + (i++) * 100 }, { "Opacity", 1f } }, TweenQuad.EaseOut); + Add(btn); + } + } + + private void Select(short selected) + { + Game.vm.SendCommand(new VMNetChangeControlCmd() { TargetID = selected }); + Kill(); + } + + public void Kill() + { + foreach (var child in Children) + { + GameFacade.Screens.Tween.To(child, 0.3f, new Dictionary() { { "Opacity", 0f } }, TweenQuad.EaseOut); + } + GameFacade.Screens.Tween.To(this, 0.3f, new Dictionary() { { "Opacity", 0f } }, TweenQuad.EaseOut); + OnEnd?.Invoke(); + GameThread.SetTimeout(() => Parent.Remove(this), 300); + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Bg, new Rectangle(0, 0, Bg.Width / 2, Bg.Height), new Vector2(60, 0)); + DrawLocalTexture(batch, Bg, new Rectangle(Bg.Width / 2, 0, Bg.Width / 2, Bg.Height), new Vector2(60 + Bg.Width / 2, 0), new Vector2(12, 1)); + base.Draw(batch); + } + } + + public class UIAvatarSelectButton : UIElasticButton + { + public Texture2D Icon; + public Texture2D Outline; + public bool Outlined; + + public UIAvatarSelectButton(Texture2D icon) : base(Content.Get().CustomUI.Get("pswitch_icon_bg.png").Get(GameFacade.GraphicsDevice)) + { + Icon = icon; + Outline = Content.Get().CustomUI.Get("pswitch_icon_sel.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch SBatch) + { + DrawLocalTexture(SBatch, Texture, null, new Vector2(Texture.Width, Texture.Height) / -2, Vector2.One, new Color(104, 164, 184, 255)); + if (Icon != null) DrawLocalTexture(SBatch, Icon, new Vector2(Icon.Width, Icon.Height) / -2); + if (Outlined) DrawLocalTexture(SBatch, Outline, null, new Vector2(Outline.Width, Outline.Height) / -2, Vector2.One, UIStyle.Current.ActiveSelection); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIHeadlineRenderer.cs b/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIHeadlineRenderer.cs new file mode 100644 index 0000000..3506299 --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIHeadlineRenderer.cs @@ -0,0 +1,214 @@ +using FSO.Client; +using FSO.Common.Utils; +using FSO.Files.Formats.IFF; +using FSO.Files.Formats.IFF.Chunks; +using FSO.LotView; +using FSO.SimAntics; +using FSO.SimAntics.Model; +using FSO.SimAntics.Primitives; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simitone.Client.UI.Panels.WorldUI +{ + public class UIHeadlineRenderer : VMHeadlineRenderer + { + private static IffFile Sprites; + private static Texture2D WhitePx; + private static int[] GroupOffsets = + { + 0x000, + 0x064, + 0x190, + 0x0C8, + 0x12C, + 0x1F4, + 0x258, + 0x000, //algorithmic + 0x2BC, + 0x320 + }; + private static int[] ZoomToDiv = + { + 0, + 4, + 2, + 1 + }; + + private RenderTarget2D Texture; + private SPR Sprite; + private SPR BGSprite; + private WorldZoom LastZoom; + private Texture2D AlgTex; + private int ZoomFrame; + private bool Invalidated; + + private bool DrawSkill + { + get + { + return LastZoom == WorldZoom.Near && Headline.Operand.Group == VMSetBalloonHeadlineOperandGroup.Progress && Headline.Index < 10; + } + } + + public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline) + { + if (Sprites == null) + { + Sprites = new FSO.Files.Formats.IFF.IffFile(FSO.Content.Content.Get().GetPath("objectdata/globals/sprites.iff")); + WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice); + } + + if (Headline.Operand.Group != VMSetBalloonHeadlineOperandGroup.Algorithmic) + Sprite = Sprites.Get((ushort)(GroupOffsets[(int)Headline.Operand.Group] + Headline.Index)); + + if (Headline.Operand.Type != 255 && Headline.Operand.Type != 3) + BGSprite = Sprites.Get((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon]+Headline.Operand.Type)); + + LastZoom = WorldZoom.Near; + RecalculateTarget(); + } + + public void RecalculateTarget() + { + ZoomFrame = 3 - (int)LastZoom; + + if (Texture != null) + { + Texture.Dispose(); + Texture = null; + } + + if (DrawSkill) + { + Texture = new RenderTarget2D(GameFacade.GraphicsDevice, 160, 49); + return; + } + + if (Sprite != null) + { + var bigFrame = (BGSprite != null) ? BGSprite.Frames[ZoomFrame].GetTexture(GameFacade.GraphicsDevice) : Sprite.Frames[ZoomFrame].GetTexture(GameFacade.GraphicsDevice); + if (bigFrame.Width == 0) return; + Texture = new RenderTarget2D(GameFacade.GraphicsDevice, Math.Max(1,bigFrame.Width), Math.Max(1,bigFrame.Height)); + } + else if (Headline.Operand.Group == VMSetBalloonHeadlineOperandGroup.Algorithmic && LastZoom != WorldZoom.Far) + { + AlgTex = (Headline.IconTarget == null)?WhitePx:Headline.IconTarget.GetIcon(GameFacade.GraphicsDevice, (int)LastZoom - 1); + var bigFrame = (BGSprite != null) ? BGSprite.Frames[ZoomFrame].GetTexture(GameFacade.GraphicsDevice) : AlgTex; + if (bigFrame.Width == 0) return; + Texture = new RenderTarget2D(GameFacade.GraphicsDevice, bigFrame.Width, bigFrame.Height); + } + else AlgTex = null; + Invalidated = true; + } + + public string SkillString; + public string SpeedString; + + public int SkillValue = -1; + public int SpeedValue = -1; + + public void ProcessSkill() + { + var avatar = (VMAvatar)Headline.Target; + var eff = avatar.GetPersonData(VMPersonDataVariable.SkillEfficiency); + var e1 = eff >> 8; + if (e1 < 0 || e1 > 100) return; //invalid skill + var skillValue = avatar.GetPersonData((VMPersonDataVariable)(e1)); + var speedValue = (eff & 0xFF); + + if (skillValue != SkillValue || SpeedValue != speedValue) + { + Invalidated = true; + SkillValue = skillValue; + SpeedValue = speedValue; + SkillString = "Skill: " + (SkillValue / 100.0).ToString("F2"); + SpeedString = "Speed: " + SpeedValue + "%"; + } + } + + public override Texture2D DrawFrame(World world) + { + if (LastZoom != world.State.Zoom || Texture == null) + { + Invalidated = true; + LastZoom = world.State.Zoom; + RecalculateTarget(); + if (Texture == null) return null; + } + var GD = GameFacade.GraphicsDevice; + var batch = GameFacade.Screens.SpriteBatch; + + if (DrawSkill) ProcessSkill(); + else if (Headline.Anim % 15 == 0 && Sprite != null && Sprite.Frames.Count > 3) Invalidated = true; + + if (Invalidated) //todo: logic for drawing skills less often + { + GD.SetRenderTarget(Texture); + GD.Clear(Color.Transparent); + batch.Begin(); + + if (BGSprite != null) batch.Draw(BGSprite.Frames[ZoomFrame].GetTexture(GD), new Vector2(), Color.White); + + Texture2D main = null; + Vector2 offset = new Vector2(); + if (Sprite != null) + { + var animFrame = (Headline.Anim / 15) % (Sprite.Frames.Count / 3); + main = Sprite.Frames[ZoomFrame + animFrame * 3].GetTexture(GD); + offset = new Vector2(0, 4); + } + else if (AlgTex != null) + { + main = AlgTex; + offset = new Vector2(0, -6); + } + offset /= ZoomToDiv[(int)LastZoom]; + + if (main != null && Texture != null) batch.Draw(main, new Vector2(Texture.Width / 2 - main.Width / 2, Texture.Height / 2 - main.Height / 2) + offset, Color.White); + + if (Headline.Operand.Crossed) + { + Texture2D Cross = Sprites.Get(0x67).Frames[ZoomFrame].GetTexture(GD); + batch.Draw(Cross, new Vector2(Texture.Width / 2 - Cross.Width / 2, Texture.Height / 2 - Cross.Height / 4), Color.White); + } + + if (DrawSkill) + { + batch.Draw(WhitePx, new Rectangle(88, 4, 71, 41), new Color(92, 92, 92)); + var font = GameFacade.MainFont.GetNearest(14).Font; + + Vector2 fontOrigin = font.MeasureString(SkillString) / 2; + batch.DrawString(font, SkillString, new Vector2(88 + 35, 15) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0); + + fontOrigin = font.MeasureString(SpeedString) / 2; + batch.DrawString(font, SpeedString, new Vector2(88 + 35, 34) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0); + } + + batch.End(); + GD.SetRenderTarget(null); + Invalidated = false; + } + + return Texture; + } + + public override void Dispose() + { + if (Texture != null) Texture.Dispose(); + } + } + + public class UIHeadlineRendererProvider : VMHeadlineRendererProvider + { + public VMHeadlineRenderer Get(VMRuntimeHeadline headline) + { + return (headline.Operand.Group == VMSetBalloonHeadlineOperandGroup.Money)? new UIMoneyHeadline(headline) : ((VMHeadlineRenderer)new UIHeadlineRenderer(headline)); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIMoneyHeadline.cs b/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIMoneyHeadline.cs new file mode 100644 index 0000000..4eb5aca --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Panels/WorldUI/UIMoneyHeadline.cs @@ -0,0 +1,69 @@ +using FSO.SimAntics.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.LotView; +using Microsoft.Xna.Framework.Graphics; +using FSO.Client.UI.Framework; +using Microsoft.Xna.Framework; +using FSO.Client; + +namespace Simitone.Client.UI.Panels.WorldUI +{ + public class UIMoneyHeadline : VMHeadlineRenderer + { + private RenderTarget2D MoneyTarget; + private TextStyle Style; + private Texture2D MoneyBG; + private string Text; + + public UIMoneyHeadline(VMRuntimeHeadline headline) : base(headline) + { + Style = TextStyle.DefaultLabel.Clone(); + Style.Size = 12; + var value = (int)(headline.Operand.Flags2 | (ushort)(headline.Operand.Duration << 16)); + Text = (value > 0)?("§" + value):("-§"+ value); + 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); + MoneyBG = FSO.Content.Content.Get().CustomUI.Get("money_bg.png").Get(GD); + + DrawNewFrame(); + } + + public void DrawNewFrame() + { + var GD = GameFacade.GraphicsDevice; + GD.SetRenderTarget(MoneyTarget); + GD.Clear(Color.TransparentBlack); + var batch = GameFacade.Screens.SpriteBatch; + var opacity = (Headline.Duration / 60f); + batch.Begin(); + batch.Draw(MoneyBG, new Vector2(0, Headline.Duration / 2), new Rectangle(0, 0, 12, 24), Model.UIStyle.Current.Bg * opacity, + 0, Vector2.Zero, new Vector2(0.8f, 0.8f), SpriteEffects.None, 0); + batch.Draw(MoneyBG, new Vector2(9.6f, Headline.Duration / 2), new Rectangle(12, 0, 12, 24), Model.UIStyle.Current.Bg * opacity, + 0, Vector2.Zero, new Vector2(((MoneyTarget.Width-19.2f)/12f), 0.8f), SpriteEffects.None, 0); + batch.Draw(MoneyBG, new Vector2(MoneyTarget.Width-9.6f, Headline.Duration / 2), new Rectangle(24, 0, 12, 24), Model.UIStyle.Current.Bg * opacity, + 0, Vector2.Zero, new Vector2(0.8f, 0.8f), SpriteEffects.None, 0); + Style.Color.A = (byte)(opacity*255); + batch.DrawString(Style.SpriteFont, Text, new Vector2(5, Headline.Duration/2), Style.Color); + batch.End(); + GD.SetRenderTarget(null); + } + + public override Texture2D DrawFrame(World world) + { + DrawNewFrame(); + return MoneyTarget; + } + + public override void Dispose() + { + base.Dispose(); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Screens/LoadingGameScreen.cs b/Client/Simitone/Simitone.Client/UI/Screens/LoadingGameScreen.cs new file mode 100644 index 0000000..a7693be --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Screens/LoadingGameScreen.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Controls; +using System.Threading; +using FSO.Client; +using FSO.Common.Rendering.Framework.Model; +using FSO.Content; +using Simitone.Client.UI.Panels; +using Simitone.Client.UI.Controls; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using FSO.Common.Utils; + +namespace Simitone.Client.UI.Screens +{ + public class LoadingScreen : FSO.Client.UI.Framework.GameScreen + { + public string[] LoadText = new string[] { + "", //Started = 0, + "Identifying Works...", //ScanningFiles = 1, + "Categorising Works...", //InitGlobal = 2, + "Arranging Wardrobes...", //InitBCF = 3, + "Reticulating Splines...", //InitAvatars = 4, + "Performing Sound Check...", //InitAudio = 5, + "Arranging Furniture...", //InitObjects = 6, + "Building Concert Hall...", //InitArch = 7, + " " //Done = 8, + }; + + public UISimitoneBg Bg; + public UIDiagonalStripe ProgressDiag; + public UIDiagonalStripe TextDiag; + public UILoadProgress LoadProgress; + public UISimitoneLogo Logo; + public UISimitoneLoadLabel LastLabel; + public bool LoadingComplete; + + private bool Closing = false; + private float _i; + public float InterpolatedAnimation + { + set + { + TextDiag.X = (Closing) ? 0 : (ScreenWidth * (1 - value)); + TextDiag.BodySize = new Point((int)(value * ScreenWidth), 75); + TextDiag.Y = ScreenHeight*0.75f - 37; + + ProgressDiag.X = (Closing) ? (ScreenWidth * (1 - value)) : 0; + ProgressDiag.BodySize = new Point((int)(value * ScreenWidth), 150); + + LoadProgress.Opacity = value; + + _i = value; + } + + get + { + return _i; + } + } + + public LoadingScreen() + { + Content.InitBasic(GlobalSettings.Default.StartupPath, GameFacade.GraphicsDevice); + + Bg = new UISimitoneBg(); + Bg.Position = (new Vector2(ScreenWidth, ScreenHeight)) / 2; + Add(Bg); + + ProgressDiag = new UIDiagonalStripe(new Point(0, 150), UIDiagonalStripeSide.RIGHT, Color.Black * 0.75f); + ProgressDiag.Position = new Vector2(0, ScreenHeight / 2 - 75); + Add(ProgressDiag); + + TextDiag = new UIDiagonalStripe(new Point(0, 150), UIDiagonalStripeSide.LEFT, Color.Black * 0.5f); + TextDiag.Position = new Vector2(0, ScreenHeight * 0.75f - 37); + Add(TextDiag); + + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "InterpolatedAnimation", 1f } }, TweenQuad.EaseOut); + + LoadProgress = new UILoadProgress(); + LoadProgress.Position = (new Vector2(ScreenWidth, ScreenHeight) - new Vector2(938, 112))/2; + Add(LoadProgress); + + Logo = new UISimitoneLogo(); + Logo.Position = new Vector2(ScreenWidth, ScreenHeight) / 2; + Add(Logo); + GameFacade.Screens.Tween.To(Logo, 1f, new Dictionary() { { "Y", ScreenHeight/4 }, { "ScaleX", 0.5f }, { "ScaleY", 0.5f } }, TweenQuad.EaseOut); + + InterpolatedAnimation = InterpolatedAnimation; + + (new Thread(() => { + FSO.Content.Content.Init(GlobalSettings.Default.StartupPath, GameFacade.GraphicsDevice); + lock (this) + { + LoadingComplete = true; + } + })).Start(); + } + + public void Close() + { + Closing = true; + GameThread.SetTimeout(() => + { + ProgressDiag.DiagSide = UIDiagonalStripeSide.LEFT; + TextDiag.DiagSide = UIDiagonalStripeSide.RIGHT; + GameFacade.Screens.Tween.To(this, 0.5f, new Dictionary() { { "InterpolatedAnimation", 0f } }, TweenQuad.EaseOut); + GameFacade.Screens.Tween.To(Logo, 0.5f, new Dictionary() { { "Y", -200f } }, TweenQuad.EaseIn); + GameFacade.Screens.Tween.To(Bg, 0.5f, new Dictionary() { { "Opacity", 0f } }, TweenQuad.EaseOut); + + GameThread.SetTimeout(() => + { + ProgressDiag.Parent.Remove(ProgressDiag); + TextDiag.Parent.Remove(TextDiag); + Logo.Parent.Remove(Logo); + LoadProgress.Parent.Remove(LoadProgress); + Bg.Parent.Remove(Bg); + }, 500); + }, 750); + } + + public ContentLoadingProgress LastProgress = ContentLoadingProgress.Invalid; + + public override void Update(UpdateState state) + { + if (LastProgress != Content.LoadProgress) + { + LastProgress = Content.LoadProgress; + + if (LastLabel != null) + { + LastLabel.Kill(); + } + LastLabel = new UISimitoneLoadLabel(LoadText[(int)LastProgress]); + LastLabel.Position = new Vector2(ScreenWidth/2, ScreenHeight * 0.75f); + Add(LastLabel); + + LoadProgress.OverallPercent = (float)LastProgress / (float)ContentLoadingProgress.Done; + } + lock (this) + { + if (LoadingComplete) + { + GameController.EnterGameMode("", false); + } + } + base.Update(state); + } + } + + public class UISimitoneLogo : UIElement + { + public Texture2D Logo; + + public UISimitoneLogo() : base() + { + var ui = Content.Get().CustomUI; + Logo = ui.Get("load_logo.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch batch) + { + DrawLocalTexture(batch, Logo, new Vector2(Logo.Width, Logo.Height) / -2); + } + } + + public class UISimitoneBg : UIElement + { + public Texture2D Bg; + + public UISimitoneBg() : base() + { + var ui = Content.Get().CustomUI; + Bg = ui.Get("load_static_bg.png").Get(GameFacade.GraphicsDevice); + } + + public override void Draw(UISpriteBatch batch) + { + if (!Visible) return; + var scale = Math.Max(GameFacade.Screens.CurrentUIScreen.ScreenWidth / 1136f, GameFacade.Screens.CurrentUIScreen.ScreenHeight / 640f); + DrawLocalTexture(batch, Bg, null, new Vector2(Bg.Width, Bg.Height) / -2 * scale, new Vector2(scale)); + } + } + + public class UISimitoneLoadLabel : UIContainer + { + public UILabel Label; + + private float _Alpha; + public float Alpha + { + get + { + return _Alpha; + } + set + { + Label.CaptionStyle.Color = Color.White * value; + _Alpha = value; + } + } + + public UISimitoneLoadLabel(string text) + { + Label = new UILabel(); + Label.CaptionStyle = Label.CaptionStyle.Clone(); + Label.CaptionStyle.Size = 37; + Label.CaptionStyle.Color = Color.White; + Label.Caption = text; + Label.Alignment = TextAlignment.Center | TextAlignment.Middle; + Label.Size = new Vector2(1, 1); + Label.Y = 100f; + Add(Label); + Alpha = Alpha; + GameFacade.Screens.Tween.To(Label, 0.4f, new Dictionary() { { "Y", 0f } }, TweenQuad.EaseOut); + GameFacade.Screens.Tween.To(this, 0.4f, new Dictionary() { { "Alpha", 1f } }, TweenQuad.EaseOut); + } + + public void Kill() + { + GameFacade.Screens.Tween.To(Label, 0.4f, new Dictionary() { { "Y", -100f } }, TweenQuad.EaseIn); + GameFacade.Screens.Tween.To(this, 0.4f, new Dictionary() { { "Alpha", 0f } }, TweenQuad.EaseIn); + GameThread.SetTimeout(() => { Parent.Remove(this); }, 400); + } + } +} diff --git a/Client/Simitone/Simitone.Client/UI/Screens/TS1GameScreen.cs b/Client/Simitone/Simitone.Client/UI/Screens/TS1GameScreen.cs new file mode 100644 index 0000000..7a28b4a --- /dev/null +++ b/Client/Simitone/Simitone.Client/UI/Screens/TS1GameScreen.cs @@ -0,0 +1,549 @@ + +using FSO.Client; +using FSO.Client.Debug; +using FSO.Client.UI.Framework; +using FSO.Client.UI.Model; +using FSO.Common; +using FSO.Common.Rendering.Framework; +using FSO.Common.Utils; +using FSO.Content; +using FSO.Files.Formats.IFF.Chunks; +using FSO.HIT; +using FSO.LotView; +using FSO.SimAntics; +using FSO.SimAntics.Engine.TSOTransaction; +using FSO.SimAntics.Marshals; +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.Input; +using Simitone.Client.UI.Panels; +using Simitone.Client.UI.Panels.WorldUI; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Client.UI.Screens +{ + public class TS1GameScreen : FSO.Client.UI.Framework.GameScreen + { + public UIContainer WindowContainer; + public bool Downtown; + + public UILotControl LotControl { get; set; } + public UISimitoneFrontend Frontend { get; set; } + private FSO.LotView.World World; + public FSO.SimAntics.VM vm { get; set; } + public VMNetDriver Driver; + public UISimitoneBg Bg; + public uint VisualBudget { get; set; } + + //for TS1 hybrid mode + public UINeighborhoodSelectionPanel TS1NeighPanel; + public FAMI ActiveFamily; + + public bool InLot + { + get + { + return (vm != null); + } + } + + private int m_ZoomLevel; + public int ZoomLevel + { + get + { + return m_ZoomLevel; + } + set + { + value = Math.Max(1, Math.Min(3, value)); + + if (value < 4) + { + if (vm == null) + { + + } + else + { + var targ = (WorldZoom)(4 - value); //near is 3 for some reason... will probably revise + HITVM.Get().PlaySoundEvent(UIMusic.None); + LotControl.Visible = true; + Bg.Visible = false; + World.Visible = true; + //ucp.SetMode(UIUCP.UCPMode.LotMode); + if (m_ZoomLevel != value) vm.Context.World.InitiateSmoothZoom(targ); + vm.Context.World.State.Zoom = targ; + m_ZoomLevel = value; + } + } + else //cityrenderer! we'll need to recreate this if it doesn't exist... + { + if (m_ZoomLevel < 4) + { //coming from lot view... snap zoom % to 0 or 1 + if (World != null) + { + LotControl.Visible = false; + } + } + m_ZoomLevel = value; + } + } + } + + private int _Rotation = 0; + public int Rotation + { + get + { + return _Rotation; + } + set + { + _Rotation = value; + World.State.CenterTile = World.EstTileAtPosWithScroll(new Vector2(ScreenWidth / 2, ScreenHeight / 2)); + if (World != null) + { + switch (_Rotation) + { + case 0: + World.State.Rotation = WorldRotation.TopLeft; break; + case 1: + World.State.Rotation = WorldRotation.TopRight; break; + case 2: + World.State.Rotation = WorldRotation.BottomRight; break; + case 3: + World.State.Rotation = WorldRotation.BottomLeft; break; + } + } + World.RestoreTerrainToCenterTile(); + } + } + + public sbyte Level + { + get + { + if (World == null) return 1; + else return World.State.Level; + } + set + { + if (World != null) + { + World.State.Level = value; + } + } + } + + public sbyte Stories + { + get + { + if (World == null) return 2; + return World.Stories; + } + } + + public VMAvatar SelectedAvatar + { + get + { + return vm.GetAvatarByPersist(vm.MyUID); + } + } + + public TS1GameScreen() : base() + { + Bg = new UISimitoneBg(); + Bg.Position = (new Vector2(ScreenWidth, ScreenHeight)) / 2; + Add(Bg); + + WindowContainer = new UIContainer(); + Add(WindowContainer); + + if (Content.Get().TS1) + { + TS1NeighPanel = new UINeighborhoodSelectionPanel(4); + TS1NeighPanel.OnHouseSelect += (house) => + { + ActiveFamily = Content.Get().Neighborhood.GetFamilyForHouse((short)house); + InitializeLot(Path.Combine(Content.Get().TS1BasePath, "UserData/Houses/House" + house.ToString().PadLeft(2, '0') + ".iff"), false);// "UserData/Houses/House21.iff" + Remove(TS1NeighPanel); + }; + Add(TS1NeighPanel); + } + } + + public override void GameResized() + { + base.GameResized(); + Bg.Position = (new Vector2(ScreenWidth, ScreenHeight)) / 2; + World?.GameResized(); + } + + public void Initialize(string propertyName, bool external) + { + GameFacade.CurrentCityName = propertyName; + ZoomLevel = 1; //screen always starts at near zoom + InitializeLot(propertyName, external); + } + + private int SwitchLot = -1; + + public void ChangeSpeedTo(int speed) + { + //0 speed is 0x + //1 speed is 1x + //2 speed is 3x + //3 speed is 10x + + if (vm == null) return; + + switch (vm.SpeedMultiplier) + { + case 0: + switch (speed) + { + case 1: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo1); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo2); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.SpeedPTo3); break; + } + break; + case 1: + switch (speed) + { + case 0: + HITVM.Get().PlaySoundEvent(UISounds.Speed1ToP); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.Speed1To2); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.Speed1To3); break; + } + break; + case 3: + switch (speed) + { + case 0: + HITVM.Get().PlaySoundEvent(UISounds.Speed2ToP); break; + case 1: + HITVM.Get().PlaySoundEvent(UISounds.Speed2To1); break; + case 3: + HITVM.Get().PlaySoundEvent(UISounds.Speed2To3); break; + } + break; + case 10: + switch (speed) + { + case 0: + HITVM.Get().PlaySoundEvent(UISounds.Speed3ToP); break; + case 1: + HITVM.Get().PlaySoundEvent(UISounds.Speed3To1); break; + case 2: + HITVM.Get().PlaySoundEvent(UISounds.Speed3To2); break; + } + break; + } + + switch (speed) + { + case 0: vm.SpeedMultiplier = 0; break; + case 1: vm.SpeedMultiplier = 1; break; + case 2: vm.SpeedMultiplier = 3; break; + case 3: vm.SpeedMultiplier = 10; break; + } + } + + public override void Update(FSO.Common.Rendering.Framework.Model.UpdateState state) + { + GameFacade.Game.IsFixedTimeStep = (vm == null || vm.Ready); + + 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.P)) ChangeSpeedTo(0); + + if (World != null) + { + //stub smooth zoom? + } + + if (SwitchLot > 0) + { + if (!Downtown) SavedLot = vm.Save(); + if (SwitchLot == ActiveFamily.HouseNumber && SavedLot != null) + { + Downtown = false; + InitializeLot(SavedLot); + SavedLot = null; + } + else + { + Downtown = true; + InitializeLot(Path.Combine(Content.Get().TS1BasePath, "UserData/Houses/House" + SwitchLot.ToString().PadLeft(2, '0') + ".iff"), false); + } + SwitchLot = -1; + } + if (vm != null) vm.Update(); + } + + public override void PreDraw(UISpriteBatch batch) + { + base.PreDraw(batch); + vm?.PreDraw(); + } + + public void CleanupLastWorld() + { + if (vm == null) return; + + //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(); + foreach (var ent in vm.Entities) + { //stop object sounds + var threads = ent.SoundThreads; + for (int i = 0; i < threads.Count; i++) + { + threads[i].Sound.RemoveOwner(ent.ObjectID); + } + threads.Clear(); + } + vm.CloseNet(VMCloseNetReason.LeaveLot); + GameFacade.Scenes.Remove(World); + World.Dispose(); + //LotControl.Dispose(); + this.Remove(LotControl); + this.Remove(Frontend); + vm.SuppressBHAVChanges(); + vm = null; + World = null; + Driver = null; + LotControl = null; + } + + private VMMarshal SavedLot; + + public void InitializeLot() + { + CleanupLastWorld(); + + World = new FSO.LotView.World(GameFacade.GraphicsDevice); + World.Opacity = 1; + GameFacade.Scenes.Add(World); + + var globalLink = new VMTSOGlobalLinkStub(); + Driver = new VMServerDriver(globalLink); + + vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider()); + vm.ListenBHAVChanges(); + vm.Init(); + + LotControl = new UILotControl(vm, World); + this.AddAt(0, LotControl); + Frontend = new UISimitoneFrontend(this); + this.Add(Frontend); + + var time = DateTime.UtcNow; + var tsoTime = TSOTime.FromUTC(time); + + vm.Context.Clock.Hours = tsoTime.Item1; + vm.Context.Clock.Minutes = tsoTime.Item2; + if (m_ZoomLevel > 3) + { + World.Visible = false; + LotControl.Visible = false; + } + + ZoomLevel = Math.Max(ZoomLevel, 4); + + if (IDEHook.IDE != null) IDEHook.IDE.StartIDE(vm); + + vm.OnFullRefresh += VMRefreshed; + //vm.OnEODMessage += LotControl.EODs.OnEODMessage; + vm.OnRequestLotSwitch += VMLotSwitch; + vm.OnGenericVMEvent += Vm_OnGenericVMEvent; + } + + public void InitializeLot(VMMarshal marshal) + { + InitializeLot(); + vm.MyUID = 1; + vm.Load(marshal); + + vm.ActivateFamily(ActiveFamily); + + var settings = GlobalSettings.Default; + var myClient = new VMNetClient + { + PersistID = 1, + RemoteIP = "local", + AvatarState = new VMNetAvatarPersistState() + { + Name = settings.LastUser ?? "", + DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender), + BodyOutfit = settings.DebugBody, + HeadOutfit = settings.DebugHead, + PersistID = 1, + SkinTone = (byte)settings.DebugSkin, + Gender = (short)(settings.DebugGender ? 1 : 0), + Permissions = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin, + Budget = 1000000 + } + + }; + + var server = (VMServerDriver)Driver; + server.ConnectClient(myClient); + + GameFacade.Cursor.SetCursor(CursorType.Normal); + ZoomLevel = 1; + } + + public void InitializeLot(string lotName, bool external) + { + if (lotName == "") return; + InitializeLot(); + + if (!external) + { + if (!Downtown && ActiveFamily != null) + { + ActiveFamily.SelectWholeFamily(); + vm.ActivateFamily(ActiveFamily); + } + BlueprintReset(lotName); + + vm.Context.Clock.Hours = 0; + vm.TSOState.Size = (10) | (3 << 8); + vm.Context.UpdateTSOBuildableArea(); + vm.MyUID = 1; + var settings = GlobalSettings.Default; + var myClient = new VMNetClient + { + PersistID = 1, + RemoteIP = "local", + AvatarState = new VMNetAvatarPersistState() + { + Name = settings.LastUser ?? "", + DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender), + BodyOutfit = settings.DebugBody, + HeadOutfit = settings.DebugHead, + PersistID = 1, + SkinTone = (byte)settings.DebugSkin, + Gender = (short)(settings.DebugGender ? 1 : 0), + Permissions = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin, + Budget = 1000000 + } + + }; + + var server = (VMServerDriver)Driver; + server.ConnectClient(myClient); + + GameFacade.Cursor.SetCursor(CursorType.Normal); + ZoomLevel = 1; + } + } + + public void BlueprintReset(string path) + { + string filename = Path.GetFileName(path); + try + { + using (var file = new BinaryReader(File.OpenRead(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/") + filename.Substring(0, filename.Length - 4) + ".fsov"))) + { + var marshal = new FSO.SimAntics.Marshals.VMMarshal(); + marshal.Deserialize(file); + //vm.SendCommand(new VMStateSyncCmd() + //{ + // State = marshal + //}); + + vm.Load(marshal); + vm.Reset(); + } + } + catch (Exception) + { + var floorClip = Rectangle.Empty; + var offset = new Point(); + var targetSize = 0; + + var isIff = path.EndsWith(".iff"); + short jobLevel = -1; + if (isIff) jobLevel = short.Parse(path.Substring(path.Length - 6, 2)); + vm.SendCommand(new VMBlueprintRestoreCmd + { + JobLevel = jobLevel, + XMLData = File.ReadAllBytes(path), + IffData = isIff, + + FloorClipX = floorClip.X, + FloorClipY = floorClip.Y, + FloorClipWidth = floorClip.Width, + FloorClipHeight = floorClip.Height, + OffsetX = offset.X, + OffsetY = offset.Y, + TargetSize = targetSize + }); + } + vm.Tick(); + } + + + private void Vm_OnGenericVMEvent(VMEventType type, object data) + { + //hmm... + } + + private void VMLotSwitch(uint lotId) + { + vm.SpeedMultiplier = 0; + if ((short)lotId == -1) + { + lotId = (uint)ActiveFamily.HouseNumber; + } + SwitchLot = (int)lotId; + } + + private void VMRefreshed() + { + if (vm == null) return; + LotControl.ActiveEntity = null; + LotControl.RefreshCut(); + } + + private void SaveHouseButton_OnButtonClick(UIElement button) + { + if (vm == null) return; + + var exporter = new VMWorldExporter(); + exporter.SaveHouse(vm, GameFacade.GameFilePath("housedata/blueprints/house_00.xml")); + var marshal = vm.Save(); + Directory.CreateDirectory(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/")); + using (var output = new FileStream(Path.Combine(FSOEnvironment.UserDir, "LocalHouse/house_00.fsov"), FileMode.Create)) + { + marshal.SerializeInto(new BinaryWriter(output)); + } + if (vm.GlobalLink != null) ((VMTSOGlobalLinkStub)vm.GlobalLink).Database.Save(); + } + } +} \ No newline at end of file diff --git a/Client/Simitone/Simitone.Windows/GameLocator/ILocator.cs b/Client/Simitone/Simitone.Windows/GameLocator/ILocator.cs new file mode 100644 index 0000000..7493c99 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/GameLocator/ILocator.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simitone.Windows.GameLocator +{ + interface ILocator + { + string FindTheSimsOnline(); + string FindTheSims1(); + } +} diff --git a/Client/Simitone/Simitone.Windows/GameLocator/LinuxLocator.cs b/Client/Simitone/Simitone.Windows/GameLocator/LinuxLocator.cs new file mode 100644 index 0000000..6d6f305 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/GameLocator/LinuxLocator.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simitone.Windows.GameLocator +{ + public class LinuxLocator : ILocator + { + public string FindTheSimsOnline() + { + return "game/TSOClient/"; + } + + public string FindTheSims1() + { + return "game1/"; + } + } +} diff --git a/Client/Simitone/Simitone.Windows/GameLocator/MacOSLocator.cs b/Client/Simitone/Simitone.Windows/GameLocator/MacOSLocator.cs new file mode 100644 index 0000000..ef8c18f --- /dev/null +++ b/Client/Simitone/Simitone.Windows/GameLocator/MacOSLocator.cs @@ -0,0 +1,17 @@ +using System; + +namespace Simitone.Windows.GameLocator +{ + public class MacOSLocator : ILocator + { + public string FindTheSimsOnline() + { + return string.Format("{0}/Documents/The Sims Online/TSOClient/", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); + } + + public string FindTheSims1() + { + return "game1/"; + } + } +} diff --git a/Client/Simitone/Simitone.Windows/GameLocator/WindowsLocator.cs b/Client/Simitone/Simitone.Windows/GameLocator/WindowsLocator.cs new file mode 100644 index 0000000..4804748 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/GameLocator/WindowsLocator.cs @@ -0,0 +1,96 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Simitone.Windows.GameLocator +{ + public class WindowsLocator : ILocator + { + public string FindTheSimsOnline() + { + string Software = ""; + + using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)) + { + //Find the path to TSO on the user's system. + RegistryKey softwareKey = hklm.OpenSubKey("SOFTWARE"); + + if (Array.Exists(softwareKey.GetSubKeyNames(), delegate (string s) { return s.Equals("Maxis", StringComparison.InvariantCultureIgnoreCase); })) + { + RegistryKey maxisKey = softwareKey.OpenSubKey("Maxis"); + if (Array.Exists(maxisKey.GetSubKeyNames(), delegate (string s) { return s.Equals("The Sims Online", StringComparison.InvariantCultureIgnoreCase); })) + { + RegistryKey tsoKey = maxisKey.OpenSubKey("The Sims Online"); + string installDir = (string)tsoKey.GetValue("InstallDir"); + installDir += "\\TSOClient\\"; + return installDir.Replace('\\', '/'); + } + } + } + return @"C:\Program Files\Maxis\The Sims Online\TSOClient\".Replace('\\', '/'); + } + + public string FindTheSims1() + { + string Software = ""; + + using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)) + { + //Find the path to TSO on the user's system. + RegistryKey softwareKey = hklm.OpenSubKey("SOFTWARE"); + + if (Array.Exists(softwareKey.GetSubKeyNames(), delegate (string s) { return s.Equals("Maxis", StringComparison.InvariantCultureIgnoreCase); })) + { + RegistryKey maxisKey = softwareKey.OpenSubKey("Maxis"); + if (Array.Exists(maxisKey.GetSubKeyNames(), delegate (string s) { return s.Equals("The Sims Online", StringComparison.InvariantCultureIgnoreCase); })) + { + RegistryKey tsoKey = maxisKey.OpenSubKey("The Sims"); + string installDir = (string)tsoKey.GetValue("InstallPath"); + installDir += "\\"; + return installDir.Replace('\\', '/'); + } + } + } + return @"C:\Program Files (x86)\Maxis\The Sims\".Replace('\\', '/'); + } + + private static bool is64BitProcess = (IntPtr.Size == 8); + private static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64(); + + [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWow64Process( + [In] IntPtr hProcess, + [Out] out bool wow64Process + ); + + /// + /// Determines if this process is run on a 64bit OS. + /// + /// True if it is, false otherwise. + public static bool InternalCheckIsWow64() + { + if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || + Environment.OSVersion.Version.Major >= 6) + { + using (Process p = Process.GetCurrentProcess()) + { + bool retVal; + if (!IsWow64Process(p.Handle, out retVal)) + { + return false; + } + return retVal; + } + } + else + { + return false; + } + } + } +} diff --git a/Client/Simitone/Simitone.Windows/Icon.ico b/Client/Simitone/Simitone.Windows/Icon.ico new file mode 100644 index 0000000..7d9dec1 Binary files /dev/null and b/Client/Simitone/Simitone.Windows/Icon.ico differ diff --git a/Client/Simitone/Simitone.Windows/Program.cs b/Client/Simitone/Simitone.Windows/Program.cs new file mode 100644 index 0000000..0070bd8 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/Program.cs @@ -0,0 +1,88 @@ +using FSO.Client; +using FSO.Common; +using FSO.LotView; +using Simitone.Client; +using Simitone.Windows.GameLocator; +using System; +using System.Threading; + +namespace Simitone.Windows +{ +#if WINDOWS || LINUX + /// + /// The main class. + /// + public static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + var gameLocator = new WindowsLocator(); + + var useDX = false; + var path = gameLocator.FindTheSimsOnline(); + + if (useDX) GlobalSettings.Default.AntiAlias = false; + + bool ide = false; + #region User resolution parmeters + + foreach (var arg in args) + { + if (arg[0] == '-') + { + var cmd = arg.Substring(1); + if (cmd.StartsWith("lang")) + { + GlobalSettings.Default.LanguageCode = byte.Parse(cmd.Substring(4)); + } + else if (cmd.StartsWith("hz")) GlobalSettings.Default.TargetRefreshRate = int.Parse(cmd.Substring(2)); + else + { + //normal style param + switch (cmd) + { + case "ide": + ide = true; + break; + } + } + } + } + + #endregion + + FSOEnvironment.SoftwareDepth = false; + FSOEnvironment.UseMRT = true; + + if (path != null) + { + FSOEnvironment.ContentDir = "Content/"; + FSOEnvironment.GFXContentDir = "Content/" + (useDX ? "DX/" : "OGL/"); + FSOEnvironment.Linux = false; + FSOEnvironment.DirectX = useDX; + FSOEnvironment.GameThread = Thread.CurrentThread; + if (GlobalSettings.Default.LanguageCode == 0) GlobalSettings.Default.LanguageCode = 1; + FSO.Files.Formats.IFF.Chunks.STR.DefaultLangCode = (FSO.Files.Formats.IFF.Chunks.STRLangCode)GlobalSettings.Default.LanguageCode; + + GlobalSettings.Default.StartupPath = path; + GlobalSettings.Default.TS1HybridEnable = true; + GlobalSettings.Default.TS1HybridPath = gameLocator.FindTheSims1(); + GlobalSettings.Default.ClientVersion = "0"; + + GameFacade.DirectX = useDX; + World.DirectX = useDX; + + if (ide) new FSO.IDE.VolcanicStartProxy().InitVolcanic(); + + SimitoneGame game = new SimitoneGame(); + game.Run(); + game.Dispose(); + } + } + } +#endif +} diff --git a/Client/Simitone/Simitone.Windows/Properties/AssemblyInfo.cs b/Client/Simitone/Simitone.Windows/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..78a5f29 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Simitone.Windows")] +[assembly: AssemblyProduct("Simitone.Windows")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("03895786-8413-4eac-a9de-3c347fa61252")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj new file mode 100644 index 0000000..2ae8d90 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj @@ -0,0 +1,106 @@ + + + + + Debug + x86 + 8.0.30703 + 2.0 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802} + WinExe + Properties + Simitone.Windows + Simitone.Windows + 512 + Windows + v4.5 + + + x86 + true + full + false + bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\ + DEBUG;TRACE;WINDOWS + prompt + 4 + + + x86 + pdbonly + true + bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\ + TRACE;WINDOWS + prompt + 4 + + + Icon.ico + + + + + + + + + + + + + + + + + + + {6d6009f4-0afb-4806-89d7-7945f20270f5} + MonoGame.Framework.Net.WindowsGL + + + {6d75e618-19ca-4c51-9546-f10965fbc0b8} + MonoGame.Framework.WindowsGL + + + {5deb20eb-1eb7-48f9-922c-463abae56e63} + FSO.IDE + + + {73e2ad5b-720b-4ef3-9b7c-55931d0ec693} + FSO.UI + + + {c42962a1-8796-4f47-9dcd-79ed5904d8ca} + FSO.Common + + + {c0068df7-f2e8-4399-846d-556bf9a35c00} + FSO.Content + + + {18583453-a970-4ac5-83b1-2d6bfdf94c24} + FSO.Files + + + {5eddefd2-c850-49c1-812d-ddeff09125ef} + FSO.SimAntics + + + {b1a6e4c2-e080-4c34-a604-d11b5296a9b8} + FSO.LotView + + + {0f20013d-0610-4573-a346-1c5a461b0ba0} + Simitone.Client + + + + + + \ No newline at end of file diff --git a/Client/Simitone/Simitone.sln b/Client/Simitone/Simitone.sln new file mode 100644 index 0000000..fe6310d --- /dev/null +++ b/Client/Simitone/Simitone.sln @@ -0,0 +1,796 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simitone.iOS", "Simitone\Simitone.iOS.csproj", "{F0BFC685-A357-4E5A-B502-1B5A35970E63}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simitone.Windows", "Simitone.Windows\Simitone.Windows.csproj", "{32CBA4DB-99D8-4D1E-9420-E9B0D2359802}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.UI", "..\..\FreeSO\TSOClient\FSO.UI\FSO.UI.csproj", "{73E2AD5B-720B-4EF3-9B7C-55931D0EC693}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simitone.Client", "Simitone.Client\Simitone.Client.csproj", "{0F20013D-0610-4573-A346-1C5A461B0BA0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.Content", "..\..\FreeSO\TSOClient\tso.content\FSO.Content.csproj", "{C0068DF7-F2E8-4399-846D-556BF9A35C00}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.Common", "..\..\FreeSO\TSOClient\tso.common\FSO.Common.csproj", "{C42962A1-8796-4F47-9DCD-79ED5904D8CA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.Files", "..\..\FreeSO\TSOClient\tso.files\FSO.Files.csproj", "{18583453-A970-4AC5-83B1-2D6BFDF94C24}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.SimAntics", "..\..\FreeSO\TSOClient\tso.simantics\FSO.SimAntics.csproj", "{5EDDEFD2-C850-49C1-812D-DDEFF09125EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.HIT", "..\..\FreeSO\TSOClient\tso.sound\FSO.HIT.csproj", "{072781D8-51EC-4143-9CAE-DAF50177D3AD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.Vitaboy.Engine", "..\..\FreeSO\TSOClient\tso.vitaboy.engine\FSO.Vitaboy.Engine.csproj", "{FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.Vitaboy", "..\..\FreeSO\TSOClient\tso.vitaboy.model\FSO.Vitaboy.csproj", "{9D9558A9-755E-43F9-8BB6-B26F365F5042}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.LotView", "..\..\FreeSO\TSOClient\tso.world\FSO.LotView.csproj", "{B1A6E4C2-E080-4C34-A604-D11B5296A9B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.Windows", "..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.Windows.csproj", "{7DE47032-A904-4C29-BD22-2D235E8D91BA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.Net.WindowsGL", "..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.Net.WindowsGL.csproj", "{6D6009F4-0AFB-4806-89D7-7945F20270F5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.iOS", "..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.iOS.csproj", "{DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargaImage", "..\..\FreeSO\Other\libs\TargaImage\TargaImage.csproj", "{56F4BD87-2404-4263-80D5-6FA2161EB0A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargaImagePCL", "..\..\FreeSO\Other\libs\TargaImagePCL\TargaImagePCL.csproj", "{D8232422-9D79-4200-A981-EB70ED82CCF3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mp3Sharp", "..\..\FreeSO\Other\libs\mp3sharp\mp3sharp\Mp3Sharp.csproj", "{834CAB58-648D-47CC-AC6F-D01C08C809A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.WindowsGL", "..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.WindowsGL.csproj", "{6D75E618-19CA-4C51-9546-F10965FBC0B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.WindowsGL", "..\..\FreeSO\Other\libs\FSOMonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.WindowsGL.csproj", "{AE483C29-042E-4226-BA52-D247CE7676DA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.iOS", "..\..\FreeSO\Other\libs\FSOMonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.iOS.csproj", "{734EAA48-F1CA-481A-B391-0285BC0E8B40}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.Net.iOS", "..\..\FreeSO\Other\libs\FSOMonoGame\MonoGame.Framework\MonoGame.Framework.Net.iOS.csproj", "{D4838656-8545-4DC5-8822-D4AD313E17AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSO.IDE", "..\..\FreeSO\TSOClient\FSO.IDE\FSO.IDE.csproj", "{5DEB20EB-1EB7-48F9-922C-463ABAE56E63}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimplePaletteQuantizer", "..\..\FreeSO\Other\libs\ColorQuantizer\SimplePaletteQuantizer\SimplePaletteQuantizer.csproj", "{37812A22-91F3-4220-891E-5C26DA64A975}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Ad-Hoc|Any CPU = Ad-Hoc|Any CPU + Ad-Hoc|iPhone = Ad-Hoc|iPhone + Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator + Ad-Hoc|x86 = Ad-Hoc|x86 + AppStore|Any CPU = AppStore|Any CPU + AppStore|iPhone = AppStore|iPhone + AppStore|iPhoneSimulator = AppStore|iPhoneSimulator + AppStore|x86 = AppStore|x86 + Debug|Any CPU = Debug|Any CPU + Debug|iPhone = Debug|iPhone + Debug|iPhoneSimulator = Debug|iPhoneSimulator + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|iPhone = Release|iPhone + Release|iPhoneSimulator = Release|iPhoneSimulator + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|iPhone.Build.0 = AppStore|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.AppStore|x86.ActiveCfg = AppStore|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|Any CPU.ActiveCfg = Debug|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|iPhone.ActiveCfg = Debug|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|iPhone.Build.0 = Debug|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Debug|x86.ActiveCfg = Debug|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|Any CPU.ActiveCfg = Release|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|iPhone.ActiveCfg = Release|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|iPhone.Build.0 = Release|iPhone + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {F0BFC685-A357-4E5A-B502-1B5A35970E63}.Release|x86.ActiveCfg = Release|iPhone + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Ad-Hoc|x86.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|Any CPU.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|Any CPU.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|iPhone.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|iPhone.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|x86.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.AppStore|x86.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|Any CPU.ActiveCfg = Debug|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|Any CPU.Build.0 = Debug|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|iPhone.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|x86.ActiveCfg = Debug|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Debug|x86.Build.0 = Debug|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|Any CPU.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|Any CPU.Build.0 = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|iPhone.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|x86.ActiveCfg = Release|x86 + {32CBA4DB-99D8-4D1E-9420-E9B0D2359802}.Release|x86.Build.0 = Release|x86 + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|Any CPU.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|iPhone.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|x86.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.AppStore|x86.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|iPhone.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|iPhone.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|x86.ActiveCfg = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Debug|x86.Build.0 = Debug|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|Any CPU.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|iPhone.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|iPhone.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|x86.ActiveCfg = Release|Any CPU + {73E2AD5B-720B-4EF3-9B7C-55931D0EC693}.Release|x86.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|Any CPU.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|iPhone.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|x86.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.AppStore|x86.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|iPhone.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|iPhone.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Debug|x86.Build.0 = Debug|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|Any CPU.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|iPhone.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|iPhone.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|x86.ActiveCfg = Release|Any CPU + {0F20013D-0610-4573-A346-1C5A461B0BA0}.Release|x86.Build.0 = Release|Any CPU + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Ad-Hoc|x86.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|Any CPU.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|Any CPU.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|iPhone.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|iPhone.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|x86.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.AppStore|x86.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|Any CPU.ActiveCfg = Debug|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|Any CPU.Build.0 = Debug|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|iPhone.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|iPhone.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|x86.ActiveCfg = Debug|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Debug|x86.Build.0 = Debug|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|Any CPU.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|Any CPU.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|iPhone.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|iPhone.Build.0 = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|x86.ActiveCfg = Release|x86 + {C0068DF7-F2E8-4399-846D-556BF9A35C00}.Release|x86.Build.0 = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Ad-Hoc|x86.Build.0 = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|Any CPU.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|iPhone.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|x86.ActiveCfg = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.AppStore|x86.Build.0 = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|iPhone.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|iPhone.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|x86.ActiveCfg = Debug|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Debug|x86.Build.0 = Debug|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|Any CPU.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|iPhone.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|iPhone.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|x86.ActiveCfg = Release|x86 + {C42962A1-8796-4F47-9DCD-79ED5904D8CA}.Release|x86.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Ad-Hoc|x86.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|Any CPU.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|Any CPU.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|iPhone.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|iPhone.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|x86.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.AppStore|x86.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|Any CPU.ActiveCfg = Debug|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|Any CPU.Build.0 = Debug|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|iPhone.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|iPhone.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|x86.ActiveCfg = Debug|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Debug|x86.Build.0 = Debug|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|Any CPU.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|Any CPU.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|iPhone.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|iPhone.Build.0 = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|x86.ActiveCfg = Release|x86 + {18583453-A970-4AC5-83B1-2D6BFDF94C24}.Release|x86.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Ad-Hoc|x86.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|Any CPU.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|Any CPU.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|iPhone.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|iPhone.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|x86.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.AppStore|x86.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|Any CPU.ActiveCfg = Debug|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|Any CPU.Build.0 = Debug|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|iPhone.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|iPhone.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|x86.ActiveCfg = Debug|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Debug|x86.Build.0 = Debug|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|Any CPU.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|Any CPU.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|iPhone.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|iPhone.Build.0 = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|x86.ActiveCfg = Release|x86 + {5EDDEFD2-C850-49C1-812D-DDEFF09125EF}.Release|x86.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Ad-Hoc|x86.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|Any CPU.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|Any CPU.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|iPhone.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|iPhone.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|x86.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.AppStore|x86.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|Any CPU.ActiveCfg = Debug|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|Any CPU.Build.0 = Debug|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|iPhone.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|iPhone.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|x86.ActiveCfg = Debug|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Debug|x86.Build.0 = Debug|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|Any CPU.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|Any CPU.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|iPhone.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|iPhone.Build.0 = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|x86.ActiveCfg = Release|x86 + {072781D8-51EC-4143-9CAE-DAF50177D3AD}.Release|x86.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Ad-Hoc|x86.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|Any CPU.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|Any CPU.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|iPhone.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|iPhone.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|x86.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.AppStore|x86.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|Any CPU.ActiveCfg = Debug|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|Any CPU.Build.0 = Debug|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|iPhone.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|iPhone.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|x86.ActiveCfg = Debug|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Debug|x86.Build.0 = Debug|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|Any CPU.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|Any CPU.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|iPhone.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|iPhone.Build.0 = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|x86.ActiveCfg = Release|x86 + {FD7957F7-A1E0-4D00-8F6C-3FA555EAA163}.Release|x86.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Ad-Hoc|x86.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|Any CPU.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|Any CPU.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|iPhone.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|iPhone.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|x86.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.AppStore|x86.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|Any CPU.ActiveCfg = Debug|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|Any CPU.Build.0 = Debug|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|iPhone.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|iPhone.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|x86.ActiveCfg = Debug|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Debug|x86.Build.0 = Debug|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|Any CPU.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|Any CPU.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|iPhone.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|iPhone.Build.0 = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|x86.ActiveCfg = Release|x86 + {9D9558A9-755E-43F9-8BB6-B26F365F5042}.Release|x86.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|Any CPU.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|iPhone.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Ad-Hoc|x86.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|Any CPU.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|Any CPU.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|iPhone.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|iPhone.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|iPhoneSimulator.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|x86.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.AppStore|x86.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|Any CPU.ActiveCfg = Debug|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|Any CPU.Build.0 = Debug|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|iPhone.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|iPhone.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|x86.ActiveCfg = Debug|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Debug|x86.Build.0 = Debug|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|Any CPU.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|Any CPU.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|iPhone.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|iPhone.Build.0 = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|iPhoneSimulator.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|x86.ActiveCfg = Release|x86 + {B1A6E4C2-E080-4C34-A604-D11B5296A9B8}.Release|x86.Build.0 = Release|x86 + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|Any CPU.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|iPhone.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {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|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 + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Debug|x86.Build.0 = Debug|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|Any CPU.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|iPhone.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|iPhone.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|x86.ActiveCfg = Release|Any CPU + {7DE47032-A904-4C29-BD22-2D235E8D91BA}.Release|x86.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|Any CPU.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|iPhone.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {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|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 + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|x86.ActiveCfg = Debug|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Debug|x86.Build.0 = Debug|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|Any CPU.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|iPhone.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|iPhone.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|x86.ActiveCfg = Release|Any CPU + {6D6009F4-0AFB-4806-89D7-7945F20270F5}.Release|x86.Build.0 = Release|Any CPU + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|Any CPU.ActiveCfg = AppStore|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|iPhone.Build.0 = AppStore|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.AppStore|x86.ActiveCfg = AppStore|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|iPhone.ActiveCfg = Release|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|iPhone.Build.0 = Release|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|iPhone.ActiveCfg = Release|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|iPhone.Build.0 = Release|iPhone + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {DB8508BB-9849-4CC2-BC0F-8EB5DACB3C47}.Release|x86.ActiveCfg = Release|iPhoneSimulator + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|Any CPU.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|iPhone.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|x86.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.AppStore|x86.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|iPhone.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|iPhone.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|x86.ActiveCfg = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Debug|x86.Build.0 = Debug|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|Any CPU.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|iPhone.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|iPhone.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|x86.ActiveCfg = Release|Any CPU + {56F4BD87-2404-4263-80D5-6FA2161EB0A4}.Release|x86.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|Any CPU.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|iPhone.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|x86.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.AppStore|x86.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|iPhone.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|iPhone.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|x86.ActiveCfg = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Debug|x86.Build.0 = Debug|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|Any CPU.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|iPhone.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|iPhone.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|x86.ActiveCfg = Release|Any CPU + {D8232422-9D79-4200-A981-EB70ED82CCF3}.Release|x86.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|Any CPU.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|iPhone.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|x86.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.AppStore|x86.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|iPhone.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|iPhone.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|x86.ActiveCfg = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Debug|x86.Build.0 = Debug|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|Any CPU.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|iPhone.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|iPhone.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|x86.ActiveCfg = Release|Any CPU + {834CAB58-648D-47CC-AC6F-D01C08C809A4}.Release|x86.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|Any CPU.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|iPhone.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {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|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 + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|x86.ActiveCfg = Debug|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Debug|x86.Build.0 = Debug|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|Any CPU.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|iPhone.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|iPhone.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|x86.ActiveCfg = Release|Any CPU + {6D75E618-19CA-4C51-9546-F10965FBC0B8}.Release|x86.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|Any CPU.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|iPhone.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {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|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 + {AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.Build.0 = Debug|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|Any CPU.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|iPhone.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|iPhone.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.ActiveCfg = Release|Any CPU + {AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.Build.0 = Release|Any CPU + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|Any CPU.ActiveCfg = AppStore|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|iPhone.Build.0 = AppStore|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.AppStore|x86.ActiveCfg = AppStore|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|iPhone.ActiveCfg = Debug|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|iPhone.Build.0 = Debug|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|iPhone.ActiveCfg = Release|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|iPhone.Build.0 = Release|iPhone + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {734EAA48-F1CA-481A-B391-0285BC0E8B40}.Release|x86.ActiveCfg = Release|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|Any CPU.ActiveCfg = AppStore|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|iPhone.Build.0 = AppStore|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.AppStore|x86.ActiveCfg = AppStore|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|iPhone.ActiveCfg = Release|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|iPhone.Build.0 = Release|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|iPhone.ActiveCfg = Release|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|iPhone.Build.0 = Release|iPhone + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {D4838656-8545-4DC5-8822-D4AD313E17AC}.Release|x86.ActiveCfg = Release|iPhoneSimulator + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|x86.ActiveCfg = Release|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Ad-Hoc|x86.Build.0 = Release|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|Any CPU.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|iPhone.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|x86.ActiveCfg = Release|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.AppStore|x86.Build.0 = Release|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|iPhone.Build.0 = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|x86.ActiveCfg = Debug|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Debug|x86.Build.0 = Debug|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|Any CPU.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|iPhone.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|iPhone.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|x86.ActiveCfg = Release|x86 + {5DEB20EB-1EB7-48F9-922C-463ABAE56E63}.Release|x86.Build.0 = Release|x86 + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|Any CPU.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|iPhone.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|x86.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.AppStore|x86.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|iPhone.Build.0 = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|x86.ActiveCfg = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Debug|x86.Build.0 = Debug|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|Any CPU.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|iPhone.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|iPhone.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|x86.ActiveCfg = Release|Any CPU + {37812A22-91F3-4220-891E-5C26DA64A975}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal