From cda87c3f065355d4f4635c4b8c7b6d9b45d413db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Tue, 12 Dec 2017 23:17:25 +0100 Subject: [PATCH] story: Fixed initial contact ship being without equipment --- TODO.md | 1 - graphics/exported/character/random-off.png | Bin 0 -> 3963 bytes graphics/exported/character/random-on.png | Bin 0 -> 4383 bytes graphics/exported/character/rename-off.png | Bin 0 -> 1173 bytes graphics/exported/character/rename-on.png | Bin 0 -> 1783 bytes graphics/exported/character/validate.png | Bin 0 -> 4400 bytes graphics/ui/character.svg | 302 ++++++++++++++++++++- src/core/Equipment.ts | 2 +- src/core/Fleet.ts | 2 +- src/core/Ship.spec.ts | 18 +- src/core/Ship.ts | 14 +- src/core/ShipGenerator.spec.ts | 2 +- src/core/ShipGenerator.ts | 2 +- src/core/missions/MainStory.spec.ts | 2 + src/core/missions/MainStory.ts | 3 +- src/core/missions/MissionGenerator.ts | 33 ++- src/ui/battle/ShipTooltip.spec.ts | 2 +- src/ui/battle/ShipTooltip.ts | 2 +- src/ui/character/CharacterFleetMember.ts | 2 +- src/ui/character/CharacterSheet.spec.ts | 8 +- src/ui/character/CharacterSheet.ts | 2 +- src/ui/character/FleetCreationView.ts | 4 +- src/ui/common/UIConversation.ts | 2 +- 23 files changed, 354 insertions(+), 49 deletions(-) create mode 100644 graphics/exported/character/random-off.png create mode 100644 graphics/exported/character/random-on.png create mode 100644 graphics/exported/character/rename-off.png create mode 100644 graphics/exported/character/rename-on.png create mode 100644 graphics/exported/character/validate.png diff --git a/TODO.md b/TODO.md index 68f2060..d20da42 100644 --- a/TODO.md +++ b/TODO.md @@ -12,7 +12,6 @@ Menu/settings/saves Map/story --------- -* Initial contact has no equipment, and dies immediately in the first fight * Add sound effects and more visual effects (jumps...) * Add factions and reputation * Allow to cancel secondary missions diff --git a/graphics/exported/character/random-off.png b/graphics/exported/character/random-off.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf37135c50c573c2468c902547e7093085c0ea7 GIT binary patch literal 3963 zcmV->4}|cEP)rv-Bz!kVTN#<o!88Ilzi7lBTDGL-W&WtIF^Xaa7_ueetr>eTE zXNKe`Pzr2xPfbsEojUh>?j>Qu@y9Q|_^`A3hYI=}fF}SLe6$Zy;5AabOospQTVGwf z()A`9J@IF2YfIE~FDmqp02GIMNvip4iPEWfj_5GIsRZy3Q>J*~8(;a#?TLV&yRh~N z75g#>zj0UqX#|KK;I6Cc;oJbi&tdTSzxnbDKOOt7=Ps9K*@zGJBO*Ru1#t@vdAXEEkN<|qs2pXA0_y<)3 zg+fFSPAdco7(hhEm`((=fbR)_e$N5=$$h;dvf2gIU`|3^k~4fC$K#d~*_TZKl16`JNtd6a9CD)h^R@b{wcP zbrg0nB3m*r*1(`}W~= zsA0M^2DET4uu35XxyZ03(;2uDaL>U^*+yUyv^54I5&y1sH9x30U*l8VhG_^xXigR}|o~#9(I^G}VW77D5I- z{!QHineWj#;2!k8!N(ajhUDZ*r zVOUcKngq@mLSY@O4eVNDQ8g>%NjGo$hqB;|VmD$=Uq_h2|CaTO@lELuab)}XL1 znreI)iy}VH&CO%`_96;*8BaZR0@m)|LNg0?cZb;6xQ6xhE4Y2@6Bz8SV&<?CcI8 z!VqI%t%da-o&vjt>!b7~2IVe9k@LNRU;uCvY$JWSQFcRk4`IHlDwKmEjIo%Tok71B zz!uh`aN%{&1%FM!YGGj+A}jD-u(ULNpn_&;X&NU_E?{e`#OtrWf!nt|Zr^fPTwX?5 zmME(V&H&^brl;pn`U->L4m<reexw#&mdg>JB=ikEiop%8d6waYn z6j)q1g8A8bKs`t~yHc_=6SGBjp9y8=m=9~q*%ZPI6#;t>VaCS#2e^6T9XK-e{S{RMvT{XQOCJ%eYS`7{=mKMfo6_T*YV{BCpe9lY_ze`de{u(&vd?d=c1%(?h5 zu}UMMY{EHR8UrE&Kw_Sj&Rpy|MK;Zj3`p>0VGd=V3dA!so>vhtGoXs9+{V=_uj8Fx z{1pBEG9G#4QGDhz=P)zVp9r|u>*3CwEewZ!lqI9rv)QzXf<>8l<4o+b>UyBA^qOuP zU=S4hFr3UF74zCG&JmtdAQRzi>O>*Eq!{46$JW+5E?(TgrAx13e*PHFo;{1FpZ-+r zn&Owc0{#9xoOAHrv`jFz+#^3nW)pje4NOc+l-1B6EOZsqt}6#q>O&jnggLimDw01e zw`tmbKgC+Q-=BhWB`#mSgv*!z2P-Ql@a(hC;MA#8U>=|>w=o!OgJ^(Wuf81b1tN7L zGI|&?APT*A3eF0x<)I1sm+O*HRbzwR=u^XulU%ALpqbq<1p}Cxnu3U6aj}PfzaLHS z7G8Vp6>M%k5Ls3@_cl(Qnr<<=wN*l-kD@5R%$Yqyl-W<$7|}M=4@?YP4xNRzwhEBC z_objb#J7sb1i7a6&*|xDoIk&dxw+p(s@(w=P=#Tvo;y3g(Rp3c2z@k z-djFu=f#7Ay@`#DIas@jrKP1>&iSY?ycgI5Pr*d7xw(TYS2nS=bsQp(;o*nRzFGc)ksj|uU$P_H=)YRb1^tkDRVlcmcKjp6-4Gai5ZiEOrs(WHuv+^6YI+^PH34dKe6t6*po1mZR&%u#^77s{#&q40rpahMatOsa0YnBAOGGks z-&Qa-N9wrX+@nh~L&Wko-2mvGof0OmG1Oy`y7)jnIcVhB!=B!EnR7PzWZFQKYc*@w zi0q2iEdzC2n`yU&>80kvoMO*ecOYZajj@z8I`F<1A8&${<`_oOBk0qd>iax&+k1}e zI)`N=Lo!tjlY`WX5rGUrC4jTef<3psDE(bomZ&PmE3aH@MQLeVXcy4r=LxjW06FN? zQNpc9GLp;Q+}$1|N~Zt-3MMOYavv-A*rHjeQK$*xH+$a+T12q3vx8S(UBS%E444^J zRiWRX$3qYGLLWT=Xd1FL!FuoEnZe8`y$45$CyDo|V@j`~7+axmV>P8p2u$&9Sy@Pv zdTYZ#OTz3|0N8lWIva!mk$PQ$fPUZSX2Lm#J+V zv@>Yu9k%#EA$@a@Cc6Rg<3zJO^Nv_o%#w7e>WCj%Fmk zPgJs%GzaI+pyN7MhX??fFq+9Rt*x1I##x1=6{xVLSJlP65qd*gD6$evJ?3Uicvk#!7NvB|z0~p55xduF<5QM;_ zFl3;{z*G#y5Ca@mR~NCmx`-eB=pF11s0Gk7#}reW zrx%829|voUiWybq^9`t?&gMC>D|?!Aw+}boM228A=)lHVs0tihnCr5M@8RI%YJ=b= z(GAD|)_^%&{PpYgLR?vLG}U05%p7OK3{{}w5XGzLzf}rWBW4|LRNIub@#xCKu4@G; z&4V?8h7HUXfSRaw5uqRxv}$W0EU?aH?JKV1V0&j9zkF{Fw{A&e8D$BTXO!g-Wvr#s z4G7|Td>zmEI41QRgH^-aS-4f4XlsI^djM`OkTvGSWDHmV>j=bvQeak@gJNk7G%1

