├── .gitignore ├── .gitmodules ├── COMPATIBILITY.xxx ├── LICENSE.txt ├── README.md ├── api.php ├── client ├── AI.js ├── Calculator.js ├── Canvas.MiniMap.js ├── Chat.DOM.js ├── Chat.Server.js ├── Common.js ├── Context.js ├── DOM.Bits.js ├── DOM.Common.js ├── DOM.Context.js ├── DOM.Controls.js ├── DOM.Map.js ├── DOM.MiniMap.js ├── DOM.Slider.js ├── DOM.UI.js ├── Debug.js ├── Effects.js ├── Entry.Browser.js ├── Entry.Worker.js ├── H3.AI.Nop.js ├── H3.AI.Trivial.Combat.js ├── H3.AI.Trivial.js ├── H3.Combat.js ├── H3.DOM.Audio.js ├── H3.DOM.Bits.js ├── H3.DOM.Combat.js ├── H3.DOM.Loading.js ├── H3.DOM.MainMenu.js ├── H3.DOM.UI.js ├── H3.Databank.js ├── H3.PathCost.js ├── H3.Rules.RPC.js ├── H3.Rules.js ├── H3.js ├── Map.js ├── Maps.js ├── ObjectStore.js ├── PathFind.AStar.js ├── RPC.Common.js ├── RPC.WebSocket.js ├── RPC.js ├── Screen.Tracker.js ├── Screen.js ├── Shroud.Effects.js ├── Shroud.js ├── Strings.js ├── Templates.js ├── WebSite.GrantModules.js ├── WebSite.TopBar.js ├── config.js ├── jquery.js └── json.js ├── core.php ├── css-monitor.php ├── custom-graphics ├── 3DOLOGO-z2-200p.png ├── CCELLGRD │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── pattern.png ├── CCELLSHD.png ├── CHATPLUG.png ├── CMNUMWIN │ ├── gray.png │ ├── green.png │ ├── purple-cyan.png │ ├── purple-violet.png │ ├── purple.png │ ├── red.png │ ├── samples │ │ ├── gray.png │ │ ├── green.png │ │ ├── purple-cyan.png │ │ ├── purple-violet.png │ │ ├── purple.png │ │ ├── red.png │ │ └── yellow.png │ └── yellow.png ├── DEF-CUR │ ├── CRADVNTR │ │ ├── CursrA00.cur │ │ ├── CursrA01.cur │ │ ├── CursrA02.cur │ │ ├── CursrA03.cur │ │ ├── CursrA04.cur │ │ ├── CursrA05.cur │ │ ├── CursrA06.cur │ │ ├── CursrA07.cur │ │ ├── CursrA08.cur │ │ ├── CursrA10.cur │ │ ├── CursrA11.cur │ │ ├── CursrA20.cur │ │ ├── CursrA21.cur │ │ ├── CursrA22.cur │ │ ├── CursrA23.cur │ │ ├── CursrA24.cur │ │ ├── CursrA25.cur │ │ ├── CursrA26.cur │ │ ├── CursrA27.cur │ │ ├── CursrA28.cur │ │ ├── CursrA29.cur │ │ ├── CursrA30.cur │ │ ├── CursrA31.cur │ │ ├── CursrA32.cur │ │ ├── CursrA33.cur │ │ ├── CursrA34.cur │ │ ├── CursrA35.cur │ │ ├── CursrA36.cur │ │ ├── CursrA37.cur │ │ ├── CursrA38.cur │ │ ├── CursrA39.cur │ │ ├── CursrA40.cur │ │ ├── CursrA41.cur │ │ ├── CursrA42.cur │ │ ├── CursrA43.cur │ │ ├── CursrA44.cur │ │ ├── CursrA45.cur │ │ ├── CursrA46.cur │ │ ├── CursrA47.cur │ │ ├── CursrA48.cur │ │ ├── CursrA49.cur │ │ └── CursrA50.cur │ ├── CRCOMBAT │ │ ├── Crcom000.cur │ │ ├── Crcom003.cur │ │ ├── Crcom006.cur │ │ ├── Crcom009.cur │ │ ├── Crcom012.cur │ │ ├── Crcom015.cur │ │ ├── Crcom016.cur │ │ ├── Crcom017.cur │ │ ├── Crcom018.cur │ │ ├── Crcom019.cur │ │ ├── Crcom020.cur │ │ ├── Crcom021.cur │ │ ├── Crcom022.cur │ │ ├── Crcom023.cur │ │ ├── Crcom026.cur │ │ ├── Crcom028.cur │ │ ├── Crcom031.cur │ │ ├── Crcom032.cur │ │ ├── Crcom033.cur │ │ └── Crcom034.cur │ └── CRDEFLT │ │ ├── CursrD00.cur │ │ ├── CursrD01.cur │ │ └── CursrD02.cur ├── DEF │ ├── .gitignore │ ├── SGFRWA43.bmp │ ├── SGTWWA12.bmp │ ├── SGTWWA41.bmp │ ├── _SGCSDRW.def │ ├── _SGCSMOAT.def │ ├── _SGCSWA1.def │ ├── _SGCSWA3.def │ ├── _SGCSWA4.def │ ├── _SGCSWA6.def │ ├── _SGDNDRW.def │ ├── _SGDNMOAT.def │ ├── _SGDNWA1.def │ ├── _SGDNWA3.def │ ├── _SGDNWA4.def │ ├── _SGDNWA6.def │ ├── _SGELDRW.def │ ├── _SGELMOAT.def │ ├── _SGELWA1.def │ ├── _SGELWA3.def │ ├── _SGELWA4.def │ ├── _SGELWA6.def │ ├── _SGFRDRW.def │ ├── _SGFRMOAT.def │ ├── _SGFRWA1.def │ ├── _SGFRWA3.def │ ├── _SGFRWA4.def │ ├── _SGFRWA6.def │ ├── _SGINDRW.def │ ├── _SGINMOAT.def │ ├── _SGINWA1.def │ ├── _SGINWA3.def │ ├── _SGINWA4.def │ ├── _SGINWA6.def │ ├── _SGNCDRW.def │ ├── _SGNCMOAT.def │ ├── _SGNCWA1.def │ ├── _SGNCWA3.def │ ├── _SGNCWA4.def │ ├── _SGNCWA6.def │ ├── _SGRMDRW.def │ ├── _SGRMMOAT.def │ ├── _SGRMWA1.def │ ├── _SGRMWA3.def │ ├── _SGRMWA4.def │ ├── _SGRMWA6.def │ ├── _SGSTDRW.def │ ├── _SGSTMOAT.def │ ├── _SGSTWA1.def │ ├── _SGSTWA3.def │ ├── _SGSTWA4.def │ ├── _SGSTWA6.def │ ├── _SGTWDRW.def │ ├── _SGTWWA1.def │ ├── _SGTWWA3.def │ ├── _SGTWWA4.def │ ├── _SGTWWA6.def │ └── gen.php ├── DIALGBOX │ ├── blue-help.png │ ├── blue.png │ ├── green-help.png │ ├── green.png │ ├── orange-help.png │ ├── orange.png │ ├── pink-help.png │ ├── pink.png │ ├── purple-help.png │ ├── purple.png │ ├── red-help.png │ ├── red.png │ ├── tan-help.png │ ├── tan.png │ ├── teal-help.png │ └── teal.png ├── EDG │ ├── composed-bk.png │ ├── composed-edge.png │ ├── composed-test.png │ └── composed.png ├── GTSINGL │ ├── 0-0.png │ ├── 0-1.png │ └── 0-2.png ├── LOADPROG.png ├── NWCLOGO-SMK-z2-200p.png ├── SYSOB12 │ ├── 0.png │ ├── 1.png │ └── 2.png ├── SYSOB13 │ ├── 0.png │ ├── 1.png │ └── 2.png ├── combat-list.png ├── list-resting.png ├── loading │ ├── body.php │ ├── font │ │ ├── Font License.txt │ │ ├── Pixel Emulator.otf │ │ └── fontsquirrel generator_config.txt │ ├── gen.sh │ ├── images │ │ ├── AH00_-blueOwner.gif │ │ ├── AH00_-blueOwner.png │ │ ├── AH00_-greenOwner.gif │ │ ├── AH00_-greenOwner.png │ │ ├── AH00_-orangeOwner.gif │ │ ├── AH00_-orangeOwner.png │ │ ├── AH00_-pinkOwner.gif │ │ ├── AH00_-pinkOwner.png │ │ ├── AH00_-purpleOwner.gif │ │ ├── AH00_-purpleOwner.png │ │ ├── AH00_-redOwner.gif │ │ ├── AH00_-redOwner.png │ │ ├── AH00_-tanOwner.gif │ │ ├── AH00_-tanOwner.png │ │ ├── AH00_-tealOwner.gif │ │ ├── AH00_-tealOwner.png │ │ ├── AH01_-blueOwner.gif │ │ ├── AH01_-blueOwner.png │ │ ├── AH01_-greenOwner.gif │ │ ├── AH01_-greenOwner.png │ │ ├── AH01_-orangeOwner.gif │ │ ├── AH01_-orangeOwner.png │ │ ├── AH01_-pinkOwner.gif │ │ ├── AH01_-pinkOwner.png │ │ ├── AH01_-purpleOwner.gif │ │ ├── AH01_-purpleOwner.png │ │ ├── AH01_-redOwner.gif │ │ ├── AH01_-redOwner.png │ │ ├── AH01_-tanOwner.gif │ │ ├── AH01_-tanOwner.png │ │ ├── AH01_-tealOwner.gif │ │ ├── AH01_-tealOwner.png │ │ ├── AH02_-blueOwner.gif │ │ ├── AH02_-blueOwner.png │ │ ├── AH02_-greenOwner.gif │ │ ├── AH02_-greenOwner.png │ │ ├── AH02_-orangeOwner.gif │ │ ├── AH02_-orangeOwner.png │ │ ├── AH02_-pinkOwner.gif │ │ ├── AH02_-pinkOwner.png │ │ ├── AH02_-purpleOwner.gif │ │ ├── AH02_-purpleOwner.png │ │ ├── AH02_-redOwner.gif │ │ ├── AH02_-redOwner.png │ │ ├── AH02_-tanOwner.gif │ │ ├── AH02_-tanOwner.png │ │ ├── AH02_-tealOwner.gif │ │ ├── AH02_-tealOwner.png │ │ ├── AH03_-blueOwner.gif │ │ ├── AH03_-blueOwner.png │ │ ├── AH03_-greenOwner.gif │ │ ├── AH03_-greenOwner.png │ │ ├── AH03_-orangeOwner.gif │ │ ├── AH03_-orangeOwner.png │ │ ├── AH03_-pinkOwner.gif │ │ ├── AH03_-pinkOwner.png │ │ ├── AH03_-purpleOwner.gif │ │ ├── AH03_-purpleOwner.png │ │ ├── AH03_-redOwner.gif │ │ ├── AH03_-redOwner.png │ │ ├── AH03_-tanOwner.gif │ │ ├── AH03_-tanOwner.png │ │ ├── AH03_-tealOwner.gif │ │ ├── AH03_-tealOwner.png │ │ ├── AH04_-blueOwner.gif │ │ ├── AH04_-blueOwner.png │ │ ├── AH04_-greenOwner.gif │ │ ├── AH04_-greenOwner.png │ │ ├── AH04_-orangeOwner.gif │ │ ├── AH04_-orangeOwner.png │ │ ├── AH04_-pinkOwner.gif │ │ ├── AH04_-pinkOwner.png │ │ ├── AH04_-purpleOwner.gif │ │ ├── AH04_-purpleOwner.png │ │ ├── AH04_-redOwner.gif │ │ ├── AH04_-redOwner.png │ │ ├── AH04_-tanOwner.gif │ │ ├── AH04_-tanOwner.png │ │ ├── AH04_-tealOwner.gif │ │ ├── AH04_-tealOwner.png │ │ ├── AH05_-blueOwner.gif │ │ ├── AH05_-blueOwner.png │ │ ├── AH05_-greenOwner.gif │ │ ├── AH05_-greenOwner.png │ │ ├── AH05_-orangeOwner.gif │ │ ├── AH05_-orangeOwner.png │ │ ├── AH05_-pinkOwner.gif │ │ ├── AH05_-pinkOwner.png │ │ ├── AH05_-purpleOwner.gif │ │ ├── AH05_-purpleOwner.png │ │ ├── AH05_-redOwner.gif │ │ ├── AH05_-redOwner.png │ │ ├── AH05_-tanOwner.gif │ │ ├── AH05_-tanOwner.png │ │ ├── AH05_-tealOwner.gif │ │ ├── AH05_-tealOwner.png │ │ ├── AH06_-blueOwner.gif │ │ ├── AH06_-blueOwner.png │ │ ├── AH06_-greenOwner.gif │ │ ├── AH06_-greenOwner.png │ │ ├── AH06_-orangeOwner.gif │ │ ├── AH06_-orangeOwner.png │ │ ├── AH06_-pinkOwner.gif │ │ ├── AH06_-pinkOwner.png │ │ ├── AH06_-purpleOwner.gif │ │ ├── AH06_-purpleOwner.png │ │ ├── AH06_-redOwner.gif │ │ ├── AH06_-redOwner.png │ │ ├── AH06_-tanOwner.gif │ │ ├── AH06_-tanOwner.png │ │ ├── AH06_-tealOwner.gif │ │ ├── AH06_-tealOwner.png │ │ ├── AH07_-blueOwner.gif │ │ ├── AH07_-blueOwner.png │ │ ├── AH07_-greenOwner.gif │ │ ├── AH07_-greenOwner.png │ │ ├── AH07_-orangeOwner.gif │ │ ├── AH07_-orangeOwner.png │ │ ├── AH07_-pinkOwner.gif │ │ ├── AH07_-pinkOwner.png │ │ ├── AH07_-purpleOwner.gif │ │ ├── AH07_-purpleOwner.png │ │ ├── AH07_-redOwner.gif │ │ ├── AH07_-redOwner.png │ │ ├── AH07_-tanOwner.gif │ │ ├── AH07_-tanOwner.png │ │ ├── AH07_-tealOwner.gif │ │ ├── AH07_-tealOwner.png │ │ ├── AH08_-blueOwner.gif │ │ ├── AH08_-blueOwner.png │ │ ├── AH08_-greenOwner.gif │ │ ├── AH08_-greenOwner.png │ │ ├── AH08_-orangeOwner.gif │ │ ├── AH08_-orangeOwner.png │ │ ├── AH08_-pinkOwner.gif │ │ ├── AH08_-pinkOwner.png │ │ ├── AH08_-purpleOwner.gif │ │ ├── AH08_-purpleOwner.png │ │ ├── AH08_-redOwner.gif │ │ ├── AH08_-redOwner.png │ │ ├── AH08_-tanOwner.gif │ │ ├── AH08_-tanOwner.png │ │ ├── AH08_-tealOwner.gif │ │ ├── AH08_-tealOwner.png │ │ ├── AH09_-blueOwner.gif │ │ ├── AH09_-blueOwner.png │ │ ├── AH09_-greenOwner.gif │ │ ├── AH09_-greenOwner.png │ │ ├── AH09_-orangeOwner.gif │ │ ├── AH09_-orangeOwner.png │ │ ├── AH09_-pinkOwner.gif │ │ ├── AH09_-pinkOwner.png │ │ ├── AH09_-purpleOwner.gif │ │ ├── AH09_-purpleOwner.png │ │ ├── AH09_-redOwner.gif │ │ ├── AH09_-redOwner.png │ │ ├── AH09_-tanOwner.gif │ │ ├── AH09_-tanOwner.png │ │ ├── AH09_-tealOwner.gif │ │ ├── AH09_-tealOwner.png │ │ ├── AH10_-blueOwner.gif │ │ ├── AH10_-blueOwner.png │ │ ├── AH10_-greenOwner.gif │ │ ├── AH10_-greenOwner.png │ │ ├── AH10_-orangeOwner.gif │ │ ├── AH10_-orangeOwner.png │ │ ├── AH10_-pinkOwner.gif │ │ ├── AH10_-pinkOwner.png │ │ ├── AH10_-purpleOwner.gif │ │ ├── AH10_-purpleOwner.png │ │ ├── AH10_-redOwner.gif │ │ ├── AH10_-redOwner.png │ │ ├── AH10_-tanOwner.gif │ │ ├── AH10_-tanOwner.png │ │ ├── AH10_-tealOwner.gif │ │ ├── AH10_-tealOwner.png │ │ ├── AH11_-blueOwner.gif │ │ ├── AH11_-blueOwner.png │ │ ├── AH11_-greenOwner.gif │ │ ├── AH11_-greenOwner.png │ │ ├── AH11_-orangeOwner.gif │ │ ├── AH11_-orangeOwner.png │ │ ├── AH11_-pinkOwner.gif │ │ ├── AH11_-pinkOwner.png │ │ ├── AH11_-purpleOwner.gif │ │ ├── AH11_-purpleOwner.png │ │ ├── AH11_-redOwner.gif │ │ ├── AH11_-redOwner.png │ │ ├── AH11_-tanOwner.gif │ │ ├── AH11_-tanOwner.png │ │ ├── AH11_-tealOwner.gif │ │ ├── AH11_-tealOwner.png │ │ ├── AH12_-blueOwner.gif │ │ ├── AH12_-blueOwner.png │ │ ├── AH12_-greenOwner.gif │ │ ├── AH12_-greenOwner.png │ │ ├── AH12_-orangeOwner.gif │ │ ├── AH12_-orangeOwner.png │ │ ├── AH12_-pinkOwner.gif │ │ ├── AH12_-pinkOwner.png │ │ ├── AH12_-purpleOwner.gif │ │ ├── AH12_-purpleOwner.png │ │ ├── AH12_-redOwner.gif │ │ ├── AH12_-redOwner.png │ │ ├── AH12_-tanOwner.gif │ │ ├── AH12_-tanOwner.png │ │ ├── AH12_-tealOwner.gif │ │ ├── AH12_-tealOwner.png │ │ ├── AH13_-blueOwner.gif │ │ ├── AH13_-blueOwner.png │ │ ├── AH13_-greenOwner.gif │ │ ├── AH13_-greenOwner.png │ │ ├── AH13_-orangeOwner.gif │ │ ├── AH13_-orangeOwner.png │ │ ├── AH13_-pinkOwner.gif │ │ ├── AH13_-pinkOwner.png │ │ ├── AH13_-purpleOwner.gif │ │ ├── AH13_-purpleOwner.png │ │ ├── AH13_-redOwner.gif │ │ ├── AH13_-redOwner.png │ │ ├── AH13_-tanOwner.gif │ │ ├── AH13_-tanOwner.png │ │ ├── AH13_-tealOwner.gif │ │ ├── AH13_-tealOwner.png │ │ ├── AH14_-blueOwner.gif │ │ ├── AH14_-blueOwner.png │ │ ├── AH14_-greenOwner.gif │ │ ├── AH14_-greenOwner.png │ │ ├── AH14_-orangeOwner.gif │ │ ├── AH14_-orangeOwner.png │ │ ├── AH14_-pinkOwner.gif │ │ ├── AH14_-pinkOwner.png │ │ ├── AH14_-purpleOwner.gif │ │ ├── AH14_-purpleOwner.png │ │ ├── AH14_-redOwner.gif │ │ ├── AH14_-redOwner.png │ │ ├── AH14_-tanOwner.gif │ │ ├── AH14_-tanOwner.png │ │ ├── AH14_-tealOwner.gif │ │ ├── AH14_-tealOwner.png │ │ ├── AH15_-blueOwner.gif │ │ ├── AH15_-blueOwner.png │ │ ├── AH15_-greenOwner.gif │ │ ├── AH15_-greenOwner.png │ │ ├── AH15_-orangeOwner.gif │ │ ├── AH15_-orangeOwner.png │ │ ├── AH15_-pinkOwner.gif │ │ ├── AH15_-pinkOwner.png │ │ ├── AH15_-purpleOwner.gif │ │ ├── AH15_-purpleOwner.png │ │ ├── AH15_-redOwner.gif │ │ ├── AH15_-redOwner.png │ │ ├── AH15_-tanOwner.gif │ │ ├── AH15_-tanOwner.png │ │ ├── AH15_-tealOwner.gif │ │ ├── AH15_-tealOwner.png │ │ ├── AH16_-blueOwner.gif │ │ ├── AH16_-blueOwner.png │ │ ├── AH16_-greenOwner.gif │ │ ├── AH16_-greenOwner.png │ │ ├── AH16_-orangeOwner.gif │ │ ├── AH16_-orangeOwner.png │ │ ├── AH16_-pinkOwner.gif │ │ ├── AH16_-pinkOwner.png │ │ ├── AH16_-purpleOwner.gif │ │ ├── AH16_-purpleOwner.png │ │ ├── AH16_-redOwner.gif │ │ ├── AH16_-redOwner.png │ │ ├── AH16_-tanOwner.gif │ │ ├── AH16_-tanOwner.png │ │ ├── AH16_-tealOwner.gif │ │ ├── AH16_-tealOwner.png │ │ ├── AH17_-blueOwner.gif │ │ ├── AH17_-blueOwner.png │ │ ├── AH17_-greenOwner.gif │ │ ├── AH17_-greenOwner.png │ │ ├── AH17_-orangeOwner.gif │ │ ├── AH17_-orangeOwner.png │ │ ├── AH17_-pinkOwner.gif │ │ ├── AH17_-pinkOwner.png │ │ ├── AH17_-purpleOwner.gif │ │ ├── AH17_-purpleOwner.png │ │ ├── AH17_-redOwner.gif │ │ ├── AH17_-redOwner.png │ │ ├── AH17_-tanOwner.gif │ │ ├── AH17_-tanOwner.png │ │ ├── AH17_-tealOwner.gif │ │ └── AH17_-tealOwner.png │ └── styles.css └── menu │ ├── bullet_up.png │ ├── folder-up.png │ ├── folder.png │ ├── internet_explorer.png │ ├── key_solid.png │ ├── mark_to_download.png │ ├── move_to_folder.png │ ├── plus.png │ └── readme-fatcow.txt ├── databank ├── Animations.txt ├── CMNUMWIN2png.php ├── Formats.txt ├── Images.txt ├── Sounds.txt ├── Versions.txt ├── bmp2png.php ├── bmp2shape.php ├── core.php ├── cur-hotspot.php ├── databank-artifacts.php ├── databank-buildings.php ├── databank-combat.php ├── databank-creatureAnimations.php ├── databank-creatures.php ├── databank-custom.php ├── databank-effects.php ├── databank-heroes.php ├── databank-objects.php ├── databank-skills.php ├── databank-spells.php ├── databank.php ├── def2png.php ├── find-image.php ├── find-special DEF.txt ├── find-special.php ├── h3m2herowo.php ├── map-list.php ├── obst.php └── shapes.json ├── exception-map.js ├── exception.php ├── favicon.ico ├── herowo-h3-menu.css ├── herowo.css ├── index.php ├── maps.php ├── noXXXep-config.php ├── noXXXep.css ├── statistics.php ├── strings-game.json └── strings-menu.json /.gitignore: -------------------------------------------------------------------------------- 1 | /server/ 2 | /api-db.php 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "client/nodash"] 2 | path = client/nodash 3 | url = https://github.com/ProgerXP/NoDash.git 4 | [submodule "client/sqimitive"] 5 | path = client/sqimitive 6 | url = https://github.com/ProgerXP/Sqimitive.git 7 | [submodule "client/PathAnimator"] 8 | path = client/PathAnimator 9 | url = https://github.com/yairEO/pathAnimator.git 10 | [submodule "client/r.js"] 11 | path = client/r.js 12 | url = https://github.com/requirejs/r.js.git 13 | shallow = 1 14 | [submodule "databank/h3m2json"] 15 | path = databank/h3m2json 16 | url = https://github.com/HeroWO-js/h3m2json.git 17 | [submodule "noXXXep"] 18 | path = noXXXep 19 | url = https://github.com/ProgerXP/noXXXep.git 20 | [submodule "Phiws"] 21 | path = Phiws 22 | url = https://github.com/ProgerXP/Phiws.git 23 | [submodule "source-map"] 24 | path = source-map 25 | url = https://github.com/mozilla/source-map.git 26 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HeroWO's Game Core 2 | 3 | Part of the HeroWO.js project - a JavaScript re-implementation of *Heroes of Might and Magic III*. 4 | 5 | https://github.com/HeroWO-js/Workbench 6 | 7 | https://herowo.game 8 | 9 | ## client 10 | 11 | The main thing - JavaScript game engine with client side of the multi-player (server side that amounts to about 4% of Core is proprietary). 12 | 13 | Dependencies are included as git submodules: 14 | 15 | * NoDash - a utility library with `_.pick()` and 80+ other functions 16 | https://squizzle.me/js/nodash/ 17 | * Sqimitive - the backbone framework for everything 18 | https://squizzle.me/js/sqimitive/ 19 | * Require.js - a module system that doesn't get in the way 20 | https://requirejs.org 21 | * PathAnimator - a teeny function converting arbitrary SVG curve to coordinates 22 | https://github.com/yairEO/pathAnimator 23 | * Source Map - allows recreating non-minified stack traces in exception reports 24 | https://github.com/mozilla/source-map 25 | 26 | ...except for `jquery.js` that is bundled directly. 27 | https://jquery.com 28 | 29 | ## databank 30 | 31 | The, er, bank of game data - most of it coming from HoMM 3 TXT files. One way to create modifications ("mods"), and the easiest also, is by changing databank files - either prior to convertion (edit `databank-*.php` or supply already modded TXTs) or after it (edit `*.json`). 32 | 33 | HoMM 3 map convertion is backed by `h3m2json.php`. 34 | https://github.com/HeroWO-js/h3m2json 35 | 36 | ## noXXXep 37 | 38 | HeroWO is a work in progress and includes hundreds of small and large to-do tasks (`XXX`). These are embedded directly in code to make them versioned, easy to modify en masse and tightly bound to their context. **noXXXep** is what [presents them nicely](https://herowo.io/noXXXep/). 39 | 40 | https://github.com/ProgerXP/noXXXep 41 | 42 | ## Phiws, api.php and others 43 | 44 | `api.php` is the server side coordinator of client side JavaScript engine, providing the latter with the list of lobby games, playable maps and chat messages. 45 | 46 | **Phiws** is a *PHp WebSockets* implementation used by `api.php` to communicate with HeroWO servers and clients. Unauthenticated data (list of maps and global chat messages) is distributed over Server-Sent Events (SSE). One can use `api.php` to start local games or connect to games on external servers. 47 | 48 | Other files and folders facilitate smaller aspects of running the game: 49 | 50 | * `custom-graphics` - folder with custom graphics that wasn't taken from HoMM 3 files (i.e. isn't part of the databank) or that was transformed in some way 51 | * `css-monitor.php` - watches local CSS files and refreshes styles without reloading the page; indispensible when developing HeroWO UI 52 | * `herowo*.css` - technically part of the game client code 53 | * `index.php` - user's entry point; bootstraps HeroWO environment in a web browser 54 | * `maps.php` - provides insight into maps existing on the server and allows uploading new maps 55 | -------------------------------------------------------------------------------- /client/DOM.Context.js: -------------------------------------------------------------------------------- 1 | define(['DOM.Common', 'Context'], function (Common, Context) { 2 | "use strict" 3 | var _ = Common._ 4 | var $ = Common.$ 5 | 6 | // Represents an engine instance running in a web browser. 7 | return Context.Fetching.extend('HeroWO.DOM.Context', { 8 | mixIns: [Common.jQuery.MixIn], 9 | el: {class: 'Hcx'}, 10 | _window: null, 11 | _timedScale: null, 12 | 13 | //> scale bool `- Enables automatic scaling of the entire UI 14 | // (`#Context.`'el) to fit document width. See `#scale(). 15 | _opt: { 16 | scale: false, 17 | }, 18 | 19 | events: { 20 | init: function () { 21 | this._window = $(window) 22 | this._updateClassic() 23 | }, 24 | 25 | change_scale: 'scale', 26 | 27 | 'change_loading, menu': function () { 28 | // Different states can have different content dimensions. 29 | _.defer(Common.ef('scale', this)) 30 | }, 31 | 32 | change_classic: '_updateClassic', 33 | 34 | // Can be called multiple times. 35 | attach: function () { 36 | this._timedScale = _.throttle(Common.ef('scale', this), 100) 37 | 38 | this._window 39 | .off('.' + this._cid) 40 | .on('resize.' + this._cid, this._timedScale) 41 | }, 42 | 43 | unnest: function () { 44 | this._timedScale.cancel() 45 | this._window.off('.' + this._cid) 46 | }, 47 | }, 48 | 49 | // Updates the root `'el's scaling according to the node's and window's sizes. 50 | // 51 | // ` `#scale() is called automatically if the `'scale `#_opt is enabled 52 | // whenever window is resized. Usually the root `'el has the same size 53 | // no matter current game state but you can call this method manually if 54 | // this is not the case. 55 | scale: function () { 56 | this.el.toggleClass('Hcx_scale', this.get('scale')) 57 | Common.oneClass(this.el, 'Hcx_scale_') 58 | if (!this.get('scale')) { 59 | var ratio = 1 60 | } else { 61 | var ratio = Math.min(this._window.width() / this.el.width(), 62 | this._window.height() / (this.el.height() + this.el.offset().top)) 63 | this.el.addClass('Hcx_scale_' + (ratio < 1 ? 'down' : 'up')) 64 | } 65 | this.el.css('transform', ratio == 1 ? '' : 'scale(' + ratio + ')') 66 | _.invoke(this.screens(), 'set', 'scaleFactor', ratio) 67 | }, 68 | 69 | _updateClassic: function () { 70 | Common.oneClass(this.el, 'Hcx_classic_', this.get('classic') ? 'yes' : 'no') 71 | }, 72 | }) 73 | }) -------------------------------------------------------------------------------- /client/DOM.MiniMap.js: -------------------------------------------------------------------------------- 1 | define(['DOM.Common', 'Canvas.MiniMap'], function (Common, CanvasMiniMap) { 2 | "use strict" 3 | var _ = Common._ 4 | var $ = Common.$ 5 | 6 | // Uses browser's DOM to draw a simplified tile-based adventure map. 7 | // 8 | // `'el is the node where tile nodes are placed. Usually it matches 9 | // `@DOM.UI.miniMapEl`@. 10 | // 11 | // This class is using the following CSS classes: 12 | //* Hroot__mmap, Hmmap* 13 | return CanvasMiniMap.extend('HeroWO.DOM.MiniMap', { 14 | _cellEls: [], // [z] => [n] => Element 15 | 16 | //> sharedEl true shared and this MiniMap took over`, false shared but other MiniMap is primary `- a hack to make hotseat games playable to avoid the explosion of DOM nodes 17 | _opt: { 18 | sharedEl: null, 19 | }, 20 | 21 | events: { 22 | '=attach': function (sup) { 23 | return sup(this, this.get('sharedEl') === false ? [null] : []) 24 | }, 25 | 26 | '=change_hidden, =_update, =_mousedown, =_updateZ, =_updateRectPos': function (sup) { 27 | this.get('sharedEl') === false || sup(this, arguments) 28 | }, 29 | 30 | change_sharedEl: function (now) { 31 | _.log && _.log('MiniMap P%d sharedEl : %j', this.sc.get('player'), now) 32 | 33 | if (now && this.get('rendered')) { 34 | this.get('attachPath').append(this.el) 35 | this.el.toggleClass('Hmmap_hidden', this.get('hidden')) 36 | this.update() 37 | this._updateShroudAll() 38 | } 39 | }, 40 | 41 | '=_createNodes': function () { 42 | var info = this.map.get() 43 | this._rectEl = this.el.children('.Hmmap_rect')[0] 44 | 45 | if (this._rectEl) { 46 | for (var z = 0; z < info.levels; z++) { 47 | var el = this._levelEls[z] = this.el[0].children[z] 48 | this._cellEls[z] = el.children 49 | } 50 | } else { 51 | var html = Array(info.width * info.height) 52 | 53 | for (var x = 0; x < info.width; x++) { 54 | for (var y = 0; y < info.height; y++) { 55 | html[x + y * info.width] = 56 | '' 60 | } 61 | } 62 | 63 | for (var z = 0; z < info.levels; z++) { 64 | if (!z) { 65 | var el = document.createElement('div') 66 | el.innerHTML = html.join('') 67 | } else { 68 | el = el.cloneNode(true) 69 | } 70 | this._levelEls[z] = el 71 | this._cellEls[z] = el.children 72 | } 73 | 74 | this.el.append(this._levelEls) 75 | 76 | var random = Common.Sqimitive.unique('wr') 77 | var style = [] 78 | _.each(this._miniMapColors, function (color, key) { 79 | style.push('.Hmmap__id_' + random + ' .Hmmap__cell_subtype_' + key + 80 | '{background-color:#' + color + '}') 81 | }) 82 | this.el.addClass('Hmmap__id_' + random) 83 | .append('