Showing preview only (5,760K chars total). Download the full file or copy to clipboard to get everything.
Repository: huangkaoya/redalert2
Branch: main
Commit: 05433ac8100c
Files: 1289
Total size: 5.2 MB
Directory structure:
gitextract_zvkrxqle/
├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── package.json
├── public/
│ ├── 7zz.wasm
│ ├── config.ini
│ ├── css/
│ │ └── main-legacy.css
│ ├── general.csf
│ ├── ini.mix
│ ├── mods.ini
│ ├── other/
│ │ └── file-explorer.css
│ ├── res/
│ │ ├── fonts/
│ │ │ └── fonts.css
│ │ ├── locale/
│ │ │ ├── en-US.json
│ │ │ └── zh-CN.json
│ │ └── ra2cd.mix
│ └── servers.ini
├── src/
│ ├── App.tsx
│ ├── Application.ts
│ ├── BattleControlApi.ts
│ ├── ClientApi.ts
│ ├── Config.ts
│ ├── ConsoleVars.ts
│ ├── ErrorHandler.ts
│ ├── Gui.ts
│ ├── LocalPrefs.ts
│ ├── RouteHelper.ts
│ ├── data/
│ │ ├── AudioBagFile.ts
│ │ ├── Bitmap.ts
│ │ ├── Crc32.ts
│ │ ├── CsfFile.ts
│ │ ├── DataStream.ts
│ │ ├── HvaFile.ts
│ │ ├── IdxEntry.ts
│ │ ├── IdxFile.ts
│ │ ├── IniFile.ts
│ │ ├── IniParser.ts
│ │ ├── IniSection.ts
│ │ ├── MapFile.ts
│ │ ├── MapObjects.ts
│ │ ├── MixEntry.ts
│ │ ├── MixFile.ts
│ │ ├── Mp3File.ts
│ │ ├── Palette.ts
│ │ ├── PcxFile.ts
│ │ ├── ShpFile.ts
│ │ ├── ShpImage.ts
│ │ ├── Strings.ts
│ │ ├── TmpFile.ts
│ │ ├── TmpImage.ts
│ │ ├── VxlFile.ts
│ │ ├── WavFile.ts
│ │ ├── encoding/
│ │ │ ├── Blowfish.ts
│ │ │ ├── BlowfishKey.ts
│ │ │ ├── Format3.ts
│ │ │ ├── Format5.ts
│ │ │ ├── Format80.ts
│ │ │ ├── MiniLzo.ts
│ │ │ └── lzo1x.ts
│ │ ├── hva/
│ │ │ └── Section.ts
│ │ ├── map/
│ │ │ ├── MapLighting.ts
│ │ │ ├── MapObjects.ts
│ │ │ ├── SpecialFlags.ts
│ │ │ ├── Variable.ts
│ │ │ ├── tag/
│ │ │ │ ├── CellTag.ts
│ │ │ │ ├── CellTagsReader.ts
│ │ │ │ ├── Tag.ts
│ │ │ │ ├── TagRepeatType.ts
│ │ │ │ └── TagsReader.ts
│ │ │ └── trigger/
│ │ │ ├── Trigger.ts
│ │ │ ├── TriggerAction.ts
│ │ │ ├── TriggerActionType.ts
│ │ │ ├── TriggerEvent.ts
│ │ │ ├── TriggerEventType.ts
│ │ │ └── TriggerReader.ts
│ │ ├── vfs/
│ │ │ ├── Archive.ts
│ │ │ ├── FileNotFoundError.ts
│ │ │ ├── FileSystem.ts
│ │ │ ├── IOError.ts
│ │ │ ├── MemArchive.ts
│ │ │ ├── NameNotAllowedError.ts
│ │ │ ├── RealFileSystem.ts
│ │ │ ├── RealFileSystemDir.ts
│ │ │ ├── StorageQuotaError.ts
│ │ │ ├── VirtualFile.ts
│ │ │ └── VirtualFileSystem.ts
│ │ ├── vxl/
│ │ │ ├── Section.ts
│ │ │ ├── Span.ts
│ │ │ ├── SpanOffsets.ts
│ │ │ ├── Voxel.ts
│ │ │ ├── VoxelField.ts
│ │ │ ├── VxlHeader.ts
│ │ │ └── normals.ts
│ │ └── zip/
│ │ ├── Zip.ts
│ │ └── ZipUtils.ts
│ ├── engine/
│ │ ├── AnimProps.ts
│ │ ├── Animation.ts
│ │ ├── AsyncResourceCollection.ts
│ │ ├── Engine.ts
│ │ ├── EngineType.ts
│ │ ├── GameAnimationLoop.ts
│ │ ├── ImageFinder.ts
│ │ ├── IsoCoords.ts
│ │ ├── LazyAsyncResourceCollection.ts
│ │ ├── LazyResourceCollection.ts
│ │ ├── Lighting.ts
│ │ ├── MapDigest.ts
│ │ ├── MapList.ts
│ │ ├── MapManifest.ts
│ │ ├── MapSupport.ts
│ │ ├── RenderableManager.ts
│ │ ├── ResourceCollection.ts
│ │ ├── ResourceLoader.ts
│ │ ├── Theater.ts
│ │ ├── TheaterType.ts
│ │ ├── UiAnimationLoop.ts
│ │ ├── animation/
│ │ │ ├── Runner.ts
│ │ │ └── SimpleRunner.ts
│ │ ├── gameRes/
│ │ │ ├── CdnManifest.ts
│ │ │ ├── CdnResourceLoader.ts
│ │ │ ├── FileSystemAccessLib.ts
│ │ │ ├── FileSystemUtil.ts
│ │ │ ├── GameRes.ts
│ │ │ ├── GameResConfig.ts
│ │ │ ├── GameResImporter.ts
│ │ │ ├── GameResSource.ts
│ │ │ ├── VideoConverter.ts
│ │ │ ├── browserFileSystemAccess.ts
│ │ │ └── importError/
│ │ │ ├── ArchiveDownloadError.ts
│ │ │ ├── ArchiveExtractionError.ts
│ │ │ ├── ChecksumError.ts
│ │ │ ├── FileNotFoundError.ts
│ │ │ ├── InvalidArchiveError.ts
│ │ │ ├── NoStorageError.ts
│ │ │ └── NoWebAssemblyError.ts
│ │ ├── gfx/
│ │ │ ├── BufferGeometryUtils.ts
│ │ │ ├── Camera.ts
│ │ │ ├── CanvasUtils.ts
│ │ │ ├── DebugUtils.ts
│ │ │ ├── FrustumCuller.ts
│ │ │ ├── GrowingPacker.ts
│ │ │ ├── ImageUtils.ts
│ │ │ ├── MathUtils.ts
│ │ │ ├── OctreeContainer.ts
│ │ │ ├── OverlayUtils.ts
│ │ │ ├── Renderable.ts
│ │ │ ├── RenderableContainer.ts
│ │ │ ├── Renderer.ts
│ │ │ ├── RendererError.ts
│ │ │ ├── Scene.ts
│ │ │ ├── SpriteUtils.ts
│ │ │ ├── TextureAtlas.ts
│ │ │ ├── TextureUtils.ts
│ │ │ ├── batch/
│ │ │ │ ├── BatchedMesh.ts
│ │ │ │ ├── InstancedMesh.ts
│ │ │ │ ├── MergedSpriteMesh.ts
│ │ │ │ ├── MeshBatchManager.ts
│ │ │ │ ├── MeshInstancingBatch.ts
│ │ │ │ └── MeshMergingBatch.ts
│ │ │ ├── drawable/
│ │ │ │ ├── PalDrawable.ts
│ │ │ │ └── TmpDrawable.ts
│ │ │ ├── geometry/
│ │ │ │ ├── BufferGeometrySerializer.ts
│ │ │ │ └── VxlGeometryCache.ts
│ │ │ ├── lighting/
│ │ │ │ ├── LightingDirector.ts
│ │ │ │ ├── LightingFx.ts
│ │ │ │ ├── LightningStormFx.ts
│ │ │ │ └── NukeLightingFx.ts
│ │ │ └── material/
│ │ │ ├── PaletteBasicMaterial.ts
│ │ │ ├── PaletteLambertMaterial.ts
│ │ │ ├── PalettePhongMaterial.ts
│ │ │ └── paletteShaderLib.ts
│ │ ├── mixDatabase.ts
│ │ ├── renderable/
│ │ │ ├── AlphaRenderable.ts
│ │ │ ├── CameraPan.ts
│ │ │ ├── CameraZoom.ts
│ │ │ ├── DebugRenderable.ts
│ │ │ ├── Entity.ts
│ │ │ ├── MapSpriteTranslation.ts
│ │ │ ├── Renderable.ts
│ │ │ ├── RenderablePlugin.ts
│ │ │ ├── ShadowRenderable.ts
│ │ │ ├── ShpRenderable.ts
│ │ │ ├── WithPosition.ts
│ │ │ ├── WithVisibility.ts
│ │ │ ├── WorldScene.ts
│ │ │ ├── builder/
│ │ │ │ ├── BatchShpBuilder.ts
│ │ │ │ ├── CanvasSpriteBuilder.ts
│ │ │ │ ├── CanvasTextureAtlas.ts
│ │ │ │ ├── ObjectBuilder.ts
│ │ │ │ ├── ShpAggregator.ts
│ │ │ │ ├── ShpBuilder.ts
│ │ │ │ ├── ShpTextureAtlas.ts
│ │ │ │ ├── SpriteBuilder.ts
│ │ │ │ ├── VxlBatchedBuilder.ts
│ │ │ │ ├── VxlBuilder.ts
│ │ │ │ ├── VxlBuilderFactory.ts
│ │ │ │ ├── VxlNonBatchedBuilder.ts
│ │ │ │ └── vxlGeometry/
│ │ │ │ ├── VxlGeometryCulledBuilder.ts
│ │ │ │ ├── VxlGeometryMonotoneBuilder.ts
│ │ │ │ ├── VxlGeometryNaiveBuilder.ts
│ │ │ │ └── VxlGeometryPool.ts
│ │ │ ├── entity/
│ │ │ │ ├── Aircraft.ts
│ │ │ │ ├── Anim.ts
│ │ │ │ ├── BoxIntersectObject3D.ts
│ │ │ │ ├── Building.ts
│ │ │ │ ├── Debris.ts
│ │ │ │ ├── HighlightAnimRunner.ts
│ │ │ │ ├── Infantry.ts
│ │ │ │ ├── InvulnerableAnimRunner.ts
│ │ │ │ ├── IsoCoords.ts
│ │ │ │ ├── Overlay.ts
│ │ │ │ ├── PipOverlay.ts
│ │ │ │ ├── Projectile.ts
│ │ │ │ ├── RenderableFactory.ts
│ │ │ │ ├── Smudge.ts
│ │ │ │ ├── TargetLines.ts
│ │ │ │ ├── Terrain.ts
│ │ │ │ ├── TransientAnim.ts
│ │ │ │ ├── Vehicle.ts
│ │ │ │ ├── WaypointLine.ts
│ │ │ │ ├── WaypointLines.ts
│ │ │ │ ├── building/
│ │ │ │ │ ├── AnimationType.ts
│ │ │ │ │ ├── BuildingAnimArtProps.ts
│ │ │ │ │ ├── BuildingAnimData.ts
│ │ │ │ │ ├── BuildingShpHelper.ts
│ │ │ │ │ ├── DamageType.ts
│ │ │ │ │ └── PsychicDetectPlugin.ts
│ │ │ │ ├── map/
│ │ │ │ │ ├── MapBounds.ts
│ │ │ │ │ ├── MapGrid.ts
│ │ │ │ │ ├── MapRenderable.ts
│ │ │ │ │ ├── MapShroudLayer.ts
│ │ │ │ │ ├── MapSpriteBatchLayer.ts
│ │ │ │ │ ├── MapSurface.ts
│ │ │ │ │ ├── MapTileLayer.ts
│ │ │ │ │ ├── MapTileLayerDebug.ts
│ │ │ │ │ ├── MinimapModel.ts
│ │ │ │ │ └── MinimapRenderer.ts
│ │ │ │ ├── plugin/
│ │ │ │ │ ├── ChronoSparkleFxPlugin.ts
│ │ │ │ │ ├── DamageSmokePlugin.ts
│ │ │ │ │ ├── HarvesterPlugin.ts
│ │ │ │ │ ├── InfantryDisguisePlugin.ts
│ │ │ │ │ ├── MindControlLinkPlugin.ts
│ │ │ │ │ ├── MoveSoundFxPlugin.ts
│ │ │ │ │ ├── ObjectCloakPlugin.ts
│ │ │ │ │ ├── ShipWakeTrailPlugin.ts
│ │ │ │ │ ├── TntFxPlugin.ts
│ │ │ │ │ ├── TrailerSmokePlugin.ts
│ │ │ │ │ └── VehicleDisguisePlugin.ts
│ │ │ │ └── unit/
│ │ │ │ ├── BlobShadow.ts
│ │ │ │ ├── DebugLabel.ts
│ │ │ │ ├── ExtraLightHelper.ts
│ │ │ │ ├── FlyerHelperMode.ts
│ │ │ │ ├── ModelQuality.ts
│ │ │ │ ├── RotorHelper.ts
│ │ │ │ └── ShadowQuality.ts
│ │ │ └── fx/
│ │ │ ├── DamageSmokeFx.ts
│ │ │ ├── DetectionLineFx.ts
│ │ │ ├── Effect.ts
│ │ │ ├── LaserFx.ts
│ │ │ ├── LineTrailFx.ts
│ │ │ ├── MeshLineResolution.ts
│ │ │ ├── MindControlLinkFx.ts
│ │ │ ├── RadBeamFx.ts
│ │ │ ├── RallyPointFx.ts
│ │ │ ├── SparkFx.ts
│ │ │ ├── TeslaFx.ts
│ │ │ ├── TrailerSmokeFx.ts
│ │ │ ├── handler/
│ │ │ │ ├── BeaconFxHandler.ts
│ │ │ │ ├── ChronoFxHandler.ts
│ │ │ │ ├── CrateFxHandler.ts
│ │ │ │ ├── ParasiteSparkFxHandler.ts
│ │ │ │ ├── SuperWeaponFxHandler.ts
│ │ │ │ ├── TriggerActionFxHandler.ts
│ │ │ │ └── WarheadDetonateFxHandler.ts
│ │ │ ├── speCompat.ts
│ │ │ └── speRuntime.ts
│ │ ├── resourceConfigs.ts
│ │ ├── sound/
│ │ │ ├── AudioLoop.ts
│ │ │ ├── AudioSequence.ts
│ │ │ ├── AudioSystem.ts
│ │ │ ├── ChannelType.ts
│ │ │ ├── Eva.ts
│ │ │ ├── EvaSpecs.ts
│ │ │ ├── InternalPlaybackHandle.ts
│ │ │ ├── Mixer.ts
│ │ │ ├── Music.ts
│ │ │ ├── MusicSpecs.ts
│ │ │ ├── Sound.ts
│ │ │ ├── SoundKey.ts
│ │ │ ├── SoundSpec.ts
│ │ │ ├── SoundSpecs.ts
│ │ │ └── WorldSound.ts
│ │ ├── type/
│ │ │ ├── LightingType.ts
│ │ │ ├── ObjectType.ts
│ │ │ ├── OverlayTibType.ts
│ │ │ ├── PaletteType.ts
│ │ │ ├── PointerType.ts
│ │ │ ├── TerrainType.ts
│ │ │ └── TiberiumType.ts
│ │ └── util/
│ │ ├── EntityIntersectHelper.ts
│ │ ├── MapPanningHelper.ts
│ │ ├── MapTileIntersectHelper.ts
│ │ ├── RaycastHelper.ts
│ │ └── WorldViewportHelper.ts
│ ├── game/
│ │ ├── Alliances.ts
│ │ ├── AttackerInfo.ts
│ │ ├── BotManager.ts
│ │ ├── Building.ts
│ │ ├── ConstructionWorker.ts
│ │ ├── Coords.ts
│ │ ├── CountdownTimer.ts
│ │ ├── Country.ts
│ │ ├── Game.ts
│ │ ├── GameEventBus.ts
│ │ ├── GameFactory.ts
│ │ ├── GameMap.ts
│ │ ├── GameSpeed.ts
│ │ ├── GameTurnManager.ts
│ │ ├── Hashable.ts
│ │ ├── Player.ts
│ │ ├── PlayerList.ts
│ │ ├── Prng.ts
│ │ ├── SideType.ts
│ │ ├── StartingUnitsGenerator.ts
│ │ ├── SuperWeapon.ts
│ │ ├── Target.ts
│ │ ├── Traits.ts
│ │ ├── Warhead.ts
│ │ ├── Weapon.ts
│ │ ├── WeaponInfo.ts
│ │ ├── WeaponTargeting.ts
│ │ ├── WeaponType.ts
│ │ ├── World.ts
│ │ ├── action/
│ │ │ ├── Action.ts
│ │ │ ├── ActionFactory.ts
│ │ │ ├── ActionFactoryReg.ts
│ │ │ ├── ActionQueue.ts
│ │ │ ├── ActionType.ts
│ │ │ ├── ActivateSuperWeaponAction.ts
│ │ │ ├── DebugAction.ts
│ │ │ ├── DropPlayerAction.ts
│ │ │ ├── NoAction.ts
│ │ │ ├── ObserveGameAction.ts
│ │ │ ├── OrderActionContext.ts
│ │ │ ├── OrderUnitsAction.ts
│ │ │ ├── PingLocationAction.ts
│ │ │ ├── PlaceBuildingAction.ts
│ │ │ ├── ResignGameAction.ts
│ │ │ ├── SelectUnitsAction.ts
│ │ │ ├── SellObjectAction.ts
│ │ │ ├── ToggleAllianceAction.ts
│ │ │ ├── ToggleRepairAction.ts
│ │ │ ├── UpdateQueueAction.ts
│ │ │ └── factories/
│ │ │ ├── ActivateSuperWeaponActionFactory.ts
│ │ │ ├── DebugActionFactory.ts
│ │ │ ├── DropPlayerActionFactory.ts
│ │ │ ├── NoActionFactory.ts
│ │ │ ├── ObserveGameActionFactory.ts
│ │ │ ├── OrderUnitsActionFactory.ts
│ │ │ ├── PingLocationActionFactory.ts
│ │ │ ├── PlaceBuildingActionFactory.ts
│ │ │ ├── ResignGameActionFactory.ts
│ │ │ ├── SelectUnitsActionFactory.ts
│ │ │ ├── SellObjectActionFactory.ts
│ │ │ ├── ToggleAllianceFactory.ts
│ │ │ ├── ToggleRepairActionFactory.ts
│ │ │ └── UpdateQueueActionFactory.ts
│ │ ├── ai/
│ │ │ ├── Ai.ts
│ │ │ └── thirdpartbot/
│ │ │ ├── BotRegistry.ts
│ │ │ ├── BotSandbox.ts
│ │ │ ├── BotUploader.ts
│ │ │ ├── ThirdPartyBotAdapter.ts
│ │ │ ├── ThirdPartyBotInterface.ts
│ │ │ ├── builtIn/
│ │ │ │ ├── BuiltInBotAdapter.ts
│ │ │ │ ├── bot/
│ │ │ │ │ ├── bot.ts
│ │ │ │ │ ├── logic/
│ │ │ │ │ │ ├── awareness.ts
│ │ │ │ │ │ ├── building/
│ │ │ │ │ │ │ ├── antiAirStaticDefence.ts
│ │ │ │ │ │ │ ├── antiGroundStaticDefence.ts
│ │ │ │ │ │ │ ├── artilleryUnit.ts
│ │ │ │ │ │ │ ├── basicAirUnit.ts
│ │ │ │ │ │ │ ├── basicBuilding.ts
│ │ │ │ │ │ │ ├── basicGroundUnit.ts
│ │ │ │ │ │ │ ├── buildingRules.ts
│ │ │ │ │ │ │ ├── common.ts
│ │ │ │ │ │ │ ├── harvester.ts
│ │ │ │ │ │ │ ├── powerPlant.ts
│ │ │ │ │ │ │ ├── queueController.ts
│ │ │ │ │ │ │ └── resourceCollectionBuilding.ts
│ │ │ │ │ │ ├── common/
│ │ │ │ │ │ │ ├── context.ts
│ │ │ │ │ │ │ ├── rulesCache.ts
│ │ │ │ │ │ │ ├── scout.ts
│ │ │ │ │ │ │ ├── tileUtils.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── map/
│ │ │ │ │ │ │ ├── buildSpaceCache.ts
│ │ │ │ │ │ │ ├── incrementalGridCache.ts
│ │ │ │ │ │ │ ├── map.ts
│ │ │ │ │ │ │ ├── sector.ts
│ │ │ │ │ │ │ └── sectorUtils.ts
│ │ │ │ │ │ ├── mission/
│ │ │ │ │ │ │ ├── actionBatcher.ts
│ │ │ │ │ │ │ ├── mission.ts
│ │ │ │ │ │ │ ├── missionController.ts
│ │ │ │ │ │ │ └── missions/
│ │ │ │ │ │ │ ├── attackMission.ts
│ │ │ │ │ │ │ ├── baseBuildingMission.ts
│ │ │ │ │ │ │ ├── defenceMission.ts
│ │ │ │ │ │ │ ├── engineerMission.ts
│ │ │ │ │ │ │ ├── expansionMission.ts
│ │ │ │ │ │ │ ├── retreatMission.ts
│ │ │ │ │ │ │ ├── scoutingMission.ts
│ │ │ │ │ │ │ └── squads/
│ │ │ │ │ │ │ ├── combatSquad.ts
│ │ │ │ │ │ │ ├── common.ts
│ │ │ │ │ │ │ └── squad.ts
│ │ │ │ │ │ └── threat/
│ │ │ │ │ │ ├── sectorThreat.ts
│ │ │ │ │ │ ├── threat.ts
│ │ │ │ │ │ └── threatCalculator.ts
│ │ │ │ │ └── strategy/
│ │ │ │ │ ├── compositionUtils.ts
│ │ │ │ │ ├── defaultStrategy.ts
│ │ │ │ │ └── strategy.ts
│ │ │ │ └── game-api.ts
│ │ │ ├── example/
│ │ │ │ ├── README.md
│ │ │ │ └── bot.ts
│ │ │ └── index.ts
│ │ ├── api/
│ │ │ ├── ActionsApi.ts
│ │ │ ├── ChatApi.ts
│ │ │ ├── EventsApi.ts
│ │ │ ├── GameApi.ts
│ │ │ ├── LoggerApi.ts
│ │ │ ├── MapApi.ts
│ │ │ ├── ProductionApi.ts
│ │ │ ├── RulesApi.ts
│ │ │ ├── index.ts
│ │ │ └── interface/
│ │ │ ├── BuildingPlacementData.ts
│ │ │ ├── GameObjectData.ts
│ │ │ ├── PathFinderOptions.ts
│ │ │ ├── PathNode.ts
│ │ │ ├── PlayerData.ts
│ │ │ ├── PlayerStats.ts
│ │ │ ├── SuperWeaponData.ts
│ │ │ ├── TileResourceData.ts
│ │ │ └── UnitData.ts
│ │ ├── art/
│ │ │ ├── Art.ts
│ │ │ ├── FlhCoords.ts
│ │ │ ├── ObjectArt.ts
│ │ │ ├── RotorData.ts
│ │ │ ├── SequenceReader.ts
│ │ │ └── SequenceType.ts
│ │ ├── bot/
│ │ │ ├── Bot.ts
│ │ │ ├── BotFactory.ts
│ │ │ ├── BotsLib.ts
│ │ │ └── DummyBot.ts
│ │ ├── event/
│ │ │ ├── AllianceChangeEvent.ts
│ │ │ ├── BridgeRepairEvent.ts
│ │ │ ├── BuildStatusChangeEvent.ts
│ │ │ ├── BuildingCaptureEvent.ts
│ │ │ ├── BuildingEvacuateEvent.ts
│ │ │ ├── BuildingFailedPlaceEvent.ts
│ │ │ ├── BuildingGarrisonEvent.ts
│ │ │ ├── BuildingInfiltrationEvent.ts
│ │ │ ├── BuildingPlaceEvent.ts
│ │ │ ├── BuildingRepairFullEvent.ts
│ │ │ ├── BuildingRepairStartEvent.ts
│ │ │ ├── CheerEvent.ts
│ │ │ ├── CratePickupEvent.ts
│ │ │ ├── DeployNotAllowedEvent.ts
│ │ │ ├── EnterObjectEvent.ts
│ │ │ ├── EnterTileEvent.ts
│ │ │ ├── EnterTransportEvent.ts
│ │ │ ├── EventMap.ts
│ │ │ ├── EventType.ts
│ │ │ ├── FactoryProduceUnitEvent.ts
│ │ │ ├── GameEvent.ts
│ │ │ ├── HealthChangeEvent.ts
│ │ │ ├── InflictDamageEvent.ts
│ │ │ ├── InsufficientFundsEvent.ts
│ │ │ ├── LeaveTransportEvent.ts
│ │ │ ├── LightningStormCloudEvent.ts
│ │ │ ├── LightningStormManifestEvent.ts
│ │ │ ├── ObjectAttackedEvent.ts
│ │ │ ├── ObjectCloakChangeEvent.ts
│ │ │ ├── ObjectCrashingEvent.ts
│ │ │ ├── ObjectDestroyEvent.ts
│ │ │ ├── ObjectDisguiseChangeEvent.ts
│ │ │ ├── ObjectLandEvent.ts
│ │ │ ├── ObjectLiftOffEvent.ts
│ │ │ ├── ObjectMorphEvent.ts
│ │ │ ├── ObjectOwnerChangeEvent.ts
│ │ │ ├── ObjectSellEvent.ts
│ │ │ ├── ObjectSpawnEvent.ts
│ │ │ ├── ObjectTeleportEvent.ts
│ │ │ ├── ObjectUnspawnEvent.ts
│ │ │ ├── PingLocationEvent.ts
│ │ │ ├── PlayerDefeatedEvent.ts
│ │ │ ├── PlayerDroppedEvent.ts
│ │ │ ├── PlayerResignedEvent.ts
│ │ │ ├── PowerChangeEvent.ts
│ │ │ ├── PowerLowEvent.ts
│ │ │ ├── PowerRestoreEvent.ts
│ │ │ ├── PrimaryFactoryChangeEvent.ts
│ │ │ ├── RadarEvent.ts
│ │ │ ├── RadarOnOffEvent.ts
│ │ │ ├── RallyPointChangeEvent.ts
│ │ │ ├── ShipSubmergeChangeEvent.ts
│ │ │ ├── StalemateDetectEvent.ts
│ │ │ ├── SuperWeaponActivateEvent.ts
│ │ │ ├── SuperWeaponReadyEvent.ts
│ │ │ ├── TimerExpireEvent.ts
│ │ │ ├── TriggerAnimEvent.ts
│ │ │ ├── TriggerEvaEvent.ts
│ │ │ ├── TriggerSoundFxEvent.ts
│ │ │ ├── TriggerStopSoundFxEvent.ts
│ │ │ ├── TriggerTextEvent.ts
│ │ │ ├── UnitDeployUndeployEvent.ts
│ │ │ ├── UnitPromoteEvent.ts
│ │ │ ├── UnitRecycleEvent.ts
│ │ │ ├── UnitRepairFinishEvent.ts
│ │ │ ├── UnitRepairStartEvent.ts
│ │ │ ├── WarheadDetonateEvent.ts
│ │ │ └── WeaponFireEvent.ts
│ │ ├── gameobject/
│ │ │ ├── Aircraft.ts
│ │ │ ├── Bridge.ts
│ │ │ ├── Building.ts
│ │ │ ├── Debris.ts
│ │ │ ├── GameObject.ts
│ │ │ ├── Infantry.ts
│ │ │ ├── ObjectFactory.ts
│ │ │ ├── ObjectPosition.ts
│ │ │ ├── Overlay.ts
│ │ │ ├── Projectile.ts
│ │ │ ├── Smudge.ts
│ │ │ ├── Techno.ts
│ │ │ ├── Terrain.ts
│ │ │ ├── Unit.ts
│ │ │ ├── Vehicle.ts
│ │ │ ├── Weapon.ts
│ │ │ ├── common/
│ │ │ │ ├── AnimTerrainEffect.ts
│ │ │ │ └── DeathType.ts
│ │ │ ├── infantry/
│ │ │ │ ├── InfDeathType.ts
│ │ │ │ ├── StanceType.ts
│ │ │ │ └── sequenceMap.ts
│ │ │ ├── locomotor/
│ │ │ │ ├── ChronoLocomotor.ts
│ │ │ │ ├── DriveLocomotor.ts
│ │ │ │ ├── FootLocomotor.ts
│ │ │ │ ├── HoverLocomotor.ts
│ │ │ │ ├── JumpjetLocomotor.ts
│ │ │ │ ├── Locomotor.ts
│ │ │ │ ├── LocomotorFactory.ts
│ │ │ │ ├── MissileLocomotor.ts
│ │ │ │ └── WingedLocomotor.ts
│ │ │ ├── selection/
│ │ │ │ ├── SelectionLevel.ts
│ │ │ │ ├── SelectionList.ts
│ │ │ │ ├── SelectionModel.ts
│ │ │ │ ├── UnitSelection.ts
│ │ │ │ └── UnitSelectionLite.ts
│ │ │ ├── task/
│ │ │ │ ├── AttackTask.ts
│ │ │ │ ├── CaptureBuildingTask.ts
│ │ │ │ ├── CheerTask.ts
│ │ │ │ ├── EnterBuildingTask.ts
│ │ │ │ ├── EnterHospitalTask.ts
│ │ │ │ ├── EnterRecyclerTask.ts
│ │ │ │ ├── EnterTransportTask.ts
│ │ │ │ ├── EvacuateTransportTask.ts
│ │ │ │ ├── GarrisonBuildingTask.ts
│ │ │ │ ├── InfiltrateBuildingTask.ts
│ │ │ │ ├── MoveToDockTask.ts
│ │ │ │ ├── ParadropTask.ts
│ │ │ │ ├── PlantC4Task.ts
│ │ │ │ ├── RepairBuildingTask.ts
│ │ │ │ ├── ScatterTask.ts
│ │ │ │ ├── TurnTask.ts
│ │ │ │ ├── WaitForBuildUpTask.ts
│ │ │ │ ├── harvester/
│ │ │ │ │ ├── GatherOreTask.ts
│ │ │ │ │ ├── ReturnOreTask.ts
│ │ │ │ │ └── TeleportMoveToRefineryTask.ts
│ │ │ │ ├── morph/
│ │ │ │ │ ├── DeployIntoTask.ts
│ │ │ │ │ ├── MorphIntoTask.ts
│ │ │ │ │ ├── PackBuildingTask.ts
│ │ │ │ │ └── UndeployIntoTask.ts
│ │ │ │ ├── move/
│ │ │ │ │ ├── AttackMoveTargetTask.ts
│ │ │ │ │ ├── AttackMoveTask.ts
│ │ │ │ │ ├── ExitFactoryTask.ts
│ │ │ │ │ ├── MoveAsideTask.ts
│ │ │ │ │ ├── MoveInWeaponRangeTask.ts
│ │ │ │ │ ├── MoveInsideTask.ts
│ │ │ │ │ ├── MoveOutsideTask.ts
│ │ │ │ │ ├── MoveTargetTask.ts
│ │ │ │ │ ├── MoveTask.ts
│ │ │ │ │ └── MoveToBlockTask.ts
│ │ │ │ └── system/
│ │ │ │ ├── CallbackTask.ts
│ │ │ │ ├── TargetLinesConfig.ts
│ │ │ │ ├── Task.ts
│ │ │ │ ├── TaskGroup.ts
│ │ │ │ ├── TaskRunner.ts
│ │ │ │ ├── TaskStatus.ts
│ │ │ │ ├── WaitMinutesTask.ts
│ │ │ │ └── WaitTicksTask.ts
│ │ │ ├── trait/
│ │ │ │ ├── AgentTrait.ts
│ │ │ │ ├── AirSpawnTrait.ts
│ │ │ │ ├── AirportBoundTrait.ts
│ │ │ │ ├── AmmoTrait.ts
│ │ │ │ ├── ArmedTrait.ts
│ │ │ │ ├── AttackTrait.ts
│ │ │ │ ├── AutoRepairTrait.ts
│ │ │ │ ├── BridgeTrait.ts
│ │ │ │ ├── C4ChargeTrait.ts
│ │ │ │ ├── CabHutTrait.ts
│ │ │ │ ├── CloakableTrait.ts
│ │ │ │ ├── CrashableTrait.ts
│ │ │ │ ├── CrewedTrait.ts
│ │ │ │ ├── DelayedKillTrait.ts
│ │ │ │ ├── DeployerTrait.ts
│ │ │ │ ├── DisguiseTrait.ts
│ │ │ │ ├── DockTrait.ts
│ │ │ │ ├── DockableTrait.ts
│ │ │ │ ├── FactoryTrait.ts
│ │ │ │ ├── FreeUnitTrait.ts
│ │ │ │ ├── GapGeneratorTrait.ts
│ │ │ │ ├── GarrisonTrait.ts
│ │ │ │ ├── GunnerTrait.ts
│ │ │ │ ├── HarvesterTrait.ts
│ │ │ │ ├── HealthTrait.ts
│ │ │ │ ├── HelipadTrait.ts
│ │ │ │ ├── HospitalTrait.ts
│ │ │ │ ├── HoverBobTrait.ts
│ │ │ │ ├── IdleActionTrait.ts
│ │ │ │ ├── InvulnerableTrait.ts
│ │ │ │ ├── MindControllableTrait.ts
│ │ │ │ ├── MindControllerTrait.ts
│ │ │ │ ├── MissileSpawnTrait.ts
│ │ │ │ ├── MoveTrait.ts
│ │ │ │ ├── OilDerrickTrait.ts
│ │ │ │ ├── OverpoweredTrait.ts
│ │ │ │ ├── ParasiteableTrait.ts
│ │ │ │ ├── PoweredTrait.ts
│ │ │ │ ├── PsychicDetectorTrait.ts
│ │ │ │ ├── RallyTrait.ts
│ │ │ │ ├── SelfHealingTrait.ts
│ │ │ │ ├── SensorsTrait.ts
│ │ │ │ ├── SpawnDebrisTrait.ts
│ │ │ │ ├── SpawnLinkTrait.ts
│ │ │ │ ├── SubmergibleTrait.ts
│ │ │ │ ├── SuperWeaponTrait.ts
│ │ │ │ ├── SuppressionTrait.ts
│ │ │ │ ├── TemporalTrait.ts
│ │ │ │ ├── TiberiumTrait.ts
│ │ │ │ ├── TiberiumTreeTrait.ts
│ │ │ │ ├── TilterTrait.ts
│ │ │ │ ├── TntChargeTrait.ts
│ │ │ │ ├── TransportTrait.ts
│ │ │ │ ├── TurretTrait.ts
│ │ │ │ ├── UnitOrderTrait.ts
│ │ │ │ ├── UnitReloadTrait.ts
│ │ │ │ ├── UnitRepairTrait.ts
│ │ │ │ ├── UnlandableTrait.ts
│ │ │ │ ├── VeteranTrait.ts
│ │ │ │ ├── WallTrait.ts
│ │ │ │ ├── WarpedOutTrait.ts
│ │ │ │ └── interface/
│ │ │ │ ├── NotifyAttack.ts
│ │ │ │ ├── NotifyBuildStatus.ts
│ │ │ │ ├── NotifyCrash.ts
│ │ │ │ ├── NotifyDamage.ts
│ │ │ │ ├── NotifyDestroy.ts
│ │ │ │ ├── NotifyHeal.ts
│ │ │ │ ├── NotifyHealthChange.ts
│ │ │ │ ├── NotifyOrder.ts
│ │ │ │ ├── NotifyOwnerChange.ts
│ │ │ │ ├── NotifySell.ts
│ │ │ │ ├── NotifySpawn.ts
│ │ │ │ ├── NotifyTeleport.ts
│ │ │ │ ├── NotifyTick.ts
│ │ │ │ ├── NotifyTileChange.ts
│ │ │ │ ├── NotifyUnspawn.ts
│ │ │ │ └── NotifyWarpChange.ts
│ │ │ └── unit/
│ │ │ ├── CollisionHelper.ts
│ │ │ ├── CollisionType.ts
│ │ │ ├── CrateBonuses.ts
│ │ │ ├── FacingUtil.ts
│ │ │ ├── HealthLevel.ts
│ │ │ ├── LosHelper.ts
│ │ │ ├── MovePositionHelper.ts
│ │ │ ├── RangeHelper.ts
│ │ │ ├── ScatterPositionHelper.ts
│ │ │ ├── TargetUtil.ts
│ │ │ ├── Timer.ts
│ │ │ ├── VeteranAbility.ts
│ │ │ ├── VeteranLevel.ts
│ │ │ └── ZoneType.ts
│ │ ├── gameopts/
│ │ │ ├── GameOptRandomGen.ts
│ │ │ ├── GameOptSanitizer.ts
│ │ │ ├── GameOpts.ts
│ │ │ └── constants.ts
│ │ ├── ini/
│ │ │ ├── GameModeType.ts
│ │ │ ├── GameModes.ts
│ │ │ ├── MixinRules.ts
│ │ │ └── MixinRulesType.ts
│ │ ├── map/
│ │ │ ├── BridgeOverlayTypes.ts
│ │ │ ├── Bridges.ts
│ │ │ ├── MapBounds.ts
│ │ │ ├── MapShroud.ts
│ │ │ ├── OreOverlayTypes.ts
│ │ │ ├── OreSpread.ts
│ │ │ ├── Terrain.ts
│ │ │ ├── Tile.ts
│ │ │ ├── TileCollection.ts
│ │ │ ├── TileOcclusion.ts
│ │ │ ├── TileOccupation.ts
│ │ │ ├── pathFinder/
│ │ │ │ ├── NodeHeap.ts
│ │ │ │ ├── PathFinder.ts
│ │ │ │ └── SearchStatePool.ts
│ │ │ ├── tileFinder/
│ │ │ │ ├── CardinalTileFinder.ts
│ │ │ │ ├── DirectionalTileFinder.ts
│ │ │ │ ├── FloodTileFinder.ts
│ │ │ │ ├── RadialBackFirstTileFinder.ts
│ │ │ │ ├── RadialTileFinder.ts
│ │ │ │ └── RandomTileFinder.ts
│ │ │ └── wallTypes.ts
│ │ ├── math/
│ │ │ ├── Box2.ts
│ │ │ ├── CubicBezierCurve3.ts
│ │ │ ├── CurvePath.ts
│ │ │ ├── Cylindrical.ts
│ │ │ ├── Euler.ts
│ │ │ ├── GameMath.ts
│ │ │ ├── LineCurve.ts
│ │ │ ├── Matrix4.ts
│ │ │ ├── QuadraticBezierCurve.ts
│ │ │ ├── Quaternion.ts
│ │ │ ├── Spherical.ts
│ │ │ ├── Vector2.ts
│ │ │ ├── Vector3.ts
│ │ │ └── geometry.ts
│ │ ├── order/
│ │ │ ├── AttackMoveOrder.ts
│ │ │ ├── AttackOrder.ts
│ │ │ ├── CaptureOrder.ts
│ │ │ ├── CheerOrder.ts
│ │ │ ├── DeployOrder.ts
│ │ │ ├── DockOrder.ts
│ │ │ ├── EnterTransportOrder.ts
│ │ │ ├── GatherOrder.ts
│ │ │ ├── GuardAreaOrder.ts
│ │ │ ├── MoveOrder.ts
│ │ │ ├── OccupyOrder.ts
│ │ │ ├── Order.ts
│ │ │ ├── OrderFactory.ts
│ │ │ ├── OrderFeedbackType.ts
│ │ │ ├── OrderType.ts
│ │ │ ├── RepairOrder.ts
│ │ │ ├── ScatterOrder.ts
│ │ │ ├── StopOrder.ts
│ │ │ └── orderPriorities.ts
│ │ ├── player/
│ │ │ ├── PlayerFactory.ts
│ │ │ ├── production/
│ │ │ │ ├── Production.ts
│ │ │ │ └── ProductionQueue.ts
│ │ │ └── trait/
│ │ │ ├── PowerTrait.ts
│ │ │ ├── RadarTrait.ts
│ │ │ ├── SharedDetectDisguiseTrait.ts
│ │ │ └── SuperWeaponsTrait.ts
│ │ ├── rules/
│ │ │ ├── AiRules.ts
│ │ │ ├── AudioVisualRules.ts
│ │ │ ├── CombatDamageRules.ts
│ │ │ ├── CountryRules.ts
│ │ │ ├── CrateRules.ts
│ │ │ ├── DebrisRules.ts
│ │ │ ├── ElevationModelRules.ts
│ │ │ ├── GeneralRules.ts
│ │ │ ├── LandRules.ts
│ │ │ ├── MpDialogSettings.ts
│ │ │ ├── ObjectRules.ts
│ │ │ ├── ObjectRulesFactory.ts
│ │ │ ├── OverlayRules.ts
│ │ │ ├── PowerupsRules.ts
│ │ │ ├── ProjectileRules.ts
│ │ │ ├── RadiationRules.ts
│ │ │ ├── Rules.ts
│ │ │ ├── SmudgeRules.ts
│ │ │ ├── SuperWeaponRules.ts
│ │ │ ├── TechnoRules.ts
│ │ │ ├── TerrainRules.ts
│ │ │ ├── TiberiumRules.ts
│ │ │ ├── WarheadRules.ts
│ │ │ ├── WeaponRules.ts
│ │ │ ├── general/
│ │ │ │ ├── CrewRules.ts
│ │ │ │ ├── DMislRules.ts
│ │ │ │ ├── HoverRules.ts
│ │ │ │ ├── LightningStormRules.ts
│ │ │ │ ├── MissileRules.ts
│ │ │ │ ├── ParadropRules.ts
│ │ │ │ ├── PrismRules.ts
│ │ │ │ ├── RadarRules.ts
│ │ │ │ ├── RepairRules.ts
│ │ │ │ ├── ThreatRules.ts
│ │ │ │ ├── V3RocketRules.ts
│ │ │ │ └── VeteranRules.ts
│ │ │ └── mpAllowedColors.ts
│ │ ├── superweapon/
│ │ │ ├── ChronoSphereEffect.ts
│ │ │ ├── IronCurtainEffect.ts
│ │ │ ├── LightningStormEffect.ts
│ │ │ ├── NukeEffect.ts
│ │ │ ├── ParadropEffect.ts
│ │ │ └── SuperWeaponEffect.ts
│ │ ├── theater/
│ │ │ ├── AutoLat.ts
│ │ │ ├── TileSet.ts
│ │ │ ├── TileSetAnim.ts
│ │ │ ├── TileSetEntry.ts
│ │ │ ├── TileSets.ts
│ │ │ └── rampHeights.ts
│ │ ├── trait/
│ │ │ ├── CrateGeneratorTrait.ts
│ │ │ ├── MapLightingTrait.ts
│ │ │ ├── MapRadiationTrait.ts
│ │ │ ├── MapShroudTrait.ts
│ │ │ ├── PowerTrait.ts
│ │ │ ├── ProductionTrait.ts
│ │ │ ├── RadarTrait.ts
│ │ │ ├── SellTrait.ts
│ │ │ ├── SharedDetectCloakTrait.ts
│ │ │ ├── SharedDetectDisguiseTrait.ts
│ │ │ ├── StalemateDetectTrait.ts
│ │ │ ├── SuperWeaponsTrait.ts
│ │ │ └── interface/
│ │ │ ├── NotifyAllianceChange.ts
│ │ │ ├── NotifyAttack.ts
│ │ │ ├── NotifyDestroy.ts
│ │ │ ├── NotifyElevationChange.ts
│ │ │ ├── NotifyHealthChange.ts
│ │ │ ├── NotifyObjectTraitAdd.ts
│ │ │ ├── NotifyOwnerChange.ts
│ │ │ ├── NotifyPlaceBuilding.ts
│ │ │ ├── NotifyPower.ts
│ │ │ ├── NotifyProduceUnit.ts
│ │ │ ├── NotifySpawn.ts
│ │ │ ├── NotifySuperWeaponActivate.ts
│ │ │ ├── NotifySuperWeaponDeactivate.ts
│ │ │ ├── NotifyTargetDestroy.ts
│ │ │ ├── NotifyTick.ts
│ │ │ ├── NotifyTileChange.ts
│ │ │ ├── NotifyUnspawn.ts
│ │ │ └── NotifyWarpChange.ts
│ │ ├── trigger/
│ │ │ ├── TriggerCondition.ts
│ │ │ ├── TriggerConditionFactory.ts
│ │ │ ├── TriggerExecutor.ts
│ │ │ ├── TriggerExecutorFactory.ts
│ │ │ ├── TriggerInstance.ts
│ │ │ ├── TriggerManager.ts
│ │ │ ├── TriggerTarget.ts
│ │ │ ├── condition/
│ │ │ │ ├── AmbientLightCondition.ts
│ │ │ │ ├── AnyEventCondition.ts
│ │ │ │ ├── AttackedByAnyCondition.ts
│ │ │ │ ├── AttackedByHouseCondition.ts
│ │ │ │ ├── BuildObjectTypeCondition.ts
│ │ │ │ ├── BuildingExistsCondition.ts
│ │ │ │ ├── ComesNearWaypointCondition.ts
│ │ │ │ ├── CreditsBelowCondition.ts
│ │ │ │ ├── CreditsExceedCondition.ts
│ │ │ │ ├── CrossHorizLineCondition.ts
│ │ │ │ ├── CrossVertLineCondition.ts
│ │ │ │ ├── DestroyedAllBuildingsCondition.ts
│ │ │ │ ├── DestroyedAllCondition.ts
│ │ │ │ ├── DestroyedAllUnitsCondition.ts
│ │ │ │ ├── DestroyedAllUnitsLandCondition.ts
│ │ │ │ ├── DestroyedAllUnitsNavalCondition.ts
│ │ │ │ ├── DestroyedBridgeCondition.ts
│ │ │ │ ├── DestroyedBuildingsCondition.ts
│ │ │ │ ├── DestroyedByAnyCondition.ts
│ │ │ │ ├── DestroyedOrCapturedCondition.ts
│ │ │ │ ├── DestroyedOrCapturedOrInfiltratedCondition.ts
│ │ │ │ ├── DestroyedUnitsCondition.ts
│ │ │ │ ├── ElapsedScenarioTimeCondition.ts
│ │ │ │ ├── ElapsedTimeCondition.ts
│ │ │ │ ├── EnteredByCondition.ts
│ │ │ │ ├── GlobalVariableCondition.ts
│ │ │ │ ├── HealthBelowAnyCondition.ts
│ │ │ │ ├── HealthBelowCombatCondition.ts
│ │ │ │ ├── LocalVariableCondition.ts
│ │ │ │ ├── LowPowerCondition.ts
│ │ │ │ ├── NoEventCondition.ts
│ │ │ │ ├── NoFactoriesLeftCondition.ts
│ │ │ │ ├── PickupCrateAnyCondition.ts
│ │ │ │ ├── PickupCrateCondition.ts
│ │ │ │ ├── RandomDelayCondition.ts
│ │ │ │ ├── SpiedByCondition.ts
│ │ │ │ ├── SpyEnteringAsHouseCondition.ts
│ │ │ │ ├── SpyEnteringAsInfantryCondition.ts
│ │ │ │ └── TimerExpiredCondition.ts
│ │ │ └── executor/
│ │ │ ├── AddSuperWeaponExecutor.ts
│ │ │ ├── ApplyDamageExecutor.ts
│ │ │ ├── ChangeHouseAllExecutor.ts
│ │ │ ├── ChangeHouseExecutor.ts
│ │ │ ├── CheerExecutor.ts
│ │ │ ├── CreateCrateExecutor.ts
│ │ │ ├── CreateRadarEventExecutor.ts
│ │ │ ├── DestroyObjectExecutor.ts
│ │ │ ├── DestroyTagExecutor.ts
│ │ │ ├── DestroyTriggerExecutor.ts
│ │ │ ├── DetonateWarheadExecutor.ts
│ │ │ ├── EvictOccupiersExecutor.ts
│ │ │ ├── FireSaleExecutor.ts
│ │ │ ├── ForceEndExecutor.ts
│ │ │ ├── ForceTriggerExecutor.ts
│ │ │ ├── GlobalVariableExecutor.ts
│ │ │ ├── IronCurtainExecutor.ts
│ │ │ ├── LightningStrikeExecutor.ts
│ │ │ ├── LocalVariableExecutor.ts
│ │ │ ├── NoActionExecutor.ts
│ │ │ ├── NukeStrikeExecutor.ts
│ │ │ ├── PlayAnimAtExecutor.ts
│ │ │ ├── PlaySoundFxAtExecutor.ts
│ │ │ ├── PlaySoundFxExecutor.ts
│ │ │ ├── PlaySpeechExecutor.ts
│ │ │ ├── ReshroudMapExecutor.ts
│ │ │ ├── ResizePlayerViewExecutor.ts
│ │ │ ├── RevealAroundWaypointExecutor.ts
│ │ │ ├── RevealMapExecutor.ts
│ │ │ ├── SellBuildingExecutor.ts
│ │ │ ├── SetAmbientLightExecutor.ts
│ │ │ ├── SetAmbientRateExecutor.ts
│ │ │ ├── SetAmbientStepExecutor.ts
│ │ │ ├── StopSoundFxAtExecutor.ts
│ │ │ ├── TextTriggerExecutor.ts
│ │ │ ├── TimerExtendExecutor.ts
│ │ │ ├── TimerSetExecutor.ts
│ │ │ ├── TimerShortenExecutor.ts
│ │ │ ├── TimerStartExecutor.ts
│ │ │ ├── TimerStopExecutor.ts
│ │ │ ├── TimerTextExecutor.ts
│ │ │ ├── ToggleTriggerExecutor.ts
│ │ │ ├── TurnOnOffBuildingExecutor.ts
│ │ │ └── UnrevealAroundWaypointExecutor.ts
│ │ └── type/
│ │ ├── ArmorType.ts
│ │ ├── LandTargeting.ts
│ │ ├── LandType.ts
│ │ ├── LocomotorType.ts
│ │ ├── MovementZone.ts
│ │ ├── NavalTargeting.ts
│ │ ├── PipColor.ts
│ │ ├── PowerupType.ts
│ │ ├── SpeedType.ts
│ │ ├── SuperWeaponType.ts
│ │ └── VhpScan.ts
│ ├── gui/
│ │ ├── CanvasMetrics.ts
│ │ ├── FullScreen.ts
│ │ ├── HtmlContainer.ts
│ │ ├── HtmlReactElement.ts
│ │ ├── HtmlReactElement.tsx
│ │ ├── LazyHtmlElement.ts
│ │ ├── MobileTouchControls.ts
│ │ ├── Pointer.ts
│ │ ├── PointerEvents.ts
│ │ ├── PointerSprite.ts
│ │ ├── ReactFormat.tsx
│ │ ├── ReplayManager.ts
│ │ ├── ShpSpriteBatch.ts
│ │ ├── UiObject.ts
│ │ ├── UiObjectSprite.ts
│ │ ├── UiScene.ts
│ │ ├── Viewport.ts
│ │ ├── chat/
│ │ │ ├── ChatHistory.ts
│ │ │ └── ChatMessageFormat.tsx
│ │ ├── component/
│ │ │ ├── BasicErrorBoxApi.tsx
│ │ │ ├── BotUploadDialog.tsx
│ │ │ ├── ButtonSelect.tsx
│ │ │ ├── ChannelOpIndicator.tsx
│ │ │ ├── ChannelUser.tsx
│ │ │ ├── Chat.tsx
│ │ │ ├── ChatInput.tsx
│ │ │ ├── ColorSelect.tsx
│ │ │ ├── CountryIcon.tsx
│ │ │ ├── CountrySelect.tsx
│ │ │ ├── Dialog.tsx
│ │ │ ├── GameResBoxApi.tsx
│ │ │ ├── GameResForm.tsx
│ │ │ ├── GameResourcesViewer.tsx
│ │ │ ├── Image.tsx
│ │ │ ├── ImageContext.tsx
│ │ │ ├── List.tsx
│ │ │ ├── MenuButton.tsx
│ │ │ ├── MenuVideo.tsx
│ │ │ ├── MessageBoxApi.tsx
│ │ │ ├── Option.tsx
│ │ │ ├── PingIndicator.tsx
│ │ │ ├── PromptDialog.tsx
│ │ │ ├── Select.tsx
│ │ │ ├── Slider.tsx
│ │ │ ├── SplashScreen.tsx
│ │ │ ├── StartPosSelect.tsx
│ │ │ ├── TeamSelect.tsx
│ │ │ ├── ToastApi.tsx
│ │ │ ├── Toasts.tsx
│ │ │ ├── UiText.tsx
│ │ │ └── fileExplorer/
│ │ │ ├── StorageFileExplorer.css
│ │ │ └── StorageFileExplorer.tsx
│ │ ├── jsx/
│ │ │ ├── HtmlView.ts
│ │ │ ├── JsxRenderer.ts
│ │ │ ├── UiComponent.ts
│ │ │ └── jsx.ts
│ │ ├── replay/
│ │ │ ├── ReplayExistsError.ts
│ │ │ ├── ReplayMeta.ts
│ │ │ ├── ReplayStorage.ts
│ │ │ ├── ReplayStorageError.ts
│ │ │ ├── ReplayStorageFileSystem.ts
│ │ │ ├── ReplayStorageMemStorage.ts
│ │ │ └── ReplayStorageMigration.ts
│ │ └── screen/
│ │ ├── Controller.ts
│ │ ├── RootController.ts
│ │ ├── RootRoute.ts
│ │ ├── RootScreen.ts
│ │ ├── Screen.ts
│ │ ├── ScreenType.ts
│ │ ├── game/
│ │ │ ├── ChatNetHandler.ts
│ │ │ ├── ChatTypingHandler.ts
│ │ │ ├── CombatantUi.tsx
│ │ │ ├── GameLoader.ts
│ │ │ ├── GameMenu.ts
│ │ │ ├── GameMenuScreen.ts
│ │ │ ├── GameScreen.ts
│ │ │ ├── HudFactory.ts
│ │ │ ├── MapFileLoader.ts
│ │ │ ├── MedianPing.ts
│ │ │ ├── NetStats.ts
│ │ │ ├── ObserverUi.ts
│ │ │ ├── PingMonitor.ts
│ │ │ ├── PlayerUi.ts
│ │ │ ├── SoundHandler.ts
│ │ │ ├── TauntHandler.ts
│ │ │ ├── TauntPlayback.ts
│ │ │ ├── TooltipTextResolver.ts
│ │ │ ├── WorldView.ts
│ │ │ ├── component/
│ │ │ │ ├── GameResultPopup.ts
│ │ │ │ ├── Hud.ts
│ │ │ │ ├── Minimap.tsx
│ │ │ │ ├── MinimapPing.ts
│ │ │ │ └── hud/
│ │ │ │ ├── DebugText.ts
│ │ │ │ ├── GameMenuContentArea.ts
│ │ │ │ ├── HudChat.tsx
│ │ │ │ ├── Messages.ts
│ │ │ │ ├── ReplayStatsOverlay.ts
│ │ │ │ ├── SidebarCard.ts
│ │ │ │ ├── SidebarCredits.ts
│ │ │ │ ├── SidebarGameTime.ts
│ │ │ │ ├── SidebarIconButton.ts
│ │ │ │ ├── SidebarMenu.ts
│ │ │ │ ├── SidebarPower.ts
│ │ │ │ ├── SidebarRadar.ts
│ │ │ │ ├── SidebarRadarAnimRunner.ts
│ │ │ │ ├── SidebarTabs.ts
│ │ │ │ ├── SuperWeaponTimers.ts
│ │ │ │ ├── commandBar/
│ │ │ │ │ ├── CommandBarButtonList.ts
│ │ │ │ │ ├── CommandBarButtonType.ts
│ │ │ │ │ ├── CommandButtonConfig.ts
│ │ │ │ │ └── commandButtonConfigs.ts
│ │ │ │ └── viewmodel/
│ │ │ │ ├── CombatantSidebarModel.ts
│ │ │ │ ├── MessageList.ts
│ │ │ │ ├── SidebarModel.ts
│ │ │ │ └── SidebarTab.ts
│ │ │ ├── gameMenu/
│ │ │ │ ├── ConInfoForm.tsx
│ │ │ │ ├── ConnectionInfoScreen.ts
│ │ │ │ ├── DiploForm.tsx
│ │ │ │ ├── DiploScreen.ts
│ │ │ │ ├── GameMenuController.ts
│ │ │ │ ├── GameMenuHomeScreen.ts
│ │ │ │ ├── QuitConfirmScreen.ts
│ │ │ │ ├── ScreenParamsMap.ts
│ │ │ │ └── ScreenType.ts
│ │ │ ├── loadingScreen/
│ │ │ │ ├── LanLoadingScreenApi.ts
│ │ │ │ ├── LoadingScreen.tsx
│ │ │ │ ├── LoadingScreenApi.ts
│ │ │ │ ├── LoadingScreenApiFactory.ts
│ │ │ │ ├── LoadingScreenWrapper.tsx
│ │ │ │ ├── MpLoadingScreenApi.ts
│ │ │ │ ├── ReplayLoadingScreenApi.ts
│ │ │ │ └── SpLoadingScreenApi.ts
│ │ │ └── worldInteraction/
│ │ │ ├── ArrowScrollHandler.ts
│ │ │ ├── BeaconMode.ts
│ │ │ ├── CameraPanHandler.ts
│ │ │ ├── CustomScrollHandler.ts
│ │ │ ├── DefaultActionHandler.ts
│ │ │ ├── InteractionMode.ts
│ │ │ ├── MapHoverHandler.ts
│ │ │ ├── MapScrollHandler.ts
│ │ │ ├── MinimapHandler.ts
│ │ │ ├── PendingPlacementHandler.ts
│ │ │ ├── PlacementMode.ts
│ │ │ ├── PlanningMode.ts
│ │ │ ├── RepairMode.ts
│ │ │ ├── SellMode.ts
│ │ │ ├── SpecialActionMode.ts
│ │ │ ├── Tooltip.ts
│ │ │ ├── TooltipHandler.ts
│ │ │ ├── UnitSelectionHandler.ts
│ │ │ ├── WorldInteraction.ts
│ │ │ ├── WorldInteractionFactory.ts
│ │ │ ├── keyboard/
│ │ │ │ ├── KeyBinds.ts
│ │ │ │ ├── KeyCommand.ts
│ │ │ │ ├── KeyCommandType.ts
│ │ │ │ ├── KeyboardHandler.ts
│ │ │ │ └── command/
│ │ │ │ ├── CenterBaseCmd.ts
│ │ │ │ ├── CenterGroupCmd.ts
│ │ │ │ ├── CenterViewCmd.ts
│ │ │ │ ├── FollowUnitCmd.ts
│ │ │ │ ├── GoToCameraLocationCmd.ts
│ │ │ │ ├── LastRadarEventCmd.ts
│ │ │ │ ├── SelectGroupCmd.ts
│ │ │ │ ├── SelectNextUnitCmd.ts
│ │ │ │ ├── SelectPlayerCmd.ts
│ │ │ │ ├── SelectTypeByCmd.ts
│ │ │ │ └── SetCameraLocationCmd.ts
│ │ │ └── placementMode/
│ │ │ ├── PlacementGrid.ts
│ │ │ └── PlacementGridModel.ts
│ │ ├── mainMenu/
│ │ │ ├── MainMenuController.ts
│ │ │ ├── MainMenuRootScreen.ts
│ │ │ ├── MainMenuRoute.ts
│ │ │ ├── MainMenuScreen.ts
│ │ │ ├── ScreenType.ts
│ │ │ ├── component/
│ │ │ │ ├── Iframe.tsx
│ │ │ │ ├── MainMenu.ts
│ │ │ │ ├── MenuMpSlotAnimRunner.ts
│ │ │ │ ├── MenuMpSlotText.tsx
│ │ │ │ ├── MenuSdTopAnimRunner.ts
│ │ │ │ ├── MenuSlotAnimationRunner.ts
│ │ │ │ ├── MenuTooltip.tsx
│ │ │ │ ├── MenuVideo.tsx
│ │ │ │ ├── PrefetchProgress.tsx
│ │ │ │ ├── SidebarPreview.tsx
│ │ │ │ ├── SidebarTitle.tsx
│ │ │ │ ├── VersionString.tsx
│ │ │ │ └── viewmodel/
│ │ │ │ └── MenuButtonConfig.ts
│ │ │ ├── credits/
│ │ │ │ ├── Credits.tsx
│ │ │ │ └── CreditsScreen.ts
│ │ │ ├── customGame/
│ │ │ │ ├── CustomGameScreen.ts
│ │ │ │ └── component/
│ │ │ │ └── GameBrowser.tsx
│ │ │ ├── infoAndCredits/
│ │ │ │ └── InfoAndCreditsScreen.ts
│ │ │ ├── ladder/
│ │ │ │ ├── LadderScreen.ts
│ │ │ │ └── component/
│ │ │ │ └── Ladder.tsx
│ │ │ ├── ladderRules/
│ │ │ │ └── LadderRulesScreen.ts
│ │ │ ├── lan/
│ │ │ │ ├── LanRecentPlay.ts
│ │ │ │ ├── LanSetupScreen.ts
│ │ │ │ └── component/
│ │ │ │ ├── LanSetup.tsx
│ │ │ │ ├── QrCodeCard.tsx
│ │ │ │ └── QrScannerPanel.tsx
│ │ │ ├── lobby/
│ │ │ │ ├── LobbyScreen.ts
│ │ │ │ ├── MapPreviewRenderer.ts
│ │ │ │ ├── PreferredHostOpts.ts
│ │ │ │ ├── PregameController.ts
│ │ │ │ ├── SelectMapParams.ts
│ │ │ │ ├── SkirmishScreen.ts
│ │ │ │ └── component/
│ │ │ │ ├── CreateGameBox.tsx
│ │ │ │ ├── LobbyForm.tsx
│ │ │ │ ├── PasswordBox.tsx
│ │ │ │ ├── RankIndicator.tsx
│ │ │ │ └── viewmodel/
│ │ │ │ └── lobby.ts
│ │ │ ├── login/
│ │ │ │ ├── LoginBox.tsx
│ │ │ │ ├── LoginScreen.ts
│ │ │ │ ├── ServerList.tsx
│ │ │ │ ├── ServerPingIndicator.tsx
│ │ │ │ └── ServerPings.ts
│ │ │ ├── main/
│ │ │ │ ├── HomeScreen.ts
│ │ │ │ ├── ReportBug.tsx
│ │ │ │ └── TestEntryScreen.ts
│ │ │ ├── mapSel/
│ │ │ │ ├── MapSelScreen.ts
│ │ │ │ └── component/
│ │ │ │ └── MapSel.tsx
│ │ │ ├── modSel/
│ │ │ │ ├── BadModArchiveError.ts
│ │ │ │ ├── DuplicateModError.ts
│ │ │ │ ├── Mod.ts
│ │ │ │ ├── ModDetailsPane.tsx
│ │ │ │ ├── ModDownloadPrompt.tsx
│ │ │ │ ├── ModImporter.ts
│ │ │ │ ├── ModManager.ts
│ │ │ │ ├── ModMeta.ts
│ │ │ │ ├── ModSel.tsx
│ │ │ │ ├── ModSelScreen.ts
│ │ │ │ └── ModStatus.ts
│ │ │ ├── newAccount/
│ │ │ │ ├── NewAccountBox.tsx
│ │ │ │ └── NewAccountScreen.ts
│ │ │ ├── patchNotes/
│ │ │ │ └── PatchNotesScreen.ts
│ │ │ ├── quickGame/
│ │ │ │ ├── ChatUi.ts
│ │ │ │ ├── QuickGameScreen.ts
│ │ │ │ └── component/
│ │ │ │ ├── QuickGameChat.tsx
│ │ │ │ └── QuickGameForm.tsx
│ │ │ └── score/
│ │ │ ├── ScoreScreen.ts
│ │ │ └── ScoreTable.tsx
│ │ ├── options/
│ │ │ ├── GeneralOptions.ts
│ │ │ ├── GraphicsOptions.ts
│ │ │ ├── KeyboardScreen.ts
│ │ │ ├── OptionsScreen.ts
│ │ │ ├── SoundOptsScreen.ts
│ │ │ ├── StorageScreen.ts
│ │ │ └── component/
│ │ │ ├── GeneralOpts.tsx
│ │ │ ├── KeyOpts.tsx
│ │ │ ├── MusicJukebox.tsx
│ │ │ ├── PressKeyInput.tsx
│ │ │ ├── Resolution.tsx
│ │ │ ├── SoundOpts.tsx
│ │ │ ├── StorageExplorer.tsx
│ │ │ ├── configurableCmds.ts
│ │ │ └── getHumanReadableKey.ts
│ │ └── replay/
│ │ ├── KeepReplayBox.tsx
│ │ ├── ReplayDetailsPane.tsx
│ │ ├── ReplayScreen.ts
│ │ ├── ReplaySel.tsx
│ │ ├── ReplaySelScreen.ts
│ │ └── StorageWarning.tsx
│ ├── main.tsx
│ ├── network/
│ │ ├── HttpRequest.ts
│ │ ├── IrcConnection.ts
│ │ ├── WolConnection.ts
│ │ ├── WolGameReport.ts
│ │ ├── chat/
│ │ │ └── ChatMessage.ts
│ │ ├── gameopt/
│ │ │ ├── FileNameEncoder.ts
│ │ │ ├── LoadInfoParser.ts
│ │ │ ├── MapNameLegacyEncoder.ts
│ │ │ ├── Parser.ts
│ │ │ ├── Serializer.ts
│ │ │ └── SlotInfo.ts
│ │ ├── gamestate/
│ │ │ ├── PlayerConnectionStatus.ts
│ │ │ ├── Replay.ts
│ │ │ ├── ReplayRecorder.ts
│ │ │ ├── ReplayTurnManager.ts
│ │ │ ├── SoloPlayTurnManager.ts
│ │ │ └── replay/
│ │ │ ├── ChatMessageReplayEvent.ts
│ │ │ └── TauntReplayEvent.ts
│ │ ├── gservConfig.ts
│ │ ├── ladder/
│ │ │ ├── LadderHead.ts
│ │ │ ├── PagedResponse.ts
│ │ │ ├── PlayerLadderRung.ts
│ │ │ ├── PlayerProfile.ts
│ │ │ ├── PlayerRankType.ts
│ │ │ ├── WLadderService.ts
│ │ │ └── wladderConfig.ts
│ │ └── lan/
│ │ ├── LanLockstepTurnManager.ts
│ │ ├── LanMatchSession.ts
│ │ ├── LanMeshSession.ts
│ │ ├── LanQrPayload.ts
│ │ ├── LanRoomSession.ts
│ │ ├── ManualSdpLanSession.ts
│ │ └── SdpCandidateDiagnostics.ts
│ ├── performance/
│ │ ├── PerformanceOptions.ts
│ │ └── PerformanceRuntime.ts
│ ├── setupThreeGlobal.ts
│ ├── test/
│ │ └── performance/
│ │ ├── GeneralOptions.test.ts
│ │ └── PerformanceHelpers.test.ts
│ ├── tools/
│ │ ├── AircraftTester.ts
│ │ ├── BuildingTester.ts
│ │ ├── CameraZoomControls.ts
│ │ ├── DevToolsApi.ts
│ │ ├── InfantryTester.ts
│ │ ├── LiveInteractionTester.ts
│ │ ├── LobbyFormTester.ts
│ │ ├── PerformanceTester.ts
│ │ ├── ShpTester.ts
│ │ ├── SoundTester.ts
│ │ ├── TestToolSupport.ts
│ │ ├── UnitMovementTester.ts
│ │ ├── VehicleTester.ts
│ │ ├── VxlTester.ts
│ │ └── WorldSceneTester.ts
│ ├── types/
│ │ ├── game.d.ts
│ │ └── global.d.ts
│ ├── util/
│ │ ├── Base64.ts
│ │ ├── BoxedVar.ts
│ │ ├── Color.ts
│ │ ├── CssLoader.ts
│ │ ├── Graph.ts
│ │ ├── PointerLock.ts
│ │ ├── QuadTree.ts
│ │ ├── Routing.ts
│ │ ├── ScriptLoader.ts
│ │ ├── Sentry.ts
│ │ ├── Serializable.ts
│ │ ├── array.ts
│ │ ├── bresenham.ts
│ │ ├── disposable/
│ │ │ ├── CompositeDisposable.ts
│ │ │ ├── Disposable.ts
│ │ │ └── LegacyDisposable.ts
│ │ ├── dom.ts
│ │ ├── event.ts
│ │ ├── format.ts
│ │ ├── fullScreen.ts
│ │ ├── geometry.ts
│ │ ├── keyNames.ts
│ │ ├── logger.ts
│ │ ├── math.ts
│ │ ├── mouse.ts
│ │ ├── number.ts
│ │ ├── stream.ts
│ │ ├── string.ts
│ │ ├── time.ts
│ │ ├── typeGuard.ts
│ │ └── userAgent.ts
│ ├── version.ts
│ └── vite-env.d.ts
├── tsconfig.build.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
docs/
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
public/cdn/
.artifacts/
scripts/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarnclean
# dotenv environment variables file
.env
.env.*
!.env.example
# parcel-bundler cache files
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Docusaurus cache and build output
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# IDE files
.idea/
.vscode/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# macOS
.DS_Store
# Vite build output
dist
# Temporary test files
__test_strip.mjs
__stripped_output.js
_temp_builtIn/
#शंकर
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# RA2WEB React
免责声明:这是基于《时空分裂》中文版RA2WEB www.ra2web.com 的分析而开发,并意图基于最新的react和three版本进行重构。
但项目所有权利(包括收益权)归《时空分裂》/RA2WEB负责人所有。未经《时空分裂》的所有者/RA2WEB负责人许可,严禁用于任何商业行为。
需要注意的是,《时空分裂》的所有者从未以任何方式开源游戏客户端代码(即便存在诸如mod-sdk之类的周边开源内容)。本项目运行产生的BUG、功能不完善,不能等同视为对《时空分裂》的名誉贬损。任何基于本项目开展商业行为,包括但不限于植入广告、开发“弹幕红警”收受礼物获利、直接封装收费、以“作者”身份骗取赞助和充电收益等,均视为对《时空分裂》原作者Alexandru Ciucă和RA2WEB的侵权。
红色警戒2网页版,一款经典的即时战略类游戏的完整TypeScript重构版本,使用React + TypeScript + Vite + Three.js构建。

Disclaimer
This project is developed based on the analysis of the Chinese version of Chronodivide — RA2WEB (www.ra2web.com), and is intended to be refactored using the latest versions of React and Three.js. All rights to this project, including profit rights, belong to the owner of Chronodivide. Without permission from the owner of Chronodivide, any commercial use of this project is strictly prohibited.
It should be noted that the owner of Chronodivide has never open-sourced the game client code in any form, even though some peripheral open‑source content such as a mod‑SDK exists. Bugs, incomplete functions or other issues arising from the operation of this project shall not be regarded as damage to the reputation of Chronodivide. Any commercial activities conducted based on this project, including but not limited to placing advertisements, developing a “bullet-screen Red Alert” mode to profit from gifts, directly packaging and selling the project, or fraudulently obtaining sponsorship and donation revenue by claiming to be the “author”, shall be deemed as infringement upon the original author of Chronodivide, Alexandru Ciucă, and RA2WEB.



## 项目简介
本项目是使用Typescript编写,完全对标“红色警戒2”的游戏引擎,本地自行导入红色警戒2美术素材后,就可以获得类似红警2的游玩体验
## 当前技术状态
### 运行时和构建
- 包管理与本地运行时:`Bun 1.3.10`
- 开发服务器:`Vite 8.0.1`
- UI:`React 19.2.4` + `react-dom 19.2.4`
- 类型系统:`TypeScript 5.9.3`
- 渲染:`three 0.183.2`
- 自动化:`Playwright 1.58.2`
- 默认开发和预览端口:`127.0.0.1:4000`
## 快速开始
### 环境要求
- `Bun 1.3+`
- 现代浏览器,推荐 Chrome / Edge
- 浏览器需要支持:
- `WebGL`
- `Web Audio API`
- `File System Access API`
### 安装与启动
```bash
cd redalert2
bun install
bun run dev
```
默认访问地址:
```text
http://127.0.0.1:4000
```
生产构建与预览:
```bash
bun run build
bun run preview
```
类型检查:
```bash
bun run typecheck:entry
```
## 自动化回归
仓库当前已经不再只依赖手点验证。`scripts/` 下维护了一组可直接执行的回归脚本,主要覆盖大厅、进图、机制和 tester 入口。
常用命令包括:
```bash
bun run debug:game-res-init
bun run debug:viewport
bun run debug:options
bun run debug:storage-explorer
bun run debug:skirmish
bun run debug:skirmish-lobby-data
bun run debug:victory-exit
bun run debug:superweapon
bun run debug:nuke
bun run debug:radiation
bun run debug:minimap-shroud
bun run debug:anti-air-hit
bun run debug:terror-drone
bun run debug:chrono-legionnaire
bun run debug:test-entries
bun run debug:tester-panels
```
这些脚本的产物默认会写入 `.artifacts/`,便于回看截图和 JSON 结果。
## 测试入口
主菜单中的测试入口目前分为三类:
1. 素材测试
- `VXL测试`
- `SHP测试`
- `音频测试`
2. 机制测试
- `建筑测试`
- `载具测试`
- `步兵测试`
- `飞行器测试`
3. 场景测试
- `大厅测试`
- `世界测试`
- `移动测试`
这些 tester 页面不是孤立 Demo,而是当前仓库里很重要的调试和回归入口。页面左侧面板状态会同步到调试状态对象,自动化脚本也会直接使用这些入口验证渲染和交互结果。
## 技术架构
### 核心技术栈
- `React 19.2.4`
- `TypeScript 5.9.3`
- `Vite 8.0.1`
- `three 0.183.2`
- `Bun 1.3.10`
- `Playwright 1.58.2`
- `7z-wasm`
- `file-system-access`
- `@ffmpeg/ffmpeg`
- `@ra2web/pcxfile`
- `@ra2web/wavefile`
### 目录说明
```text
redalert2/
├── public/ 静态资源、配置、locale、遗留样式
├── scripts/ Playwright 自动化回归脚本
├── src/
│ ├── data/ 原版资源格式、编码、地图、VFS
│ ├── engine/ 渲染、音频、资源加载、底层引擎能力
│ ├── game/ 游戏逻辑、对象系统、触发器、规则、超武
│ ├── gui/ 主菜单、HUD、选项、游戏内 UI
│ ├── network/ 网络和联机相关基础设施
│ ├── tools/ 独立 tester 页面
│ └── util/ 通用工具
├── docs/ 对齐记录与工程说明
└── vite.config.ts 开发和构建配置
```
### 主要模块
`src/engine/`
- `gfx/`:three 渲染层、材质、批处理、viewport、lighting
- `renderable/`:游戏对象到可视对象的桥接层
- `sound/`:音频混音、音乐、音效播放
- `gameRes/`:资源导入、CDN 加载、缓存与目录处理
`src/game/`
- `gameobject/`:单位、建筑、抛射体、trait、locomotor
- `rules/`:INI 规则读取与对象规则构建
- `trigger/`:地图触发器、条件、执行器
- `superweapon/`:核弹、闪电风暴、超时空等超武逻辑
`src/gui/`
- `screen/mainMenu/`:主菜单、地图选择、大厅、选项
- `screen/game/`:游戏内 HUD、世界交互、菜单
- `component/`:React 组件
- `jsx/`:自定义 UI 渲染桥接
`src/tools/`
- 提供素材、机制、场景三类 tester 页面
- 当前是调试结果可视化和自动化断言的重要入口
## 开发命令
```bash
bun run dev
bun run build
bun run preview
bun run typecheck:entry
```
## 文档与调试约定
- 开发端口固定为 `4000`
- 主要技术对齐记录维护在 `docs/build-alignment-log.md`
- 自动化产物默认输出到 `.artifacts/`
- 构建通过并不等于所有行为已完全对齐,功能层面仍应优先参考专项脚本和实际流程验证
## 贡献建议
提交改动前,至少建议执行:
```bash
bun run typecheck:entry
bun run build
```
如果改动涉及大厅、资源加载、进图、HUD、机制或 tester,请补跑相应的 `debug:*` 脚本。
## 许可证
本项目基于GNU General Public License v3.0(GPL-3.0)许可证开源。详见 [LICENSE](LICENSE) 文件。
### 重要说明
- 可以自由使用、修改和分发,除非取得RA2WEB负责人许可,否则严禁用于商业目的
- 必须保留版权声明和许可证文本
- 任何衍生作品必须使用相同的 GPL-3.0 许可证
- 必须提供源代码,包括修改后的版本
- 不能将 GPL 代码集成到专有软件中
**注意:** 本项目仅用于学习和研究目的。红色警戒2是EA公司的知识产权,导入美术素材时请确保拥有合法的游戏副本。
## 致谢
- RA2WEB.COM
- Three.js 社区
- React 团队
- TypeScript 团队
- 相关开源依赖维护者
- 红警 2 玩家社区
---
**免责声明**: 本项目仅供学习研究使用,不用于商业目的。红色警戒2及相关商标归EA公司所有。
---
================================================
FILE: index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>网页红井-联机对战平台</title>
<meta name="keywords"
content="红色警戒下载, 如何玩红警, webra2, 苹果如何玩红警, 平板上如何玩红警, 手机上如何玩红警, win7如何玩红警, win10如何玩红警, win11如何玩红警, 红警, 红警2, 红色警戒2, 网页红警, 云红警, 在线游戏, 游戏平台,对战平台,战网, 红色警戒3, 红警3, RA2, RA2WEB" />
<meta name="description" content="在网页上就能玩经典的红色井界游戏,无需下载安装,随时随地在手机、电脑、平板甚至手表上畅玩。提供多种游戏模式和地图,与全球玩家实时对战。" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content" />
<link rel="stylesheet" href="/css/main-legacy.css" />
<link rel="stylesheet" href="/res/fonts/fonts.css" />
</head>
<body>
<div id="root"></div>
<div id="ra2web-root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
================================================
FILE: package.json
================================================
{
"name": "redalert2-web",
"private": true,
"version": "0.0.0",
"type": "module",
"packageManager": "bun@1.3.10",
"scripts": {
"dev": "node ./node_modules/vite/bin/vite.js",
"dev:bun": "bun --bun vite",
"build": "bun --bun vite build",
"test": "bun test",
"typecheck:entry": "bun --bun tsc -p tsconfig.build.json",
"preview": "bun --bun vite preview",
"live:runtime": "bun scripts/live-interaction-runtime.mjs",
"live:runtime:build": "bun --bun vite build && bun scripts/live-interaction-runtime.mjs",
"debug:skirmish": "bun scripts/skirmish-flow.mjs",
"debug:live-interaction": "bun scripts/live-interaction-flow.mjs",
"debug:live-interaction-loading": "bun scripts/live-interaction-loading-flow.mjs",
"debug:perf-smoke": "bun scripts/perf-smoke-flow.mjs",
"debug:perftest": "bun scripts/perftest-flow.mjs",
"debug:game-res-init": "bun scripts/game-res-init-flow.mjs",
"debug:refinery-free-unit": "bun scripts/refinery-free-unit-flow.mjs",
"debug:viewport": "bun scripts/viewport-flow.mjs",
"debug:terror-drone": "bun scripts/terror-drone-flow.mjs",
"debug:chrono-legionnaire": "bun scripts/chrono-legionnaire-flow.mjs",
"debug:radiation": "bun scripts/radiation-flow.mjs",
"debug:storage-explorer": "bun scripts/storage-explorer-flow.mjs",
"debug:options": "bun scripts/options-flow.mjs",
"debug:test-entries": "bun scripts/test-entry-flow.mjs",
"debug:tester-panels": "bun scripts/tester-panel-flow.mjs",
"debug:skirmish-lobby-data": "bun scripts/skirmish-lobby-data-flow.mjs",
"debug:victory-exit": "bun scripts/victory-exit-flow.mjs",
"debug:crate-sound": "bun scripts/crate-sound-flow.mjs",
"debug:superweapon": "bun scripts/superweapon-flow.mjs",
"debug:nuke": "bun scripts/nuke-flow.mjs",
"debug:minimap-shroud": "bun scripts/minimap-shroud-flow.mjs",
"debug:anti-air-hit": "bun scripts/anti-air-hit-flow.mjs",
"debug:lan-mesh": "bun scripts/lan-mesh-flow.mjs",
"debug:lan-app-message": "bun scripts/lan-app-message-flow.mjs",
"debug:lan-entry": "bun scripts/lan-entry-shot.mjs",
"debug:lan-lockstep": "bun scripts/lan-lockstep-flow.mjs",
"debug:lan-match-session": "bun scripts/lan-match-session-flow.ts",
"debug:lan-map-transfer": "bun scripts/lan-room-map-transfer-flow.ts"
},
"dependencies": {
"7z-wasm": "^1.1.0",
"@brakebein/threeoctree": "^2.0.1",
"@datastructures-js/priority-queue": "^6.3.5",
"@ffmpeg/ffmpeg": "^0.12.15",
"@puzzl/core": "^1.0.0-beta.1",
"@ra2web/pcxfile": "^1.0.1",
"@ra2web/wavefile": "^1.0.2",
"@timohausmann/quadtree-ts": "2.2.2",
"classnames": "^2.5.1",
"file-system-access": "^1.0.4",
"js-logger": "^1.6.1",
"jsqr": "^1.4.0",
"liang-barsky": "^1.0.12",
"mersenne-twister": "^1.1.0",
"qrcode": "^1.5.4",
"react": "19.2.4",
"react-dom": "19.2.4",
"shader-particle-engine": "^1.0.6",
"sprintf-js": "^1.1.3",
"stats.js": "^0.17.0",
"three": "0.183.2",
"three.meshline": "^1.4.0"
},
"devDependencies": {
"@playwright/test": "1.58.2",
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3",
"@types/sprintf-js": "^1.1.4",
"@types/three": "0.183.1",
"@vitejs/plugin-basic-ssl": "^2.3.0",
"@vitejs/plugin-react": "6.0.1",
"typescript": "5.9.3",
"vite": "8.0.1"
}
}
================================================
FILE: public/config.ini
================================================
[General]
discordUrl=https://discord.com
csfFile = general.csf
# Where game resources are located
gameresBaseUrl=/cdn/game-res/v2/
mapsBaseUrl=/cdn/maps/
modsBaseUrl=/cdn/mods/
gameResArchiveUrl=https://download.ra2web.com/full-pack.7z
patchNotesUrl=//www.ra2web.com/patch-notes.html
ladderRulesUrl=//www.ra2web.com/ladder-rules.html
modSdkUrl=https://github.com/ra2web/mod-sdk
breakingNewsUrl=/breaking-news.html
oldClientsBaseUrl=/old/
quickMatchEnabled=yes
botsEnabled=yes
debugLogging=wol
defaultLanguage=zh-CN
viewport.width=1024
viewport.height=768
================================================
FILE: public/css/main-legacy.css
================================================
html, body {
height: 100%;
}
body {
margin: 0;
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
box-sizing: border-box;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, .75);
overscroll-behavior: none;
}
html:-webkit-full-screen body {
background: black;
}
html:-moz-full-screen body {
background: black;
}
#ra2web-root .stats-layer canvas {
display: initial !important;
cursor: auto !important;
}
#ra2web-root {
position: relative;
touch-action: none;
user-select: none;
-webkit-user-select: none;
}
#ra2web-root, #ra2web-root input, #ra2web-root select, #ra2web-root .select, #ra2web-root button {
font-family: 'Fira Sans Condensed', Arial, sans-serif;
font-size: 13px;
color: yellow;
font-weight: 500;
border-radius: 0;
}
#ra2web-root select option {
background: black;
}
#ra2web-root a:link,
#ra2web-root a:visited {
color: red;
}
#ra2web-root > * {
vertical-align: top;
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader-logo {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10000;
background: url(res/img/cd-logo.png) no-repeat center center;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 240px;
height: 240px;
margin: -120px 0 0 -120px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #3498db;
animation: spin 2s linear infinite;
z-index: 1001;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #e74c3c;
animation: spin 3s linear infinite;
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #f9c922;
animation: spin 1.5s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.no-js #loader-wrapper {
display: none;
}
#ra2web-root video::-webkit-media-controls {
display: none;
}
#ra2web-root .video-wrapper,
#ra2web-root .video-wrapper video {
width: 632px;
height: 570px;
}
#ra2web-root .video-wrapper .logo {
position: absolute;
left: 325px;
top: 355px;
width: 400px;
height: 44px;
transform: translateX(-50%) translateY(-50%);
background-image: var(--res-menu-logo);
}
#ra2web-root .message-box {
width: 451px;
height: 326px;
background-image: var(--res-dlg-bgn);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
#ra2web-root .message-box-content {
padding: 50px;
}
#ra2web-root .message-box-footer {
position: absolute;
bottom: 0;
right: 0;
padding: 20px;
}
#ra2web-root .toasts {
position: absolute;
top: 16px;
left: 16px;
}
#ra2web-root .toasts .toast {
max-width: 600px;
width: fit-content;
padding: 8px;
background: rgba(0, 0, 0, .75);
border: 1px red solid;
animation: slideInFromLeft .4s;
}
#ra2web-root .toasts .toast + .toast {
margin-top: 8px;
}
@keyframes slideInFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
#ra2web-root .menu-button {
cursor: default;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#ra2web-root .menu-button.disabled {
color: #6e6e6e;
opacity: 0.68;
text-shadow: 1px 1px rgba(0, 0, 0, 0.75);
}
#ra2web-root .menu-version-string {
text-align: center;
}
#ra2web-root .menu-mp-slot {
position: relative;
}
#ra2web-root pre.menu-mp-slot-text {
width: 100%;
text-align: center;
margin: 0;
padding: 10px 8px 0 8px;
box-sizing: border-box;
white-space: pre-line;
font-family: inherit;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
max-height: 71px;
}
#ra2web-root .menu-mp-slot-icon {
position: absolute;
top: 10px;
left: 7px;
}
#ra2web-root .sidebar-title {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
width: inherit;
text-align: center;
font-size: 12px;
}
#ra2web-root .menu-tooltip {
padding: 10px;
box-sizing: border-box;
width: 0;
overflow: hidden;
white-space: nowrap;
}
#ra2web-root .menu-tooltip.anim {
transition: width .4s;
width: 100%;
}
#ra2web-root .login-wrapper {
width: 451px;
height: 500px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
#ra2web-root .login-wrapper .title {
text-align: center;
margin-bottom: 20px;
}
#ra2web-root .login-wrapper .login-form {
padding: 0 20px;
margin: 24px 0;
}
#ra2web-root .login-wrapper .server-list {
display: inline-block;
width: 250px;
}
#ra2web-root .login-wrapper .server-list,
#ra2web-root .login-wrapper .refresh-button {
vertical-align: top;
margin-top: -4px;
}
#ra2web-root .login-wrapper .refresh-button {
margin-left: 8px;
}
#ra2web-root .login-wrapper .server-list .list-item {
display: flex;
}
#ra2web-root .login-wrapper .server-list .list-item .label {
flex-grow: 1;
}
#ra2web-root .server-ping {
width: 70px;
justify-content: right;
display: flex;
}
#ra2web-root .server-ping .ping-text {
margin-right: 3px;
}
#ra2web-root .server-ping .ping-text.ping-good {
color: lawngreen;
}
#ra2web-root .server-ping .ping-text.ping-avg {
color: yellow;
}
#ra2web-root .server-ping .ping-text.ping-bad {
color: red;
}
#ra2web-root .list-item.selected .server-ping .ping-text.ping-bad {
color: orange;
text-shadow: 1px 1px black;
}
#ra2web-root .login-wrapper .server-list .list-item .offline-text {
color: red;
text-transform: uppercase;
}
#ra2web-root .login-wrapper .server-list .list-item .online-text {
color: lawngreen;
text-transform: uppercase;
}
#ra2web-root .login-wrapper .news {
box-sizing: border-box;
height: 200px;
overflow-y: auto;
overflow-x: hidden;
}
#ra2web-root .login-wrapper .news > div {
font-size: 14px;
color: white;
font-weight: normal;
font-family: Arial, sans-serif;
}
#ra2web-root .login-box .field {
margin-bottom: 10px;
}
#ra2web-root .login-box .field label {
margin-right: 10px;
text-align: right;
display: inline-block;
min-width: 100px;
}
#ra2web-root .login-box.new-account-box {
width: 500px;
}
#ra2web-root .new-account-box .login-box .field label {
min-width: 130px;
}
#ra2web-root .login-box.create-game-box .field input[name="enablepass"],
#ra2web-root .login-box.create-game-box .field input[name="lobbypass"] {
margin-right: 10px;
vertical-align: middle;
}
#ra2web-root .prompt-box .field label {
display: block;
}
#ra2web-root .prompt-box .field input[type="text"] {
margin-top: 5px;
}
#ra2web-root .dialog-button {
width: 126px;
height: 25px;
border: none;
outline: none;
background-image: var(--res-mnbttn);
background-position: 0 0;
display: block;
margin-top: 10px;
}
#ra2web-root .dialog-button:hover:not(:disabled) {
background-position: -126px 0;
}
#ra2web-root .dialog-button:active:not(:disabled) {
background-position: -252px 0;
}
#ra2web-root .dialog-button:disabled {
color: black;
}
#ra2web-root .lobby-form,
#ra2web-root .gamebrowser-wrapper,
#ra2web-root .map-sel-form,
#ra2web-root .replay-sel-form,
#ra2web-root .mod-sel-form,
#ra2web-root .qm-form,
#ra2web-root .ladder {
width: 632px;
}
#ra2web-root .lobby-form,
#ra2web-root .qm-form,
#ra2web-root .ladder {
padding: 40px 40px;
box-sizing: border-box;
}
#ra2web-root .lobby-form {
padding: 30px 30px;
}
#ra2web-root .lobby-form.lobby-form-server-sel {
padding: 15px 30px;
}
#ra2web-root .lobby-form .game-server {
margin-bottom: 8px;
text-align: right;
padding-right: 2px;
}
#ra2web-root .lobby-form .game-server span.label {
margin-right: 10px;
vertical-align: middle;
}
#ra2web-root .lobby-form.lobby-form-sp {
padding: 40px 59px;
}
#ra2web-root .lobby-form .player-slots,
#ra2web-root .lobby-form .game-options,
#ra2web-root .qm-form .qm-top .opts {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#ra2web-root input[type="checkbox"] {
background-image: var(--res-cue-i);
width: 18px;
height: 18px;
-webkit-appearance: none;
appearance: none;
margin: 0;
border: 0;
}
#ra2web-root input[type="checkbox"]:checked {
background-image: var(--res-cce-i);
}
#ra2web-root input[type="checkbox"].semi-checked-left {
background-image: var(--res-cce-il);
}
#ra2web-root input[type="checkbox"].semi-checked-right {
background-image: var(--res-cce-ir);
}
#ra2web-root input[type="range"] {
-webkit-appearance: none;
appearance: none;
background: transparent;
margin: 0;
height: 24px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
border-radius: 0;
border: none;
height: 22px;
width: 12px;
background-color: red;
background-image: var(--res-icons-24);
background-position: -264px 0;
}
input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
border-radius: 0;
border: none;
height: 22px;
width: 12px;
background-color: red;
background-image: var(--res-icons-24);
background-position: -264px 0;
}
input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 24px;
background: transparent;
border: 1px red solid;
}
input[type="range"]::-moz-range-track {
width: 100%;
height: 24px;
background: transparent;
border: 1px red solid;
}
input[type="range"]:focus {
outline: none;
}
#ra2web-root input[type="text"],
#ra2web-root input[type="url"],
#ra2web-root input[type="password"],
#ra2web-root select,
#ra2web-root .select {
background: transparent;
border: 1px red solid;
}
#ra2web-root input[type="text"],
#ra2web-root input[type="url"],
#ra2web-root input[type="password"],
#ra2web-root select,
#ra2web-root .select {
height: 26px;
box-sizing: border-box;
}
#ra2web-root .dialog-button {
height: 25px;
box-sizing: border-box;
}
#ra2web-root input[type="text"],
#ra2web-root input[type="url"],
#ra2web-root input[type="password"] {
padding-left: 4px;
}
#ra2web-root input:focus,
#ra2web-root select:focus {
outline: none;
}
#ra2web-root select:disabled,
#ra2web-root .select.disabled,
#ra2web-root input:disabled,
#ra2web-root label input:disabled + span,
#ra2web-root .lobby-form .all-disabled span,
#ra2web-root .lobby-form .all-disabled input[type="text"]:disabled {
color: #9c0000;
border-color: #9c0000;
}
#ra2web-root input[type="checkbox"]:disabled,
#ra2web-root input[type="range"]:disabled {
opacity: 0.7;
}
#ra2web-root input[type="range"] + input[type="text"]:disabled {
opacity: 1;
}
#ra2web-root .select {
position: relative;
user-select: none;
-webkit-user-select: none;
}
#ra2web-root .select .select-value {
padding: 4px 21px 4px 3px;
height: 100%;
box-sizing: border-box;
}
#ra2web-root .select::before {
pointer-events: none;
content: "";
position: absolute;
right: 1px;
top: 1px;
width: 18px;
height: 22px;
background-image: var(--res-icons-24);
background-position: -96px 0;
}
#ra2web-root .select::before:hover {
background-position: -120px 0;
}
#ra2web-root .select .select-layer {
z-index: 1;
position: absolute;
top: 26px;
left: 0;
width: 100%;
outline: 1px red solid;
background: rgba(0, 0, 0, .75);
}
#ra2web-root .select .select-layer .option {
padding: 4px 3px;
height: 24px;
box-sizing: border-box;
}
#ra2web-root .select .select-value > div,
#ra2web-root .select .select-layer .option > div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#ra2web-root .select .select-layer .option.selected {
background: red;
}
#ra2web-root .select .select-layer .option.disabled {
color: gray;
}
#ra2web-root .player-color-select.bg-color .select .select-value {
padding: 2px 21px 2px 2px;
}
#ra2web-root .player-color-select .select .select-layer .option.bg-color {
padding: 2px;
}
#ra2web-root .player-color-select.bg-color .select .select-value > div,
#ra2web-root .player-color-select .select .select-layer .option.bg-color > div {
width: 100%;
height: 100%;
}
#ra2web-root .player-color-select.bg-color .select.disabled .select-value > div {
opacity: .75;
}
#ra2web-root .lobby-form .player-slots {
height: 263px; /* 27px * 9 slots + 20px header */
}
#ra2web-root .lobby-form .player-slot-header .player-header-players {
margin-left: 57px; /* 16px rank, 3px spacing, 16px ping, 3px spacing, 16px ready, 3px spacing */
width: 150px;
}
#ra2web-root .lobby-form.lobby-form-sp .player-slot-header .player-header-players {
margin-left: 0;
}
#ra2web-root .lobby-form .player-slot-header .player-header-side {
margin-left: 57px; /* 3px spacing, 47px icon, 7 px spacing */
width: 120px;
}
#ra2web-root .lobby-form .player-slot-header .player-header-color,
#ra2web-root .lobby-form .player-slot-header .player-header-position,
#ra2web-root .lobby-form .player-slot-header .player-header-team {
margin-left: 7px;
width: 55px;
}
#ra2web-root .lobby-form .player-slot {
height: 26px;
}
#ra2web-root .lobby-form .player-slot.player-slot-header {
height: 20px;
}
#ra2web-root .lobby-form .player-slot + .player-slot {
margin-top: 1px;
}
#ra2web-root .country-select {
display: inline-block;
}
#ra2web-root .lobby-form .player-slot .rank-indicator,
#ra2web-root .lobby-form .player-slot .ping-indicator,
#ra2web-root .lobby-form .player-slot .player-status,
#ra2web-root .player-country-icon,
#ra2web-root .lobby-form .player-slot .player-country-select,
#ra2web-root .lobby-form .player-slot .player-color-select,
#ra2web-root .lobby-form .player-slot .player-start-pos-select,
#ra2web-root .lobby-form .player-slot .player-team-select,
#ra2web-root .lobby-form .player-slot-header > div {
display: inline-block;
vertical-align: middle;
margin-left: 3px;
}
#ra2web-root .lobby-form .player-slot .rank-indicator {
margin-left: 0;
}
#ra2web-root .rank-indicator,
#ra2web-root .ping-indicator,
#ra2web-root .lobby-form .player-slot .player-status {
width: 16px;
height: 16px;
}
#ra2web-root .lobby-form.lobby-form-sp .player-slot .rank-indicator,
#ra2web-root .lobby-form.lobby-form-sp .player-slot .ping-indicator,
#ra2web-root .lobby-form.lobby-form-sp .player-slot .player-status {
display: none;
}
#ra2web-root .player-country-icon {
width: 47px;
height: 23px;
}
#ra2web-root .lobby-form .player-slot .player-country-select,
#ra2web-root .lobby-form .player-slot .player-color-select,
#ra2web-root .lobby-form .player-slot .player-start-pos-select,
#ra2web-root .lobby-form .player-slot .player-team-select {
margin-left: 7px;
}
#ra2web-root .lobby-form .player-slot .player-country-select .select,
#ra2web-root .qm-form .player-country-select .select {
width: 120px;
}
#ra2web-root .lobby-form .player-slot .player-color-select .select,
#ra2web-root .lobby-form .player-slot .player-start-pos-select .select,
#ra2web-root .lobby-form .player-slot .player-team-select .select,
#ra2web-root .qm-form .player-color-select {
width: 55px;
}
#ra2web-root .lobby-form .player-slot .player-name {
margin-left: 3px;
vertical-align: middle;
width: 150px;
}
#ra2web-root .lobby-form.lobby-form-sp .player-slot .player-name {
margin-left: 0;
}
#ra2web-root .lobby-form .game-options {
margin-top: 10px;
}
#ra2web-root .lobby-form .game-options::after {
content: "";
display: block;
clear: both;
}
#ra2web-root .lobby-form .game-options-left {
margin-left: 0;
float: left;
height: 114px;
column-count: 2;
column-gap: 10px;
column-fill: auto;
}
#ra2web-root .lobby-form.lobby-form-sp .game-options-left {
column-gap: 0;
width: 250px;
padding-top: 4px;
}
#ra2web-root .lobby-form .game-options-right {
float: right;
}
#ra2web-root .lobby-form .game-options-left > div {
margin-bottom: 5px;
}
#ra2web-root .lobby-form.lobby-form-sp .game-options-left > div {
margin-bottom: 12px;
}
#ra2web-root .lobby-form .game-options label {
display: inline-block;
line-height: 18px;
}
#ra2web-root .lobby-form .game-options-left label {
white-space: nowrap;
}
#ra2web-root input[type="checkbox"] {
vertical-align: top;
margin-right: 3px;
}
#ra2web-root .lobby-form .game-options-right > div {
margin-bottom: 6px;
margin-left: 10px;
}
#ra2web-root .slider-item input[type="range"] {
width: 79px;
vertical-align: top;
margin-left: 0;
margin-right: 0;
}
#ra2web-root .slider-item input[type="text"] {
width: 50px;
box-sizing: border-box;
text-align: center;
padding-left: 0;
border-color: red;
color: yellow;
}
#ra2web-root .slider-item span.label {
width: 100px;
display: inline-block;
vertical-align: middle;
}
#ra2web-root .slider-item input[type="text"] {
height: 24px;
background: #5a0000;
box-shadow: inset 0 0 10px #000;
}
#ra2web-root .lobby-form .game-options-right .checkbox-item {
margin-top: 12px;
}
#ra2web-root .list {
border: 1px red solid;
overflow-y: auto;
overflow-x: hidden;
}
#ra2web-root .list-title {
text-align: center;
margin-bottom: 8px;
}
#ra2web-root .list-header,
#ra2web-root .list .list-item {
user-select: none;
-webkit-user-select: none;
cursor: default;
padding: 3px;
}
#ra2web-root .list .list-item.selected {
background: red;
}
#ra2web-root .list .list-item.disabled {
background: transparent;
color: gray;
}
#ra2web-root .gamebrowser-wrapper {
padding: 16px;
box-sizing: border-box;
}
#ra2web-root .gamebrowser-wrapper .gamebrowser-top {
overflow: hidden;
}
#ra2web-root .gamebrowser-wrapper .gamebrowser-bottom {
display: flex;
align-items: stretch;
margin-top: 10px;
}
#ra2web-root .gamebrowser-wrapper .chat-wrapper {
width: 410px;
}
#ra2web-root .gamebrowser-wrapper .players-list {
height: 242px;
width: 180px;
margin-left: 10px;
}
#ra2web-root .gamebrowser-wrapper .games-header {
height: 24px;
}
#ra2web-root .icon-button {
width: 24px;
height: 24px;
background-image: var(--res-icons-24);
border: none;
outline: none;
}
#ra2web-root .gamebrowser-wrapper .refresh-button {
background-position: 0 0;
vertical-align: middle;
}
#ra2web-root .gamebrowser-wrapper .refresh-button:hover {
background-position: -24px 0;
}
#ra2web-root .gamebrowser-wrapper .chat-wrapper .messages {
height: 200px;
}
#ra2web-root .chat-wrapper .send-message-button {
background-position: -48px 0;
}
#ra2web-root .chat-wrapper .send-message-button:hover {
background-position: -72px 0;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-flags span {
width: 16px;
height: 16px;
display: inline-block;
margin-right: 3px;
vertical-align: middle;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-map,
#ra2web-root .gamebrowser-wrapper .games .game .game-name {
margin-right: 5px;
width: 150px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-players {
width: 30px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-map,
#ra2web-root .gamebrowser-wrapper .games .game .game-name,
#ra2web-root .gamebrowser-wrapper .games .game .game-players,
#ra2web-root .gamebrowser-wrapper .games .game .game-host,
#ra2web-root .gamebrowser-wrapper .games .game .game-ping {
display: inline-block;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-host .rank-indicator {
display: inline-block;
vertical-align: top;
margin-left: 3px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-flags img {
vertical-align: middle;
}
#ra2web-root .gamebrowser-wrapper .games .games-label {
margin-left: 3px;
vertical-align: middle;
}
#ra2web-root .gamebrowser-wrapper .games-list {
height: 235px;
}
#ra2web-root .players-list .player {
padding: 3px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
cursor: pointer;
}
#ra2web-root .players-list .player.operator {
color: cyan;
}
#ra2web-root .players-list .player .channel-op-indicator {
display: inline-block;
vertical-align: middle;
width: 14px;
height: 14px;
}
#ra2web-root .players-list .player .rank-indicator {
display: inline-block;
vertical-align: top;
margin-right: 3px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-host {
width: 129px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping {
width: 30px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter {
width: 100%;
height: 11px;
position: relative;
top: -1px;
/* Needed for Firefox */
background: transparent;
border-width: 0;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter::-webkit-meter-bar {
background: transparent;
border-radius: 0;
border-width: 0;
height: 11px;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter::-moz-meter-bar {
background: transparent;
border-radius: 0;
border-width: 0;
height: 11px;
box-sizing: border-box;
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter::-webkit-meter-optimum-value {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #b0b0b0, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(limegreen, limegreen);
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter:-moz-meter-optimum::-moz-meter-bar {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #b0b0b0, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(limegreen, limegreen);
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter::-webkit-meter-suboptimum-value {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #b0b0b0, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(orange, orange);
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter:-moz-meter-sub-optimum::-moz-meter-bar {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #b0b0b0, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(orange, orange);
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter::-webkit-meter-even-less-good-value {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #808080, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(red, red);
}
#ra2web-root .gamebrowser-wrapper .games .game .game-ping meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #808080, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(red, red);
}
#ra2web-root .lobby-form .chat-wrapper {
margin-top: 10px;
clear: both;
}
#ra2web-root .chat-wrapper .messages {
margin-bottom: 10px;
padding: 3px;
border: 1px red solid;
height: 125px;
overflow-y: auto;
}
#ra2web-root .lobby-form .messages {
height: 70px;
}
#ra2web-root .chat-wrapper .messages .message {
white-space: pre-wrap;
word-wrap: break-word;
}
#ra2web-root .chat-wrapper .messages .message.operator-message {
color: cyan !important;
}
#ra2web-root .chat-wrapper .messages .message.type-page {
color: white;
}
#ra2web-root .chat-wrapper .messages .message.type-whisper {
color: mediumpurple;
}
#ra2web-root .chat-wrapper .messages .message .user-link {
cursor: pointer;
}
#ra2web-root .chat-wrapper .new-message-wrapper {
padding-right: 27px; /** 3px margin + 24px icon */
position: relative;
}
#ra2web-root .chat-wrapper .new-message {
width: 100%;
display: flex;
align-items: center;
}
#ra2web-root .chat-wrapper .new-message input {
flex-grow: 1;
}
#ra2web-root .chat-wrapper .new-message * + input {
margin-left: 8px;
}
#ra2web-root .chat-wrapper .new-message input::placeholder {
color: gray;
}
#ra2web-root .chat-wrapper .send-message-button {
position: absolute;
right: 0;
top: 0;
}
#ra2web-root .map-sel-form {
padding: 86px 86px;
box-sizing: border-box;
}
#ra2web-root .map-sel-form .map-sel-title {
text-align: center;
margin-bottom: 40px;
}
#ra2web-root .map-sel-form .map-sel-body {
display: flex;
}
#ra2web-root .map-sel-form .map-sel-body > * + * {
margin-left: 20px;
}
#ra2web-root .map-sel-form .map-sel-game-mode {
width: 150px;
}
#ra2web-root .map-sel-form .map-sel-game-mode .list-title {
line-height: 26px;
}
#ra2web-root .map-sel-form .map-sel-map {
width: 250px;
}
#ra2web-root .map-sel-form .game-mode-list,
#ra2web-root .map-sel-form .map-list {
height: 300px;
}
#ra2web-root .map-sel-form .list-header,
#ra2web-root .map-sel-form .map-list .list-item {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#ra2web-root .map-sel-form .map-list-title {
display: flex;
justify-content: space-between;
align-items: center;
text-align: left;
}
#ra2web-root .map-sel-form .map-list-sort label {
font-size: 16px;
vertical-align: middle;
}
#ra2web-root .map-sel-form .map-list-sort .map-list-sort-select {
margin-left: 5px;
min-width: 100px;
}
#ra2web-root .map-sel-form .map-sel-search {
margin-top: 10px;
}
#ra2web-root .map-sel-form .map-sel-search label {
display: flex;
align-items: center;
}
#ra2web-root .map-sel-form .map-sel-search label span {
margin-right: 5px;
}
#ra2web-root .map-sel-form .map-sel-search label input {
flex: 1 0;
}
#ra2web-root .lan-setup-form {
padding: 20px 34px 26px;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form[data-lan-view="entry"] {
height: 100%;
min-height: 100%;
display: flex;
flex-direction: column;
}
#ra2web-root .lan-setup-form[data-lan-view="waiting"] {
padding: 18px 30px 22px;
height: 100%;
min-height: 100%;
display: flex;
flex-direction: column;
}
#ra2web-root .lan-setup-form .lan-setup-notice {
margin-bottom: 18px;
padding: 8px 10px;
border: 1px red solid;
background: rgba(32, 0, 0, 0.45);
color: #ffcc7a;
line-height: 1.35;
}
#ra2web-root .lan-setup-form .lan-setup-content {
display: flex;
align-items: flex-start;
}
#ra2web-root .lan-setup-form .lan-setup-content > * + * {
margin-left: 16px;
}
#ra2web-root .lan-setup-form .lan-entry-layout {
flex: 1 1 auto;
min-height: 510px;
display: flex;
flex-direction: column;
gap: 14px;
}
#ra2web-root .lan-setup-form .lan-entry-profile-panel {
flex: 0 0 auto;
}
#ra2web-root .lan-setup-form .lan-entry-profile-grid {
display: grid;
grid-template-columns: minmax(260px, 1.2fr) minmax(220px, 0.9fr);
gap: 16px;
align-items: stretch;
}
#ra2web-root .lan-setup-form .lan-entry-profile-editor {
display: flex;
flex-direction: column;
}
#ra2web-root .lan-setup-form .lan-entry-field-hint {
margin-top: 8px;
color: silver;
line-height: 1.35;
}
#ra2web-root .lan-setup-form .lan-entry-profile-stats {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
#ra2web-root .lan-setup-form .lan-entry-stat {
border: 1px red solid;
background: rgba(0, 0, 0, 0.3);
min-height: 58px;
padding: 7px 10px 6px;
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form .lan-entry-stat span {
color: silver;
}
#ra2web-root .lan-setup-form .lan-entry-stat strong {
color: white;
font-weight: inherit;
}
#ra2web-root .lan-setup-form .lan-entry-panel,
#ra2web-root .lan-setup-form .lan-room-summary-panel,
#ra2web-root .lan-setup-form .lan-room-loading-panel {
min-height: 170px;
}
#ra2web-root .lan-setup-form .lan-entry-recent-panel {
flex: 1 1 auto;
min-height: 292px;
display: flex;
flex-direction: column;
}
#ra2web-root .lan-setup-form .lan-entry-recent-list {
flex: 1 1 auto;
min-height: 240px;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item {
padding: 9px 10px 8px;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item + .lan-entry-recent-item {
border-top: 1px solid rgba(255, 0, 0, 0.35);
}
#ra2web-root .lan-setup-form .lan-entry-recent-item-top,
#ra2web-root .lan-setup-form .lan-entry-recent-item-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
flex-wrap: wrap;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item-top strong {
color: white;
font-weight: inherit;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item-top span,
#ra2web-root .lan-setup-form .lan-entry-recent-item-members {
color: silver;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item-meta {
margin-top: 4px;
font-size: 15px;
}
#ra2web-root .lan-setup-form .lan-entry-recent-item-members {
margin-top: 5px;
line-height: 1.35;
}
#ra2web-root .lan-setup-form .lan-entry-recent-chip {
display: inline-flex;
align-items: center;
min-height: 20px;
padding: 2px 7px 1px;
border: 1px red solid;
background: rgba(34, 0, 0, 0.45);
color: #ffe165;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form .lan-entry-empty-state {
flex: 1 1 auto;
min-height: 180px;
border: 1px red solid;
background: rgba(0, 0, 0, 0.2);
padding: 14px;
color: silver;
line-height: 1.45;
display: flex;
align-items: center;
}
#ra2web-root .lan-setup-form .lan-setup-main {
flex: 1 1 auto;
min-width: 0;
}
#ra2web-root .lan-setup-form .lan-waiting-main {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
margin-top: auto;
}
#ra2web-root .lan-setup-form .lan-room-status-strip {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 10px;
}
#ra2web-root .lan-setup-form .lan-status-chip {
display: inline-flex;
align-items: center;
gap: 4px;
min-height: 24px;
padding: 3px 8px 2px;
border: 1px red solid;
background: rgba(0, 0, 0, 0.25);
line-height: 1.35;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form .lan-status-chip strong {
color: white;
font-weight: inherit;
}
#ra2web-root .lan-setup-form .lan-status-divider {
color: silver;
}
#ra2web-root .lan-setup-form .lan-room-form-shell {
margin-top: 14px;
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
}
#ra2web-root .lan-setup-form .lan-room-form-shell-compact {
margin-top: 0;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form {
width: 100%;
flex: 1 1 auto;
min-height: 0;
padding: 0;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form[data-lan-view="waiting"] .lan-room-form-shell > .lobby-form {
display: flex;
flex-direction: column;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .player-slots {
height: auto;
min-height: 0;
flex: 0 0 auto;
}
#ra2web-root .lan-setup-form[data-lan-view="waiting"] .lan-room-form-shell > .lobby-form .player-slots {
min-height: 263px;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .player-slot:empty {
display: none;
}
#ra2web-root .lan-setup-form[data-lan-view="waiting"] .lan-room-form-shell > .lobby-form .game-options {
margin-top: auto;
padding-top: 12px;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .lobby-form-before-chat {
margin-top: 4px;
clear: both;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .lobby-form-before-chat .lan-room-status-strip {
margin-bottom: 0;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .chat-wrapper {
margin-top: 4px;
}
#ra2web-root .lan-setup-form .lan-room-form-shell > .lobby-form .messages {
height: 54px;
margin-bottom: 6px;
}
#ra2web-root .lan-setup-form .lan-room-loading-panel-compact {
min-height: 0;
}
#ra2web-root .lan-setup-form .lan-panel {
border: 1px red solid;
background: rgba(0, 0, 0, 0.25);
padding: 10px;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form .lan-panel + .lan-panel {
margin-top: 14px;
}
#ra2web-root .lan-setup-form .lan-entry-layout > .lan-panel + .lan-panel,
#ra2web-root .lan-setup-form .lan-dialog-grid > .lan-panel + .lan-panel {
margin-top: 0;
}
#ra2web-root .lan-setup-form .lan-panel-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
}
#ra2web-root .lan-setup-form .lan-panel-header h3 {
margin: 0;
font-size: 20px;
}
#ra2web-root .lan-setup-form .lan-panel-header span {
color: silver;
text-align: right;
}
#ra2web-root .lan-setup-form .lan-input-label {
display: block;
margin-bottom: 5px;
}
#ra2web-root .lan-setup-form .lan-text-input {
width: 100%;
box-sizing: border-box;
}
#ra2web-root .lan-setup-form .lan-join-hint {
line-height: 1.45;
}
#ra2web-root .lan-setup-form .lan-sdp-textarea {
width: 100%;
min-height: 118px;
resize: vertical;
box-sizing: border-box;
border: 1px red solid;
background: black;
color: white;
padding: 7px 8px;
font: inherit;
}
#ra2web-root .lan-setup-form .lan-sdp-textarea::placeholder {
color: gray;
}
#ra2web-root .lan-setup-form .lan-actions {
margin-top: 10px;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
}
#ra2web-root .lan-setup-form .lan-hint {
color: silver;
}
#ra2web-root .lan-setup-form .lan-qr-card {
margin-bottom: 10px;
}
#ra2web-root .lan-setup-form .lan-qr-artwork,
#ra2web-root .lan-setup-form .lan-scanner-preview {
border: 1px red solid;
background: black;
min-height: 286px;
display: flex;
align-items: center;
justify-content: center;
}
#ra2web-root .lan-setup-form .lan-qr-artwork img,
#ra2web-root .lan-setup-form .lan-scanner-preview video {
display: block;
width: 100%;
max-width: 286px;
image-rendering: pixelated;
}
#ra2web-root .lan-setup-form .lan-qr-placeholder {
padding: 20px;
text-align: center;
color: silver;
line-height: 1.4;
}
#ra2web-root .lan-setup-form .lan-hidden-input {
display: none;
}
#ra2web-root .lan-setup-form .lan-error-text {
margin-top: 10px;
color: #ff8888;
}
#ra2web-root .lan-setup-form .lan-chat-panel .messages {
height: 110px;
}
#ra2web-root .lan-dialog-overlay {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.65);
z-index: 60;
padding: 20px;
box-sizing: border-box;
}
#ra2web-root .lan-dialog {
width: min(760px, 100%);
max-height: calc(100vh - 40px);
overflow: auto;
border: 1px red solid;
background: rgba(10, 0, 0, 0.96);
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.05);
}
#ra2web-root .lan-dialog.lan-dialog-wide {
width: min(1080px, 100%);
}
#ra2web-root .lan-dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 14px 16px 12px;
border-bottom: 1px solid rgba(255, 0, 0, 0.6);
}
#ra2web-root .lan-dialog-header h3 {
margin: 0;
font-size: 22px;
}
#ra2web-root .lan-dialog-close {
min-width: 34px;
min-height: 34px;
border: 1px red solid;
background: black;
color: white;
font: inherit;
cursor: pointer;
}
#ra2web-root .lan-dialog-body {
padding: 16px;
}
#ra2web-root .lan-dialog-body > * + * {
margin-top: 16px;
}
#ra2web-root .lan-dialog-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 16px;
align-items: start;
}
#ra2web-root .lan-setup-form .tone-good {
color: #55ff55;
}
#ra2web-root .lan-setup-form .tone-warn {
color: #ffcc66;
}
#ra2web-root .lan-setup-form .tone-bad {
color: #ff6666;
}
@media (max-width: 700px) {
#ra2web-root .lan-setup-form {
padding: 20px 18px;
}
#ra2web-root .lan-setup-form .lan-entry-layout {
gap: 12px;
}
#ra2web-root .lan-setup-form .lan-setup-content {
display: block;
}
#ra2web-root .lan-setup-form .lan-setup-content > * + * {
margin-left: 0;
margin-top: 16px;
}
#ra2web-root .lan-setup-form .lan-panel-header {
display: block;
}
#ra2web-root .lan-setup-form .lan-panel-header span {
display: block;
margin-top: 4px;
text-align: left;
}
#ra2web-root .lan-setup-form .lan-entry-profile-grid,
#ra2web-root .lan-setup-form .lan-entry-profile-stats {
grid-template-columns: 1fr;
}
#ra2web-root .lan-dialog-overlay {
padding: 10px;
}
#ra2web-root .lan-dialog {
max-height: calc(100vh - 20px);
}
#ra2web-root .lan-dialog-grid {
grid-template-columns: 1fr;
}
}
#ra2web-root ::-webkit-scrollbar {
width: 19px;
height: 18px;
}
#ra2web-root ::-webkit-scrollbar,
#ra2web-root ::-webkit-scrollbar-button:vertical,
#ra2web-root ::-webkit-scrollbar-thumb:vertical {
border-left: 1px red solid;
border-right: 1px red solid;
}
#ra2web-root ::-webkit-scrollbar-button:vertical,
#ra2web-root ::-webkit-scrollbar-thumb:vertical {
background-image: var(--res-icons-24);
}
#ra2web-root ::-webkit-scrollbar-thumb:vertical {
border-top: 1px solid #a20000;
border-bottom: 1px solid #a20000;
}
#ra2web-root ::-webkit-scrollbar-button:vertical:increment {
background-position: -96px 0;
width: 18px;
height: 22px;
}
#ra2web-root ::-webkit-scrollbar-button:vertical:increment:hover {
background-position: -120px 0;
}
#ra2web-root ::-webkit-scrollbar-button:vertical:decrement {
background-position: -144px 0;
width: 18px;
height: 22px;
}
#ra2web-root ::-webkit-scrollbar-button:vertical:decrement:hover {
background-position: -168px 0;
}
#ra2web-root ::-webkit-scrollbar-thumb:vertical {
background-position: -216px 0;
background-repeat: repeat-y;
}
#ra2web-root .loading-screen .special-unit-name {
position: absolute;
top: 94px;
left: 20px;
color: black;
text-transform: uppercase;
}
#ra2web-root .loading-screen .briefing-text {
position: absolute;
top: 170px;
left: 20px;
background: rgba(0, 0, 0, .5);
padding: 3px;
width: 400px;
font-weight: bold;
}
#ra2web-root .loading-screen .loading-text {
position: absolute;
top: 280px;
left: 20px;
background: rgba(0, 0, 0, .5);
padding: 3px;
font-weight: bold;
}
#ra2web-root .loading-screen .player-status-container {
position: absolute;
top: 300px;
left: 20px;
background: rgba(0, 0, 0, .5);
padding: 3px;
width: 400px;
}
#ra2web-root .loading-screen .player-status {
margin-top: 3px;
display: flex;
align-items: center;
}
#ra2web-root progress {
background: transparent;
border-width: 1px;
border-style: solid;
border-color: currentColor;
padding: 2px;
height: 11px;
box-sizing: border-box;
}
#ra2web-root progress::-webkit-progress-bar {
background: transparent;
}
#ra2web-root progress::-webkit-progress-value {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #808080, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(currentColor, currentColor);
}
#ra2web-root progress::-moz-progress-bar {
background-blend-mode: multiply, screen, multiply;
background:
linear-gradient(90deg, #808080, #fff),
linear-gradient(180deg, #606060 20%, #000 21%),
linear-gradient(180deg, #fff 79%, #ccc 80%),
linear-gradient(currentColor, currentColor);
}
#ra2web-root .loading-screen .country-name {
position: absolute;
bottom: 30px;
right: 80px;
font-weight: bold;
}
#ra2web-root .loading-screen .map-name {
position: absolute;
bottom: 30px;
left: 20px;
padding: 3px;
background: rgba(0, 0, 0, .5);
font-weight: bold;
}
#ra2web-root .loading-screen .player-team {
margin-right: 10px;
min-width: 40px;
color: white;
}
#ra2web-root .loading-screen .player-name {
margin-left: 10px;
font-weight: bold;
}
#ra2web-root .loading-screen .player-country-icon {
margin-left: 10px;
}
#ra2web-root .opts {
padding: 86px;
box-sizing: border-box;
}
#ra2web-root .opts .slider-item,
#ra2web-root .opts .item {
margin: 15px 0;
}
#ra2web-root .opts .item span.label {
width: 150px;
display: inline-block;
vertical-align: middle;
}
#ra2web-root .opts .slider-item {
text-align: center;
}
#ra2web-root .opts .item span.info {
margin-left: 5px;
vertical-align: middle;
}
#ra2web-root .opts .slider-item span.label,
#ra2web-root .opts .item span.label {
width: 150px;
text-align: right;
margin-right: 10px;
}
#ra2web-root .opts.sound-opts input[type="range"] {
width: 200px;
}
#ra2web-root .opts.general-opts {
padding: 34px 86px;
}
#ra2web-root .opts.general-opts .slider-item {
text-align: left;
}
#ra2web-root .opts.general-opts .slider-item span {
width: 150px;
}
#ra2web-root .opts.general-opts input[type="range"] {
width: 150px;
}
#ra2web-root .opts.general-opts fieldset + fieldset {
margin-top: 20px;
}
#ra2web-root .opts.general-opts .select {
min-width: 100px;
}
#ra2web-root .opts.general-opts .resolution-select .select {
min-width: 150px;
}
#ra2web-root .opts.general-opts .fullscreen-toggle-button {
min-width: 100px;
}
#ra2web-root[data-mobile-layout="true"] .opts.general-opts {
width: 100%;
max-width: 440px;
padding: 24px 48px;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts {
padding: 16px 72px;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts fieldset + fieldset {
margin-top: 10px;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts .slider-item,
#ra2web-root[data-compact-layout="true"] .opts.general-opts .item {
margin: 8px 0;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts .slider-item span.label,
#ra2web-root[data-compact-layout="true"] .opts.general-opts .item span.label {
width: 140px;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts .select {
min-width: 96px;
}
#ra2web-root[data-compact-layout="true"] .opts.general-opts .resolution-select .select,
#ra2web-root[data-compact-layout="true"] .opts.general-opts .fullscreen-toggle-button {
min-width: 128px;
}
#ra2web-root[data-mobile-layout="true"] .opts .item span.label,
#ra2web-root[data-mobile-layout="true"] .opts .slider-item span.label {
width: 135px;
}
#ra2web-root .opts.sound-opts {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
padding: 32px 0;
margin: 0 auto;
width: 410px;
}
#ra2web-root .opts.sound-opts .music-jukebox {
margin-top: 16px;
display: flex;
flex-direction: column;
min-height: 0;
}
#ra2web-root .opts.sound-opts .music-jukebox .jukebox-content {
display: flex;
justify-content: center;
align-items: end;
min-height: 0;
}
#ra2web-root .opts.sound-opts .music-jukebox .jukebox-content .controls {
width: 135px;
margin-left: 50px;
}
#ra2web-root .opts.sound-opts .music-jukebox .jukebox-content .controls > div {
margin-top: 16px;
}
#ra2web-root .opts.sound-opts .music-jukebox .jukebox-content .playlist {
width: 220px;
height: 100%;
max-height: 200px;
min-height: 0;
}
#ra2web-root .opts.sound-opts .music-jukebox .jukebox-footer {
margin-top: 16px;
display: flex;
justify-content: space-between;
margin-left: 50px;
}
#ra2web-root .key-opts {
margin: 0 auto;
position: relative;
top: 50%;
transform: translateY(-50%);
}
#ra2web-root .key-opts .key-opts-list,
#ra2web-root .key-opts .key-opts-cur-assign,
#ra2web-root .key-opts .key-opts-ch-assign {
display: flex;
}
#ra2web-root .key-opts .key-opts-list {
height: 200px;
margin-bottom: 15px;
}
#ra2web-root .key-opts .key-opts-left,
#ra2web-root .key-opts .key-opts-right {
margin: 0 20px;
width: 50%;
}
#ra2web-root .key-opts .key-opts-list .key-opts-left {
display: flex;
flex-direction: column;
}
#ra2web-root .key-opts .key-opts-list .key-opts-right {
display: flex;
flex-direction: column;
justify-content: center;
}
#ra2web-root .key-opts .key-opts-list .key-opts-right .key-opts-desc-container {
height: 100px;
margin-bottom: 50px;
}
#ra2web-root .key-opts .key-opts-list .key-opts-right .key-opts-cur-assign {
height: 30px;
margin-top: 15px;
}
#ra2web-root .key-opts .key-opts-cur-assign {
margin-bottom: 15px;
}
#ra2web-root .key-opts .key-opts-cur-assign .key-opts-cur-assign-value {
min-height: 15px;
}
#ra2web-root .key-opts .key-opts-ch-assign input {
margin: 5px 0;
width: 100%;
}
#ra2web-root .key-opts .key-opts-ch-assign .key-opts-right {
margin-top: 10px;
}
#ra2web-root .key-opts .key-opts-ch-assign-warn {
margin: 15px 20px 0 20px;
}
#ra2web-root fieldset {
border: 1px red solid;
}
#ra2web-root .replay-sel-form {
padding: 46px;
box-sizing: border-box;
}
#ra2web-root .replay-sel-form .replay-list {
height: 300px;
}
#ra2web-root .replay-sel-form .replay-list .replay-name {
width: 70%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-right: 5px;
}
#ra2web-root .replay-sel-form .replay-details {
border: 1px red solid;
padding: 3px;
margin-top: 16px;
}
#ra2web-root .replay-sel-form .storage-warning {
margin-top: 16px;
color: orange;
}
#ra2web-root .keep-replay-box input[type="text"] {
width: 100%;
margin-top: 8px;
}
#ra2web-root .mod-sel-form {
padding: 46px;
box-sizing: border-box;
}
#ra2web-root .mod-sel-form .mod-list {
height: 200px;
}
#ra2web-root .mod-sel-form .mod-list .mod-name {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
#ra2web-root .mod-sel-form .mod-details {
border: 1px red solid;
padding: 3px;
margin-top: 16px;
}
#ra2web-root .mod-sel-form .mod-details .mod-desc {
overflow: auto;
display: block;
max-height: 70px;
}
#ra2web-root .diplo-form {
padding: 34px 86px;
}
#ra2web-root .con-info-form {
padding: 86px 86px;
}
#ra2web-root .diplo-form,
#ra2web-root .con-info-form {
box-sizing: border-box;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
#ra2web-root .diplo-form .players {
overflow: auto;
min-height: 240px;
}
#ra2web-root .diplo-form table {
margin: 0 auto;
}
#ra2web-root .diplo-form thead {
color: yellow;
text-align: left;
}
#ra2web-root .diplo-form th {
font-weight: 500;
}
#ra2web-root .diplo-form th,
#ra2web-root .diplo-form td {
width: 70px;
padding: 5px 0;
}
#ra2web-root .diplo-form th.player-country,
#ra2web-root .diplo-form td.player-country {
width: 55px;
}
#ra2web-root .diplo-form th.player-ping,
#ra2web-root .diplo-form td.player-ping {
width: 20px;
min-width: 20px;
}
#ra2web-root .diplo-form th.player-name,
#ra2web-root .diplo-form td.player-name {
width: 200px;
}
#ra2web-root .diplo-form input[type="checkbox"]:disabled {
opacity: 0.5;
}
#ra2web-root .diplo-form-footer,
#ra2web-root .con-info-form-footer {
margin: 0 auto;
width: 100%;
max-width: 500px;
}
#ra2web-root .diplo-form-footer > *,
#ra2web-root .con-info-form-footer > * {
margin-top: 10px;
}
#ra2web-root .diplo-form-footer > * + *,
#ra2web-root .con-info-form-footer > * + * {
margin-top: 20px;
}
#ra2web-root .con-info-form .con-info-form-content {
flex-grow: 1;
}
#ra2web-root .con-info-form table {
margin: 0 auto;
}
#ra2web-root .con-info-form th.player-name {
text-align: left;
}
#ra2web-root .con-info-form td {
width: 70px;
padding: 3px 0;
}
#ra2web-root .con-info-form th.player-name,
#ra2web-root .con-info-form td.player-name {
width: 150px;
}
#ra2web-root .con-info-form th.player-ping,
#ra2web-root .con-info-form td.player-ping {
width: 250px;
}
#ra2web-root .con-info-form th.player-time,
#ra2web-root .con-info-form td.player-time {
width: 50px;
text-align: right;
}
#ra2web-root .con-info-form td.player-ping meter {
width: 100%;
height: 24px;
/* Needed for Firefox */
background: transparent;
border: 1px red solid;
}
#ra2web-root .player-ping meter::-webkit-meter-bar {
background: transparent;
border-radius: 0;
border: 1px red solid;
padding: 1px;
height: 24px;
}
#ra2web-root .player-ping meter::-moz-meter-bar {
background: transparent;
border-radius: 0;
margin: 1px;
height: 22px;
box-sizing: border-box;
}
#ra2web-root .player-ping meter::-webkit-meter-optimum-value {
background: limegreen;
}
#ra2web-root .player-ping meter:-moz-meter-optimum::-moz-meter-bar {
background: limegreen;
}
#ra2web-root .player-ping meter::-webkit-meter-suboptimum-value {
background: orange;
}
#ra2web-root .player-ping meter:-moz-meter-sub-optimum::-moz-meter-bar {
background: orange;
}
#ra2web-root .player-ping meter::-webkit-meter-even-less-good-value {
background: red;
}
#ra2web-root .player-ping meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
background: red;
}
#ra2web-root .prefetch-progress {
display: flex;
justify-content: center;
pointer-events: none;
color: red;
}
#ra2web-root .prefetch-progress > div {
padding: 0 5px;
background: rgba(0, 0, 0, .5);
}
#ra2web-root .prefetch-progress label {
margin-right: 10px;
}
#ra2web-root .prefetch-progress label,
#ra2web-root .prefetch-progress progress {
vertical-align: middle;
}
#ra2web-root .game-res-box.message-box,
#ra2web-root .patch-notes-box.message-box,
#ra2web-root .basic-error-box.message-box {
background: rgba(255, 255, 255, .1);
border: 2px #8d8d8d outset;
}
#ra2web-root .game-res-box.message-box,
#ra2web-root .patch-notes-box.message-box {
width: 640px;
height: 520px;
text-align: center;
/* Leave space for the disclaimer on low res */
margin-top: -30px;
}
#ra2web-root .game-res-box.message-box .message-box-content {
padding: 30px;
padding-top: 5px;
}
#ra2web-root .game-res-box.message-box .message-box-content .title {
font-size: 15px;
text-align: center;
margin: 8px 0 15px 0;
}
#ra2web-root .game-res-box.message-box .close-button {
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjIgKDY3MTQ1KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5iYXNlbGluZS1jbG9zZS0yNHB4PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9InJlQ3JlYXRlIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0idHhWaWV3X2dyYXBocyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTExMzIuMDAwMDAwLCAtMTk4LjAwMDAwMCkiIGZpbGw9InllbGxvdyIgZmlsbC1ydWxlPSJub256ZXJvIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMzAuMDAwMDAwLCAxNzYuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iR3JvdXAtMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIyLjAwMDAwMCwgMTYuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9ImJhc2VsaW5lLWNsb3NlLTI0cHgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDc4MC4wMDAwMDAsIDYuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgcG9pbnRzPSIxOSA2LjQxIDE3LjU5IDUgMTIgMTAuNTkgNi40MSA1IDUgNi40MSAxMC41OSAxMiA1IDE3LjU5IDYuNDEgMTkgMTIgMTMuNDEgMTcuNTkgMTkgMTkgMTcuNTkgMTMuNDEgMTIiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==");
width: 24px;
height: 24px;
position: absolute;
top: 8px;
right: 8px;
cursor: pointer;
}
#ra2web-root .game-res-box.message-box .message-box-content .drop-container {
border: 2px dashed #353535;
background-repeat: no-repeat;
background-image: url(res/img/download-arrow.png);
background-position: 50% 170px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#ra2web-root .game-res-box.message-box .message-box-content .drop-container.dropzone-active {
background: rgba(255, 255, 255, .2);
}
#ra2web-root .game-res-box.message-box .message-box-content .drop-container .drop-figures {
color: white;
font-size: 16px;
height: 153px;
margin-bottom: 40px;
pointer-events: none;
}
#ra2web-root .game-res-box.message-box .message-box-content .drop-container .drop-figures * {
vertical-align: middle;
margin: 0 10px 0 15px;
display: inline-block;
}
#ra2web-root .game-res-box.message-box .message-box-content .drop-container .desc {
color: #777;
font-size: 14px;
}
#ra2web-root .game-res-box.message-box .message-box-content .browse-buttons {
text-align: center;
}
#ra2web-root .game-res-box.message-box .message-box-content .browse-buttons .dialog-button:first-child {
margin-right: 10px;
}
#ra2web-root .game-res-box.message-box .message-box-content .dialog-button,
#ra2web-root .basic-error-box.message-box .message-box-footer .dialog-button {
display: inline-block;
margin: 0;
background: darkred;
border: 1px red outset;
}
#ra2web-root .game-res-box.message-box .message-box-content .dialog-button:hover:not(:disabled),
#ra2web-root .basic-error-box.message-box .message-box-footer .dialog-button:hover:not(:disabled) {
background: orangered;
}
#ra2web-root .game-res-box.message-box .message-box-content .link-container .link-field {
display: flex;
align-items: baseline;
}
#ra2web-root .game-res-box.message-box .message-box-content .link-container .link-field input {
margin-left: 8px;
flex-grow: 1;
display: block;
background: rgba(255, 255, 255, .1);
border-color: #ccc;
border-style: inset;
}
#ra2web-root .game-res-box.message-box .message-box-content .link-container .download-button {
text-align: center;
}
#ra2web-root .game-res-box.message-box .message-box-content .browse-container .archive-formats {
text-align: center;
}
#ra2web-root .game-res-box.message-box .message-box-content em {
font-size: 11px;
}
#ra2web-root .patch-notes-box.message-box .message-box-content {
height: calc(100% - 65px);
padding: 0;
border-bottom: 1px darkgray solid;
}
#ra2web-root .patch-notes-box.message-box .message-box-content iframe {
padding: 0;
}
#ra2web-root .score-wrapper {
margin: 86px;
padding: 8px;
box-sizing: border-box;
background-color: rgba(0, 0, 0, .65);
}
#ra2web-root .score-wrapper .score-title {
display: flex;
justify-content: space-between;
align-items: center;
height: 19px;
padding-bottom: 8px;
margin-bottom: 8px;
border-bottom: 1px red solid;
}
#ra2web-root .score-wrapper .score-title .game-result {
font-size: 16px;
text-transform: uppercase;
}
#ra2web-root .score-wrapper .score-title .points-gain-value {
color: orangered;
}
#ra2web-root .score-wrapper .score-title .points-gain-value.positive {
color: lime;
}
#ra2web-root .score-wrapper .score-header {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
}
#ra2web-root .score-wrapper table {
margin: 0 auto;
}
#ra2web-root .score-wrapper thead {
color: yellow;
text-align: left;
}
#ra2web-root .score-wrapper th {
font-weight: 500;
}
#ra2web-root .score-wrapper td {
text-shadow: 1px 1px black;
}
#ra2web-root .score-wrapper th,
#ra2web-root .score-wrapper td {
width: 70px;
padding: 5px 0;
}
#ra2web-root .score-wrapper .number {
text-align: right;
}
#ra2web-root .score-wrapper th.player-rank,
#ra2web-root .score-wrapper td.player-rank {
width: 20px;
min-width: 20px;
}
#ra2web-root .score-wrapper th.player-name,
#ra2web-root .score-wrapper td.player-name {
width: 200px;
}
#ra2web-root .score-wrapper th.player-mmr,
#ra2web-root .score-wrapper td.player-mmr {
width: 100px;
}
#ra2web-root .score-wrapper td.player-mmr .mmr-gain.positive {
color: lime;
}
#ra2web-root .score-wrapper td.player-mmr .mmr-gain {
color: orangered;
}
#ra2web-root .patch-notes,
#ra2web-root .ladder-rules {
padding: 5px;
box-sizing: border-box;
border: 0;
height: 100%;
width: 100%;
}
#ra2web-root .credits-container {
overflow-y: auto;
overflow-x: hidden;
margin: 7px;
height: calc(100% - 11px);
width: calc(100% - 12px);
}
#ra2web-root .credits-container .credits {
padding: 32px;
text-align: center;
}
#ra2web-root .credits-container .credits .def {
display: flex;
margin: 0 auto;
width: 75%;
}
#ra2web-root .credits-container .credits .def .filler {
flex-grow: 1;
}
#ra2web-root .storage-explorer {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 8px;
}
#ra2web-root .storage-explorer .fe_fileexplorer_wrap {
font-size: 16px !important;
color: #000 !important;
}
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_path_segments_scroll_wrap::-webkit-scrollbar,
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_folder_tools_scroll_wrap::-webkit-scrollbar,
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay::-webkit-scrollbar,
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_textarea::-webkit-scrollbar {
border: 0 !important;
width: 0 !important;
height: 0 !important;
}
#ra2web-root .storage-explorer .fe_fileexplorer_wrap button,
#ra2web-root .storage-explorer .fe_fileexplorer_wrap input,
#ra2web-root .storage-explorer .fe_fileexplorer_wrap select {
color: inherit !important;
}
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_popup_wrap {
color: inherit !important;
}
#ra2web-root .storage-explorer .fe_fileexplorer_wrap .fe_fileexplorer_items_wrap {
padding-right: 2px;
}
#ra2web-root .qm-form {
padding: 16px;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
#ra2web-root .qm-form .qm-top {
min-height: 275px;
display: flex;
justify-content: space-between;
}
#ra2web-root .qm-form .opts {
flex-grow: 1;
margin-top: 9px;
margin-right: 10px;
border: 1px red solid;
padding: 20px 0 0 0;
}
#ra2web-root .qm-form .opts .item {
margin: 0;
}
#ra2web-root .qm-form .opts .item + .item {
margin-top: 15px;
}
#ra2web-root .qm-form .opts .item span.label {
width: 140px;
}
#ra2web-root .qm-form .item.qm-game-type-item {
margin-top: 5px;
}
#ra2web-root .qm-form .qm-game-type {
display: inline-block;
vertical-align: top;
margin-top: -5px;
}
#ra2web-root .qm-form .qm-game-type .button-select {
display: block;
}
#ra2web-root .qm-form .qm-game-type > .button-select + .button-select {
margin-top: 8px;
}
#ra2web-root .button-select {
display: inline-block;
vertical-align: middle;
}
#ra2web-root .button-select div {
display: inline-block;
}
#ra2web-root .button-select .option {
border: 1px red solid;
font-size: 14px;
padding: 4px 8px 3px 8px;
background: rgba(0, 0, 0, .75);
}
#ra2web-root .button-select .option:hover,
#ra2web-root .button-select .option.selected {
border-color: orange;
}
#ra2web-root .button-select .option.disabled {
color: gray;
border-color: gray;
}
#ra2web-root .button-select > div + div {
margin-left: 8px;
}
#ra2web-root .qm-form .country-select {
display: inline-flex;
flex-direction: row-reverse;
}
#ra2web-root .qm-form fieldset.qm-profile {
width: 170px;
margin-inline: 0;
}
#ra2web-root .qm-form .qm-profile legend {
font-size: 16px;
}
#ra2web-root .qm-form .qm-profile .placement {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
margin-top: 0 !important;
text-align: center;
}
#ra2web-root .qm-form .qm-profile .player-rank {
margin-bottom: 16px;
}
#ra2web-root .qm-form .qm-profile .player-rank .rank-indicator {
vertical-align: middle;
margin-left: 0;
}
#ra2web-root .qm-form .qm-profile .player-rank .rank-name {
font-size: 16px;
}
#ra2web-root .qm-form .qm-profile .player-rank .rank-number {
margin-left: 20px;
margin-top: 3px;
color: cyan;
}
#ra2web-root .qm-form .qm-profile * + .item {
margin-top: 15px;
}
/* Mobile touch controls - hidden on desktop */
.mobile-touch-controls {
display: none;
}
#ra2web-root[data-mobile-layout="true"] .mobile-touch-controls {
display: flex;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
gap: 24px;
z-index: 1000;
pointer-events: auto;
}
.mobile-touch-btn {
width: 56px;
height: 56px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.4);
background: rgba(0, 0, 0, 0.2);
color: rgba(255, 255, 255, 0.5);
font-size: 20px;
font-weight: bold;
font-family: inherit;
cursor: pointer;
touch-action: manipulation;
user-select: none;
-webkit-user-select: none;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.mobile-touch-btn.active {
background: rgba(255, 255, 255, 0.25);
border-color: rgba(255, 255, 255, 0.8);
color: rgba(255, 255, 255, 0.9);
}
#ra2web-root .qm-form .qm-profile .value {
float: right;
}
#ra2web-root .qm-form .qm-profile .rank-indicator {
display: inline-block;
vertical-align: top;
margin-left: 3px;
}
#ra2web-root .qm-form .qm-profile .promo-progress span.label {
display: block;
}
#ra2web-root .qm-form .qm-profile .promo-progress .value {
display: block;
width: 100%;
text-align: left;
margin-top: 8px;
float: none;
}
#ra2web-root .qm-form .qm-profile .promo-progress.demotion .value {
color: orangered;
}
#ra2web-root .qm-form .qm-profile .promo-progress .next-rank .promotion-indicator {
color: lime;
}
#ra2web-root .qm-form .qm-profile .promo-progress .next-rank .demotion-indicator {
text-shadow: 0px 0px 5px orange;
}
#ra2web-root .qm-form .qm-profile .promo-progress progress {
width: 100%;
}
#ra2web-root .qm-form .qm-profile hr {
border-top: 1px solid;
border-bottom: 0;
border-color: dimgray;
margin: 15px 0 8px 0;
}
#ra2web-root .qm-form .qm-profile .info {
vertical-align: top;
margin-left: 3px;
}
#ra2web-root .qm-form .qm-bottom {
margin-top: 15px;
display: flex;
flex-direction: row;
overflow-y: auto;
flex: 1;
}
#ra2web-root .qm-form .qm-bottom .chat-wrapper {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-basis: min-content;
}
#ra2web-root .qm-form .qm-bottom .chat-wrapper .messages {
height: auto;
flex-grow: 1;
}
#ra2web-root .qm-form .qm-bottom .players-list {
height: auto;
width: 190px;
box-sizing: border-box;
margin-left: 10px;
}
#ra2web-root .ladder {
padding: 20px;
}
#ra2web-root .ladder .toolbar {
margin-bottom: 10px;
display: flex;
/* justify-content: center; */
}
#ra2web-root .ladder .ladder-content {
display: flex;
align-items: flex-start;
margin: 0 auto;
}
#ra2web-root .ladder .ladder-content .ladder-types {
margin-right: 10px;
width: 130px;
box-sizing: border-box;
}
#ra2web-root .ladder .ladder-content .list.ladder-types {
border: 0px;
}
#ra2web-root .ladder .ladder-content .list.ladder-types .list-item {
border: 1px red solid;
padding: 4px 8px 3px 8px;
}
#ra2web-root .ladder .ladder-content .list.ladder-types .list-item:not(.selected) {
background-color: #480000;
}
#ra2web-root .ladder .ladder-content .list.ladder-types .list-item:hover {
background-color: red;
}
#ra2web-root .ladder .ladder-content .list.ladder-types .list-item + .list-item {
margin-top: 8px;
}
#ra2web-root .ladder .ladder-content .season-info {
padding: 24px;
box-sizing: border-box;
}
#ra2web-root .ladder .ladder-content .season-info .item {
margin-top: 16px;
}
#ra2web-root .ladder .ladder-content .season-info header + .item {
margin-top: 32px;
}
#ra2web-root .ladder .ladder-content .season-info h2 {
margin-top: 0;
}
#ra2web-root .ladder .season-info,
#ra2web-root .ladder table {
border: 1px red solid;
width: 450px;
}
#ra2web-root .ladder table {
border-collapse: collapse;
}
#ra2web-root .ladder table th,
#ra2web-root .ladder table td {
font-size: 13px;
padding: 3px 8px;
}
#ra2web-root .ladder table thead th {
border-bottom: 1px red solid;
text-align: left;
}
#ra2web-root .ladder table thead th.player-rank-icon {
width: 20px;
}
#ra2web-root .ladder table thead th.player-name {
width: 200px;
}
#ra2web-root .ladder .player-rank-icon .rank-indicator {
display: inline-block;
vertical-align: top;
}
#ra2web-root .ladder table tr:nth-child(2n) {
background-color: rgba(21, 21, 21, .75);
}
#ra2web-root .ladder table tr:nth-child(2n+1) {
background-color: rgba(55, 55, 55, .75);
}
#ra2web-root .ladder table tr.selected {
background-color: red;
}
#ra2web-root .ladder table tr.disabled {
color: gray;
}
#ra2web-root .ladder .pagination {
margin-top: 10px;
display: flex;
justify-content: center;
}
#ra2web-root .ladder button {
appearance: none;
border: 1px red solid;
background-color: #480000;
padding: 4px 8px 3px 8px;
}
#ra2web-root .ladder * + button {
margin-left: 5px;
}
#ra2web-root .ladder button:hover:not(:disabled) {
background-color: orangered;
}
#ra2web-root .ladder button:disabled {
color: gray;
}
#ra2web-root .ladder .toolbar.no-season-select {
padding-left: 140px;
min-height: 26px;
}
#ra2web-root .ladder .season-select,
#ra2web-root .ladder .ladder-select {
width: 130px;
margin-right: 10px;
}
#ra2web-root .ladder .ladder-select {
width: auto;
min-width: 200px;
}
#ra2web-root .ladder .ladder-select .select-layer {
max-height: 320px;
overflow-y: auto;
}
#ra2web-root .ladder .player-search {
display: flex;
}
#ra2web-root .ladder .player-search .player {
margin-right: 5px;
width: 100px;
}
#ra2web-root .game-chat-input {
width: 400px;
display: flex;
align-items: center;
font-size: 13px;
padding: 0 4px;
background: rgba(0, 0, 0, .75)
}
#ra2web-root .game-chat-input input {
flex-grow: 1;
border: 0;
height: 20px;
font-size: 13px;
}
/* Bot Upload Dialog */
#ra2web-root .bot-upload-dialog-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
#ra2web-root .bot-upload-dialog {
background: #5a0000;
border: 2px solid #8B0000;
border-radius: 4px;
width: 460px;
max-height: 80vh;
display: flex;
flex-direction: column;
color: #FFD700;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.7), 0 0 15px rgba(139, 0, 0, 0.5);
}
#ra2web-root .bot-upload-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid #8B0000;
background: #700000;
}
#ra2web-root .bot-upload-header h3 {
margin: 0;
font-size: 15px;
color: #ffd700;
}
#ra2web-root .bot-upload-close {
background: none;
border: none;
color: #FFD700;
font-size: 20px;
cursor: pointer;
padding: 0 4px;
}
#ra2web-root .bot-upload-close:hover {
color: #FFF8DC;
}
#ra2web-root .bot-upload-body {
padding: 16px;
overflow-y: auto;
flex: 1;
}
#ra2web-root .bot-upload-section {
margin-bottom: 16px;
}
#ra2web-root .bot-upload-section h4 {
margin: 0 0 8px;
font-size: 13px;
color: #FFD700;
}
#ra2web-root .bot-upload-label {
display: block;
margin-bottom: 6px;
font-size: 13px;
color: #FFD700;
}
#ra2web-root .bot-upload-input {
width: 100%;
font-size: 12px;
padding: 6px;
box-sizing: border-box;
}
#ra2web-root .bot-upload-hint {
margin-top: 4px;
font-size: 11px;
color: #D4A017;
}
#ra2web-root .bot-upload-status {
padding: 8px;
text-align: center;
color: #FFD700;
font-size: 13px;
}
#ra2web-root .bot-upload-message {
padding: 8px 12px;
border-radius: 3px;
margin-bottom: 12px;
font-size: 12px;
white-space: pre-wrap;
}
#ra2web-root .bot-upload-message-success {
background: rgba(255, 215, 0, 0.15);
border: 1px solid rgba(255, 215, 0, 0.3);
color: #FFD700;
}
#ra2web-root .bot-upload-message-error {
background: rgba(255, 0, 0, 0.2);
border: 1px solid rgba(255, 80, 80, 0.5);
color: #FF6B6B;
}
#ra2web-root .bot-upload-empty {
color: #D4A017;
font-size: 12px;
text-align: center;
padding: 12px;
}
#ra2web-root .bot-upload-list {
list-style: none;
margin: 0;
padding: 0;
}
#ra2web-root .bot-upload-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 8px;
border-bottom: 1px solid #8B0000;
font-size: 12px;
}
#ra2web-root .bot-upload-item:last-child {
border-bottom: none;
}
#ra2web-root .bot-upload-item-info {
display: flex;
gap: 8px;
align-items: center;
}
#ra2web-root .bot-upload-item-name {
color: #FFD700;
font-weight: bold;
}
#ra2web-root .bot-upload-item-version {
color: #D4A017;
}
#ra2web-root .bot-upload-item-author {
color: #B8860B;
}
#ra2web-root .bot-upload-item-remove {
background: rgba(139, 0, 0, 0.5);
border: 1px solid #B22222;
color: #FFD700;
padding: 2px 8px;
font-size: 11px;
cursor: pointer;
border-radius: 2px;
}
#ra2web-root .bot-upload-item-remove:hover {
background: rgba(178, 34, 34, 0.7);
}
#ra2web-root .bot-upload-footer {
padding: 12px 16px;
border-top: 1px solid #8B0000;
background: #700000;
text-align: right;
}
#ra2web-root .bot-upload-btn {
background: rgba(139, 0, 0, 0.5);
border: 1px solid #B22222;
color: #FFD700;
padding: 4px 12px;
font-size: 12px;
cursor: pointer;
border-radius: 2px;
margin-left: 8px;
}
#ra2web-root .bot-upload-btn:hover {
background: rgba(178, 34, 34, 0.7);
}
================================================
FILE: public/mods.ini
================================================
[General]
1=athse
2=gonghui
3=meisuzhenba
[gonghui]
ID=gonghui
Name=共和国之辉
Description=风靡全球的低质量MOD移植到网页平台,更多平衡性提高!
Author=共和国之辉网
Version=Rev.2025.05.01.1
Website=https://www.gongheguozhihui.com
Download=https://ra2webmod.k0s.cn/mod/gonghui/gonghui-05012025-1.zip
DownloadSize=2028803
[athse]
ID=athse
Name=Scorched Earth
Description=A mature overhaul of RA2, with an emphasis on the best combat experience.
Author=G-E
Version=Rev.2023.06.11
Website=https://www.moddb.com/mods/scorched-earth-ra2-mod-with-smart-ai
Download=athse/athse-snapshot-06112023.rar
DownloadSize=112948223
[meisuzhenba]
ID=meisuzhenba
Name=红色警戒2原版阵营补丁
Description=将所有的子阵营合并成两个,但是美国可以建造巨炮、黑鹰、狙击手、坦克杀手,苏联可以建造辐射工兵、自爆卡车、恐怖分子
Author=QQ2174328393
Version=Rev.1
Website=https://www.bilibili.com
Download=https://download.ra2web.com/meisuzhenba-v1.zip
DownloadSize=97419
================================================
FILE: public/other/file-explorer.css
================================================
.fe_fileexplorer_hidden { display: none !important; }
.fe_fileexplorer_invisible { visibility: hidden; }
.fe_fileexplorer_disabled { filter: grayscale(95%); opacity: 0.6; }
.fe_fileexplorer_open_icon { background-image: url('fileexplorer_sprites.png'); width: 24px; height: 24px; background-position: -48px -96px; image-rendering: pixelated; }
.fe_fileexplorer_wrap { position: relative; font-size: 1.0em; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; cursor: default; height: 100%; min-height: 9em; }
.fe_fileexplorer_wrap .fe_fileexplorer_operation_in_progress { cursor: progress; }
.fe_fileexplorer_wrap .fe_fileexplorer_operation_in_progress button { cursor: progress; }
.fe_fileexplorer_wrap .fe_fileexplorer_dropzone_wrap { height: 100%; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap { border: 1px solid #AAAAAA; color: #000000; background-color: #FFFFFF; display: flex; flex-direction: column; height: 100%; box-sizing: border-box; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused { border: 1px solid #0063B1; }
.fe_fileexplorer_wrap button::-moz-focus-inner { border: 0; }
.fe_fileexplorer_wrap .fe_fileexplorer_toolbar { display: flex; margin-top: 0.4em; align-items: center; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtools { display: flex; margin-left: 5px; margin-right: 0.1em; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtools button { padding: 0; border: 0 none; box-sizing: border-box; height: 24px; background-color: transparent; outline: none; background-repeat: no-repeat; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtools button.fe_fileexplorer_disabled { opacity: 0.4; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_back { background-image: url('fileexplorer_sprites.png'); width: 32px; background-position: -0px -0px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_forward { background-image: url('fileexplorer_sprites.png'); width: 32px; background-position: -64px -0px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_history { background-image: url('fileexplorer_sprites.png'); width: 18px; background-position: -84px -24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_up { background-image: url('fileexplorer_sprites.png'); width: 24px; background-position: -0px -24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_back:not(.fe_fileexplorer_disabled):hover, .fe_fileexplorer_wrap .fe_fileexplorer_navtool_back:not(.fe_fileexplorer_disabled):focus { background-image: url('fileexplorer_sprites.png'); width: 32px; background-position: -32px -0px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_forward:not(.fe_fileexplorer_disabled):hover, .fe_fileexplorer_wrap .fe_fileexplorer_navtool_forward:not(.fe_fileexplorer_disabled):focus { background-image: url('fileexplorer_sprites.png'); width: 32px; background-position: -96px -0px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_history:not(.fe_fileexplorer_disabled):hover, .fe_fileexplorer_wrap .fe_fileexplorer_navtool_history:not(.fe_fileexplorer_disabled):focus { background-image: url('fileexplorer_sprites.png'); width: 18px; background-position: -102px -24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_navtool_up:not(.fe_fileexplorer_disabled):hover, .fe_fileexplorer_wrap .fe_fileexplorer_navtool_up:not(.fe_fileexplorer_disabled):focus { background-image: url('fileexplorer_sprites.png'); width: 24px; background-position: -24px -24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_wrap { display: flex; flex: 1; align-items: center; overflow: hidden; border: 1px solid #D9D9D9; margin-right: 12px; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_icon { height: 24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_icon_inner { background-image: url('fileexplorer_sprites.png'); width: 24px; height: 24px; margin-left: 2px; margin-right: 4px; background-position: -72px -96px; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segments_scroll_wrap { flex: 1; position: relative; overflow-x: scroll; box-sizing: border-box; scrollbar-width: none; -ms-overflow-style: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segments_scroll_wrap::-webkit-scrollbar { height: 0px; background: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segments_wrap { display: flex; flex: 1; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segments_wrap button { padding: 0.5em; border: 1px solid transparent; box-sizing: border-box; line-height: 1; background-color: transparent; outline: none; font-size: 0.75em; white-space: nowrap; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segments_wrap::after { content: ''; padding-left: 10%; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap { display: flex; border: 1px solid transparent; outline: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap::-moz-focus-inner { border: 0; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap .fe_fileexplorer_path_opts { padding: 0; background-repeat: no-repeat; background-image: url('fileexplorer_sprites.png'); width: 18px; background-position: -48px -24px; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap:hover { border: 1px solid #CCE8FF; background-color: #E5F3FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap:hover .fe_fileexplorer_path_opts { padding: 0; border-left: 1px solid #CCE8FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap:focus, .fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap.fe_fileexplorer_path_segment_wrap_focus { border: 1px solid #99D1FF; background-color: #CCE8FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap:focus .fe_fileexplorer_path_opts, .fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap.fe_fileexplorer_path_segment_wrap_focus .fe_fileexplorer_path_opts { border-left: 1px solid #99D1FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap.fe_fileexplorer_path_segment_wrap_down .fe_fileexplorer_path_name { padding: calc(0.5em + 1px) calc(0.5em - 1px) calc(0.5em - 1px) calc(0.5em + 1px); }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap.fe_fileexplorer_path_segment_wrap_down .fe_fileexplorer_path_opts { background-image: url('fileexplorer_sprites.png'); background-position: -84px -24px; }
.fe_fileexplorer_wrap .fe_fileexplorer_path_segment_wrap.fe_fileexplorer_drag_hover { border: 1px solid #99D1FF; background-color: #CCE8FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_body_wrap_outer { flex: 1; display: flex; margin-top: 0.3em; overflow: hidden; position: relative; }
.fe_fileexplorer_wrap .fe_fileexplorer_body_wrap { display: flex; align-items: stretch; overflow: hidden; min-height: 5em; width: 100%; height: 100%; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools_scroll_wrap { padding: 0.4em 10px; border-right: 1px solid #CCE8FF; overflow-y: scroll; box-sizing: border-box; scrollbar-width: none; -ms-overflow-style: none; position: relative; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools_scroll_wrap::-webkit-scrollbar { width: 0px; background: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools { display: flex; flex-direction: column; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools button { margin-bottom: 0.3em; border: 1px solid transparent; box-sizing: border-box; padding: 4px; width: 34px; height: 34px; background-color: transparent; outline: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools button::before { display: block; width: 24px; height: 24px; content: ''; background-repeat: no-repeat; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tools button:not(.fe_fileexplorer_disabled):hover, .fe_fileexplorer_wrap .fe_fileexplorer_folder_tools button:not(.fe_fileexplorer_disabled):focus { border: 1px solid #99D1FF; background-color: #E5F3FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_separator { margin: 0 -0.1em 0.3em; border-top: 1px solid #DFE7F0; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_new_folder::before { background-image: url('fileexplorer_sprites.png'); background-position: -24px -144px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_new_file::before { background-image: url('fileexplorer_sprites.png'); background-position: -0px -144px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_upload::before { background-image: url('fileexplorer_sprites.png'); background-position: -96px -144px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_download::before { background-image: url('fileexplorer_sprites.png'); background-position: -96px -120px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_copy::before { background-image: url('fileexplorer_sprites.png'); background-position: -24px -120px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_paste::before { background-image: url('fileexplorer_sprites.png'); background-position: -48px -144px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_cut::before { background-image: url('fileexplorer_sprites.png'); background-position: -48px -120px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_delete::before { background-image: url('fileexplorer_sprites.png'); background-position: -72px -120px; }
.fe_fileexplorer_wrap .fe_fileexplorer_folder_tool_item_checkboxes::before { background-image: url('fileexplorer_sprites.png'); background-position: -72px -144px; }
.fe_fileexplorer_wrap .fe_fileexplorer_show_item_checkboxes .fe_fileexplorer_folder_tool_item_checkboxes::before { background-image: url('fileexplorer_sprites.png'); background-position: -0px -120px; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_scroll_wrap { flex: 1; overflow-y: auto; box-sizing: border-box; outline: none; position: relative; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_scroll_wrap::-moz-focus-inner { border: 0; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_scroll_wrap_inner { position: relative; min-height: 100%; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_message_wrap { padding: 1.5em 1em 1em 1em; color: #6D6D6D; font-size: 0.75em; text-align: center; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_wrap { display: flex; flex-wrap: wrap; padding: 0.3em 12px 0.2em 4px; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap { margin-left: 0.56em; margin-bottom: 1px; width: 4.7em; box-sizing: border-box; text-align: center; overflow: hidden; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap_inner { position: relative; border: 1px solid transparent; padding: 0.1em 0.3em; outline: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap_inner::-moz-focus-inner { border: 0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap_inner:hover { background-color: #E5F3FF; border-color: #E5F3FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap:not(.fe_fileexplorer_inner_wrap_focused) .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner { background-color: #D9D9D9; border-color: #D9D9D9; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap:not(.fe_fileexplorer_inner_wrap_focused) .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner:hover { background-color: #E5F3FF; border-color: #99D1FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap:not(.fe_fileexplorer_items_focus) .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner { background-color: #D9D9D9; border-color: #D9D9D9; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap:not(.fe_fileexplorer_items_focus) .fe_fileexplorer_item_wrap_inner:hover { background-color: #E5F3FF; border-color: #99D1FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_selecting .fe_fileexplorer_item_wrap_inner { background-color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_focus .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner { background-color: #CDE8FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_focus .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner:hover { border-color: #99D1FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_focus .fe_fileexplorer_item_selected.fe_fileexplorer_item_focused .fe_fileexplorer_item_wrap_inner { background-color: #CCE8FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_focus .fe_fileexplorer_item_focused .fe_fileexplorer_item_wrap_inner { border-color: #99D1FF; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap .fe_fileexplorer_items_wrap .fe_fileexplorer_item_wrap.fe_fileexplorer_drag_hover .fe_fileexplorer_item_wrap_inner { background-color: #CDE8FF; }
/*
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_copy { cursor: copy; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_move_copy .fe_fileexplorer_item_folder:not(.fe_fileexplorer_item_selected) .fe_fileexplorer_item_wrap_inner:hover { background-color: #CDE8FF; border-color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_move_copy .fe_fileexplorer_item_wrap:not(.fe_fileexplorer_item_folder):not(.fe_fileexplorer_item_selected) .fe_fileexplorer_item_wrap_inner { opacity: 0.7; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_move_copy .fe_fileexplorer_item_wrap:not(.fe_fileexplorer_item_folder):not(.fe_fileexplorer_item_selected) .fe_fileexplorer_item_wrap_inner:hover { background-color: transparent; border-color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap.fe_fileexplorer_items_move_copy .fe_fileexplorer_item_wrap.fe_fileexplorer_item_selected:not(.fe_fileexplorer_item_focused) .fe_fileexplorer_item_wrap_inner:hover { border-color: transparent; }
*/
.fe_fileexplorer_wrap .fe_fileexplorer_item_checkbox { position: absolute; left: 0; top: 0; margin: 2px; z-index: 1; display: none; padding: initial; border: initial; transform: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_show_item_checkboxes .fe_fileexplorer_item_wrap_inner:hover .fe_fileexplorer_item_checkbox { display: block; }
.fe_fileexplorer_wrap .fe_fileexplorer_show_item_checkboxes .fe_fileexplorer_item_selected .fe_fileexplorer_item_checkbox { display: block; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon { width: 48px; height: 48px; margin-left: auto; margin-right: auto; background-repeat: no-repeat; position: relative; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_img { width: auto; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon img { position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%); max-width: 100%; max-height: calc(100% - 2px); -webkit-box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.15); box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.15); }
.fe_fileexplorer_wrap .fe_fileexplorer_item_text { margin-top: 0.1em; font-size: 0.75em; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; word-wrap: break-word; overflow: hidden; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_text.fe_fileexplorer_invisible { color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_folder { background-image: url('fileexplorer_sprites.png'); background-position: -48px -48px; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file { background-image: url('fileexplorer_sprites.png'); background-position: -0px -48px; image-rendering: pixelated; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext)::after { position: absolute; bottom: 10px; left: 0px; box-sizing: border-box; content: attr(data-ext); color: #FFFFFF; font-size: 11px; padding: 1px 3px; width: 36px; overflow: hidden; white-space: nowrap; background-color: #888888; text-transform: uppercase; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_a::after { background-color: #F03C3C; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_b::after { background-color: #F05A3C; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_c::after { background-color: #F0783C; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_d::after { background-color: #F0963C; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_e::after { background-color: #E0862B; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_f::after { background-color: #DCA12B; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_g::after { background-color: #C7AB1E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_h::after { background-color: #C7C71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_i::after { background-color: #ABC71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_j::after { background-color: #8FC71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_k::after { background-color: #72C71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_l::after { background-color: #56C71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_m::after { background-color: #3AC71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_n::after { background-color: #1EC71E; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_o::after { background-color: #1EC73A; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_p::after { background-color: #1EC756; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_q::after { background-color: #1EC78F; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_r::after { background-color: #1EC7AB; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_s::after { background-color: #1EC7C7; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_t::after { background-color: #1EABC7; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_u::after { background-color: #1E8FC7; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_v::after { background-color: #1E72C7; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_w::after { background-color: #3C78F0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_x::after { background-color: #3C5AF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_y::after { background-color: #3C3CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_z::after { background-color: #5A3CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_0::after { background-color: #783CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_1::after { background-color: #963CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_2::after { background-color: #B43CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_3::after { background-color: #D23CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_4::after { background-color: #F03CF0; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_5::after { background-color: #F03CD2; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_6::after { background-color: #F03CB4; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_7::after { background-color: #F03C96; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_8::after { background-color: #F03C78; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_icon_file:not(.fe_fileexplorer_item_icon_file_no_ext).fe_fileexplorer_item_icon_ext_9::after { background-color: #F03C5A; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap { position: absolute; left: 53px; top: 0; width: calc(100% - 53px); height: 100%; pointer-events: none; z-index: 2; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap.fe_fileexplorer_items_show_clipboard_overlay_paste { height: 200px; max-height: 75%; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_inner_wrap { position: relative; height: 100%; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_text_wrap { position: absolute; left: 0; top: 0; width: 100%; height: 100%; box-sizing: border-box; background-color: rgba(255, 255, 255, 0.95); border: 2px dashed #AAAAAA; -webkit-box-shadow: 2px 3px 5px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 2px 3px 5px 0px rgba(0, 0, 0, 0.15); box-shadow: 2px 3px 5px 0px rgba(0, 0, 0, 0.15); }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap:hover .fe_fileexplorer_items_clipboard_overlay_paste_text_wrap, .fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap_focus .fe_fileexplorer_items_clipboard_overlay_paste_text_wrap { border-color: #3298FE; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap:not(.fe_fileexplorer_items_show_clipboard_overlay_paste) .fe_fileexplorer_items_clipboard_overlay_paste_text_wrap { display: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_text { position: absolute; left: 50%; top: 50%; color: #888888; transform: translate(-50%, -50%); text-align: center; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_text_big { font-size: 2em; margin-bottom: 0.3em; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_text_small { font-size: 0.75em; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay { position: absolute; left: 0; top: -10px; width: 100%; height: calc(100% + 10px); margin: 0; border: 0 none; padding: 0; color: transparent; background-color: transparent; text-shadow: 0px 0px 0px transparent; caret-color: transparent; cursor: default; resize: none; box-sizing: border-box; scrollbar-width: none; -ms-overflow-style: none; text-align: center; outline: none; font-size: 1px; line-height: 1; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay::-webkit-scrollbar { width: 0px; height: 0px; background: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap.fe_fileexplorer_items_clipboard_contextmenu .fe_fileexplorer_items_clipboard_overlay { pointer-events: auto; }
.fe_fileexplorer_wrap .fe_fileexplorer_items_clipboard_overlay_paste_wrap.fe_fileexplorer_items_show_clipboard_overlay_paste .fe_fileexplorer_items_clipboard_overlay { pointer-events: auto; }
.fe_fileexplorer_wrap .fe_fileexplorer_select_box { position: absolute; box-sizing: border-box; border: 1px solid #0078D7; background-color: rgba(0, 120, 215, 0.33); }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_wrap { display: flex; white-space: nowrap; font-size: 0.75em; color: #14273E; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_wrap.fe_fileexplorer_statusbar_wrap_multiline { display: block; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_text_wrap { display: flex; margin-left: 15px; margin-right: 12px; padding-top: 0.3em; padding-bottom: 0.3em; overflow: hidden; flex: 1; line-height: 1.1; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_text_segment_wrap { padding-right: 1em; border-right: 1px solid #F0F0F0; margin-right: 1em; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_text_segment_wrap_last { padding-right: 0; border-right: 0 none; margin-right: 0; overflow: hidden; text-overflow: ellipsis; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_measure_em_size { display: inline-block; position: fixed; left: -9999px; width: 1em; height: 1em; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_wrap { display: flex; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_wrap { display: flex; padding-top: 0.3em; padding-bottom: 0.3em; overflow: hidden; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_wrap { margin-left: 1em; border-left: 1px solid #F0F0F0; padding-left: 1em; overflow: hidden; text-overflow: ellipsis; line-height: 1.1; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_wrap_last { margin-right: 0.4em; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_cancel_wrap { padding-left: 0.6em; padding-right: 0.6em; line-height: 1.1; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_cancel_wrap::after { content: '\00D7'; font-weight: bold; outline: none; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_cancel_wrap:hover::after, .fe_fileexplorer_wrap .fe_fileexplorer_action_progress_cancel_wrap:focus::after { color: #E81123; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_wrap.fe_fileexplorer_statusbar_wrap_multiline .fe_fileexplorer_action_progress_wrap { width: 100%; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_wrap.fe_fileexplorer_statusbar_wrap_multiline .fe_fileexplorer_action_progress_msg_wrap:first-child { margin-left: 15px; border-left: 0 none; padding-left: 0; }
.fe_fileexplorer_wrap .fe_fileexplorer_statusbar_wrap.fe_fileexplorer_statusbar_wrap_multiline .fe_fileexplorer_action_progress_msg_wrap_last { flex-grow: 1; }
@font-face { font-family: 'fe_fileexplorer_actions'; src: url('fileexplorer_actions.woff?20200530-01') format('woff'); font-weight: normal; font-style: normal; font-display: block; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_icon { font-family: 'fe_fileexplorer_actions' !important; speak: none; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; line-height: 1; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_icon.fe_fileexplorer_action_progress_msg_icon_uploads_in_progress::before { content: '\E900'; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_icon.fe_fileexplorer_action_progress_msg_icon_queued::before { content: '\E901'; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_icon.fe_fileexplorer_action_progress_msg_icon_done::before { content: '\E902'; }
.fe_fileexplorer_wrap .fe_fileexplorer_action_progress_msg_icon.fe_fileexplorer_action_progress_msg_icon_errors::before { content: '\E903'; }
.fe_fileexplorer_popup_wrap { position: absolute; left: -9999px; max-height: 33vh; overflow: hidden; overflow-y: auto; border: 1px solid #A0A0A0; background-color: #F2F2F2; min-width: 11em; max-width: 17em; z-index: 100; -webkit-box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.57); -moz-box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.57); box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.57); font-size: 1.0em; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; cursor: default; outline: none; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_inner_wrap { position: relative; padding: 2px; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_split { margin-left: 34px; margin-top: 0.1em; border-top: 1px solid #D7D7D7; padding-top: 0.1em; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap { display: flex; align-items: center; box-sizing: border-box; outline: none; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap:focus { background-color: #C3DEF5; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_icon { height: 24px; image-rendering: pixelated; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_icon_inner { width: 24px; height: 24px; margin-left: 5px; margin-right: 5px; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_text { overflow: hidden; text-overflow: ellipsis; font-size: 0.75em; line-height: 1; white-space: nowrap; padding: 0.5em 0.3em; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_text.fe_fileexplorer_popup_item_active { font-weight: bold; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap.fe_fileexplorer_popup_item_disabled:focus { background-color: #E5E5E5; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap.fe_fileexplorer_popup_item_disabled .fe_fileexplorer_popup_item_text { color: #6D6D6D; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap.fe_fileexplorer_popup_item_disabled .fe_fileexplorer_popup_item_icon_inner { filter: grayscale(95%); opacity: 0.9; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap:focus .fe_fileexplorer_popup_item_icon_back { background-image: url('fileexplorer_sprites.png'); background-position: -96px -48px; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_wrap:focus .fe_fileexplorer_popup_item_icon_forward { background-image: url('fileexplorer_sprites.png'); background-position: -24px -96px; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_icon_check { background-image: url('fileexplorer_sprites.png'); background-position: -0px -96px; }
.fe_fileexplorer_popup_wrap .fe_fileexplorer_popup_item_icon_folder { background-image: url('fileexplorer_sprites.png'); background-position: -96px -96px; }
.fe_fileexplorer_textarea { position: absolute; resize: none; border: 1px solid #000000; padding: 1px; font-family: inherit; font-size: 0.75em; overflow-y: auto; box-sizing: border-box; scrollbar-width: none; -ms-overflow-style: none; text-align: center; outline: none; z-index: 2; }
.fe_fileexplorer_textarea::-webkit-scrollbar { width: 0px; height: 0px; background: transparent; }
.fe_fileexplorer_textarea[readonly] { color: #666666; }
.fe_fileexplorer_floating_drag_icon_wrap { position: fixed; left: -9999px; padding: 1.5em; pointer-events: none; border: 1px solid rgba(151, 220, 252, 0.4); background-image: linear-gradient(rgba(227, 245, 252, 0.4), rgba(189, 231, 252, 0.4)); z-index: 100; -webkit-box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.3); -moz-box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.3); box-shadow: 5px 5px 4px -3px rgba(0, 0, 0, 0.3); user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; }
.fe_fileexplorer_floating_drag_icon_wrap .fe_fileexplorer_floating_drag_icon_wrap_inner { position: relative; width: 48px; height: 48px; overflow: hidden; }
.fe_fileexplorer_floating_drag_icon_wrap .fe_fileexplorer_item_icon { width: 48px; height: 48px; background-repeat: no-repeat; position: relative; opacity: 0.82; image-rendering: pixelated; }
.fe_fileexplorer_floating_drag_icon_wrap .fe_fileexplorer_item_icon_folder { background-image: url('fileexplorer_sprites.png'); background-position: -48px -48px; image-rendering: pixelated; }
.fe_fileexplorer_floating_drag_icon_wrap .fe_fileexplorer_item_icon_file { background-image: url('fileexplorer_sprites.png'); background-position: -0px -48px; image-rendering: pixelated; }
.fe_fileexplorer_floating_drag_icon_wrap .fe_fileexplorer_floating_drag_icon_wrap_inner[data-numitems]::after { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -30%); padding: 0.1em 0.3em; font-size: 0.75em; background-color: #0074CC; border: 1px solid #FFFFFF; color: #FFFFFF; content: attr(data-numitems); }
.fe_fileexplorer_download_iframe_wrap { position: fixed; left: -9999px; border: 0 none; width: 1px; height: 1px; }
@media (pointer: coarse) {
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap { margin-top: 0.1em; margin-bottom: 0.1em; }
.fe_fileexplorer_wrap .fe_fileexplorer_show_item_checkboxes .fe_fileexplorer_item_checkbox { display: block; }
.fe_fileexplorer_wrap .fe_fileexplorer_item_wrap_inner:hover { background-color: transparent; border-color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap:not(.fe_fileexplorer_inner_wrap_focused) .fe_fileexplorer_item_selected .fe_fileexplorer_item_wrap_inner:hover { background-color: transparent; border-color: transparent; }
.fe_fileexplorer_wrap .fe_fileexplorer_inner_wrap.fe_fileexplorer_inner_wrap_focused .fe_fileexplorer_items_wrap:not(.fe_fileexplorer_items_focus) .fe_fileexplorer_item_wrap_inner:hover { background-color: transparent; border-color: transparent; }
}
================================================
FILE: public/res/fonts/fonts.css
================================================
/* Generated from https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:wght@500;600;700&display=swap */
/* cyrillic-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMl0ciZb.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMB0ciZb.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMh0ciZb.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMd0ciZb.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMt0ciZb.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMp0ciZb.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWQXOuMR0cg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMl0ciZb.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMB0ciZb.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMh0ciZb.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMd0ciZb.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMt0ciZb.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMp0ciZb.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWSnJuMR0cg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMl0ciZb.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMB0ciZb.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMh0ciZb.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMd0ciZb.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMt0ciZb.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMp0ciZb.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Fira Sans Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMR0cg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
================================================
FILE: public/res/locale/en-US.json
================================================
{
"gui:ok": "OK",
"txt_copyright": "© 2000 ELECTRONIC ARTS INC. ALL RIGHTS RESERVED",
"gui:wwbrand": "WESTWOOD STUDIOS™ IS AN ELECTRONIC ARTS™ BRAND",
"gui:loadingex": "Loading...",
"ts:disclaimer": "DISCLAIMER:\n\"Chrono Divide\" is a non-profit fan project and is in no way affiliated with Electronic Arts Inc.\nNo copyright infringement is intended. All rights are held by their respective owners.",
"ts:downloading": "Downloading...",
"ts:downloadingpg": "Downloading... (%.1f%%)",
"ts:downloadingpgsize": "Downloading %.1f MiB / %.1f MiB... (%d%%)",
"ts:downloadingpgunkn": "Downloading %.1f MiB...",
"ts:downloadfailed": "A remote resource could not be downloaded.",
"ts:gameres_locate_title": "Locate original game assets",
"ts:gameres_import_desc": "If you have a copy of RA2 already installed, you can import it below. You can also choose to import an archive containing *.mix files from the local filesystem or a web URL.",
"ts:gameres_drop_desc": "Drop the required game files here",
"ts:gameres_or": "OR",
"ts:gameres_browse_folder": "Select folder...",
"ts:gameres_browse_archive": "Select archive...",
"ts:gameres_supported_archive_formats": "Supported archive formats: rar, tar, tar.gz, tar.bz2, tar.xz, zip, 7z, exe (sfx)",
"ts:gameres_download_url": "URL:",
"ts:gameres_invalid_url": "Please enter a valid URL.",
"ts:gameres_insecure_url": "You must enter a secure URL (HTTPS).",
"ts:gameres_download_button": "Download",
"ts:gameres_download_size": "Download size: ~%d MiB",
"ts:import_preparing_for_import": "Preparing for import...",
"ts:import_loading_archive": "Loading archive...",
"ts:import_extracting_archive": "Extracting archive...\n\nThis may take a minute.",
"ts:import_extracting": "Extracting \"%s\"...",
"ts:import_importing": "Importing \"%s\"...",
"ts:import_importing_pg": "Importing \"%s\"... (%d%%)",
"ts:import_importing_long": "Importing \"%s\"...\n\nThis may take a minute.",
"ts:import_failed": "Failed to import game assets.",
"ts:import_file_not_found": "File \"%s\" not found.",
"ts:import_archive_download_failed": "The download failed.\n\nPlease ensure that the specified URL is accessible and that the server accepts cross-origin (CORS) requests. Alternatively, you can manually download the file by right-clicking on the link below and selecting \"Save link as...\":\n\n%s\n\nOnce the download is complete, close this dialog and import the file directly, without opening it.",
"ts:import_archive_extract_failed": "Archive extraction failed.",
"ts:import_invalid_archive": "Archive extraction failed. Please provide a valid archive.",
"ts:import_out_of_memory": "Ran out of memory while extracting archive. Please make sure you are using a 64-bit desktop browser with a memory limit of at least 1GiB per tab.",
"ts:import_load_files_failed": "Failed to load game files.",
"ts:import_checksum_mismatch": "File \"%s\" appears to be corrupt. Please make sure you are using a compatible game client as source (Origin or XWIS), updated to the latest version (v1.006).",
"ts:import_no_web_assembly": "WebAssembly is required for archive extraction.",
"ts:import_no_storage": "No browser storage is available. Please make sure you are not browsing in Private mode.",
"ts:storage_quota_exceeded": "Browser storage quota exceeded. Please make sure you have sufficient disk space and not browsing in Private mode.",
"ts:storage_io_error": "A file could not be read from browser storage. Please close this tab and re-open the game in a new tab. If the problem persists, clear all website data and retry.",
"ts:storage_migrating_file": "Moving \"%s\" to new storage system...",
"ts:replay_storage_migrating": "Migrating replay storage... (%d%%)",
"ts:warning": "Warning",
"ts:preloading": "Prefetching assets...",
"ts:reportbug": "Report a Bug",
"ts:reportbugtt": "You can report any bugs you find on our Discord server",
"ts:reportbugdesc": "You can submit a bug on our dedicated Discord server channel by following the link below:",
"ts:patchnotes": "Patch Notes",
"stt:patchnotes": "Displays the change log for each version of the game client",
"ts:infoandcredits": "Info & Credits",
"stt:infoandcredits": "View additional information and credits",
"ts:outdatedclient": "You are using an outdated client. Please refresh the page. If the problem persists, you may also need to clear your browser's cache.",
"txt_mismatch": "Game versions incompatible. The room you are trying to join is using a different game version.",
"gui:joinernomap": "You do not have %s.",
"ts:gamecrashed": "Grats. You broke it. :|\n\nThe game client has crashed unexpectedly. This is a fatal error.",
"ts:custommapcrash": "The current map is most likely unsupported or contains errors. Please contact the map author.",
"ts:desyncdetected": "Game desynchronization detected. This a fatal error.",
"ts:badnickname": "Nickname may contain only alphanumerical characters (A-Z, a-z, 0-9), underscore (_) or dash (-).",
"ts:toall": "To all:",
"ts:toallies": "To allies:",
"ts:to": "To %s:",
"ts:replaychatfrom": "(%s):",
"ts:chatfrom": "%s:",
"ts:chatfromallies": "%s (allies):",
"ts:pagefrom": "(%s):",
"ts:chatuserlink": "[%s]",
"ts:chattimestamp": "[%s]",
"ts:chatcyclehint": "Press (%s) to cycle chat recipients",
"ts:chatrestricted": "You are currently not allowed to speak in public games.",
"ts:stalematewarning": "Stalemate detected! The game will end in %d minutes unless any player trains a unit, constructs a building (except walls), destroys or captures an enemy building, gains resources (if owning at least a production building or Construction Yard).",
"ts:stalematetimer": "The game will end in:",
"ts:playerassetssplit": "Units and resources owned by %s have been split among remaining allies.",
"gui:mastervolume": "Master Volume",
"gui:sfxvolume": "SFX Volume",
"gui:ambientvolume": "Ambient Volume",
"gui:uivolume": "UI Volume",
"gui:creditsvolume": "Credits Volume",
"gui:requestaudiopermission": "The game requires your permission to play audio.\n\nTo prevent this message from being shown in the future, please allow audio to always play on this website from your browser settings.",
"gui:fullscreen": "Fullscreen (%s)",
"stt:fullscreen": "Toggle full screen mode",
"ts:hotkeyfswarning": "Some hotkeys may only be captured in full-screen",
"cmnd:togglefps": "Toggle FPS",
"cmnd:togglefpsdesc": "Toggles display of performance statistics, such as frame rate, memory usage and latency",
"ts:reconnectprompt": "Would you like to reconnect to your previous game?",
"ts:reconnect": "Reconnect",
"ts:gameplayopts": "Gameplay",
"ts:flyerlabel": "Show Flyer Helper",
"stt:flyerlabel": "Marks the position of flying units on the ground",
"ts:flyeralways": "Always",
"ts:flyerselected": "Selected",
"ts:flyernever": "Never",
"ts:attackmovebutton": "Attack/Move Button",
"stt:attackmovebutton": "Allows using a different mouse button for issuing orders versus selecting units",
"ts:attackmovebuttonleft": "Left Mouse",
"ts:attackmovebuttonright": "Right Mouse",
"ts:rightclickscroll": "Right Click Scrolling",
"stt:rightclickscroll": "When right mouse button is held, player can scroll around the map",
"ts:mouseaccel": "Mouse Acceleration",
"stt:mouseaccel": "Controls precision of mouse movements when the mouse pointer is captured",
"ts:mouseaccelhint": "Overrides the native OS setting on supported platforms. Disable this if you are experiencing unpredictable pointer movement.",
"ts:gfxopts": "Graphics",
"ts:resolution": "Resolution",
"ts:resolutionhint": "Maximum resolution is determined by your operating system settings and the size of the browser tab/window. You can use the browser zoom function ([Ctrl] + [+]/[-]) to adjust it.",
"ts:resolutionfit": "Fit window (%s)",
"ts:resolutionfullscreen": "Fullscreen (%s)",
"ts:gfxmodels": "Models",
"stt:gfxmodels": "Adjusts the quality of 3D voxel models",
"ts:gfxshadows": "Dynamic Shadows",
"stt:gfxshadows": "Adjust the quality of dynamically rendered shadows",
"ts:gfxqualityhigh": "High",
"ts:gfxqualitymed": "Medium",
"ts:gfxqualitylow": "Low",
"ts:gfxqualityoff": "Off",
"ts:pingvalue": "%d ms",
"ts:serveroffline": "Offline",
"ts:serveronline": "Online",
"gui:demo": "Demo Mode",
"stt:demo": "Play a singleplayer match against a training dummy",
"gui:aidummy": "Training Dummy",
"gui:ainormal": "AI - Normal",
"gui:ainormal:tooltip": "Normal difficulty AI. Builds base, trains units and attacks.",
"gui:aicustom": "AI - Custom",
"gui:aicustom:tooltip": "Uses uploaded custom AI bot script.",
"gui:botupload": "Upload AI Bot",
"gui:botupload:title": "Upload AI Bot Script",
"gui:botupload:select": "Select Bot Zip File",
"gui:botupload:success": "Bot uploaded successfully!",
"gui:botupload:fail": "Bot upload failed",
"gui:botupload:manage": "Manage Bots",
"gui:botupload:remove": "Remove",
"gui:botupload:nobot": "No custom bots uploaded",
"gui:botupload:hint": "Upload a .zip file containing bot.ts or index.ts",
"stt:skirmishbuttonuploadbot": "Upload a custom AI bot script package",
"gui:gameresultwaiting": "Waiting for server results...",
"gui:gameresultvictory": "Victory!",
"gui:gameresultdefeat": "Defeat!",
"gui:gameresultdraw": "Draw!",
"gui:quickmatchgamemode": "Select Mode",
"gui:ranked": "Ranked",
"gui:unranked": "Unranked",
"gui:quickmatchplay": "Play",
"wol:matchmodeunavail": "This game mode is currently unavailable.",
"wol:matchavgwaittime": "Average Wait Time: ",
"wol:matchavgwaittimeminutes": "%s minute(s)",
"wol:matchavgwaittimeunavail": "Unavailable",
"wol:matchplayersinqueue": "Players in queue: %d",
"wol:matchstartseconds": "Game starting in %d...",
"gui:viewladder": "View Ladder",
"gui:breakingnews": "Breaking News",
"gui:viewrules": "View Rules",
"gui:rules": "Rules",
"gui:laddercurrent": "Current Season",
"gui:ladderprev": "Previous Season",
"gui:ladderseason": "Season %s",
"gui:draws": "Draws :",
"gui:profileprovmmr": "Provisional MMR :",
"gui:profilemmr": "MMR :",
"gui:mmr": "MMR",
"gui:profilebonuspool": "Bonus Pool :",
"gui:ladderplacement": "Complete %d ranked matches to determine your initial rank placement.",
"gui:ladderpromoprogress": "Progress :",
"gui:ladderdivision": "Division: %s",
"gui:ladderseasoninfo": "Season Info",
"gui:laddertoptierstart": "Generals Start: ",
"gui:laddertoptierpromotions": "Generals Promotions: ",
"gui:laddertoptierdemotions": "Generals Demotions: ",
"gui:ladderseasonlock": "Season Lock: ",
"gui:ladderrankedplayers": "Ranked Players: %d",
"gui:laddertype1v1": "1v1",
"gui:laddertype2v2": "2v2",
"gui:laddertype2v2random": "2v2 Random",
"gui:laddertype2v2arranged": "2v2 Arranged",
"GUI:RankPrivate": "Private",
"GUI:RankCorporal": "Corporal",
"GUI:RankSergeant": "Sergeant",
"GUI:RankLieutenant": "Lieutenant",
"GUI:RankMajor": "Major",
"GUI:RankColonel": "Colonel",
"GUI:RankBrigGeneral": "Brigadier General",
"GUI:RankGeneral": "General",
"GUI:RankFiveStar": "5-Star General",
"GUI:RankCmdInChief": "Commander-in-chief",
"gui:team": "Team",
"gui:teamno": "Team %s",
"gui:teamgame": "Team Alliance",
"stt:modeteamgame": "In 'Team Alliance' players should choose a start position near their allies.",
"gui:startposition": "Start",
"gui:noneassymbols": "--",
"stt:hostcombostart": "Player's start position.",
"stt:hostcomboteam": "Player's team.",
"txt_cannot_ally": "Must have more than one team to start a game!",
"gui:hostteams": "Host Teams",
"stt:hostcboxhostteams": "The host chooses the team and starting location for each player",
"gui:destroyablebridges": "Destroyable Bridges",
"stt:destroyablebridges": "Bridges can be destroyed by force-firing on them.",
"gui:nodogengikills": "No Dog Engineer Kills",
"stt:nodogengikills": "Dogs will be unable to kill engineers.",
"stt:multiengineer": "Capturing an enemy structure requires %d engineers instead of one.",
"gui:replays": "Replays",
"stt:replays": "Play back a recording of a previously played game",
"gui:selectreplay": "Select replay:",
"gui:loadreplay": "Load",
"gui:deletereplay": "Delete",
"gui:replaylisterror": "Failed to load replays",
"gui:replayerror": "Failed to load replay",
"gui:replayversionmismatch": "The replay was recorded with a different game version (%s) and could not be loaded.",
"gui:replaymodmismatch": "The replay was recorded with different game client modifications and could not be loaded.",
"gui:replayopenoldclient": "The replay will be loaded with game version %s in a new browser tab or window.",
"gui:replaywindowclose": "You may now close this browser tab/window",
"gui:confirmdeletereplay": "Are you sure you want to delete the replay \"%s\"?",
"gui:keepreplay": "Keep",
"stt:keepreplay": "Permanently stores the replay, preventing it from being automatically deleted when new replays are created",
"gui:renamereplay": "Rename",
"gui:replaynameprompt": "Enter a replay name:",
"gui:exportreplay": "Export...",
"stt:exportreplay": "Exports a raw replay file that can be imported later in a compatible client.",
"gui:importreplay": "Import...",
"stt:importreplay": "Imports a replay previously exported from a compatible client",
"gui:importreplayerror": "Failed to import replay. The file is corrupt or incompatible with this game client.",
"gui:savereplayerror": "Failed to save replay. Please check your browser storage quota.",
"gui:replayexistserror": "A replay with that name already exists.",
"gui:deletereplayerror": "Failed to delete replay",
"gui:replaytime": "Recorded at",
"gui:gameversion": "Game version",
"gui:gameid": "Game ID",
"gui:duration": "Duration",
"tip:replayrewind": "Restart",
"tip:play": "Play",
"tip:pause": "Pause",
"tip:replayspeed": "Replay speed",
"ts:replayspeedconfirm": "Replay speed changed to %s",
"gui:mods": "Mods",
"stt:mods": "Manage and play modified versions of the base game",
"gui:selectmod": "Select Mod:",
"gui:modname": "Name",
"gui:modstatus": "Status",
"gui:modstatusinstalled": "Installed",
"gui:modstatusupdateavail": "Update Available",
"gui:modstatusnotinstalled": "Not Installed",
"gui:modloaded": "Loaded",
"gui:modactioninstall": "Install",
"gui:modactionupdate": "Update",
"gui:modactionloadanyway": "Load Anyway",
"gui:moddescription": "Description",
"gui:modauthor": "Author(s)",
"gui:modwebsite": "Website",
"gui:modversion": "Version",
"gui:modunsupported": "Unsupported",
"gui:modlisterror": "Failed to load mods",
"gui:loadmod": "Load",
"gui:unloadmod": "Unload",
"gui:uninstallmod": "Uninstall",
"stt:uninstallmod": "Deletes the selected mod and all files belonging to it",
"gui:confirmuninstallmod": "Are you sure you want to uninstall the mod \"%s\"?\n\nIf you continue, all mod files will be deleted. This operation cannot be undone!",
"gui:uninstallmoderror": "Failed to delete mod files",
"gui:importmod": "Import...",
"stt:importmod": "Installs a mod from a local archive file",
"gui:browsemod": "View Files",
"stt:browsemod": "Reveals the mod files in Storage Explorer",
"gui:modsdk": "Mod SDK",
"stt:modsdk": "Opens the documentation and resources for mod development in a new tab",
"gui:importmoderror": "The mod archive could not be imported.",
"gui:importmodfolderprompt": "Choose a name for the mod:\n\nThe name may only contain alphanumeric characters, dash (-) and underscore (_).",
"gui:importmodfolderbadname": "The name may only contain alphanumeric characters, dash (-) and underscore (_).",
"gui:importmodfolderexists": "A mod with that name already exists. Please choose a different name.",
"gui:importmodbadarchive": "The provided archive doesn't appear to contain a valid mod.",
"gui:importmodunsupportedwarn": "The mod you are trying to install was not updated for the Chrono Divide game engine. You may still install any vanilla RA2 mod, but it may not work correctly. Proceed at your own risk!",
"gui:importduplicatemoderror": "This mod is already installed.",
"gui:installmoddownloadprompt": "The mod will now be downloaded from the server. The estimated download size is %d MiB. Do you wish to continue?",
"gui:modupdateavail": "An update is available.",
"gui:updatemodprompt": "Version: %s\nDownload Size: %.1d MiB.\n\nDo you want to download it now?",
"gui:manualdownloadmodprompt": "Please download the mod archive from the following URL, then click the \"Import...\" button from the sidebar to install it.",
"gui:installmodstoragefull": "There is insufficient space available in browser storage (%d MiB available, %d MiB required). Try freeing some disk space and retry.",
"gui:roomdesc": "Room Description",
"gui:ping": "Ping",
"gui:hostname": "Host",
"gui:gamemod": "Mod: %s",
"gui:custommap": "Custom Map",
"stt:verifiedmap": "Verified: This map has been reviewed and contains no custom game rules that create unfair advantages.",
"stt:unverifiedmap": "Unverified: This map may contain custom game rules that could impact fair gameplay.",
"gui:hostnomapupload": "The map cannot be transferred because new accounts are not allowed to upload custom maps.",
"ts:region": "Region",
"ts:serverlabel": "Server",
"ts:connectfailed": "Couldn't connect to server",
"gui:changeserver": "Change Server",
"stt:changeserver": "Play on another game server or region",
"ts:serverfull": "Server is Full.",
"ts:loginavgwaittime": "Average wait time: ",
"ts:loginavgwaittimeminutes": "%s minute(s)",
"ts:loginavgwaittimeunavail": "Unavailable",
"ts:loginpositioninqueue": "Position in queue: %d",
"wol:toomanyloginattempts": "Too many failed login attempts",
"wol:alreadyloggedin": "This nickname is already logged in",
"wol:instancenotfound": "Game instance not found",
"wol:createdtoomanyinstances": "You have created too many game instances recently and you must wait before trying again.",
"wol:instancenotallowed": "Not allowed to connect to this game instance",
"wol:gamealreadystarted": "Cannot join a game that has already started",
"ts:assetloaderror": "Failed to load game assets",
"ts:gameiniterror": "Failed to initialize game",
"ts:mapnotfound": "Map %s not found",
"ts:mapdownloadfailed": "Failed to download map %s",
"ts:mapmismatch": "The replay was recorded with a different version of the map %s and cannot be loaded.",
"ts:mapunsupportedgamemode": "The selected map doesn't support any of the available game modes.",
"ts:mapunsupportedgame": "The selected map doesn't appear to be a Red Alert 2 map.",
"ts:mapunsupportedtileset": "The selected map uses an unsupported tile set.",
"ts:mapunsupportedoverlay": "The selected map uses an unsupported overlay (%d).",
"ts:mapunsupportedterrain": "The selected map uses an unsupported terrain (%s).",
"ts:mapunsupportedweapon": "The selected map uses an unsupported weapon type (%s).",
"ts:mapunsupportedprojectile": "The selected map uses an unsupported projectile type (%s).",
"ts:mapunsupportedwarhead": "The selected map uses an unsupported warhead type (%s).",
"ts:mapunsupportedtechno": "The selected map uses an unsupported techno type (%s).",
"ts:mapunsupportedtheater": "The selected map uses an unsupported theater (%s).",
"ts:mapunsupportedtriggers": "The selected map contains unsupported trigger events and/or actions and may not work correctly.\n\nYou may proceed at your own risk!",
"ts:gameinitoom": "Ran out of memory while loading game. Please make sure you are using a 64-bit desktop browser with a memory limit of at least 1GiB per tab.",
"ts:gamecrashoom": "The game crashed because it ran out of memory. Please make sure you are using a 64-bit desktop browser with a memory limit of at least 1GiB per tab.",
"ts:rendererwarning": "Unsupported graphics card detected. Would you like to try low quality settings?\n\nFor optimal performance, please make sure your browser is using a dedicated graphics card (e.g. NVIDIA, AMD) and hardware acceleration is enabled. For common setups, you can follow {link}these instructions{/link}.",
"ts:rendereruselow": "Use low settings",
"ts:rendererignore": "Ignore",
"ts:rendererchangedesc": "Graphics card change detected. Would you like to switch to high quality settings?",
"ts:rendereriniterror": "Failed to initialize WebGL renderer",
"ts:guiinitfserror": "Failed to read data from browser storage. Please refresh the page. If the problem persists, empty your browser cache and site data.",
"ts:guiinitunknownerror": "Unknown error occurred while initializing user interface",
"ts:modloaderror": "This game mod could not be loaded. Please contact the mod author.",
"gui:notready": "Not ready",
"stt:notready": "Notifies the host that you are not ready to start the game",
"ts:importmap": "Custom Map...",
"stt:importmap": "Adds a custom map file from the local file system",
"ts:importmaperror": "The map could not be imported.",
"ts:filenameerror": "The file name contains restricted characters and cannot be saved",
"ts:importmapunsupportedtype": "Unsupported file type.\n\nSupported map types: %s",
"ts:importmapduplicateerror": "Map \"%s\" already exists.",
"ts:sortnone": "-",
"ts:sortname": "Map Name",
"ts:sortmaxslots": "Max Slots",
"stt:sortby": "Sorts available maps by the selected criteria",
"ts:storage_quota_warning": "WARNING: New replays may not be saved because browser storage is full (%d of %d MiB used). Please check your browser storage quota, make sure you have sufficient disk space and not browsing in Private mode.",
"gui:storage": "Storage",
"gui:storageused": "%s of %s used",
"gui:uploading": "Uploading \"%s\"...",
"gui:uploadfinished": "Upload finished.",
"gui:uploadfailed": "Upload failed.",
"gui:uploadfailedquota": "Upload failed. Storage quota exceeded.",
"gui:confirmdeletefiles": "Are you sure you want to permanently delete these %d items?",
"gui:confirmdeletefile": "Are you sure you want to permanently delete this item?",
"gui:confirmdeletesystemfile": "The item \"%s\" is a system file or folder. If you remove it, the game may no longer work correctly and you will have to locate the original game files again.\n\nAre you sure you want to continue?",
"gui:exitandreload": "Exit & Reload",
"gui:confirmoverwritefile": "The destination folder \"%s\" already contains a file named \"%s\".\n\nAre you sure you want to overwrite it?",
"gui:yestoall": "Yes to all",
"gui:creatingarchive": "Creating ZIP archive...\n\nThis may take a minute.",
"gui:downloadfinished": "Download finished.",
"gui:downloadfailed": "Download failed.",
"gui:downloadaborted": "Download aborted.",
"gui:newfolderprompt": "Choose a folder name:",
"gui:newfoldernotallowed": "Can't create a new folder here.",
"gui:newfolderexists": "An entry with that name already exists.",
"gui:newfolderinvalidname": "Invalid folder name.",
"GUI:LoadingFileExplorer": "Loading file explorer..."
}
================================================
FILE: public/res/locale/zh-CN.json
================================================
{
"gui:ok": "确定",
"txt_copyright": "© 2025 网页红井制作组保留渲染引擎和联机服务的权利",
"gui:wwbrand": "美术素材版权为EA所有,目前正在逐步替换中",
"gui:loadingex": "加载中...",
"ts:disclaimer": "免责声明:\n\"网页红井\" 是一个非盈利的粉丝项目,与 Electronic Arts Inc.(EA) 没有任何关联。\n没有侵犯版权的意图。所有权利均归其各自所有者所有。",
"ts:downloadingpgsize": "下载中 %.1f MiB / %.1f MiB... (%d%%)",
"ts:downloadingpgunkn": "下载中 %.1f MiB...",
"ts:downloading": "正在下载...",
"ts:downloadingpg": "正在下载...(%d%%)",
"ts:downloadfailed": "无法下载远程资源。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:gameres_locate_title": "❗❗--请关注公众号 思牛逼 获取游玩指南--❗❗",
"ts:gameres_import_desc": "如果你需要游玩MOD,那么你必须要导入网页红井的完全体副本。否则请点击右上角 X",
"ts:gameres_drop_desc": "将所需的游戏文件拖放到此处",
"ts:gameres_or": "或者",
"ts:gameres_browse_folder": "选择文件夹...",
"ts:gameres_browse_archive": "选择归档文件...",
"ts:gameres_supported_archive_formats": "支持的归档文件格式:rar、tar、tar.gz、tar.bz2、tar.xz、zip、7z、exe(sfx)",
"ts:gameres_download_desc": "我们在交流群中提供,您可以微信关注公众号 思牛逼 获取群号,其他问题也可以入群讨论",
"ts:gameres_download_hint": "提示:加入QQ群后,群文件内下载 完全体副本,存储在你的本地",
"ts:gameres_download_size": "然后点击下方的 选择归档文件 按钮,选择你下载的完全体副本后导入",
"ts:import_preparing_for_import": "准备导入...",
"ts:import_loading_archive": "正在加载归档...",
"ts:import_extracting_archive": "正在解压归档...\n\n这可能需要一分钟的时间。",
"ts:import_importing": "正在导入\"%s\"...",
"ts:import_importing_pg": "正在导入\"%s\"...(%d%%)",
"ts:import_importing_long": "正在导入\"%s\"...\n\n这可能需要一分钟的时间。",
"ts:import_failed": "无法导入游戏资源。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_file_not_found": "找不到文件\"%s\"。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_extracting": "正在解压 \"%s\"...",
"ts:import_archive_download_failed": "下载失败,请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_archive_extract_failed": "解压归档文件失败。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_invalid_archive": "解压归档文件失败。请提供有效的归档文件。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_out_of_memory": "解压归档文件时内存不足。请确保您使用的是64位桌面浏览器,并且每个选项卡的内存限制至少为1 GiB。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_load_files_failed": "无法加载游戏文件。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:import_checksum_mismatch": "文件\"%s\"似乎损坏。请确保您使用的是兼容的游戏客户端(Origin 或 XWIS),已更新到最新版本(v1.006)。",
"ts:import_no_web_assembly": "WebAssembly 必须用于解压归档文件。",
"ts:import_no_storage": "没有可用的浏览器存储。请确保您未在隐私模式下浏览。",
"ts:storage_quota_exceeded": "浏览器存储配额超过限制。请确保您有足够的磁盘空间,并且未在隐私模式下浏览。",
"ts:storage_io_error": "无法从浏览器存储中读取文件。请关闭此选项卡,然后在新选项卡中重新打开游戏。如果问题仍然存在,请清除所有网站数据并重试。",
"ts:storage_migrating_file": "正在将\"%s\"移动到新的存储系统中...",
"ts:replay_storage_migrating": "正在迁移回放存储...(%d%%)",
"ts:warning": "警告",
"ts:preloading": "预加载资源中...",
"ts:reportbug": "报告错误",
"ts:reportbugtt": "请微信关注公众号 思牛逼 报告BUG或者获取解决方案!",
"ts:reportbugdesc": "请微信关注公众号 思牛逼 报告BUG或者获取解决方案!:",
"ts:patchnotes": "补丁说明",
"stt:patchnotes": "显示游戏客户端每个版本的更改日志",
"ts:infoandcredits": "信息与制作人员",
"stt:infoandcredits": "查看附加信息和制作人员名单",
"ts:outdatedclient": "您正在使用过时的客户端。请刷新页面。如果问题仍然存在,请微信关注公众号 思牛逼 阅读里面文章获取解决方案!。",
"txt_mismatch": "游戏版本不兼容。请关注微信公众号 思牛逼 获取解决方案!",
"gui:joinernomap": "你没有 %s。",
"ts:gamecrashed": "恭喜。游戏崩溃。:|\n\n游戏客户端意外崩溃。这是一个致命错误。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:custommapcrash": "当前地图可能是不受支持的,或包含错误。请与地图作者联系。或者微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:desyncdetected": "检测到游戏失去同步。这是一个致命错误。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"ts:badnickname": "昵称只能包含字母、数字字符(A-Z, a-z, 0-9),下划线 (_) 或破折号 (-)。",
"ts:toall": "对所有人说:",
"ts:toallies": "对盟友说:",
"ts:to": "对 %s 说:",
"ts:replaychatfrom": "(%s):",
"ts:chatfrom": "%s:",
"ts:chatfromallies": "%s(盟友):",
"ts:pagefrom": "(%s):",
"ts:chatuserlink": "[%s]",
"ts:chattimestamp": "[%s]",
"ts:chatcyclehint": "按下(%s)以循环切换聊天接收者",
"ts:stalematewarning": "检测到僵局!游戏将在 %d 分钟后结束。除非任何玩家训练单位、建造建筑(除了墙壁)、摧毁或夺取敌方建筑、获得资源(如果拥有至少一个生产建筑或建筑工厂)",
"ts:stalematetimer": "游戏将在:",
"gui:mastervolume": "主音量",
"gui:sfxvolume": "音效音量",
"gui:ambientvolume": "环境音量",
"gui:uivolume": "界面音量",
"gui:creditsvolume": "制作人员音量",
"gui:requestaudiopermission": "游戏需要您的许可来播放音频。\n\n为了防止将来显示此消息,请从浏览器设置中允许音频始终在此网站上播放。",
"gui:fullscreen": "全屏(%s)",
"stt:fullscreen": "切换全屏模式",
"ts:hotkeyfswarning": "某些快捷键只能在全屏模式中捕捉",
"cmnd:togglefps": "切换 FPS",
"cmnd:togglefpsdesc": "切换显示性能统计信息,如帧率、内存使用情况和延迟",
"ts:reconnectprompt": "您是否要重新连接到上一局游戏?",
"ts:reconnect": "重新连接",
"ts:gameplayopts": "游戏设置",
"ts:flyerlabel": "显示飞行单位辅助",
"stt:flyerlabel": "在地面上标记飞行单位的位置",
"ts:flyeralways": "始终",
"ts:flyerselected": "选定",
"ts:flyernever": "从不",
"ts:attackmovebutton": "攻击/移动按钮",
"stt:attackmovebutton": "允许使用不同的鼠标按钮来下达指令和选择单位",
"ts:attackmovebuttonleft": "鼠标左键",
"ts:attackmovebuttonright": "鼠标右键",
"ts:rightclickscroll": "右键滚动",
"stt:rightclickscroll": "当按住右鼠标键时,玩家可以在地图上滚动",
"ts:mouseaccel": "鼠标加速",
"stt:mouseaccel": "控制鼠标在捕捉鼠标指针时的移动精度",
"ts:mouseaccelhint": "在受支持的平台上覆盖原生操作系统设置。如果遇到不可预测的指针移动,请禁用此功能。",
"ts:gfxopts": "图形设置",
"ts:resolution": "分辨率",
"ts:resolutionhint": "最大分辨率取决于操作系统设置和浏览器选项卡/窗口的大小。您可以使用浏览器的缩放功能([Ctrl] + [+]/[-])进行调整。",
"ts:resolutionfit": "适应窗口(%s)",
"ts:resolutionfullscreen": "全屏(%s)",
"ts:gfxmodels": "模型",
"stt:gfxmodels": "调整 3D 体素模型的质量",
"ts:gfxshadows": "动态阴影",
"stt:gfxshadows": "调整动态渲染阴影的质量",
"ts:gfxqualityhigh": "高",
"ts:gfxqualitymed": "中",
"ts:gfxqualitylow": "低",
"ts:gfxqualityoff": "关闭",
"ts:pingvalue": "%d 毫秒",
"ts:serveroffline": "离线",
"ts:serveronline": "在线",
"gui:demo": "单机模式",
"stt:demo": "无需保持网络连接,即可与各类AI对战",
"gui:aidummy": "AI-弱智",
"gui:ainormal": "AI-普通",
"gui:ainormal:tooltip": "普通难度AI,会建设基地、训练部队并发起进攻。",
"gui:aicustom": "AI-自定义",
"gui:aicustom:tooltip": "使用上传的自定义AI机器人脚本。",
"gui:botupload": "上传AI机器人",
"gui:botupload:title": "上传AI脚本",
"gui:botupload:select": "选择Bot压缩包",
"gui:botupload:success": "AI机器人上传成功!",
"gui:botupload:fail": "AI机器人上传失败",
"gui:botupload:manage": "管理AI机器人",
"gui:botupload:remove": "删除",
"gui:botupload:nobot": "暂无自定义AI机器人",
"gui:botupload:hint": "上传包含 bot.ts 或 index.ts 的 .zip 文件",
"stt:skirmishbuttonuploadbot": "上传自定义AI机器人脚本包",
"gui:quickmatchgamemode": "选择模式",
"gui:ranked": "排位赛",
"gui:unranked": "非排位赛",
"gui:quickmatchplay": "开始快速匹配",
"wol:matchjoininggame": "正在加入游戏...",
"wol:matchwaitingforplayers": "等待对手加入游戏...",
"wol:matchavgwaittime": "平均等待时间:",
"wol:matchavgwaittimeminutes": "%s 分钟",
"wol:matchavgwaittimeunavail": "不可用",
"wol:matchplayersinqueue": "排队中的玩家数:%d",
"wol:matchstartseconds": "游戏将在 %d 秒后开始...",
"gui:viewladder": "查看排行榜",
"gui:breakingnews": "突发新闻",
"gui:viewrules": "查看排位规则",
"gui:rules": "排位赛规则",
"gui:laddercurrent": "当前赛季",
"gui:ladderprev": "先前赛季",
"gui:ladderseason": "第 %s 赛季",
"GUI:RankPrivate": "列兵",
"GUI:RankCorporal": "下士",
"GUI:RankSergeant": "中士",
"GUI:RankLieutenant": "少尉",
"GUI:RankMajor": "少校",
"GUI:RankColonel": "上校",
"GUI:RankBrigGeneral": "准将",
"GUI:RankGeneral": "将军",
"GUI:RankFiveStar": "五星上将",
"GUI:RankCmdInChief": "统帅",
"gui:team": "队伍",
"gui:teamgame": "团队联盟",
"stt:modeteamgame": "在\"团队联盟\"模式中,玩家应选择靠近盟友的起始位置。",
"gui:startposition": "起始位置",
"gui:noneassymbols": "--",
"stt:hostcombostart": "玩家的起始位置。",
"stt:hostcomboteam": "玩家的队伍。",
"txt_cannot_ally": "必须有多于一个队伍才能开始游戏!",
"gui:hostteams": "房主队伍",
"stt:hostcboxhostteams": "房主为每个玩家选择队伍和起始位置",
"gui:replays": "回放",
"stt:replays": "播放以前进行过的游戏的记录",
"gui:selectreplay": "选择回放:",
"gui:loadreplay": "加载",
"gui:deletereplay": "删除",
"gui:replaylisterror": "无法加载回放",
"gui:replayerror": "无法加载回放",
"gui:replayversionmismatch": "回放使用的是不同的游戏版本(%s),无法加载。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"gui:replaymodmismatch": "回放是在不同的游戏客户端修改下录制的,无法加载。请微信关注公众号 思牛逼 阅读里面文章获取解决方案!",
"gui:replayopenoldclient": "将在新的浏览器选项卡或窗口中使用游戏版本 %s 加载回放。",
"gui:replaywindowclose": "您现在可以关闭此浏览器选项卡/窗口",
"gui:confirmdeletereplay": "您确定要永久删除回放\"%s\"吗?",
"gui:keepreplay": "保留",
"stt:keepreplay": "永久保存回放,防止在创建新回放时自动删除",
"gui:renamereplay": "重命名",
"gui:replaynameprompt": "输入回放名称:",
"gui:exportreplay": "导出...",
"stt:exportreplay": "导出一个原始回放文件,以便以后在兼容的客户端中导入",
"gui:importreplay": "导入...",
"stt:importreplay": "导入之前从兼容客户端导出的回放",
"gui:importreplayerror": "无法导入回放。文件损坏或与此游戏客户端不兼容。",
"gui:savereplayerror": "无法保存回放。请检查您的浏览器存储配额。",
"gui:replayexistserror": "同名的回放已存在。",
"gui:deletereplayerror": "无法删除回放",
"gui:replaytime": "录制于",
"gui:gameversion": "游戏版本",
"gui:duration": "持续时间",
"tip:replayrewind": "重新开始",
"tip:play": "播放",
"tip:pause": "暂停",
"tip:replayspeed": "回放速度",
"ts:replayspeedconfirm": "回放速度改为 %s",
"gui:mods": "MOD",
"stt:mods": "管理和玩基础游戏的MOD",
"gui:selectmod": "选择MOD:",
"gui:modname": "名称",
"gui:modstatus": "状态",
"gui:modstatusinstalled": "已安装",
"gui:modstatusupdateavail": "有更新可用",
"gui:modstatusnotinstalled": "未安装",
"gui:modloaded": "已加载",
"gui:modactioninstall": "安装",
"gui:modactionupdate": "更新",
"gui:modactionloadanyway": "仍然加载",
"gui:moddescription": "描述",
"gui:modauthor": "作者",
"gui:modwebsite": "网站",
"gui:modversion": "版本",
"gui:modunsupported": "不受支持",
"gui:modlisterror": "无法加载MOD",
"gui:loadmod": "加载",
"gui:unloadmod": "卸载",
"gui:uninstallmod": "卸载",
"stt:uninstallmod": "删除所选MOD和所有其相关文件",
"gui:confirmuninstallmod": "您确定要卸载MOD\"%s\"吗?\n\n如果继续操作,所有MOD文件都将被删除。此操作无法撤销!",
"gui:uninstallmoderror": "无法删除MOD文件",
"gui:importmod": "导入...",
"stt:importmod": "从本地归档文件中安装MOD",
"gui:browsemod": "查看文件夹",
"stt:browsemod": "在存储资源管理器中显示MOD文件",
"gui:modsdk": "MOD SDK",
"stt:modsdk": "在新选项卡中打开用于修改开发的文档和资源",
"gui:importmoderror": "MOD归档无法导入。",
"gui:importmodfolderprompt": "为MOD选择一个名称:\n\n名称只能包含字母、数字字符和破折号(-)或下划线(_)。",
"gui:importmodfolderbadname": "名称只能包含字母、数字字符和破折号(-)或下划线(_)。",
"gui:importmodfolderexists": "同名的MOD已存在。请重新选择一个名称。",
"gui:importmodbadarchive": "提供的归档似乎不包含有效的MOD。",
"gui:importmodunsupportedwarn": "您要安装的MOD未针对Chrono Divide游戏引擎进行更新。您仍然可以安装任何红色井界通用MOD,但可能无法正常工作。请自行决定是否继续!",
"gui:importduplicatemoderror": "此MOD已安装。",
"gui:installmoddownloadprompt": "MOD现将从服务器下载。预计下载大小为 %d MiB。您是否希望继续?",
"gui:modupdateavail": "有可用的更新。",
"gui:updatemodprompt": "版本:%s\n下载大小:%.1d MiB。\n\n您现在要下载吗?",
"gui:manualdownloadmodprompt": "请从以下 URL 下载MOD归档,然后从侧边栏单击\"导入...\"按钮安装它。",
"gui:installmodstoragefull": "浏览器存储空间不足(可用空间 %d MiB,需要空间 %d MiB)。请尝试释放一些磁盘空间并重试。",
"gui:roomdesc": "房间描述",
"gui:ping": "延迟",
"gui:hostname": "房主",
"gui:gamemod": "MOD:%s",
"gui:custommap": "自定义地图",
"stt:verifiedmap": "已认证:该地图经过认证,不存在不公平改动。",
"stt:unverifiedmap": "未认证:该地图未经过认证,可能存在影响游戏平衡性的改动。",
"ts:serverlabel": "服务器",
"ts:connectfailed": "无法连接到服务器,微信关注公众号 思牛逼 阅读里面文章获取解决方案",
"gui:changeserver": "更改服务器",
"stt:changeserver": "在其他游戏服务器或地区上进行游戏",
"ts:serverfull": "服务器已满。微信关注公众号 思牛逼 阅读里面文章获取解决方案",
"ts:loginavgwaittime": "平均等待时间:",
"ts:loginavgwaittimeminutes": "%s 分钟",
"ts:loginavgwaittimeunavail": "不可用",
"ts:loginpositioninqueue": "队列中的位置:%d",
"wol:toomanyloginattempts": "你尝试登陆失败太多次了,这似乎不太正常",
"wol:alreadyloggedin": "该用户已经处于登陆状态",
"wol:instancenotfound": "未找到游戏实例",
"wol:createdtoomanyinstances": "你最近已经创建了足够多的游戏实例,在重试之前你需要等待一会儿。",
"wol:instancenotallowed": "不允许连接到该游戏实例(通常是对局)",
"wol:gamealreadystarted": "无法加入一个已经开始的对局",
gitextract_zvkrxqle/ ├── .gitignore ├── LICENSE ├── README.md ├── index.html ├── package.json ├── public/ │ ├── 7zz.wasm │ ├── config.ini │ ├── css/ │ │ └── main-legacy.css │ ├── general.csf │ ├── ini.mix │ ├── mods.ini │ ├── other/ │ │ └── file-explorer.css │ ├── res/ │ │ ├── fonts/ │ │ │ └── fonts.css │ │ ├── locale/ │ │ │ ├── en-US.json │ │ │ └── zh-CN.json │ │ └── ra2cd.mix │ └── servers.ini ├── src/ │ ├── App.tsx │ ├── Application.ts │ ├── BattleControlApi.ts │ ├── ClientApi.ts │ ├── Config.ts │ ├── ConsoleVars.ts │ ├── ErrorHandler.ts │ ├── Gui.ts │ ├── LocalPrefs.ts │ ├── RouteHelper.ts │ ├── data/ │ │ ├── AudioBagFile.ts │ │ ├── Bitmap.ts │ │ ├── Crc32.ts │ │ ├── CsfFile.ts │ │ ├── DataStream.ts │ │ ├── HvaFile.ts │ │ ├── IdxEntry.ts │ │ ├── IdxFile.ts │ │ ├── IniFile.ts │ │ ├── IniParser.ts │ │ ├── IniSection.ts │ │ ├── MapFile.ts │ │ ├── MapObjects.ts │ │ ├── MixEntry.ts │ │ ├── MixFile.ts │ │ ├── Mp3File.ts │ │ ├── Palette.ts │ │ ├── PcxFile.ts │ │ ├── ShpFile.ts │ │ ├── ShpImage.ts │ │ ├── Strings.ts │ │ ├── TmpFile.ts │ │ ├── TmpImage.ts │ │ ├── VxlFile.ts │ │ ├── WavFile.ts │ │ ├── encoding/ │ │ │ ├── Blowfish.ts │ │ │ ├── BlowfishKey.ts │ │ │ ├── Format3.ts │ │ │ ├── Format5.ts │ │ │ ├── Format80.ts │ │ │ ├── MiniLzo.ts │ │ │ └── lzo1x.ts │ │ ├── hva/ │ │ │ └── Section.ts │ │ ├── map/ │ │ │ ├── MapLighting.ts │ │ │ ├── MapObjects.ts │ │ │ ├── SpecialFlags.ts │ │ │ ├── Variable.ts │ │ │ ├── tag/ │ │ │ │ ├── CellTag.ts │ │ │ │ ├── CellTagsReader.ts │ │ │ │ ├── Tag.ts │ │ │ │ ├── TagRepeatType.ts │ │ │ │ └── TagsReader.ts │ │ │ └── trigger/ │ │ │ ├── Trigger.ts │ │ │ ├── TriggerAction.ts │ │ │ ├── TriggerActionType.ts │ │ │ ├── TriggerEvent.ts │ │ │ ├── TriggerEventType.ts │ │ │ └── TriggerReader.ts │ │ ├── vfs/ │ │ │ ├── Archive.ts │ │ │ ├── FileNotFoundError.ts │ │ │ ├── FileSystem.ts │ │ │ ├── IOError.ts │ │ │ ├── MemArchive.ts │ │ │ ├── NameNotAllowedError.ts │ │ │ ├── RealFileSystem.ts │ │ │ ├── RealFileSystemDir.ts │ │ │ ├── StorageQuotaError.ts │ │ │ ├── VirtualFile.ts │ │ │ └── VirtualFileSystem.ts │ │ ├── vxl/ │ │ │ ├── Section.ts │ │ │ ├── Span.ts │ │ │ ├── SpanOffsets.ts │ │ │ ├── Voxel.ts │ │ │ ├── VoxelField.ts │ │ │ ├── VxlHeader.ts │ │ │ └── normals.ts │ │ └── zip/ │ │ ├── Zip.ts │ │ └── ZipUtils.ts │ ├── engine/ │ │ ├── AnimProps.ts │ │ ├── Animation.ts │ │ ├── AsyncResourceCollection.ts │ │ ├── Engine.ts │ │ ├── EngineType.ts │ │ ├── GameAnimationLoop.ts │ │ ├── ImageFinder.ts │ │ ├── IsoCoords.ts │ │ ├── LazyAsyncResourceCollection.ts │ │ ├── LazyResourceCollection.ts │ │ ├── Lighting.ts │ │ ├── MapDigest.ts │ │ ├── MapList.ts │ │ ├── MapManifest.ts │ │ ├── MapSupport.ts │ │ ├── RenderableManager.ts │ │ ├── ResourceCollection.ts │ │ ├── ResourceLoader.ts │ │ ├── Theater.ts │ │ ├── TheaterType.ts │ │ ├── UiAnimationLoop.ts │ │ ├── animation/ │ │ │ ├── Runner.ts │ │ │ └── SimpleRunner.ts │ │ ├── gameRes/ │ │ │ ├── CdnManifest.ts │ │ │ ├── CdnResourceLoader.ts │ │ │ ├── FileSystemAccessLib.ts │ │ │ ├── FileSystemUtil.ts │ │ │ ├── GameRes.ts │ │ │ ├── GameResConfig.ts │ │ │ ├── GameResImporter.ts │ │ │ ├── GameResSource.ts │ │ │ ├── VideoConverter.ts │ │ │ ├── browserFileSystemAccess.ts │ │ │ └── importError/ │ │ │ ├── ArchiveDownloadError.ts │ │ │ ├── ArchiveExtractionError.ts │ │ │ ├── ChecksumError.ts │ │ │ ├── FileNotFoundError.ts │ │ │ ├── InvalidArchiveError.ts │ │ │ ├── NoStorageError.ts │ │ │ └── NoWebAssemblyError.ts │ │ ├── gfx/ │ │ │ ├── BufferGeometryUtils.ts │ │ │ ├── Camera.ts │ │ │ ├── CanvasUtils.ts │ │ │ ├── DebugUtils.ts │ │ │ ├── FrustumCuller.ts │ │ │ ├── GrowingPacker.ts │ │ │ ├── ImageUtils.ts │ │ │ ├── MathUtils.ts │ │ │ ├── OctreeContainer.ts │ │ │ ├── OverlayUtils.ts │ │ │ ├── Renderable.ts │ │ │ ├── RenderableContainer.ts │ │ │ ├── Renderer.ts │ │ │ ├── RendererError.ts │ │ │ ├── Scene.ts │ │ │ ├── SpriteUtils.ts │ │ │ ├── TextureAtlas.ts │ │ │ ├── TextureUtils.ts │ │ │ ├── batch/ │ │ │ │ ├── BatchedMesh.ts │ │ │ │ ├── InstancedMesh.ts │ │ │ │ ├── MergedSpriteMesh.ts │ │ │ │ ├── MeshBatchManager.ts │ │ │ │ ├── MeshInstancingBatch.ts │ │ │ │ └── MeshMergingBatch.ts │ │ │ ├── drawable/ │ │ │ │ ├── PalDrawable.ts │ │ │ │ └── TmpDrawable.ts │ │ │ ├── geometry/ │ │ │ │ ├── BufferGeometrySerializer.ts │ │ │ │ └── VxlGeometryCache.ts │ │ │ ├── lighting/ │ │ │ │ ├── LightingDirector.ts │ │ │ │ ├── LightingFx.ts │ │ │ │ ├── LightningStormFx.ts │ │ │ │ └── NukeLightingFx.ts │ │ │ └── material/ │ │ │ ├── PaletteBasicMaterial.ts │ │ │ ├── PaletteLambertMaterial.ts │ │ │ ├── PalettePhongMaterial.ts │ │ │ └── paletteShaderLib.ts │ │ ├── mixDatabase.ts │ │ ├── renderable/ │ │ │ ├── AlphaRenderable.ts │ │ │ ├── CameraPan.ts │ │ │ ├── CameraZoom.ts │ │ │ ├── DebugRenderable.ts │ │ │ ├── Entity.ts │ │ │ ├── MapSpriteTranslation.ts │ │ │ ├── Renderable.ts │ │ │ ├── RenderablePlugin.ts │ │ │ ├── ShadowRenderable.ts │ │ │ ├── ShpRenderable.ts │ │ │ ├── WithPosition.ts │ │ │ ├── WithVisibility.ts │ │ │ ├── WorldScene.ts │ │ │ ├── builder/ │ │ │ │ ├── BatchShpBuilder.ts │ │ │ │ ├── CanvasSpriteBuilder.ts │ │ │ │ ├── CanvasTextureAtlas.ts │ │ │ │ ├── ObjectBuilder.ts │ │ │ │ ├── ShpAggregator.ts │ │ │ │ ├── ShpBuilder.ts │ │ │ │ ├── ShpTextureAtlas.ts │ │ │ │ ├── SpriteBuilder.ts │ │ │ │ ├── VxlBatchedBuilder.ts │ │ │ │ ├── VxlBuilder.ts │ │ │ │ ├── VxlBuilderFactory.ts │ │ │ │ ├── VxlNonBatchedBuilder.ts │ │ │ │ └── vxlGeometry/ │ │ │ │ ├── VxlGeometryCulledBuilder.ts │ │ │ │ ├── VxlGeometryMonotoneBuilder.ts │ │ │ │ ├── VxlGeometryNaiveBuilder.ts │ │ │ │ └── VxlGeometryPool.ts │ │ │ ├── entity/ │ │ │ │ ├── Aircraft.ts │ │ │ │ ├── Anim.ts │ │ │ │ ├── BoxIntersectObject3D.ts │ │ │ │ ├── Building.ts │ │ │ │ ├── Debris.ts │ │ │ │ ├── HighlightAnimRunner.ts │ │ │ │ ├── Infantry.ts │ │ │ │ ├── InvulnerableAnimRunner.ts │ │ │ │ ├── IsoCoords.ts │ │ │ │ ├── Overlay.ts │ │ │ │ ├── PipOverlay.ts │ │ │ │ ├── Projectile.ts │ │ │ │ ├── RenderableFactory.ts │ │ │ │ ├── Smudge.ts │ │ │ │ ├── TargetLines.ts │ │ │ │ ├── Terrain.ts │ │ │ │ ├── TransientAnim.ts │ │ │ │ ├── Vehicle.ts │ │ │ │ ├── WaypointLine.ts │ │ │ │ ├── WaypointLines.ts │ │ │ │ ├── building/ │ │ │ │ │ ├── AnimationType.ts │ │ │ │ │ ├── BuildingAnimArtProps.ts │ │ │ │ │ ├── BuildingAnimData.ts │ │ │ │ │ ├── BuildingShpHelper.ts │ │ │ │ │ ├── DamageType.ts │ │ │ │ │ └── PsychicDetectPlugin.ts │ │ │ │ ├── map/ │ │ │ │ │ ├── MapBounds.ts │ │ │ │ │ ├── MapGrid.ts │ │ │ │ │ ├── MapRenderable.ts │ │ │ │ │ ├── MapShroudLayer.ts │ │ │ │ │ ├── MapSpriteBatchLayer.ts │ │ │ │ │ ├── MapSurface.ts │ │ │ │ │ ├── MapTileLayer.ts │ │ │ │ │ ├── MapTileLayerDebug.ts │ │ │ │ │ ├── MinimapModel.ts │ │ │ │ │ └── MinimapRenderer.ts │ │ │ │ ├── plugin/ │ │ │ │ │ ├── ChronoSparkleFxPlugin.ts │ │ │ │ │ ├── DamageSmokePlugin.ts │ │ │ │ │ ├── HarvesterPlugin.ts │ │ │ │ │ ├── InfantryDisguisePlugin.ts │ │ │ │ │ ├── MindControlLinkPlugin.ts │ │ │ │ │ ├── MoveSoundFxPlugin.ts │ │ │ │ │ ├── ObjectCloakPlugin.ts │ │ │ │ │ ├── ShipWakeTrailPlugin.ts │ │ │ │ │ ├── TntFxPlugin.ts │ │ │ │ │ ├── TrailerSmokePlugin.ts │ │ │ │ │ └── VehicleDisguisePlugin.ts │ │ │ │ └── unit/ │ │ │ │ ├── BlobShadow.ts │ │ │ │ ├── DebugLabel.ts │ │ │ │ ├── ExtraLightHelper.ts │ │ │ │ ├── FlyerHelperMode.ts │ │ │ │ ├── ModelQuality.ts │ │ │ │ ├── RotorHelper.ts │ │ │ │ └── ShadowQuality.ts │ │ │ └── fx/ │ │ │ ├── DamageSmokeFx.ts │ │ │ ├── DetectionLineFx.ts │ │ │ ├── Effect.ts │ │ │ ├── LaserFx.ts │ │ │ ├── LineTrailFx.ts │ │ │ ├── MeshLineResolution.ts │ │ │ ├── MindControlLinkFx.ts │ │ │ ├── RadBeamFx.ts │ │ │ ├── RallyPointFx.ts │ │ │ ├── SparkFx.ts │ │ │ ├── TeslaFx.ts │ │ │ ├── TrailerSmokeFx.ts │ │ │ ├── handler/ │ │ │ │ ├── BeaconFxHandler.ts │ │ │ │ ├── ChronoFxHandler.ts │ │ │ │ ├── CrateFxHandler.ts │ │ │ │ ├── ParasiteSparkFxHandler.ts │ │ │ │ ├── SuperWeaponFxHandler.ts │ │ │ │ ├── TriggerActionFxHandler.ts │ │ │ │ └── WarheadDetonateFxHandler.ts │ │ │ ├── speCompat.ts │ │ │ └── speRuntime.ts │ │ ├── resourceConfigs.ts │ │ ├── sound/ │ │ │ ├── AudioLoop.ts │ │ │ ├── AudioSequence.ts │ │ │ ├── AudioSystem.ts │ │ │ ├── ChannelType.ts │ │ │ ├── Eva.ts │ │ │ ├── EvaSpecs.ts │ │ │ ├── InternalPlaybackHandle.ts │ │ │ ├── Mixer.ts │ │ │ ├── Music.ts │ │ │ ├── MusicSpecs.ts │ │ │ ├── Sound.ts │ │ │ ├── SoundKey.ts │ │ │ ├── SoundSpec.ts │ │ │ ├── SoundSpecs.ts │ │ │ └── WorldSound.ts │ │ ├── type/ │ │ │ ├── LightingType.ts │ │ │ ├── ObjectType.ts │ │ │ ├── OverlayTibType.ts │ │ │ ├── PaletteType.ts │ │ │ ├── PointerType.ts │ │ │ ├── TerrainType.ts │ │ │ └── TiberiumType.ts │ │ └── util/ │ │ ├── EntityIntersectHelper.ts │ │ ├── MapPanningHelper.ts │ │ ├── MapTileIntersectHelper.ts │ │ ├── RaycastHelper.ts │ │ └── WorldViewportHelper.ts │ ├── game/ │ │ ├── Alliances.ts │ │ ├── AttackerInfo.ts │ │ ├── BotManager.ts │ │ ├── Building.ts │ │ ├── ConstructionWorker.ts │ │ ├── Coords.ts │ │ ├── CountdownTimer.ts │ │ ├── Country.ts │ │ ├── Game.ts │ │ ├── GameEventBus.ts │ │ ├── GameFactory.ts │ │ ├── GameMap.ts │ │ ├── GameSpeed.ts │ │ ├── GameTurnManager.ts │ │ ├── Hashable.ts │ │ ├── Player.ts │ │ ├── PlayerList.ts │ │ ├── Prng.ts │ │ ├── SideType.ts │ │ ├── StartingUnitsGenerator.ts │ │ ├── SuperWeapon.ts │ │ ├── Target.ts │ │ ├── Traits.ts │ │ ├── Warhead.ts │ │ ├── Weapon.ts │ │ ├── WeaponInfo.ts │ │ ├── WeaponTargeting.ts │ │ ├── WeaponType.ts │ │ ├── World.ts │ │ ├── action/ │ │ │ ├── Action.ts │ │ │ ├── ActionFactory.ts │ │ │ ├── ActionFactoryReg.ts │ │ │ ├── ActionQueue.ts │ │ │ ├── ActionType.ts │ │ │ ├── ActivateSuperWeaponAction.ts │ │ │ ├── DebugAction.ts │ │ │ ├── DropPlayerAction.ts │ │ │ ├── NoAction.ts │ │ │ ├── ObserveGameAction.ts │ │ │ ├── OrderActionContext.ts │ │ │ ├── OrderUnitsAction.ts │ │ │ ├── PingLocationAction.ts │ │ │ ├── PlaceBuildingAction.ts │ │ │ ├── ResignGameAction.ts │ │ │ ├── SelectUnitsAction.ts │ │ │ ├── SellObjectAction.ts │ │ │ ├── ToggleAllianceAction.ts │ │ │ ├── ToggleRepairAction.ts │ │ │ ├── UpdateQueueAction.ts │ │ │ └── factories/ │ │ │ ├── ActivateSuperWeaponActionFactory.ts │ │ │ ├── DebugActionFactory.ts │ │ │ ├── DropPlayerActionFactory.ts │ │ │ ├── NoActionFactory.ts │ │ │ ├── ObserveGameActionFactory.ts │ │ │ ├── OrderUnitsActionFactory.ts │ │ │ ├── PingLocationActionFactory.ts │ │ │ ├── PlaceBuildingActionFactory.ts │ │ │ ├── ResignGameActionFactory.ts │ │ │ ├── SelectUnitsActionFactory.ts │ │ │ ├── SellObjectActionFactory.ts │ │ │ ├── ToggleAllianceFactory.ts │ │ │ ├── ToggleRepairActionFactory.ts │ │ │ └── UpdateQueueActionFactory.ts │ │ ├── ai/ │ │ │ ├── Ai.ts │ │ │ └── thirdpartbot/ │ │ │ ├── BotRegistry.ts │ │ │ ├── BotSandbox.ts │ │ │ ├── BotUploader.ts │ │ │ ├── ThirdPartyBotAdapter.ts │ │ │ ├── ThirdPartyBotInterface.ts │ │ │ ├── builtIn/ │ │ │ │ ├── BuiltInBotAdapter.ts │ │ │ │ ├── bot/ │ │ │ │ │ ├── bot.ts │ │ │ │ │ ├── logic/ │ │ │ │ │ │ ├── awareness.ts │ │ │ │ │ │ ├── building/ │ │ │ │ │ │ │ ├── antiAirStaticDefence.ts │ │ │ │ │ │ │ ├── antiGroundStaticDefence.ts │ │ │ │ │ │ │ ├── artilleryUnit.ts │ │ │ │ │ │ │ ├── basicAirUnit.ts │ │ │ │ │ │ │ ├── basicBuilding.ts │ │ │ │ │ │ │ ├── basicGroundUnit.ts │ │ │ │ │ │ │ ├── buildingRules.ts │ │ │ │ │ │ │ ├── common.ts │ │ │ │ │ │ │ ├── harvester.ts │ │ │ │ │ │ │ ├── powerPlant.ts │ │ │ │ │ │ │ ├── queueController.ts │ │ │ │ │ │ │ └── resourceCollectionBuilding.ts │ │ │ │ │ │ ├── common/ │ │ │ │ │ │ │ ├── context.ts │ │ │ │ │ │ │ ├── rulesCache.ts │ │ │ │ │ │ │ ├── scout.ts │ │ │ │ │ │ │ ├── tileUtils.ts │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ ├── map/ │ │ │ │ │ │ │ ├── buildSpaceCache.ts │ │ │ │ │ │ │ ├── incrementalGridCache.ts │ │ │ │ │ │ │ ├── map.ts │ │ │ │ │ │ │ ├── sector.ts │ │ │ │ │ │ │ └── sectorUtils.ts │ │ │ │ │ │ ├── mission/ │ │ │ │ │ │ │ ├── actionBatcher.ts │ │ │ │ │ │ │ ├── mission.ts │ │ │ │ │ │ │ ├── missionController.ts │ │ │ │ │ │ │ └── missions/ │ │ │ │ │ │ │ ├── attackMission.ts │ │ │ │ │ │ │ ├── baseBuildingMission.ts │ │ │ │ │ │ │ ├── defenceMission.ts │ │ │ │ │ │ │ ├── engineerMission.ts │ │ │ │ │ │ │ ├── expansionMission.ts │ │ │ │ │ │ │ ├── retreatMission.ts │ │ │ │ │ │ │ ├── scoutingMission.ts │ │ │ │ │ │ │ └── squads/ │ │ │ │ │ │ │ ├── combatSquad.ts │ │ │ │ │ │ │ ├── common.ts │ │ │ │ │ │ │ └── squad.ts │ │ │ │ │ │ └── threat/ │ │ │ │ │ │ ├── sectorThreat.ts │ │ │ │ │ │ ├── threat.ts │ │ │ │ │ │ └── threatCalculator.ts │ │ │ │ │ └── strategy/ │ │ │ │ │ ├── compositionUtils.ts │ │ │ │ │ ├── defaultStrategy.ts │ │ │ │ │ └── strategy.ts │ │ │ │ └── game-api.ts │ │ │ ├── example/ │ │ │ │ ├── README.md │ │ │ │ └── bot.ts │ │ │ └── index.ts │ │ ├── api/ │ │ │ ├── ActionsApi.ts │ │ │ ├── ChatApi.ts │ │ │ ├── EventsApi.ts │ │ │ ├── GameApi.ts │ │ │ ├── LoggerApi.ts │ │ │ ├── MapApi.ts │ │ │ ├── ProductionApi.ts │ │ │ ├── RulesApi.ts │ │ │ ├── index.ts │ │ │ └── interface/ │ │ │ ├── BuildingPlacementData.ts │ │ │ ├── GameObjectData.ts │ │ │ ├── PathFinderOptions.ts │ │ │ ├── PathNode.ts │ │ │ ├── PlayerData.ts │ │ │ ├── PlayerStats.ts │ │ │ ├── SuperWeaponData.ts │ │ │ ├── TileResourceData.ts │ │ │ └── UnitData.ts │ │ ├── art/ │ │ │ ├── Art.ts │ │ │ ├── FlhCoords.ts │ │ │ ├── ObjectArt.ts │ │ │ ├── RotorData.ts │ │ │ ├── SequenceReader.ts │ │ │ └── SequenceType.ts │ │ ├── bot/ │ │ │ ├── Bot.ts │ │ │ ├── BotFactory.ts │ │ │ ├── BotsLib.ts │ │ │ └── DummyBot.ts │ │ ├── event/ │ │ │ ├── AllianceChangeEvent.ts │ │ │ ├── BridgeRepairEvent.ts │ │ │ ├── BuildStatusChangeEvent.ts │ │ │ ├── BuildingCaptureEvent.ts │ │ │ ├── BuildingEvacuateEvent.ts │ │ │ ├── BuildingFailedPlaceEvent.ts │ │ │ ├── BuildingGarrisonEvent.ts │ │ │ ├── BuildingInfiltrationEvent.ts │ │ │ ├── BuildingPlaceEvent.ts │ │ │ ├── BuildingRepairFullEvent.ts │ │ │ ├── BuildingRepairStartEvent.ts │ │ │ ├── CheerEvent.ts │ │ │ ├── CratePickupEvent.ts │ │ │ ├── DeployNotAllowedEvent.ts │ │ │ ├── EnterObjectEvent.ts │ │ │ ├── EnterTileEvent.ts │ │ │ ├── EnterTransportEvent.ts │ │ │ ├── EventMap.ts │ │ │ ├── EventType.ts │ │ │ ├── FactoryProduceUnitEvent.ts │ │ │ ├── GameEvent.ts │ │ │ ├── HealthChangeEvent.ts │ │ │ ├── InflictDamageEvent.ts │ │ │ ├── InsufficientFundsEvent.ts │ │ │ ├── LeaveTransportEvent.ts │ │ │ ├── LightningStormCloudEvent.ts │ │ │ ├── LightningStormManifestEvent.ts │ │ │ ├── ObjectAttackedEvent.ts │ │ │ ├── ObjectCloakChangeEvent.ts │ │ │ ├── ObjectCrashingEvent.ts │ │ │ ├── ObjectDestroyEvent.ts │ │ │ ├── ObjectDisguiseChangeEvent.ts │ │ │ ├── ObjectLandEvent.ts │ │ │ ├── ObjectLiftOffEvent.ts │ │ │ ├── ObjectMorphEvent.ts │ │ │ ├── ObjectOwnerChangeEvent.ts │ │ │ ├── ObjectSellEvent.ts │ │ │ ├── ObjectSpawnEvent.ts │ │ │ ├── ObjectTeleportEvent.ts │ │ │ ├── ObjectUnspawnEvent.ts │ │ │ ├── PingLocationEvent.ts │ │ │ ├── PlayerDefeatedEvent.ts │ │ │ ├── PlayerDroppedEvent.ts │ │ │ ├── PlayerResignedEvent.ts │ │ │ ├── PowerChangeEvent.ts │ │ │ ├── PowerLowEvent.ts │ │ │ ├── PowerRestoreEvent.ts │ │ │ ├── PrimaryFactoryChangeEvent.ts │ │ │ ├── RadarEvent.ts │ │ │ ├── RadarOnOffEvent.ts │ │ │ ├── RallyPointChangeEvent.ts │ │ │ ├── ShipSubmergeChangeEvent.ts │ │ │ ├── StalemateDetectEvent.ts │ │ │ ├── SuperWeaponActivateEvent.ts │ │ │ ├── SuperWeaponReadyEvent.ts │ │ │ ├── TimerExpireEvent.ts │ │ │ ├── TriggerAnimEvent.ts │ │ │ ├── TriggerEvaEvent.ts │ │ │ ├── TriggerSoundFxEvent.ts │ │ │ ├── TriggerStopSoundFxEvent.ts │ │ │ ├── TriggerTextEvent.ts │ │ │ ├── UnitDeployUndeployEvent.ts │ │ │ ├── UnitPromoteEvent.ts │ │ │ ├── UnitRecycleEvent.ts │ │ │ ├── UnitRepairFinishEvent.ts │ │ │ ├── UnitRepairStartEvent.ts │ │ │ ├── WarheadDetonateEvent.ts │ │ │ └── WeaponFireEvent.ts │ │ ├── gameobject/ │ │ │ ├── Aircraft.ts │ │ │ ├── Bridge.ts │ │ │ ├── Building.ts │ │ │ ├── Debris.ts │ │ │ ├── GameObject.ts │ │ │ ├── Infantry.ts │ │ │ ├── ObjectFactory.ts │ │ │ ├── ObjectPosition.ts │ │ │ ├── Overlay.ts │ │ │ ├── Projectile.ts │ │ │ ├── Smudge.ts │ │ │ ├── Techno.ts │ │ │ ├── Terrain.ts │ │ │ ├── Unit.ts │ │ │ ├── Vehicle.ts │ │ │ ├── Weapon.ts │ │ │ ├── common/ │ │ │ │ ├── AnimTerrainEffect.ts │ │ │ │ └── DeathType.ts │ │ │ ├── infantry/ │ │ │ │ ├── InfDeathType.ts │ │ │ │ ├── StanceType.ts │ │ │ │ └── sequenceMap.ts │ │ │ ├── locomotor/ │ │ │ │ ├── ChronoLocomotor.ts │ │ │ │ ├── DriveLocomotor.ts │ │ │ │ ├── FootLocomotor.ts │ │ │ │ ├── HoverLocomotor.ts │ │ │ │ ├── JumpjetLocomotor.ts │ │ │ │ ├── Locomotor.ts │ │ │ │ ├── LocomotorFactory.ts │ │ │ │ ├── MissileLocomotor.ts │ │ │ │ └── WingedLocomotor.ts │ │ │ ├── selection/ │ │ │ │ ├── SelectionLevel.ts │ │ │ │ ├── SelectionList.ts │ │ │ │ ├── SelectionModel.ts │ │ │ │ ├── UnitSelection.ts │ │ │ │ └── UnitSelectionLite.ts │ │ │ ├── task/ │ │ │ │ ├── AttackTask.ts │ │ │ │ ├── CaptureBuildingTask.ts │ │ │ │ ├── CheerTask.ts │ │ │ │ ├── EnterBuildingTask.ts │ │ │ │ ├── EnterHospitalTask.ts │ │ │ │ ├── EnterRecyclerTask.ts │ │ │ │ ├── EnterTransportTask.ts │ │ │ │ ├── EvacuateTransportTask.ts │ │ │ │ ├── GarrisonBuildingTask.ts │ │ │ │ ├── InfiltrateBuildingTask.ts │ │ │ │ ├── MoveToDockTask.ts │ │ │ │ ├── ParadropTask.ts │ │ │ │ ├── PlantC4Task.ts │ │ │ │ ├── RepairBuildingTask.ts │ │ │ │ ├── ScatterTask.ts │ │ │ │ ├── TurnTask.ts │ │ │ │ ├── WaitForBuildUpTask.ts │ │ │ │ ├── harvester/ │ │ │ │ │ ├── GatherOreTask.ts │ │ │ │ │ ├── ReturnOreTask.ts │ │ │ │ │ └── TeleportMoveToRefineryTask.ts │ │ │ │ ├── morph/ │ │ │ │ │ ├── DeployIntoTask.ts │ │ │ │ │ ├── MorphIntoTask.ts │ │ │ │ │ ├── PackBuildingTask.ts │ │ │ │ │ └── UndeployIntoTask.ts │ │ │ │ ├── move/ │ │ │ │ │ ├── AttackMoveTargetTask.ts │ │ │ │ │ ├── AttackMoveTask.ts │ │ │ │ │ ├── ExitFactoryTask.ts │ │ │ │ │ ├── MoveAsideTask.ts │ │ │ │ │ ├── MoveInWeaponRangeTask.ts │ │ │ │ │ ├── MoveInsideTask.ts │ │ │ │ │ ├── MoveOutsideTask.ts │ │ │ │ │ ├── MoveTargetTask.ts │ │ │ │ │ ├── MoveTask.ts │ │ │ │ │ └── MoveToBlockTask.ts │ │ │ │ └── system/ │ │ │ │ ├── CallbackTask.ts │ │ │ │ ├── TargetLinesConfig.ts │ │ │ │ ├── Task.ts │ │ │ │ ├── TaskGroup.ts │ │ │ │ ├── TaskRunner.ts │ │ │ │ ├── TaskStatus.ts │ │ │ │ ├── WaitMinutesTask.ts │ │ │ │ └── WaitTicksTask.ts │ │ │ ├── trait/ │ │ │ │ ├── AgentTrait.ts │ │ │ │ ├── AirSpawnTrait.ts │ │ │ │ ├── AirportBoundTrait.ts │ │ │ │ ├── AmmoTrait.ts │ │ │ │ ├── ArmedTrait.ts │ │ │ │ ├── AttackTrait.ts │ │ │ │ ├── AutoRepairTrait.ts │ │ │ │ ├── BridgeTrait.ts │ │ │ │ ├── C4ChargeTrait.ts │ │ │ │ ├── CabHutTrait.ts │ │ │ │ ├── CloakableTrait.ts │ │ │ │ ├── CrashableTrait.ts │ │ │ │ ├── CrewedTrait.ts │ │ │ │ ├── DelayedKillTrait.ts │ │ │ │ ├── DeployerTrait.ts │ │ │ │ ├── DisguiseTrait.ts │ │ │ │ ├── DockTrait.ts │ │ │ │ ├── DockableTrait.ts │ │ │ │ ├── FactoryTrait.ts │ │ │ │ ├── FreeUnitTrait.ts │ │ │ │ ├── GapGeneratorTrait.ts │ │ │ │ ├── GarrisonTrait.ts │ │ │ │ ├── GunnerTrait.ts │ │ │ │ ├── HarvesterTrait.ts │ │ │ │ ├── HealthTrait.ts │ │ │ │ ├── HelipadTrait.ts │ │ │ │ ├── HospitalTrait.ts │ │ │ │ ├── HoverBobTrait.ts │ │ │ │ ├── IdleActionTrait.ts │ │ │ │ ├── InvulnerableTrait.ts │ │ │ │ ├── MindControllableTrait.ts │ │ │ │ ├── MindControllerTrait.ts │ │ │ │ ├── MissileSpawnTrait.ts │ │ │ │ ├── MoveTrait.ts │ │ │ │ ├── OilDerrickTrait.ts │ │ │ │ ├── OverpoweredTrait.ts │ │ │ │ ├── ParasiteableTrait.ts │ │ │ │ ├── PoweredTrait.ts │ │ │ │ ├── PsychicDetectorTrait.ts │ │ │ │ ├── RallyTrait.ts │ │ │ │ ├── SelfHealingTrait.ts │ │ │ │ ├── SensorsTrait.ts │ │ │ │ ├── SpawnDebrisTrait.ts │ │ │ │ ├── SpawnLinkTrait.ts │ │ │ │ ├── SubmergibleTrait.ts │ │ │ │ ├── SuperWeaponTrait.ts │ │ │ │ ├── SuppressionTrait.ts │ │ │ │ ├── TemporalTrait.ts │ │ │ │ ├── TiberiumTrait.ts │ │ │ │ ├── TiberiumTreeTrait.ts │ │ │ │ ├── TilterTrait.ts │ │ │ │ ├── TntChargeTrait.ts │ │ │ │ ├── TransportTrait.ts │ │ │ │ ├── TurretTrait.ts │ │ │ │ ├── UnitOrderTrait.ts │ │ │ │ ├── UnitReloadTrait.ts │ │ │ │ ├── UnitRepairTrait.ts │ │ │ │ ├── UnlandableTrait.ts │ │ │ │ ├── VeteranTrait.ts │ │ │ │ ├── WallTrait.ts │ │ │ │ ├── WarpedOutTrait.ts │ │ │ │ └── interface/ │ │ │ │ ├── NotifyAttack.ts │ │ │ │ ├── NotifyBuildStatus.ts │ │ │ │ ├── NotifyCrash.ts │ │ │ │ ├── NotifyDamage.ts │ │ │ │ ├── NotifyDestroy.ts │ │ │ │ ├── NotifyHeal.ts │ │ │ │ ├── NotifyHealthChange.ts │ │ │ │ ├── NotifyOrder.ts │ │ │ │ ├── NotifyOwnerChange.ts │ │ │ │ ├── NotifySell.ts │ │ │ │ ├── NotifySpawn.ts │ │ │ │ ├── NotifyTeleport.ts │ │ │ │ ├── NotifyTick.ts │ │ │ │ ├── NotifyTileChange.ts │ │ │ │ ├── NotifyUnspawn.ts │ │ │ │ └── NotifyWarpChange.ts │ │ │ └── unit/ │ │ │ ├── CollisionHelper.ts │ │ │ ├── CollisionType.ts │ │ │ ├── CrateBonuses.ts │ │ │ ├── FacingUtil.ts │ │ │ ├── HealthLevel.ts │ │ │ ├── LosHelper.ts │ │ │ ├── MovePositionHelper.ts │ │ │ ├── RangeHelper.ts │ │ │ ├── ScatterPositionHelper.ts │ │ │ ├── TargetUtil.ts │ │ │ ├── Timer.ts │ │ │ ├── VeteranAbility.ts │ │ │ ├── VeteranLevel.ts │ │ │ └── ZoneType.ts │ │ ├── gameopts/ │ │ │ ├── GameOptRandomGen.ts │ │ │ ├── GameOptSanitizer.ts │ │ │ ├── GameOpts.ts │ │ │ └── constants.ts │ │ ├── ini/ │ │ │ ├── GameModeType.ts │ │ │ ├── GameModes.ts │ │ │ ├── MixinRules.ts │ │ │ └── MixinRulesType.ts │ │ ├── map/ │ │ │ ├── BridgeOverlayTypes.ts │ │ │ ├── Bridges.ts │ │ │ ├── MapBounds.ts │ │ │ ├── MapShroud.ts │ │ │ ├── OreOverlayTypes.ts │ │ │ ├── OreSpread.ts │ │ │ ├── Terrain.ts │ │ │ ├── Tile.ts │ │ │ ├── TileCollection.ts │ │ │ ├── TileOcclusion.ts │ │ │ ├── TileOccupation.ts │ │ │ ├── pathFinder/ │ │ │ │ ├── NodeHeap.ts │ │ │ │ ├── PathFinder.ts │ │ │ │ └── SearchStatePool.ts │ │ │ ├── tileFinder/ │ │ │ │ ├── CardinalTileFinder.ts │ │ │ │ ├── DirectionalTileFinder.ts │ │ │ │ ├── FloodTileFinder.ts │ │ │ │ ├── RadialBackFirstTileFinder.ts │ │ │ │ ├── RadialTileFinder.ts │ │ │ │ └── RandomTileFinder.ts │ │ │ └── wallTypes.ts │ │ ├── math/ │ │ │ ├── Box2.ts │ │ │ ├── CubicBezierCurve3.ts │ │ │ ├── CurvePath.ts │ │ │ ├── Cylindrical.ts │ │ │ ├── Euler.ts │ │ │ ├── GameMath.ts │ │ │ ├── LineCurve.ts │ │ │ ├── Matrix4.ts │ │ │ ├── QuadraticBezierCurve.ts │ │ │ ├── Quaternion.ts │ │ │ ├── Spherical.ts │ │ │ ├── Vector2.ts │ │ │ ├── Vector3.ts │ │ │ └── geometry.ts │ │ ├── order/ │ │ │ ├── AttackMoveOrder.ts │ │ │ ├── AttackOrder.ts │ │ │ ├── CaptureOrder.ts │ │ │ ├── CheerOrder.ts │ │ │ ├── DeployOrder.ts │ │ │ ├── DockOrder.ts │ │ │ ├── EnterTransportOrder.ts │ │ │ ├── GatherOrder.ts │ │ │ ├── GuardAreaOrder.ts │ │ │ ├── MoveOrder.ts │ │ │ ├── OccupyOrder.ts │ │ │ ├── Order.ts │ │ │ ├── OrderFactory.ts │ │ │ ├── OrderFeedbackType.ts │ │ │ ├── OrderType.ts │ │ │ ├── RepairOrder.ts │ │ │ ├── ScatterOrder.ts │ │ │ ├── StopOrder.ts │ │ │ └── orderPriorities.ts │ │ ├── player/ │ │ │ ├── PlayerFactory.ts │ │ │ ├── production/ │ │ │ │ ├── Production.ts │ │ │ │ └── ProductionQueue.ts │ │ │ └── trait/ │ │ │ ├── PowerTrait.ts │ │ │ ├── RadarTrait.ts │ │ │ ├── SharedDetectDisguiseTrait.ts │ │ │ └── SuperWeaponsTrait.ts │ │ ├── rules/ │ │ │ ├── AiRules.ts │ │ │ ├── AudioVisualRules.ts │ │ │ ├── CombatDamageRules.ts │ │ │ ├── CountryRules.ts │ │ │ ├── CrateRules.ts │ │ │ ├── DebrisRules.ts │ │ │ ├── ElevationModelRules.ts │ │ │ ├── GeneralRules.ts │ │ │ ├── LandRules.ts │ │ │ ├── MpDialogSettings.ts │ │ │ ├── ObjectRules.ts │ │ │ ├── ObjectRulesFactory.ts │ │ │ ├── OverlayRules.ts │ │ │ ├── PowerupsRules.ts │ │ │ ├── ProjectileRules.ts │ │ │ ├── RadiationRules.ts │ │ │ ├── Rules.ts │ │ │ ├── SmudgeRules.ts │ │ │ ├── SuperWeaponRules.ts │ │ │ ├── TechnoRules.ts │ │ │ ├── TerrainRules.ts │ │ │ ├── TiberiumRules.ts │ │ │ ├── WarheadRules.ts │ │ │ ├── WeaponRules.ts │ │ │ ├── general/ │ │ │ │ ├── CrewRules.ts │ │ │ │ ├── DMislRules.ts │ │ │ │ ├── HoverRules.ts │ │ │ │ ├── LightningStormRules.ts │ │ │ │ ├── MissileRules.ts │ │ │ │ ├── ParadropRules.ts │ │ │ │ ├── PrismRules.ts │ │ │ │ ├── RadarRules.ts │ │ │ │ ├── RepairRules.ts │ │ │ │ ├── ThreatRules.ts │ │ │ │ ├── V3RocketRules.ts │ │ │ │ └── VeteranRules.ts │ │ │ └── mpAllowedColors.ts │ │ ├── superweapon/ │ │ │ ├── ChronoSphereEffect.ts │ │ │ ├── IronCurtainEffect.ts │ │ │ ├── LightningStormEffect.ts │ │ │ ├── NukeEffect.ts │ │ │ ├── ParadropEffect.ts │ │ │ └── SuperWeaponEffect.ts │ │ ├── theater/ │ │ │ ├── AutoLat.ts │ │ │ ├── TileSet.ts │ │ │ ├── TileSetAnim.ts │ │ │ ├── TileSetEntry.ts │ │ │ ├── TileSets.ts │ │ │ └── rampHeights.ts │ │ ├── trait/ │ │ │ ├── CrateGeneratorTrait.ts │ │ │ ├── MapLightingTrait.ts │ │ │ ├── MapRadiationTrait.ts │ │ │ ├── MapShroudTrait.ts │ │ │ ├── PowerTrait.ts │ │ │ ├── ProductionTrait.ts │ │ │ ├── RadarTrait.ts │ │ │ ├── SellTrait.ts │ │ │ ├── SharedDetectCloakTrait.ts │ │ │ ├── SharedDetectDisguiseTrait.ts │ │ │ ├── StalemateDetectTrait.ts │ │ │ ├── SuperWeaponsTrait.ts │ │ │ └── interface/ │ │ │ ├── NotifyAllianceChange.ts │ │ │ ├── NotifyAttack.ts │ │ │ ├── NotifyDestroy.ts │ │ │ ├── NotifyElevationChange.ts │ │ │ ├── NotifyHealthChange.ts │ │ │ ├── NotifyObjectTraitAdd.ts │ │ │ ├── NotifyOwnerChange.ts │ │ │ ├── NotifyPlaceBuilding.ts │ │ │ ├── NotifyPower.ts │ │ │ ├── NotifyProduceUnit.ts │ │ │ ├── NotifySpawn.ts │ │ │ ├── NotifySuperWeaponActivate.ts │ │ │ ├── NotifySuperWeaponDeactivate.ts │ │ │ ├── NotifyTargetDestroy.ts │ │ │ ├── NotifyTick.ts │ │ │ ├── NotifyTileChange.ts │ │ │ ├── NotifyUnspawn.ts │ │ │ └── NotifyWarpChange.ts │ │ ├── trigger/ │ │ │ ├── TriggerCondition.ts │ │ │ ├── TriggerConditionFactory.ts │ │ │ ├── TriggerExecutor.ts │ │ │ ├── TriggerExecutorFactory.ts │ │ │ ├── TriggerInstance.ts │ │ │ ├── TriggerManager.ts │ │ │ ├── TriggerTarget.ts │ │ │ ├── condition/ │ │ │ │ ├── AmbientLightCondition.ts │ │ │ │ ├── AnyEventCondition.ts │ │ │ │ ├── AttackedByAnyCondition.ts │ │ │ │ ├── AttackedByHouseCondition.ts │ │ │ │ ├── BuildObjectTypeCondition.ts │ │ │ │ ├── BuildingExistsCondition.ts │ │ │ │ ├── ComesNearWaypointCondition.ts │ │ │ │ ├── CreditsBelowCondition.ts │ │ │ │ ├── CreditsExceedCondition.ts │ │ │ │ ├── CrossHorizLineCondition.ts │ │ │ │ ├── CrossVertLineCondition.ts │ │ │ │ ├── DestroyedAllBuildingsCondition.ts │ │ │ │ ├── DestroyedAllCondition.ts │ │ │ │ ├── DestroyedAllUnitsCondition.ts │ │ │ │ ├── DestroyedAllUnitsLandCondition.ts │ │ │ │ ├── DestroyedAllUnitsNavalCondition.ts │ │ │ │ ├── DestroyedBridgeCondition.ts │ │ │ │ ├── DestroyedBuildingsCondition.ts │ │ │ │ ├── DestroyedByAnyCondition.ts │ │ │ │ ├── DestroyedOrCapturedCondition.ts │ │ │ │ ├── DestroyedOrCapturedOrInfiltratedCondition.ts │ │ │ │ ├── DestroyedUnitsCondition.ts │ │ │ │ ├── ElapsedScenarioTimeCondition.ts │ │ │ │ ├── ElapsedTimeCondition.ts │ │ │ │ ├── EnteredByCondition.ts │ │ │ │ ├── GlobalVariableCondition.ts │ │ │ │ ├── HealthBelowAnyCondition.ts │ │ │ │ ├── HealthBelowCombatCondition.ts │ │ │ │ ├── LocalVariableCondition.ts │ │ │ │ ├── LowPowerCondition.ts │ │ │ │ ├── NoEventCondition.ts │ │ │ │ ├── NoFactoriesLeftCondition.ts │ │ │ │ ├── PickupCrateAnyCondition.ts │ │ │ │ ├── PickupCrateCondition.ts │ │ │ │ ├── RandomDelayCondition.ts │ │ │ │ ├── SpiedByCondition.ts │ │ │ │ ├── SpyEnteringAsHouseCondition.ts │ │ │ │ ├── SpyEnteringAsInfantryCondition.ts │ │ │ │ └── TimerExpiredCondition.ts │ │ │ └── executor/ │ │ │ ├── AddSuperWeaponExecutor.ts │ │ │ ├── ApplyDamageExecutor.ts │ │ │ ├── ChangeHouseAllExecutor.ts │ │ │ ├── ChangeHouseExecutor.ts │ │ │ ├── CheerExecutor.ts │ │ │ ├── CreateCrateExecutor.ts │ │ │ ├── CreateRadarEventExecutor.ts │ │ │ ├── DestroyObjectExecutor.ts │ │ │ ├── DestroyTagExecutor.ts │ │ │ ├── DestroyTriggerExecutor.ts │ │ │ ├── DetonateWarheadExecutor.ts │ │ │ ├── EvictOccupiersExecutor.ts │ │ │ ├── FireSaleExecutor.ts │ │ │ ├── ForceEndExecutor.ts │ │ │ ├── ForceTriggerExecutor.ts │ │ │ ├── GlobalVariableExecutor.ts │ │ │ ├── IronCurtainExecutor.ts │ │ │ ├── LightningStrikeExecutor.ts │ │ │ ├── LocalVariableExecutor.ts │ │ │ ├── NoActionExecutor.ts │ │ │ ├── NukeStrikeExecutor.ts │ │ │ ├── PlayAnimAtExecutor.ts │ │ │ ├── PlaySoundFxAtExecutor.ts │ │ │ ├── PlaySoundFxExecutor.ts │ │ │ ├── PlaySpeechExecutor.ts │ │ │ ├── ReshroudMapExecutor.ts │ │ │ ├── ResizePlayerViewExecutor.ts │ │ │ ├── RevealAroundWaypointExecutor.ts │ │ │ ├── RevealMapExecutor.ts │ │ │ ├── SellBuildingExecutor.ts │ │ │ ├── SetAmbientLightExecutor.ts │ │ │ ├── SetAmbientRateExecutor.ts │ │ │ ├── SetAmbientStepExecutor.ts │ │ │ ├── StopSoundFxAtExecutor.ts │ │ │ ├── TextTriggerExecutor.ts │ │ │ ├── TimerExtendExecutor.ts │ │ │ ├── TimerSetExecutor.ts │ │ │ ├── TimerShortenExecutor.ts │ │ │ ├── TimerStartExecutor.ts │ │ │ ├── TimerStopExecutor.ts │ │ │ ├── TimerTextExecutor.ts │ │ │ ├── ToggleTriggerExecutor.ts │ │ │ ├── TurnOnOffBuildingExecutor.ts │ │ │ └── UnrevealAroundWaypointExecutor.ts │ │ └── type/ │ │ ├── ArmorType.ts │ │ ├── LandTargeting.ts │ │ ├── LandType.ts │ │ ├── LocomotorType.ts │ │ ├── MovementZone.ts │ │ ├── NavalTargeting.ts │ │ ├── PipColor.ts │ │ ├── PowerupType.ts │ │ ├── SpeedType.ts │ │ ├── SuperWeaponType.ts │ │ └── VhpScan.ts │ ├── gui/ │ │ ├── CanvasMetrics.ts │ │ ├── FullScreen.ts │ │ ├── HtmlContainer.ts │ │ ├── HtmlReactElement.ts │ │ ├── HtmlReactElement.tsx │ │ ├── LazyHtmlElement.ts │ │ ├── MobileTouchControls.ts │ │ ├── Pointer.ts │ │ ├── PointerEvents.ts │ │ ├── PointerSprite.ts │ │ ├── ReactFormat.tsx │ │ ├── ReplayManager.ts │ │ ├── ShpSpriteBatch.ts │ │ ├── UiObject.ts │ │ ├── UiObjectSprite.ts │ │ ├── UiScene.ts │ │ ├── Viewport.ts │ │ ├── chat/ │ │ │ ├── ChatHistory.ts │ │ │ └── ChatMessageFormat.tsx │ │ ├── component/ │ │ │ ├── BasicErrorBoxApi.tsx │ │ │ ├── BotUploadDialog.tsx │ │ │ ├── ButtonSelect.tsx │ │ │ ├── ChannelOpIndicator.tsx │ │ │ ├── ChannelUser.tsx │ │ │ ├── Chat.tsx │ │ │ ├── ChatInput.tsx │ │ │ ├── ColorSelect.tsx │ │ │ ├── CountryIcon.tsx │ │ │ ├── CountrySelect.tsx │ │ │ ├── Dialog.tsx │ │ │ ├── GameResBoxApi.tsx │ │ │ ├── GameResForm.tsx │ │ │ ├── GameResourcesViewer.tsx │ │ │ ├── Image.tsx │ │ │ ├── ImageContext.tsx │ │ │ ├── List.tsx │ │ │ ├── MenuButton.tsx │ │ │ ├── MenuVideo.tsx │ │ │ ├── MessageBoxApi.tsx │ │ │ ├── Option.tsx │ │ │ ├── PingIndicator.tsx │ │ │ ├── PromptDialog.tsx │ │ │ ├── Select.tsx │ │ │ ├── Slider.tsx │ │ │ ├── SplashScreen.tsx │ │ │ ├── StartPosSelect.tsx │ │ │ ├── TeamSelect.tsx │ │ │ ├── ToastApi.tsx │ │ │ ├── Toasts.tsx │ │ │ ├── UiText.tsx │ │ │ └── fileExplorer/ │ │ │ ├── StorageFileExplorer.css │ │ │ └── StorageFileExplorer.tsx │ │ ├── jsx/ │ │ │ ├── HtmlView.ts │ │ │ ├── JsxRenderer.ts │ │ │ ├── UiComponent.ts │ │ │ └── jsx.ts │ │ ├── replay/ │ │ │ ├── ReplayExistsError.ts │ │ │ ├── ReplayMeta.ts │ │ │ ├── ReplayStorage.ts │ │ │ ├── ReplayStorageError.ts │ │ │ ├── ReplayStorageFileSystem.ts │ │ │ ├── ReplayStorageMemStorage.ts │ │ │ └── ReplayStorageMigration.ts │ │ └── screen/ │ │ ├── Controller.ts │ │ ├── RootController.ts │ │ ├── RootRoute.ts │ │ ├── RootScreen.ts │ │ ├── Screen.ts │ │ ├── ScreenType.ts │ │ ├── game/ │ │ │ ├── ChatNetHandler.ts │ │ │ ├── ChatTypingHandler.ts │ │ │ ├── CombatantUi.tsx │ │ │ ├── GameLoader.ts │ │ │ ├── GameMenu.ts │ │ │ ├── GameMenuScreen.ts │ │ │ ├── GameScreen.ts │ │ │ ├── HudFactory.ts │ │ │ ├── MapFileLoader.ts │ │ │ ├── MedianPing.ts │ │ │ ├── NetStats.ts │ │ │ ├── ObserverUi.ts │ │ │ ├── PingMonitor.ts │ │ │ ├── PlayerUi.ts │ │ │ ├── SoundHandler.ts │ │ │ ├── TauntHandler.ts │ │ │ ├── TauntPlayback.ts │ │ │ ├── TooltipTextResolver.ts │ │ │ ├── WorldView.ts │ │ │ ├── component/ │ │ │ │ ├── GameResultPopup.ts │ │ │ │ ├── Hud.ts │ │ │ │ ├── Minimap.tsx │ │ │ │ ├── MinimapPing.ts │ │ │ │ └── hud/ │ │ │ │ ├── DebugText.ts │ │ │ │ ├── GameMenuContentArea.ts │ │ │ │ ├── HudChat.tsx │ │ │ │ ├── Messages.ts │ │ │ │ ├── ReplayStatsOverlay.ts │ │ │ │ ├── SidebarCard.ts │ │ │ │ ├── SidebarCredits.ts │ │ │ │ ├── SidebarGameTime.ts │ │ │ │ ├── SidebarIconButton.ts │ │ │ │ ├── SidebarMenu.ts │ │ │ │ ├── SidebarPower.ts │ │ │ │ ├── SidebarRadar.ts │ │ │ │ ├── SidebarRadarAnimRunner.ts │ │ │ │ ├── SidebarTabs.ts │ │ │ │ ├── SuperWeaponTimers.ts │ │ │ │ ├── commandBar/ │ │ │ │ │ ├── CommandBarButtonList.ts │ │ │ │ │ ├── CommandBarButtonType.ts │ │ │ │ │ ├── CommandButtonConfig.ts │ │ │ │ │ └── commandButtonConfigs.ts │ │ │ │ └── viewmodel/ │ │ │ │ ├── CombatantSidebarModel.ts │ │ │ │ ├── MessageList.ts │ │ │ │ ├── SidebarModel.ts │ │ │ │ └── SidebarTab.ts │ │ │ ├── gameMenu/ │ │ │ │ ├── ConInfoForm.tsx │ │ │ │ ├── ConnectionInfoScreen.ts │ │ │ │ ├── DiploForm.tsx │ │ │ │ ├── DiploScreen.ts │ │ │ │ ├── GameMenuController.ts │ │ │ │ ├── GameMenuHomeScreen.ts │ │ │ │ ├── QuitConfirmScreen.ts │ │ │ │ ├── ScreenParamsMap.ts │ │ │ │ └── ScreenType.ts │ │ │ ├── loadingScreen/ │ │ │ │ ├── LanLoadingScreenApi.ts │ │ │ │ ├── LoadingScreen.tsx │ │ │ │ ├── LoadingScreenApi.ts │ │ │ │ ├── LoadingScreenApiFactory.ts │ │ │ │ ├── LoadingScreenWrapper.tsx │ │ │ │ ├── MpLoadingScreenApi.ts │ │ │ │ ├── ReplayLoadingScreenApi.ts │ │ │ │ └── SpLoadingScreenApi.ts │ │ │ └── worldInteraction/ │ │ │ ├── ArrowScrollHandler.ts │ │ │ ├── BeaconMode.ts │ │ │ ├── CameraPanHandler.ts │ │ │ ├── CustomScrollHandler.ts │ │ │ ├── DefaultActionHandler.ts │ │ │ ├── InteractionMode.ts │ │ │ ├── MapHoverHandler.ts │ │ │ ├── MapScrollHandler.ts │ │ │ ├── MinimapHandler.ts │ │ │ ├── PendingPlacementHandler.ts │ │ │ ├── PlacementMode.ts │ │ │ ├── PlanningMode.ts │ │ │ ├── RepairMode.ts │ │ │ ├── SellMode.ts │ │ │ ├── SpecialActionMode.ts │ │ │ ├── Tooltip.ts │ │ │ ├── TooltipHandler.ts │ │ │ ├── UnitSelectionHandler.ts │ │ │ ├── WorldInteraction.ts │ │ │ ├── WorldInteractionFactory.ts │ │ │ ├── keyboard/ │ │ │ │ ├── KeyBinds.ts │ │ │ │ ├── KeyCommand.ts │ │ │ │ ├── KeyCommandType.ts │ │ │ │ ├── KeyboardHandler.ts │ │ │ │ └── command/ │ │ │ │ ├── CenterBaseCmd.ts │ │ │ │ ├── CenterGroupCmd.ts │ │ │ │ ├── CenterViewCmd.ts │ │ │ │ ├── FollowUnitCmd.ts │ │ │ │ ├── GoToCameraLocationCmd.ts │ │ │ │ ├── LastRadarEventCmd.ts │ │ │ │ ├── SelectGroupCmd.ts │ │ │ │ ├── SelectNextUnitCmd.ts │ │ │ │ ├── SelectPlayerCmd.ts │ │ │ │ ├── SelectTypeByCmd.ts │ │ │ │ └── SetCameraLocationCmd.ts │ │ │ └── placementMode/ │ │ │ ├── PlacementGrid.ts │ │ │ └── PlacementGridModel.ts │ │ ├── mainMenu/ │ │ │ ├── MainMenuController.ts │ │ │ ├── MainMenuRootScreen.ts │ │ │ ├── MainMenuRoute.ts │ │ │ ├── MainMenuScreen.ts │ │ │ ├── ScreenType.ts │ │ │ ├── component/ │ │ │ │ ├── Iframe.tsx │ │ │ │ ├── MainMenu.ts │ │ │ │ ├── MenuMpSlotAnimRunner.ts │ │ │ │ ├── MenuMpSlotText.tsx │ │ │ │ ├── MenuSdTopAnimRunner.ts │ │ │ │ ├── MenuSlotAnimationRunner.ts │ │ │ │ ├── MenuTooltip.tsx │ │ │ │ ├── MenuVideo.tsx │ │ │ │ ├── PrefetchProgress.tsx │ │ │ │ ├── SidebarPreview.tsx │ │ │ │ ├── SidebarTitle.tsx │ │ │ │ ├── VersionString.tsx │ │ │ │ └── viewmodel/ │ │ │ │ └── MenuButtonConfig.ts │ │ │ ├── credits/ │ │ │ │ ├── Credits.tsx │ │ │ │ └── CreditsScreen.ts │ │ │ ├── customGame/ │ │ │ │ ├── CustomGameScreen.ts │ │ │ │ └── component/ │ │ │ │ └── GameBrowser.tsx │ │ │ ├── infoAndCredits/ │ │ │ │ └── InfoAndCreditsScreen.ts │ │ │ ├── ladder/ │ │ │ │ ├── LadderScreen.ts │ │ │ │ └── component/ │ │ │ │ └── Ladder.tsx │ │ │ ├── ladderRules/ │ │ │ │ └── LadderRulesScreen.ts │ │ │ ├── lan/ │ │ │ │ ├── LanRecentPlay.ts │ │ │ │ ├── LanSetupScreen.ts │ │ │ │ └── component/ │ │ │ │ ├── LanSetup.tsx │ │ │ │ ├── QrCodeCard.tsx │ │ │ │ └── QrScannerPanel.tsx │ │ │ ├── lobby/ │ │ │ │ ├── LobbyScreen.ts │ │ │ │ ├── MapPreviewRenderer.ts │ │ │ │ ├── PreferredHostOpts.ts │ │ │ │ ├── PregameController.ts │ │ │ │ ├── SelectMapParams.ts │ │ │ │ ├── SkirmishScreen.ts │ │ │ │ └── component/ │ │ │ │ ├── CreateGameBox.tsx │ │ │ │ ├── LobbyForm.tsx │ │ │ │ ├── PasswordBox.tsx │ │ │ │ ├── RankIndicator.tsx │ │ │ │ └── viewmodel/ │ │ │ │ └── lobby.ts │ │ │ ├── login/ │ │ │ │ ├── LoginBox.tsx │ │ │ │ ├── LoginScreen.ts │ │ │ │ ├── ServerList.tsx │ │ │ │ ├── ServerPingIndicator.tsx │ │ │ │ └── ServerPings.ts │ │ │ ├── main/ │ │ │ │ ├── HomeScreen.ts │ │ │ │ ├── ReportBug.tsx │ │ │ │ └── TestEntryScreen.ts │ │ │ ├── mapSel/ │ │ │ │ ├── MapSelScreen.ts │ │ │ │ └── component/ │ │ │ │ └── MapSel.tsx │ │ │ ├── modSel/ │ │ │ │ ├── BadModArchiveError.ts │ │ │ │ ├── DuplicateModError.ts │ │ │ │ ├── Mod.ts │ │ │ │ ├── ModDetailsPane.tsx │ │ │ │ ├── ModDownloadPrompt.tsx │ │ │ │ ├── ModImporter.ts │ │ │ │ ├── ModManager.ts │ │ │ │ ├── ModMeta.ts │ │ │ │ ├── ModSel.tsx │ │ │ │ ├── ModSelScreen.ts │ │ │ │ └── ModStatus.ts │ │ │ ├── newAccount/ │ │ │ │ ├── NewAccountBox.tsx │ │ │ │ └── NewAccountScreen.ts │ │ │ ├── patchNotes/ │ │ │ │ └── PatchNotesScreen.ts │ │ │ ├── quickGame/ │ │ │ │ ├── ChatUi.ts │ │ │ │ ├── QuickGameScreen.ts │ │ │ │ └── component/ │ │ │ │ ├── QuickGameChat.tsx │ │ │ │ └── QuickGameForm.tsx │ │ │ └── score/ │ │ │ ├── ScoreScreen.ts │ │ │ └── ScoreTable.tsx │ │ ├── options/ │ │ │ ├── GeneralOptions.ts │ │ │ ├── GraphicsOptions.ts │ │ │ ├── KeyboardScreen.ts │ │ │ ├── OptionsScreen.ts │ │ │ ├── SoundOptsScreen.ts │ │ │ ├── StorageScreen.ts │ │ │ └── component/ │ │ │ ├── GeneralOpts.tsx │ │ │ ├── KeyOpts.tsx │ │ │ ├── MusicJukebox.tsx │ │ │ ├── PressKeyInput.tsx │ │ │ ├── Resolution.tsx │ │ │ ├── SoundOpts.tsx │ │ │ ├── StorageExplorer.tsx │ │ │ ├── configurableCmds.ts │ │ │ └── getHumanReadableKey.ts │ │ └── replay/ │ │ ├── KeepReplayBox.tsx │ │ ├── ReplayDetailsPane.tsx │ │ ├── ReplayScreen.ts │ │ ├── ReplaySel.tsx │ │ ├── ReplaySelScreen.ts │ │ └── StorageWarning.tsx │ ├── main.tsx │ ├── network/ │ │ ├── HttpRequest.ts │ │ ├── IrcConnection.ts │ │ ├── WolConnection.ts │ │ ├── WolGameReport.ts │ │ ├── chat/ │ │ │ └── ChatMessage.ts │ │ ├── gameopt/ │ │ │ ├── FileNameEncoder.ts │ │ │ ├── LoadInfoParser.ts │ │ │ ├── MapNameLegacyEncoder.ts │ │ │ ├── Parser.ts │ │ │ ├── Serializer.ts │ │ │ └── SlotInfo.ts │ │ ├── gamestate/ │ │ │ ├── PlayerConnectionStatus.ts │ │ │ ├── Replay.ts │ │ │ ├── ReplayRecorder.ts │ │ │ ├── ReplayTurnManager.ts │ │ │ ├── SoloPlayTurnManager.ts │ │ │ └── replay/ │ │ │ ├── ChatMessageReplayEvent.ts │ │ │ └── TauntReplayEvent.ts │ │ ├── gservConfig.ts │ │ ├── ladder/ │ │ │ ├── LadderHead.ts │ │ │ ├── PagedResponse.ts │ │ │ ├── PlayerLadderRung.ts │ │ │ ├── PlayerProfile.ts │ │ │ ├── PlayerRankType.ts │ │ │ ├── WLadderService.ts │ │ │ └── wladderConfig.ts │ │ └── lan/ │ │ ├── LanLockstepTurnManager.ts │ │ ├── LanMatchSession.ts │ │ ├── LanMeshSession.ts │ │ ├── LanQrPayload.ts │ │ ├── LanRoomSession.ts │ │ ├── ManualSdpLanSession.ts │ │ └── SdpCandidateDiagnostics.ts │ ├── performance/ │ │ ├── PerformanceOptions.ts │ │ └── PerformanceRuntime.ts │ ├── setupThreeGlobal.ts │ ├── test/ │ │ └── performance/ │ │ ├── GeneralOptions.test.ts │ │ └── PerformanceHelpers.test.ts │ ├── tools/ │ │ ├── AircraftTester.ts │ │ ├── BuildingTester.ts │ │ ├── CameraZoomControls.ts │ │ ├── DevToolsApi.ts │ │ ├── InfantryTester.ts │ │ ├── LiveInteractionTester.ts │ │ ├── LobbyFormTester.ts │ │ ├── PerformanceTester.ts │ │ ├── ShpTester.ts │ │ ├── SoundTester.ts │ │ ├── TestToolSupport.ts │ │ ├── UnitMovementTester.ts │ │ ├── VehicleTester.ts │ │ ├── VxlTester.ts │ │ └── WorldSceneTester.ts │ ├── types/ │ │ ├── game.d.ts │ │ └── global.d.ts │ ├── util/ │ │ ├── Base64.ts │ │ ├── BoxedVar.ts │ │ ├── Color.ts │ │ ├── CssLoader.ts │ │ ├── Graph.ts │ │ ├── PointerLock.ts │ │ ├── QuadTree.ts │ │ ├── Routing.ts │ │ ├── ScriptLoader.ts │ │ ├── Sentry.ts │ │ ├── Serializable.ts │ │ ├── array.ts │ │ ├── bresenham.ts │ │ ├── disposable/ │ │ │ ├── CompositeDisposable.ts │ │ │ ├── Disposable.ts │ │ │ └── LegacyDisposable.ts │ │ ├── dom.ts │ │ ├── event.ts │ │ ├── format.ts │ │ ├── fullScreen.ts │ │ ├── geometry.ts │ │ ├── keyNames.ts │ │ ├── logger.ts │ │ ├── math.ts │ │ ├── mouse.ts │ │ ├── number.ts │ │ ├── stream.ts │ │ ├── string.ts │ │ ├── time.ts │ │ ├── typeGuard.ts │ │ └── userAgent.ts │ ├── version.ts │ └── vite-env.d.ts ├── tsconfig.build.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts
Showing preview only (778K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (9525 symbols across 1233 files)
FILE: src/App.tsx
function App (line 5) | function App() {
FILE: src/Application.ts
type SplashScreenUpdateCallback (line 48) | type SplashScreenUpdateCallback = (props: ComponentProps<typeof SplashSc...
class MockLocalPrefs (line 49) | class MockLocalPrefs extends LocalPrefs {
method constructor (line 50) | constructor(storage: Storage) {
class MockConsoleVars (line 55) | class MockConsoleVars extends ConsoleVars {
method constructor (line 56) | constructor() {
class MockDevToolsApi (line 61) | class MockDevToolsApi {
method registerCommand (line 62) | static registerCommand(name: string, cmd: Function) { console.log(`Moc...
method registerVar (line 63) | static registerVar(name: string, bv: BoxedVar<any>) { console.log(`Moc...
method listCommands (line 64) | static listCommands(): string[] { return []; }
method listVars (line 65) | static listVars(): string[] { return []; }
class ViewportAdapter (line 71) | class ViewportAdapter implements Viewport {
method constructor (line 72) | constructor(private boxedVar: BoxedVar<ViewportRect>) { }
method value (line 73) | get value(): ViewportRect {
method getValue (line 76) | getValue(): ViewportRect {
class Application (line 81) | class Application {
method importOptionalDevModule (line 84) | private async importOptionalDevModule<T = any>(path: string): Promise<...
method formatString (line 91) | private formatString(template: string, ...args: any[]): string {
method constructor (line 136) | constructor(splashScreenUpdateCallback?: SplashScreenUpdateCallback) {
method getVersion (line 150) | public getVersion(): string {
method loadConfig (line 153) | private async loadConfig(): Promise<void> {
method loadTranslations (line 178) | private async loadTranslations(): Promise<void> {
method checkGlobalLibs (line 235) | private checkGlobalLibs(): void {
method initLogging (line 238) | private async initLogging(): Promise<void> {
method loadGeneralOptions (line 241) | private loadGeneralOptions(): void {
method initializePreferredViewportSize (line 254) | private initializePreferredViewportSize(): void {
method bindPerformanceRuntimeVars (line 270) | private bindPerformanceRuntimeVars(): void {
method setPreferredViewportSize (line 284) | private setPreferredViewportSize(resolution?: {
method getRequestedResolution (line 292) | private getRequestedResolution(): { width: number; height: number; } |...
method isMobileLayout (line 298) | private isMobileLayout(): boolean {
method getAvailableDisplaySize (line 301) | private getAvailableDisplaySize(): { width: number; height: number; } {
method normalizeViewportDimension (line 310) | private normalizeViewportDimension(value: number, minimum: number): nu...
method computeDesktopViewportSize (line 314) | private computeDesktopViewportSize(availableSize: {
method computeViewportSize (line 337) | private computeViewportSize(isFullScreen: boolean, availableSize: { wi...
method computeViewportLayout (line 378) | private computeViewportLayout(isFullScreen: boolean): ViewportRect {
method applyRootLayout (line 395) | private applyRootLayout(viewport: ViewportRect): void {
method isNativeFullScreen (line 408) | private isNativeFullScreen(): boolean {
method updateViewportSize (line 413) | private updateViewportSize(isFullScreen: boolean = this.fullScreen.isF...
method onFullScreenChange (line 426) | private onFullScreenChange(isFullScreen: boolean): void {
method loadGpuBenchmarkData (line 430) | private async loadGpuBenchmarkData(): Promise<any> {
method main (line 434) | public async main(): Promise<void> {
method loadGameResConfig (line 761) | private loadGameResConfig(prefs: LocalPrefs): GameResConfig | undefined {
method createTestToolContext (line 778) | private createTestToolContext(): TestToolRuntimeContext {
method initRouting (line 785) | private initRouting(): void {
method destroy (line 922) | async destroy(): Promise<void> {
method createSplashScreenInterface (line 939) | private createSplashScreenInterface() {
method handleGameResLoadError (line 994) | private async handleGameResLoadError(error: Error, strings: Strings, f...
method handleGameResImportError (line 1050) | private async handleGameResImportError(error: Error, strings: Strings)...
type Window (line 1128) | interface Window {
FILE: src/BattleControlApi.ts
type WorldInteraction (line 2) | interface WorldInteraction {
type ToggleCallback (line 12) | type ToggleCallback = (value: any) => void;
class BattleControlApi (line 13) | class BattleControlApi {
method constructor (line 16) | constructor() {
method _setWorldInteraction (line 18) | _setWorldInteraction(worldInteraction: WorldInteraction): void {
method _notifyToggle (line 21) | _notifyToggle(value: any): void {
method onToggle (line 31) | onToggle(callback: ToggleCallback): () => void {
method requestPan (line 37) | requestPan(x: number, y: number): void {
method cancelPan (line 41) | cancelPan(): void {
method executeKeyCommand (line 44) | executeKeyCommand(command: string): void {
method applyKeyModifiers (line 47) | applyKeyModifiers(modifiers: any): void {
FILE: src/ClientApi.ts
class ClientApi (line 2) | class ClientApi {
method constructor (line 4) | constructor() {
FILE: src/Config.ts
type ViewportConfig (line 3) | interface ViewportConfig {
type SentryConfig (line 7) | interface SentryConfig {
class Config (line 13) | class Config {
method constructor (line 21) | constructor() {
method load (line 24) | public load(iniFile: IniFile): void {
method getGeneralData (line 57) | public getGeneralData(): IniSection {
method defaultLocale (line 64) | get defaultLocale(): string {
method serversUrl (line 67) | get serversUrl(): string {
method gameresBaseUrl (line 70) | get gameresBaseUrl(): string | undefined {
method gameResArchiveUrl (line 74) | get gameResArchiveUrl(): string | undefined {
method mapsBaseUrl (line 78) | get mapsBaseUrl(): string | undefined {
method modsBaseUrl (line 82) | get modsBaseUrl(): string | undefined {
method devMode (line 86) | get devMode(): boolean {
method discordUrl (line 89) | get discordUrl(): string | undefined {
method patchNotesUrl (line 93) | get patchNotesUrl(): string | undefined {
method ladderRulesUrl (line 97) | get ladderRulesUrl(): string | undefined {
method modSdkUrl (line 101) | get modSdkUrl(): string | undefined {
method breakingNewsUrl (line 105) | get breakingNewsUrl(): string | undefined {
method quickMatchEnabled (line 109) | get quickMatchEnabled(): boolean {
method unrankedQueueEnabled (line 112) | get unrankedQueueEnabled(): boolean {
method botsEnabled (line 115) | get botsEnabled(): boolean {
method oldClientsBaseUrl (line 118) | get oldClientsBaseUrl(): string | undefined {
method debugGameState (line 122) | get debugGameState(): boolean {
method debugLogging (line 125) | get debugLogging(): boolean | string | undefined {
method getCorsProxy (line 136) | public getCorsProxy(urlToMatch: string): string | undefined {
FILE: src/ConsoleVars.ts
class ConsoleVars (line 2) | class ConsoleVars {
method constructor (line 21) | constructor() {
FILE: src/ErrorHandler.ts
type MessageBoxApi (line 1) | interface MessageBoxApi {
type StringsApi (line 4) | interface StringsApi {
class ErrorHandler (line 7) | class ErrorHandler {
method constructor (line 11) | constructor(messageBoxApi: MessageBoxApi, strings: StringsApi) {
method handle (line 15) | handle(error: any, message: string, callback?: () => void): void {
FILE: src/Gui.ts
class Gui (line 46) | class Gui {
method constructor (line 76) | constructor(appVersion: string, strings: Strings, config: Config, view...
method init (line 89) | async init(): Promise<void> {
method initRenderer (line 103) | private initRenderer(): void {
method handleViewportChange (line 113) | private handleViewportChange(newViewport: {
method initUiScene (line 132) | private initUiScene(): void {
method initJsxRenderer (line 136) | private initJsxRenderer(): void {
method initPointer (line 145) | private initPointer(): void {
method initRootController (line 156) | private initRootController(): void {
method loadGameResources (line 161) | private async loadGameResources(): Promise<void> {
method getMainMenuVideoUrl (line 186) | private async getMainMenuVideoUrl(): Promise<string | File | undefined> {
method routeToInitialScreen (line 264) | private async routeToInitialScreen(): Promise<void> {
method navigateToMainMenu (line 291) | private async navigateToMainMenu(): Promise<void> {
method startAnimationLoop (line 381) | private startAnimationLoop(): void {
method getRootController (line 384) | getRootController(): RootController {
method getMessageBoxApi (line 390) | getMessageBoxApi(): MessageBoxApi {
method destroy (line 396) | async destroy(): Promise<void> {
method initAudioSystem (line 461) | private async initAudioSystem(): Promise<void> {
method createDefaultMixer (line 532) | private createDefaultMixer(): Mixer {
method initMusicSystem (line 544) | private async initMusicSystem(): Promise<void> {
method initOptionsSystem (line 598) | private async initOptionsSystem(): Promise<void> {
FILE: src/LocalPrefs.ts
type StorageKey (line 1) | enum StorageKey {
class LocalPrefs (line 26) | class LocalPrefs {
method constructor (line 28) | constructor(storage: Storage) {
method getItem (line 31) | getItem(key: StorageKey | string): string | undefined {
method setItem (line 40) | setItem(key: StorageKey | string, value: string): boolean {
method removeItem (line 50) | removeItem(key: StorageKey | string): void {
method listItems (line 58) | listItems(): string[] {
method getBool (line 71) | getBool(key: StorageKey | string, defaultValue: boolean = false): bool...
method getNumber (line 77) | getNumber(key: StorageKey | string, defaultValue: number = 0): number {
FILE: src/RouteHelper.ts
type GameParams (line 2) | interface GameParams {
class RouteHelper (line 10) | class RouteHelper {
method getGameRoute (line 12) | static getGameRoute(params: GameParams): string {
method extractGameParams (line 23) | static extractGameParams(encodedParams: string): GameParams {
FILE: src/data/AudioBagFile.ts
class AudioBagFile (line 5) | class AudioBagFile {
method constructor (line 7) | constructor() {
method fromVirtualFile (line 10) | public async fromVirtualFile(bagFile: VirtualFile, idx: IdxFile): Prom...
method getFileList (line 18) | public getFileList(): string[] {
method containsFile (line 21) | public containsFile(filename: string): boolean {
method openFile (line 24) | public openFile(filename: string): VirtualFile {
method buildWavData (line 32) | private buildWavData(sourceStream: DataStream, idxEntry: IdxEntry): Da...
FILE: src/data/Bitmap.ts
type PixelFormat (line 1) | enum PixelFormat {
function getBytesPerPixel (line 6) | function getBytesPerPixel(format: PixelFormat): number {
class Bitmap (line 18) | class Bitmap {
method constructor (line 23) | constructor(width: number, height: number, data?: Uint8Array, pixelFor...
method drawIndexedImage (line 32) | drawIndexedImage(sourceBitmap: IndexedBitmap, x: number, y: number): v...
class IndexedBitmap (line 60) | class IndexedBitmap extends Bitmap {
method constructor (line 61) | constructor(width: number, height: number, data?: Uint8Array) {
class RgbBitmap (line 65) | class RgbBitmap extends Bitmap {
method constructor (line 66) | constructor(width: number, height: number, data?: Uint8Array) {
class RgbaBitmap (line 70) | class RgbaBitmap extends Bitmap {
method constructor (line 71) | constructor(width: number, height: number, data?: Uint8Array) {
method drawRgbaImage (line 74) | drawRgbaImage(sourceBitmap: RgbaBitmap, x: number, y: number, destWidt...
FILE: src/data/Crc32.ts
class Crc32 (line 1) | class Crc32 {
method constructor (line 57) | constructor(initialValue: number = 0xFFFFFFFF) {
method calculateCrc (line 61) | public static calculateCrc(data: Uint8Array, initialValue: number = 0x...
method append (line 68) | public append(data: Uint8Array): void {
method get (line 73) | public get(): number {
FILE: src/data/CsfFile.ts
constant CSF_LABEL_HAS_VALUE_MAGIC (line 4) | const CSF_LABEL_HAS_VALUE_MAGIC = new Uint32Array(new Uint8Array(strwCha...
type CsfLanguage (line 15) | enum CsfLanguage {
class CsfFile (line 41) | class CsfFile {
method constructor (line 46) | constructor(virtualFile?: VirtualFile) {
method fromVirtualFile (line 51) | public fromVirtualFile(file: VirtualFile): void {
method autoDetectLocale (line 151) | private autoDetectLocale(): void {
method getIsoLocale (line 165) | public getIsoLocale(): string | undefined {
FILE: src/data/DataStream.ts
type TypedArray (line 1) | type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | In...
class DataStream (line 2) | class DataStream {
method constructor (line 13) | constructor(bufferOrSize: ArrayBuffer | DataView | TypedArray | number...
method dynamicSize (line 32) | get dynamicSize(): boolean {
method dynamicSize (line 35) | set dynamicSize(value: boolean) {
method byteLength (line 41) | get byteLength(): number {
method buffer (line 44) | get buffer(): ArrayBuffer {
method buffer (line 48) | set buffer(newBuffer: ArrayBuffer) {
method byteOffset (line 53) | get byteOffset(): number {
method byteOffset (line 56) | set byteOffset(newOffset: number) {
method dataView (line 60) | get dataView(): DataView {
method dataView (line 63) | set dataView(newDataView: DataView | TypedArray) {
method bigEndian (line 69) | public bigEndian(): this {
method littleEndian (line 73) | public littleEndian(): this {
method _realloc (line 77) | private _realloc(bytesNeededForOperation: number): void {
method _trimAlloc (line 106) | private _trimAlloc(): void {
method seek (line 120) | public seek(offset: number): void {
method isEof (line 124) | public isEof(): boolean {
method readInt8 (line 127) | public readInt8(): number {
method readUint8 (line 132) | public readUint8(): number {
method readInt16 (line 137) | public readInt16(endianness?: boolean): number {
method readUint16 (line 142) | public readUint16(endianness?: boolean): number {
method readInt32 (line 147) | public readInt32(endianness?: boolean): number {
method readUint32 (line 152) | public readUint32(endianness?: boolean): number {
method readFloat32 (line 157) | public readFloat32(endianness?: boolean): number {
method readFloat64 (line 162) | public readFloat64(endianness?: boolean): number {
method writeInt8 (line 167) | public writeInt8(value: number): void {
method writeUint8 (line 172) | public writeUint8(value: number): void {
method writeInt16 (line 177) | public writeInt16(value: number, endianness?: boolean): void {
method writeUint16 (line 182) | public writeUint16(value: number, endianness?: boolean): void {
method writeInt32 (line 187) | public writeInt32(value: number, endianness?: boolean): void {
method writeUint32 (line 192) | public writeUint32(value: number, endianness?: boolean): void {
method writeFloat32 (line 197) | public writeFloat32(value: number, endianness?: boolean): void {
method writeFloat64 (line 202) | public writeFloat64(value: number, endianness?: boolean): void {
method mapInt32Array (line 207) | public mapInt32Array(count: number, endianness?: boolean): Int32Array {
method mapInt16Array (line 214) | public mapInt16Array(count: number, endianness?: boolean): Int16Array {
method mapInt8Array (line 221) | public mapInt8Array(count: number): Int8Array {
method mapUint32Array (line 227) | public mapUint32Array(count: number, endianness?: boolean): Uint32Array {
method mapUint16Array (line 234) | public mapUint16Array(count: number, endianness?: boolean): Uint16Array {
method mapUint8Array (line 241) | public mapUint8Array(count: number): Uint8Array {
method mapFloat64Array (line 247) | public mapFloat64Array(count: number, endianness?: boolean): Float64Ar...
method mapFloat32Array (line 254) | public mapFloat32Array(count: number, endianness?: boolean): Float32Ar...
method readInt32Array (line 261) | public readInt32Array(count?: number, endianness?: boolean): Int32Array {
method readInt16Array (line 269) | public readInt16Array(count?: number, endianness?: boolean): Int16Array {
method readInt8Array (line 277) | public readInt8Array(count?: number): Int8Array {
method readUint32Array (line 284) | public readUint32Array(count?: number, endianness?: boolean): Uint32Ar...
method readUint16Array (line 292) | public readUint16Array(count?: number, endianness?: boolean): Uint16Ar...
method readUint8Array (line 300) | public readUint8Array(count?: number): Uint8Array {
method readFloat64Array (line 307) | public readFloat64Array(count?: number, endianness?: boolean): Float64...
method readFloat32Array (line 315) | public readFloat32Array(count?: number, endianness?: boolean): Float32...
method writeUint8Array (line 323) | public writeUint8Array(array: Uint8Array): void {
method readString (line 328) | public readString(length?: number, encoding?: string): string {
method writeString (line 336) | public writeString(str: string, encoding?: string, fixedLength?: numbe...
method readCString (line 359) | public readCString(maxLength?: number): string {
method writeCString (line 379) | public writeCString(str: string): void {
method readUCS2String (line 385) | public readUCS2String(length: number, endianness?: boolean): string {
method writeUCS2String (line 388) | public writeUCS2String(str: string, endianness?: boolean, fixedLength?...
method writeUtf8WithLen (line 399) | public writeUtf8WithLen(str: string): this {
method readUtf8WithLen (line 405) | public readUtf8WithLen(): string {
method toUint8Array (line 409) | public toUint8Array(): Uint8Array {
method getBytes (line 413) | public getBytes(): Uint8Array {
method memcpy (line 416) | public static memcpy(dst: ArrayBuffer, dstOffset: number, src: ArrayBu...
method flipArrayEndianness (line 423) | public static flipArrayEndianness(array: TypedArray): TypedArray {
method arrayToNative (line 437) | public static arrayToNative(array: TypedArray, endianness: boolean): T...
method nativeToEndian (line 440) | public static nativeToEndian(array: TypedArray, endianness: boolean): ...
method createStringFromArray (line 443) | public static createStringFromArray(array: Uint8Array | Uint16Array): ...
FILE: src/data/HvaFile.ts
class HvaFile (line 5) | class HvaFile {
method constructor (line 8) | constructor(source: VirtualFile | DataStream) {
method fromVirtualFile (line 19) | private fromVirtualFile(file: VirtualFile): void {
method parseHvaData (line 23) | private parseHvaData(stream: DataStream, filename: string): void {
method readMatrix (line 41) | private readMatrix(stream: DataStream): Matrix4 {
FILE: src/data/IdxEntry.ts
class IdxEntry (line 1) | class IdxEntry {
FILE: src/data/IdxFile.ts
class IdxFile (line 3) | class IdxFile {
method constructor (line 5) | constructor(stream: DataStream) {
method parse (line 9) | private parse(stream: DataStream): void {
FILE: src/data/IniFile.ts
class IniFile (line 5) | class IniFile {
method constructor (line 7) | constructor(source?: VirtualFile | Record<string, any> | string) {
method fromVirtualFile (line 24) | public fromVirtualFile(virtualFile: VirtualFile): this {
method fromString (line 27) | public fromString(iniString: string): this {
method fromJson (line 32) | public fromJson(sectionsObject: Record<string, any>): this {
method toString (line 52) | public toString(): string {
method clone (line 59) | public clone(): IniFile {
method getOrCreateSection (line 66) | public getOrCreateSection(sectionName: string): IniSection {
method getSection (line 74) | public getSection(sectionName: string): IniSection | undefined {
method getOrderedSections (line 77) | public getOrderedSections(): IniSection[] {
method mergeWith (line 80) | public mergeWith(otherIniFile: IniFile): this {
FILE: src/data/IniParser.ts
class IniParser (line 2) | class IniParser {
method parse (line 6) | public parse(iniString: string): Record<string, IniSection> {
method stripQuotesAndComments (line 57) | private stripQuotesAndComments(str: string): string {
FILE: src/data/IniSection.ts
class IniSection (line 1) | class IniSection {
method constructor (line 5) | constructor(name: string) {
method fromJson (line 10) | public fromJson(json: Record<string, any>): this {
method clone (line 24) | public clone(): IniSection {
method set (line 34) | public set(key: string, value: string | string[]): void {
method get (line 37) | public get(key: string): string | string[] | undefined {
method has (line 40) | public has(key: string): boolean {
method getString (line 43) | public getString(key: string, defaultValue: string = ""): string {
method parseNumber (line 47) | private parseNumber(valueStr: string): number | undefined {
method getNumber (line 57) | public getNumber(key: string, defaultValue: number = 0): number {
method toFixedPointPrecision (line 69) | private toFixedPointPrecision(num: number): number {
method getFixed (line 72) | public getFixed(key: string, defaultValue: number = 0): number {
method getBool (line 75) | public getBool(key: string, defaultValue: boolean = false): boolean {
method getKeyArray (line 88) | public getKeyArray(key: string, defaultValue: string[] = []): string[] {
method getArray (line 92) | public getArray(key: string, separator: RegExp = /,\s*/, defaultValue:...
method getNumberArray (line 97) | public getNumberArray(key: string, separator: RegExp = /,\s*/, default...
method getFixedArray (line 120) | public getFixedArray(key: string, separator: RegExp = /,\s*/, defaultV...
method getEnum (line 124) | public getEnum<T extends object>(key: string, enumObject: T, defaultVa...
method getEnumNumeric (line 149) | public getEnumNumeric<T extends object>(key: string, enumObject: T, de...
method getEnumArray (line 166) | public getEnumArray<T extends object>(key: string, enumObject: T, sepa...
method getHighestNumericIndex (line 207) | public getHighestNumericIndex(): number {
method isNumericIndexArray (line 217) | public isNumericIndexArray(): boolean {
method getConcatenatedValues (line 225) | public getConcatenatedValues(): string {
method toString (line 237) | public toString(parentPrefix?: string): string {
method mergeWith (line 256) | public mergeWith(otherSection: IniSection): void {
method getOrCreateSection (line 278) | public getOrCreateSection(sectionName: string): IniSection {
method getSection (line 286) | public getSection(sectionName: string): IniSection | undefined {
method getOrderedSections (line 289) | public getOrderedSections(): IniSection[] {
FILE: src/data/MapFile.ts
type MapTile (line 14) | type MapTile = {
type Waypoint (line 23) | type Waypoint = {
class MapFile (line 28) | class MapFile extends IniFile {
method fromString (line 69) | fromString(iniString: string) {
method fromJson (line 112) | fromJson(i: any) {
method readStartingLocations (line 119) | readStartingLocations(waypoints: Waypoint[]) {
method readLighting (line 131) | readLighting() {
method readTagsAndTriggers (line 137) | readTagsAndTriggers() {
method readCellTags (line 148) | readCellTags(e: number) {
method readVariableNames (line 151) | readVariableNames() {
method readTiles (line 166) | readTiles() {
method readWaypoints (line 221) | readWaypoints(e: any) {
method readStructures (line 234) | readStructures(e: any) {
method readTagId (line 251) | readTagId(e: string) {
method readVehicles (line 254) | readVehicles() {
method readInfantries (line 279) | readInfantries() {
method readAircrafts (line 305) | readAircrafts() {
method readTerrains (line 326) | readTerrains(e: any) {
method readOverlays (line 339) | readOverlays() {
method readSmudges (line 370) | readSmudges() {
method decodePreviewImage (line 389) | decodePreviewImage() {
method normalizeIniEntryValue (line 396) | private normalizeIniEntryValue(value: string | string[]): string {
FILE: src/data/MapObjects.ts
class MapObject (line 2) | class MapObject {
method constructor (line 4) | constructor(type: ObjectType) {
method isStructure (line 7) | isStructure(): boolean {
method isVehicle (line 10) | isVehicle(): boolean {
method isInfantry (line 13) | isInfantry(): boolean {
method isAircraft (line 16) | isAircraft(): boolean {
method isTerrain (line 19) | isTerrain(): boolean {
method isSmudge (line 22) | isSmudge(): boolean {
method isOverlay (line 25) | isOverlay(): boolean {
method isNamed (line 28) | isNamed(): boolean {
method isTechno (line 31) | isTechno(): boolean {
class PositionedMapObject (line 35) | class PositionedMapObject extends MapObject {
class NamedMapObject (line 39) | class NamedMapObject extends PositionedMapObject {
class TechnoObject (line 42) | class TechnoObject extends NamedMapObject {
class TechnoTypeObject (line 50) | class TechnoTypeObject extends TechnoObject {
class Structure (line 52) | class Structure extends TechnoTypeObject {
method constructor (line 54) | constructor() {
class Vehicle (line 58) | class Vehicle extends TechnoTypeObject {
method constructor (line 59) | constructor() {
class Infantry (line 63) | class Infantry extends TechnoTypeObject {
method constructor (line 65) | constructor() {
class Aircraft (line 69) | class Aircraft extends TechnoTypeObject {
method constructor (line 70) | constructor() {
class Terrain (line 74) | class Terrain extends NamedMapObject {
method constructor (line 75) | constructor() {
class Smudge (line 79) | class Smudge extends NamedMapObject {
method constructor (line 80) | constructor() {
class Overlay (line 84) | class Overlay extends PositionedMapObject {
method constructor (line 87) | constructor() {
FILE: src/data/MixEntry.ts
class MixEntry (line 3) | class MixEntry {
method constructor (line 8) | constructor(hash: number, offset: number, length: number) {
method hashFilename (line 13) | public static hashFilename(filename: string, debugLog: boolean = false...
FILE: src/data/MixFile.ts
type MixFileFlags (line 6) | enum MixFileFlags {
class MixFile (line 10) | class MixFile {
method constructor (line 15) | constructor(stream: DataStream) {
method parseHeader (line 20) | private parseHeader(): void {
method parseRaHeader (line 34) | private parseRaHeader(): number {
method parseTdHeader (line 49) | private parseTdHeader(e: DataStream): number {
method containsFile (line 90) | public containsFile(filename: string): boolean {
method openFile (line 93) | public openFile(filename: string): VirtualFile {
FILE: src/data/Mp3File.ts
class Mp3File (line 3) | class Mp3File {
method constructor (line 6) | constructor(source: VirtualFile | DataStream | Blob | File, fileName?:...
method asFile (line 18) | asFile(): File {
method getBlob (line 39) | getBlob(): Blob {
FILE: src/data/Palette.ts
class Palette (line 5) | class Palette {
method fromVirtualFile (line 9) | static fromVirtualFile(file: VirtualFile): Palette {
method constructor (line 14) | constructor(source?: VirtualFile | Uint8Array | number[] | {
method fromVirtualFile (line 31) | private fromVirtualFile(vf: VirtualFile): void {
method fromJsonCompatible (line 35) | private fromJsonCompatible(data: Uint8Array | number[]): void {
method getColor (line 45) | getColor(index: number): Color {
method getColorAsHex (line 48) | getColorAsHex(index: number): number {
method setColors (line 51) | setColors(newColors: Color[]): void {
method size (line 58) | get size(): number {
method hash (line 61) | get hash(): number {
method computeHash (line 64) | private computeHash(colorArray: Color[]): number {
method clone (line 74) | clone(): Palette {
method remap (line 77) | remap(baseColor: Color): Palette {
FILE: src/data/PcxFile.ts
class PcxFile (line 5) | class PcxFile {
method constructor (line 10) | constructor(source: VirtualFile | DataStream) {
method fromVirtualFile (line 38) | static fromVirtualFile(vf: VirtualFile): PcxFile {
method toPngBlob (line 41) | async toPngBlob(): Promise<Blob | null> {
method toDataUrl (line 45) | toDataUrl(): string {
method toCanvas (line 48) | toCanvas(): HTMLCanvasElement {
method fixAlpha (line 51) | private fixAlpha(rgbaPixelArray: Uint8Array | Uint8ClampedArray): void {
FILE: src/data/ShpFile.ts
type ShpFrameHeader (line 5) | interface ShpFrameHeader {
class ShpFile (line 13) | class ShpFile {
method fromVirtualFile (line 19) | static fromVirtualFile(file: VirtualFile): ShpFile {
method constructor (line 24) | constructor(file?: VirtualFile) {
method fromVirtualFile (line 29) | private fromVirtualFile(file: VirtualFile): void {
method readFrameHeader (line 97) | private readFrameHeader(s: DataStream): ShpFrameHeader {
method readImageData (line 118) | private readImageData(s: DataStream, width: number, height: number, co...
method getImage (line 168) | getImage(index: number): ShpImage {
method addImage (line 174) | addImage(image: ShpImage): void {
method clip (line 180) | clip(newWidth: number, newHeight: number): ShpFile {
FILE: src/data/ShpImage.ts
class ShpImage (line 1) | class ShpImage {
method constructor (line 7) | constructor(imageData?: Uint8Array, width?: number, height?: number, x...
method clip (line 16) | clip(clipWidth: number, clipHeight: number): ShpImage {
FILE: src/data/Strings.ts
class Strings (line 3) | class Strings {
method constructor (line 7) | constructor(source?: CsfFile | {
method fromCsf (line 21) | public fromCsf(csfFile: CsfFile): void {
method fromJson (line 24) | public fromJson(jsonData: {
method sanitizeValue (line 31) | private sanitizeValue(value: string): string {
method setValue (line 34) | public setValue(key: string, value: string): void {
method has (line 37) | public has(key: string): boolean {
method get (line 40) | public get(key: string, ...args: any[]): string {
method getKeys (line 56) | public getKeys(): string[] {
FILE: src/data/TmpFile.ts
class TmpFile (line 4) | class TmpFile {
method constructor (line 10) | constructor(file?: VirtualFile) {
method fromVirtualFile (line 15) | private fromVirtualFile(file: VirtualFile): void {
method getTile (line 39) | public getTile(tileX: number, tileY: number): TmpImage | undefined {
FILE: src/data/TmpImage.ts
type TmpImageFlags (line 3) | enum TmpImageFlags {
class TmpImage (line 11) | class TmpImage {
method constructor (line 30) | constructor(stream: DataStream, tileWidthCells: number, tileHeightCell...
method fromStream (line 33) | private fromStream(stream: DataStream, tileWidthCells: number, tileHei...
method readRadarRgbInternal (line 68) | private readRadarRgbInternal(r: number, g: number, b: number): Color {
FILE: src/data/VxlFile.ts
type Voxel (line 6) | interface Voxel {
type Span (line 13) | interface Span {
type SectionTailer (line 18) | interface SectionTailer {
type PlainVxlFile (line 23) | interface PlainVxlFile {
class VxlFile (line 27) | class VxlFile {
method constructor (line 31) | constructor(virtualFile?: VirtualFile) {
method fromVirtualFile (line 36) | fromVirtualFile(virtualFile: VirtualFile): void {
method readSectionHeader (line 69) | private readSectionHeader(section: Section, stream: DataStream): void {
method readSectionTailer (line 75) | private readSectionTailer(section: Section, stream: DataStream): Secti...
method readTransfMatrix (line 93) | private readTransfMatrix(stream: DataStream): THREE.Matrix4 {
method readSectionBodySpans (line 101) | private readSectionBodySpans(section: Section, tailer: SectionTailer, ...
method readSpanVoxels (line 133) | private readSpanVoxels(startOffset: number, endOffset: number, x: numb...
method fromPlain (line 155) | fromPlain(plainObject: PlainVxlFile): VxlFile {
method toPlain (line 160) | toPlain(): PlainVxlFile {
method getSection (line 166) | getSection(index: number): Section | undefined {
FILE: src/data/WavFile.ts
class WavFile (line 4) | class WavFile {
method constructor (line 7) | constructor(source: VirtualFile | DataStream | Uint8Array) {
method fromRawData (line 18) | private fromRawData(data: Uint8Array): this {
method fromVirtualFileOrDataStream (line 22) | private fromVirtualFileOrDataStream(file: VirtualFile | DataStream): t...
method getRawData (line 38) | getRawData(): Uint8Array | undefined {
method getData (line 41) | getData(): Uint8Array {
method setData (line 51) | setData(decodedData: Uint8Array): void {
method decodeData (line 55) | private decodeData(data: Uint8Array): Uint8Array {
method isRawImaAdpcm (line 63) | isRawImaAdpcm(): boolean {
FILE: src/data/encoding/Blowfish.ts
class Blowfish (line 1) | class Blowfish {
method byteSwap32 (line 4) | private static byteSwap32(value: number): number {
method constructor (line 9) | constructor(key: number[] | Uint8Array) {
method encrypt (line 219) | encrypt(data: Uint32Array): Uint32Array {
method decrypt (line 222) | decrypt(data: Uint32Array): Uint32Array {
method runCipher (line 225) | private runCipher(data: Uint32Array, cipherFunc: (l: number, r: number...
method _encrypt (line 241) | private _encrypt(l: number, r: number): [
method _decrypt (line 260) | private _decrypt(l: number, r: number): [
method s (line 279) | private s(val: number, boxIndex: number): number {
method bf_f (line 282) | private bf_f(val: number): number {
method round (line 287) | private round(l: number, r: number, pIndex: number): number {
FILE: src/data/encoding/BlowfishKey.ts
class i (line 19) | class i {
method constructor (line 23) | constructor() {
class BlowfishKey (line 28) | class BlowfishKey {
method constructor (line 39) | constructor() {
method init_bignum (line 46) | init_bignum(e, t, i) {
method move_key_to_big (line 51) | move_key_to_big(e, t, i, r) {
method key_to_bignum (line 61) | key_to_bignum(e, t, i) {
method len_bignum (line 74) | len_bignum(e, t) {
method bitlen_bignum (line 80) | bitlen_bignum(e, t) {
method init_pubkey (line 89) | init_pubkey() {
method len_predata (line 113) | len_predata() {
method cmp_bignum (line 117) | cmp_bignum(e, t, i) {
method mov_bignum (line 126) | mov_bignum(e, t, i) {
method shr_bignum (line 130) | shr_bignum(e, t, i) {
method shl_bignum (line 147) | shl_bignum(e, t, i) {
method sub_bignum (line 164) | sub_bignum(e, t, i, r, s) {
method sub_bignum_word (line 178) | sub_bignum_word(e, t, i, r, s) {
method inv_bignum (line 189) | inv_bignum(e, t, i) {
method inc_bignum (line 210) | inc_bignum(e, t) {
method init_two_dw (line 215) | init_two_dw(e, t) {
method mul_bignum_word (line 235) | mul_bignum_word(e, t, i, r) {
method mul_bignum (line 246) | mul_bignum(e, t, i, r) {
method not_bignum (line 255) | not_bignum(e, t) {
method neg_bignum (line 260) | neg_bignum(e, t) {
method get_mulword (line 263) | get_mulword(e, t) {
method dec_bignum (line 282) | dec_bignum(e, t) {
method calc_a_bignum (line 287) | calc_a_bignum(e, t, i, r) {
method clear_tmp_vars (line 316) | clear_tmp_vars(e) {
method calc_a_key (line 327) | calc_a_key(e, t, i, r, s) {
method memcpy (line 347) | memcpy(e, t, i) {
method process_predata (line 352) | process_predata(e, t, i) {
method decryptKey (line 364) | decryptKey(e) {
FILE: src/data/encoding/Format3.ts
class Format3 (line 1) | class Format3 {
method decode (line 2) | static decode(sourceData: Uint8Array, width: number, height: number): ...
FILE: src/data/encoding/Format5.ts
class Format5 (line 3) | class Format5 {
method decode (line 4) | static decode(input: Uint8Array, outputSize: number, format: number = ...
method decodeInto (line 9) | static decodeInto(input: Uint8Array, output: Uint8Array, format: numbe...
FILE: src/data/encoding/Format80.ts
class Format80 (line 2) | class Format80 {
method decode (line 3) | static decode(input: Uint8Array, outputSize: number): Uint8Array {
method decodeInto (line 8) | static decodeInto(input: Uint8Array, output: Uint8Array): number {
method replicatePrevious (line 61) | private static replicatePrevious(output: Uint8Array, destIndex: number...
FILE: src/data/encoding/MiniLzo.ts
class MiniLzo (line 2) | class MiniLzo {
method decompress (line 3) | static decompress(input: Uint8Array, outputSize: number): Uint8Array {
FILE: src/data/encoding/lzo1x.ts
type LzoState (line 1) | interface LzoState {
type LzoConfig (line 6) | interface LzoConfig {
class Lzo1xImpl (line 11) | class Lzo1xImpl {
method setBlockSize (line 46) | setBlockSize(blockSize: number) {
method setOutputSize (line 54) | setOutputSize(outputSize: number) {
method setReturnNewBuffers (line 62) | setReturnNewBuffers(value: boolean) {
method applyConfig (line 66) | applyConfig(cfg?: LzoConfig) {
method extendBuffer (line 75) | extendBuffer() {
method match_next (line 82) | match_next() {
method match_done (line 97) | match_done() {
method copy_match (line 102) | copy_match() {
method copy_from_buf (line 113) | copy_from_buf() {
method match (line 123) | match() {
method decompress (line 180) | decompress(state: LzoState) {
method compress (line 251) | compress(_state: LzoState) {
method setBlockSize (line 259) | setBlockSize(blockSize: number) {
method setOutputEstimate (line 262) | setOutputEstimate(outputSize: number) {
method setReturnNewBuffers (line 265) | setReturnNewBuffers(value: boolean) {
method compress (line 268) | compress(state: LzoState, cfg?: LzoConfig) {
method decompress (line 274) | decompress(state: LzoState, cfg?: LzoConfig) {
FILE: src/data/hva/Section.ts
class Section (line 2) | class Section {
method constructor (line 5) | constructor() {
method getMatrix (line 7) | public getMatrix(index: number): Matrix4 {
FILE: src/data/map/MapLighting.ts
class MapLighting (line 1) | class MapLighting {
method constructor (line 9) | constructor() {
method read (line 18) | read(reader: any, prefix: string = ""): MapLighting {
method copy (line 27) | copy(source: MapLighting): MapLighting {
FILE: src/data/map/MapObjects.ts
class MapObject (line 2) | class MapObject {
method constructor (line 3) | constructor(public type: ObjectType) { }
method isStructure (line 4) | isStructure(): boolean {
method isVehicle (line 7) | isVehicle(): boolean {
method isInfantry (line 10) | isInfantry(): boolean {
method isAircraft (line 13) | isAircraft(): boolean {
method isTerrain (line 16) | isTerrain(): boolean {
method isSmudge (line 19) | isSmudge(): boolean {
method isOverlay (line 22) | isOverlay(): boolean {
method isNamed (line 25) | isNamed(): boolean {
method isTechno (line 28) | isTechno(): boolean {
class Structure (line 32) | class Structure extends MapObject {
method constructor (line 33) | constructor() {
class Vehicle (line 37) | class Vehicle extends MapObject {
method constructor (line 38) | constructor() {
class Infantry (line 42) | class Infantry extends MapObject {
method constructor (line 43) | constructor() {
class Aircraft (line 47) | class Aircraft extends MapObject {
method constructor (line 48) | constructor() {
class Terrain (line 52) | class Terrain extends MapObject {
method constructor (line 53) | constructor() {
class Smudge (line 57) | class Smudge extends MapObject {
method constructor (line 58) | constructor() {
class Overlay (line 62) | class Overlay extends MapObject {
method constructor (line 63) | constructor() {
FILE: src/data/map/SpecialFlags.ts
class SpecialFlags (line 1) | class SpecialFlags {
method read (line 3) | read(data: {
FILE: src/data/map/Variable.ts
class Variable (line 1) | class Variable {
method constructor (line 4) | constructor(name: string, value: any) {
method clone (line 8) | clone(): Variable {
FILE: src/data/map/tag/CellTag.ts
class CellTag (line 1) | class CellTag {
FILE: src/data/map/tag/CellTagsReader.ts
class CellTagsReader (line 2) | class CellTagsReader {
method read (line 3) | read(section: IniSection, version: number): Array<{
method readCoords (line 24) | readCoords(key: number, version: number): {
FILE: src/data/map/tag/Tag.ts
class Tag (line 1) | class Tag {
FILE: src/data/map/tag/TagRepeatType.ts
type TagRepeatType (line 1) | enum TagRepeatType {
FILE: src/data/map/tag/TagsReader.ts
class TagsReader (line 3) | class TagsReader {
method read (line 4) | read(section: IniSection): Array<{
FILE: src/data/map/trigger/Trigger.ts
class Trigger (line 1) | class Trigger {
FILE: src/data/map/trigger/TriggerAction.ts
class TriggerAction (line 1) | class TriggerAction {
method constructor (line 2) | constructor() {
method execute (line 4) | execute(): void {
FILE: src/data/map/trigger/TriggerActionType.ts
type TriggerActionType (line 1) | enum TriggerActionType {
FILE: src/data/map/trigger/TriggerEvent.ts
class TriggerEvent (line 1) | class TriggerEvent {
method constructor (line 2) | constructor() {
FILE: src/data/map/trigger/TriggerEventType.ts
type TriggerEventType (line 1) | enum TriggerEventType {
FILE: src/data/map/trigger/TriggerReader.ts
class TriggerReader (line 4) | class TriggerReader {
method read (line 5) | read(triggers: IniSection, events: IniSection, actions: IniSection, ta...
method readTriggers (line 55) | private readTriggers(triggers: IniSection) {
method readEvents (line 86) | private readEvents(events: IniSection) {
method readActions (line 122) | private readActions(actions: IniSection) {
method readAZActionParam (line 170) | private readAZActionParam(param: string): number {
FILE: src/data/vfs/Archive.ts
class Archive (line 1) | class Archive {
method constructor (line 2) | constructor() {
FILE: src/data/vfs/FileNotFoundError.ts
class FileNotFoundError (line 1) | class FileNotFoundError extends Error {
method constructor (line 3) | constructor(message?: string, cause?: Error) {
FILE: src/data/vfs/FileSystem.ts
type FileSystem (line 4) | interface FileSystem {
FILE: src/data/vfs/IOError.ts
class IOError (line 1) | class IOError extends Error {
method constructor (line 3) | constructor(message: string, cause?: Error) {
FILE: src/data/vfs/MemArchive.ts
class MemArchive (line 2) | class MemArchive {
method constructor (line 4) | constructor() {
method addFile (line 7) | addFile(file: VirtualFile): void {
method containsFile (line 10) | containsFile(filename: string): boolean {
method openFile (line 13) | openFile(filename: string): VirtualFile {
method listFiles (line 19) | listFiles(): string[] {
method getAllFiles (line 22) | getAllFiles(): VirtualFile[] {
FILE: src/data/vfs/NameNotAllowedError.ts
class NameNotAllowedError (line 2) | class NameNotAllowedError extends IOError {
method constructor (line 3) | constructor(message: string = "File name is not allowed", cause?: Erro...
FILE: src/data/vfs/RealFileSystem.ts
type RFSConstructorOptions (line 4) | interface RFSConstructorOptions {
class RealFileSystem (line 6) | class RealFileSystem {
method constructor (line 10) | constructor(options?: RFSConstructorOptions) {
method addRootDirectoryHandle (line 13) | addRootDirectoryHandle(handle: FileSystemDirectoryHandle): RealFileSys...
method getRootDirectoryHandle (line 20) | getRootDirectoryHandle(): FileSystemDirectoryHandle | undefined {
method addDirectoryHandle (line 23) | addDirectoryHandle(handle: FileSystemDirectoryHandle): RealFileSystemD...
method addDirectory (line 28) | addDirectory(dir: RealFileSystemDir): void {
method getDirectory (line 33) | async getDirectory(path: string): Promise<RealFileSystemDir> {
method findDirectory (line 47) | async findDirectory(directoryName: string): Promise<RealFileSystemDir ...
method getRootDirectory (line 60) | getRootDirectory(): RealFileSystemDir | undefined {
method containsEntry (line 63) | async containsEntry(entryName: string): Promise<boolean> {
method openFile (line 71) | async openFile(filename: string, skipCaseFix: boolean = false): Promis...
method getRawFile (line 84) | async getRawFile(filename: string): Promise<File> {
method getEntries (line 96) | async *getEntries(): AsyncGenerator<string, void, undefined> {
FILE: src/data/vfs/RealFileSystemDir.ts
class RealFileSystemDir (line 7) | class RealFileSystemDir {
method constructor (line 10) | constructor(handle: FileSystemDirectoryHandle, caseSensitive: boolean ...
method getNativeHandle (line 14) | getNativeHandle(): FileSystemDirectoryHandle {
method name (line 17) | get name(): string {
method getEntries (line 20) | async *getEntries(): AsyncGenerator<string, void, undefined> {
method listEntries (line 36) | async listEntries(): Promise<string[]> {
method getFileHandles (line 43) | async *getFileHandles(): AsyncGenerator<FileSystemFileHandle, void, un...
method getRawFiles (line 61) | async *getRawFiles(): AsyncGenerator<File, void, undefined> {
method containsEntry (line 66) | async containsEntry(entryName: string): Promise<boolean> {
method resolveEntryName (line 69) | async resolveEntryName(entryName: string): Promise<string | undefined> {
method fixEntryCase (line 93) | async fixEntryCase(entryName: string): Promise<string> {
method getRawFile (line 103) | async getRawFile(filename: string, skipCaseFix: boolean = false, type?...
method openFile (line 127) | async openFile(filename: string, skipCaseFix: boolean = false): Promis...
method writeFile (line 131) | async writeFile(virtualFile: VirtualFile, filenameOverride?: string): ...
method deleteFile (line 169) | async deleteFile(filename: string, skipCaseFix: boolean = false): Prom...
method getDirectory (line 192) | async getDirectory(dirName: string, forceCaseSensitive: boolean = this...
method getOrCreateDirectory (line 212) | async getOrCreateDirectory(dirName: string, forceCaseSensitive: boolea...
method getOrCreateDirectoryHandle (line 234) | async getOrCreateDirectoryHandle(dirName: string, isPrivate?: boolean)...
method deleteDirectory (line 238) | async deleteDirectory(dirName: string, recursive: boolean = false): Pr...
FILE: src/data/vfs/StorageQuotaError.ts
class StorageQuotaError (line 1) | class StorageQuotaError extends Error {
method constructor (line 3) | constructor(message: string = "Storage quota exceeded", cause?: Error) {
FILE: src/data/vfs/VirtualFile.ts
class VirtualFile (line 3) | class VirtualFile {
method fromRealFile (line 6) | public static async fromRealFile(realFile: File): Promise<VirtualFile> {
method fromBytes (line 19) | public static fromBytes(bytes: ArrayBuffer | ArrayBufferView, filename...
method factory (line 26) | public static factory(buffer: ArrayBuffer | ArrayBufferView, filename:...
method constructor (line 37) | constructor(stream: DataStream, filename: string) {
method readAsString (line 41) | readAsString(encoding?: string): string {
method getBytes (line 45) | getBytes(): Uint8Array {
method getSize (line 48) | getSize(): number {
method asFile (line 51) | asFile(mimeType?: string): File {
FILE: src/data/vfs/VirtualFileSystem.ts
type VfsLogger (line 10) | interface VfsLogger {
type Archive (line 15) | interface Archive {
class VirtualFileSystem (line 19) | class VirtualFileSystem {
method constructor (line 24) | constructor(rfs: RealFileSystem, logger: VfsLogger) {
method fileExists (line 30) | fileExists(filename: string): boolean {
method openFile (line 38) | openFile(filename: string): VirtualFile {
method addArchive (line 46) | addArchive(archive: Archive, name: string): void {
method hasArchive (line 53) | hasArchive(name: string): boolean {
method removeArchive (line 56) | removeArchive(name: string): void {
method listArchives (line 67) | listArchives(): string[] {
method debugListFileOwners (line 70) | debugListFileOwners(filename: string): string[] {
method openFileWithRfs (line 82) | private async openFileWithRfs(filename: string): Promise<VirtualFile |...
method addArchiveByFilename (line 101) | private async addArchiveByFilename(filename: string, createArchive: (f...
method addMixFile (line 120) | async addMixFile(filename: string): Promise<void> {
method addBagFile (line 135) | async addBagFile(filename: string): Promise<void> {
method loadImplicitMixFiles (line 154) | async loadImplicitMixFiles(engineType: EngineType): Promise<void> {
method loadExtraMixFiles (line 197) | async loadExtraMixFiles(engineType: EngineType): Promise<void> {
method loadStandaloneFiles (line 244) | async loadStandaloneFiles(options?: {
FILE: src/data/vxl/Section.ts
type PlainSection (line 6) | interface PlainSection {
class Section (line 18) | class Section {
method spanX (line 29) | get spanX(): number {
method spanY (line 32) | get spanY(): number {
method spanZ (line 35) | get spanZ(): number {
method scaleX (line 38) | get scaleX(): number {
method scaleY (line 41) | get scaleY(): number {
method scaleZ (line 44) | get scaleZ(): number {
method scale (line 47) | get scale(): Vector3 {
method getAllVoxels (line 50) | getAllVoxels(): {
method getNormals (line 66) | getNormals(): Vector3[] {
method scaleHvaMatrix (line 77) | scaleHvaMatrix(matrix: Matrix4): Matrix4 {
method toPlain (line 86) | toPlain(): PlainSection {
method fromPlain (line 100) | fromPlain(plain: PlainSection): this {
FILE: src/data/vxl/Span.ts
type Span (line 2) | interface Span {
FILE: src/data/vxl/SpanOffsets.ts
class SpanOffsets (line 1) | class SpanOffsets {
method constructor (line 2) | constructor() {
FILE: src/data/vxl/Voxel.ts
type Voxel (line 1) | interface Voxel {
FILE: src/data/vxl/VoxelField.ts
class VoxelField (line 2) | class VoxelField {
method constructor (line 7) | constructor(sizeX: number, sizeY: number, sizeZ: number) {
method add (line 13) | add(voxel: Voxel): void {
method get (line 24) | get(x: number, y: number, z: number): Voxel | undefined {
method forEachVoxel (line 30) | forEachVoxel(callback: (voxel: Voxel, x: number, y: number, z: number)...
FILE: src/data/vxl/VxlHeader.ts
class VxlHeader (line 2) | class VxlHeader {
method read (line 11) | read(stream: DataStream): void {
FILE: src/data/zip/Zip.ts
type FileRecord (line 3) | interface FileRecord {
type ByteArrayData (line 11) | interface ByteArrayData {
class Zip (line 15) | class Zip {
method constructor (line 22) | constructor(zip64: boolean = false) {
method enqueue (line 38) | private enqueue(data: Uint8Array): void {
method close (line 41) | private close(): void {
method getZip64ExtraField (line 44) | private getZip64ExtraField(sizeBig: bigint, offsetBig: bigint): Uint8A...
method isWritingFile (line 54) | private isWritingFile(): boolean {
method startFile (line 58) | public startFile(fileName: string, fileDate: Date): void {
method appendData (line 98) | public appendData(data: Uint8Array): void {
method endFile (line 107) | public endFile(): void {
method finish (line 122) | public finish(): void {
method getOutputStream (line 207) | public getOutputStream(): ReadableStream<Uint8Array> {
FILE: src/data/zip/ZipUtils.ts
class ZipUtils (line 1) | class ZipUtils {
method createByteArray (line 2) | static createByteArray(entries: {
method getTimeStruct (line 37) | static getTimeStruct(date: Date): number {
method getDateStruct (line 40) | static getDateStruct(date: Date): number {
FILE: src/engine/AnimProps.ts
class AnimProps (line 5) | class AnimProps {
method constructor (line 20) | constructor(public art: IniSection, frameCountOrShpFile: number | ShpF...
method init (line 23) | private init(frameCountOrShpFile: number | ShpFile): void {
method getArt (line 48) | getArt(): IniSection {
method setArt (line 51) | setArt(art: IniSection): void {
FILE: src/engine/Animation.ts
type AnimationState (line 4) | enum AnimationState {
class Animation (line 11) | class Animation {
method constructor (line 19) | constructor(public props: AnimProps, public speed: BoxedVar<number>) { }
method getState (line 20) | getState(): AnimationState {
method start (line 23) | start(time: number, delayFrames: number = 0): void {
method pause (line 30) | pause(): void {
method unpause (line 35) | unpause(): void {
method reset (line 40) | reset(): void {
method stop (line 43) | stop(): void {
method update (line 46) | update(time: number): void {
method endLoop (line 67) | endLoop(): void {
method endLoopAndPlayToEnd (line 70) | endLoopAndPlayToEnd(): void {
method rewind (line 74) | rewind(): void {
method getCurrentFrame (line 82) | getCurrentFrame(): number {
method computeNextFrame (line 85) | private computeNextFrame(framesToAdvance: number): boolean {
FILE: src/engine/AsyncResourceCollection.ts
class AsyncResourceCollection (line 1) | class AsyncResourceCollection {
method constructor (line 2) | constructor() {
FILE: src/engine/Engine.ts
type AppLoggerType (line 24) | type AppLoggerType = typeof AppLogger;
type TheaterSettings (line 25) | interface TheaterSettings {
type VfsLogger (line 36) | interface VfsLogger {
type EngineType (line 41) | enum EngineType {
class Engine (line 48) | class Engine {
method getVersion (line 213) | static getVersion(): string {
method getModHash (line 216) | static getModHash(): number {
method getActiveMod (line 222) | static getActiveMod(): string | undefined {
method setActiveMod (line 225) | static setActiveMod(modName: string | undefined): void {
method initGameResSource (line 228) | static initGameResSource(source: GameResSource): void {
method initRfs (line 231) | static async initRfs(rootHandle: FileSystemDirectoryHandle): Promise<R...
method initVfs (line 236) | static async initVfs(rfsInstance: RealFileSystem | undefined, logger: ...
method supportsTheater (line 270) | static supportsTheater(theaterType: TheaterType): boolean {
method getTheaterSettings (line 274) | static getTheaterSettings(engineType: EngineType, theaterType: Theater...
method loadTheater (line 285) | static async loadTheater(theaterType: TheaterType): Promise<Theater> {
method unloadTheater (line 312) | static unloadTheater(theaterType: TheaterType): void {
method unloadSideMixData (line 321) | static unloadSideMixData(): void {
method getTheaterIni (line 334) | static getTheaterIni(engineType: EngineType, theaterType: TheaterType)...
method loadRules (line 338) | static loadRules(): void {
method computeModHash (line 364) | static computeModHash(): number {
method getRules (line 401) | static getRules(): IniFile {
method getArt (line 407) | static getArt(): IniFile {
method getAi (line 412) | static getAi(): IniFile {
method getFileNameVariant (line 417) | static getFileNameVariant(baseFileName: string): string {
method getMpModes (line 428) | static getMpModes(): GameModes {
method getUiIni (line 431) | static getUiIni(): IniFile {
method getIni (line 435) | static getIni(fileName: string): IniFile {
method loadMapList (line 443) | static async loadMapList(): Promise<MapList> {
method getTileData (line 493) | static getTileData(): LazyResourceCollection<TmpFile> {
method getImages (line 496) | static getImages(): LazyResourceCollection<ShpFile> {
method getVoxels (line 499) | static getVoxels(): LazyResourceCollection<VxlFile> {
method getVoxelAnims (line 502) | static getVoxelAnims(): LazyResourceCollection<HvaFile> {
method getPalettes (line 505) | static getPalettes(): LazyResourceCollection<Palette> {
method getSounds (line 508) | static getSounds(): LazyResourceCollection<WavFile> {
method getThemes (line 511) | static getThemes(): LazyAsyncResourceCollection<Mp3File> {
method getTaunts (line 514) | static getTaunts(): LazyAsyncResourceCollection<WavFile> {
method getActiveEngine (line 517) | static getActiveEngine(): EngineType {
method getLastTheaterType (line 520) | static getLastTheaterType(): TheaterType | undefined {
method getCacheDir (line 523) | static async getCacheDir(): Promise<FileSystemDirectoryHandle | undefi...
method getReplayDir (line 532) | static async getReplayDir(): Promise<FileSystemDirectoryHandle | undef...
method getModDir (line 543) | static async getModDir(): Promise<FileSystemDirectoryHandle | undefine...
method getMapDir (line 546) | static async getMapDir(): Promise<FileSystemDirectoryHandle | undefine...
method getOrCreateDir (line 549) | static async getOrCreateDir(dirName: string, isPrivate: boolean = fals...
method getMapList (line 562) | static getMapList(): MapList | undefined {
method destroy (line 565) | static destroy(): void {
FILE: src/engine/EngineType.ts
type EngineType (line 1) | enum EngineType {
FILE: src/engine/GameAnimationLoop.ts
type LocalPlayer (line 3) | interface LocalPlayer {
type Renderer (line 6) | interface Renderer {
type Sound (line 15) | interface Sound {
type GameTurnManager (line 20) | interface GameTurnManager {
type GameAnimationLoopOptions (line 26) | interface GameAnimationLoopOptions {
class GameAnimationLoop (line 31) | class GameAnimationLoop {
method constructor (line 46) | constructor(localPlayer: LocalPlayer, renderer: Renderer, sound: Sound...
method start (line 149) | start(): void {
method updateDeltaGameFrames (line 164) | private updateDeltaGameFrames(timestamp: number): number {
method tickGame (line 184) | private tickGame(timestamp: number): boolean {
method updateRenderer (line 197) | private updateRenderer(timestamp: number, interpolation: number): void {
method render (line 215) | private render(): boolean {
method stop (line 232) | stop(): void {
method destroy (line 246) | destroy(): void {
FILE: src/engine/ImageFinder.ts
class MissingImageError (line 1) | class MissingImageError extends Error {
class ImageFinder (line 3) | class ImageFinder {
method constructor (line 7) | constructor(images: Map<string, any>, theater: any) {
method findByObjectArt (line 11) | findByObjectArt(objectArt: {
method find (line 17) | find(artName: string, useTheaterExtension: boolean) {
method tryFind (line 25) | tryFind(artName: string, useTheaterExtension: boolean) {
method getFilename (line 36) | getFilename(artName: string, useTheaterExtension: boolean) {
method applyNewTheaterIfNeeded (line 42) | applyNewTheaterIfNeeded(artName: string, filename: string) {
method applyNewTheater (line 51) | applyNewTheater(filename: string) {
FILE: src/engine/IsoCoords.ts
type Point (line 2) | interface Point {
type Point3D (line 6) | interface Point3D extends Point {
class IsoCoords (line 9) | class IsoCoords {
method init (line 11) | static init(origin: Point): void {
method worldToScreen (line 14) | static worldToScreen(x: number, y: number): Point {
method screenToWorld (line 27) | static screenToWorld(x: number, y: number): Point {
method vecWorldToScreen (line 36) | static vecWorldToScreen(vec: Point3D): Point {
method tileToScreen (line 41) | static tileToScreen(tileX: number, tileY: number): Point {
method tileHeightToScreen (line 45) | static tileHeightToScreen(height: number): number {
method tile3dToScreen (line 48) | static tile3dToScreen(tileX: number, tileY: number, height: number): P...
method screenTileToScreen (line 53) | static screenTileToScreen(tileX: number, tileY: number): Point {
method screenToScreenTile (line 59) | static screenToScreenTile(x: number, y: number): Point {
method screenTileToWorld (line 65) | static screenTileToWorld(tileX: number, tileY: number): Point {
method getScreenTileSize (line 69) | static getScreenTileSize(): {
method screenDistanceToWorld (line 78) | static screenDistanceToWorld(x: number, y: number): {
FILE: src/engine/LazyAsyncResourceCollection.ts
class LazyAsyncResourceCollection (line 2) | class LazyAsyncResourceCollection<T> {
method constructor (line 7) | constructor(resourceFactory: (file: VirtualFile | File) => Promise<T> ...
method setDir (line 11) | setDir(rfsDir: FileSystemDirectoryHandle | undefined): void {
method set (line 14) | set(key: string, resource: T): void {
method has (line 17) | async has(key: string): Promise<boolean> {
method get (line 28) | async get(key: string): Promise<T | undefined> {
method clear (line 45) | clear(key?: string): void {
method clearAll (line 53) | clearAll(): void {
FILE: src/engine/LazyResourceCollection.ts
class LazyResourceCollection (line 3) | class LazyResourceCollection<T> {
method constructor (line 7) | constructor(resourceFactory: (file: VirtualFile) => T) {
method setVfs (line 10) | setVfs(vfs: VirtualFileSystem): void {
method set (line 13) | set(key: string, resource: T): void {
method has (line 16) | has(key: string): boolean {
method get (line 26) | get(key: string): T | undefined {
method clear (line 58) | clear(key?: string): void {
method clearAll (line 66) | clearAll(): void {
FILE: src/engine/Lighting.ts
class Lighting (line 6) | class Lighting {
method constructor (line 12) | constructor(parent?: Lighting) {
method onChange (line 27) | get onChange() {
method mapLighting (line 30) | get mapLighting() {
method getAmbient (line 33) | getAmbient(): MapLighting {
method forceUpdate (line 36) | forceUpdate(force?: any) {
method applyAmbientOverride (line 39) | applyAmbientOverride(override: MapLighting) {
method getBaseAmbient (line 43) | getBaseAmbient() {
method addTileLight (line 46) | addTileLight(tile: string, light: any) {
method removeTileLight (line 52) | removeTileLight(tile: string, light: any) {
method compute (line 61) | compute(type: LightingType, tile: any, height: number = 0): THREE.Vect...
method computeNoAmbient (line 72) | computeNoAmbient(type: LightingType, tile: any, height: number = 0): n...
method computeLevel (line 75) | computeLevel(type: LightingType, height: number): number {
method computeTint (line 78) | computeTint(type: LightingType): THREE.Vector3 {
method computeTileTint (line 87) | computeTileTint(tile: string, type: LightingType, result: THREE.Vector...
method computeTileLightIntensity (line 101) | computeTileLightIntensity(tile: string): number {
method getAmbientIntensity (line 111) | getAmbientIntensity(): number {
method dispose (line 114) | dispose() {
FILE: src/engine/MapDigest.ts
class MapDigest (line 2) | class MapDigest {
method compute (line 3) | static compute(data: {
FILE: src/engine/MapList.ts
class MapList (line 5) | class MapList {
method constructor (line 8) | constructor(gameModes: GameModes) {
method addFromIni (line 11) | addFromIni(iniFile: IniFile): this {
method add (line 30) | add(manifest: MapManifest): void {
method addFromMapFile (line 33) | addFromMapFile(mapFile: VirtualFile): void {
method getAll (line 36) | getAll(): MapManifest[] {
method getByName (line 39) | getByName(fileName: string): MapManifest | undefined {
method sortByName (line 42) | sortByName(): void {
method clone (line 45) | clone(): MapList {
method mergeWith (line 50) | mergeWith(otherList: MapList): this {
method dedupeEntries (line 55) | private dedupeEntries(): void {
FILE: src/engine/MapManifest.ts
class MapManifest (line 5) | class MapManifest {
method fromIni (line 11) | fromIni(section: IniSection, availableGameModes: GameModeEntry[]): this {
method getFullMapTitle (line 20) | getFullMapTitle(strings: Strings): string {
method addTitleSlotsSuffix (line 24) | private addTitleSlotsSuffix(title: string, maxPlayers: number): string {
method fromMapFile (line 30) | fromMapFile(mapFile: VirtualFile, availableGameModes: GameModeEntry[])...
method extractIniSection (line 59) | private extractIniSection(sectionName: string, content: string): strin...
FILE: src/engine/MapSupport.ts
type BuildingRule (line 8) | interface BuildingRule {
type TechnoRule (line 11) | interface TechnoRule {
class MapSupport (line 15) | class MapSupport {
method check (line 16) | static check(map: MapFile, translator: Strings): string | undefined {
FILE: src/engine/RenderableManager.ts
class RenderableManager (line 8) | class RenderableManager {
method constructor (line 20) | constructor(world: World, worldScene: WorldScene, camera: Camera, rend...
method init (line 64) | init(): void {
method getRenderableById (line 73) | getRenderableById(id: string): Renderable {
method getRenderableByGameObject (line 76) | getRenderableByGameObject(gameObject: GameObject): Renderable {
method getRenderableContainer (line 79) | getRenderableContainer(): OctreeContainer {
method onObjectPositionChanged (line 82) | onObjectPositionChanged(gameObject: GameObject, tileChanged: boolean):...
method removeAndDisposeRenderable (line 89) | removeAndDisposeRenderable(renderable: Renderable, gameObject: GameObj...
method createTransientAnim (line 98) | createTransientAnim(anim: any, callback?: (renderable: Renderable) => ...
method createAnim (line 106) | createAnim(anim: any, callback?: (renderable: Renderable) => void, ski...
method addEffect (line 116) | addEffect(effect: any): void {
method dispose (line 120) | dispose(): void {
method createRenderable (line 134) | createRenderable(gameObject: GameObject, container: any): Renderable {
method updateLighting (line 142) | updateLighting(): void {
FILE: src/engine/ResourceCollection.ts
class ResourceCollection (line 1) | class ResourceCollection {
method constructor (line 2) | constructor() {
FILE: src/engine/ResourceLoader.ts
type FetchResourceOptions (line 4) | interface FetchResourceOptions {
type LoadResourceItem (line 7) | interface LoadResourceItem {
class LoaderResult (line 13) | class LoaderResult {
method constructor (line 15) | constructor(items: Map<ResourceId, ArrayBuffer | string | any>) {
method pop (line 18) | pop(resourceIdentifier: ResourceType | ResourceId): ArrayBuffer | stri...
class ResourceLoader (line 41) | class ResourceLoader {
method constructor (line 44) | constructor(resourceBaseUrl: string) {
method prefetchResource (line 48) | async prefetchResource(resourceType: ResourceType, cancellationToken?:...
method getResourceUrl (line 91) | getResourceUrl(resourceTypeOrConfig: ResourceType | ResourceConfig): s...
method getResourceFileName (line 98) | getResourceFileName(resourceType: ResourceType): string {
method buildResourceManifest (line 103) | buildResourceManifest(resources: (ResourceType | ResourceConfig)[]): L...
method loadText (line 123) | async loadText(srcRelative: string, cancellationToken?: CancellationTo...
method loadBinary (line 126) | async loadBinary(srcRelative: string, cancellationToken?: Cancellation...
method loadJson (line 129) | async loadJson(srcRelative: string, cancellationToken?: CancellationTo...
method loadResource (line 132) | private async loadResource(item: LoadResourceItem, cancellationToken?:...
method loadResources (line 137) | async loadResources(resourceTypes: (ResourceType | ResourceConfig)[], ...
method fetchResource (line 168) | protected async fetchResource(url: string, cancellationToken?: Cancell...
FILE: src/engine/Theater.ts
class Theater (line 9) | class Theater {
method factory (line 19) | static factory(type: TheaterType, theaterIni: IniFile, settings: Theat...
method constructor (line 44) | constructor(type: TheaterType, settings: TheaterSettings, palettes: La...
method getPalette (line 55) | getPalette(type: PaletteType, customPaletteName?: string): Palette {
FILE: src/engine/TheaterType.ts
type TheaterSettings (line 1) | interface TheaterSettings {
type TheaterType (line 11) | enum TheaterType {
FILE: src/engine/UiAnimationLoop.ts
class UiAnimationLoop (line 3) | class UiAnimationLoop {
method constructor (line 9) | constructor(renderer: Renderer) {
method start (line 55) | start(): void {
method stop (line 68) | stop(): void {
method destroy (line 82) | destroy(): void {
FILE: src/engine/animation/Runner.ts
class Runner (line 1) | class Runner {
method constructor (line 2) | constructor() {
FILE: src/engine/animation/SimpleRunner.ts
class SimpleRunner (line 2) | class SimpleRunner {
method constructor (line 4) | constructor() { }
method tick (line 5) | tick(time: number): void {
method getCurrentFrame (line 22) | getCurrentFrame(): number {
method shouldUpdate (line 25) | shouldUpdate(): boolean {
method setAnimation (line 28) | setAnimation(animation: Animation): void {
method start (line 31) | start(time: number, delayFrames?: number): void {
method stop (line 36) | stop(): void {
method update (line 41) | update(time: number): void {
method isStopped (line 46) | isStopped(): boolean {
method getState (line 49) | getState(): AnimationState | undefined {
FILE: src/engine/gameRes/CdnManifest.ts
type CdnManifest (line 1) | interface CdnManifest {
FILE: src/engine/gameRes/CdnResourceLoader.ts
type CdnManifest (line 9) | interface CdnManifest {
type CdnFetchOptions (line 16) | interface CdnFetchOptions {
class CdnResourceLoader (line 19) | class CdnResourceLoader extends ResourceLoader {
method clearCache (line 24) | static async clearCache(cacheDir: RealFileSystemDir): Promise<void> {
method constructor (line 36) | constructor(baseUrl: string, manifest: CdnManifest, cacheDirHandle?: F...
method getFileNameFromUrl (line 44) | private getFileNameFromUrl(url: string): string {
method fetchResource (line 48) | protected async fetchResource(url: string, cancellationToken?: Cancell...
FILE: src/engine/gameRes/FileSystemAccessLib.ts
type FileSystemAccessAdapterSupport (line 1) | interface FileSystemAccessAdapterSupport {
type FileSystemAccessAdapters (line 6) | interface FileSystemAccessAdapters {
type FileSystemAccessLib (line 11) | interface FileSystemAccessLib {
FILE: src/engine/gameRes/FileSystemUtil.ts
class FileSystemUtil (line 3) | class FileSystemUtil {
method getDirContents (line 4) | static async getDirContents(directoryHandle: FileSystemDirectoryHandle...
method listDir (line 26) | static async listDir(directoryHandle: FileSystemDirectoryHandle): Prom...
method showArchivePicker (line 48) | static async showArchivePicker(fsAccessLib?: any): Promise<FileSystemF...
method polyfillGetFile (line 89) | static polyfillGetFile(): void {
FILE: src/engine/gameRes/GameRes.ts
type FsAccessLibrary (line 36) | interface FsAccessLibrary {
type InitResult (line 50) | interface InitResult {
type LoadProgressCallback (line 54) | type LoadProgressCallback = (loadingText?: string, backgroundImage?: str...
type FatalErrorCallback (line 55) | type FatalErrorCallback = (error: Error, strings: Strings) => Promise<vo...
type ImportErrorCallback (line 56) | type ImportErrorCallback = (error: Error, strings: Strings) => Promise<v...
class GameRes (line 57) | class GameRes {
method constructor (line 69) | constructor(appVersion: string, modName: string | undefined, fsAccessL...
method init (line 82) | async init(persistedConfig: GameResConfig | undefined, onFatalError: F...
method loadMod (line 299) | private async loadMod(rfs: RealFileSystem, modDirHandle: FileSystemDir...
method lookForGameFiles (line 318) | private async lookForGameFiles(rfsDir: RealFileSystemDir): Promise<boo...
method migrateStorageToNative (line 326) | private async migrateStorageToNative(nativeFsHandle: FileSystemDirecto...
method migrateDir (line 413) | private async migrateDir(sourceDirHandleWrapper: RealFileSystemDir, ta...
method loadResources (line 430) | private async loadResources(rfs: RealFileSystem | undefined, config: G...
method checkMixesIntegrity (line 478) | private async checkMixesIntegrity(rfsDir: RealFileSystemDir): Promise<...
method loadCustomMix (line 508) | private async loadCustomMix(vfs: VirtualFileSystem): Promise<void> {
method loadMixes (line 514) | private async loadMixes(config: GameResConfig, cdnLoader: CdnResourceL...
method initUiCssVariables (line 556) | private async initUiCssVariables(rootElement: HTMLElement): Promise<vo...
method loadSplashScreenBackground (line 616) | private async loadSplashScreenBackground(rfsDir: RealFileSystemDir | u...
method getBrowserFsHandle (line 643) | private async getBrowserFsHandle(preference: "native" | "fallback"): P...
method convertImagesToPng (line 705) | private async convertImagesToPng(vfs: VirtualFileSystem, imageDefs: [
method generateIconSprite (line 742) | private async generateIconSprite(vfs: VirtualFileSystem): Promise<Blob...
FILE: src/engine/gameRes/GameResConfig.ts
class GameResConfig (line 2) | class GameResConfig {
method constructor (line 6) | constructor(defaultCdnBaseUrl: string) {
method unserialize (line 9) | unserialize(serializedConfig: string): void {
method serialize (line 18) | serialize(): string {
method isCdn (line 28) | isCdn(): boolean {
method getCdnBaseUrl (line 31) | getCdnBaseUrl(): string | undefined {
FILE: src/engine/gameRes/GameResImporter.ts
type SevenZipWasmModule (line 25) | interface SevenZipWasmModule {
type SevenZipWasmOptions (line 29) | interface SevenZipWasmOptions {
constant REQUIRED_MIX_SIZES (line 33) | const REQUIRED_MIX_SIZES = new Map<string, number>()
function formatBytes (line 38) | function formatBytes(bytes: number): string {
function wrapFsOpen (line 41) | function wrapFsOpen(originalFsOpen: any, prefilledContents: Map<string, ...
type ImportProgressCallback (line 63) | type ImportProgressCallback = (text?: string, backgroundImage?: Blob | s...
type ImportSource (line 64) | type ImportSource = URL | File | FileSystemDirectoryHandle | FileSystemF...
class GameResImporter (line 65) | class GameResImporter {
method constructor (line 69) | constructor(appConfig: Config, strings: Strings, sentry?: any) {
method import (line 74) | async import(source: ImportSource | undefined, targetRfsRootDir: RealF...
method readFileFromEmFs (line 324) | private readFileFromEmFs(emFs: any, filePath: string): VirtualFile {
method importMixArchive (line 334) | private async importMixArchive(mixVirtualFile: VirtualFile, targetRfsR...
method importMusic (line 362) | private async importMusic(mixVirtualFile: VirtualFile, targetMusicDir:...
method importVideo (line 424) | private async importVideo(languageMixVirtualFile: VirtualFile, targetR...
method createFFmpeg (line 491) | private async createFFmpeg(): Promise<FFmpeg> {
method importSplashImage (line 509) | private async importSplashImage(ra2MixVirtualFile: VirtualFile, target...
FILE: src/engine/gameRes/GameResSource.ts
type GameResSource (line 1) | enum GameResSource {
FILE: src/engine/gameRes/VideoConverter.ts
class VideoConverter (line 4) | class VideoConverter {
method convertBinkVideo (line 5) | async convertBinkVideo(ffmpeg: FFmpeg, binkFile: VirtualFile, outputFo...
FILE: src/engine/gameRes/browserFileSystemAccess.ts
method polyfillDataTransferItem (line 20) | async polyfillDataTransferItem() {
FILE: src/engine/gameRes/importError/ArchiveDownloadError.ts
class ArchiveDownloadError (line 1) | class ArchiveDownloadError extends Error {
method constructor (line 4) | constructor(url: string, message: string, options?: {
FILE: src/engine/gameRes/importError/ArchiveExtractionError.ts
class ArchiveExtractionError (line 1) | class ArchiveExtractionError extends Error {
method constructor (line 2) | constructor(message: string, options?: ErrorOptions) {
FILE: src/engine/gameRes/importError/ChecksumError.ts
class ChecksumError (line 1) | class ChecksumError extends Error {
method constructor (line 5) | constructor(message: string, fileName?: string, expectedChecksum?: str...
FILE: src/engine/gameRes/importError/FileNotFoundError.ts
class FileNotFoundError (line 1) | class FileNotFoundError extends Error {
method constructor (line 3) | constructor(messageOrFileName: string, fileName?: string) {
FILE: src/engine/gameRes/importError/InvalidArchiveError.ts
class InvalidArchiveError (line 1) | class InvalidArchiveError extends Error {
method constructor (line 3) | constructor(message: string, options?: {
FILE: src/engine/gameRes/importError/NoStorageError.ts
class NoStorageError (line 1) | class NoStorageError extends Error {
method constructor (line 2) | constructor(message: string = "No available or functional storage adap...
FILE: src/engine/gameRes/importError/NoWebAssemblyError.ts
class NoWebAssemblyError (line 1) | class NoWebAssemblyError extends Error {
method constructor (line 3) | constructor(message: string, options?: {
FILE: src/engine/gfx/BufferGeometryUtils.ts
class BufferGeometryUtils (line 2) | class BufferGeometryUtils {
method mergeVertices (line 3) | static mergeVertices(geometry: THREE.BufferGeometry, tolerance: number...
method mergeBufferGeometries (line 93) | static mergeBufferGeometries(geometries: THREE.BufferGeometry[], useGr...
method mergeBufferAttributes (line 165) | static mergeBufferAttributes(attributes: THREE.BufferAttribute[]): THR...
FILE: src/engine/gfx/Camera.ts
class Camera (line 1) | class Camera {
FILE: src/engine/gfx/CanvasUtils.ts
type DrawTextOptions (line 2) | interface DrawTextOptions {
type TextRect (line 21) | interface TextRect {
class CanvasUtils (line 27) | class CanvasUtils {
method canvasFromRgbaImageData (line 28) | static canvasFromRgbaImageData(data: Uint8Array, width: number, height...
method canvasFromRgbImageData (line 48) | static canvasFromRgbImageData(data: Uint8Array, width: number, height:...
method canvasFromIndexedImageData (line 68) | static canvasFromIndexedImageData(data: Uint8Array, width: number, hei...
method canvasToBlob (line 91) | static async canvasToBlob(canvas: HTMLCanvasElement, mimeType: string ...
method dataUrlToBlob (line 114) | static dataUrlToBlob(dataUrl: string): Blob {
method drawText (line 129) | static drawText(ctx: CanvasRenderingContext2D, text: string, x: number...
FILE: src/engine/gfx/DebugUtils.ts
class DebugUtils (line 4) | class DebugUtils {
method createWireframe (line 5) | static createWireframe(size: {
method createBoxGeometry (line 11) | static createBoxGeometry(size: {
method createIndexedCheckerTex (line 28) | static createIndexedCheckerTex(color1: number, color2: number): THREE....
FILE: src/engine/gfx/FrustumCuller.ts
class FrustumCuller (line 3) | class FrustumCuller {
method cull (line 4) | cull<T extends THREE.Mesh = THREE.Mesh>(octree: Octree<T>, frustum: TH...
FILE: src/engine/gfx/GrowingPacker.ts
type GrowingPackerBlock (line 1) | interface GrowingPackerBlock {
type GrowingPackerNode (line 6) | interface GrowingPackerNode {
class GrowingPacker (line 15) | class GrowingPacker {
method fit (line 17) | fit(blocks: GrowingPackerBlock[]): void {
method findNode (line 26) | private findNode(root: GrowingPackerNode | undefined, width: number, h...
method splitNode (line 38) | private splitNode(node: GrowingPackerNode, width: number, height: numb...
method growNode (line 44) | private growNode(width: number, height: number): GrowingPackerNode | u...
method growRight (line 63) | private growRight(width: number, height: number): GrowingPackerNode | ...
method growDown (line 76) | private growDown(width: number, height: number): GrowingPackerNode | u...
FILE: src/engine/gfx/ImageUtils.ts
class ImageUtils (line 5) | class ImageUtils {
method convertShpToPng (line 6) | static async convertShpToPng(shpFile: ShpFile, palette: Palette): Prom...
method convertShpToBitmap (line 10) | static convertShpToBitmap(shpFile: ShpFile, palette: Palette, forceSqu...
method convertShpToCanvas (line 28) | static convertShpToCanvas(shpFile: ShpFile, palette: Palette, forceSqu...
FILE: src/engine/gfx/MathUtils.ts
class MathUtils (line 2) | class MathUtils {
method rotateObjectAboutPoint (line 3) | static rotateObjectAboutPoint(object: THREE.Object3D, point: THREE.Vec...
method translateTowardsCamera (line 15) | static translateTowardsCamera(object: THREE.Object3D, camera: THREE.Ca...
FILE: src/engine/gfx/OctreeContainer.ts
constant CAMERA_PADDING (line 6) | const CAMERA_PADDING = 3;
class OctreeContainer (line 8) | class OctreeContainer extends RenderableContainer {
method factory (line 14) | static factory(camera: THREE.Camera): OctreeContainer {
method constructor (line 26) | constructor(tree: Octree, frustumCuller: FrustumCuller, camera: THREE....
method update (line 36) | update(deltaTime: number): void {
method cullChildren (line 42) | cullChildren(): void {
method computeProjectionMatrix (line 54) | computeProjectionMatrix(): THREE.Matrix4 {
method updateChild (line 71) | updateChild(child: any): void {
FILE: src/engine/gfx/OverlayUtils.ts
class OverlayUtils (line 3) | class OverlayUtils {
method createGroundCircle (line 4) | static createGroundCircle(radius: number, color: THREE.ColorRepresenta...
method createTextBox (line 23) | static createTextBox(text: string, options: any): HTMLCanvasElement {
FILE: src/engine/gfx/Renderable.ts
class Renderable (line 1) | class Renderable {
method constructor (line 3) | constructor() {
FILE: src/engine/gfx/RenderableContainer.ts
type Renderable (line 2) | interface Renderable {
class RenderableContainer (line 8) | class RenderableContainer {
method constructor (line 12) | constructor(container?: THREE.Object3D) {
method set3DObject (line 17) | set3DObject(container: THREE.Object3D): void {
method get3DObject (line 20) | get3DObject(): THREE.Object3D | undefined {
method getChildren (line 23) | getChildren(): Renderable[] {
method add (line 26) | add(...objects: Renderable[]): void {
method remove (line 34) | remove(...objects: Renderable[]): void {
method removeAll (line 51) | removeAll(): void {
method processRenderQueue (line 54) | processRenderQueue(): void {
method create3DObject (line 67) | create3DObject(): void {
method update (line 70) | update(deltaTime: number, ...args: any[]): void {
FILE: src/engine/gfx/Renderer.ts
class Renderer (line 5) | class Renderer {
method constructor (line 13) | constructor(width: number, height: number) {
method onFrame (line 17) | get onFrame() {
method getCanvas (line 20) | getCanvas(): HTMLCanvasElement {
method getStats (line 23) | getStats(): Stats | undefined {
method supportsInstancing (line 26) | supportsInstancing(): boolean {
method initStats (line 32) | initStats(container: HTMLElement): void {
method destroyStats (line 42) | destroyStats(): void {
method init (line 50) | init(container: HTMLElement): void {
method createGlRenderer (line 66) | createGlRenderer(canvas?: HTMLCanvasElement): THREE.WebGLRenderer {
method setSize (line 87) | setSize(width: number, height: number): void {
method addScene (line 94) | addScene(scene: any): void {
method removeScene (line 98) | removeScene(scene: any): void {
method getScenes (line 101) | getScenes(): any[] {
method update (line 104) | update(deltaTime: number, ...args: any[]): void {
method render (line 110) | render(): void {
method flush (line 121) | flush(): void {
method dispose (line 124) | dispose(): void {
FILE: src/engine/gfx/RendererError.ts
class RendererError (line 1) | class RendererError extends Error {
method constructor (line 2) | constructor(message?: string) {
FILE: src/engine/gfx/Scene.ts
class Scene (line 1) | class Scene {
method constructor (line 2) | constructor() {
FILE: src/engine/gfx/SpriteUtils.ts
type TextureArea (line 4) | interface TextureArea {
type Offset (line 10) | interface Offset {
type Align (line 14) | interface Align {
type ImageSize (line 18) | interface ImageSize {
type SpriteGeometryOptions (line 22) | interface SpriteGeometryOptions {
class SpriteUtilsClass (line 33) | class SpriteUtilsClass {
method constructor (line 38) | constructor() {
method createSpriteGeometry (line 43) | createSpriteGeometry(options: SpriteGeometryOptions): THREE.BufferGeom...
method createRectGeometry (line 102) | createRectGeometry(width: number, height: number): THREE.BufferGeometry {
method createNonIndexedRectGeometry (line 107) | createNonIndexedRectGeometry(width: number, height: number): THREE.Buf...
method createIndexedRectGeometry (line 120) | createIndexedRectGeometry(width: number, height: number): THREE.Buffer...
method addRectUvs (line 133) | addRectUvs(geometry: THREE.BufferGeometry, textureArea: TextureArea, i...
method writeNonIndexedRectUvsIntoBuffer (line 143) | writeNonIndexedRectUvsIntoBuffer(buffer: Float32Array, offset: number,...
method writeIndexedRectUvsIntoBuffer (line 150) | writeIndexedRectUvsIntoBuffer(buffer: Float32Array, offset: number, te...
method applyDepth (line 157) | applyDepth(geometry: THREE.BufferGeometry, camera: THREE.Camera, depth...
method applyFlatDepth (line 171) | applyFlatDepth(geometry: THREE.BufferGeometry, depthOffset: number): v...
constant VERTICES_PER_SPRITE (line 180) | const VERTICES_PER_SPRITE: number = spriteUtilsInstance.VERTICES_PER_SPR...
constant TRIANGLES_PER_SPRITE (line 181) | const TRIANGLES_PER_SPRITE: number = spriteUtilsInstance.TRIANGLES_PER_S...
constant MAGIC_DEPTH_SCALE (line 182) | const MAGIC_DEPTH_SCALE: number = SpriteUtilsClass.MAGIC_DEPTH_SCALE;
FILE: src/engine/gfx/TextureAtlas.ts
function createAtlasBitmap (line 4) | function createAtlasBitmap(blocks: any[], width: number, height: number,...
function createAtlasRgbaData (line 18) | function createAtlasRgbaData(bitmap: IndexedBitmap): Uint8Array {
class TextureAtlas (line 30) | class TextureAtlas {
method getTexture (line 35) | getTexture(): THREE.DataTexture {
method getImageRect (line 41) | getImageRect(image: IndexedBitmap): any {
method pack (line 51) | pack(images: IndexedBitmap[]): void {
method dispose (line 79) | dispose(): void {
FILE: src/engine/gfx/TextureUtils.ts
class TextureUtilsClass (line 7) | class TextureUtilsClass {
method textureFromPalette (line 9) | static textureFromPalette(palette: Palette): THREE.Texture {
method textureFromPalettes (line 20) | static textureFromPalettes(palettes: Palette[]): THREE.Texture {
method textureFromPalBitmap (line 39) | static textureFromPalBitmap(bitmap: RgbaBitmap): THREE.Texture {
FILE: src/engine/gfx/batch/BatchedMesh.ts
type BatchMode (line 2) | enum BatchMode {
class BatchedMesh (line 6) | class BatchedMesh extends THREE.Mesh {
method constructor (line 14) | constructor(geometry: THREE.BufferGeometry, material: THREE.Material, ...
method getOpacity (line 23) | getOpacity(): number {
method setOpacity (line 26) | setOpacity(opacity: number): void {
method getExtraLight (line 29) | getExtraLight(): THREE.Vector3 {
method setExtraLight (line 32) | setExtraLight(extraLight: THREE.Vector3): void {
method getPaletteIndex (line 35) | getPaletteIndex(): number {
method setPaletteIndex (line 38) | setPaletteIndex(paletteIndex: number): void {
method getClippingPlanes (line 41) | getClippingPlanes(): THREE.Plane[] {
method setClippingPlanes (line 44) | setClippingPlanes(clippingPlanes: THREE.Plane[]): void {
method updateClippingPlanesHash (line 48) | private updateClippingPlanesHash(clippingPlanes: THREE.Plane[]): void {
method getClippingPlanesHash (line 54) | getClippingPlanesHash(): string {
FILE: src/engine/gfx/batch/InstancedMesh.ts
class InstancedMesh (line 16) | class InstancedMesh extends THREE.Mesh {
method constructor (line 21) | constructor(geometry: THREE.BufferGeometry, material: THREE.Material, ...
method initAttributes (line 34) | private initAttributes(geometry: THREE.InstancedBufferGeometry): void {
method decorateMaterial (line 72) | private decorateMaterial(material: THREE.Material): THREE.Material {
method setRenderCount (line 93) | public setRenderCount(count: number): void {
method setMatrixAt (line 99) | public setMatrixAt(index: number, matrix: THREE.Matrix4): void {
method updateFromMeshes (line 105) | public updateFromMeshes(meshes: any[]): void {
method dispose (line 142) | public dispose(): void {
FILE: src/engine/gfx/batch/MergedSpriteMesh.ts
class MergedSpriteMesh (line 6) | class MergedSpriteMesh extends THREE.Mesh {
method createMergedGeometry (line 10) | static createMergedGeometry(sourceGeometry: THREE.BufferGeometry, maxI...
method constructor (line 39) | constructor(sourceGeometry: THREE.BufferGeometry, material: THREE.Mate...
method decorateMaterial (line 47) | private decorateMaterial(material: THREE.Material): THREE.Material {
method updateFromMeshes (line 60) | public updateFromMeshes(meshes: any[]): void {
method setGeometryAt (line 95) | private setGeometryAt(vertexOffset: number, sourceGeometry: THREE.Buff...
method setColorMultAt (line 122) | private setColorMultAt(vertexOffset: number, colorMult: THREE.Vector4,...
method setPaletteIndexAt (line 133) | private setPaletteIndexAt(vertexOffset: number, paletteIndex: number, ...
method dispose (line 141) | public dispose(): void {
FILE: src/engine/gfx/batch/MeshBatchManager.ts
type MeshBatch (line 6) | interface MeshBatch {
class MeshBatchManager (line 14) | class MeshBatchManager extends RenderableContainer {
method constructor (line 17) | constructor(renderableContainer: RenderableContainer) {
method create3DObject (line 21) | create3DObject(): void {
method updateMeshes (line 31) | updateMeshes(): void {
method collectMeshes (line 40) | private collectMeshes(container: THREE.Object3D): BatchedMesh[] {
method fillBatches (line 49) | private fillBatches(groupedMeshes: Map<string, BatchedMesh[]>): Map<st...
method cleanUnusedBatches (line 80) | private cleanUnusedBatches(usedBatchCounts: Map<string, number>): void {
method groupMeshesByBatchKey (line 95) | private groupMeshesByBatchKey(meshes: BatchedMesh[]): Map<string, Batc...
method getBatchKey (line 109) | private getBatchKey(mesh: BatchedMesh): string {
method dispose (line 127) | dispose(): void {
FILE: src/engine/gfx/batch/MeshInstancingBatch.ts
class MeshInstancingBatch (line 3) | class MeshInstancingBatch {
method constructor (line 11) | constructor(maxInstances: number) {
method castShadow (line 14) | get castShadow(): boolean {
method castShadow (line 17) | set castShadow(value: boolean) {
method receiveShadow (line 23) | get receiveShadow(): boolean {
method receiveShadow (line 26) | set receiveShadow(value: boolean) {
method clippingPlanes (line 32) | get clippingPlanes(): THREE.Plane[] {
method clippingPlanes (line 35) | set clippingPlanes(value: THREE.Plane[]) {
method renderOrder (line 41) | get renderOrder(): number {
method renderOrder (line 44) | set renderOrder(value: number) {
method get3DObject (line 50) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 53) | create3DObject(): void {
method setMeshes (line 63) | setMeshes(meshes: any[]): void {
method update (line 95) | update(): void {
method dispose (line 97) | dispose(): void {
FILE: src/engine/gfx/batch/MeshMergingBatch.ts
class MeshMergingBatch (line 3) | class MeshMergingBatch {
method constructor (line 11) | constructor(maxInstances: number) {
method castShadow (line 14) | get castShadow(): boolean {
method castShadow (line 17) | set castShadow(value: boolean) {
method receiveShadow (line 23) | get receiveShadow(): boolean {
method receiveShadow (line 26) | set receiveShadow(value: boolean) {
method clippingPlanes (line 32) | get clippingPlanes(): THREE.Plane[] {
method clippingPlanes (line 35) | set clippingPlanes(value: THREE.Plane[]) {
method renderOrder (line 41) | get renderOrder(): number {
method renderOrder (line 44) | set renderOrder(value: number) {
method get3DObject (line 50) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 53) | create3DObject(): void {
method setMeshes (line 63) | setMeshes(meshes: any[]): void {
method update (line 90) | update(): void {
method dispose (line 92) | dispose(): void {
FILE: src/engine/gfx/drawable/PalDrawable.ts
class PalDrawable (line 3) | class PalDrawable {
method constructor (line 5) | constructor(palette: Palette) {
method draw (line 8) | draw(): RgbaBitmap {
FILE: src/engine/gfx/drawable/TmpDrawable.ts
type TileData (line 2) | interface TileData {
class TmpDrawable (line 13) | class TmpDrawable {
method drawTileBlock (line 14) | drawTileBlock(tile: TileData, bitmap: IndexedBitmap, width: number, he...
method draw (line 48) | draw(tile: TileData, width: number, height: number): IndexedBitmap {
method drawExtraData (line 66) | drawExtraData(tile: TileData, bitmap: IndexedBitmap): void {
FILE: src/engine/gfx/geometry/BufferGeometrySerializer.ts
class BufferGeometrySerializer (line 3) | class BufferGeometrySerializer {
method serialize (line 4) | serialize(geometry: THREE.BufferGeometry): ArrayBuffer {
method unserialize (line 37) | unserialize(stream: DataStream): THREE.BufferGeometry {
method writeTypedArray (line 54) | writeTypedArray(stream: DataStream, array: ArrayLike<number> & {
method readTypedArray (line 80) | readTypedArray(stream: DataStream): Float32Array | Uint32Array | Uint1...
method getTypedArrayByteSize (line 94) | getTypedArrayByteSize(array: ArrayLike<number> & {
FILE: src/engine/gfx/geometry/VxlGeometryCache.ts
type VirtualFileSystem (line 6) | interface VirtualFileSystem {
type VxlFile (line 14) | interface VxlFile {
class VxlGeometryCache (line 17) | class VxlGeometryCache {
method constructor (line 22) | constructor(cacheDir: VirtualFileSystem | null, activeMod: string | nu...
method loadFromStorage (line 27) | async loadFromStorage(vxlFile: VxlFile, filename: string): Promise<THR...
method persistToStorage (line 47) | async persistToStorage(vxlFile: VxlFile, filename: string, data: Array...
method clearStorage (line 53) | async clearStorage(): Promise<void> {
method clearOtherModStorage (line 56) | async clearOtherModStorage(): Promise<void> {
method clearStorageFiles (line 60) | async clearStorageFiles(filter: (filename: string) => boolean = () => ...
method getCacheFileName (line 70) | getCacheFileName(filename: string, vxlName: string): string {
method getModPrefix (line 74) | getModPrefix(): string {
method clear (line 77) | clear(): void {
method get (line 86) | get(vxlFile: VxlFile): THREE.BufferGeometry | undefined {
method set (line 89) | set(vxlFile: VxlFile, geometry: THREE.BufferGeometry): void {
FILE: src/engine/gfx/lighting/LightingDirector.ts
class LightingDirector (line 4) | class LightingDirector {
method constructor (line 17) | constructor(lighting: Lighting, renderer: {
method init (line 60) | init(): void {
method addEffect (line 63) | addEffect(effect: LightingFx): void {
method dispose (line 67) | dispose(): void {
FILE: src/engine/gfx/lighting/LightingFx.ts
type LightingFxPriority (line 2) | enum LightingFxPriority {
class LightingFx (line 6) | class LightingFx {
method constructor (line 11) | constructor() {
method update (line 16) | update(time: number, gameSpeed: number): {
FILE: src/engine/gfx/lighting/LightningStormFx.ts
class LightningStormFx (line 2) | class LightningStormFx extends LightingFx {
method constructor (line 6) | constructor(durationGameSeconds: number, ionLighting: any) {
method waitForCloudAnim (line 12) | waitForCloudAnim(anim: any): void {
method update (line 15) | update(time: number, gameSpeed: number): {
FILE: src/engine/gfx/lighting/NukeLightingFx.ts
class NukeLightingFx (line 2) | class NukeLightingFx extends LightingFx {
method constructor (line 4) | constructor() {
method update (line 8) | update(time: number, gameSpeed: number): {
FILE: src/engine/gfx/material/PaletteBasicMaterial.ts
class PaletteBasicMaterial (line 34) | class PaletteBasicMaterial extends THREE.MeshBasicMaterial {
method palette (line 38) | get palette() {
method palette (line 41) | set palette(value) {
method paletteOffset (line 44) | get paletteOffset() {
method paletteOffset (line 47) | set paletteOffset(value) {
method paletteCount (line 50) | get paletteCount() {
method paletteCount (line 53) | set paletteCount(value) {
method extraLight (line 56) | get extraLight() {
method extraLight (line 59) | set extraLight(value) {
method useVertexColorMult (line 62) | set useVertexColorMult(value) {
method constructor (line 71) | constructor({ palette, paletteCount, paletteOffset, extraLight, useVer...
method copy (line 118) | copy(source) {
FILE: src/engine/gfx/material/PaletteLambertMaterial.ts
class PaletteLambertMaterial (line 16) | class PaletteLambertMaterial extends THREE.MeshLambertMaterial {
method palette (line 20) | get palette() {
method palette (line 23) | set palette(value) {
method paletteOffset (line 26) | get paletteOffset() {
method paletteOffset (line 29) | set paletteOffset(value) {
method paletteCount (line 32) | get paletteCount() {
method paletteCount (line 35) | set paletteCount(value) {
method extraLight (line 38) | get extraLight() {
method extraLight (line 41) | set extraLight(value) {
method constructor (line 44) | constructor({ palette, paletteCount, paletteOffset, extraLight, ...opt...
method copy (line 59) | copy(source: PaletteLambertMaterial): this {
FILE: src/engine/gfx/material/PalettePhongMaterial.ts
type PalettePhongMaterialParameters (line 3) | interface PalettePhongMaterialParameters extends THREE.MeshPhongMaterial...
type ShaderMaterial (line 9) | interface ShaderMaterial {
class PalettePhongMaterial (line 29) | class PalettePhongMaterial extends THREE.MeshPhongMaterial {
method constructor (line 35) | constructor(parameters: PalettePhongMaterialParameters = {}) {
method palette (line 55) | get palette(): THREE.Texture {
method palette (line 58) | set palette(value: THREE.Texture) {
method paletteOffset (line 61) | get paletteOffset(): number {
method paletteOffset (line 64) | set paletteOffset(value: number) {
method paletteCount (line 67) | get paletteCount(): number {
method paletteCount (line 70) | set paletteCount(value: number) {
method extraLight (line 73) | get extraLight(): THREE.Vector3 {
method extraLight (line 76) | set extraLight(value: THREE.Vector3) {
method copy (line 79) | copy(source: PalettePhongMaterial): this {
FILE: src/engine/renderable/AlphaRenderable.ts
class AlphaRenderable (line 6) | class AlphaRenderable {
method getOrCreateAlphaPalette (line 15) | static getOrCreateAlphaPalette(): Palette {
method constructor (line 29) | constructor(shpFile: any, camera: THREE.Camera, drawOffset: any) {
method setVisible (line 35) | setVisible(visible: boolean): void {
method setSize (line 41) | setSize(size: number): void {
method create3DObject (line 45) | create3DObject(): void {
method get3DObject (line 69) | get3DObject(): THREE.Object3D | undefined {
method update (line 72) | update(delta: number): void { }
method dispose (line 73) | dispose(): void {
FILE: src/engine/renderable/CameraPan.ts
class CameraPan (line 3) | class CameraPan {
method constructor (line 15) | constructor(freeCamera: BoxedVar<boolean>) {
method setPanLimits (line 19) | setPanLimits(limits: {
method getPanLimits (line 28) | getPanLimits(): {
method getPan (line 36) | getPan(): {
method setPan (line 42) | setPan(pan: {
FILE: src/engine/renderable/CameraZoom.ts
class CameraZoom (line 2) | class CameraZoom {
method constructor (line 5) | constructor(freeCamera: BoxedVar<boolean>) {
method getZoom (line 9) | getZoom(): number {
method applyStep (line 12) | applyStep(step: number): void {
FILE: src/engine/renderable/DebugRenderable.ts
type Foundation (line 7) | interface Foundation {
type DebugRenderableOptions (line 11) | interface DebugRenderableOptions {
type MaterialCacheEntry (line 14) | interface MaterialCacheEntry {
class DebugRenderable (line 18) | class DebugRenderable {
method getOrCreateTexture (line 31) | static getOrCreateTexture(): Texture {
method clearCaches (line 39) | static clearCaches(): void {
method constructor (line 44) | constructor(foundation: Foundation, height: number, palette: Palette, ...
method useMaterial (line 50) | private useMaterial(paletteTexture: Texture): PaletteBasicMaterial {
method freeMaterial (line 72) | private freeMaterial(): void {
method getGeometryCacheKey (line 87) | private getGeometryCacheKey(): string {
method setBatched (line 90) | setBatched(useBatching: boolean): void {
method getBatchPaletteIndex (line 96) | private getBatchPaletteIndex(palette: Palette): number {
method setPalette (line 103) | setPalette(palette: Palette): void {
method setBatchPalettes (line 117) | setBatchPalettes(palettes: Palette[]): void {
method setOpacity (line 126) | setOpacity(opacity: number): void {
method updateOpacity (line 132) | private updateOpacity(): void {
method create3DObject (line 142) | create3DObject(): void {
method get3DObject (line 175) | get3DObject(): Mesh | BatchedMesh | undefined {
method update (line 178) | update(deltaTime: number): void {
method dispose (line 180) | dispose(): void {
FILE: src/engine/renderable/Entity.ts
class Entity (line 4) | class Entity {
method constructor (line 8) | constructor() {
method get3DObject (line 14) | get3DObject(): THREE.Object3D | undefined {
method set3DObject (line 17) | set3DObject(object: THREE.Object3D): void {
method setPosition (line 22) | setPosition(x: number, y: number, z: number): void {
method getPosition (line 25) | getPosition(): THREE.Vector3 {
method setVisible (line 28) | setVisible(visible: boolean): void {
method isVisible (line 31) | isVisible(): boolean {
FILE: src/engine/renderable/MapSpriteTranslation.ts
class MapSpriteTranslation (line 4) | class MapSpriteTranslation {
method constructor (line 7) | constructor(rx: number, ry: number) {
method compute (line 11) | compute(): {
FILE: src/engine/renderable/RenderablePlugin.ts
class RenderablePlugin (line 1) | class RenderablePlugin {
method constructor (line 2) | constructor() {
FILE: src/engine/renderable/ShadowRenderable.ts
class ShadowRenderable (line 7) | class ShadowRenderable {
method getOrCreateShadowPalette (line 23) | static getOrCreateShadowPalette(): Palette {
method constructor (line 31) | constructor(shpFile: any, camera: any, drawOffset: {
method setVisible (line 44) | setVisible(visible: boolean): void {
method setSize (line 51) | setSize(size: number): void {
method setBatched (line 55) | setBatched(batched: boolean): void {
method setBaseFrame (line 59) | setBaseFrame(frameNo: number): void {
method setFrameOffset (line 67) | setFrameOffset(offset: number): void {
method computeShadowFrameNo (line 71) | computeShadowFrameNo(frameNo: number): number {
method create3DObject (line 74) | create3DObject(): void {
method frameHasShadowData (line 107) | frameHasShadowData(frameNo: number): boolean {
method get3DObject (line 110) | get3DObject(): THREE.Object3D | undefined {
method update (line 113) | update(delta: number): void { }
method dispose (line 114) | dispose(): void {
FILE: src/engine/renderable/ShpRenderable.ts
class ShpRenderable (line 5) | class ShpRenderable {
method factory (line 12) | static factory(shpFile: any, palette: any, camera: any, drawOffset: {
method constructor (line 30) | constructor(builder: ShpBuilder, shadowRenderable?: ShadowRenderable, ...
method get3DObject (line 35) | get3DObject(): THREE.Object3D | undefined {
method setBatched (line 38) | setBatched(batched: boolean): void {
method setBatchPalettes (line 43) | setBatchPalettes(palettes: any[]): void {
method setSize (line 47) | setSize(size: number): void {
method getFlat (line 52) | getFlat(): boolean {
method setFlat (line 55) | setFlat(flat: boolean): void {
method setFrame (line 58) | setFrame(frame: number): void {
method setFrameOffset (line 65) | setFrameOffset(offset: number): void {
method setPalette (line 70) | setPalette(palette: any): void {
method setExtraLight (line 74) | setExtraLight(light: any): void {
method setOpacity (line 78) | setOpacity(opacity: number): void {
method setForceTransparent (line 82) | setForceTransparent(transparent: boolean): void {
method frameCount (line 86) | get frameCount(): number {
method getShapeMesh (line 91) | getShapeMesh(): THREE.Object3D | undefined {
method getShadowMesh (line 94) | getShadowMesh(): THREE.Object3D | undefined {
method setShadowVisible (line 97) | setShadowVisible(visible: boolean): void {
method create3DObject (line 100) | create3DObject(): void {
method update (line 123) | update(delta: number): void { }
method dispose (line 124) | dispose(): void {
FILE: src/engine/renderable/WithPosition.ts
class WithPosition (line 2) | class WithPosition {
method constructor (line 6) | constructor() {
method setPosition (line 9) | setPosition(x: number, y: number, z: number): void {
method getPosition (line 15) | getPosition(): THREE.Vector3 {
method updatePosition (line 18) | updatePosition(): void {
method applyTo (line 30) | applyTo(target: any): void {
FILE: src/engine/renderable/WithVisibility.ts
class WithVisibility (line 1) | class WithVisibility {
method constructor (line 4) | constructor() {
method setVisible (line 7) | setVisible(visible: boolean): void {
method isVisible (line 11) | isVisible(): boolean {
method updateVisibility (line 14) | updateVisibility(): void {
method applyTo (line 22) | applyTo(target: any): void {
FILE: src/engine/renderable/WorldScene.ts
constant AMBIENT_LIGHT_INTENSITY (line 13) | const AMBIENT_LIGHT_INTENSITY = 0.8;
constant CAMERA_FAR (line 14) | const CAMERA_FAR = 16000;
constant SHADOW_QUALITY_MAP (line 15) | const SHADOW_QUALITY_MAP = new Map([
class WorldScene (line 20) | class WorldScene extends RenderableContainer {
method onBeforeCameraUpdate (line 48) | get onBeforeCameraUpdate() {
method onCameraUpdate (line 51) | get onCameraUpdate() {
method factory (line 54) | static factory(viewport: {
method getCameraParams (line 67) | static getCameraParams(viewport: {
method createCamera (line 82) | static createCamera(viewport: {
method constructor (line 94) | constructor(scene: THREE.Scene, camera: THREE.OrthographicCamera, view...
method updateViewport (line 112) | updateViewport(viewport: {
method updateCamera (line 128) | updateCamera(pan: {
method create3DObject (line 148) | create3DObject(): void {
method updateShadowQuality (line 176) | updateShadowQuality(light: THREE.DirectionalLight, quality: ShadowQual...
method setLightFocusPoint (line 197) | setLightFocusPoint(x: number, y: number): void {
method applyLighting (line 200) | applyLighting(lighting: {
method update (line 211) | update(deltaTime: number, time?: number): void {
method dispose (line 225) | dispose(): void {
FILE: src/engine/renderable/builder/BatchShpBuilder.ts
type BatchItem (line 7) | interface BatchItem {
class BatchShpBuilder (line 20) | class BatchShpBuilder {
method verticesPerSprite (line 35) | get verticesPerSprite(): number {
method trianglesPerSprite (line 38) | get trianglesPerSprite(): number {
method constructor (line 41) | constructor(shpFile: ShpFile, palette: any, camera: THREE.Camera, text...
method initTexture (line 52) | private initTexture(): void {
method getSpriteGeometryOptions (line 62) | private getSpriteGeometryOptions(item: BatchItem) {
method setPalette (line 79) | setPalette(palette: any): void {
method build (line 87) | build(): THREE.Mesh {
method add (line 135) | add(item: BatchItem): void {
method setSpecGeometry (line 156) | private setSpecGeometry(item: BatchItem, geometry: THREE.BufferGeometr...
method has (line 202) | has(item: BatchItem): boolean {
method remove (line 205) | remove(item: BatchItem): void {
method update (line 218) | update(item: BatchItem): void {
method isFull (line 227) | isFull(): boolean {
method isEmpty (line 230) | isEmpty(): boolean {
method setLightingAt (line 233) | private setLightingAt(spriteIndex: number, lightMult: THREE.Vector3, a...
method setVisibilityAt (line 240) | private setVisibilityAt(spriteIndex: number, visible: boolean, array: ...
method updateLighting (line 245) | updateLighting(): void {
method dispose (line 255) | dispose(): void {
FILE: src/engine/renderable/builder/CanvasSpriteBuilder.ts
class CanvasSpriteBuilder (line 4) | class CanvasSpriteBuilder {
method clearCaches (line 23) | static clearCaches(): void {
method constructor (line 26) | constructor(images: HTMLImageElement[], camera: THREE.Camera) {
method setOffset (line 38) | setOffset(offset: {
method setAlign (line 44) | setAlign(x: number, y: number): void {
method initTexture (line 53) | private initTexture(): void {
method getSpriteGeometryOptions (line 64) | private getSpriteGeometryOptions() {
method setFrame (line 78) | setFrame(frameNo: number): void {
method getFrame (line 91) | getFrame(): number {
method getSize (line 94) | getSize(): {
method frameCount (line 103) | get frameCount(): number {
method setOpacity (line 106) | setOpacity(opacity: number): void {
method setForceTransparent (line 120) | setForceTransparent(forceTransparent: boolean): void {
method updateTransparency (line 126) | private updateTransparency(): void {
method setExtraLight (line 132) | setExtraLight(extraLight: any): void {
method setFrustumCulled (line 135) | setFrustumCulled(frustumCulled: boolean): void {
method build (line 141) | build(): THREE.Mesh {
method dispose (line 159) | dispose(): void {
FILE: src/engine/renderable/builder/CanvasTextureAtlas.ts
type CanvasTextureAtlasBlock (line 3) | type CanvasTextureAtlasBlock = GrowingPackerBlock & {
class CanvasTextureAtlas (line 6) | class CanvasTextureAtlas {
method getTexture (line 14) | getTexture(): THREE.Texture {
method getImageRect (line 20) | getImageRect(image: HTMLImageElement): {
method pack (line 35) | pack(images: HTMLImageElement[]): void {
FILE: src/engine/renderable/builder/ObjectBuilder.ts
class ObjectBuilder (line 1) | class ObjectBuilder {
method constructor (line 2) | constructor() { }
FILE: src/engine/renderable/builder/ShpAggregator.ts
class ShpAggregator (line 3) | class ShpAggregator {
method getShpFrameInfo (line 4) | static getShpFrameInfo(file: ShpFile, hasShadow: boolean) {
method aggregate (line 11) | aggregate(frames: Array<{
FILE: src/engine/renderable/builder/ShpBuilder.ts
class ShpBuilder (line 7) | class ShpBuilder {
method prepareTexture (line 41) | static prepareTexture(shpFile) {
method clearCaches (line 47) | static clearCaches() {
method constructor (line 53) | constructor(shpFile, palette, camera, scale = 1, depth = false, depthO...
method setUiAnchorCompensation (line 71) | setUiAnchorCompensation(enabled) {
method useMaterial (line 77) | useMaterial(texture, palette, transparent) {
method freeMaterial (line 102) | freeMaterial() {
method setBatched (line 117) | setBatched(batched) {
method setOffset (line 123) | setOffset(offset) {
method setAlign (line 129) | setAlign(x, y) {
method setFrameOffset (line 135) | setFrameOffset(frameOffset) {
method initTexture (line 141) | initTexture() {
method getSpriteGeometryOptions (line 145) | getSpriteGeometryOptions(frameNo) {
method getGeometryCacheKey (line 165) | getGeometryCacheKey(frameNo) {
method setFrame (line 183) | setFrame(frameNo) {
method getGeometryCache (line 198) | getGeometryCache() {
method getFrame (line 206) | getFrame() {
method setSize (line 209) | setSize(size) {
method getSize (line 212) | getSize() {
method frameCount (line 215) | get frameCount() {
method getBatchPaletteIndex (line 218) | getBatchPaletteIndex(palette) {
method setPalette (line 225) | setPalette(palette) {
method setBatchPalettes (line 239) | setBatchPalettes(palettes) {
method setExtraLight (line 248) | setExtraLight(extraLight) {
method setOpacity (line 260) | setOpacity(opacity) {
method setForceTransparent (line 270) | setForceTransparent(forceTransparent) {
method updateOpacity (line 276) | updateOpacity() {
method updateTransparency (line 286) | updateTransparency() {
method build (line 300) | build() {
method dispose (line 344) | dispose() {
FILE: src/engine/renderable/builder/ShpTextureAtlas.ts
class ShpTextureAtlas (line 3) | class ShpTextureAtlas {
method fromShpFile (line 6) | fromShpFile(shpFile: any): ShpTextureAtlas {
method getTextureArea (line 18) | getTextureArea(imageIndex: number): any {
method getTexture (line 21) | getTexture(): any {
method dispose (line 24) | dispose(): void {
FILE: src/engine/renderable/builder/SpriteBuilder.ts
class SpriteBuilder (line 1) | class SpriteBuilder {
method constructor (line 2) | constructor() { }
FILE: src/engine/renderable/builder/VxlBatchedBuilder.ts
class VxlBatchedBuilder (line 9) | class VxlBatchedBuilder extends VxlBuilder {
method constructor (line 24) | constructor(vxlFile: VxlFile, hvaFile: HvaFile | undefined, palettes: ...
method createVxlMeshes (line 32) | createVxlMeshes(): Map<string, BatchedMesh> {
method useMaterial (line 59) | private useMaterial(texture: THREE.Texture): PalettePhongMaterial {
method freeMaterial (line 78) | private freeMaterial(): void {
method getPaletteIndex (line 90) | private getPaletteIndex(palette: Palette): number {
method setPalette (line 97) | setPalette(palette: Palette): void {
method setExtraLight (line 104) | setExtraLight(light: any): void {
method setShadow (line 110) | setShadow(castShadow: boolean): void {
method setClippingPlanes (line 116) | setClippingPlanes(planes: any[]): void {
method setOpacity (line 122) | setOpacity(opacity: number): void {
method dispose (line 128) | dispose(): void {
FILE: src/engine/renderable/builder/VxlBuilder.ts
type Camera (line 3) | interface Camera {
method constructor (line 13) | constructor(camera: Camera) {
method build (line 16) | build(): THREE.Object3D {
method getSection (line 52) | getSection(sectionName: string): THREE.Mesh | undefined {
method getLocalBoundingBox (line 58) | getLocalBoundingBox(): THREE.Box3 | undefined {
FILE: src/engine/renderable/builder/VxlBuilderFactory.ts
class VxlBuilderFactory (line 9) | class VxlBuilderFactory {
method constructor (line 10) | constructor(private vxlGeometryPool: VxlGeometryPool, private useBatch...
method create (line 11) | create(vxlData: VxlFile, hvaData: HvaFile | undefined, palettes: Palet...
FILE: src/engine/renderable/builder/VxlNonBatchedBuilder.ts
type VxlSection (line 6) | interface VxlSection {
type VxlFile (line 11) | interface VxlFile {
type HvaSection (line 14) | interface HvaSection {
type HvaFile (line 17) | interface HvaFile {
type VxlGeometryPool (line 20) | interface VxlGeometryPool {
class VxlNonBatchedBuilder (line 23) | class VxlNonBatchedBuilder extends VxlBuilder {
method constructor (line 32) | constructor(vxlFile: VxlFile, palette: Palette, hvaFile: HvaFile | nul...
method createVxlMeshes (line 41) | createVxlMeshes(): Map<string, THREE.Mesh> {
method setPalette (line 68) | setPalette(palette: Palette): void {
method setExtraLight (line 75) | setExtraLight(extraLight: any): void {
method setShadow (line 81) | setShadow(castShadow: boolean): void {
method setClippingPlanes (line 89) | setClippingPlanes(clippingPlanes: THREE.Plane[]): void {
method setOpacity (line 95) | setOpacity(opacity: number): void {
method dispose (line 101) | dispose(): void {
FILE: src/engine/renderable/builder/vxlGeometry/VxlGeometryCulledBuilder.ts
class VxlGeometryCulledBuilder (line 3) | class VxlGeometryCulledBuilder {
method build (line 4) | build(e: any) {
FILE: src/engine/renderable/builder/vxlGeometry/VxlGeometryMonotoneBuilder.ts
class VxlGeometryMonotoneBuilder (line 3) | class VxlGeometryMonotoneBuilder {
method build (line 4) | build(e, t = false) {
class VxlRun (line 162) | class VxlRun {
method constructor (line 166) | constructor(e, t, i, r) {
method close_off (line 171) | close_off(e) {
method merge_run (line 175) | merge_run(e, t, i) {
FILE: src/engine/renderable/builder/vxlGeometry/VxlGeometryNaiveBuilder.ts
class VxlGeometryNaiveBuilder (line 3) | class VxlGeometryNaiveBuilder {
method build (line 4) | build(vxl: any): THREE.BufferGeometry {
method createPositionAttr (line 18) | private createPositionAttr(vxl: any, voxels: any[], boxGeometry: THREE...
method createNormalAttr (line 35) | private createNormalAttr(vxl: any, voxels: any[], vertexCount: number)...
method createColorAttr (line 49) | private createColorAttr(voxels: any[], vertexCount: number, normalArra...
method createIndexAttr (line 63) | private createIndexAttr(voxels: any[], boxGeometry: THREE.BoxBufferGeo...
FILE: src/engine/renderable/builder/vxlGeometry/VxlGeometryPool.ts
class VxlGeometryPool (line 4) | class VxlGeometryPool {
method constructor (line 7) | constructor(cache, modelQuality = ModelQuality.High) {
method setModelQuality (line 11) | setModelQuality(modelQuality) {
method getModelQuality (line 14) | getModelQuality() {
method loadFromStorage (line 17) | async loadFromStorage(data, param) {
method persistToStorage (line 21) | async persistToStorage(data, param, results) {
method clear (line 27) | clear() {
method clearStorage (line 30) | async clearStorage() {
method clearOtherModStorage (line 33) | async clearOtherModStorage() {
method get (line 36) | get(key) {
FILE: src/engine/renderable/entity/Aircraft.ts
type GameObject (line 16) | interface GameObject {
type Rules (line 46) | interface Rules {
type Palette (line 57) | interface Palette {
type VoxelAnims (line 61) | interface VoxelAnims {
type Voxels (line 64) | interface Voxels {
type Lighting (line 67) | interface Lighting {
type GameSpeed (line 71) | interface GameSpeed {
type SelectionModel (line 73) | interface SelectionModel {
type VxlBuilderFactory (line 75) | interface VxlBuilderFactory {
type VxlBuilder (line 78) | interface VxlBuilder {
type PipOverlay (line 86) | interface PipOverlay {
type Plugin (line 92) | interface Plugin {
type RenderableManager (line 101) | interface RenderableManager {
type DebugFrame (line 104) | interface DebugFrame {
class Aircraft (line 107) | class Aircraft {
method constructor (line 144) | constructor(gameObject: GameObject, rules: Rules, voxels: Voxels, voxe...
method init (line 164) | private init(): void {
method updateBaseLight (line 172) | private updateBaseLight(): void {
method updateLighting (line 175) | updateLighting(): void {
method get3DObject (line 180) | get3DObject(): THREE.Object3D | undefined {
method getIntersectTarget (line 183) | getIntersectTarget(): THREE.Object3D | undefined {
method getUiName (line 186) | getUiName(): string {
method create3DObject (line 190) | create3DObject(): void {
method setPosition (line 209) | setPosition(position: {
method getPosition (line 216) | getPosition(): THREE.Vector3 {
method registerPlugin (line 219) | registerPlugin(plugin: Plugin): void {
method highlight (line 222) | highlight(): void {
method update (line 229) | update(deltaTime: number): void {
method updateVxlRotation (line 287) | private updateVxlRotation(): void {
method createObjects (line 302) | private createObjects(target: THREE.Object3D): void {
method createMainObject (line 318) | private createMainObject(): THREE.Object3D {
method onCreate (line 350) | onCreate(renderableManager: RenderableManager): void {
method onRemove (line 354) | onRemove(renderableManager: RenderableManager): void {
method dispose (line 376) | dispose(): void {
FILE: src/engine/renderable/entity/Anim.ts
type ObjectArt (line 12) | interface ObjectArt {
type Theater (line 27) | interface Theater {
type Camera (line 30) | interface Camera {
type DebugFrame (line 32) | interface DebugFrame {
type WorldSound (line 35) | interface WorldSound {
type SoundHandle (line 38) | interface SoundHandle {
type Palette (line 42) | interface Palette {
class Anim (line 46) | class Anim {
method constructor (line 70) | constructor(name: string, objectArt: ObjectArt, extraOffset: {
method get3DObject (line 88) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 91) | create3DObject(): void {
method setPosition (line 103) | setPosition(position: {
method getPosition (line 110) | getPosition(): THREE.Vector3 {
method update (line 113) | update(deltaTime: number): void {
method createObjects (line 141) | private createObjects(parentObj: THREE.Object3D): void {
method setExtraLight (line 188) | setExtraLight(light: THREE.Vector3): void {
method setRenderOrder (line 192) | setRenderOrder(order: number): void {
method computeSpriteAnchorOffset (line 198) | private computeSpriteAnchorOffset(spriteOffset: {
method createMainObject (line 211) | private createMainObject(offset: {
method getAnimProps (line 234) | getAnimProps(): AnimProps | undefined {
method getShpFile (line 237) | getShpFile(): any {
method remapColor (line 240) | remapColor(colorMap: any): void {
method isAnimFinished (line 248) | isAnimFinished(): boolean {
method isAnimNotStarted (line 251) | isAnimNotStarted(): boolean {
method endAnimationLoop (line 254) | endAnimationLoop(): void {
method reset (line 257) | reset(): void {
method dispose (line 260) | dispose(): void {
FILE: src/engine/renderable/entity/BoxIntersectObject3D.ts
class BoxIntersectObject3D (line 2) | class BoxIntersectObject3D extends THREE.Object3D {
method constructor (line 8) | constructor(boxSize: THREE.Vector3) {
method raycast (line 12) | raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]):...
FILE: src/engine/renderable/entity/Building.ts
class Building (line 118) | class Building {
method constructor (line 199) | constructor(e: any, t: any, i: any, r: any, s: any, a: any, n: any, o:...
method updateBaseLight (line 271) | updateBaseLight() {
method updateLighting (line 277) | updateLighting() {
method get3DObject (line 283) | get3DObject() {
method getIntersectTarget (line 286) | getIntersectTarget() {
method updateIntersectTarget (line 289) | updateIntersectTarget() {
method getUiName (line 299) | getUiName() {
method create3DObject (line 303) | create3DObject() {
method createLamp (line 347) | createLamp(e) {
method createLampTexture (line 384) | createLampTexture(e) {
method setPosition (line 398) | setPosition(e) {
method getPosition (line 402) | getPosition() {
method registerPlugin (line 405) | registerPlugin(e) {
method highlight (line 408) | highlight() {
method update (line 412) | update(i) {
method createExplosionAnims (line 649) | createExplosionAnims(e) {
method updateMuzzleAnims (line 659) | updateMuzzleAnims(t) {
method getNormalizedAnimType (line 670) | getNormalizedAnimType(e) {
method hasObjectWithStoppedAnimation (line 674) | hasObjectWithStoppedAnimation(t) {
method computeDamageType (line 685) | computeDamageType(e) {
method updateImage (line 700) | updateImage(o) {
method updateMainObjFrame (line 738) | updateMainObjFrame(e, t) {
method updateWallImage (line 751) | updateWallImage(e, t) {
method createObjects (line 762) | createObjects(t) {
method computeSpriteAnchorOffset (line 856) | computeSpriteAnchorOffset(e) {
method createMainObject (line 860) | createMainObject(e, t, i = false) {
method createRubbleObject (line 874) | createRubbleObject(t) {
method createAnimObjects (line 890) | createAnimObjects(n, o) {
method createFireObjects (line 905) | createFireObjects(n) {
method createMuzzleFlashAnim (line 940) | createMuzzleFlashAnim(e, i) {
method createAnimObject (line 957) | createAnimObject(e, t, i, r, s) {
method createBibObject (line 978) | createBibObject(e, t) {
method createTurretObject (line 988) | createTurretObject(i, e) {
method createRangeCircle (line 1060) | createRangeCircle(e) {
method toggleRangeCircleVisibility (line 1065) | toggleRangeCircleVisibility(e) {
method setAnimationVisibility (line 1081) | setAnimationVisibility(e, i, t = -1) {
method setActiveAnimationVisible (line 1098) | setActiveAnimationVisible() {
method setPowered (line 1110) | setPowered(r) {
method hasAnimation (line 1136) | hasAnimation(e) {
method setAnimation (line 1141) | setAnimation(e, t) {
method doWithAnimation (line 1282) | doWithAnimation(e, i) {
method doWithCurrentAnimation (line 1292) | doWithCurrentAnimation(e) {
method endCurrentAnimation (line 1295) | endCurrentAnimation() {
method handleSoundChange (line 1298) | handleSoundChange(e, t, i, r = 1) {
method onCreate (line 1311) | onCreate(t) {
method onRemove (line 1318) | onRemove(t) {
method dispose (line 1332) | dispose() {
FILE: src/engine/renderable/entity/Debris.ts
type GameObject (line 10) | interface GameObject {
type Rules (line 27) | interface Rules {
type ImageFinder (line 30) | interface ImageFinder {
type Voxels (line 33) | interface Voxels {
type Palette (line 36) | interface Palette {
type Camera (line 38) | interface Camera {
type Lighting (line 40) | interface Lighting {
type GameSpeed (line 44) | interface GameSpeed {
type VxlBuilderFactory (line 46) | interface VxlBuilderFactory {
type VxlBuilder (line 49) | interface VxlBuilder {
type Plugin (line 54) | interface Plugin {
class Debris (line 61) | class Debris {
method constructor (line 89) | constructor(gameObject: GameObject, rules: Rules, imageFinder: ImageFi...
method init (line 110) | private init(): void {
method registerPlugin (line 119) | public registerPlugin(plugin: Plugin): void {
method updateLighting (line 122) | public updateLighting(): void {
method get3DObject (line 131) | public get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 134) | public create3DObject(): void {
method setPosition (line 148) | public setPosition(position: THREE.Vector3): void {
method getPosition (line 151) | public getPosition(): THREE.Vector3 {
method update (line 154) | public update(time: number, deltaTime: number = 0): void {
method createObjects (line 187) | private createObjects(parent: THREE.Object3D): void {
method computeSpriteAnchorOffset (line 195) | private computeSpriteAnchorOffset(offset: {
method createMainObject (line 205) | private createMainObject(): THREE.Object3D {
method getVxlFileName (line 254) | private getVxlFileName(objectRules: any, objectArt: any): string {
method onCreate (line 267) | public onCreate(context: any): void {
method onRemove (line 270) | public onRemove(context: any): void {
method dispose (line 279) | public dispose(): void {
FILE: src/engine/renderable/entity/HighlightAnimRunner.ts
class HighlightAnimRunner (line 7) | class HighlightAnimRunner extends SimpleRunner {
method constructor (line 10) | constructor(gameSpeed: number | BoxedVar<number>, maxAmount: number = ...
method animate (line 21) | animate(loopCount: number): void {
method getValue (line 25) | getValue(): number {
FILE: src/engine/renderable/entity/Infantry.ts
class Infantry (line 27) | class Infantry {
method constructor (line 81) | constructor(gameObject: any, rules: any, art: any, imageFinder: any, t...
method updateBaseLight (line 105) | updateBaseLight(): void {
method registerPlugin (line 110) | registerPlugin(plugin: any): void {
method updateLighting (line 113) | updateLighting(): void {
method get3DObject (line 118) | get3DObject(): THREE.Object3D {
method getIntersectTarget (line 121) | getIntersectTarget(): THREE.Object3D {
method getUiName (line 124) | getUiName(): string {
method create3DObject (line 128) | create3DObject(): void {
method setPosition (line 146) | setPosition(position: {
method getPosition (line 153) | getPosition(): THREE.Vector3 {
method highlight (line 156) | highlight(): void {
method update (line 163) | update(deltaTime: number): void {
method findIdleSequence (line 387) | findIdleSequence(zone: ZoneType, stance: StanceType, art: any): Sequen...
method prepareDeadBodyAnim (line 399) | prepareDeadBodyAnim(): void {
method findSequenceBy (line 406) | findSequenceBy(zone: ZoneType, stance: StanceType, isMoving: boolean, ...
method setAnimParams (line 413) | setAnimParams(sequenceType: SequenceType, time: number, loop: boolean ...
method updateShapeFrame (line 442) | updateShapeFrame(facingNumber: number): void {
method computeFacingNumber (line 451) | computeFacingNumber(direction: number): number {
method directionFromFacingNo (line 454) | directionFromFacingNo(facingNumber: number): number {
method createObjects (line 457) | createObjects(parent: THREE.Object3D): void {
method createMainObject (line 476) | createMainObject(art: any): THREE.Object3D {
method setDisguise (line 511) | setDisguise(disguise: any): void {
method updateShpRenderableFromArt (line 519) | updateShpRenderableFromArt(art: any): void {
method onCreate (line 527) | onCreate(renderableManager: any): void {
method onRemove (line 534) | onRemove(renderableManager: any): Promise<void> | void {
method dispose (line 585) | dispose(): void {
FILE: src/engine/renderable/entity/InvulnerableAnimRunner.ts
class InvulnerableAnimRunner (line 6) | class InvulnerableAnimRunner extends SimpleRunner {
method constructor (line 11) | constructor(gameSpeed: number, minAmount: number = -0.75, maxAmount: n...
method animate (line 23) | animate(): void {
method getValue (line 26) | getValue(): number {
FILE: src/engine/renderable/entity/IsoCoords.ts
class IsoCoords (line 2) | class IsoCoords {
method init (line 7) | static init(origin: {
method worldToScreen (line 13) | static worldToScreen(x: number, y: number): {
method screenToWorld (line 27) | static screenToWorld(x: number, y: number): {
method vecWorldToScreen (line 39) | static vecWorldToScreen(vec: {
method tileToScreen (line 51) | static tileToScreen(tileX: number, tileY: number): {
method tileHeightToScreen (line 58) | static tileHeightToScreen(height: number): number {
method tile3dToScreen (line 61) | static tile3dToScreen(tileX: number, tileY: number, height: number): {
method screenTileToScreen (line 69) | static screenTileToScreen(tileX: number, tileY: number): {
method screenToScreenTile (line 78) | static screenToScreenTile(x: number, y: number): {
method screenTileToWorld (line 87) | static screenTileToWorld(tileX: number, tileY: number): {
method getScreenTileSize (line 94) | static getScreenTileSize(): {
method screenDistanceToWorld (line 103) | static screenDistanceToWorld(x: number, y: number): number {
FILE: src/engine/renderable/entity/Overlay.ts
type GameObject (line 16) | interface GameObject {
type Rules (line 42) | interface Rules {
type Art (line 50) | interface Art {
type ObjectArt (line 53) | interface ObjectArt {
type ImageFinder (line 59) | interface ImageFinder {
type Palette (line 62) | interface Palette {
type Camera (line 64) | interface Camera {
type Lighting (line 66) | interface Lighting {
type DebugFrame (line 69) | interface DebugFrame {
type MapOverlayLayer (line 72) | interface MapOverlayLayer {
type TransientAnimCreator (line 80) | interface TransientAnimCreator {
class Overlay (line 83) | class Overlay {
method constructor (line 105) | constructor(gameObject: GameObject, rules: Rules, art: Art, imageFinde...
method init (line 122) | private init(): void {
method updateLighting (line 127) | private updateLighting(): void {
method get3DObject (line 133) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 136) | create3DObject(): void {
method update (line 149) | update(deltaTime: number): void {
method computeFrame (line 171) | private computeFrame(isDamaged: boolean): number {
method setPosition (line 188) | setPosition(position: THREE.Vector3): void {
method getPosition (line 191) | getPosition(): THREE.Vector3 {
method getIntersectTarget (line 194) | getIntersectTarget(): THREE.Object3D | undefined {
method getUiName (line 197) | getUiName(): string {
method createObjects (line 200) | private createObjects(parent: THREE.Object3D): void {
method buildVirtualBridgeFile (line 292) | private buildVirtualBridgeFile(bridgeType: OverlayBridgeType): ShpFile {
method createBridgeShadowSurface (line 313) | private createBridgeShadowSurface(): THREE.Mesh {
method createWireframe (line 329) | private createWireframe(foundation: {
method createMainObject (line 338) | private createMainObject(imageSource: any, drawOffset: THREE.Vector3):...
method onRemove (line 350) | onRemove(transientAnimCreator: TransientAnimCreator): void {
method dispose (line 368) | dispose(): void {
FILE: src/engine/renderable/entity/PipOverlay.ts
constant HEALTH_BAR_OFFSET (line 19) | const HEALTH_BAR_OFFSET = -1;
constant CONTROL_GROUP_SIZE (line 20) | const CONTROL_GROUP_SIZE = { width: 8, height: 11 };
constant BORDER_WIDTH (line 21) | const BORDER_WIDTH = 1;
constant SELECTION_LEVEL_MAP (line 22) | const SELECTION_LEVEL_MAP: Record<number, SelectionLevel> = {
constant HEALTH_LEVEL_TO_IMAGE (line 30) | const HEALTH_LEVEL_TO_IMAGE = new Map<HealthLevel, number>()
type SpriteGeometryConfig (line 34) | interface SpriteGeometryConfig {
type ImageHandle (line 53) | interface ImageHandle {
type UnitHealthBarResult (line 57) | interface UnitHealthBarResult {
type GameObject (line 61) | interface GameObject {
type SelectionModel (line 133) | interface SelectionModel {
type AnimFactory (line 137) | interface AnimFactory {
class PipOverlay (line 140) | class PipOverlay {
method clearCaches (line 207) | static clearCaches(): void {
method constructor (line 224) | constructor(paradropRules: any, audioVisualRules: any, gameObject: Gam...
method create3DObject (line 250) | create3DObject(): void {
method onCreate (line 317) | onCreate(effectManager: any): void {
method initTexture (line 325) | private initTexture(): TextureAtlas {
method buildSpriteGeometry (line 343) | private buildSpriteGeometry(imageHandle: any): SpriteGeometryConfig {
method createBuildingHealthBar (line 361) | private createBuildingHealthBar(gameObject: GameObject): THREE.Mesh {
method createUnitHealthBar (line 403) | private createUnitHealthBar(gameObject: GameObject): UnitHealthBarResu...
method createUnitHealthTexture (line 474) | private createUnitHealthTexture(isVehicle: boolean): THREE.Texture {
method createBuildingSelectionBox (line 519) | private createBuildingSelectionBox(gameObject: GameObject): THREE.Obje...
method createBuildingSelectionCornerMesh (line 541) | private createBuildingSelectionCornerMesh(): THREE.LineSegments {
method createBuildingOccupationInfo (line 555) | private createBuildingOccupationInfo(gameObject: GameObject): THREE.Me...
method createPipsSprite (line 580) | private createPipsSprite(pipColors: PipColor[], totalSlots: number, is...
method createControlGroupTexture (line 618) | private createControlGroupTexture(color: any): THREE.Texture {
method createControlGroupSprite (line 641) | private createControlGroupSprite(groupNumber: number): THREE.Mesh {
method createPrimaryFactoryTexture (line 677) | private createPrimaryFactoryTexture(color: any): THREE.Texture {
method createPrimaryFactorySprite (line 696) | private createPrimaryFactorySprite(): THREE.Mesh | undefined {
method createVeteranIndicator (line 731) | private createVeteranIndicator(gameObject: GameObject): THREE.Mesh | u...
method createRepairWrench (line 744) | private createRepairWrench(): any {
method objectIsOpaqueToViewer (line 749) | private objectIsOpaqueToViewer(): boolean {
method update (line 755) | update(deltaTime: number): void {
method updateFlyerHelper (line 853) | private updateFlyerHelper(selectionLevel: SelectionLevel, deltaTime: n...
method updateBehindAnim (line 882) | private updateBehindAnim(deltaTime: number): void {
method updateDebugLabel (line 902) | private updateDebugLabel(): void {
method updateRepairWrenchSprite (line 924) | private updateRepairWrenchSprite(enabled: boolean): void {
method updateVeteranIndicatorSprite (line 936) | private updateVeteranIndicatorSprite(gameObject: GameObject): void {
method updateRallyPointLine (line 950) | private updateRallyPointLine(rallyPoint: any, rallyLine: RallyPointFx)...
method updatePrimaryFactorySprite (line 960) | private updatePrimaryFactorySprite(enabled: boolean): void {
method updateControlGroupSprite (line 972) | private updateControlGroupSprite(groupNumber: number | undefined): void {
method updatePipsSprite (line 1002) | private updatePipsSprite(): void {
method computePipsDataKey (line 1053) | private computePipsDataKey(gameObject: GameObject): any {
method updateHealthBarSprite (line 1073) | private updateHealthBarSprite(selectionLevel: SelectionLevel): void {
method get3DObject (line 1088) | get3DObject(): THREE.Object3D | undefined {
method dispose (line 1091) | dispose(): void {
FILE: src/engine/renderable/entity/Projectile.ts
class Projectile (line 19) | class Projectile {
method constructor (line 53) | constructor(gameObject: any, rules: any, imageFinder: any, voxels: any...
method registerPlugin (line 91) | registerPlugin(plugin: any): void {
method updateLighting (line 94) | updateLighting(): void {
method getIntersectTarget (line 105) | getIntersectTarget(): any { }
method get3DObject (line 106) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 109) | create3DObject(): void {
method setPosition (line 121) | setPosition(position: {
method getPosition (line 128) | getPosition(): THREE.Vector3 {
method update (line 131) | update(time: number, deltaTime: number): void {
method updateShapeFrame (line 176) | updateShapeFrame(direction: number): void {
method createObjects (line 183) | createObjects(parent: THREE.Object3D): void {
method createSonicWaveGeometry (line 258) | createSonicWaveGeometry(): THREE.PlaneGeometry {
method onCreate (line 269) | onCreate(renderableManager: any): void {
method onRemove (line 378) | onRemove(renderableManager: any): void {
method dispose (line 386) | dispose(): void {
FILE: src/engine/renderable/entity/RenderableFactory.ts
type Position (line 29) | interface Position {
type GameEntity (line 33) | interface GameEntity {
type LocalPlayer (line 61) | interface LocalPlayer {
type UnitSelection (line 63) | interface UnitSelection {
type Alliances (line 66) | interface Alliances {
type Rules (line 68) | interface Rules {
type Art (line 79) | interface Art {
type MapRenderable (line 82) | interface MapRenderable {
type ImageFinder (line 87) | interface ImageFinder {
type Palettes (line 89) | interface Palettes {
type Voxels (line 92) | interface Voxels {
type VoxelAnims (line 94) | interface VoxelAnims {
type Theater (line 96) | interface Theater {
type Camera (line 101) | interface Camera {
type Lighting (line 103) | interface Lighting {
type LightingDirector (line 105) | interface LightingDirector {
type DebugWireframes (line 107) | interface DebugWireframes {
type DebugText (line 109) | interface DebugText {
type GameSpeed (line 111) | interface GameSpeed {
type WorldSound (line 113) | interface WorldSound {
type Strings (line 115) | interface Strings {
type FlyerHelperOpt (line 117) | interface FlyerHelperOpt {
type HiddenObjectsOpt (line 119) | interface HiddenObjectsOpt {
type VxlBuilderFactory (line 121) | interface VxlBuilderFactory {
type BuildingImageDataCache (line 123) | interface BuildingImageDataCache {
type Plugin (line 125) | interface Plugin {
type RenderableEntity (line 127) | interface RenderableEntity {
class RenderableFactory (line 130) | class RenderableFactory {
method constructor (line 157) | constructor(localPlayer: LocalPlayer, unitSelection: UnitSelection, al...
method createTransientAnim (line 185) | createTransientAnim(name: string, callback?: any): TransientAnim {
method createAnim (line 189) | createAnim(name: string): Anim {
method create (line 193) | create(entity: GameEntity): RenderableEntity {
FILE: src/engine/renderable/entity/Smudge.ts
class Smudge (line 8) | class Smudge {
method constructor (line 22) | constructor(gameObject: any, imageFinder: ImageFinder, palette: any, c...
method init (line 34) | private init(): void {
method updateLighting (line 39) | private updateLighting(): void {
method get3DObject (line 44) | public get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 47) | public create3DObject(): void {
method update (line 59) | public update(delta: number): void { }
method setPosition (line 60) | public setPosition(pos: THREE.Vector3): void {
method getPosition (line 63) | public getPosition(): THREE.Vector3 {
method createObjects (line 66) | private createObjects(parent: THREE.Object3D): void {
method onRemove (line 103) | public onRemove(): void {
method dispose (line 108) | public dispose(): void {
FILE: src/engine/renderable/entity/TargetLines.ts
type LineObjects (line 5) | interface LineObjects {
class TargetLines (line 11) | class TargetLines {
method constructor (line 22) | constructor(private currentPlayer: any, private unitSelection: any, pr...
method create3DObject (line 25) | create3DObject(): void {
method get3DObject (line 57) | get3DObject(): THREE.Object3D | undefined {
method forceShow (line 60) | forceShow(): void {
method update (line 63) | update(now: number): void {
method showLines (line 116) | showLines(unit: any, now: number): void {
method hideAllLines (line 124) | hideAllLines(): void {
method updateLines (line 130) | updateLines(unit: any): void {
method createLineHead (line 196) | createLineHead(isAttack: boolean): THREE.Mesh {
method disposeUnitLines (line 203) | disposeUnitLines(): void {
method disposeLineObjects (line 209) | disposeLineObjects(lineObjects: LineObjects): void {
method dispose (line 212) | dispose(): void {
method updateLineEndpoints (line 220) | private updateLineEndpoints(unit: any): void {
method syncLineHeadPositions (line 251) | private syncLineHeadPositions(line: THREE.Line, srcLineHead: THREE.Mes...
FILE: src/engine/renderable/entity/Terrain.ts
class Terrain (line 13) | class Terrain {
method constructor (line 32) | constructor(gameObject: any, terrainLayer: any, imageFinder: ImageFind...
method init (line 46) | private init(): void {
method updateLighting (line 52) | private updateLighting(): void {
method get3DObject (line 57) | public get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 60) | public create3DObject(): void {
method setPosition (line 72) | public setPosition(pos: THREE.Vector3): void {
method getPosition (line 75) | public getPosition(): THREE.Vector3 {
method update (line 78) | public update(delta: number): void {
method createObjects (line 96) | private createObjects(parent: THREE.Object3D): void {
method onRemove (line 162) | public onRemove(): void {
method dispose (line 167) | public dispose(): void {
FILE: src/engine/renderable/entity/TransientAnim.ts
class TransientAnim (line 2) | class TransientAnim extends Anim {
method constructor (line 4) | constructor(e: any, t: any, i: any, r: any, s: any, a: any, n: any, o:...
method update (line 8) | update(e: number): void {
method remove (line 21) | remove(): void {
FILE: src/engine/renderable/entity/Vehicle.ts
type SquidGrabAnimType (line 63) | enum SquidGrabAnimType {
type GameObjectInterface (line 69) | interface GameObjectInterface {
class Vehicle (line 139) | class Vehicle {
method constructor (line 216) | constructor(e, t, i, r, s, a, n, o, l, c, h, u, d, g, p, m, f) {
method updateBaseLight (line 248) | updateBaseLight() {
method registerPlugin (line 255) | registerPlugin(e) {
method updateLighting (line 258) | updateLighting() {
method get3DObject (line 264) | get3DObject() {
method create3DObject (line 267) | create3DObject() {
method updateClippingPlanes (line 284) | updateClippingPlanes(e, t = !1) {
method getIntersectTarget (line 292) | getIntersectTarget() {
method getUiName (line 295) | getUiName() {
method setPosition (line 299) | setPosition(e) {
method getPosition (line 302) | getPosition() {
method highlight (line 305) | highlight() {
method update (line 311) | update(i, r = 0) {
method updateVxlRotation (line 463) | updateVxlRotation(e: number, t: boolean) {
method startRocking (line 501) | startRocking(i, r, s) {
method updateRocking (line 527) | updateRocking(t, i) {
method updateSquidGrab (line 549) | updateSquidGrab(e, t, i, r, s, a, n) {
method updateShapeAnimation (line 594) | updateShapeAnimation(t, i) {
method updateShapeFrame (line 612) | updateShapeFrame(t, i, r) {
method updateSquidGrabAnim (line 630) | updateSquidGrabAnim(e, t, i) {
method createObjects (line 643) | createObjects(t) {
method computeSpriteAnchorOffset (line 664) | computeSpriteAnchorOffset(e) {
method createMainObject (line 668) | createMainObject() {
method createPlaceholder (line 807) | createPlaceholder() {
method updateActiveTurret (line 815) | updateActiveTurret(i) {
method updateBodyVxl (line 820) | updateBodyVxl() {
method isSinker (line 832) | isSinker() {
method onCreate (line 836) | onCreate(t) {
method onRemove (line 842) | onRemove(t) {
method dispose (line 890) | dispose() {
FILE: src/engine/renderable/entity/WaypointLine.ts
type WaypointVertex (line 5) | interface WaypointVertex {
type LinePath (line 10) | interface LinePath {
type Camera (line 16) | interface Camera extends THREE.Camera {
class WaypointLine (line 21) | class WaypointLine {
method constructor (line 35) | constructor(linePath: LinePath, camera: Camera) {
method get3DObject (line 57) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 60) | create3DObject(): void {
method update (line 78) | update(timestamp: number): void {
method computeLineLength (line 114) | private computeLineLength(vertices: THREE.Vector3[]): number {
method getEnabledVertices (line 121) | private getEnabledVertices(): THREE.Vector3[] {
method getEnabledLineHeadVertices (line 126) | private getEnabledLineHeadVertices(): THREE.Vector3[] {
method createLineGeometry (line 131) | private createLineGeometry(vertices: THREE.Vector3[]): {
method updateLineGeometry (line 150) | private updateLineGeometry(vertices: THREE.Vector3[]): number {
method createFgLineMaterial (line 166) | private createFgLineMaterial(color: THREE.Color, lineLength: number): ...
method createBgLineMaterial (line 177) | private createBgLineMaterial(color: THREE.Color): MeshLineMaterial {
method computeDashArray (line 187) | private computeDashArray(lineLength: number): number {
method computeResolution (line 190) | private computeResolution(camera: Camera): THREE.Vector2 {
method createLineHeads (line 193) | private createLineHeads(positions: THREE.Vector3[]): THREE.Points[] {
method updateLineHeads (line 202) | private updateLineHeads(positions: THREE.Vector3[]): void {
method dispose (line 217) | dispose(): void {
FILE: src/engine/renderable/entity/WaypointLines.ts
type VertexType (line 7) | enum VertexType {
type Unit (line 12) | interface Unit {
type Player (line 25) | interface Player {
type Waypoint (line 27) | interface Waypoint {
type WaypointPath (line 34) | interface WaypointPath {
type PathNode (line 38) | interface PathNode {
type Target (line 48) | interface Target {
type UnitSelection (line 53) | interface UnitSelection {
type Camera (line 58) | interface Camera {
type LineVertex (line 60) | interface LineVertex {
type LinePath (line 68) | interface LinePath {
class WaypointLines (line 75) | class WaypointLines {
method constructor (line 87) | constructor(unitSelection: UnitSelection, currentPlayer: Player, selec...
method create3DObject (line 94) | create3DObject(): void {
method get3DObject (line 101) | get3DObject(): THREE.Object3D | undefined {
method update (line 104) | update(deltaTime: number): void {
method createSourceLinePath (line 185) | private createSourceLinePath(unit: Unit, path?: WaypointPath): LinePath {
method updateSourceLinePath (line 228) | private updateSourceLinePath(linePath: LinePath, unit: Unit, path?: Wa...
method createWaypointLinePath (line 267) | private createWaypointLinePath(path: WaypointPath, isSelected: boolean...
method updateWaypointLinePath (line 281) | private updateWaypointLinePath(linePath: LinePath): void {
method computeInitialTargetPosition (line 292) | private computeInitialTargetPosition(config: TargetLinesConfig): THREE...
method dispose (line 302) | dispose(): void {
FILE: src/engine/renderable/entity/building/AnimationType.ts
type AnimationType (line 1) | enum AnimationType {
FILE: src/engine/renderable/entity/building/BuildingAnimArtProps.ts
constant ANIM_PROP_NAMES (line 5) | const ANIM_PROP_NAMES = new Map<AnimationType, string[]>([
class BuildingAnimArtProps (line 37) | class BuildingAnimArtProps {
method constructor (line 39) | constructor() {
method read (line 42) | read(config: IniSection, objectManager: any): void {
method getByType (line 97) | getByType(type: AnimationType): BuildingAnimData[] {
method getAll (line 103) | getAll(): Map<AnimationType, BuildingAnimData[]> {
FILE: src/engine/renderable/entity/building/BuildingAnimData.ts
class BuildingAnimData (line 1) | class BuildingAnimData {
FILE: src/engine/renderable/entity/building/BuildingShpHelper.ts
class BuildingShpHelper (line 4) | class BuildingShpHelper {
method constructor (line 5) | constructor(private imageFinder: ImageFinder) { }
method getShpFrameInfos (line 6) | getShpFrameInfos(building: {
method collectAnimShpFiles (line 25) | collectAnimShpFiles(anims: {
FILE: src/engine/renderable/entity/building/DamageType.ts
type DamageType (line 1) | enum DamageType {
FILE: src/engine/renderable/entity/building/PsychicDetectPlugin.ts
class PsychicDetectPlugin (line 3) | class PsychicDetectPlugin {
method constructor (line 13) | constructor(gameObject: any, psychicDetectorTrait: any, localPlayer: {
method onCreate (line 22) | onCreate(renderableManager: any): void {
method update (line 25) | update(delta: number): void {
method onRemove (line 78) | onRemove(): void {
method dispose (line 82) | dispose(): void {
method disposeLine (line 85) | private disposeLine(effect: DetectionLineFx): void {
FILE: src/engine/renderable/entity/map/MapBounds.ts
type Point (line 5) | interface Point {
type Size (line 9) | interface Size {
type BoundsInfo (line 13) | interface BoundsInfo {
type Map (line 21) | interface Map {
class MapBounds (line 24) | class MapBounds {
method constructor (line 30) | constructor(map: Map) {
method build (line 44) | private build(): THREE.Object3D {
method createBoundRect (line 57) | private createBoundRect(start: Point, end: Point, color: number): THRE...
method get3DObject (line 82) | public get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 85) | public create3DObject(): void {
method update (line 98) | public update(): void { }
method setVisible (line 99) | public setVisible(visible: boolean): void {
method dispose (line 116) | public dispose(): void {
FILE: src/engine/renderable/entity/map/MapGrid.ts
type Size (line 4) | interface Size {
class MapGrid (line 8) | class MapGrid {
method constructor (line 11) | constructor(size: Size) {
method build (line 15) | private build(): void {
method get3DObject (line 43) | public get3DObject(): THREE.Object3D {
method create3DObject (line 46) | public create3DObject(): void { }
method update (line 47) | public update(): void { }
FILE: src/engine/renderable/entity/map/MapRenderable.ts
class MapRenderable (line 10) | class MapRenderable {
method constructor (line 42) | constructor(gameObj: any, mapShroud: any, mapRadiation: any, lighting:...
method get3DObject (line 58) | get3DObject() {
method getGameObject (line 61) | getGameObject() {
method init (line 64) | init() {
method setShroud (line 94) | setShroud(shroud: any) {
method addObject (line 113) | addObject(obj: any) {
method removeObject (line 120) | removeObject(obj: any) {
method create3DObject (line 129) | create3DObject() {
method update (line 142) | update(deltaTime: number, ...args: any[]) {
method updateLighting (line 178) | updateLighting(lightingData: any) {
method dispose (line 184) | dispose() {
FILE: src/engine/renderable/entity/map/MapShroudLayer.ts
class MapShroudLayer (line 49) | class MapShroudLayer {
method constructor (line 60) | constructor(shroud: any, imageFinder: any, camera: any) {
method get3DObject (line 78) | get3DObject() {
method create3DObject (line 81) | create3DObject() {
method setShroud (line 93) | setShroud(shroud: any) {
method createTileObjects (line 99) | createTileObjects(parent: any) {
method createTileGeometry (line 154) | createTileGeometry(shroudCoords: any, textureAtlas: any, frameNo: numb...
method getTileGeometryOptions (line 161) | getTileGeometryOptions(textureAtlas: any, frameNo: number) {
method update (line 171) | update(deltaTime: number) {
method extendToAdjacentTiles (line 192) | extendToAdjacentTiles(coords: any[]) {
method updateTiles (line 208) | updateTiles(coords: any[]) {
method updateAllTiles (line 215) | updateAllTiles() {
method toggleAllTiles (line 225) | toggleAllTiles(shroudType: any) {
method updateTilePiece (line 234) | updateTilePiece(tileIndex: number, frameNo: number) {
method getFrameNo (line 237) | getFrameNo(shroudCoords: any): number {
method hasShroudedNeighbour (line 279) | hasShroudedNeighbour({ sx, sy }: any, dx: number, dy: number): boolean {
method dispose (line 285) | dispose() {
FILE: src/engine/renderable/entity/map/MapSpriteBatchLayer.ts
type BatchShpSpec (line 9) | interface BatchShpSpec {
type ObjectSpecs (line 18) | interface ObjectSpecs {
class MapSpriteBatchLayer (line 22) | class MapSpriteBatchLayer {
method constructor (line 40) | constructor(label: string, batchedObjectRules: any[], spriteUseDepth: ...
method get3DObject (line 56) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 59) | create3DObject(): void {
method createAggregatedShpFile (line 68) | private createAggregatedShpFile(filename: string): any {
method update (line 86) | update(deltaTime: number): void { }
method updateLighting (line 87) | updateLighting(): void {
method shouldBeBatched (line 95) | shouldBeBatched(obj: any): boolean {
method getBatchKey (line 98) | private getBatchKey(obj: any): string {
method addObject (line 101) | addObject(obj: any): void {
method buildBatchShpSpec (line 150) | private buildBatchShpSpec(obj: any, aggregatedData: any): BatchShpSpec {
method buildShadowBatchShpSpec (line 172) | private buildShadowBatchShpSpec(mainSpec: BatchShpSpec, aggregatedData...
method removeObject (line 185) | removeObject(obj: any): void {
method hasObject (line 211) | hasObject(obj: any): boolean {
method getObjectFrameCount (line 214) | getObjectFrameCount(obj: any): number {
method setObjectFrame (line 221) | setObjectFrame(obj: any, frameIndex: number): void {
method dispose (line 244) | dispose(): void {
FILE: src/engine/renderable/entity/map/MapSurface.ts
constant MAGIC_OFFSET (line 6) | const MAGIC_OFFSET = 0.05;
class MapSurface (line 7) | class MapSurface {
method constructor (line 13) | constructor(map: any, theater: any) {
method get3DObject (line 18) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 21) | create3DObject(): void {
method update (line 31) | update(): void { }
method setVisible (line 32) | setVisible(visible: boolean): void {
method createObject (line 38) | private createObject(): THREE.Mesh {
method createRectGeometry (line 58) | private createRectGeometry(rampType: number): THREE.BufferGeometry {
method dispose (line 73) | dispose(): void {
FILE: src/engine/renderable/entity/map/MapTileLayer.ts
class MapTileLayer (line 13) | class MapTileLayer {
method constructor (line 30) | constructor(mapData: any, theater: any, art: any, imageFinder: any, ca...
method get3DObject (line 45) | get3DObject(): any {
method create3DObject (line 48) | create3DObject(): void {
method createTileObjects (line 58) | createTileObjects(parent: any): void {
method update (line 225) | update(deltaTime: number): void {
method updateLighting (line 230) | updateLighting(tiles?: any[]): void {
method updateColorMultBuffer (line 258) | private updateColorMultBuffer(lightingData: number[], buffer: Float32A...
method updateColorMultBufferAtIndex (line 274) | private updateColorMultBufferAtIndex(tileIndex: number, r: number, g: ...
method dispose (line 284) | dispose(): void {
FILE: src/engine/renderable/entity/map/MapTileLayerDebug.ts
class MapTileLayerDebug (line 9) | class MapTileLayerDebug {
method constructor (line 21) | constructor(map: any, theater: any, camera: any) {
method get3DObject (line 30) | get3DObject(): any {
method create3DObject (line 33) | create3DObject(): void {
method update (line 52) | update(): void {
method setVisible (line 59) | setVisible(visible: boolean): void {
method setupLines (line 78) | private setupLines(target: any): void {
method destroyLines (line 89) | private destroyLines(): void {
method createTileOverlay (line 96) | private createTileOverlay(): any {
method getTileTexture (line 127) | private getTileTexture(): any {
method createConnectivityLines (line 175) | private createConnectivityLines(speedType: any, includeT: boolean, col...
method onRemove (line 202) | onRemove(): void {
method dispose (line 207) | dispose(): void {
FILE: src/engine/renderable/entity/map/MinimapModel.ts
constant DEFAULT_COLOR (line 3) | const DEFAULT_COLOR = new THREE.Color("rgb(173, 170, 132)");
constant WALL_COLORS (line 4) | const WALL_COLORS = new Map([
constant DEFAULT_WALL_COLOR (line 10) | const DEFAULT_WALL_COLOR = new THREE.Color("rgb(90, 89, 82)");
constant RUBBLE_COLOR (line 11) | const RUBBLE_COLOR = new THREE.Color(0);
constant TIBERIUM_COLOR (line 12) | const TIBERIUM_COLOR = new THREE.Color("rgb(173, 170, 132)");
constant OVERLAY_COLOR (line 13) | const OVERLAY_COLOR = new THREE.Color(0);
class MinimapModel (line 14) | class MinimapModel {
method constructor (line 25) | constructor(tiles: any, tileOccupation: any, shroud: MapShroud | undef...
method computeAllColors (line 38) | computeAllColors(): void {
method updateColors (line 41) | updateColors(tiles: any[]): void {
method getTileColor (line 107) | getTileColor(tile: any): string {
FILE: src/engine/renderable/entity/map/MinimapRenderer.ts
type DxySize (line 2) | interface DxySize {
type CanvasSize (line 8) | interface CanvasSize {
type Point (line 12) | interface Point {
class MinimapRenderer (line 16) | class MinimapRenderer {
method constructor (line 25) | constructor(map: any, minimapModel: any, size: CanvasSize, borderColor...
method computeCanvasSize (line 40) | private computeCanvasSize(size: CanvasSize, aspectRatio: number): Canv...
method renderFull (line 57) | public renderFull(): HTMLCanvasElement {
method renderIncremental (line 75) | public renderIncremental(tiles: any[]): void {
method renderTiles (line 83) | private renderTiles(tiles: Set<any> | any[], isFullRender: boolean = f...
method tileToLocalRxyOrigin (line 106) | private tileToLocalRxyOrigin(tile: any): Point {
method dxyToLocalRxy (line 113) | private dxyToLocalRxy(x: number, y: number): Point {
method dxyToCanvas (line 119) | public dxyToCanvas(x: number, y: number): Point {
method canvasToDxy (line 126) | public canvasToDxy(x: number, y: number): Point {
FILE: src/engine/renderable/entity/plugin/ChronoSparkleFxPlugin.ts
class ChronoSparkleFxPlugin (line 2) | class ChronoSparkleFxPlugin {
method constructor (line 10) | constructor(gameObject: any, sparkleAnimName: string) {
method onCreate (line 15) | onCreate(renderableManager: any): void {
method update (line 18) | update(): void {
method onRemove (line 46) | onRemove(): void {
method dispose (line 50) | dispose(): void { }
FILE: src/engine/renderable/entity/plugin/DamageSmokePlugin.ts
class DamageSmokePlugin (line 2) | class DamageSmokePlugin {
method constructor (line 12) | constructor(gameObject: any, art: any, theater: any, imageFinder: any,...
method onCreate (line 19) | onCreate(renderableManager: any): void {
method update (line 22) | update(time: number): void {
method disposeSmokeFx (line 52) | private disposeSmokeFx(): void {
method onRemove (line 58) | onRemove(): void {
method dispose (line 62) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/HarvesterPlugin.ts
class HarvesterPlugin (line 3) | class HarvesterPlugin {
method constructor (line 9) | constructor(gameObject: any, harvesterTrait: any) {
method onCreate (line 13) | onCreate(renderableManager: any): void {
method update (line 16) | update(time: number): void {
method disposeHarvAnim (line 44) | private disposeHarvAnim(): void {
method onRemove (line 49) | onRemove(): void {
method dispose (line 52) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/InfantryDisguisePlugin.ts
class InfantryDisguisePlugin (line 2) | class InfantryDisguisePlugin {
method constructor (line 14) | constructor(gameObject: any, disguiseTrait: any, localPlayer: any, all...
method onCreate (line 23) | onCreate(): void { }
method update (line 24) | update(time: number): void {
method onRemove (line 62) | onRemove(): void { }
method getUiNameOverride (line 63) | getUiNameOverride(): string | undefined {
method dispose (line 70) | dispose(): void { }
FILE: src/engine/renderable/entity/plugin/MindControlLinkPlugin.ts
class MindControlLinkPlugin (line 3) | class MindControlLinkPlugin {
method constructor (line 10) | constructor(source: any, selectionModel: any, alliances: any, viewer: ...
method onCreate (line 17) | onCreate(renderableManager: any): void {
method update (line 20) | update(): void {
method onRemove (line 52) | onRemove(): void {
method dispose (line 56) | dispose(): void {
method disposeLinks (line 59) | private disposeLinks(): void {
FILE: src/engine/renderable/entity/plugin/MoveSoundFxPlugin.ts
class MoveSoundFxPlugin (line 2) | class MoveSoundFxPlugin {
method constructor (line 8) | constructor(gameObject: any, moveSound: any, worldSound: any) {
method onCreate (line 13) | onCreate(): void { }
method update (line 14) | update(): void {
method onRemove (line 38) | onRemove(): void {
method dispose (line 41) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/ObjectCloakPlugin.ts
class ObjectCloakPlugin (line 1) | class ObjectCloakPlugin {
method constructor (line 8) | constructor(gameObject: any, localPlayer: any, alliances: any, rendera...
method onCreate (line 14) | onCreate(): void { }
method update (line 15) | update(time: number): void {
method onRemove (line 27) | onRemove(): void { }
method dispose (line 28) | dispose(): void { }
FILE: src/engine/renderable/entity/plugin/ShipWakeTrailPlugin.ts
class ShipWakeTrailPlugin (line 7) | class ShipWakeTrailPlugin {
method constructor (line 20) | constructor(gameObject: any, rules: any, art: any, theater: any, image...
method onCreate (line 29) | onCreate(renderableManager: any): void {
method update (line 32) | update(time: number): void {
method onRemove (line 73) | onRemove(): void {
method dispose (line 77) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/TntFxPlugin.ts
class TntFxPlugin (line 3) | class TntFxPlugin {
method constructor (line 19) | constructor(gameObject: any, tntChargeTrait: any, frameDurationTicks: ...
method onCreate (line 31) | onCreate(): void {
method update (line 34) | update(time: number): void {
method disposeBombAnim (line 83) | private disposeBombAnim(): void {
method onRemove (line 89) | onRemove(): void {
method dispose (line 93) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/TrailerSmokePlugin.ts
class TrailerSmokePlugin (line 3) | class TrailerSmokePlugin {
method constructor (line 12) | constructor(gameObject: any, art: any, theater: any, imageFinder: any,...
method onCreate (line 19) | onCreate(renderableManager: any): void {
method update (line 23) | update(time: number): void {
method onRemove (line 60) | onRemove(): void {
method dispose (line 64) | dispose(): void {
FILE: src/engine/renderable/entity/plugin/VehicleDisguisePlugin.ts
constant FADE_OUT_MS (line 7) | const FADE_OUT_MS = 200;
constant FADE_IN_MS (line 8) | const FADE_IN_MS = 200;
constant BLINK_TREE_MS (line 10) | const BLINK_TREE_MS = 3000;
constant BLINK_TANK_MS (line 11) | const BLINK_TANK_MS = 1500;
class VehicleDisguisePlugin (line 13) | class VehicleDisguisePlugin {
method constructor (line 43) | constructor(gameObject: any, disguiseTrait: any, localPlayer: any, all...
method onCreate (line 58) | onCreate(): void { }
method update (line 60) | update(time: number): void {
method ensureDisguiseObj (line 170) | private ensureDisguiseObj(): void {
method setMainVehicleOpacity (line 179) | private setMainVehicleOpacity(opacity: number): void {
method createDisguiseObj (line 193) | private createDisguiseObj(disguise: any): THREE.Object3D {
method updateLighting (line 217) | updateLighting(): void {
method onRemove (line 232) | onRemove(): void {
method getUiNameOverride (line 240) | getUiNameOverride(): string | undefined {
method shouldDisableHighlight (line 247) | shouldDisableHighlight(): boolean {
method dispose (line 252) | dispose(): void {
FILE: src/engine/renderable/entity/unit/BlobShadow.ts
class BlobShadow (line 6) | class BlobShadow {
method constructor (line 18) | constructor(private gameObject: any, private radius: number, private u...
method get3DObject (line 19) | get3DObject(): THREE.Mesh | BatchedMesh | undefined {
method create3DObject (line 22) | create3DObject(): void {
method update (line 34) | update(_: any, __: any): void {
method dispose (line 63) | dispose(): void { }
FILE: src/engine/renderable/entity/unit/DebugLabel.ts
class DebugLabel (line 5) | class DebugLabel {
method constructor (line 8) | constructor(private text: string, private color: string, private camer...
method get3DObject (line 9) | get3DObject(): THREE.Mesh | undefined {
method create3DObject (line 12) | create3DObject(): void {
method createMesh (line 22) | private createMesh(texture: THREE.Texture): THREE.Mesh {
method createTexture (line 40) | private createTexture(text: string, color: string, outlineColor: strin...
method update (line 76) | update(): void { }
method dispose (line 77) | dispose(): void {
FILE: src/engine/renderable/entity/unit/ExtraLightHelper.ts
class ExtraLightHelper (line 2) | class ExtraLightHelper {
method multiplyShp (line 3) | static multiplyShp(target: THREE.Color, source: THREE.Color, intensity...
method multiplyVxl (line 6) | static multiplyVxl(target: THREE.Color, source: THREE.Color, intensity...
FILE: src/engine/renderable/entity/unit/FlyerHelperMode.ts
type FlyerHelperMode (line 1) | enum FlyerHelperMode {
FILE: src/engine/renderable/entity/unit/ModelQuality.ts
type ModelQuality (line 1) | enum ModelQuality {
FILE: src/engine/renderable/entity/unit/RotorHelper.ts
class RotorHelper (line 4) | class RotorHelper {
method computeRotationStep (line 5) | static computeRotationStep(entity: {
FILE: src/engine/renderable/entity/unit/ShadowQuality.ts
type ShadowQuality (line 1) | enum ShadowQuality {
FILE: src/engine/renderable/fx/DamageSmokeFx.ts
constant PARTICLE_COUNT (line 6) | const PARTICLE_COUNT = 1000;
class DamageSmokeFx (line 7) | class DamageSmokeFx {
method clearTextureCache (line 23) | static clearTextureCache() {
method constructor (line 27) | constructor(gameObject: any, smokeArt: any, shpFile: any, palette: any...
method setContainer (line 36) | setContainer(container: any) {
method create3DObject (line 39) | create3DObject() {
method computeEmitterPosition (line 94) | computeEmitterPosition() {
method get3DObject (line 99) | get3DObject() {
method update (line 102) | update(timeMillis: number) {
method finishAndRemove (line 129) | finishAndRemove() {
method dispose (line 132) | dispose() {
FILE: src/engine/renderable/fx/DetectionLineFx.ts
type Camera (line 5) | interface Camera {
type Container (line 10) | interface Container {
class DetectionLineFx (line 14) | class DetectionLineFx {
method constructor (line 31) | constructor(camera: Camera, sourcePos: THREE.Vector3, targetPos: THREE...
method setContainer (line 47) | setContainer(container: Container): void {
method get3DObject (line 50) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 53) | create3DObject(): void {
method update (line 66) | update(timeMillis: number): void {
method createLineMesh (line 93) | private createLineMesh(): THREE.Mesh {
method createLineGeometry (line 100) | private createLineGeometry(sourcePos: THREE.Vector3, targetPos: THREE....
method createLineMaterial (line 109) | private createLineMaterial(color: THREE.Color, distance: number): Mesh...
method createLineHead (line 120) | private createLineHead(): THREE.Mesh {
method computeDashArray (line 127) | private computeDashArray(distance: number): number {
method computeResolution (line 130) | private computeResolution(camera: Camera): THREE.Vector2 {
method remove (line 133) | remove(): void {
method dispose (line 136) | dispose(): void {
FILE: src/engine/renderable/fx/Effect.ts
class Effect (line 1) | class Effect {
FILE: src/engine/renderable/fx/LaserFx.ts
type Container (line 5) | interface Container {
class LaserFx (line 8) | class LaserFx {
method constructor (line 19) | constructor(camera: THREE.Camera, sourcePos: THREE.Vector3, targetPos:...
method setContainer (line 27) | setContainer(container: Container): void {
method get3DObject (line 30) | get3DObject(): THREE.Mesh | undefined {
method create3DObject (line 33) | create3DObject(): void {
method update (line 39) | update(timeMillis: number): void {
method createObject (line 51) | private createObject(): THREE.Mesh {
method isFinished (line 70) | private isFinished(): boolean {
method dispose (line 73) | dispose(): void {
FILE: src/engine/renderable/fx/LineTrailFx.ts
type GameSpeed (line 6) | interface GameSpeed {
type Container (line 9) | interface Container {
class LineTrailFx (line 12) | class LineTrailFx {
method constructor (line 31) | constructor(lazyTarget: () => THREE.Object3D | undefined, trailColor: ...
method setContainer (line 38) | setContainer(container: Container): void {
method get3DObject (line 41) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 44) | create3DObject(): void {
method update (line 50) | update(timeMillis: number): void {
method createTrail (line 90) | private createTrail(color: THREE.Color, decrement: number): THREE.Mesh...
method isFinished (line 118) | isFinished(): boolean {
method requestFinishAndDispose (line 121) | requestFinishAndDispose(): void {
method stopTracking (line 125) | stopTracking(): void {
method dispose (line 131) | dispose(): void {
method resolveTargetPosition (line 139) | private resolveTargetPosition(): THREE.Vector3 | undefined {
method updateTrailGeometry (line 151) | private updateTrailGeometry(currentTargetPosition: THREE.Vector3): void {
method flattenPoints (line 176) | private flattenPoints(points: THREE.Vector3[]): number[] {
method computeCameraHash (line 179) | private computeCameraHash(): string {
method computeResolution (line 183) | private computeResolution(): THREE.Vector2 {
method getGameSpeedValue (line 186) | private getGameSpeedValue(): number {
FILE: src/engine/renderable/fx/MeshLineResolution.ts
type MeshLineCamera (line 3) | interface MeshLineCamera extends THREE.Camera {
function setMeshLineViewportResolution (line 14) | function setMeshLineViewportResolution(camera: MeshLineCamera, width: nu...
function getMeshLineResolution (line 17) | function getMeshLineResolution(camera: MeshLineCamera): THREE.Vector2 {
FILE: src/engine/renderable/fx/MindControlLinkFx.ts
class MindControlLinkFx (line 3) | class MindControlLinkFx {
method constructor (line 12) | constructor(sourcePos: THREE.Vector3, targetPos: THREE.Vector3, color:...
method setContainer (line 18) | setContainer(container: any): void {
method get3DObject (line 21) | get3DObject(): THREE.Line | undefined {
method create3DObject (line 24) | create3DObject(): void {
method updateEndpoints (line 30) | updateEndpoints(sourcePos: THREE.Vector3, targetPos: THREE.Vector3): v...
method update (line 39) | update(timeMillis: number): void {
method createObject (line 49) | private createObject(): THREE.Line {
method createLineGeometry (line 59) | private createLineGeometry(source: THREE.Vector3, target: THREE.Vector...
method removeAndDispose (line 88) | removeAndDispose(): void {
method dispose (line 92) | dispose(): void {
FILE: src/engine/renderable/fx/RadBeamFx.ts
class RadBeamFx (line 6) | class RadBeamFx {
method constructor (line 18) | constructor(camera: THREE.Camera, sourcePos: THREE.Vector3, targetPos:...
method setContainer (line 26) | setContainer(container: any): void {
method get3DObject (line 29) | get3DObject(): THREE.Mesh | undefined {
method create3DObject (line 32) | create3DObject(): void {
method update (line 38) | update(timeMillis: number): void {
method createObject (line 54) | private createObject(): THREE.Mesh {
method createLineGeometry (line 67) | private createLineGeometry(sourcePos: THREE.Vector3, targetPos: THREE....
method isFinished (line 82) | private isFinished(): boolean {
method dispose (line 85) | dispose(): void {
FILE: src/engine/renderable/fx/RallyPointFx.ts
type Camera (line 5) | interface Camera extends THREE.Camera {
type Container (line 10) | interface Container {
class RallyPointFx (line 13) | class RallyPointFx {
method constructor (line 27) | constructor(camera: Camera, sourcePos: THREE.Vector3, targetPos: THREE...
method setContainer (line 35) | setContainer(container: Container): void {
method get3DObject (line 38) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 41) | create3DObject(): void {
method update (line 55) | update(currentTime: number): void {
method createLineMesh (line 109) | private createLineMesh(): THREE.Mesh {
method createLineShadowMesh (line 118) | private createLineShadowMesh(): THREE.Mesh {
method createShadowLineGeometry (line 125) | private createShadowLineGeometry(sourcePos: THREE.Vector3, targetPos: ...
method createLineGeometry (line 129) | private createLineGeometry(sourcePos: THREE.Vector3, targetPos: THREE....
method createLineMaterial (line 138) | private createLineMaterial(color: THREE.Color, distance: number): Mesh...
method computeDashArray (line 149) | private computeDashArray(distance: number): number {
method computeResolution (line 152) | private computeResolution(camera: Camera): THREE.Vector2 {
method remove (line 155) | remove(): void {
method dispose (line 160) | dispose(): void {
FILE: src/engine/renderable/fx/SparkFx.ts
class SparkFx (line 5) | class SparkFx {
method constructor (line 22) | constructor(pos: THREE.Vector3, color: THREE.Color, spawnDurationSecon...
method setContainer (line 31) | setContainer(container: any): void {
method create3DObject (line 34) | create3DObject(): void {
method get3DObject (line 69) | get3DObject(): THREE.Object3D | undefined {
method update (line 72) | update(timeMillis: number): void {
method dispose (line 95) | dispose(): void {
FILE: src/engine/renderable/fx/TeslaFx.ts
type TeslaBoltRuntime (line 3) | type TeslaBoltRuntime = {
class TeslaFx (line 10) | class TeslaFx {
method constructor (line 22) | constructor(sourcePos: THREE.Vector3, targetPos: THREE.Vector3, primar...
method setContainer (line 31) | setContainer(container: any): void {
method get3DObject (line 34) | get3DObject(): THREE.Object3D | undefined {
method create3DObject (line 37) | create3DObject(): void {
method update (line 56) | update(timeMillis: number): void {
method createBolt (line 73) | private createBolt(color: number): {
method isFinished (line 123) | isFinished(): boolean {
method dispose (line 126) | dispose(): void {
FILE: src/engine/renderable/fx/TrailerSmokeFx.ts
type SmokeArt (line 6) | interface SmokeArt {
type ShpFile (line 13) | interface ShpFile {
type GameSpeed (line 18) | interface GameSpeed {
type Container (line 21) | interface Container {
type GroupConfig (line 25) | interface GroupConfig {
type EmitterConfig (line 38) | interface EmitterConfig {
class Group (line 60) | class Group {
class Emitter (line 66) | class Emitter {
constant MAX_PARTICLES (line 76) | const MAX_PARTICLES = 1000;
constant PARTICLE_COUNT (line 77) | const PARTICLE_COUNT = 1000;
class TrailerSmokeFx (line 78) | class TrailerSmokeFx {
method clearTextureCache (line 96) | static clearTextureCache(): void {
method constructor (line 100) | constructor(pos: THREE.Vector3, spawnDelayFrames: number, smokeArt: Sm...
method setContainer (line 111) | setContainer(container: Container): void {
method create3DObject (line 114) | create3DObject(): void {
method get3DObject (line 165) | get3DObject(): THREE.Mesh | undefined {
method update (line 168) | update(currentTime: number): void {
method finishAndRemove (line 201) | finishAndRemove(): void {
method disable (line 204) | disable(): void {
method enable (line 207) | enable(): void {
method dispose (line 210) | dispose(): void {
FILE: src/engine/renderable/fx/handler/BeaconFxHandler.ts
type Game (line 5) | interface Game {
type Player (line 20) | interface Player {
type Tile (line 24) | interface Tile {
type Bridge (line 30) | interface Bridge {
type RenderableManager (line 33) | interface RenderableManager {
type Renderer (line 36) | interface Renderer {
type WorldSound (line 43) | interface WorldSound {
type Beacon (line 46) | interface Beacon {
class BeaconFxHandler (line 51) | class BeaconFxHandler {
method constructor (line 62) | constructor(game: Game, localPlayer: {
method init (line 130) | init(): void {
method canPingLocation (line 135) | canPingLocation(player: Player, tile: Tile): boolean {
method dispose (line 141) | dispose(): void {
FILE: src/engine/renderable/fx/handler/ChronoFxHandler.ts
type Game (line 6) | interface Game {
type RenderableManager (line 19) | interface RenderableManager {
type GameObject (line 22) | interface GameObject {
type TeleportEvent (line 39) | interface TeleportEvent {
type DestroyEvent (line 48) | interface DestroyEvent {
class ChronoFxHandler (line 51) | class ChronoFxHandler {
method constructor (line 57) | constructor(game: Game, renderableManager: RenderableManager) {
method init (line 91) | init(): void {
method dispose (line 94) | dispose(): void {
FILE: src/engine/renderable/fx/handler/CrateFxHandler.ts
type Game (line 4) | interface Game {
type RenderableManager (line 11) | interface RenderableManager {
type CratePickupEvent (line 14) | interface CratePickupEvent {
class CrateFxHandler (line 24) | class CrateFxHandler {
method constructor (line 28) | constructor(game: Game, renderableManager: RenderableManager) {
method init (line 33) | init(): void {
method dispose (line 44) | dispose(): void {
FILE: src/engine/renderable/fx/handler/ParasiteSparkFxHandler.ts
type Game (line 7) | interface Game {
type RenderableManager (line 15) | interface RenderableManager {
type GameObject (line 18) | interface GameObject {
type Attacker (line 31) | interface Attacker {
type DamageEvent (line 34) | interface DamageEvent {
class ParasiteSparkFxHandler (line 38) | class ParasiteSparkFxHandler {
method constructor (line 42) | constructor(game: Game, renderableManager: RenderableManager) {
method init (line 60) | init(): void {
method dispose (line 63) | dispose(): void {
FILE: src/engine/renderable/fx/handler/SuperWeaponFxHandler.ts
type Game (line 8) | interface Game {
type Tile (line 35) | interface Tile {
type Bridge (line 40) | interface Bridge {
type RenderableManager (line 43) | interface RenderableManager {
type LightingDirector (line 50) | interface LightingDirector {
type LightningStormEvent (line 53) | interface LightningStormEvent {
type SuperWeaponActivateEvent (line 56) | interface SuperWeaponActivateEvent {
class SuperWeaponFxHandler (line 61) | class SuperWeaponFxHandler {
method constructor (line 68) | constructor(game: Game, renderableManager: RenderableManager, lighting...
method init (line 74) | init(): void {
method createChronoSphereAnim (line 110) | createChronoSphereAnim(tile: Tile): void {
method disposeChronoSphereAnim (line 117) | disposeChronoSphereAnim(): void {
method dispose (line 124) | dispose(): void {
FILE: src/engine/renderable/fx/handler/TriggerActionFxHandler.ts
type Game (line 4) | interface Game {
type RenderableManager (line 11) | interface RenderableManager {
type TriggerAnimEvent (line 14) | interface TriggerAnimEvent {
class TriggerActionFxHandler (line 23) | class TriggerActionFxHandler {
method constructor (line 27) | constructor(game: Game, renderableManager: RenderableManager) {
method init (line 44) | init(): void {
method dispose (line 47) | dispose(): void {
FILE: src/engine/renderable/fx/handler/WarheadDetonateFxHandler.ts
type Game (line 6) | interface Game {
type RenderableManager (line 18) | interface RenderableManager {
type WarheadDetonateEvent (line 21) | interface WarheadDetonateEvent {
class WarheadDetonateFxHandler (line 31) | class WarheadDetonateFxHandler {
method constructor (line 36) | constructor(game: Game, renderableManager: RenderableManager) {
method init (line 61) | init(): void {
method dispose (line 64) | dispose(): void {
FILE: src/engine/renderable/fx/speCompat.ts
function patchShaderSource (line 4) | function patchShaderSource(source: string): string {
function patchShaders (line 9) | function patchShaders(): void {
function patchSpeGroup (line 25) | function patchSpeGroup(group: any): any {
FILE: src/engine/resourceConfigs.ts
type ResourceType (line 2) | enum ResourceType {
type ResourceId (line 27) | type ResourceId = string;
type ResourceConfig (line 28) | interface ResourceConfig {
FILE: src/engine/sound/AudioLoop.ts
type AudioItem (line 2) | interface AudioItem {
type PlayBufferResult (line 11) | interface PlayBufferResult {
type DelayRange (line 19) | interface DelayRange {
class AudioLoop (line 23) | class AudioLoop {
method constructor (line 39) | constructor(audioContext: AudioContext, volume: number, pan: number, r...
method setBuffers (line 59) | setBuffers(buffers: AudioBuffer[]): void {
method start (line 66) | start(startTime: number): void {
method isPlaying (line 76) | isPlaying(): boolean {
method stop (line 79) | stop(): void {
method setVolume (line 96) | setVolume(volume: number): void {
method setPan (line 100) | setPan(pan: number): void {
method add (line 104) | private add(item: AudioItem): void {
method removeCompleted (line 107) | private removeCompleted(): void {
method fill (line 110) | private fill(buffers: AudioBuffer[]): void {
method queueBuffer (line 135) | private queueBuffer(buffer: AudioBuffer, startTime: number): number {
FILE: src/engine/sound/AudioSequence.ts
type AudioItem (line 1) | interface AudioItem {
type PlayBufferResult (line 10) | interface PlayBufferResult {
class AudioSequence (line 18) | class AudioSequence {
method constructor (line 30) | constructor(audioContext: AudioContext, volume: number, pan: number, r...
method setBuffers (line 46) | setBuffers(buffers: AudioBuffer[]): void {
method start (line 53) | start(startTime: number): void {
method isPlaying (line 63) | isPlaying(): boolean {
method stop (line 66) | stop(): void {
method setVolume (line 73) | setVolume(volume: number): void {
method setPan (line 77) | setPan(pan: number): void {
method add (line 81) | private add(item: AudioItem): void {
method removeCompleted (line 84) | private removeCompleted(): void {
method fill (line 87) | private fill(buffers: AudioBuffer[]): void {
method queueBuffer (line 95) | private queueBuffer(buffer: AudioBuffer, startTime: number, delay: num...
FILE: src/engine/sound/AudioSystem.ts
constant SILENT_MP3 (line 6) | const SILENT_MP3 = "data:audio/mpeg;base64,/+MYxAAAAANIAUAAAASEEB/jwOFM/...
type Mixer (line 7) | interface Mixer {
type AudioFile (line 16) | interface AudioFile {
type MusicState (line 20) | interface MusicState {
class AudioSystem (line 25) | class AudioSystem {
method constructor (line 33) | constructor(mixer: Mixer) {
method isInitialized (line 41) | isInitialized(): boolean {
method isSuspended (line 44) | isSuspended(): boolean {
method initialize (line 47) | initialize(): void {
method dispose (line 55) | dispose(): void {
method createChannels (line 70) | private createChannels(audioContext: AudioContext, mixer: Mixer): void {
method getChannel (line 94) | private getChannel(channelType: ChannelType): GainNode {
method setMuted (line 100) | setMuted(muted: boolean): void {
method playWavFile (line 103) | playWavFile(file: AudioFile, channel: ChannelType, volume: number = 1,...
method removeSuspendedSounds (line 111) | private removeSuspendedSounds(): void {
method playWavLoop (line 123) | playWavLoop(files: AudioFile[], channel: ChannelType, volume: number =...
method playWavSequence (line 147) | playWavSequence(files: AudioFile[], channel: ChannelType, volume: numb...
method decodeFile (line 168) | private async decodeFile(file: AudioFile, audioContext: AudioContext):...
method playWavFileAtTime (line 180) | private playWavFileAtTime(file: AudioFile, channel: ChannelType, start...
method playAudioBuffer (line 213) | private playAudioBuffer(handle: InternalPlaybackHandle, buffer: AudioB...
method initMusicLoop (line 233) | async initMusicLoop(): Promise<void> {
method playMusicFile (line 251) | async playMusicFile(file: AudioFile, repeat: boolean, onEnded?: () => ...
method initMusicNode (line 271) | private initMusicNode(): MusicState {
method playOrResumeMusic (line 291) | private async playOrResumeMusic(): Promise<void> {
method stopMusic (line 303) | stopMusic(): void {
FILE: src/engine/sound/ChannelType.ts
type ChannelType (line 1) | enum ChannelType {
FILE: src/engine/sound/Eva.ts
type EvaSpec (line 2) | interface EvaSpec {
type EvaSpecs (line 7) | interface EvaSpecs {
type Sound (line 10) | interface Sound {
type Renderer (line 16) | interface Renderer {
class Eva (line 22) | class Eva {
method constructor (line 29) | constructor(evaSpecs: EvaSpecs, sound: Sound, renderer: Renderer) {
method init (line 53) | init(): void {
method dispose (line 56) | dispose(): void {
method play (line 60) | play(name: string, queue: boolean = false): void {
FILE: src/engine/sound/EvaSpecs.ts
type EvaPriority (line 2) | enum EvaPriority {
type EvaSpec (line 8) | interface EvaSpec {
class EvaSpecs (line 14) | class EvaSpecs {
method constructor (line 17) | constructor(sideType: SideType) {
method readIni (line 20) | readIni(ini: any): EvaSpecs {
method getSpec (line 46) | getSpec(name: string): EvaSpec | undefined {
FILE: src/engine/sound/InternalPlaybackHandle.ts
class InternalPlaybackHandle (line 1) | class InternalPlaybackHandle {
method setNodes (line 10) | setNodes(sourceNode: AudioBufferSourceNode, gainNode: GainNode, panNod...
method isPlaying (line 26) | isPlaying(): boolean {
method stop (line 29) | stop(): void {
method setVolume (line 43) | setVolume(volume: number): void {
method setPan (line 51) | setPan(pan: number): void {
FILE: src/engine/sound/Mixer.ts
class Mixer (line 2) | class Mixer {
method onVolumeChange (line 9) | get onVolumeChange() {
method setVolume (line 12) | setVolume(channel: number, volume: number): void {
method getVolume (line 18) | getVolume(channel: number): number {
method setMuted (line 21) | setMuted(channel: number, muted: boolean): void {
method isMuted (line 25) | isMuted(channel: number): boolean {
method serialize (line 28) | serialize(): string {
method unserialize (line 33) | unserialize(data: string): Mixer {
FILE: src/engine/sound/Music.ts
type MusicType (line 2) | enum MusicType {
type MusicSpec (line 11) | interface MusicSpec {
type MusicSpecs (line 17) | interface MusicSpecs {
type AudioSystem (line 21) | interface AudioSystem {
type AudioFiles (line 25) | interface AudioFiles {
class Music (line 28) | class Music {
method constructor (line 38) | constructor(audioSystem: AudioSystem, audioFiles: AudioFiles, musicSpe...
method unserializeOptions (line 43) | unserializeOptions(data: string): void {
method serializeOptions (line 49) | serializeOptions(): string {
method getShuffleMode (line 58) | getShuffleMode(): boolean {
method getRepeatMode (line 61) | getRepeatMode(): boolean {
method getPlaylist (line 64) | getPlaylist(): MusicSpec[] {
method getCurrentPlaylistItem (line 67) | getCurrentPlaylistItem(): MusicSpec | undefined {
method dispose (line 72) | dispose(): void {
method getMusicSpec (line 75) | private getMusicSpec(name: string): MusicSpec | undefined {
method play (line 86) | async play(type: MusicType): Promise<void> {
method stopPlaying (line 117) | stopPlaying(): void {
method setShuffleMode (line 121) | setShuffleMode(shuffle: boolean): void {
method setRepeatMode (line 133) | setRepeatMode(repeat: boolean): void {
method playSpec (line 136) | private async playSpec(spec: MusicSpec, onEnded?: () => void): Promise...
method getMp3File (line 143) | private async getMp3File(name: string): Promise<any> {
method buildPlaylist (line 169) | private buildPlaylist(shuffle: boolean): MusicSpec[] {
method shufflePlaylist (line 176) | private shufflePlaylist(playlist: MusicSpec[]): MusicSpec[] {
method advancePlaylist (line 184) | private async advancePlaylist(): Promise<void> {
method selectPlaylistItem (line 190) | async selectPlaylistItem(item: MusicSpec): Promise<void> {
FILE: src/engine/sound/MusicSpecs.ts
type MusicSpec (line 1) | interface MusicSpec {
class MusicSpecs (line 7) | class MusicSpecs {
method constructor (line 10) | constructor(ini: any) {
method parse (line 14) | private parse(): void {
method getSpec (line 39) | getSpec(name: string): MusicSpec | undefined {
method getAll (line 42) | getAll(): MusicSpec[] {
FILE: src/engine/sound/Sound.ts
type AudioVisualRules (line 6) | interface AudioVisualRules {
type AudioFiles (line 11) | interface AudioFiles {
type SoundSpec (line 14) | interface SoundSpec {
type AudioSystem (line 32) | interface AudioSystem {
type PlaybackHandle (line 42) | interface PlaybackHandle {
class Sound (line 46) | class Sound {
method constructor (line 53) | constructor(audioSystem: AudioSystem, audioFiles: AudioFiles, soundSpe...
method initialize (line 78) | initialize(): void {
method dispose (line 82) | dispose(): void {
method getSoundKey (line 86) | private getSoundKey(key: SoundKey | string): string | undefined {
method getSoundSpec (line 98) | private getSoundSpec(key: SoundKey | string): SoundSpec | undefined {
method play (line 110) | play(key: SoundKey | string, channel: ChannelType): PlaybackHandle | u...
method playWithOptions (line 119) | private playWithOptions(spec: SoundSpec, channel: ChannelType, volume:...
method buildAttackDecaySequence (line 177) | private buildAttackDecaySequence(spec: SoundSpec, hasAttack: boolean, ...
method getWavFile (line 198) | private getWavFile(soundName: string): any {
method cleanOldHandles (line 205) | private cleanOldHandles(): void {
FILE: src/engine/sound/SoundKey.ts
type SoundKey (line 1) | enum SoundKey {
FILE: src/engine/sound/SoundSpec.ts
type MinMaxPair (line 2) | interface MinMaxPair {
type SoundDefaults (line 6) | interface SoundDefaults {
class SoundSpec (line 14) | class SoundSpec {
method read (line 30) | read(section: any, defaults: SoundDefaults): SoundSpec {
method createMinMaxPair (line 62) | private createMinMaxPair(values: number[]): MinMaxPair | undefined {
FILE: src/engine/sound/SoundSpecs.ts
type SoundType (line 2) | enum SoundType {
type SoundPriority (line 11) | enum SoundPriority {
type SoundControl (line 18) | enum SoundControl {
class SoundSpecs (line 28) | class SoundSpecs {
method constructor (line 32) | constructor(ini: any) {
method parse (line 37) | private parse(): void {
method getSpec (line 70) | getSpec(name: string): SoundSpec | undefined {
method getAll (line 73) | getAll(): SoundSpec[] {
FILE: src/engine/sound/WorldSound.ts
type WorldPosition (line 10) | interface WorldPosition {
type GameObject (line 15) | interface GameObject {
type SoundSpec (line 20) | interface SoundSpec {
type PlaybackHandle (line 34) | interface PlaybackHandle {
type Sound (line 40) | interface Sound {
type Player (line 44) | interface Player {
type Shroud (line 46) | interface Shroud {
type WorldViewportHelper (line 49) | interface WorldViewportHelper {
type MapTileIntersectHelper (line 56) | interface MapTileIntersectHelper {
type World (line 65) | interface World {
type WorldScene (line 71) | interface WorldScene {
type Renderer (line 79) | interface Renderer {
type SoundInstance (line 85) | interface SoundInstance {
class WorldSound (line 95) | class WorldSound {
method constructor (line 126) | constructor(sound: Sound, localPlayer: Player, shroud: Shroud, worldVi...
method init (line 165) | init(): void {
method changeLocalPlayer (line 169) | changeLocalPlayer(player: Player, shroud: Shroud): void {
method dispose (line 173) | dispose(): void {
method update (line 178) | private update(): void {
method updateLegacy (line 183) | private updateLegacy(): void {
method updateOptimized (line 213) | private updateOptimized(): void {
method cleanOldInstances (line 242) | private cleanOldInstances(): void {
method playEffect (line 245) | playEffect(key: SoundKey | string, target: GameObject | WorldPosition,...
method computeVolumeAndPan (line 297) | private computeVolumeAndPan(spec: SoundSpec, worldPos: WorldPosition, ...
FILE: src/engine/type/LightingType.ts
type LightingType (line 1) | enum LightingType {
FILE: src/engine/type/ObjectType.ts
type ObjectType (line 1) | enum ObjectType {
FILE: src/engine/type/OverlayTibType.ts
type OverlayTibType (line 1) | enum OverlayTibType {
FILE: src/engine/type/PaletteType.ts
type PaletteType (line 1) | enum PaletteType {
FILE: src/engine/type/PointerType.ts
type PointerType (line 1) | enum PointerType {
FILE: src
Condensed preview — 1289 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,748K chars).
[
{
"path": ".gitignore",
"chars": 1984,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 5365,
"preview": "# RA2WEB React\n\n免责声明:这是基于《时空分裂》中文版RA2WEB www.ra2web.com 的分析而开发,并意图基于最新的react和three版本进行重构。\n\n但项目所有权利(包括收益权)归《时空分裂》/RA2WEB负"
},
{
"path": "index.html",
"chars": 881,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>网页红井-联机对战平台</title>\n <meta name=\"ke"
},
{
"path": "package.json",
"chars": 3388,
"preview": "{\n \"name\": \"redalert2-web\",\n \"private\": true,\n \"version\": \"0.0.0\",\n \"type\": \"module\",\n \"packageManager\": \"bun@1.3.1"
},
{
"path": "public/config.ini",
"chars": 557,
"preview": "[General]\ndiscordUrl=https://discord.com\ncsfFile = general.csf\n\n# Where game resources are located\ngameresBaseUrl=/cdn/g"
},
{
"path": "public/css/main-legacy.css",
"chars": 72504,
"preview": "html, body {\n height: 100%;\n}\n\nbody {\n margin: 0;\n padding: env(safe-area-inset-top) env(safe-area-inset-right)"
},
{
"path": "public/mods.ini",
"chars": 837,
"preview": "[General]\n1=athse\n2=gonghui\n3=meisuzhenba\n\n[gonghui]\nID=gonghui\nName=共和国之辉\nDescription=风靡全球的低质量MOD移植到网页平台,更多平衡性提高!\nAutho"
},
{
"path": "public/other/file-explorer.css",
"chars": 34670,
"preview": ".fe_fileexplorer_hidden { display: none !important; }\n.fe_fileexplorer_invisible { visibility: hidden; }\n.fe_fileexplore"
},
{
"path": "public/res/fonts/fonts.css",
"chars": 7344,
"preview": "/* Generated from https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:wght@500;600;700&display=swap */\r\n\r\n/* cy"
},
{
"path": "public/res/locale/en-US.json",
"chars": 24291,
"preview": "{\r\n \"gui:ok\": \"OK\",\r\n \"txt_copyright\": \"© 2000 ELECTRONIC ARTS INC. ALL RIGHTS RESERVED\",\r\n \"gui:wwbrand\": \"WES"
},
{
"path": "public/res/locale/zh-CN.json",
"chars": 16028,
"preview": "{\n \"gui:ok\": \"确定\",\n \"txt_copyright\": \"© 2025 网页红井制作组保留渲染引擎和联机服务的权利\",\n \"gui:wwbrand\": \"美术素材版权为EA所有,目前正在逐步替换中\",\n "
},
{
"path": "public/servers.ini",
"chars": 586,
"preview": "[am-eu]\nlabel=\"Americas & Europe\"\navailable=yes\ngameVersion=0.65.1\nwolUrl=\"wss://wol-eu1.chronodivide.com\"\napiRegUrl=\"ht"
},
{
"path": "src/App.tsx",
"chars": 3282,
"preview": "import { useEffect, useRef, useState } from 'react';\nimport { Application, SplashScreenUpdateCallback } from './Applicat"
},
{
"path": "src/Application.ts",
"chars": 59341,
"preview": "import { BoxedVar } from './util/BoxedVar';\nimport { EventDispatcher } from './util/event';\nimport { Routing } from './u"
},
{
"path": "src/BattleControlApi.ts",
"chars": 1568,
"preview": "declare const THREE: any;\ninterface WorldInteraction {\n customScrollHandler: {\n requestScroll(vector: any): vo"
},
{
"path": "src/ClientApi.ts",
"chars": 205,
"preview": "import { BattleControlApi } from './BattleControlApi';\nexport class ClientApi {\n public battleControl: BattleControlA"
},
{
"path": "src/Config.ts",
"chars": 5733,
"preview": "import { IniFile } from './data/IniFile';\nimport { IniSection } from './data/IniSection';\ninterface ViewportConfig {\n "
},
{
"path": "src/ConsoleVars.ts",
"chars": 1783,
"preview": "import { BoxedVar } from './util/BoxedVar';\nexport class ConsoleVars {\n public readonly debugWireframes: BoxedVar<boo"
},
{
"path": "src/ErrorHandler.ts",
"chars": 971,
"preview": "interface MessageBoxApi {\n show(message: string, buttonText?: string, callback?: () => void): void;\n}\ninterface Strin"
},
{
"path": "src/Gui.ts",
"chars": 36916,
"preview": "import { Renderer } from './engine/gfx/Renderer.js';\nimport { UiScene } from './gui/UiScene.js';\nimport { JsxRenderer } "
},
{
"path": "src/LocalPrefs.ts",
"chars": 2732,
"preview": "export enum StorageKey {\n GameRes = \"_r_gameRes\",\n Options = \"_r_opts_v3\",\n Mixer = \"_r_mixer_v3\",\n MusicOpt"
},
{
"path": "src/RouteHelper.ts",
"chars": 817,
"preview": "import { Base64 } from '@/util/Base64';\ninterface GameParams {\n gameId: string;\n gameTimestamp: number;\n gservU"
},
{
"path": "src/data/AudioBagFile.ts",
"chars": 3923,
"preview": "import { DataStream } from \"./DataStream\";\nimport { VirtualFile } from \"./vfs/VirtualFile\";\nimport type { IdxFile } from"
},
{
"path": "src/data/Bitmap.ts",
"chars": 4410,
"preview": "export enum PixelFormat {\n Rgb = 1,\n Rgba = 2,\n Indexed = 3\n}\nfunction getBytesPerPixel(format: PixelFormat): n"
},
{
"path": "src/data/Crc32.ts",
"chars": 4350,
"preview": "export class Crc32 {\n private static readonly lookUp: Uint32Array = new Uint32Array([\n 0, 1996959894, 39939197"
},
{
"path": "src/data/CsfFile.ts",
"chars": 7900,
"preview": "import { DataStream } from './DataStream';\nimport { VirtualFile } from './vfs/VirtualFile';\nconst strwChars = Array.from"
},
{
"path": "src/data/DataStream.ts",
"chars": 19993,
"preview": "type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64A"
},
{
"path": "src/data/HvaFile.ts",
"chars": 2189,
"preview": "import { Section } from './hva/Section';\nimport type { VirtualFile } from './vfs/VirtualFile';\nimport type { DataStream "
},
{
"path": "src/data/IdxEntry.ts",
"chars": 221,
"preview": "export class IdxEntry {\n public filename: string = \"\";\n public offset: number = 0;\n public length: number = 0;\n"
},
{
"path": "src/data/IdxFile.ts",
"chars": 1580,
"preview": "import { DataStream } from \"./DataStream\";\nimport { IdxEntry } from \"./IdxEntry\";\nexport class IdxFile {\n public entr"
},
{
"path": "src/data/IniFile.ts",
"chars": 3360,
"preview": "import { IniSection } from './IniSection';\nimport { IniParser } from './IniParser';\nimport { VirtualFile } from './vfs/V"
},
{
"path": "src/data/IniParser.ts",
"chars": 3168,
"preview": "import { IniSection } from './IniSection';\nexport class IniParser {\n private readonly lineRegex = /^\\s*\\[([^\\]]+)\\]\\s"
},
{
"path": "src/data/IniSection.ts",
"chars": 11812,
"preview": "export class IniSection {\n public entries: Map<string, string | string[]>;\n public sections: Map<string, IniSectio"
},
{
"path": "src/data/MapFile.ts",
"chars": 16084,
"preview": "import * as mapObjects from \"@/data/MapObjects\";\nimport { IniFile } from \"@/data/IniFile\";\nimport { TheaterType } from \""
},
{
"path": "src/data/MapObjects.ts",
"chars": 2098,
"preview": "import { ObjectType } from \"@/engine/type/ObjectType\";\nexport class MapObject {\n type: ObjectType;\n constructor(ty"
},
{
"path": "src/data/MixEntry.ts",
"chars": 2288,
"preview": "import { binaryStringToUint8Array } from '../util/string';\nimport { Crc32 } from './Crc32';\nexport class MixEntry {\n "
},
{
"path": "src/data/MixFile.ts",
"chars": 4041,
"preview": "import { DataStream } from \"./DataStream\";\nimport { Blowfish } from \"./encoding/Blowfish\";\nimport { BlowfishKey } from \""
},
{
"path": "src/data/Mp3File.ts",
"chars": 1717,
"preview": "import type { VirtualFile } from \"./vfs/VirtualFile\";\nimport type { DataStream } from \"./DataStream\";\nexport class Mp3Fi"
},
{
"path": "src/data/Palette.ts",
"chars": 3689,
"preview": "import { Color } from \"../util/Color\";\nimport { fnv32a } from \"../util/math\";\nimport { VirtualFile } from \"./vfs/Virtual"
},
{
"path": "src/data/PcxFile.ts",
"chars": 2220,
"preview": "import PcxJs from '@ra2web/pcxfile';\nimport { CanvasUtils } from '../engine/gfx/CanvasUtils';\nimport type { VirtualFile "
},
{
"path": "src/data/ShpFile.ts",
"chars": 8154,
"preview": "import { Format3 } from \"./encoding/Format3\";\nimport { ShpImage } from \"./ShpImage\";\nimport { VirtualFile } from \"./vfs/"
},
{
"path": "src/data/ShpImage.ts",
"chars": 1447,
"preview": "export class ShpImage {\n public width: number;\n public height: number;\n public x: number;\n public y: number;"
},
{
"path": "src/data/Strings.ts",
"chars": 1859,
"preview": "import { CsfFile } from './CsfFile';\nimport { sprintf } from 'sprintf-js';\nexport class Strings {\n private data: {\n "
},
{
"path": "src/data/TmpFile.ts",
"chars": 1652,
"preview": "import { TmpImage } from \"./TmpImage\";\nimport { VirtualFile } from \"./vfs/VirtualFile\";\nimport { DataStream } from \"./Da"
},
{
"path": "src/data/TmpImage.ts",
"chars": 3104,
"preview": "import type { DataStream } from \"./DataStream\";\nimport { Color } from \"three\";\nexport enum TmpImageFlags {\n ExtraData"
},
{
"path": "src/data/VxlFile.ts",
"chars": 6410,
"preview": "import { VirtualFile } from '@/data/vfs/VirtualFile';\nimport { Section } from '@/data/vxl/Section';\nimport { VxlHeader }"
},
{
"path": "src/data/WavFile.ts",
"chars": 2506,
"preview": "import { WaveFile } from '@ra2web/wavefile';\nimport type { VirtualFile } from './vfs/VirtualFile';\nimport type { DataStr"
},
{
"path": "src/data/encoding/Blowfish.ts",
"chars": 18765,
"preview": "export class Blowfish {\n private m_p: Uint32Array;\n private m_s: Uint32Array[];\n private static byteSwap32(valu"
},
{
"path": "src/data/encoding/BlowfishKey.ts",
"chars": 13007,
"preview": "const s = \"AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V\";\nconst a = new Int8Array([\n -1, -1, -1, -1, -1, "
},
{
"path": "src/data/encoding/Format3.ts",
"chars": 1716,
"preview": "export class Format3 {\n static decode(sourceData: Uint8Array, width: number, height: number): Uint8Array {\n co"
},
{
"path": "src/data/encoding/Format5.ts",
"chars": 1434,
"preview": "import { Format80 } from './Format80';\nimport { MiniLzo } from './MiniLzo';\nexport class Format5 {\n static decode(inp"
},
{
"path": "src/data/encoding/Format80.ts",
"chars": 3097,
"preview": "import { DataStream } from '../DataStream';\nexport class Format80 {\n static decode(input: Uint8Array, outputSize: num"
},
{
"path": "src/data/encoding/MiniLzo.ts",
"chars": 419,
"preview": "import { lzo1x } from './lzo1x';\nexport class MiniLzo {\n static decompress(input: Uint8Array, outputSize: number): Ui"
},
{
"path": "src/data/encoding/lzo1x.ts",
"chars": 8711,
"preview": "interface LzoState {\n inputBuffer: Uint8Array;\n outputBuffer: Uint8Array | null;\n}\n\ninterface LzoConfig {\n outp"
},
{
"path": "src/data/hva/Section.ts",
"chars": 246,
"preview": "import type { Matrix4 } from 'three';\nexport class Section {\n public name: string = \"\";\n public matrices: Matrix4["
},
{
"path": "src/data/map/MapLighting.ts",
"chars": 1143,
"preview": "export class MapLighting {\n level: number;\n ambient: number;\n red: number;\n green: number;\n blue: number;"
},
{
"path": "src/data/map/MapObjects.ts",
"chars": 1566,
"preview": "import { ObjectType } from \"@/engine/type/ObjectType\";\nexport class MapObject {\n constructor(public type: ObjectType)"
},
{
"path": "src/data/map/SpecialFlags.ts",
"chars": 231,
"preview": "export class SpecialFlags {\n initialVeteran: boolean;\n read(data: {\n getBool: (key: string) => boolean;\n "
},
{
"path": "src/data/map/Variable.ts",
"chars": 246,
"preview": "export class Variable {\n name: string;\n value: any;\n constructor(name: string, value: any) {\n this.name "
},
{
"path": "src/data/map/tag/CellTag.ts",
"chars": 25,
"preview": "export class CellTag {\n}\n"
},
{
"path": "src/data/map/tag/CellTagsReader.ts",
"chars": 964,
"preview": "import { IniSection } from '@/data/IniSection';\nexport class CellTagsReader {\n read(section: IniSection, version: num"
},
{
"path": "src/data/map/tag/Tag.ts",
"chars": 21,
"preview": "export class Tag {\n}\n"
},
{
"path": "src/data/map/tag/TagRepeatType.ts",
"chars": 79,
"preview": "export enum TagRepeatType {\n OnceAny = 0,\n OnceAll = 1,\n Repeat = 2\n}\n"
},
{
"path": "src/data/map/tag/TagsReader.ts",
"chars": 1212,
"preview": "import { TagRepeatType } from './TagRepeatType';\nimport { IniSection } from '@/data/IniSection';\nexport class TagsReader"
},
{
"path": "src/data/map/trigger/Trigger.ts",
"chars": 49,
"preview": "export class Trigger {\n [key: string]: any;\n}\n"
},
{
"path": "src/data/map/trigger/TriggerAction.ts",
"chars": 85,
"preview": "export class TriggerAction {\n constructor() {\n }\n execute(): void {\n }\n}\n"
},
{
"path": "src/data/map/trigger/TriggerActionType.ts",
"chars": 1193,
"preview": "export enum TriggerActionType {\n NoAction = 0,\n FireSale = 9,\n TextTrigger = 11,\n DestroyTrigger = 12,\n C"
},
{
"path": "src/data/map/trigger/TriggerEvent.ts",
"chars": 56,
"preview": "export class TriggerEvent {\n constructor() {\n }\n}\n"
},
{
"path": "src/data/map/trigger/TriggerEventType.ts",
"chars": 1328,
"preview": "export enum TriggerEventType {\n NoEvent = 0,\n EnteredBy = 1,\n SpiedBy = 2,\n AttackedByAny = 6,\n Destroyed"
},
{
"path": "src/data/map/trigger/TriggerReader.ts",
"chars": 7601,
"preview": "import { TriggerEventType } from './TriggerEventType';\nimport { TriggerActionType } from './TriggerActionType';\nimport {"
},
{
"path": "src/data/vfs/Archive.ts",
"chars": 51,
"preview": "export class Archive {\n constructor() {\n }\n}\n"
},
{
"path": "src/data/vfs/FileNotFoundError.ts",
"chars": 326,
"preview": "export class FileNotFoundError extends Error {\n public cause?: Error;\n constructor(message?: string, cause?: Error"
},
{
"path": "src/data/vfs/FileSystem.ts",
"chars": 120,
"preview": "/**\n * FileSystem interface for virtual file system access.\n */\nexport interface FileSystem {\n [key: string]: any;\n}\n"
},
{
"path": "src/data/vfs/IOError.ts",
"chars": 295,
"preview": "export class IOError extends Error {\n public cause?: Error;\n constructor(message: string, cause?: Error) {\n "
},
{
"path": "src/data/vfs/MemArchive.ts",
"chars": 777,
"preview": "import type { VirtualFile } from \"./VirtualFile\";\nexport class MemArchive {\n private entries: Map<string, VirtualFile"
},
{
"path": "src/data/vfs/NameNotAllowedError.ts",
"chars": 407,
"preview": "import { IOError } from \"./IOError\";\nexport class NameNotAllowedError extends IOError {\n constructor(message: string "
},
{
"path": "src/data/vfs/RealFileSystem.ts",
"chars": 3675,
"preview": "import { FileNotFoundError } from \"./FileNotFoundError\";\nimport { RealFileSystemDir } from \"./RealFileSystemDir\";\nimport"
},
{
"path": "src/data/vfs/RealFileSystemDir.ts",
"chars": 11882,
"preview": "import { StorageQuotaError } from \"./StorageQuotaError\";\nimport { equalsIgnoreCase } from \"../../util/string\";\nimport { "
},
{
"path": "src/data/vfs/StorageQuotaError.ts",
"chars": 352,
"preview": "export class StorageQuotaError extends Error {\n public cause?: Error;\n constructor(message: string = \"Storage quot"
},
{
"path": "src/data/vfs/VirtualFile.ts",
"chars": 2214,
"preview": "import { DataStream } from '../DataStream';\nimport { IOError } from './IOError';\nexport class VirtualFile {\n public s"
},
{
"path": "src/data/vfs/VirtualFileSystem.ts",
"chars": 11151,
"preview": "import { AudioBagFile } from \"../AudioBagFile\";\nimport { IdxFile } from \"../IdxFile\";\nimport { MixFile } from \"../MixFil"
},
{
"path": "src/data/vxl/Section.ts",
"chars": 4075,
"preview": "import * as Normals from \"./normals\";\nimport { VoxelField } from \"./VoxelField\";\nimport type { Voxel } from \"./Voxel\";\ni"
},
{
"path": "src/data/vxl/Span.ts",
"chars": 131,
"preview": "import type { Voxel } from './Voxel';\nexport interface Span {\n voxels: Voxel[];\n startIndex: number;\n endIndex:"
},
{
"path": "src/data/vxl/SpanOffsets.ts",
"chars": 55,
"preview": "export class SpanOffsets {\n constructor() {\n }\n}\n"
},
{
"path": "src/data/vxl/Voxel.ts",
"chars": 122,
"preview": "export interface Voxel {\n x: number;\n y: number;\n z: number;\n colorIndex: number;\n normalIndex?: number;\n"
},
{
"path": "src/data/vxl/VoxelField.ts",
"chars": 1562,
"preview": "import type { Voxel } from './Voxel';\nexport class VoxelField {\n public sizeX: number;\n public sizeY: number;\n "
},
{
"path": "src/data/vxl/VxlHeader.ts",
"chars": 801,
"preview": "import type { DataStream } from \"../DataStream\";\nexport class VxlHeader {\n public static readonly size = 32;\n publ"
},
{
"path": "src/data/vxl/normals.ts",
"chars": 19235,
"preview": "import { Vector3 } from 'three';\nexport const normals1: Vector3[] = [\n new Vector3(0.54946297, -183e-6, -0.835518),\n "
},
{
"path": "src/data/zip/Zip.ts",
"chars": 8826,
"preview": "import { Crc32 } from '../Crc32';\nimport { ZipUtils } from './ZipUtils';\ninterface FileRecord {\n name: string;\n si"
},
{
"path": "src/data/zip/ZipUtils.ts",
"chars": 1819,
"preview": "export class ZipUtils {\n static createByteArray(entries: {\n size?: number;\n data: Uint8Array | number |"
},
{
"path": "src/engine/AnimProps.ts",
"chars": 2183,
"preview": "import { IniSection } from '../data/IniSection';\nimport { ShpFile } from '../data/ShpFile';\nimport { GameSpeed } from '."
},
{
"path": "src/engine/Animation.ts",
"chars": 4307,
"preview": "import { AnimProps } from './AnimProps';\nimport { BoxedVar } from '../util/BoxedVar';\nimport { getRandomInt } from '../u"
},
{
"path": "src/engine/AsyncResourceCollection.ts",
"chars": 67,
"preview": "export class AsyncResourceCollection {\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/Engine.ts",
"chars": 23703,
"preview": "import { IniFile } from '../data/IniFile';\nimport { ShpFile } from '../data/ShpFile';\nimport { VxlFile } from '../data/V"
},
{
"path": "src/engine/EngineType.ts",
"chars": 127,
"preview": "export enum EngineType {\n AutoDetect = 0,\n TiberianSun = 1,\n Firestorm = 2,\n RedAlert2 = 3,\n YurisRevenge"
},
{
"path": "src/engine/GameAnimationLoop.ts",
"chars": 8828,
"preview": "import { IrcConnection } from \"@/network/IrcConnection\";\nimport { recordGamePerformanceFrame } from \"@/performance/Perfo"
},
{
"path": "src/engine/ImageFinder.ts",
"chars": 2344,
"preview": "export class MissingImageError extends Error {\n}\nexport class ImageFinder {\n static MissingImageError = MissingImageE"
},
{
"path": "src/engine/IsoCoords.ts",
"chars": 2831,
"preview": "import { Coords } from '../game/Coords';\ninterface Point {\n x: number;\n y: number;\n}\ninterface Point3D extends Poi"
},
{
"path": "src/engine/LazyAsyncResourceCollection.ts",
"chars": 1817,
"preview": "import type { VirtualFile } from '../data/vfs/VirtualFile';\nexport class LazyAsyncResourceCollection<T> {\n private re"
},
{
"path": "src/engine/LazyResourceCollection.ts",
"chars": 2099,
"preview": "import type { VirtualFileSystem } from '../data/vfs/VirtualFileSystem';\nimport type { VirtualFile } from '../data/vfs/Vi"
},
{
"path": "src/engine/Lighting.ts",
"chars": 4337,
"preview": "import { LightingType } from './type/LightingType';\nimport { MapLighting } from '../data/map/MapLighting';\nimport { Even"
},
{
"path": "src/engine/MapDigest.ts",
"chars": 213,
"preview": "import { Crc32 } from \"../data/Crc32\";\nexport class MapDigest {\n static compute(data: {\n getBytes(): Uint8Arra"
},
{
"path": "src/engine/MapList.ts",
"chars": 2357,
"preview": "import { MapManifest } from './MapManifest';\nimport type { GameModes, GameModeEntry } from '../game/ini/GameModes';\nimpo"
},
{
"path": "src/engine/MapManifest.ts",
"chars": 5081,
"preview": "import { IniFile, IniSection } from '../data/IniFile';\nimport type { GameModeEntry } from '../game/ini/GameModes';\nimpor"
},
{
"path": "src/engine/MapSupport.ts",
"chars": 4600,
"preview": "import { MapFile } from \"@/data/MapFile\";\nimport { Strings } from \"@/data/Strings\";\nimport { Rules } from \"@/game/rules/"
},
{
"path": "src/engine/RenderableManager.ts",
"chars": 6800,
"preview": "import { OctreeContainer } from '@/engine/gfx/OctreeContainer';\nimport { World } from '@/game/World';\nimport { WorldScen"
},
{
"path": "src/engine/ResourceCollection.ts",
"chars": 62,
"preview": "export class ResourceCollection {\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/ResourceLoader.ts",
"chars": 8385,
"preview": "import { OperationCanceledError, type CancellationToken } from '@puzzl/core/lib/async/cancellation';\nimport { HttpReques"
},
{
"path": "src/engine/Theater.ts",
"chars": 3698,
"preview": "import { TileSets } from '../game/theater/TileSets';\nimport { PaletteType } from './type/PaletteType';\nimport type { The"
},
{
"path": "src/engine/TheaterType.ts",
"chars": 379,
"preview": "export interface TheaterSettings {\n isoPaletteName: string;\n overlayPaletteName: string;\n unitPaletteName: stri"
},
{
"path": "src/engine/UiAnimationLoop.ts",
"chars": 2945,
"preview": "import { Renderer } from './gfx/Renderer';\nimport { recordUiPerformanceFrame } from '@/performance/PerformanceRuntime';\n"
},
{
"path": "src/engine/animation/Runner.ts",
"chars": 50,
"preview": "export class Runner {\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/animation/SimpleRunner.ts",
"chars": 1546,
"preview": "import { Animation, AnimationState } from '../Animation';\nexport class SimpleRunner {\n animation?: Animation;\n con"
},
{
"path": "src/engine/gameRes/CdnManifest.ts",
"chars": 147,
"preview": "export interface CdnManifest {\n version: number;\n format: string;\n checksums?: Record<string, number | string>;"
},
{
"path": "src/engine/gameRes/CdnResourceLoader.ts",
"chars": 4423,
"preview": "import { DataStream } from '../../data/DataStream';\nimport { Crc32 } from '../../data/Crc32';\nimport { VirtualFile } fro"
},
{
"path": "src/engine/gameRes/FileSystemAccessLib.ts",
"chars": 780,
"preview": "export interface FileSystemAccessAdapterSupport {\n native?: boolean;\n cache?: boolean;\n [key: string]: any;\n}\ne"
},
{
"path": "src/engine/gameRes/FileSystemUtil.ts",
"chars": 4315,
"preview": "import { FileNotFoundError } from '../../data/vfs/FileNotFoundError';\nimport { IOError } from '../../data/vfs/IOError';\n"
},
{
"path": "src/engine/gameRes/GameRes.ts",
"chars": 36753,
"preview": "import { DataStream } from '../../data/DataStream';\nimport { MixFile } from '../../data/MixFile';\nimport { MixEntry } fr"
},
{
"path": "src/engine/gameRes/GameResConfig.ts",
"chars": 1224,
"preview": "import { GameResSource } from './GameResSource';\nexport class GameResConfig {\n private defaultCdnBaseUrl: string;\n "
},
{
"path": "src/engine/gameRes/GameResImporter.ts",
"chars": 29792,
"preview": "import { MixFile } from '../../data/MixFile';\nimport { Engine, EngineType } from '../Engine';\nimport { sleep } from '../"
},
{
"path": "src/engine/gameRes/GameResSource.ts",
"chars": 74,
"preview": "export enum GameResSource {\n Archive = 0,\n Cdn = 1,\n Local = 2\n}\n"
},
{
"path": "src/engine/gameRes/VideoConverter.ts",
"chars": 1662,
"preview": "import type { VirtualFile } from '../../data/vfs/VirtualFile';\nimport type { DataStream } from '../../data/DataStream';\n"
},
{
"path": "src/engine/gameRes/browserFileSystemAccess.ts",
"chars": 711,
"preview": "import {\n getOriginPrivateDirectory,\n polyfillDataTransferItem,\n showDirectoryPicker,\n showOpenFilePicker,\n "
},
{
"path": "src/engine/gameRes/importError/ArchiveDownloadError.ts",
"chars": 366,
"preview": "export class ArchiveDownloadError extends Error {\n public url: string;\n public cause?: any;\n constructor(url: s"
},
{
"path": "src/engine/gameRes/importError/ArchiveExtractionError.ts",
"chars": 198,
"preview": "export class ArchiveExtractionError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n s"
},
{
"path": "src/engine/gameRes/importError/ChecksumError.ts",
"chars": 474,
"preview": "export class ChecksumError extends Error {\n public fileName?: string;\n public expectedChecksum?: string | string[]"
},
{
"path": "src/engine/gameRes/importError/FileNotFoundError.ts",
"chars": 465,
"preview": "export class FileNotFoundError extends Error {\n public fileName?: string;\n constructor(messageOrFileName: string, "
},
{
"path": "src/engine/gameRes/importError/InvalidArchiveError.ts",
"chars": 371,
"preview": "export class InvalidArchiveError extends Error {\n public cause?: any;\n constructor(message: string, options?: {\n "
},
{
"path": "src/engine/gameRes/importError/NoStorageError.ts",
"chars": 204,
"preview": "export class NoStorageError extends Error {\n constructor(message: string = \"No available or functional storage adapte"
},
{
"path": "src/engine/gameRes/importError/NoWebAssemblyError.ts",
"chars": 368,
"preview": "export class NoWebAssemblyError extends Error {\n public cause?: any;\n constructor(message: string, options?: {\n "
},
{
"path": "src/engine/gfx/BufferGeometryUtils.ts",
"chars": 10386,
"preview": "import * as THREE from 'three';\nexport class BufferGeometryUtils {\n static mergeVertices(geometry: THREE.BufferGeomet"
},
{
"path": "src/engine/gfx/Camera.ts",
"chars": 84,
"preview": "export class Camera {\n [key: string]: any;\n top: number;\n right: number;\n}\n"
},
{
"path": "src/engine/gfx/CanvasUtils.ts",
"chars": 8798,
"preview": "import { Palette } from '../../data/Palette';\ninterface DrawTextOptions {\n color?: string;\n backgroundColor?: stri"
},
{
"path": "src/engine/gfx/DebugUtils.ts",
"chars": 1794,
"preview": "import { Coords } from '@/game/Coords';\nimport { IndexedBitmap } from '@/data/Bitmap';\nimport * as THREE from 'three';\ne"
},
{
"path": "src/engine/gfx/FrustumCuller.ts",
"chars": 1434,
"preview": "import * as THREE from 'three';\nimport { Octree } from '@brakebein/threeoctree';\nexport class FrustumCuller {\n cull<T"
},
{
"path": "src/engine/gfx/GrowingPacker.ts",
"chars": 3258,
"preview": "export interface GrowingPackerBlock {\n w: number;\n h: number;\n fit?: GrowingPackerNode;\n}\nexport interface Grow"
},
{
"path": "src/engine/gfx/ImageUtils.ts",
"chars": 1754,
"preview": "import type { ShpFile } from '../../data/ShpFile';\nimport type { Palette } from '../../data/Palette';\nimport { IndexedBi"
},
{
"path": "src/engine/gfx/MathUtils.ts",
"chars": 991,
"preview": "import * as THREE from 'three';\nexport class MathUtils {\n static rotateObjectAboutPoint(object: THREE.Object3D, point"
},
{
"path": "src/engine/gfx/OctreeContainer.ts",
"chars": 3418,
"preview": "import { RenderableContainer } from './RenderableContainer';\nimport { FrustumCuller } from './FrustumCuller';\nimport { C"
},
{
"path": "src/engine/gfx/OverlayUtils.ts",
"chars": 1415,
"preview": "import * as THREE from 'three';\nimport { CanvasUtils } from './CanvasUtils';\nexport class OverlayUtils {\n static crea"
},
{
"path": "src/engine/gfx/Renderable.ts",
"chars": 78,
"preview": "export class Renderable {\n [key: string]: any;\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/gfx/RenderableContainer.ts",
"chars": 2575,
"preview": "import * as THREE from 'three';\nexport interface Renderable {\n create3DObject(): void;\n get3DObject(): THREE.Objec"
},
{
"path": "src/engine/gfx/Renderer.ts",
"chars": 5093,
"preview": "import * as THREE from 'three';\nimport Stats from 'stats.js';\nimport { EventDispatcher } from '../../util/event';\nimport"
},
{
"path": "src/engine/gfx/RendererError.ts",
"chars": 148,
"preview": "export class RendererError extends Error {\n constructor(message?: string) {\n super(message);\n this.name"
},
{
"path": "src/engine/gfx/Scene.ts",
"chars": 49,
"preview": "export class Scene {\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/gfx/SpriteUtils.ts",
"chars": 8589,
"preview": "import { isBetween } from \"../../util/math\";\nimport { BufferGeometryUtils } from \"./BufferGeometryUtils\";\nimport * as TH"
},
{
"path": "src/engine/gfx/TextureAtlas.ts",
"chars": 3046,
"preview": "import { IndexedBitmap } from '../../data/Bitmap';\nimport * as THREE from 'three';\nimport { GrowingPacker } from './Grow"
},
{
"path": "src/engine/gfx/TextureUtils.ts",
"chars": 2404,
"preview": "import { RgbaBitmap } from \"../../data/Bitmap\";\nimport { Palette } from \"../../data/Palette\";\nimport { fnv32a } from \".."
},
{
"path": "src/engine/gfx/batch/BatchedMesh.ts",
"chars": 1871,
"preview": "import * as THREE from 'three';\nexport enum BatchMode {\n Instancing = 0,\n Merging = 1\n}\nexport class BatchedMesh e"
},
{
"path": "src/engine/gfx/batch/InstancedMesh.ts",
"chars": 6248,
"preview": "import * as THREE from 'three';\nconst depthMaterial = new THREE.MeshDepthMaterial();\ndepthMaterial.depthPacking = THREE."
},
{
"path": "src/engine/gfx/batch/MergedSpriteMesh.ts",
"chars": 8045,
"preview": "import * as THREE from 'three';\nimport * as arrayUtils from '../../../util/array';\nimport { PaletteBasicMaterial } from "
},
{
"path": "src/engine/gfx/batch/MeshBatchManager.ts",
"chars": 5255,
"preview": "import * as THREE from 'three';\nimport { BatchedMesh, BatchMode } from './BatchedMesh';\nimport { MeshInstancingBatch } f"
},
{
"path": "src/engine/gfx/batch/MeshInstancingBatch.ts",
"chars": 3644,
"preview": "import * as THREE from 'three';\nimport { InstancedMesh } from './InstancedMesh';\nexport class MeshInstancingBatch {\n "
},
{
"path": "src/engine/gfx/batch/MeshMergingBatch.ts",
"chars": 3218,
"preview": "import * as THREE from 'three';\nimport { MergedSpriteMesh } from './MergedSpriteMesh';\nexport class MeshMergingBatch {\n "
},
{
"path": "src/engine/gfx/drawable/PalDrawable.ts",
"chars": 717,
"preview": "import { RgbaBitmap } from '../../../data/Bitmap';\nimport { Palette } from '../../../data/Palette';\nexport class PalDraw"
},
{
"path": "src/engine/gfx/drawable/TmpDrawable.ts",
"chars": 3242,
"preview": "import { IndexedBitmap } from '@/data/Bitmap';\ninterface TileData {\n tileData: number[];\n x: number;\n y: number"
},
{
"path": "src/engine/gfx/geometry/BufferGeometrySerializer.ts",
"chars": 3954,
"preview": "import { DataStream } from '../../../data/DataStream';\nimport * as THREE from 'three';\nexport class BufferGeometrySerial"
},
{
"path": "src/engine/gfx/geometry/VxlGeometryCache.ts",
"chars": 3853,
"preview": "import { DataStream } from '../../../data/DataStream';\nimport { VirtualFile } from '../../../data/vfs/VirtualFile';\nimpo"
},
{
"path": "src/engine/gfx/lighting/LightingDirector.ts",
"chars": 2536,
"preview": "import { LightingFx } from './LightingFx';\nimport { MapLighting } from '@/data/map/MapLighting';\nimport { Lighting } fro"
},
{
"path": "src/engine/gfx/lighting/LightingFx.ts",
"chars": 555,
"preview": "import { MapLighting } from '@/data/map/MapLighting';\nexport enum LightingFxPriority {\n Normal = 0,\n High = 1\n}\nex"
},
{
"path": "src/engine/gfx/lighting/LightningStormFx.ts",
"chars": 1014,
"preview": "import { LightingFx } from './LightingFx';\nexport class LightningStormFx extends LightingFx {\n private durationGameSe"
},
{
"path": "src/engine/gfx/lighting/NukeLightingFx.ts",
"chars": 1337,
"preview": "import { LightingFx, LightingFxPriority } from './LightingFx';\nexport class NukeLightingFx extends LightingFx {\n priv"
},
{
"path": "src/engine/gfx/material/PaletteBasicMaterial.ts",
"chars": 4636,
"preview": "import { paletteShaderLib } from \"./paletteShaderLib\";\nimport * as THREE from 'three';\nconst PaletteBasicShader = {\n "
},
{
"path": "src/engine/gfx/material/PaletteLambertMaterial.ts",
"chars": 2675,
"preview": "import { paletteShaderLib } from \"./paletteShaderLib\";\nimport * as THREE from 'three';\nconst PaletteLambertShader = {\n "
},
{
"path": "src/engine/gfx/material/PalettePhongMaterial.ts",
"chars": 3346,
"preview": "import * as THREE from 'three';\nimport { paletteShaderLib } from '@/engine/gfx/material/paletteShaderLib';\ninterface Pal"
},
{
"path": "src/engine/gfx/material/paletteShaderLib.ts",
"chars": 3894,
"preview": "import * as THREE from 'three';\nexport const paletteShaderLib = {\n uniforms: {\n palette: { type: \"t\", value: n"
},
{
"path": "src/engine/mixDatabase.ts",
"chars": 4750,
"preview": "export const mixDatabase = new Map<string, string[]>()\n .set(\"cameo.mix\", [\n \"adogicon.shp\", \"adoguico.shp\", \"aeng"
},
{
"path": "src/engine/renderable/AlphaRenderable.ts",
"chars": 2736,
"preview": "import { Palette } from \"@/data/Palette\";\nimport { ShpBuilder } from \"@/engine/renderable/builder/ShpBuilder\";\nimport { "
},
{
"path": "src/engine/renderable/CameraPan.ts",
"chars": 1323,
"preview": "import { clamp } from '../../util/math';\nimport { BoxedVar } from '../../util/BoxedVar';\nexport class CameraPan {\n pr"
},
{
"path": "src/engine/renderable/CameraZoom.ts",
"chars": 463,
"preview": "import { BoxedVar } from '../../util/BoxedVar';\nexport class CameraZoom {\n private freeCamera: BoxedVar<boolean>;\n "
},
{
"path": "src/engine/renderable/DebugRenderable.ts",
"chars": 7329,
"preview": "import { Palette } from \"@/data/Palette\";\nimport { DebugUtils } from \"@/engine/gfx/DebugUtils\";\nimport { TextureUtils } "
},
{
"path": "src/engine/renderable/Entity.ts",
"chars": 1072,
"preview": "import { WithPosition } from \"./WithPosition\";\nimport { WithVisibility } from \"./WithVisibility\";\nimport * as THREE from"
},
{
"path": "src/engine/renderable/MapSpriteTranslation.ts",
"chars": 1151,
"preview": "import { Coords } from \"@/game/Coords\";\nimport { IsoCoords } from \"@/engine/IsoCoords\";\nimport * as THREE from \"three\";\n"
},
{
"path": "src/engine/renderable/Renderable.ts",
"chars": 54,
"preview": "export { Renderable } from '@/engine/gfx/Renderable';\n"
},
{
"path": "src/engine/renderable/RenderablePlugin.ts",
"chars": 60,
"preview": "export class RenderablePlugin {\n constructor() {\n }\n}\n"
},
{
"path": "src/engine/renderable/ShadowRenderable.ts",
"chars": 4424,
"preview": "import { Palette } from \"@/data/Palette\";\nimport { ShpBuilder } from \"@/engine/renderable/builder/ShpBuilder\";\nimport { "
},
{
"path": "src/engine/renderable/ShpRenderable.ts",
"chars": 5046,
"preview": "import { ShpBuilder } from \"./builder/ShpBuilder\";\nimport { ShadowRenderable } from \"./ShadowRenderable\";\nimport { Coord"
},
{
"path": "src/engine/renderable/WithPosition.ts",
"chars": 1025,
"preview": "import * as THREE from \"three\";\nexport class WithPosition {\n public matrixUpdate: boolean = false;\n private positi"
},
{
"path": "src/engine/renderable/WithVisibility.ts",
"chars": 641,
"preview": "export class WithVisibility {\n private visible: boolean = true;\n private target?: any;\n constructor() {\n "
},
{
"path": "src/engine/renderable/WorldScene.ts",
"chars": 10027,
"preview": "import { pointEquals } from '../../util/geometry';\nimport { RenderableContainer } from '../gfx/RenderableContainer';\nimp"
},
{
"path": "src/engine/renderable/builder/BatchShpBuilder.ts",
"chars": 11552,
"preview": "import * as THREE from 'three';\nimport { ShpTextureAtlas } from './ShpTextureAtlas';\nimport { SpriteUtils } from '../../"
},
{
"path": "src/engine/renderable/builder/CanvasSpriteBuilder.ts",
"chars": 5611,
"preview": "import * as THREE from 'three';\nimport { SpriteUtils } from '../../gfx/SpriteUtils';\nimport { CanvasTextureAtlas } from "
},
{
"path": "src/engine/renderable/builder/CanvasTextureAtlas.ts",
"chars": 2465,
"preview": "import * as THREE from 'three';\nimport { GrowingPacker, type GrowingPackerBlock } from '@/engine/gfx/GrowingPacker';\ntyp"
},
{
"path": "src/engine/renderable/builder/ObjectBuilder.ts",
"chars": 53,
"preview": "export class ObjectBuilder {\n constructor() { }\n}\n"
},
{
"path": "src/engine/renderable/builder/ShpAggregator.ts",
"chars": 1276,
"preview": "import { ShpFile } from \"@/data/ShpFile\";\nimport { ShpImage } from \"@/data/ShpImage\";\nexport class ShpAggregator {\n s"
},
{
"path": "src/engine/renderable/builder/ShpBuilder.ts",
"chars": 12053,
"preview": "import * as TextureUtils from \"../../gfx/TextureUtils\";\nimport * as SpriteUtils from \"../../gfx/SpriteUtils\";\nimport { S"
},
{
"path": "src/engine/renderable/builder/ShpTextureAtlas.ts",
"chars": 908,
"preview": "import { IndexedBitmap } from \"../../../data/Bitmap\";\nimport { TextureAtlas } from \"../../gfx/TextureAtlas\";\nexport clas"
},
{
"path": "src/engine/renderable/builder/SpriteBuilder.ts",
"chars": 53,
"preview": "export class SpriteBuilder {\n constructor() { }\n}\n"
},
{
"path": "src/engine/renderable/builder/VxlBatchedBuilder.ts",
"chars": 5166,
"preview": "import { TextureUtils } from \"@/engine/gfx/TextureUtils\";\nimport { BatchedMesh } from \"@/engine/gfx/batch/BatchedMesh\";\n"
},
{
"path": "src/engine/renderable/builder/VxlBuilder.ts",
"chars": 2516,
"preview": "import { Coords } from '@/game/Coords';\nimport * as THREE from 'three';\ninterface Camera {\n rotation: {\n y: nu"
},
{
"path": "src/engine/renderable/builder/VxlBuilderFactory.ts",
"chars": 905,
"preview": "import { VxlBatchedBuilder } from \"./VxlBatchedBuilder\";\nimport { VxlNonBatchedBuilder } from \"./VxlNonBatchedBuilder\";\n"
},
{
"path": "src/engine/renderable/builder/VxlNonBatchedBuilder.ts",
"chars": 3769,
"preview": "import { TextureUtils } from '@/engine/gfx/TextureUtils';\nimport { VxlBuilder } from '@/engine/renderable/builder/VxlBui"
},
{
"path": "src/engine/renderable/builder/vxlGeometry/VxlGeometryCulledBuilder.ts",
"chars": 2119,
"preview": "import { BufferGeometryUtils } from \"@/engine/gfx/BufferGeometryUtils\";\nimport * as THREE from 'three';\nexport class Vxl"
},
{
"path": "src/engine/renderable/builder/vxlGeometry/VxlGeometryMonotoneBuilder.ts",
"chars": 8879,
"preview": "import { BufferGeometryUtils } from \"@/engine/gfx/BufferGeometryUtils\";\nimport * as THREE from 'three';\nclass VxlGeometr"
},
{
"path": "src/engine/renderable/builder/vxlGeometry/VxlGeometryNaiveBuilder.ts",
"chars": 4022,
"preview": "import * as THREE from 'three';\nimport { BufferGeometryUtils } from '@/engine/gfx/BufferGeometryUtils';\nexport class Vxl"
},
{
"path": "src/engine/renderable/builder/vxlGeometry/VxlGeometryPool.ts",
"chars": 1520,
"preview": "import { ModelQuality } from \"@/engine/renderable/entity/unit/ModelQuality\";\nimport { isNotNullOrUndefined } from \"@/uti"
},
{
"path": "src/engine/renderable/entity/Aircraft.ts",
"chars": 16012,
"preview": "import { Coords } from \"@/game/Coords\";\nimport { WithPosition } from \"@/engine/renderable/WithPosition\";\nimport { DebugU"
},
{
"path": "src/engine/renderable/entity/Anim.ts",
"chars": 9972,
"preview": "import { WithPosition } from \"@/engine/renderable/WithPosition\";\nimport { AnimProps } from \"@/engine/AnimProps\";\nimport "
},
{
"path": "src/engine/renderable/entity/BoxIntersectObject3D.ts",
"chars": 1360,
"preview": "import * as THREE from 'three';\nexport class BoxIntersectObject3D extends THREE.Object3D {\n private static ray: THREE"
}
]
// ... and 1089 more files (download for full content)
About this extraction
This page contains the full source code of the huangkaoya/redalert2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1289 files (5.2 MB), approximately 1.4M tokens, and a symbol index with 9525 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.