tixMxPr*5tYu$x~qj>1_aSW@f1(=!Ze9O`R%B|q!Iiw+O1iU6#?6JS; z_TG;S`lWTzT;U+ZVelLyH$~to5+Zq&ZV~;{T8rJPgz-KoCIF`A1=F*$*cl80lL)I0 zoYRlAfaaj2l7WXH7bAPK#8BOHo2MfWH&jY!XcUsbO(8{*2?e~0M215i7G~HKaid8R z!a4)MVOAxIk}GWO?&iXuxsJ-*U^uNgggh*{md<-2@tK7mV=_HAQSSoh{C`&rWyot zgkeHfUp%a1TMYPcY)PB7-;Xe#Wzk2}PwUw?CkPH@BQHC&-~VBR{)&9%MrswKccSl)EsSM zY?HpZ)ukQM(>;SFeCykP@%6uNXx~Plc>cb;G;zNfAuse{WXBk;{V}6 zpzkrsm;d&wU;nR8YnpUCcVX=e#C~20PXahaz~V;{paQo6TnFgKp7p!w|0s1G{|jfQ VwZD8rh|&N6002ovPDHLkV1i-TTtEN- literal 0 HcmV?d00001 diff --git a/graphics/exported/character/random-on.png b/graphics/exported/character/random-on.png new file mode 100644 index 0000000000000000000000000000000000000000..643a80c02fce39ff8675e86da2170eda17ba9f76 GIT binary patch literal 4383 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 literal 0 HcmV?d00001 diff --git a/graphics/ui/character.svg b/graphics/ui/character.svg index ebed785..a0de0fc 100644 --- a/graphics/ui/character.svg +++ b/graphics/ui/character.svg @@ -24,6 +24,32 @@ inkscape:export-ydpi="96"> + + + + + + @@ -586,6 +612,136 @@ y1="227.4481" x2="106.11795" y2="227.4481" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml - + @@ -1788,4 +1944,140 @@ sodipodi:role="line">X + + + + + + + + + + + + ? + + + + + ... + + + + + OK + + diff --git a/src/core/Equipment.ts b/src/core/Equipment.ts index 0ae4b68..5d39a61 100644 --- a/src/core/Equipment.ts +++ b/src/core/Equipment.ts @@ -61,7 +61,7 @@ module TK.SpaceTac { } jasmineToString() { - return this.attached_to ? `${this.attached_to.ship.getFullName()} - ${this.name}` : this.name; + return this.attached_to ? `${this.attached_to.ship.getName()} - ${this.name}` : this.name; } /** diff --git a/src/core/Fleet.ts b/src/core/Fleet.ts index cfa9ae9..961b6c5 100644 --- a/src/core/Fleet.ts +++ b/src/core/Fleet.ts @@ -26,7 +26,7 @@ module TK.SpaceTac { } jasmineToString(): string { - return `${this.player.name}'s fleet [${this.ships.map(ship => ship.getFullName()).join(",")}]`; + return `${this.player.name}'s fleet [${this.ships.map(ship => ship.getName()).join(",")}]`; } /** diff --git a/src/core/Ship.spec.ts b/src/core/Ship.spec.ts index 3d78524..737b27c 100644 --- a/src/core/Ship.spec.ts +++ b/src/core/Ship.spec.ts @@ -2,16 +2,20 @@ module TK.SpaceTac.Specs { testing("Ship", test => { test.case("creates a full name", check => { let ship = new Ship(); - check.equals(ship.getFullName(false), "Level 1 unnamed"); + check.equals(ship.getName(false), "Ship"); + check.equals(ship.getName(true), "Level 1 Ship"); - ship.name = "Titan"; - check.equals(ship.getFullName(false), "Level 1 Titan"); + ship.model = new ShipModel("test", "Hauler"); + check.equals(ship.getName(false), "Hauler"); + check.equals(ship.getName(true), "Level 1 Hauler"); + + ship.name = "Titan-W12"; + check.equals(ship.getName(false), "Titan-W12"); + check.equals(ship.getName(true), "Level 1 Titan-W12"); ship.level.forceLevel(3); - check.equals(ship.getFullName(false), "Level 3 Titan"); - - ship.fleet.player.name = "Emperor"; - check.equals(ship.getFullName(true), "Emperor's Level 3 Titan"); + check.equals(ship.getName(false), "Titan-W12"); + check.equals(ship.getName(true), "Level 3 Titan-W12"); }); test.case("moves in the arena", check => { diff --git a/src/core/Ship.ts b/src/core/Ship.ts index ac229eb..696565e 100644 --- a/src/core/Ship.ts +++ b/src/core/Ship.ts @@ -12,8 +12,8 @@ module TK.SpaceTac { level = new ShipLevel() skills = new ShipSkills() - // Name of the ship - name: string + // Name of the ship, null if unimportant + name: string | null // Code of the ShipModel used to create it model: ShipModel @@ -57,7 +57,7 @@ module TK.SpaceTac { play_priority = 0; // Create a new ship inside a fleet - constructor(fleet: Fleet | null = null, name = "unnamed", model = new ShipModel("default", "Default", 1, 0, false, 0)) { + constructor(fleet: Fleet | null = null, name: string | null = null, model = new ShipModel("default", "Ship", 1, 0, false, 0)) { super(); this.fleet = fleet || new Fleet(); @@ -84,11 +84,11 @@ module TK.SpaceTac { } /** - * Returns the full name of this ship + * Returns the name of this ship */ - getFullName(owner = true): string { - let result = `Level ${this.level.get()} ${this.name}`; - return owner ? `${this.fleet.player.name}'s ${result}` : result; + getName(level = true): string { + let name = this.name || this.model.name; + return level ? `Level ${this.level.get()} ${name}` : name; } // Returns true if the ship is able to play diff --git a/src/core/ShipGenerator.spec.ts b/src/core/ShipGenerator.spec.ts index 1235342..a67fa63 100644 --- a/src/core/ShipGenerator.spec.ts +++ b/src/core/ShipGenerator.spec.ts @@ -3,7 +3,7 @@ module TK.SpaceTac.Specs { test.case("can use ship model", check => { var gen = new ShipGenerator(); var model = new ShipModel("test", "Test", 1, 2, true, 3); - var ship = gen.generate(1, model); + var ship = gen.generate(1, model, false); check.same(ship.model, model); check.equals(ship.cargo_space, 2); check.equals(ship.slots.length, 7); diff --git a/src/core/ShipGenerator.ts b/src/core/ShipGenerator.ts index 9ddd230..83d5ab9 100644 --- a/src/core/ShipGenerator.ts +++ b/src/core/ShipGenerator.ts @@ -17,7 +17,7 @@ module TK.SpaceTac { * * If *force_damage_equipment, at least one "damaging" weapon will be chosen */ - generate(level: number, model: ShipModel | null = null, upgrade = false, force_damage_equipment = true): Ship { + generate(level: number, model: ShipModel | null = null, upgrade = true, force_damage_equipment = true): Ship { if (!model) { // Get a random model model = ShipModel.getRandomModel(level, this.random); diff --git a/src/core/missions/MainStory.spec.ts b/src/core/missions/MainStory.spec.ts index 748c946..f753f9a 100644 --- a/src/core/missions/MainStory.spec.ts +++ b/src/core/missions/MainStory.spec.ts @@ -43,6 +43,8 @@ module TK.SpaceTac.Specs { checkPart(story, 3, /^Go with .* in .* system$/); check.same(fleet.ships.length, fleet_size + 1); + check.same(fleet.ships[fleet_size].critical, true); + check.greater(fleet.ships[fleet_size].getAttribute("hull_capacity"), 0); goTo(fleet, (story.current_part).destination); checkPart(story, 4, /^Listen to .*$/); diff --git a/src/core/missions/MainStory.ts b/src/core/missions/MainStory.ts index 0149a4d..5971c75 100644 --- a/src/core/missions/MainStory.ts +++ b/src/core/missions/MainStory.ts @@ -15,6 +15,7 @@ module TK.SpaceTac { let random = RandomGenerator.global; let start_location = nn(fleet.location); + let mission_generator = new MissionGenerator(universe, start_location); // Arrival let conversation = this.addPart(new MissionPartConversation(this, [], "Travel to Terranax galaxy")); @@ -24,7 +25,7 @@ module TK.SpaceTac { // Get in touch with our contact let contact_location = randomLocation(random, [start_location.star], [start_location]); - let contact_character = new Ship(null, "Osten-37", ShipModel.getRandomModel(1, random)); + let contact_character = mission_generator.generateShip(1); contact_character.fleet.setLocation(contact_location, true); this.addPart(new MissionPartGoTo(this, contact_location, `Find your contact in ${contact_location.star.name}`, MissionPartDestinationHint.SYSTEM)); conversation = this.addPart(new MissionPartConversation(this, [contact_character], "Speak with your contact")); diff --git a/src/core/missions/MissionGenerator.ts b/src/core/missions/MissionGenerator.ts index cfc4b00..fe123ab 100644 --- a/src/core/missions/MissionGenerator.ts +++ b/src/core/missions/MissionGenerator.ts @@ -1,17 +1,17 @@ module TK.SpaceTac { const POOL_SHIP_NAMES = [ - "Zert", - "Ob'tec", - "Paayk", - "Fen_amr", - "TempZst", - "croNt", - "Appn", - "Vertix", - "Opan-vel", - "Yz-aol", - "Arkant", - "PNX", + "Zert", "Zark", "Zeem", + "Ob'tec", "Ob'vac", "Ob'sig", + "Paayk", "Paakt", + "Fen_amr", "Fin_am", "Fen_AA", + "TempZst", "TriZth", + "croNt", "coRzt", + "Appn", "Appq", + "Vertix", "Vortix", + "Opan-vel", "Ipal-ven", "Epan-vek", + "Yz-aol", "Yz-aib", + "Arkant", "Arkyan", + "PNX", "PGV", "PXT", "PRZ", ] /** @@ -47,13 +47,20 @@ module TK.SpaceTac { return result; } + /** + * Generate a character name + */ + static generateCharacterName(random = RandomGenerator.global): string { + return `${random.choice(POOL_SHIP_NAMES)}-${random.randInt(10, 999)}`; + } + /** * Generate a new ship that may be used in a mission */ generateShip(level: number) { let generator = new ShipGenerator(this.random); let result = generator.generate(level, null, true); - result.name = `${this.random.choice(POOL_SHIP_NAMES)}-${this.random.randInt(10, 999)}`; + result.name = MissionGenerator.generateCharacterName(this.random); return result; } diff --git a/src/ui/battle/ShipTooltip.spec.ts b/src/ui/battle/ShipTooltip.spec.ts index a7b60a5..e9ff635 100644 --- a/src/ui/battle/ShipTooltip.spec.ts +++ b/src/ui/battle/ShipTooltip.spec.ts @@ -27,7 +27,7 @@ module TK.SpaceTac.UI.Specs { check.contains(images, "ship-fake-portrait"); check.contains(images, "equipment-equipment"); check.equals(texts, [ - "Phil's Level 1 Fury", "Plays in 2 turns", + "Level 1 Fury", "Plays in 2 turns", "7", "3", "9", "max", "12", "57", "max", "58", "100", "max", "140", "Active effects", "• hull capacity +50", "• damage -15% for 3 turns", "• limit precision to 10", "Weapons", "equipment Mk1" diff --git a/src/ui/battle/ShipTooltip.ts b/src/ui/battle/ShipTooltip.ts index 0373961..0514576 100644 --- a/src/ui/battle/ShipTooltip.ts +++ b/src/ui/battle/ShipTooltip.ts @@ -31,7 +31,7 @@ module TK.SpaceTac.UI { }); let enemy = !ship.getPlayer().is(this.battleview.player); - builder.text(ship.getFullName(), 168, 0, { color: enemy ? "#cc0d00" : "#ffffff", size: 22, bold: true }); + builder.text(ship.getName(), 168, 0, { color: enemy ? "#cc0d00" : "#ffffff", size: 22, bold: true }); if (ship.alive) { let turns = this.battleview.battle.getPlayOrder(ship); diff --git a/src/ui/character/CharacterFleetMember.ts b/src/ui/character/CharacterFleetMember.ts index 1643ff2..ee32497 100644 --- a/src/ui/character/CharacterFleetMember.ts +++ b/src/ui/character/CharacterFleetMember.ts @@ -26,7 +26,7 @@ module TK.SpaceTac.UI { this.levelup.visible = this.ship.getAvailableUpgradePoints() > 0; this.addChild(this.levelup); - sheet.view.tooltip.bindDynamicText(this, () => ship.getFullName()); + sheet.view.tooltip.bindDynamicText(this, () => ship.getName()); } /** diff --git a/src/ui/character/CharacterSheet.spec.ts b/src/ui/character/CharacterSheet.spec.ts index 48c68ba..9cf3044 100644 --- a/src/ui/character/CharacterSheet.spec.ts +++ b/src/ui/character/CharacterSheet.spec.ts @@ -28,14 +28,14 @@ module TK.SpaceTac.UI.Specs { check.equals(sheet.x, 0); check.equals(sheet.portraits.length, 2); - check.equals(sheet.ship_name.text, "Player's Level 1 Ship 1"); + check.equals(sheet.ship_name.text, "Ship 1"); check.equals(sheet.ship_slots.length, 4); check.equals(sheet.ship_cargo.length, 3); let portrait = sheet.portraits.getChildAt(1); portrait.onInputUp.dispatch(); - check.equals(sheet.ship_name.text, "Player's Level 1 Ship 2"); + check.equals(sheet.ship_name.text, "Ship 2"); check.equals(sheet.ship_slots.length, 1); check.equals(sheet.ship_cargo.length, 2); }); @@ -126,7 +126,7 @@ module TK.SpaceTac.UI.Specs { ship.critical = true; sheet.show(ship); check.equals(sheet.isInteractive(), false, "critical ship"); - + ship.critical = false; sheet.show(ship); check.equals(sheet.isInteractive(), true, "normal ship"); @@ -139,7 +139,7 @@ module TK.SpaceTac.UI.Specs { sheet.show(ship, undefined, undefined, true); check.equals(sheet.isInteractive(), true, "interactivity reenabled"); - }); + }); }); test.case("fits slots in area", check => { diff --git a/src/ui/character/CharacterSheet.ts b/src/ui/character/CharacterSheet.ts index a9353a9..68339d2 100644 --- a/src/ui/character/CharacterSheet.ts +++ b/src/ui/character/CharacterSheet.ts @@ -216,7 +216,7 @@ module TK.SpaceTac.UI { let upgrade_points = ship.getAvailableUpgradePoints(); - this.ship_name.setText(ship.getFullName()); + this.ship_name.setText(ship.getName(false)); this.ship_level.setText(ship.level.get().toString()); this.ship_experience.setValue(ship.level.getExperience(), ship.level.getNextGoal()); this.ship_upgrade_points.setText(upgrade_points.toString()); diff --git a/src/ui/character/FleetCreationView.ts b/src/ui/character/FleetCreationView.ts index e1e9c34..6e96390 100644 --- a/src/ui/character/FleetCreationView.ts +++ b/src/ui/character/FleetCreationView.ts @@ -15,8 +15,8 @@ module TK.SpaceTac.UI { let models = ShipModel.getRandomModels(2); this.built_fleet = new Fleet(); - this.built_fleet.addShip(new Ship(null, "First", models[0])); - this.built_fleet.addShip(new Ship(null, "Second", models[1])); + this.built_fleet.addShip(new Ship(null, MissionGenerator.generateCharacterName(), models[0])); + this.built_fleet.addShip(new Ship(null, MissionGenerator.generateCharacterName(), models[1])); this.built_fleet.credits = this.built_fleet.ships.length * 1000; let basic_equipments = () => { diff --git a/src/ui/common/UIConversation.ts b/src/ui/common/UIConversation.ts index c2b6163..803ca62 100644 --- a/src/ui/common/UIConversation.ts +++ b/src/ui/common/UIConversation.ts @@ -136,7 +136,7 @@ module TK.SpaceTac.UI { setCurrentShipMessage(ship: Ship, content: string): void { let style = new UIConversationStyle(); style.image = `ship-${ship.model.code}-portrait`; - style.image_caption = ship.name; + style.image_caption = ship.getName(false); style.image_size = 256; let own = ship.getPlayer() == this.view.gameui.session.player;