From f4219dff4abfb89cf62d784a98a7e94b4b719d2f Mon Sep 17 00:00:00 2001 From: ManEatingBoar Date: Fri, 20 Nov 2020 12:12:39 +1100 Subject: [PATCH] **Codename Askellon** v0.0.37 Balance and Bugfix pass - Reduced most healing in the game > No more yakkity sax - Nano-Med cooldown from 30 to 50 - Nano-Med purchase cooldown from 50 to 120 - All Alien Forms base HP regeneration reduced from 3/s to 0.5/s - Instant Regeneration Gene power cooldown from 50 to 80 - Entering and Exiting ships gives you **Void Sickness** for 30 seconds > You cannot enter any ships while under the influence of **Void Sickness** - Reduced selling price of all items from 50% to 25% > People were rushing weapon damage upgrades by selling spawned items, it's still possible but not as lucrative Bug Fixes - Fixed evolving from bugging the game - Updated Minigun purchasing tooltip - Mining laser should no longer visually glitch - Mining laser should now correctly break once you've moved too far --- README.md | 1 + config.json | 2 +- maps/askellon-sector.w3x/war3map.w3a | Bin 71244 -> 71526 bytes maps/askellon-sector.w3x/war3map.w3h | Bin 2230 -> 2483 bytes maps/askellon-sector.w3x/war3map.w3i | Bin 1108 -> 1108 bytes maps/askellon-sector.w3x/war3map.w3q | Bin 22808 -> 23090 bytes maps/askellon-sector.w3x/war3map.w3t | Bin 7238 -> 7206 bytes maps/askellon-sector.w3x/war3map.w3u | Bin 19338 -> 19338 bytes maps/askellon-sector.w3x/war3map.wts | 82 ++++++--- project.log | 99 +++++++++++ src/app/abilities/station/scan-for-player.ts | 26 ++- src/app/buff/buffs/void-sickness.ts | 62 +++++++ src/app/buff/dynamic-buff-entity.ts | 2 + src/app/force/force-entity.ts | 4 +- src/app/force/forces/alien-force.ts | 164 +++++++++++------- src/app/force/forces/force-type.ts | 1 + src/app/force/forces/observer-force.ts | 14 +- src/app/force/player-state-entity.ts | 3 +- .../interactions/interactables/ships/ship.ts | 9 + src/app/research/research-factory.ts | 6 +- src/app/space/ships/perseus-type.ts | 5 + src/app/space/space-mining-entity.ts | 10 +- src/app/world/zone-id.ts | 1 + src/resources/ability-ids.ts | 1 + src/resources/buff-ids.ts | 6 +- src/resources/crewmember-names.ts | 21 ++- src/resources/upgrade-ids.ts | 3 +- src/resources/weapon-tooltips.ts | 5 - 28 files changed, 392 insertions(+), 135 deletions(-) create mode 100644 src/app/buff/buffs/void-sickness.ts diff --git a/README.md b/README.md index 7e2248b4..457c996f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ You'll need to have [node](https://nodejs.org/en/) and [git](https://git-scm.com - Thanks to Mayday for being a boss - Thanks to Maddeem for being a boss - Thanks to Piggy for the Askellon Icon +- Thanks to ScrewTheTrees for treelib And a special thanks to my awesome testers: - Zach diff --git a/config.json b/config.json index 6bda9ef5..422124e0 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,7 @@ "mapFolder": "askellon-sector.w3x", "gameExecutable": "E:\\Warcraft III\\_retail_\\x86_64\\Warcraft III.exe", "outputFolder": "C:\\Users\\Travis\\Documents\\Warcraft III\\Maps\\Askellon", - "version": "0.0.33", + "version": "0.0.37", "minifyScript": false, "launchArgs": [ "-launch", diff --git a/maps/askellon-sector.w3x/war3map.w3a b/maps/askellon-sector.w3x/war3map.w3a index a22aea28b4c0b711e42c21912314bf56ece6039f..8b2aec0a3e82b6f68946e0cc28cf159e6c3777d8 100644 GIT binary patch delta 79 zcmV-V0I>hetOVw+1dvbxZ?RFcw*xgaIFn(a9*;$MU(NQF_#(v0T}*`9l!tp delta 39 xcmV+?0NDTLt^~}i1dvbxZn06bw*xUWHIreX9l9vMouOM2vFF_$sY*-H9rIZ diff --git a/maps/askellon-sector.w3x/war3map.w3t b/maps/askellon-sector.w3x/war3map.w3t index 2079a54a30992803a9157460aa541010f2989af3..c6e392fa0bd2905c591357b8d2fb9c98e7e37f04 100644 GIT binary patch delta 52 zcmX?RvCLw_bpd8m6T`_51tm6r65wH(Jds^wvyiAdBS(6EPKu|2fhSlbRZNC)^F;Bj FECAk85b^*3 delta 81 zcmZ2xam-@Fbpd7rV~fcT1tm6r65wHBA8t&Jy3l0swW!6OI4? diff --git a/maps/askellon-sector.w3x/war3map.w3u b/maps/askellon-sector.w3x/war3map.w3u index 251a3e5c703237af5ecf25fde4098b33c4ac531e..b4f933d2a8ee81ed6b7e91069d5bd83d8dc2a526 100644 GIT binary patch delta 39 tcmeC0&e%1bal<=KCIA2^?j0qIFx>YEgwvH)3=KX96FmQ%}71ppV14I%&l delta 39 tcmeC0&e%1bal<=KCI^SjA2^?j0qIFx>YEgwvH)3=KX96FmQ%}71pp@r4dnm; diff --git a/maps/askellon-sector.w3x/war3map.wts b/maps/askellon-sector.w3x/war3map.wts index 35c544c5..5873b147 100644 --- a/maps/askellon-sector.w3x/war3map.wts +++ b/maps/askellon-sector.w3x/war3map.wts @@ -524,12 +524,6 @@ STRING 149 Despair } -STRING 150 -// Buffs/Effects: B004 (Despair), Buffubertip (Tooltip - Extended) -{ -You've been spooked! You are visible to the |cff6f2583Alien |rand have reduced armor. -} - STRING 151 // Abilities: A00D (Apply Despair), Name (Name) { @@ -4061,19 +4055,6 @@ STRING 1037 Purchase Minigun } -STRING 1038 -// Items: I00F (MG5-27 "Flamesaw" Pattern Minigun), Ubertip (Tooltip - Extended) -{ -|cff808080Powered by galvanic rails, this old rifle has been in active circulation since the Yulvin succession wars. -Now many corporations produce upgrades and attachments that further improve upon its baseline functionality.|r - -The standard issue rifle; ideal for thinning hordes and can dish out serious damage up close. -|cff00ff00- 6 shot burst -- Each shot does 18 damage -- Short cooldown|r -|n|cff00ffffCan be enhanced with |cffc81e1ekinetic|r|cff00ffff attachments.|r -} - STRING 1040 // Abilities: A01A (Attack - Minigun), Name (Name) { @@ -4554,12 +4535,6 @@ STRING 1144 E } -STRING 1145 -// Abilities: A01O (Adaptive Regeneration), Ubertip (Tooltip - Normal - Extended) -{ -|cff808080LORE TODO|r|n|nInstantly|cff00ff00 heal 40%|r of your maximum hit points.|n|n|cff80808040 Seconds Cooldown|r -} - STRING 1147 // Abilities: A01O (Adaptive Regeneration), EditorSuffix (Editor Suffix) { @@ -6676,3 +6651,60 @@ STRING 1540 Is Alien Host } +STRING 1541 +// Items: I00F (MG5-27 "Flamesaw" Pattern Minigun), Ubertip (Tooltip - Extended) +{ +|cff808080No matter the vessel, no matter the mission, Hexcorp security always tries to bring at least one Flamesaw along. +Hostile targets are obliterated by a hail of high-powered rounds, but the Flamesaw's true source of notoriety is its infamous cooling system, which causes ammunition to engulf targets in flames.|r + +A heavy weapon designed for holding down corridors +|cff00ff00- Great Damage +- Sets targets alight while|r |cffd45e19Flamesaw|r|cff00ff00 is active +- Fires up to 250 rounds over 15 seconds|r +|cffc81e1e- Must stand still +- Turning reduces attack speed +- Unallies all units in the cone of fire|r +} + +STRING 1542 +// Abilities: A029 (Apply Void Sickness), Name (Name) +{ +Apply Void Sickness +} + +STRING 1543 +// Buffs/Effects: B00E (Void Sickness), EditorName (Name (Editor Only)) +{ +Void Sickness +} + +STRING 1544 +// Buffs/Effects: B00E (Void Sickness), Bufftip (Tooltip) +{ +Void Sickness +} + +STRING 1547 +// Buffs/Effects: B00E (Void Sickness), Buffubertip (Tooltip - Extended) +{ +|cff808080Eugh you feel sick|r|nUnable to enter ships for |cffc81e1e30 seconds|r. +} + +STRING 1548 +// Abilities: A01O (Adaptive Regeneration), Ubertip (Tooltip - Normal - Extended) +{ +|cff808080LORE TODO|r|n|nInstantly|cff00ff00 heal 40%|r of your maximum hit points.|n|n|cff80808080 Seconds Cooldown|r +} + +STRING 1549 +// Buffs/Effects: B004 (Despair), Buffubertip (Tooltip - Extended) +{ +|cff808080What was that?!|r|n|cff8a6df2Aliens smell your fear|r and have |cffc81e1evision of you|r. Your |cffc81e1eaccuracy is reduced|r and you |cffc81e1ecannot communicate|r. +} + +STRING 1550 +// Upgrades: R00K (Troll Regeneration,Improved Troll Regeneration,Advanced Troll Regeneration), Name (Name) +{ +Void Sickness +} + diff --git a/project.log b/project.log index 98741dbc..6014770a 100644 --- a/project.log +++ b/project.log @@ -712,3 +712,102 @@ [2020-11-16 09:07:04] info: Transpiling TypeScript to Lua... [2020-11-16 09:07:20] info: Building "askellon-sector.w3x"... [2020-11-16 09:07:21] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-16 12:23:43] info: Transpiling TypeScript to Lua... +[2020-11-16 12:24:04] info: Building "askellon-sector.w3x"... +[2020-11-16 12:24:05] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-16 12:28:46] info: Transpiling TypeScript to Lua... +[2020-11-16 12:29:01] info: Building "askellon-sector.w3x"... +[2020-11-16 12:29:02] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-16 12:31:45] info: Transpiling TypeScript to Lua... +[2020-11-16 12:32:01] info: Building "askellon-sector.w3x"... +[2020-11-16 12:32:02] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-16 21:09:46] info: Transpiling TypeScript to Lua... +[2020-11-16 21:10:10] info: Building "askellon-sector.w3x"... +[2020-11-16 21:10:11] info: Creating w3x archive... +[2020-11-16 23:11:37] info: Transpiling TypeScript to Lua... +[2020-11-16 23:11:52] info: Building "askellon-sector.w3x"... +[2020-11-16 23:11:53] info: Creating w3x archive... +[2020-11-17 02:13:10] info: Transpiling TypeScript to Lua... +[2020-11-17 02:13:25] info: Building "askellon-sector.w3x"... +[2020-11-17 02:13:26] info: Creating w3x archive... +[2020-11-17 05:07:33] info: Transpiling TypeScript to Lua... +[2020-11-17 05:07:49] info: Building "askellon-sector.w3x"... +[2020-11-17 05:07:52] info: Creating w3x archive... +[2020-11-17 22:20:20] info: Transpiling TypeScript to Lua... +[2020-11-17 22:20:45] info: Building "askellon-sector.w3x"... +[2020-11-17 22:21:16] info: Creating w3x archive... +[2020-11-18 02:06:12] info: Transpiling TypeScript to Lua... +[2020-11-18 02:06:27] info: Building "askellon-sector.w3x"... +[2020-11-18 02:06:30] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 22:49:00] info: Transpiling TypeScript to Lua... +[2020-11-19 22:49:18] info: Building "askellon-sector.w3x"... +[2020-11-19 22:49:20] info: Creating w3x archive... +[2020-11-19 23:14:34] info: Transpiling TypeScript to Lua... +[2020-11-19 23:14:58] info: Building "askellon-sector.w3x"... +[2020-11-19 23:14:59] info: Creating w3x archive... +[2020-11-19 23:24:24] info: Transpiling TypeScript to Lua... +[2020-11-19 23:24:41] info: Building "askellon-sector.w3x"... +[2020-11-19 23:24:41] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:29:29] info: Transpiling TypeScript to Lua... +[2020-11-19 23:29:45] info: Building "askellon-sector.w3x"... +[2020-11-19 23:29:45] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:32:49] info: Transpiling TypeScript to Lua... +[2020-11-19 23:33:05] info: Building "askellon-sector.w3x"... +[2020-11-19 23:33:06] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:37:03] info: Transpiling TypeScript to Lua... +[2020-11-19 23:37:18] info: Building "askellon-sector.w3x"... +[2020-11-19 23:37:18] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:39:50] info: Transpiling TypeScript to Lua... +[2020-11-19 23:40:06] info: Building "askellon-sector.w3x"... +[2020-11-19 23:40:07] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:42:08] info: Transpiling TypeScript to Lua... +[2020-11-19 23:42:24] info: Building "askellon-sector.w3x"... +[2020-11-19 23:42:24] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:44:19] info: Transpiling TypeScript to Lua... +[2020-11-19 23:44:35] info: Building "askellon-sector.w3x"... +[2020-11-19 23:44:35] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:48:34] info: Transpiling TypeScript to Lua... +[2020-11-19 23:48:50] info: Building "askellon-sector.w3x"... +[2020-11-19 23:48:51] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:52:38] info: Transpiling TypeScript to Lua... +[2020-11-19 23:52:53] info: Building "askellon-sector.w3x"... +[2020-11-19 23:52:54] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:55:35] info: Transpiling TypeScript to Lua... +[2020-11-19 23:55:51] info: Building "askellon-sector.w3x"... +[2020-11-19 23:55:51] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-19 23:58:09] info: Transpiling TypeScript to Lua... +[2020-11-19 23:58:26] info: Building "askellon-sector.w3x"... +[2020-11-19 23:58:26] info: Creating w3x archive... +[2020-11-20 00:09:53] info: Transpiling TypeScript to Lua... +[2020-11-20 00:10:12] info: Building "askellon-sector.w3x"... +[2020-11-20 00:10:12] info: Creating w3x archive... +[2020-11-20 00:23:16] info: Transpiling TypeScript to Lua... +[2020-11-20 00:23:32] info: Building "askellon-sector.w3x"... +[2020-11-20 00:23:33] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:29:51] info: Transpiling TypeScript to Lua... +[2020-11-20 00:30:07] info: Building "askellon-sector.w3x"... +[2020-11-20 00:30:07] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:34:44] info: Transpiling TypeScript to Lua... +[2020-11-20 00:34:59] info: Building "askellon-sector.w3x"... +[2020-11-20 00:35:00] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:40:29] info: Transpiling TypeScript to Lua... +[2020-11-20 00:40:44] info: Building "askellon-sector.w3x"... +[2020-11-20 00:40:45] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:45:06] info: Transpiling TypeScript to Lua... +[2020-11-20 00:45:22] info: Building "askellon-sector.w3x"... +[2020-11-20 00:45:22] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:50:05] info: Transpiling TypeScript to Lua... +[2020-11-20 00:50:20] info: Building "askellon-sector.w3x"... +[2020-11-20 00:50:21] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:57:14] info: Transpiling TypeScript to Lua... +[2020-11-20 00:57:29] info: Building "askellon-sector.w3x"... +[2020-11-20 00:57:30] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 00:59:17] info: Transpiling TypeScript to Lua... +[2020-11-20 00:59:33] info: Building "askellon-sector.w3x"... +[2020-11-20 00:59:34] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 01:06:22] info: Transpiling TypeScript to Lua... +[2020-11-20 01:06:37] info: Building "askellon-sector.w3x"... +[2020-11-20 01:06:38] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... +[2020-11-20 01:09:14] info: Transpiling TypeScript to Lua... +[2020-11-20 01:09:30] info: Building "askellon-sector.w3x"... +[2020-11-20 01:09:30] info: Launching map "E:/codename-askellon/dist/askellon-sector.w3x"... diff --git a/src/app/abilities/station/scan-for-player.ts b/src/app/abilities/station/scan-for-player.ts index 29464d03..b8924a42 100644 --- a/src/app/abilities/station/scan-for-player.ts +++ b/src/app/abilities/station/scan-for-player.ts @@ -42,20 +42,18 @@ export class StationSecurityScanForPlayer implements Ability { MessageAllPlayers(`Scan Complete.`); if (!this.isScanningForAliens) { Players.forEach(p => { - if (p.slotState != PLAYER_SLOT_STATE_EMPTY && p.controller == MAP_CONTROL_USER) { - const crew = PlayerStateFactory.getCrewmember(p); - if (crew) { - const pData = PlayerStateFactory.get(p); - const pMain = PlayerStateFactory.get(p).getUnit(); - if (pMain && crew && crew.unit && crew.unit.isAlive() && crew.unit === pMain) { - if (p.id < PLAYER_RGB.length) { - const c = PLAYER_RGB[p.id]; - if (c) PingMinimapEx(u.x, u.y, 6, c[0], c[1], c[2], false); - } - else { - Log.Warning(`${p.id} not in rgb colour array`); - } - } + const pData = PlayerStateFactory.get(p); + if (!pData) return; + + const crew = pData.getCrewmember(); + const pMain = pData.getUnit(); + if (pData && crew && crew.unit && crew.unit.isAlive() && crew.unit === pMain) { + if (p.id < PLAYER_RGB.length) { + const c = PLAYER_RGB[p.id]; + if (c) PingMinimapEx(pMain.x, pMain.y, 6, c[0], c[1], c[2], false); + } + else { + Log.Warning(`${p.id} not in rgb colour array`); } } }) diff --git a/src/app/buff/buffs/void-sickness.ts b/src/app/buff/buffs/void-sickness.ts new file mode 100644 index 00000000..1d74bb37 --- /dev/null +++ b/src/app/buff/buffs/void-sickness.ts @@ -0,0 +1,62 @@ +import { BUFF_ID, BUFF_ID_RESOLVE, BUFF_ID_PURITY_SEAL, BUFF_ID_VOID_SICKNESS } from "resources/buff-ids"; +import { Unit, Trigger } from "w3ts/index"; +import { SFX_FLASH_HEAL } from "resources/sfx-paths"; +import { getZFromXY } from "lib/utils"; +import { TECH_MAJOR_RELIGION, ABIL_VOID_SICKNESS_APPLY } from "resources/ability-ids"; +import { CREWMEMBER_UNIT_ID } from "resources/unit-ids"; +import { ResearchFactory } from "app/research/research-factory"; +import { EventEntity } from "app/events/event-entity"; +import { DynamicBuff } from "../dynamic-buff-type"; +import { EventListener } from "app/events/event-type"; +import { EVENT_TYPE } from "app/events/event-enum"; +import { ChatEntity } from "app/chat/chat-entity"; +import { BuffInstance } from "../buff-instance-type"; +import { DummyCast } from "lib/dummy"; +import { UPGR_DUMMY_VOID_SICKNESS } from "resources/upgrade-ids"; +import { Log } from "lib/serilog/serilog"; + +export class VoidSickness extends DynamicBuff { + id = BUFF_ID.PURITY_SEAL; + + protected doesStack = false; + + public addInstance(unit: Unit, instance: BuffInstance, isNegativeInstance?: boolean) { + super.addInstance(unit, instance, isNegativeInstance); + } + + public process(gametime: number, delta: number): boolean { + const result = super.process(gametime, delta); + if (!this.isActive) return result; + if (!UnitHasBuffBJ(this.who.handle, BUFF_ID_VOID_SICKNESS)) { + DummyCast((dummy: unit) => { + SetUnitX(dummy, this.who.x); + SetUnitY(dummy, this.who.y + 50); + IssueTargetOrder(dummy, "faeriefire", this.who.handle); + }, ABIL_VOID_SICKNESS_APPLY); + } + return result; + } + + public onStatusChange(newStatus: boolean) { + if (newStatus) { + DummyCast((dummy: unit) => { + SetUnitX(dummy, this.who.x); + SetUnitY(dummy, this.who.y + 50); + IssueTargetOrder(dummy, "faeriefire", this.who.handle); + }, ABIL_VOID_SICKNESS_APPLY); + this.who.owner.setTechResearched(UPGR_DUMMY_VOID_SICKNESS, + this.who.owner.getTechCount(UPGR_DUMMY_VOID_SICKNESS, true) + 1 + ); + // Log.Information("Void sickness tech level "+(this.who.owner.getTechCount(UPGR_DUMMY_VOID_SICKNESS, true))) + } + else { + + this.who.owner.setTechResearched(UPGR_DUMMY_VOID_SICKNESS, + this.who.owner.getTechCount(UPGR_DUMMY_VOID_SICKNESS, true) - 1 + ); + // Log.Information("down sickness tech level "+(this.who.owner.getTechCount(UPGR_DUMMY_VOID_SICKNESS, true))) + // Remove purity buff + UnitRemoveBuffBJ(BUFF_ID_VOID_SICKNESS, this.who.handle); + } + } +} \ No newline at end of file diff --git a/src/app/buff/dynamic-buff-entity.ts b/src/app/buff/dynamic-buff-entity.ts index ace126dc..80a07c5c 100644 --- a/src/app/buff/dynamic-buff-entity.ts +++ b/src/app/buff/dynamic-buff-entity.ts @@ -14,6 +14,7 @@ import { PuritySeal } from "./buffs/purity-seal"; import { onFire } from "./buffs/fire"; import { DynamicBuffState } from "./dynamic-buff-state"; import { Hooks } from "lib/Hooks"; +import { VoidSickness } from "./buffs/void-sickness"; export class DynamicBuffEntity extends Entity { @@ -47,6 +48,7 @@ export class DynamicBuffEntity extends Entity { if (id === BUFF_ID.DESPAIR) return new Despair(who); if (id === BUFF_ID.RESOLVE) return new Resolve(who); if (id === BUFF_ID.PURITY_SEAL) return new PuritySeal(); + if (id === BUFF_ID.VOID_SICKNESS) return new VoidSickness(); Log.Error("Creating new buff no instance for ID "+id); } diff --git a/src/app/force/force-entity.ts b/src/app/force/force-entity.ts index 45de8f2e..bb4c1bb2 100644 --- a/src/app/force/force-entity.ts +++ b/src/app/force/force-entity.ts @@ -497,8 +497,8 @@ export class ForceEntity extends Entity { const pData = PlayerStateFactory.get(who); if (pData && pData.getForce() && pData.getForce().is(OBSERVER_FORCE_NAME)) return false; - const playerLeaveSound = new SoundRef('Sound\\Interface\\QuestFailed.flac', false, true); - playerLeaveSound.playSound(); + // const playerLeaveSound = new SoundRef('Sound\\Interface\\QuestFailed.flac', false, true); + // playerLeaveSound.playSound(); Players.forEach(player => { ChatEntity.getInstance().postSystemMessage(player, `|cff${PLAYER_COLOR[who.id]}${PlayerStateFactory.get(who).originalName}|r has left the game!`); diff --git a/src/app/force/forces/alien-force.ts b/src/app/force/forces/alien-force.ts index 9711cf0a..bf07dc9c 100644 --- a/src/app/force/forces/alien-force.ts +++ b/src/app/force/forces/alien-force.ts @@ -34,6 +34,7 @@ import { CrewmemberForce } from "./crewmember-force"; import { MessagePlayer } from "lib/utils"; import { Quick } from "lib/Quick"; import { UPGR_DUMMY_IS_ALIEN_HOST } from "resources/upgrade-ids"; +import { ZONE_TYPE } from "app/world/zone-id"; export const MAKE_UNCLICKABLE = false; @@ -170,6 +171,7 @@ export class AlienForce extends ForceType { // Now create an alien for player this.playerAlienUnits.set(owner, alien); + // Hiding life bars if (MAKE_UNCLICKABLE) @@ -339,7 +341,7 @@ export class AlienForce extends ForceType { } removePlayerAlienUnit(whichUnit: Unit) { - Log.Information(`Remove alien unit called on ${whichUnit.owner.name}`); + // Log.Information(`Remove alien unit called on ${whichUnit.owner.name}`); // Also need to call remove player as the alien unit dying will also kill the palyer this.removePlayer(whichUnit.owner); } @@ -352,13 +354,13 @@ export class AlienForce extends ForceType { const crewmember = PlayerStateFactory.get(who).getCrewmember(); - if (!alien) return Log.Error("AlienForce::transform No alien for player!"); + if (!alien) return Log.Error("AlienForce::transform No alien for "+who.name+"!"); if (!unit) { if (crewmember && crewmember.unit) { this.playerUnits.set(who, unit); unit = this.playerUnits.get(who); } - if (!unit) return Log.Error("AlienForce::transform No human for player!"); + if (!unit) return Log.Error("AlienForce::transform No human for "+who.name+"!"); } @@ -592,72 +594,102 @@ export class AlienForce extends ForceType { */ public onEvolve(newForm: number) { - try { - // Increment current evo - this.currentAlienEvolution = newForm; - const alienHost = this.getHost(); - // const forceEnt = ForceEntity.getInstance(); - const worldEnt = WorldEntity.getInstance(); - - // Get all players - this.players.forEach(player => { - // Now get their alien units and replace with the new evo - const unit = this.playerAlienUnits.get(player); - const crew = PlayerStateFactory.getCrewmember(player); - - const isHiddenButNotTransformed = crew && crew.unit && !crew.unit.show && !this.playerIsTransformed.get(player); - - // If the current alien is hidden, skip this player - if (crew && !crew.unit.isAlive()) - return Log.Information(`EVOLVE ATTEMPT Crewmember for ${player.name} is dead`); - // If the current crew is hidden... don't evolve - if (crew && !crew.unit.show) return; - - if (unit) { - // Get old unit zone - const oldZone = worldEnt.getUnitZone(unit); - - // Remove the old unit from the zone - if (oldZone) { - worldEnt.removeUnit(unit); - } - ReplaceUnitBJ(unit.handle, newForm, 1); + // Log.Information("On evolution called"); + // Log.Information(`Current players: ${this.players.length}`); - const replacedUnit = GetLastReplacedUnitBJ(); - const alien = Unit.fromHandle(replacedUnit); - - this.registerAlienDeath(alien); - - // And handle travel - if (oldZone) { - worldEnt.travel(alien, oldZone.id); - } + // Timers.addTimedAction(3, () => { + // Increment current evo + this.currentAlienEvolution = newForm; + const alienHost = this.getHost(); + // const forceEnt = ForceEntity.getInstance(); + const worldEnt = WorldEntity.getInstance(); - SelectUnitForPlayerSingle(alien.handle, player.handle); - - this.playerAlienUnits.set(player, alien); - alien.nameProper = "|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|nAlien"; + // TODO FIXME host might be dead, keep for debbuging purposes though + const pHost = PlayerStateFactory.get(this.getHost()); + Log.Information("Alien ho/st: "+`${pHost.originalName}`) + + this.players.forEach((player, i) => { + + // TODO Remove delayed timers? + // Log.Information(`For ${i}`); + // Timers.addTimedAction(i * 5, () => { + try { + // Log.Information(`Starting ${i} ${player.name}`); + // Now get their alien units and replace with the new evo + const unit = this.playerAlienUnits.get(player); + const pData = PlayerStateFactory.get(player); + const crew = PlayerStateFactory.getCrewmember(player); + + if (!unit) { + Log.Information("wtf no unit for alien") + } + const transformationOnHiddenUnits = this.playerIsTransformed.get(player) ? (crew && crew.unit && !crew.unit.show) : (!unit.show); + + // If the current alien is hidden, skip this player + if (crew && !crew.unit.isAlive()) + return Log.Information(`EVOLVE ATTEMPT Crewmember for ${player.name} is dead`); + + if (unit) { + // Get old unit zone + const oldZone = worldEnt.getUnitZone(unit); + + // Remove the old unit from the zone + if (oldZone) { + // Log.Information("[OPTIONAL] Removing old world entity "+ZONE_TYPE[oldZone.id]); + worldEnt.removeUnit(unit); + } + + // Log.Information(`${pData.originalName} Replacing alien`); + // Remove old alien death + const oldAlienDeath = this.alienDeathTrigs.get(unit); + oldAlienDeath.destroy(); + this.alienDeathTrigs.delete(unit); + // Now call replace func + ReplaceUnitBJ(unit.handle, newForm, 1); + + const replacedUnit = GetLastReplacedUnitBJ(); + const alien = Unit.fromHandle(replacedUnit); + + // Log.Information(`${pData.originalName} Registering alien death`); + this.registerAlienDeath(alien); + + // And handle travel + if (oldZone) { + // Log.Information("[OPTIONAL] Travel to new zone "+ZONE_TYPE[oldZone.id]); + worldEnt.travel(alien, oldZone.id); + } + + SelectUnitForPlayerSingle(alien.handle, player.handle); + + Log.Information(`${pData.originalName} Setting player unit `); + this.playerAlienUnits.set(player, alien); + alien.nameProper = "|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|n|nAlien"; + + alien.name = 'Alien Host'; + alien.color = PLAYER_COLOR_PURPLE; + + if (!transformationOnHiddenUnits) { + DestroyEffect(AddSpecialEffect(SFX_ALIEN_BLOOD, alien.x, alien.y)); - alien.name = 'Alien Host'; - alien.color = PLAYER_COLOR_PURPLE; - - if (!isHiddenButNotTransformed) - DestroyEffect(AddSpecialEffect(SFX_ALIEN_BLOOD, alien.x, alien.y)); - - // Now we need to also set alien spawn penalties - this.applyAlienMinionHost(alien, player === alienHost); - - // If a player isn't transformed force the transformation - if (!this.playerIsTransformed.get(player)) { - this.transform(player, true); - } - } - }) - } - catch (e) { - Log.Error("Evolution failed!"); - Log.Error(e); - } + // Log.Information(`${pData.originalName} Applying minion host effects`); + // Now we need to also set alien spawn penalties + this.applyAlienMinionHost(alien, player === alienHost); + + // If a player isn't transformed force the transformation + if (!transformationOnHiddenUnits && !this.playerIsTransformed.get(player)) { + // Log.Information(`${pData.originalName} Transforming player!`); + this.transform(player, true); + } + } + } + } + catch (e) { + Log.Error("Evolution failed!"); + Log.Error(e); + } + // }); + }); + // }); } private applyAlienMinionHost(alien: Unit, isHost: boolean) { diff --git a/src/app/force/forces/force-type.ts b/src/app/force/forces/force-type.ts index 8c8deadc..b98f61a9 100644 --- a/src/app/force/forces/force-type.ts +++ b/src/app/force/forces/force-type.ts @@ -38,6 +38,7 @@ export abstract class ForceType { } addPlayer(who: MapPlayer) { + // Log.Information(`Adding ${who.name} to ${this.name}`); this.players.push(who); } diff --git a/src/app/force/forces/observer-force.ts b/src/app/force/forces/observer-force.ts index 4536fc08..083ae10b 100644 --- a/src/app/force/forces/observer-force.ts +++ b/src/app/force/forces/observer-force.ts @@ -74,6 +74,8 @@ export class ObserverForce extends ForceType { if (this.deltaTicker >= 15) { this.deltaTicker = 0; + if (this.players.length === 0) return; + // Loop through all game players this.players.forEach( obs => { Players.forEach( p => { @@ -85,11 +87,13 @@ export class ObserverForce extends ForceType { if (obs.handle === GetLocalPlayer() && pData && pData.getForce()) { const force = pData.getForce(); const u = pData.getUnit(); - if (force.is(ALIEN_FORCE_NAME)) { - PingMinimapEx(u.x, u.y, 3, 153, 51, 255, false); - } - else { - PingMinimapEx(u.x, u.y, 3, 102, 255, 51, false); + if (u) { + if (force.is(ALIEN_FORCE_NAME)) { + PingMinimapEx(u.x, u.y, 3, 153, 51, 255, false); + } + else { + PingMinimapEx(u.x, u.y, 3, 102, 255, 51, false); + } } } }); diff --git a/src/app/force/player-state-entity.ts b/src/app/force/player-state-entity.ts index e2d8e2fa..71e71167 100644 --- a/src/app/force/player-state-entity.ts +++ b/src/app/force/player-state-entity.ts @@ -67,7 +67,8 @@ export class PlayerStateFactory { if (this.state.has(who)) { return this.state.get(who); } - else { + else if (who.slotState !== PLAYER_SLOT_STATE_EMPTY && who.controller === MAP_CONTROL_USER) { + // Log.Warning(`Pdata.new [${who.id}]${who.name}`) const nState = new PlayerState(who); this.state.set(who, nState); return nState; diff --git a/src/app/interactions/interactables/ships/ship.ts b/src/app/interactions/interactables/ships/ship.ts index 44cfd089..14748942 100644 --- a/src/app/interactions/interactables/ships/ship.ts +++ b/src/app/interactions/interactables/ships/ship.ts @@ -7,6 +7,10 @@ import { EVENT_TYPE } from "app/events/event-enum"; import { InteractableData } from "../interactable-type"; import { COL_ATTATCH, COL_PINK } from "resources/colours"; import { Interactables } from "../interactables"; +import { BUFF_ID_VOID_SICKNESS } from "resources/buff-ids"; +import { MessagePlayer } from "lib/utils"; +import { Log } from "lib/serilog/serilog"; +import { UPGR_DUMMY_VOID_SICKNESS } from "resources/upgrade-ids"; // Interacting with asteroids const noInventorySpace = new SoundRef("Sounds\\DeniedBeep.mp3", false, true); @@ -33,6 +37,11 @@ export function initShipInteractions() { } return false; } + + if (GetPlayerTechCount(source.owner.handle, UPGR_DUMMY_VOID_SICKNESS, true) !== 0) { + MessagePlayer(source.owner, `You feel too ${COL_ATTATCH}sick|r to use this right now.`) + return false; + } EventEntity.getInstance().sendEvent(EVENT_TYPE.ENTER_SHIP, { source: source, data: { diff --git a/src/app/research/research-factory.ts b/src/app/research/research-factory.ts index 41687c8a..29c7896b 100644 --- a/src/app/research/research-factory.ts +++ b/src/app/research/research-factory.ts @@ -144,10 +144,10 @@ const majorResarchSound = new SoundRef("Sounds\\Station\\major_research_complete } const pData = PlayerStateFactory.get(p); - const pForce = pData.getForce(); - if (pData && pForce) { + if (pData) { + const pForce = pData.getForce(); - if (isInfested && pForce.is(ALIEN_FORCE_NAME)) { + if (pForce && isInfested && pForce.is(ALIEN_FORCE_NAME)) { MessagePlayer(p, STR_UPGRADE_COMPLETE_INFESTATION()); // Play infestation complete sound } diff --git a/src/app/space/ships/perseus-type.ts b/src/app/space/ships/perseus-type.ts index 95ac01d7..456a0095 100644 --- a/src/app/space/ships/perseus-type.ts +++ b/src/app/space/ships/perseus-type.ts @@ -15,6 +15,10 @@ import { ITEM_MINERALS_REACTIVE_SHIP_ID, ITEM_MINERALS_VALUABLE_SHIP_ID, ITEM_MI import { EventEntity } from "app/events/event-entity"; import { EventListener } from "app/events/event-type"; import { EVENT_TYPE } from "app/events/event-enum"; +import { DynamicBuffEntity } from "app/buff/dynamic-buff-entity"; +import { BUFF_ID } from "resources/buff-ids"; +import { BuffInstance } from "app/buff/buff-instance-type"; +import { BuffInstanceDuration } from "app/buff/buff-instance-duration-type"; export class PerseusShip extends ShipWithFuel { @@ -212,6 +216,7 @@ export class PerseusShip extends ShipWithFuel { // If we have the entering unit was selected, select the ship too SelectUnitForPlayerSingle(u.handle, u.owner.handle); PanCameraToTimedForPlayer(u.owner.handle, u.x, u.y, 0); + DynamicBuffEntity.add(BUFF_ID.VOID_SICKNESS, u, new BuffInstanceDuration(u, 30)); }); // Drop minerals off diff --git a/src/app/space/space-mining-entity.ts b/src/app/space/space-mining-entity.ts index e7983dae..146acc26 100644 --- a/src/app/space/space-mining-entity.ts +++ b/src/app/space/space-mining-entity.ts @@ -12,6 +12,7 @@ import { Log } from "lib/serilog/serilog"; import { ResearchFactory } from "app/research/research-factory"; import { TECH_MAJOR_VOID } from "resources/ability-ids"; import { PlayerStateFactory } from "app/force/player-state-entity"; +import { SPACE_UNIT_MINERAL } from "resources/unit-ids"; class MiningEvent { drillStartSound = new SoundRef("Sounds\\Ships\\LaserDrillStart.wav", false, false); @@ -47,7 +48,7 @@ class MiningEvent { this.beamLaserTargetPoint = Vector3.fromWidget(target.handle).multiply( new Vector3(GetRandomReal(-1, 1), GetRandomReal(-1, 1), GetRandomReal(-1, 1)).multiplyN(50)); this.beam = AddLightningEx("SPNL", false, - this.beamOrigin.x, this.beamOrigin.x, this.beamOrigin.z, + this.beamOrigin.x, this.beamOrigin.y, this.beamOrigin.z, this.beamLaserCurrentPoint.x, this.beamLaserCurrentPoint.y, this.beamLaserCurrentPoint.z ); this.drillStartSound.playSoundOnPont(this.beamOrigin.x, this.beamOrigin.y, 15); @@ -66,6 +67,7 @@ class MiningEvent { // Increase move speed of the beam this.beamMoveSpeed += 10 * delta; + // Set beam origin this.beamOrigin = Vector3.fromWidget(this.source.handle).projectTowards2D(this.source.facing, 45); this.beamOrigin.z = 90; @@ -77,6 +79,10 @@ class MiningEvent { const deltaPoint = this.beamLaserTargetPoint.subtract(this.beamLaserCurrentPoint).normalise().multiplyN(this.beamMoveSpeed * delta); this.beamLaserCurrentPoint = this.beamLaserCurrentPoint.add(deltaPoint); + // Prevent ships from flying away while mining + if (this.beamLaserCurrentPoint.subtract(this.beamOrigin).getLength() > 900) + return false; + // Move lightning const s = this.beamOrigin; const e = this.beamLaserCurrentPoint; @@ -100,7 +106,7 @@ class MiningEvent { new Vector3(GetRandomReal(-1, 1), GetRandomReal(-1, 1), GetRandomReal(-1, 1)).normalise().multiplyN(45 * this.target.selectionScale)); } - const rng = GetRandomReal(0, 100); + const rng = (this.target.typeId === SPACE_UNIT_MINERAL) ? 100 : 0; if (rng > 75) { const minerals = this.source.getItemInSlot(1); diff --git a/src/app/world/zone-id.ts b/src/app/world/zone-id.ts index 7cdad8d9..a8c417cd 100644 --- a/src/app/world/zone-id.ts +++ b/src/app/world/zone-id.ts @@ -52,6 +52,7 @@ ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.ARMORY, `${COL_ATTATCH}Armory|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.CHURCH, `${COL_GOLD}Cathederal|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.SERVICE_TUNNELS_WEST, `${COL_VENTS}Service Tunnels|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.SERVICE_TUNNELS_EAST, `${COL_VENTS}Service Tunnels|r`); +ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.BIOLOGY_VENT, `${COL_VENTS}Service Tunnels|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.BRIDGE, `${COL_CARGO_A}Bridge|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.BRIDGE_VENT, `${COL_VENTS}Bridge Connector|r`); ZONE_TYPE_TO_ZONE_NAME.set(ZONE_TYPE.CARGO_A, `${COL_CARGO_A}Cargo|r`); diff --git a/src/resources/ability-ids.ts b/src/resources/ability-ids.ts index ea421afc..54ce9a1c 100644 --- a/src/resources/ability-ids.ts +++ b/src/resources/ability-ids.ts @@ -7,6 +7,7 @@ export const ABIL_INQUIS_SMITE = FourCC('A013'); export const ABIL_LEAVE_ASKELLON_CONTROLS = FourCC('A00N'); export const ABIL_DESPAIR = FourCC('A00D'); export const ABIL_RESOLVE = FourCC('A007'); +export const ABIL_VOID_SICKNESS_APPLY = FourCC('A029'); // Misc export const ABILITY_SLOW_ID = FourCC('A00B'); diff --git a/src/resources/buff-ids.ts b/src/resources/buff-ids.ts index ffd55213..5338f677 100644 --- a/src/resources/buff-ids.ts +++ b/src/resources/buff-ids.ts @@ -4,7 +4,8 @@ export enum BUFF_ID { FLASH_FREEZE, FIRE, TRIFEX, - PURITY_SEAL + PURITY_SEAL, + VOID_SICKNESS, } export const BUFF_ID_FEAST = FourCC('B00C'); export const BUFF_ID_TRIFEX = FourCC('B005'); @@ -14,4 +15,5 @@ export const BUFF_ID_ROACH_ARMOR = FourCC('B006'); export const BUFF_ID_PURITY_SEAL = FourCC('B008'); export const BUFF_ID_SIGNAL_BOOSTER = FourCC('B00A'); export const BUFF_ID_NANOMED = FourCC('B00D'); -export const BUFF_ID_REGENERATION = FourCC('BIrl'); \ No newline at end of file +export const BUFF_ID_REGENERATION = FourCC('BIrl'); +export const BUFF_ID_VOID_SICKNESS = FourCC('B00E'); \ No newline at end of file diff --git a/src/resources/crewmember-names.ts b/src/resources/crewmember-names.ts index cb26c2f0..c7fc2431 100644 --- a/src/resources/crewmember-names.ts +++ b/src/resources/crewmember-names.ts @@ -9,7 +9,8 @@ export enum ROLE_TYPES { MAJOR = 'Major', DOCTOR = 'Doctor', INQUISITOR = 'Inquisitor', - PILOT = 'Pilot' + PILOT = 'Pilot', + XENOBIOLOGIST = 'Xenobiologist' } export const ROLE_NAMES = new Map>(); export const ROLE_SPAWN_LOCATIONS = new Map(); @@ -19,12 +20,13 @@ ROLE_NAMES.set(ROLE_TYPES.CAPTAIN, [ "Captain Coloma", "Captain Dallas", "Captain Cutter", "Captain Reynolds", "Captain Willard", "Captain Fodder", "Captain Cook", "Captain Kimstar", "Captain Picard", "Captain Jakov", "Captain Shepherd", "Captain America", - "Captain Sullivan", "Captain Frost", "Captain Shane", "Captain Blazkowicz" + "Captain Sullivan", "Captain Frost", "Captain Shane", "Captain Blazkowicz", + "Captain Xerxes", "Captain Alex Hawthorne" ]); ROLE_NAMES.set(ROLE_TYPES.NAVIGATOR, [ "Admiral Ackbar", "Admiral Doubt", "Admiral Hansel", "Admiral Gretel", "Admiral Jones", "Admiral Aedus", - "Admiral Alex", "Navigator Stanley" + "Admiral Alex", "Navigator Stanley", "Adminal Mayday" ]); ROLE_NAMES.set(ROLE_TYPES.SEC_GUARD, [ @@ -32,12 +34,12 @@ ROLE_NAMES.set(ROLE_TYPES.SEC_GUARD, [ "Pvt. Riley", "Pvt. Blake", "Pvt. Vasquez", "Pvt. Allen", "Pvt. Jenkins", "Pvt. Summers", "Pvt. Pyle", "Pvt. Harding", "Pvt. Hudson", "Cpl. Baker", "Cpl. Hicks", "Cpl. Emerich", "Cpl. Dilan", "Cpl. Collins", "Cpl. Duncan", "Cpl. Farquaad", "Pvt. Parts", "Pvt Fuzz", - "Pvt Chapman", "Pvt Piggy", "Col. Harkon", + "Pvt Chapman", "Pvt Piggy", "Col. Harkon", "Pvt. Bucky", "Cpl. Korgoth" ]); ROLE_NAMES.set(ROLE_TYPES.ENGINEER, [ "Engineer Fahr", "Engineer Isaac", "Engineer \"Support\" Ware", "Engineer Zed", "Engineer Swann", - "Engineer Arhanul", "Engineer Homer", + "Engineer Arhanul", "Engineer Homer", "Engineer Galileo" ]); ROLE_NAMES.set(ROLE_TYPES.MAJOR, [ @@ -45,16 +47,19 @@ ROLE_NAMES.set(ROLE_TYPES.MAJOR, [ ]); ROLE_NAMES.set(ROLE_TYPES.DOCTOR, [ - "Doctor Dimento", "Doctor Quack", "Doctor Who", "Doctor Chemix", "Doctor Freeman", "Doctor Kimberly", "Doctor Strange" + "Doctor Dimento", "Doctor Quack", "Doctor Who", "Doctor Chemix", "Doctor Freeman", "Doctor Kimberly", "Doctor Strange", "Doctor Frederik Grimm", ]); ROLE_NAMES.set(ROLE_TYPES.INQUISITOR, [ "Inquisitor Ithuriel", "Inquisitor Sapharax", "Inquisitor Eisenhorn", "Inquisitor Rhasan", "Inquisitor Lazarus", - "Inquisitor Fyre", "Inquisitor Pariah", "Inquisitor Tosh" + "Inquisitor Fyre", "Inquisitor Pariah", "Inquisitor Tosh", "Ordinator Ravenbrand" ]); ROLE_NAMES.set(ROLE_TYPES.PILOT, [ - "\"Top Gun\" Maverick", "Hoban \"Wash\" Washburne", "Gilbert Ward \"Thomas\" Kane", "Carl \"Chunky\" Rodgers", "Crocodile Jim", "Jebediah Kerman", "Jaeger \"Ace\" Ventura" + "\"Top Gun\" Maverick", "Hoban \"Wash\" Washburne", "Gilbert Ward \"Thomas\" Kane", "Carl \"Chunky\" Rodgers", "Crocodile Jim", "Jebediah Kerman", "Jaeger \"Ace\" Ventura", "Pilot Fury" +]); +ROLE_NAMES.set(ROLE_TYPES.XENOBIOLOGIST, [ + "Phineas Welles" ]); diff --git a/src/resources/upgrade-ids.ts b/src/resources/upgrade-ids.ts index 3c468097..34a48cf1 100644 --- a/src/resources/upgrade-ids.ts +++ b/src/resources/upgrade-ids.ts @@ -1 +1,2 @@ -export const UPGR_DUMMY_IS_ALIEN_HOST = FourCC('R00J'); \ No newline at end of file +export const UPGR_DUMMY_IS_ALIEN_HOST = FourCC('R00J'); +export const UPGR_DUMMY_VOID_SICKNESS = FourCC('R00k'); \ No newline at end of file diff --git a/src/resources/weapon-tooltips.ts b/src/resources/weapon-tooltips.ts index 42f09469..547cdf1c 100644 --- a/src/resources/weapon-tooltips.ts +++ b/src/resources/weapon-tooltips.ts @@ -103,11 +103,6 @@ export const MINIGUN_ITEM = (weapon: GunItem, damage: any) => `${COL_MISC}No matter the vessel, no matter the mission, Hexcorp security always tries to bring at least one Flamesaw along. Hostile targets are obliterated by a hail of high-powered rounds, but the Flamesaw's true source of notoriety is its infamous cooling system, which causes ammunition to engulf targets in flames.|r -Attached: ${weapon.attachment - ? `${COL_GOLD}${weapon.attachment.name}` - : `${COL_ATTATCH}Nothing` -}|r - A heavy weapon designed for holding down corridors ${COL_GOOD}- Great Damage - Sets targets alight while ${COL_ORANGE}Flamesaw|r${COL_GOOD} is active