From 7155f1cef00a92f07873dd3e8957ffbb4cfdde77 Mon Sep 17 00:00:00 2001 From: Regalis Date: Mon, 27 Jul 2015 23:45:20 +0300 Subject: [PATCH] Improved map rendering, shops, light bugfix, junction boxes wont break as easily --- Subsurface/Characters/Character.cs | 33 +- Subsurface/Characters/CharacterInfo.cs | 72 +++-- Subsurface/Characters/Ragdoll.cs | 10 +- .../Content/Items/Diving/divinggear.xml | 9 +- .../Content/Items/Electricity/signalitems.xml | 21 +- Subsurface/Content/Map/beaconSymbol.png | Bin 0 -> 2563 bytes Subsurface/Content/Map/citySymbol.png | Bin 0 -> 2202 bytes Subsurface/Content/Map/locationTypes.xml | 12 +- Subsurface/Content/Map/militarySymbol.png | Bin 0 -> 2173 bytes Subsurface/Content/Map/researchSymbol.png | Bin 0 -> 3195 bytes Subsurface/GUI/GUIComponent.cs | 4 +- Subsurface/GUI/GUIListBox.cs | 5 +- Subsurface/GameSession/CargoManager.cs | 53 ++++ Subsurface/GameSession/GameMode.cs | 2 +- Subsurface/GameSession/SinglePlayerMode.cs | 48 +-- .../Items/Components/Machines/Reactor.cs | 2 +- .../Items/Components/Power/PowerTransfer.cs | 5 +- .../Items/Components/Signal/LightComponent.cs | 17 +- Subsurface/Items/Item.cs | 8 +- Subsurface/Items/ItemPrefab.cs | 2 + Subsurface/Map/Hull.cs | 12 +- Subsurface/Map/Levels/Level.cs | 1 + Subsurface/Map/Lights/Light.cs | 5 + Subsurface/Map/Lights/LightManager.cs | 10 +- Subsurface/Map/Location.cs | 1 + Subsurface/Map/LocationType.cs | 11 + Subsurface/Map/Map.cs | 75 +++-- Subsurface/Map/MapEntityPrefab.cs | 7 + Subsurface/Map/WayPoint.cs | 7 +- Subsurface/Networking/GameClient.cs | 8 +- Subsurface/Networking/GameServer.cs | 8 +- Subsurface/Properties/AssemblyInfo.cs | 6 +- Subsurface/Screens/GameScreen.cs | 8 +- Subsurface/Screens/LobbyScreen.cs | 296 +++++++++--------- Subsurface/Screens/MainMenu.cs | 1 + Subsurface/Subsurface.csproj | 13 + Subsurface_Solution.v12.suo | Bin 488448 -> 489472 bytes 37 files changed, 472 insertions(+), 300 deletions(-) create mode 100644 Subsurface/Content/Map/beaconSymbol.png create mode 100644 Subsurface/Content/Map/citySymbol.png create mode 100644 Subsurface/Content/Map/militarySymbol.png create mode 100644 Subsurface/Content/Map/researchSymbol.png create mode 100644 Subsurface/GameSession/CargoManager.cs diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index a17bb1466..bbbcced1f 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -175,20 +175,13 @@ namespace Subsurface public float Bleeding { get { return bleeding; } - set { bleeding = value; } + set + { + if (float.IsNaN(value) || float.IsInfinity(value)) return; + bleeding = Math.Max(value, 0.0f); + } } - - - //public float Blood - //{ - // get { return blood; } - // set - // { - // blood = MathHelper.Clamp(value, 0.0f, 100.0f); - // if (blood == 0.0f) Kill(); - // } - //} - + public Item[] SelectedItems { get { return selectedItems; } @@ -716,7 +709,14 @@ namespace Subsurface public void Draw(SpriteBatch spriteBatch) { AnimController.Draw(spriteBatch); + + //GUI.DrawLine(spriteBatch, ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y), + // ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y) + + // ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green); + } + public void DrawFront(SpriteBatch spriteBatch) + { if (IsNetworkPlayer) { Vector2 namePos = new Vector2(Position.X, -Position.Y - 80.0f) - GUI.Font.MeasureString(Info.Name) * 0.5f; @@ -731,13 +731,12 @@ namespace Subsurface Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition); pos.Y = -pos.Y; - - + if (this == Character.controlled) return; Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f); - GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X-2, (int)healthBarPos.Y-2, 100+4, 15+4), Color.Black, false); - GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f*(health/maxHealth)), 15), Color.Red, true); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X - 2, (int)healthBarPos.Y - 2, 100 + 4, 15 + 4), Color.Black, false); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f * (health / maxHealth)), 15), Color.Red, true); //GUI.DrawLine(spriteBatch, ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y), diff --git a/Subsurface/Characters/CharacterInfo.cs b/Subsurface/Characters/CharacterInfo.cs index 67660c959..e8d68ccda 100644 --- a/Subsurface/Characters/CharacterInfo.cs +++ b/Subsurface/Characters/CharacterInfo.cs @@ -1,4 +1,5 @@ using Microsoft.Xna.Framework; +using System; using System.Collections.Generic; using System.Xml.Linq; @@ -13,9 +14,7 @@ namespace Subsurface public Character Character; public readonly string File; - - public int HeadSpriteId; - + public Job Job; private List pickedItems; @@ -23,6 +22,28 @@ namespace Subsurface private Vector2[] headSpriteRange; private Gender gender; + + public int Salary; + + public int HeadSpriteId; + private Sprite headSprite; + + public bool StartItemsGiven; + + public List PickedItemIDs + { + get { return pickedItems; } + } + + public Sprite HeadSprite + { + get + { + if (headSprite == null) LoadHeadSprite(); + return headSprite; + } + } + public Gender Gender { get { return gender; } @@ -45,25 +66,6 @@ namespace Subsurface } } - public int Salary; - - public bool StartItemsGiven; - - public List PickedItemIDs - { - get { return pickedItems; } - } - - private Sprite headSprite; - public Sprite HeadSprite - { - get - { - if (headSprite == null) LoadHeadSprite(); - return headSprite; - } - } - public CharacterInfo(string file, string name = "", Gender gender = Gender.None, JobPrefab jobPrefab = null) { this.File = file; @@ -77,8 +79,6 @@ namespace Subsurface XDocument doc = ToolBox.TryLoadXml(file); if (doc == null) return; - Salary = 500; - if (ToolBox.GetAttributeBool(doc.Root, "genders", false)) { if (gender == Gender.None) @@ -131,6 +131,8 @@ namespace Subsurface this.Name += ToolBox.GetRandomLine(lastNamePath); } } + + Salary = CalculateSalary(); } private void LoadHeadSprite() @@ -232,6 +234,20 @@ namespace Subsurface } } + private int CalculateSalary() + { + if (Name == null || Job == null) return 0; + + int salary = Math.Abs(Name.GetHashCode()) % 100; + + foreach (Skill skill in Job.Skills) + { + salary += skill.Level * 10; + } + + return salary; + } + public virtual XElement Save(XElement parentElement) { XElement charElement = new XElement("character"); @@ -244,18 +260,16 @@ namespace Subsurface new XAttribute("headspriteid", HeadSpriteId), new XAttribute("startitemsgiven", StartItemsGiven)); - if (Character!=null && Character.Inventory!=null) + if (Character != null && Character.Inventory != null) { UpdateCharacterItems(); } - - if (pickedItems.Count>0) + + if (pickedItems.Count > 0) { charElement.Add(new XAttribute("items", string.Join(",", pickedItems))); } - - Job.Save(charElement); parentElement.Add(charElement); diff --git a/Subsurface/Characters/Ragdoll.cs b/Subsurface/Characters/Ragdoll.cs index 4bd4c68e8..9bb60d500 100644 --- a/Subsurface/Characters/Ragdoll.cs +++ b/Subsurface/Characters/Ragdoll.cs @@ -320,17 +320,17 @@ namespace Subsurface } avgVelocity = avgVelocity / limbs.Count(); - - float impact = Vector2.Dot((f1.Body.LinearVelocity + avgVelocity)/2.0f, -normal); - + + float impact = Vector2.Dot((f1.Body.LinearVelocity + avgVelocity) / 2.0f, -normal); + Limb l = (Limb)f1.Body.UserData; - if (impact > 1.0f && l.HitSound != null && l.soundTimer<=0.0f) l.HitSound.Play(Math.Min(impact / 5.0f, 1.0f), impact*100.0f, l.body.FarseerBody); + if (impact > 1.0f && l.HitSound != null && l.soundTimer <= 0.0f) l.HitSound.Play(Math.Min(impact / 5.0f, 1.0f), impact * 100.0f, l.body.FarseerBody); if (impact > l.impactTolerance) { - character.Health -= (impact-l.impactTolerance*0.1f); + character.Health -= (impact - l.impactTolerance * 0.1f); strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance); } } diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index 63c0ee175..33400496a 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -3,7 +3,8 @@ + pickdistance="150" + price="50"> @@ -16,7 +17,8 @@ + pickdistance="200" + price="50"> @@ -37,7 +39,8 @@ + pickdistance="200" + price="200"> diff --git a/Subsurface/Content/Items/Electricity/signalitems.xml b/Subsurface/Content/Items/Electricity/signalitems.xml index 8ac51db20..982f40afb 100644 --- a/Subsurface/Content/Items/Electricity/signalitems.xml +++ b/Subsurface/Content/Items/Electricity/signalitems.xml @@ -7,7 +7,8 @@ Tags="smallitem" pickdistance="150" linkable="true" - canbepicked="true"> + canbepicked="true" + price="10"> @@ -23,7 +24,8 @@ name="And Component" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> @@ -52,7 +54,8 @@ name="Or Component" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> @@ -79,7 +82,8 @@ name="Not Component" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> @@ -105,7 +109,8 @@ name="Light Component" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> @@ -133,7 +138,8 @@ name="Oxygen Detector" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> @@ -157,7 +163,8 @@ name="RegEx Find Component" Tags="smallitem" pickdistance="150" - linkable="true"> + linkable="true" + price="10"> diff --git a/Subsurface/Content/Map/beaconSymbol.png b/Subsurface/Content/Map/beaconSymbol.png new file mode 100644 index 0000000000000000000000000000000000000000..24d60424d34b092bae275a5635da87dc0b30430e GIT binary patch literal 2563 zcmV+e3jFnnP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ_iAh93RCwCVn}3v5RTalS_sx4V!{e6%%ODj8GC=zwNQi+UG8t4_uO;O*=L`JPI5t$Dk8sn)pnh4*0bOn`$S`x&-(U@OR)2;LKAkfUBjR_W|3;lUcA6yCi1(@32M(}3fZteTH*r&bw zZ(t8_5I7EGfhwSzG^;Og5%8{#EC%Mrob;=}o=1qs0ioqz$r zIA8*BX^eN?BA0qS&`>S`ECX(gF^DID2Y{!GbXO-Nuooow4+7T$Q-IDM&tD@UUIjFk zY6BL>nEVEDfsX-?c})HaU@b7)(IyLQ1a6WW{0Wfp7|SPtl|XeV0{E(@+SdbffYHDc zF;@DEz*q^`hdXSQp&JWq_h>&+3s{r@J|ctXGpNgfB|vjbRX-ULU>y7j7^xMG!cAhQ zu>^3I7*|z9=Z}l|Jzu2z%9h~z_Q@6B=F#@<0&#{@0N)4Bi|BNXjLiQ|F$Y)#e9a@K zc(Bld781Z`WN}^ioh)qwry7aef_*)r&%AMLvxelE^G&C?~OCFJoM{clL~X{u?WvQ-b?1$H_5nWnyS0=Nj1zq8>F zqO1m)JWrlt4wX5^b+!gM)RTF<*{a8cH3mFGYCjr)RIrvblYzrz#rWSAz#$n$8)_72 z<%TmZf{NbP=9he3NO3Eb+!1=gYW$L+20^5=Tb@()l1w-e?4i_VC1q+Xn{GrhV)YLITda4R zmAXi2YSC152^mJ|@1vsB{~@4?EQ5gwWSAfeJ_qBm&7rN(o4q6HosN6G68XVF0ZZzS zlrnLhL^G-w3fzxhc6TTy-QF(}dGM$JRVBAzy z7{je>&`pSHGeNexp|OE%MfMev%qL5lW@gZ=t(J+^;~~d9lF115YY;U5;Y|v++24}XqUXM?P?O? zXtDm?J#vb8XkH680tuSv8De~|YVqvj3fNDA&dLcE+~P?Y30rCVof5zpOwG==Z!=`s z7BWvgi6}^TW%}Ai9=%(I(iJ>Mvm==jupd*swpEi3CoyMotVAJ1TDE%b;ZkvgwndL1 zv?asX;h{(UT}(F-L3W17t9K+$INWbB;vMLUbQ2;UHuM)g?MUp4FwAkc(s0N97ZboM zqAxbqJ+1@PK8*c%*7iO4z`zLiy*?qT_*X}xiLuFNY1k8kGeqIDj!f5Uz{@Sx)^+}F zSW%3wcpNWNKb=IzY*+^zZV|vABNXbo4irGf68Xo)6%qF9nXtdz2>ip*cnT(c-4Pfp zUUFgR>JvMnaMudoz*M$#M`W@JTOY7RO~8Ci)y3EP7JCYH81SMa;P%1Qm@^ADtZZSx z;Xyv4Y|Ocqhb93(qfmypEnb&Ei#48wm|zxDhm1m3&BJA5mgmC3JO=h4}h@>Px|T%+a|* zxE{D6V)Ym1uWA?vfp6iivtO&YV3Fm1XG{UIykEBrkur=-#@w4tVv<;&6`9jR8 z(bENkF{QAsjy5~BxVSU`WlyGK%Hgh+{GP0Gei8B*QK|IOkRK?G0)82husNx%@s^JO zz!&GQ|$jh^s99@rgp8Oj|MuEAYv52K&l(H6{U)6o&u*@X)+ z$M)*P-N$%7w+Z+-9>?>2`Fg!HVNVQ(*F%=~222KbgZRTv#o~K0=K(TW;j^SQeU-?# zMD8taOtDIK$?MyMIGs0OPLFRF3F;o>*_s0EvR+pPQzhd;XFXz>t>;-0Sk7;UcLR4Rq#h@iHAWUaD52k7 z^8e3b&J^u0r$m$Oq@JsERb$Q|T`CPZ4|5=+yIfyN!f6tHJ}h7vK$o01wd4Q*002ovPDHLkV1jUvtiJ#N literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Map/citySymbol.png b/Subsurface/Content/Map/citySymbol.png new file mode 100644 index 0000000000000000000000000000000000000000..730f9f813b384f15a78bc165944b9b80b9e362d6 GIT binary patch literal 2202 zcmV;L2xa$)P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ^AW1|)RCwCVn|Z7i)g8w__rCjN(LN&LZjcD#mb#;ewywC;ihGG$7eQ&GxT3}w ztFd(fqoTM~t5MNJ2&nOCT`HhxAtKZzidKr6zT$=mvOL~)-}R64y*eCc&Y77zb9vw7 zCO0!@X3qT1@BEhU?>B|9W5<#+wg!d(BY<6iZGdfo0YG1%0IUbT1-<~j0+s^*0zL*> z@|;{Lr~B>$j06tRi*FI*njL^Wtz&C|1;87?Ea3H?EPzdb6M#PfzXTdHxaZG+BlWvZ z!uUHd9r!MbNf$GE@e6^4zzj{cF(=JB0C)iSH*h_$`NkH&Z={}6fS*%8>=e+5Kgy2O zRRG%nQ-Nu~Fg6~B0QUhe0lU>p0LRHfpH0ufNMJ57CT}Bn2{2LnJ}H)K?|uS&4y*!N zfeO$IXp&|P1oi?3CsgeLGLX9gR|B0{3t$p(MZ%Z<3}^Thq;-C*O6gU<*2^gN> znU~9@{tjr*N&t5Q7bKX(3&4ZG?3C_my#)5I1b+~42Ji=9(-_x}mJm+|I%>56lM=lA z8;S*f1w5URudV>|fbnvJ4+GsXt{VkB0raj#02jwp`!-+#a2W7hj>c}W4Baunk{IJp z(*mXvz|k^zaVB*ra2rsrlhuC(I9My}!+1rfi3G5fBCcMZn>Q=+Td)ya-*UO)Yh#R^ z7?Ni=1uz-d(R0&hWn{kG$T7fQflFiL6c2?hXqW&_k;Qf4d0EUhw6?X|qJy16NGlP-}j{|Ov> zU-SHP#5MhabAcOe0bJ;L*bO=Q`I6K#?X@;;mnIC1xMnPH2hduz0efNiyC}R2yqM$O ztth;m4gAGAH(l&clm=8Hw#BWE=M7S#^@9;S)<&MIU zK>@f{zXh0+^UD{sl0!wf1hKD@tEBh>!%;@zD4V3BATIU>jz~DkSAo~`zgwEn5I7%pEG`y_ zlo=GEbt8(N)n5U;li-2v0V{mCwc1Z=-*s8nbZ9aS7?SnO5Q{!Kr3S1MM-dqw7d^gz z5vF976ifBspoLzh0Hxxv1IvK7tm8{+%r+N0&J8SKYIjliZ_0vRkq4wZyXpR)(zDR~RbY-vaueM^`Ubrh2B|3V-?e_RtU1tPjzB$&pC zglHP@sPc}W5u6=j8>;A3g0pkP`Ar={DwRAE9F3{z`%nh%;>Th{TS)BC9wVM;2i980 z+AwAEs1UjXIA2Lo;sC7VP!A#klPEkE5Woe%sg}VzRW_jH5aMYeZh1WJGF%}~d+=@Gw~l>Tjls{gUiL-BxcwjASF9_YgK4xZ!~^F%e#3##KZ z;x#7E!?dcba*UZQKA>zFv!i1OuU0f*8l9Nte+XjHwc5O^MY5_t@ScOjRDD z_DWD1N-Qnb$26{=YH{%ipe!r;Z4HyEml5oc>-4e4U2@GU;|Kt)-sLGKLyeSJQuLNZ z_Ypc175NcY0M$JF_5`kHkVT0-A3}*WlkHb34ft8%XNYc=@J{Ax<>Eeap{SQzQv)TI z2j*i4)9$na=unQ{TcNBATk6+Suu%44xo_os=)}S0GcpesfCR0H&ZMBb)3OTKACC9bdQfGqfgd^37GzXS|h|x;3iCMA$A{Qns0{g z#Wny6VlL{`)@x?z^a5fCnv%I+08)g}mwa5tFiRlzOLcd*V zwDA8^82g%{%WtxjXelT4oT*=LOb^mS4N>4uw-`^ + commonness="3" + symbol="Content\Map\beaconSymbol.png"> + hireablecharacters="true" + symbol="Content\Map\citySymbol.png"> + hireablecharacters="true" + symbol="Content\Map\militarySymbol.png"> + hireablecharacters="true" + symbol="Content\Map\researchSymbol.png"> (_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ^14%?dRCwCln|W*(MHI(BU0YiUEl?4~gG&w}Q4Zy-A|eQQABYlEMDU8B#sh*|htc z+1Z&lZ{EEbBS(%T#W)UV1@r{k0>=YQfJQ(rkOAxm{sguIzXLx4UjQ3{EvcMbW{Sq` z1oQ*Wl7$}=2i z3pIyU!1KU|K)dQ9z(A4E*Yf{CKj3pK07HP`K;0P6UoAwu3OHC*889h<#V-+C-~!<7 zBsR^ zI6Ic?)--lb~F#7N~O_6ikm@x0Le z31S08p^aFMLEH_jQ0CuQI4zO@M~lSNFfQT+xngzIBB_L6iVD z0L98Xh6cGHNPvrgQtPf zdzFU*_b#{B)xJW4GB!u7r{~!HUBD{R7yHC9vzo`AL-()1q^!~z>y);p9wv8Z!w;lC zHY;t7Jc|bwl%(m7t(ukUVZzBa{8bAGuw4<-xh^xdv=$JcSXoD=hn{?>s09S5P}Y&* zVPfzo{(QP4S6N4y=TLL`wSWMPm1AD&IVAmYwSWL8DaX9n!_?$h4TV}j0BsGsJcqH< ziRfTwI-#xR>3W!4zYQ(LSxQ%Uj(EZv57;11gUw?akmkGJL1|y?iK+Ot(rFNf$KTTl zS7MKJZ3Wi*0Z6U>t_yHR8ZN#LaJ|xA z?$Y{)=RXX%Ntu5Mp_+y80K2hgZF~&DBsYQrN2|oja@+@z6B2^1BCcS2A@)?5k7vd3 zQ>Ew(;2KdQHjKxVrA)!3rxq%jU_YiPqx`P&hb3e&XF=BUlh zuzWGn29pjia8Ps%CJ9-S=!K~_(t^9?V$v6BEEL2>Ov$MWlQ4O|x;3=;;h4N+6Gy*^ zQHyt-u~#v9b{B3FN!+m-7oIP6%S;Y0sEEQlC}nsqAu|^9d5Q~NfX^`HZUre`{7~^- zZi&%%DR8r9=DP@R5L1jeKjyAHjLGSbQVgofAQw}@Qv|$*rRXt)<(Mk99dXr&4P}@z zxVbSW+d|aQDonL$Z-;c&&>mB^w_I%ZJ~5wLim5YjmgmPUmoF7g*hWOLp#=qEl-wl7 z)e=mia<-kR5I;T+>tn8C^xLB>GXuJdsPWzD-DE@B^6Y@l9gh)=%Ks<{Vir zS1MNprf{lW6^}`osN`{p#>^7MbYbhIRh)2+_z?w3So}s|`EiLpSlO?}RtXXAr)D$A zf6K1-l%NjPMF3wzOcE71jriXKB?J3J8*~$EbXR2uO2(I?zlmTxLs;;~6fS(57-wBD zHOuR&I$$!t9o~Ye_n#_ucOSXhQiU%&F%_RhVrVT0I6z53W{TKzo?JPY8l>*RA68;?kO{kes_hyg|00000NkvXXu0mjf@Nd?7 literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Map/researchSymbol.png b/Subsurface/Content/Map/researchSymbol.png new file mode 100644 index 0000000000000000000000000000000000000000..bce735f30a0d716e91bdb9a0971c9cba29772bc1 GIT binary patch literal 3195 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 literal 0 HcmV?d00001 diff --git a/Subsurface/GUI/GUIComponent.cs b/Subsurface/GUI/GUIComponent.cs index d2b5ba2ba..c89948873 100644 --- a/Subsurface/GUI/GUIComponent.cs +++ b/Subsurface/GUI/GUIComponent.cs @@ -298,9 +298,9 @@ namespace Subsurface public virtual void DrawChildren(SpriteBatch spriteBatch) { - foreach (GUIComponent child in children) + for (int i = 0; i < children.Count; i++ ) { - child.Draw(spriteBatch); + children[i].Draw(spriteBatch); } } diff --git a/Subsurface/GUI/GUIListBox.cs b/Subsurface/GUI/GUIListBox.cs index 09f6f0a43..ffaf15f1e 100644 --- a/Subsurface/GUI/GUIListBox.cs +++ b/Subsurface/GUI/GUIListBox.cs @@ -280,7 +280,10 @@ namespace Subsurface Debug.WriteLine("clicked"); selected = child; if (OnSelected != null) - OnSelected(child.UserData); + { + if (!OnSelected(child.UserData)) selected = null; + } + } } else diff --git a/Subsurface/GameSession/CargoManager.cs b/Subsurface/GameSession/CargoManager.cs new file mode 100644 index 000000000..ddb928db7 --- /dev/null +++ b/Subsurface/GameSession/CargoManager.cs @@ -0,0 +1,53 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Subsurface +{ + class CargoManager + { + private List purchasedItems; + + public CargoManager() + { + purchasedItems = new List(); + } + + public void AddItem(MapEntityPrefab item) + { + purchasedItems.Add(item); + } + + public void CreateItems() + { + WayPoint wp = WayPoint.GetRandom(SpawnType.Cargo); + + if (wp==null) + { + DebugConsole.ThrowError("The submarine must have a waypoint marked as Cargo for bought items to be placed correctly!"); + return; + } + + Hull cargoRoom = Hull.FindHull(wp.Position); + + if (wp == null) + { + DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!"); + return; + } + + foreach (MapEntityPrefab prefab in purchasedItems) + { + Vector2 position = new Vector2( + Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20), + Rand.Range(cargoRoom.Rect.Y - cargoRoom.Rect.Height + 20.0f, cargoRoom.Rect.Y)); + + new Item(prefab as ItemPrefab, wp.Position); + } + + purchasedItems.Clear(); + } + } +} diff --git a/Subsurface/GameSession/GameMode.cs b/Subsurface/GameSession/GameMode.cs index ce89ffbe2..256079229 100644 --- a/Subsurface/GameSession/GameMode.cs +++ b/Subsurface/GameSession/GameMode.cs @@ -20,7 +20,7 @@ namespace Subsurface //Constructor = constructor; - Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset) }); + Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset)}); IsSinglePlayer = isSinglePlayer; diff --git a/Subsurface/GameSession/SinglePlayerMode.cs b/Subsurface/GameSession/SinglePlayerMode.cs index 3b3e2d8ed..d43ef6d5f 100644 --- a/Subsurface/GameSession/SinglePlayerMode.cs +++ b/Subsurface/GameSession/SinglePlayerMode.cs @@ -10,50 +10,58 @@ namespace Subsurface { class SinglePlayerMode : GameMode { - private const int StartCharacterAmount = 3; + //private const int StartCharacterAmount = 3; public readonly CrewManager crewManager; //public readonly HireManager hireManager; private GUIButton endShiftButton; - //private int day; - - //public int Day - //{ - // get { return day; } - //} - + public readonly CargoManager CargoManager; + public Map map; - bool crewDead; + private bool crewDead; private float endTimer; private bool savedOnStart; - public SinglePlayerMode(GameModePreset preset, bool generateCrew=true) + public SinglePlayerMode(GameModePreset preset) : base(preset) { crewManager = new CrewManager(); + CargoManager = new CargoManager(); + endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 220, 20, 200, 25), "End shift", Alignment.TopLeft, GUI.style); endShiftButton.OnClicked = EndShift; - for (int i = 0; i < StartCharacterAmount; i++) + for (int i = 0; i < 3; i++) { + JobPrefab jobPrefab = null; + switch (i) + { + case 0: + jobPrefab = JobPrefab.List.Find(jp => jp.Name == "Captain"); + break; + case 1: + jobPrefab = JobPrefab.List.Find(jp => jp.Name == "Engineer"); + break; + case 2: + jobPrefab = JobPrefab.List.Find(jp => jp.Name == "Mechanic"); + break; + } + CharacterInfo characterInfo = - new CharacterInfo(Character.HumanConfigFile, "", Gender.None, JobPrefab.Random()); + new CharacterInfo(Character.HumanConfigFile, "", Gender.None, jobPrefab); crewManager.characterInfos.Add(characterInfo); } - - //day = 1; + } public SinglePlayerMode(XElement element) - : this(GameModePreset.list.Find(gm => gm.Name == "Single Player"), false) + : this(GameModePreset.list.Find(gm => gm.Name == "Single Player")) { - //day = ToolBox.GetAttributeInt(element,"day",1); - string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a"); GenerateMap(mapSeed); @@ -75,16 +83,14 @@ namespace Subsurface public override void Start(TimeSpan duration) { + CargoManager.CreateItems(); + if (!savedOnStart) { SaveUtil.SaveGame(Game1.GameSession.SavePath); savedOnStart = true; - - - //Game1.GameSession.submarine.Load(); } - endTimer = 5.0f; crewManager.StartShift(); diff --git a/Subsurface/Items/Components/Machines/Reactor.cs b/Subsurface/Items/Components/Machines/Reactor.cs index a35c87e20..7166cd19f 100644 --- a/Subsurface/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Items/Components/Machines/Reactor.cs @@ -123,7 +123,7 @@ namespace Subsurface.Items.Components MeltDown(); return; } - else if (temperature==0.0f) + else if (temperature == 0.0f) { if (powerUpTask == null || powerUpTask.IsFinished) { diff --git a/Subsurface/Items/Components/Power/PowerTransfer.cs b/Subsurface/Items/Components/Power/PowerTransfer.cs index b51c9eaa7..83c5b31fd 100644 --- a/Subsurface/Items/Components/Power/PowerTransfer.cs +++ b/Subsurface/Items/Components/Power/PowerTransfer.cs @@ -50,7 +50,7 @@ namespace Subsurface.Items.Components pt.powerLoad += (fullLoad - pt.powerLoad) / inertia; pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia; pt.Item.SendSignal("", "power", fullPower / Math.Max(fullLoad, 1.0f)); - if (-pt.currPowerConsumption > pt.powerLoad * 2.0f) pt.item.Condition = 0.0f; + if (-pt.currPowerConsumption > Math.Max(pt.powerLoad * 2.0f, 200.0f)) pt.item.Condition -= deltaTime*10.0f; } } @@ -139,7 +139,6 @@ namespace Subsurface.Items.Components { connection.SendSignal(signal, sender, 0.0f); } - } - + } } } diff --git a/Subsurface/Items/Components/Signal/LightComponent.cs b/Subsurface/Items/Components/Signal/LightComponent.cs index dd9c66a7d..369af7c9a 100644 --- a/Subsurface/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Items/Components/Signal/LightComponent.cs @@ -83,6 +83,12 @@ namespace Subsurface.Items.Components light.Position = ConvertUnits.ToDisplayUnits(item.body.Position); } + if (item.container!= null) + { + light.Color = Color.Transparent; + return; + } + if (powerConsumption == 0.0f) { voltage = 1.0f; @@ -92,9 +98,9 @@ namespace Subsurface.Items.Components currPowerConsumption = powerConsumption; } - if (Rand.Range(0.0f, 1.0f)<0.05f && voltage < Rand.Range(0.0f, minVoltage)) + if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage)) { - if (voltage>0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.Position); + if (voltage > 0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.Position); lightBrightness = 0.0f; } else @@ -117,6 +123,13 @@ namespace Subsurface.Items.Components } } + public override void Remove() + { + base.Remove(); + + light.Remove(); + } + public override void ReceiveSignal(string signal, Connection connection, Item sender, float power=0.0f) { base.ReceiveSignal(signal, connection, sender, power); diff --git a/Subsurface/Items/Item.cs b/Subsurface/Items/Item.cs index d736ede36..9d8e4918e 100644 --- a/Subsurface/Items/Item.cs +++ b/Subsurface/Items/Item.cs @@ -65,6 +65,8 @@ namespace Subsurface get { return condition; } set { + if (float.IsNaN(value)) return; + float prev = condition; condition = MathHelper.Clamp(value, 0.0f, 100.0f); if (condition==0.0f && prev>0.0f) @@ -1063,6 +1065,8 @@ namespace Subsurface public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data) { + message.Write(condition); + switch (type) { case NetworkEventType.DropItem: @@ -1077,6 +1081,8 @@ namespace Subsurface public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) { + Condition = message.ReadFloat(); + switch (type) { case NetworkEventType.DropItem: @@ -1096,7 +1102,7 @@ namespace Subsurface base.Remove(); //sprite.Remove(); - if (body!=null) body.Remove(); + if (body != null) body.Remove(); foreach (ItemComponent ic in components) { diff --git a/Subsurface/Items/ItemPrefab.cs b/Subsurface/Items/ItemPrefab.cs index c06c83357..87360fdb4 100644 --- a/Subsurface/Items/ItemPrefab.cs +++ b/Subsurface/Items/ItemPrefab.cs @@ -156,6 +156,8 @@ namespace Subsurface focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false); offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f); + + price = ToolBox.GetAttributeInt(element, "price", 0); Triggers = new List(); diff --git a/Subsurface/Map/Hull.cs b/Subsurface/Map/Hull.cs index 5c6661380..31ff18ca9 100644 --- a/Subsurface/Map/Hull.cs +++ b/Subsurface/Map/Hull.cs @@ -32,15 +32,15 @@ namespace Subsurface public readonly Dictionary properties; - float lethalPressure; + private float lethalPressure; - float surface; - float volume; - float pressure; + private float surface; + private float volume; + private float pressure; - float oxygen; + private float oxygen; - bool update; + private bool update; float[] waveY; //displacement from the surface of the water float[] waveVel; //velocity of the point diff --git a/Subsurface/Map/Levels/Level.cs b/Subsurface/Map/Levels/Level.cs index 6f5776ee8..c950acf7d 100644 --- a/Subsurface/Map/Levels/Level.cs +++ b/Subsurface/Map/Levels/Level.cs @@ -300,6 +300,7 @@ namespace Subsurface for (int n = -1; n < 2; n += 2) { int cellIndex = FindCellIndex(new Vector2(tunnelStart.X + minWidth * 0.5f * n, tunnelStart.Y), 3); + foreach (GraphEdge ge in cells[cellIndex].edges) { if (ge.point1.Y > cells[cellIndex].Center.Y) ge.point1.Y = borders.Height + shaftHeight; diff --git a/Subsurface/Map/Lights/Light.cs b/Subsurface/Map/Lights/Light.cs index b2924d1c4..400ad8efc 100644 --- a/Subsurface/Map/Lights/Light.cs +++ b/Subsurface/Map/Lights/Light.cs @@ -57,5 +57,10 @@ namespace Subsurface.Lights float scale = range / ((float)lightTexture.Width / 2.0f); spriteBatch.Draw(lightTexture, new Vector2(Position.X, -Position.Y), null, color, 0, center, scale, SpriteEffects.None, 1); } + + public void Remove() + { + Game1.LightManager.RemoveLight(this); + } } } diff --git a/Subsurface/Map/Lights/LightManager.cs b/Subsurface/Map/Lights/LightManager.cs index 05b141d32..bb5029f5f 100644 --- a/Subsurface/Map/Lights/LightManager.cs +++ b/Subsurface/Map/Lights/LightManager.cs @@ -76,13 +76,11 @@ namespace Subsurface.Lights foreach (LightSource light in lights) { if (light.Color.A < 0.01f || light.Range < 0.01f) continue; - - - if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, viewRect)) continue; - //clear alpha to 1 - ClearAlphaToOne(graphics, spriteBatch); - + ClearAlphaToOne(graphics, spriteBatch); + + if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, viewRect)) continue; + //draw all shadows //write only to the alpha channel, which sets alpha to 0 graphics.RasterizerState = RasterizerState.CullNone; diff --git a/Subsurface/Map/Location.cs b/Subsurface/Map/Location.cs index ccfc0ddda..92d2cfb1a 100644 --- a/Subsurface/Map/Location.cs +++ b/Subsurface/Map/Location.cs @@ -29,6 +29,7 @@ namespace Subsurface get { return mapPosition; } } + public bool Discovered; public LocationType Type { diff --git a/Subsurface/Map/LocationType.cs b/Subsurface/Map/LocationType.cs index 028dfa131..cd705c61f 100644 --- a/Subsurface/Map/LocationType.cs +++ b/Subsurface/Map/LocationType.cs @@ -19,6 +19,8 @@ namespace Subsurface private List nameFormats; + private Sprite sprite; + public bool HasHireableCharacters { get; @@ -35,6 +37,11 @@ namespace Subsurface get { return nameFormats; } } + public Sprite Sprite + { + get { return sprite; } + } + private LocationType(XElement element) { name = element.Name.ToString(); @@ -49,6 +56,10 @@ namespace Subsurface { nameFormats.Add(nameFormat.Value.ToString()); } + + string spritePath = ToolBox.GetAttributeString(element, "symbol", "Content/Map/beaconSymbol.png"); + sprite = new Sprite(spritePath, null, new Microsoft.Xna.Framework.Vector2(-32, -32)); + } public static LocationType Random() diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index 67dd8b5ed..f923c26f0 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -22,7 +22,7 @@ namespace Subsurface private int seed; private int size; - private static Texture2D iceTexture; + private static Sprite iceTexture; private static Texture2D iceCraters; private static Texture2D iceCrack; @@ -61,7 +61,7 @@ namespace Subsurface connections = new List(); - if (iceTexture==null) iceTexture = Game1.TextureLoader.FromFile("Content/Map/iceSurface.png"); + if (iceTexture==null) iceTexture = new Sprite("Content/Map/iceSurface.png", Vector2.Zero); if (iceCraters == null) iceCraters = Game1.TextureLoader.FromFile("Content/Map/iceCraters.png"); if (iceCrack == null) iceCrack = Game1.TextureLoader.FromFile("Content/Map/iceCrack.png"); @@ -244,14 +244,18 @@ namespace Subsurface } private Location highlightedLocation; - public void Draw(SpriteBatch spriteBatch, Rectangle rect) + public void Draw(SpriteBatch spriteBatch, Rectangle rect, float scale = 1.0f) { //GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true); - spriteBatch.Draw(iceTexture, rect, Color.White); + Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y); + Vector2 offset = -currentLocation.MapPosition; - Vector2 rectCorner = new Vector2(rect.X, rect.Y); - Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size); + iceTexture.DrawTiled(spriteBatch, new Vector2(rect.X, rect.Y), new Vector2(rect.Width, rect.Height), offset, Color.White); + + //spriteBatch.Draw(iceTexture, offset, rect, null, null, 0f, null, Color.White, SpriteEffects.None, 0.0f); + + //Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size); float maxDist = 20.0f; float closestDist = 0.0f; @@ -259,9 +263,11 @@ namespace Subsurface for (int i = 0; i < locations.Count;i++ ) { Location location = locations[i]; - Vector2 pos = rectCorner + location.MapPosition * scale; + Vector2 pos = rectCenter + (location.MapPosition+offset) * scale; - float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(pos.X, pos.Y)); + if (!rect.Contains(pos)) continue; + + float dist = Vector2.Distance(PlayerInput.MousePosition, pos); if (dist < maxDist && (highlightedLocation == null || dist < closestDist)) { closestDist = dist; @@ -272,7 +278,7 @@ namespace Subsurface foreach (LocationConnection connection in connections) { - Color crackColor = Color.Lerp(Color.LightGreen, Color.DarkRed, connection.Difficulty/100.0f); + Color crackColor = Color.White * Math.Max(connection.Difficulty/100.0f, 0.5f); if (highlightedLocation != currentLocation && connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation)) @@ -297,32 +303,42 @@ namespace Subsurface foreach (Vector2[] segment in connection.CrackSegments) { - Vector2 start = segment[0] * scale + rectCorner; - Vector2 end = segment[1] * scale + rectCorner; + Vector2 start = rectCenter + (segment[0] + offset) * scale; + Vector2 end = rectCenter + (segment[1] + offset) * scale; + + if (!rect.Contains(start) || !rect.Contains(end)) continue; + float dist = Vector2.Distance(start, end); - //spriteBatch.Draw(iceCrack, - // new Rectangle((int)((start.X + end.X) / 2.0f), (int)((start.Y + end.Y) / 2.0f), (int)dist, 30), - // new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(start - end), - // new Vector2(dist / 2, 30), SpriteEffects.None, 0.01f); - GUI.DrawLine(spriteBatch, - segment[0] * scale + rectCorner, - segment[1] * scale + rectCorner, crackColor); + spriteBatch.Draw(iceCrack, + new Rectangle((int)start.X, (int)start.Y, (int)dist+2, 30), + new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(end -start), + new Vector2(0, 30), SpriteEffects.None, 0.01f); } } for (int i = 0; i < locations.Count; i++) { Location location = locations[i]; - Vector2 pos = rectCorner + location.MapPosition * scale; + Vector2 pos = rectCenter + (location.MapPosition + offset) * scale; + + if (!rect.Contains(pos)) continue; - int imgIndex = i % 16; - int xCell = imgIndex % 4; - int yCell = (int)Math.Floor(imgIndex / 4.0f); - spriteBatch.Draw(iceCraters, pos, - new Rectangle(xCell * 64, yCell * 64, 64, 64), - Color.White, i, - new Vector2(32, 32), 0.5f*scale, SpriteEffects.None, 0.0f); + Color color = location.Connections.Find(c => c.Locations.Contains(currentLocation))==null ? Color.White : Color.Green; + + color *= (location.Discovered) ? 0.8f : 0.4f; + + if (location == currentLocation) color = Color.Orange; + + location.Type.Sprite.Draw(spriteBatch, pos, color); + + //int imgIndex = i % 16; + //int xCell = imgIndex % 4; + //int yCell = (int)Math.Floor(imgIndex / 4.0f); + //spriteBatch.Draw(iceCraters, pos, + // new Rectangle(xCell * 64, yCell * 64, 64, 64), + // Color.White, i, + // new Vector2(32, 32), 0.5f*scale, SpriteEffects.None, 0.0f); } @@ -333,14 +349,13 @@ namespace Subsurface if (location == null) continue; - Vector2 pos = rectCorner + location.MapPosition * scale; + Vector2 pos = rectCenter + (location.MapPosition + offset) * scale; pos.X = (int)pos.X; pos.Y = (int)pos.Y; - if (highlightedLocation==location) + if (highlightedLocation == location) { - spriteBatch.DrawString(GUI.Font, location.Name, pos + new Vector2(-50, -20), Color.DarkRed); + spriteBatch.DrawString(GUI.Font, location.Name, pos + new Vector2(0, 50), Color.DarkRed, 0.0f, GUI.Font.MeasureString(location.Name)/2.0f, 1.0f, SpriteEffects.None, 0.0f); } - GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 4, (int)pos.Y - 4, 5 + 8, 5 + 8), Color.DarkRed, false); } } diff --git a/Subsurface/Map/MapEntityPrefab.cs b/Subsurface/Map/MapEntityPrefab.cs index 08e1f8492..3d219c051 100644 --- a/Subsurface/Map/MapEntityPrefab.cs +++ b/Subsurface/Map/MapEntityPrefab.cs @@ -29,6 +29,8 @@ namespace Subsurface //which prefab has been selected for placing protected static MapEntityPrefab selected; + protected int price; + public string Name { get { return name; } @@ -54,6 +56,11 @@ namespace Subsurface get { return resizeVertical; } } + public int Price + { + get { return price; } + } + public static void Init() { MapEntityPrefab ep = new MapEntityPrefab(); diff --git a/Subsurface/Map/WayPoint.cs b/Subsurface/Map/WayPoint.cs index bbf47189a..07f98d4b1 100644 --- a/Subsurface/Map/WayPoint.cs +++ b/Subsurface/Map/WayPoint.cs @@ -10,7 +10,7 @@ using System.Collections.ObjectModel; namespace Subsurface { - public enum SpawnType { None, Human, Enemy }; + public enum SpawnType { None, Human, Enemy, Cargo }; class WayPoint : MapEntity { public static List WayPointList = new List(); @@ -52,6 +52,7 @@ namespace Subsurface WayPointList.Add(this); } + public override void Draw(SpriteBatch spriteBatch, bool editing) { if (!editing && !Game1.DebugDraw) return; @@ -59,7 +60,7 @@ namespace Subsurface Point pos = new Point((int)Position.X, (int)Position.Y); Color clr = (isSelected) ? Color.Red : Color.LightGreen; - GUI.DrawRectangle(spriteBatch, new Rectangle(pos.X, -pos.Y, rect.Width, rect.Height), clr, true); + GUI.DrawRectangle(spriteBatch, new Rectangle(pos.X - rect.Width / 2, -pos.Y - rect.Height / 2, rect.Width, rect.Height), clr, true); foreach (MapEntity e in linkedTo) { @@ -102,7 +103,7 @@ namespace Subsurface spawnType += (int)button.UserData; - if (spawnType > SpawnType.Enemy) spawnType = SpawnType.None; + if (spawnType > SpawnType.Cargo) spawnType = SpawnType.None; if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy; spawnTypeText.Text = spawnType.ToString(); diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index 718139b60..ac21a7463 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -284,8 +284,12 @@ namespace Subsurface.Networking } NetworkEvent.events.Clear(); - - CheckServerMessages(); + + try + { + CheckServerMessages(); + } + catch { } // Update current time updateTimer = DateTime.Now + updateInterval; diff --git a/Subsurface/Networking/GameServer.cs b/Subsurface/Networking/GameServer.cs index 27be70d06..94d7b484b 100644 --- a/Subsurface/Networking/GameServer.cs +++ b/Subsurface/Networking/GameServer.cs @@ -56,10 +56,10 @@ namespace Subsurface.Networking public override void Update() { - if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.K)) - { - SendRandomData(); - } + //if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.K)) + //{ + // SendRandomData(); + //} if (gameStarted) inGameHUD.Update((float)Physics.step); diff --git a/Subsurface/Properties/AssemblyInfo.cs b/Subsurface/Properties/AssemblyInfo.cs index f3d07924d..5a7e7370c 100644 --- a/Subsurface/Properties/AssemblyInfo.cs +++ b/Subsurface/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyCopyright("Copyright © Undertow Games 2014")] +[assembly: AssemblyCopyright("Copyright © Undertow Games 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // 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("0.0.1.0")] -[assembly: AssemblyFileVersion("0.0.1.0")] +[assembly: AssemblyVersion("0.0.1.3")] +[assembly: AssemblyFileVersion("0.0.1.3")] diff --git a/Subsurface/Screens/GameScreen.cs b/Subsurface/Screens/GameScreen.cs index 5783725bf..a17b4a0ab 100644 --- a/Subsurface/Screens/GameScreen.cs +++ b/Subsurface/Screens/GameScreen.cs @@ -147,13 +147,7 @@ namespace Subsurface public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch) { - - System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - Game1.LightManager.DrawLightmap(graphics, spriteBatch, cam); - sw.Stop(); - System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds+" - "+sw.ElapsedTicks); //---------------------------------------------------------------------------------------- //1. draw the background, characters and the parts of the submarine that are behind them @@ -278,6 +272,8 @@ namespace Subsurface Submarine.DrawFront(spriteBatch); + foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch); + if (Game1.GameSession != null && Game1.GameSession.Level != null) { Game1.GameSession.Level.Draw(spriteBatch); diff --git a/Subsurface/Screens/LobbyScreen.cs b/Subsurface/Screens/LobbyScreen.cs index a78d00011..07cdfb0bc 100644 --- a/Subsurface/Screens/LobbyScreen.cs +++ b/Subsurface/Screens/LobbyScreen.cs @@ -9,7 +9,7 @@ namespace Subsurface { class LobbyScreen : Screen { - enum PanelTab { Crew = 0, Map = 1, CurrentLocation = 2 } + enum PanelTab { Crew = 0, Map = 1, CurrentLocation = 2, Store = 3 } GUIFrame leftPanel; GUIFrame[] rightPanel; @@ -21,12 +21,36 @@ namespace Subsurface GUIListBox characterList; GUIListBox hireList; + GUIListBox selectedItemList; + SinglePlayerMode gameMode; GUIFrame previewFrame; + GUIButton buyButton; + Level selectedLevel; + private string SelectedItemCost() + { + return selectedItemCost.ToString(); + } + + private int selectedItemCost + { + get + { + int cost = 0; + foreach (GUIComponent child in selectedItemList.children) + { + MapEntityPrefab ep = child.UserData as MapEntityPrefab; + if (ep == null) continue; + cost += ep.Price; + } + return cost; + } + } + public LobbyScreen() { Rectangle panelRect = new Rectangle( @@ -44,17 +68,21 @@ namespace Subsurface "", Color.Transparent, Color.White, Alignment.Left, GUI.style, leftPanel); moneyText.TextGetter = GetMoney; - GUIButton button = new GUIButton(new Rectangle(0, 60, 100, 30), "Map", null, Alignment.Left, GUI.style, leftPanel); + GUIButton button = new GUIButton(new Rectangle(0, 70, 100, 30), "Map", null, Alignment.Left, GUI.style, leftPanel); button.UserData = PanelTab.Map; button.OnClicked = SelectRightPanel; - button = new GUIButton(new Rectangle(0, 100, 100, 30), "Crew", null, Alignment.Left, GUI.style, leftPanel); + button = new GUIButton(new Rectangle(0, 110, 100, 30), "Crew", null, Alignment.Left, GUI.style, leftPanel); button.UserData = PanelTab.Crew; button.OnClicked = SelectRightPanel; - button = new GUIButton(new Rectangle(0, 140, 100, 30), "Location", null, Alignment.Left, GUI.style, leftPanel); + button = new GUIButton(new Rectangle(0, 150, 100, 30), "Hire", null, Alignment.Left, GUI.style, leftPanel); button.UserData = PanelTab.CurrentLocation; button.OnClicked = SelectRightPanel; + + button = new GUIButton(new Rectangle(0, 190, 100, 30), "Store", null, Alignment.Left, GUI.style, leftPanel); + button.UserData = PanelTab.Store; + button.OnClicked = SelectRightPanel; //--------------------------------------------------------------- //--------------------------------------------------------------- @@ -65,7 +93,7 @@ namespace Subsurface Game1.GraphicsWidth - panelRect.Width - 120, Game1.GraphicsHeight - 80); - rightPanel = new GUIFrame[3]; + rightPanel = new GUIFrame[4]; rightPanel[(int)PanelTab.Crew] = new GUIFrame(panelRect, GUI.style); //rightPanel[(int)PanelTab.Crew].Padding = GUI.style.smallPadding; @@ -88,14 +116,28 @@ namespace Subsurface //--------------------------------------- rightPanel[(int)PanelTab.CurrentLocation] = new GUIFrame(panelRect, GUI.style); - //rightPanel[(int)PanelTab.Hire].Padding = GUI.style.smallPadding; + //--------------------------------------- - //new GUITextBlock(new Rectangle(0, 0, 200, 25), "Location: ", Color.Transparent, Color.White, Alignment.Left, GUI.style, rightPanel[(int)PanelTab.CurrentLocation]); + rightPanel[(int)PanelTab.Store] = new GUIFrame(panelRect, GUI.style); + selectedItemList = new GUIListBox(new Rectangle(0, 0, 300, 400), Color.White * 0.7f, GUI.style, rightPanel[(int)PanelTab.Store]); - //hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), GUI.style, Alignment.Left, rightPanel[(int)PanelTab.CurrentLocation]); - //hireList.OnSelected = HireCharacter; + var costText = new GUITextBlock(new Rectangle(0, 0, 200, 25), "Cost: ", Color.Transparent, Color.White, Alignment.BottomLeft, GUI.style, rightPanel[(int)PanelTab.Store]); + costText.TextGetter = SelectedItemCost; + + buyButton = new GUIButton(new Rectangle(15, 0, 100, 25), "Buy", Alignment.Bottom, GUI.style, rightPanel[(int)PanelTab.Store]); + buyButton.OnClicked = BuyItems; + + GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 300, 400), Color.White * 0.7f, Alignment.TopRight, GUI.style, rightPanel[(int)PanelTab.Store]); + itemList.OnSelected = SelectItem; + + foreach (MapEntityPrefab ep in MapEntityPrefab.list) + { + if (ep.Price == 0) continue; + + CreateItemFrame(ep, itemList); + } } public override void Select() @@ -117,22 +159,17 @@ namespace Subsurface new GUITextBlock(new Rectangle(0, 0, 200, 25), "Location: "+location.Name, GUI.style, rightPanel[(int)PanelTab.CurrentLocation]); - new GUITextBlock(new Rectangle(0, 0, 200, 25), - "("+location.Type+")", GUI.style, rightPanel[(int)PanelTab.CurrentLocation]); + new GUITextBlock(new Rectangle(0, 20, 200, 25), + "("+location.Type.Name+")", GUI.style, rightPanel[(int)PanelTab.CurrentLocation]); if (location.HireManager != null) { - hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), GUI.style, Alignment.Left, rightPanel[(int)PanelTab.CurrentLocation]); - hireList.OnSelected = HireCharacter; + hireList = new GUIListBox(new Rectangle(0, 60, 300, 0), GUI.style, Alignment.Left, rightPanel[(int)PanelTab.CurrentLocation]); + hireList.OnSelected = SelectCharacter; hireList.ClearChildren(); foreach (CharacterInfo c in location.HireManager.availableCharacters) { - //GUIFrame frame = new GUIFrame( - // new Rectangle(0, 0, 0, 25), Color.Transparent, null, hireList); - //frame.UserData = c; - //frame.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f); - GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), c.Name + " (" + c.Job.Name + ")", GUI.style, hireList); @@ -151,59 +188,8 @@ namespace Subsurface public override void Deselect() { base.Deselect(); - - //if (previewPlatform != null) - //{ - // Game1.World.RemoveBody(previewPlatform); - // previewPlatform = null; - //} - - //if (previewHull != null) - //{ - // previewHull.Remove(); - // previewHull = null; - //} - - //if (previewCharacter != null) - //{ - // previewCharacter.Remove(); - // previewCharacter = null; - //} } - //private void CreatePreviewCharacter() - //{ - // if (previewCharacter != null) previewCharacter.Remove(); - - // Vector2 pos = new Vector2(1000.0f, 1000.0f); - - // previewCharacter = new Character(characterList.SelectedData as CharacterInfo, pos); - - // previewCharacter.AnimController.IsStanding = true; - - // if (previewPlatform == null) - // { - // Body platform = BodyFactory.CreateRectangle(Game1.World, 3.0f, 1.0f, 5.0f); - // platform.SetTransform(new Vector2(pos.X, pos.Y - 3.5f), 0.0f); - // platform.IsStatic = true; - // } - - // if (previewHull == null) - // { - // pos = ConvertUnits.ToDisplayUnits(pos); - // previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 500)); - // } - - // Physics.Alpha = 1.0f; - - // for (int i = 0; i < 500; i++) - // { - // previewCharacter.AnimController.Update((float)Physics.step); - // previewCharacter.AnimController.UpdateAnim((float)Physics.step); - // Game1.World.Step((float)Physics.step); - // } - //} - public void SelectLocation(Location location, LocationConnection connection) { GUIComponent locationPanel = rightPanel[(int)PanelTab.Map].GetChild("selectedlocation"); @@ -227,14 +213,82 @@ namespace Subsurface { GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), - c.Name + " ("+c.Job.Name+")", GUI.style, + c.Name + " (" + c.Job.Name + ")", GUI.style, Alignment.Left, Alignment.Left, characterList); textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); textBlock.UserData = c; } + } + private void CreateItemFrame(MapEntityPrefab ep, GUIListBox listBox) + { + Color color = ((listBox.CountChildren % 2) == 0) ? Color.Transparent : Color.White * 0.1f; + + GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, null, listBox); + frame.UserData = ep; + frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); + frame.Color = color; + frame.HoverColor = Color.Gold * 0.2f; + frame.SelectedColor = Color.Gold * 0.5f; + + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(40, 0, 0, 25), + ep.Name, + Color.Transparent, Color.White, + Alignment.Left, Alignment.Left, + null, frame); + textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + + textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + ep.Price.ToString(), + null, null, + Alignment.TopRight, GUI.style, textBlock); + + if (ep.sprite != null) + { + GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.Left, frame); + img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); + } + } + + private bool SelectItem(object obj) + { + MapEntityPrefab prefab = obj as MapEntityPrefab; + + if (prefab == null) return false; + + CreateItemFrame(prefab, selectedItemList); + + buyButton.Enabled = gameMode.crewManager.Money >= selectedItemCost; + + return false; + } + + private bool BuyItems(GUIButton button, object obj) + { + int cost = selectedItemCost; + + if (gameMode.crewManager.Money < cost) return false; + + gameMode.crewManager.Money -= cost; + + for (int i = selectedItemList.children.Count-1; i>=0; i--) + { + GUIComponent child = selectedItemList.children[i]; + + MapEntityPrefab ep = child.UserData as MapEntityPrefab; + if (ep == null) continue; + + gameMode.CargoManager.AddItem(ep); + + selectedItemList.RemoveChild(child); + } + + + return false; } public override void Update(double deltaTime) @@ -267,9 +321,10 @@ namespace Subsurface if (selectedRightPanel == (int)PanelTab.Map) { Game1.GameSession.Map.Draw(spriteBatch, new Rectangle( - rightPanel[selectedRightPanel].Rect.Right - 20 - 400, - rightPanel[selectedRightPanel].Rect.Y + 20, - 400, 400)); + rightPanel[selectedRightPanel].Rect.X + 20, + rightPanel[selectedRightPanel].Rect.Y + 20, + rightPanel[selectedRightPanel].Rect.Width - 40, + rightPanel[selectedRightPanel].Rect.Height - 150), 3.0f); } if (rightPanel[(int)selectedRightPanel].UserData as Location != Game1.GameSession.Map.CurrentLocation) @@ -281,37 +336,6 @@ namespace Subsurface spriteBatch.End(); - if (characterList.SelectedData != null && selectedRightPanel == (int)PanelTab.Crew) - { - if (previewFrame==null || previewFrame.UserData != characterList.UserData) - { - CharacterInfo previewCharacter = (characterList.SelectedData as CharacterInfo); - - GUIFrame frameRoot = new GUIFrame(new Rectangle(350, 30, 300, 500), - new Color(0.0f, 0.0f, 0.0f, 0.8f), - Alignment.Top, GUI.style, rightPanel[selectedRightPanel]); - frameRoot.Padding = new Vector4(20.0f,20.0f,20.0f,20.0f); - - previewFrame = previewCharacter.CreateInfoFrame(frameRoot); - previewFrame.UserData = previewCharacter; - } - //if (previewCharacter != null) - //{ - // Vector2 position = new Vector2(characterList.Rect.Right + 100, characterList.Rect.Y + 25.0f); - - // Vector2 pos = previewCharacter.Position; - // pos.Y = -pos.Y; - // Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f)); - - // spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform); - // previewCharacter.Draw(spriteBatch); - // spriteBatch.End(); - //} - //else - //{ - // CreatePreviewCharacter(); - //} - } } public bool SelectRightPanel(GUIButton button, object selection) @@ -320,42 +344,7 @@ namespace Subsurface catch { return false; } return true; } - - //private void CreatePreviewCharacter() - //{ - // if (Game1.Client.Character != null) Game1.Client.Character.Remove(); - - // Vector2 pos = new Vector2(1000.0f, 1000.0f); - - // Character character = new Character(Game1.Client.CharacterInfo, pos); - - // Game1.Client.Character = character; - - // character.animController.isStanding = true; - - // if (previewPlatform == null) - // { - // Body platform = BodyFactory.CreateRectangle(Game1.world, 3.0f, 1.0f, 5.0f); - // platform.SetTransform(new Vector2(pos.X, pos.Y - 2.5f), 0.0f); - // platform.IsStatic = true; - // } - - // if (previewPlatform == null) - // { - // pos = ConvertUnits.ToDisplayUnits(pos); - // new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200)); - // } - - // Physics.Alpha = 1.0f; - - // for (int i = 0; i < 500; i++) - // { - // character.animController.Update((float)Physics.step); - // character.animController.UpdateAnim((float)Physics.step); - // Game1.world.Step((float)Physics.step); - // } - //} - + private string GetMoney() { return "Money: " + ((Game1.GameSession == null) ? "" : gameMode.crewManager.Money.ToString()); @@ -368,17 +357,38 @@ namespace Subsurface if (Character.Controlled != null && characterInfo == Character.Controlled.Info) return false; - //CreatePreviewCharacter(); + if (previewFrame == null || previewFrame.UserData != characterInfo) + { + previewFrame = new GUIFrame(new Rectangle(350, 60, 300, 300), + new Color(0.0f, 0.0f, 0.0f, 0.8f), + Alignment.Top, GUI.style, rightPanel[selectedRightPanel]); + previewFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); + previewFrame.UserData = characterInfo; + + characterInfo.CreateInfoFrame(previewFrame); + } + + if (selectedRightPanel == (int)PanelTab.CurrentLocation) + { + GUIButton hireButton = new GUIButton(new Rectangle(0,0, 100, 20), "Hire", Alignment.BottomCenter, GUI.style, previewFrame); + hireButton.UserData = characterInfo; + hireButton.OnClicked = HireCharacter; + } return false; } - private bool HireCharacter(object selection) + private bool HireCharacter(GUIButton button, object selection) { CharacterInfo characterInfo = selection as CharacterInfo; if (characterInfo == null) return false; - gameMode.TryHireCharacter(Game1.GameSession.Map.CurrentLocation.HireManager, characterInfo); + if (gameMode.TryHireCharacter(Game1.GameSession.Map.CurrentLocation.HireManager, characterInfo)) + { + UpdateLocationTab(Game1.GameSession.Map.CurrentLocation); + } + + return false; } diff --git a/Subsurface/Screens/MainMenu.cs b/Subsurface/Screens/MainMenu.cs index d78b9bf53..c1fd544cc 100644 --- a/Subsurface/Screens/MainMenu.cs +++ b/Subsurface/Screens/MainMenu.cs @@ -43,6 +43,7 @@ namespace Subsurface button = new GUIButton(new Rectangle(0, 60, 0, 30), "Load Game", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]); button.UserData = (int)Tabs.LoadGame; button.OnClicked = SelectTab; + //button.Enabled = false; button = new GUIButton(new Rectangle(0, 120, 0, 30), "Join Server", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]); button.UserData = (int)Tabs.JoinServer; diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index ae6f44c0b..5fa1188b3 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -66,6 +66,7 @@ + @@ -410,6 +411,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -422,6 +429,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 9977e1e326cd3f26c0966c47bdaca8381c7203b1..a39d015d85f51f5b7754c9cbfa1c2f7de34bdc68 100644 GIT binary patch delta 22949 zcmeHv3tW{&`ad)8D5b=tDh~|a#*tX`nX2{X= zxat}r9n6dnidW4HFWt-xU9}s!Xsub9p=l)%{=ah$Aegmn+x~w4-+p@ee3{ETmuH@N zX6AY3ojJx!_ZVyL$&Cn1V|I2fc6N64w{G2nV~3!f(%{KNARWj6QUQNP^Za=mP2W%b z1Iy!Ss$o~~fL(8zviM`{y|NqJktt`9^#@aH`!?NQf)8a{pD_4S0Uy8{$OJTCBrx3+ zC3iGr!PgZS2RsQ31?Hj3&TvH$CZp`hgPCcQ?9+WS;-Y{@fH+_`Pz1~cQh*-7Kwy~Z zyxd{=c$DIW&^(|E;0uTn?}0lXP=U5U8sH2p0%DNI0CyHp2rLA;B5obrKEMcIGSCm0 z4Lk)r3`_?$0nY+6fSGo7rlm?No@i%UsrV#5DcRZGkLW=_DBuo60FMK6Q2amOE&+_d z6rdW|04xJkyk7x#5>N`X2lfN8h(8EdbVuYd*OuLpXK#O>wMRsQ8y?XwqO*Sh{%OD5 z^K{U;ws-546{glohe^K$`$bC|*l+g`n)?aR(b@$M{<~cuioR1s((X;XMZi17?Wh zCB&TqbO?t6L4b_#Qos`k1e_4}7F^MGFJ`ygZXyET0!M(SQAiXLJOlp~;C0|p;0a)^ zC=3XPzYUNF^hfw>xT3IaaPxsPKmt$(ya%iT{th@G?MUDS__Klaz-82L*BOx>z~2z@ z1|SMEAiNcR2G<=>fMW=I!~F}~cYrSNUx(`gbOXwPKLPIo9|9&|4e%N8DR3TWg*;E8 zksE+^2!AEmvyoov%{q5|9^M?_&%iz)3~BEHD&Z%j_k_PEqh%kkuH@I98SG0DQ3lY# z6xP<1q-&#Pzt7gNJbmQ?1)}zlpQhK{ARKvgmN2@5B%G*BcVI~ zf0P|((AATf>bdWBgF81FcFI(k#^SZ?VQd#GGk8|F&->J`%x`iPGZ`QDGx=Tflf_!z zBw42HYoknu-GfcnuO-N06>s+D>ouiezH*tb$2nFIA?Jl;v(u&pE~D&&!O$R}DJlD# z>4wW#S*(>!ai(lnqiV*aHP6vhd$EVfQsGrLaL@%uGK^uJTiMMABiSf#y~ z3&a}NEP5;hf&L*5+_rR!I#x`UN0r6JmpWVaa9)~Z;F=+tRkPA*hOU|+QTWyv}OQEL5Zc3DUv-!?ok}dCht0=kYOw9OovCa5L&R6y-U$sSrBDE%@X82&52aD zgCCES-7M3ozrJJ2YF}3E^UC~8men9Hx12eiL5JC+9#PeKi!^}J52|X}pw|y{H!tUY znqNGtVH5Y5`DSyTnX>;9Z~rD@7@F5qwz?T)#jvv4TdFLoDD(U7Y1Yc_DC&Q^ zISmenkxR@g&>QO&=I5pPdhxDIezAEX%I?6|s0I!j_KmJZJ5 zL##a1&(7<3wk9R@wM!kYBufL`9+39ut=6y;j8(E zvU8Fpn{i7xbD$LySv%VLyyUL+EM#Uz2m7lL@+`X<=^|Go<^EN2Fjf4)Ps

cH26s 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 delta 22198 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 -@~ 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 Q4gXVwW=O>8ihb?)Pk^+k(*OVf