├── .gitignore ├── LICENSE ├── README.md ├── bin ├── backup │ └── !readme.txt ├── colors.lua ├── compile.txt ├── config.lua ├── confighq.lua ├── core │ ├── ai.lua │ ├── being.lua │ ├── blueprints.lua │ ├── commands.lua │ ├── constants.lua │ ├── core.lua │ ├── functions.lua │ ├── generator.lua │ ├── item.lua │ ├── level.lua │ ├── player.lua │ ├── thing.lua │ └── ui.lua ├── danger_report.pl ├── dkey.inc ├── drl_console.bat ├── drl_gnome-terminal ├── drl_konsole ├── drl_xterm ├── font10x18.png ├── godmode.lua ├── graphics │ ├── LICENSE │ ├── background.png │ ├── cursor.png │ ├── doom.ini │ ├── doom.png │ ├── doomguy.png │ ├── doomguy_mask.png │ ├── doomguy_shadow.png │ ├── doors_and_decorations.png │ ├── doors_and_decorations_mask.png │ ├── doors_and_decorations_shadow.png │ ├── enemies.png │ ├── enemies_big.png │ ├── enemies_big_shadow.png │ ├── enemies_shadow.png │ ├── fx.png │ ├── fx_mask.png │ ├── guns_and_pickups.png │ ├── guns_and_pickups_mask.png │ ├── guns_and_pickups_shadow.png │ ├── levels.png │ ├── levels_mask.png │ ├── logo.png │ ├── lut_berserk.png │ ├── lut_clear.png │ ├── lut_enviro.png │ ├── lut_iddqd.png │ ├── message.png │ └── message.xml ├── help │ ├── angel.asc │ ├── arachno.asc │ ├── arch.asc │ ├── barmor.asc │ ├── baron.asc │ ├── cacodemon.asc │ ├── captain.asc │ ├── commando.asc │ ├── credits.hlp │ ├── cyberdemon.asc │ ├── demon.asc │ ├── disclaim.hlp │ ├── doomrl.txt │ ├── feedback.hlp │ ├── former.asc │ ├── garmor.asc │ ├── imp.asc │ ├── intro.hlp │ ├── keys.hlp │ ├── knight.asc │ ├── logo.dat │ ├── lostsoul.asc │ ├── make_manual.lua │ ├── mancubus.asc │ ├── pain.asc │ ├── player.asc │ ├── rarmor.asc │ ├── revenant.asc │ ├── sergeant.asc │ └── start.hlp ├── item_report.pl ├── itemscsv.lua ├── lua │ ├── affects.lua │ ├── ai.lua │ ├── archi.lua │ ├── beings.lua │ ├── cells.lua │ ├── challenge.lua │ ├── difficulty.lua │ ├── events.lua │ ├── generator.lua │ ├── generators.lua │ ├── items │ │ ├── eitems.lua │ │ ├── items.lua │ │ └── uitems.lua │ ├── klass.lua │ ├── levels │ │ ├── abyssal.lua │ │ ├── arena.lua │ │ ├── armory.lua │ │ ├── asmosden.lua │ │ ├── boss.lua │ │ ├── carnage.lua │ │ ├── chained.lua │ │ ├── containment.lua │ │ ├── deimoslab.lua │ │ ├── fortress.lua │ │ ├── house.lua │ │ ├── intro.lua │ │ ├── lavapits.lua │ │ ├── limbo.lua │ │ ├── milibase.lua │ │ ├── mortuary.lua │ │ ├── mterebus.lua │ │ ├── phoboslab.lua │ │ ├── skulls.lua │ │ ├── spider.lua │ │ ├── vaults.lua │ │ └── wall.lua │ ├── main.lua │ ├── medals.lua │ ├── missiles.lua │ ├── mod_arrays.lua │ ├── plot.lua │ ├── ranks.lua │ ├── rooms.lua │ ├── sprites.lua │ └── traits.lua ├── lua_check.lua ├── lua_check_config.lua ├── manual.txt ├── modules │ ├── !readme.txt │ └── classic.module │ │ ├── data │ │ └── phobos_arena.lua │ │ ├── main.lua │ │ └── module.lua ├── mortem │ └── !readme.txt ├── mp3 │ └── !readme.txt ├── music.lua ├── music │ └── !readme.txt ├── musichq.lua ├── screenshot │ └── !readme.txt ├── sound.lua ├── soundhq.lua ├── unix_notes.txt ├── version.txt ├── version_api.txt ├── wav │ └── !readme.txt └── wavhq │ └── !readme.txt ├── config-linux.lua ├── config-windows.lua ├── doomrl.code-workspace ├── install ├── install.bmp ├── install_after.txt ├── install_license.txt └── install_small.bmp ├── makefile.lua ├── makewad.bat ├── mkbin.sh ├── mksrc.sh ├── old ├── doomnet.pas ├── spritesheet.png ├── spritesheet_color.png └── spritesheet_shadow.png ├── scripts ├── doomrl_snapshot.sh └── mk_unix_dist.sh └── src ├── Makefile.fpc ├── costest.lpi ├── costest.lpr ├── dfaffect.pas ├── dfbeing.pas ├── dfdata.pas ├── dfhof.pas ├── dfitem.pas ├── dflevel.pas ├── dfmap.pas ├── dfplayer.pas ├── dfthing.pas ├── doomanimation.pas ├── doomassemblyview.pas ├── doomaudio.pas ├── doombase.pas ├── doomcommand.pas ├── doomconfig.pas ├── doomconfiguration.pas ├── doomconfirmview.pas ├── doomgfxio.pas ├── doomhelp.pas ├── doomhelpview.pas ├── doomhooks.pas ├── doomingamemenuview.pas ├── doominventory.pas ├── doomio.pas ├── doomkeybindings.pas ├── doomlua.pas ├── doommenuview.pas ├── doommodule.pas ├── doommoreview.pas ├── doomplayerview.pas ├── doomrl.inc ├── doomrl.res ├── doomsettingsview.pas ├── doomspritemap.pas ├── doomtextio.pas ├── doomtextures.pas ├── doomtrait.pas ├── doomviews.pas ├── drl.ico ├── drl.lpi ├── drl.pas ├── drlwad.lpi ├── drlwad.pas ├── gmfplayer.ico ├── gmfplayer.lpi ├── gmfplayer.lpr ├── icon.ico ├── makerel.pl ├── makewad.lpi ├── makewad.pas ├── release.bat └── version.inc /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | lib/ 3 | pkg/ 4 | CMakeLists.txt 5 | cmake-build-debug/ 6 | mod.info 7 | revision.info 8 | *.a 9 | *.mp3 10 | *.wav 11 | bin/core.wad 12 | bin/doom.prc 13 | bin/doomrl.wad 14 | src/doomrl.lps 15 | src/makewad.lps 16 | src/backup/ 17 | bin/log.txt 18 | temp/ 19 | bin/backup/ 20 | src/fpcmade.x86_64-linux 21 | src/Makefile 22 | *.wad 23 | bin/makewad 24 | bin/doomrl 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # doomrl 2 | 3 | DRL a.k.a. doomrl, a.k.a, D**m, the Roguelike, version 0.9.9.8 4 | http://drl.chaosforge.org/ 5 | 6 | This release is dedicated to Jupiter Hell Classic, the newly announced commercial remake/expansion to DRL: 7 | 8 | https://store.steampowered.com/app/3126530/Jupiter_Hell_Classic/ 9 | 10 | If you enjoy this Open Source release, please consider wishlisting and later buying Jupiter Hell Classic! Also, you might be interested in DRL's modern 3D spiritual successor, Jupiter Hell (yes, it's still turn-based :P): 11 | 12 | https://store.steampowered.com/app/811320/Jupiter_Hell/ 13 | 14 | Parts of this codebase date back to 2002, please do not judge! :P 15 | 16 | This FreePascal source code release is provided as is. You can try compiling it using the latest version of Lazarus ( http://www.lazarus-ide.org/ ). You will also need the FPC Valkyrie library ( https://github.com/ChaosForge/fpcvalkyrie/ ), version 0.9.0. You will also probably need the binary files of the full game downloadable from http://drl.chaosforge.org/ (in particular the sound, soundhq, music and mp3 folder contents, and the premade drl.wad and core.wad if you don't want to create it yourself). 17 | 18 | Compilation instructions, short version: 19 | 20 | 1. Download DRL from http://drl.chaosforge.org/ 21 | 2. Copy bin/mp3, bin/music, bin/sound, bin/soundhq from the DRL folders to the source tree bin folder 22 | 3. Download 64-bit Lazarus 23 | 4. Open src/makewad.lpi build, do not run 24 | 5. Run makewad.exe from the command line in the bin folder to generate drl.wad and core.wad (precompiled lua files) 25 | 6. Open src/drl.lpi, build and run 26 | 7. Profit (?) 27 | 28 | Lua makefile path (tested on Windows, might work on Linux): 29 | 30 | 1. Have lua (5.1 is tested, but any should work?) in your path 31 | 2. Have fpc bin directory in your path 32 | 3. From the root folder run lua5.1 makefile.lua 33 | 4. You can build packages by running "lua5.1 makefile.lua all" or lq or hq 34 | 35 | All code is (C) 2003-2024 Kornel Kisielewicz 36 | 37 | Code is distributed under the GPL 2.0 license (see LICENSE file in this folder) 38 | 39 | Original art and sprites (0.9.9.7) by Derek Yu, (C) 2003-2024, licensed under CC BY-SA 4.0. Modified version and additions (0.9.9.8+) by Łukasz Śliwiński, (C) 2024, licensed under CC BY-SA 4.0. 40 | 41 | All art is distributed under the CC-BY-SA 4.0 license (see LICENSE file in the bin/graphics/ folder). 42 | 43 | sincerely, 44 | Kornel Kisielewicz 45 | ChaosForge -------------------------------------------------------------------------------- /bin/backup/!readme.txt: -------------------------------------------------------------------------------- 1 | Player and Score backup. 2 | 3 | To control the amount of files see PlayerBackups and ScoreBackups variables in doomrl.ini. -------------------------------------------------------------------------------- /bin/colors.lua: -------------------------------------------------------------------------------- 1 | -- Custom coloring based on entity ID's. Search the DRL wiki 2 | -- for id's for entities. 3 | -- 4 | -- In case of cells, there are two overrides - [id]_light and [id]_dark 5 | -- [id]_dark cells are out of vision, [id]_light cells are ones you can see. 6 | 7 | -- Colors can be: 8 | BLUE = 1 9 | GREEN = 2 10 | CYAN = 3 11 | RED = 4 12 | MAGENTA = 5 13 | BROWN = 6 14 | LIGHTGRAY = 7 15 | DARKGRAY = 8 16 | LIGHTBLUE = 9 17 | LIGHTGREEN = 10 18 | LIGHTCYAN = 11 19 | LIGHTRED = 12 20 | LIGHTMAGENTA= 13 21 | YELLOW = 14 22 | WHITE = 15 23 | 24 | -- An example of how to change DRL's color scheme. 25 | Colors = { 26 | -- floor_dark = GREEN, 27 | -- floor_light = BLUE, 28 | -- former = BLUE, 29 | -- demon = GREEN, 30 | } 31 | -------------------------------------------------------------------------------- /bin/compile.txt: -------------------------------------------------------------------------------- 1 | ASCII help/logo.dat 2 | ASCII help/arachno.asc 3 | ASCII help/barmor.asc 4 | ASCII help/baron.asc 5 | ASCII help/cacodemon.asc 6 | ASCII help/captain.asc 7 | ASCII help/commando.asc 8 | ASCII help/cyberdemon.asc 9 | ASCII help/demon.asc 10 | ASCII help/former.asc 11 | ASCII help/garmor.asc 12 | ASCII help/imp.asc 13 | ASCII help/knight.asc 14 | ASCII help/player.asc 15 | ASCII help/rarmor.asc 16 | ASCII help/sergeant.asc 17 | ASCII help/lostsoul.asc 18 | ARCHI data/archi.txt 19 | HELP help/intro.hlp Introduction 20 | HELP help/start.hlp Getting_Started 21 | HELP help/keys.hlp Keybindings 22 | HELP help/feedback.hlp Feedback 23 | HELP help/credits.hlp Credits 24 | HELP help/disclaim.hlp Disclaimer 25 | LUA lua/enum.lua 26 | LUA lua/constants.lua 27 | LUA lua/functions.lua 28 | LUA lua/core.lua 29 | LUA lua/main.lua 30 | LUA lua/affects.lua 31 | LUA lua/medals.lua 32 | LUA lua/missiles.lua 33 | LUA lua/items.lua 34 | LUA lua/eitems.lua 35 | LUA lua/uitems.lua 36 | LUA lua/cells.lua 37 | LUA lua/traits.lua 38 | LUA lua/beings.lua 39 | LUA lua/ranks.lua 40 | LUA lua/plot.lua 41 | LUA lua/challenge.lua 42 | LUA lua/levels/boss.lua 43 | LUA lua/levels/hellgate.lua 44 | LUA lua/levels/arena.lua 45 | LUA lua/levels/fortress.lua 46 | LUA lua/levels/intro.lua 47 | LUA lua/levels/chained.lua 48 | LUA lua/levels/carnage.lua 49 | LUA lua/levels/armory.lua 50 | LUA lua/levels/spider.lua 51 | LUA lua/levels/skulls.lua 52 | LUA lua/levels/wall.lua 53 | LUA lua/levels/vaults.lua 54 | LUA lua/levels/mortuary.lua 55 | LUA lua/levels/lavapits.lua 56 | -------------------------------------------------------------------------------- /bin/core/commands.lua: -------------------------------------------------------------------------------- 1 | COMMAND_WAIT = 10; 2 | COMMAND_ENTER = 13; 3 | COMMAND_UNLOAD = 14; 4 | COMMAND_PICKUP = 15; 5 | COMMAND_DROP = 16; 6 | COMMAND_ALTFIRE = 23; 7 | COMMAND_FIRE = 24; 8 | COMMAND_USE = 25; 9 | COMMAND_SAVE = 27; 10 | COMMAND_TACTIC = 28; 11 | COMMAND_SWAPWEAPON = 34; 12 | COMMAND_ACTION = 43; 13 | COMMAND_ALTPICKUP = 44; 14 | COMMAND_RELOAD = 45; 15 | COMMAND_ALTRELOAD = 46; 16 | COMMAND_MELEE = 47; 17 | COMMAND_MOVE = 48; 18 | COMMAND_WEAR = 49; 19 | COMMAND_SWAP = 50; 20 | COMMAND_TAKEOFF = 51; 21 | COMMAND_QUICKKEY = 52; 22 | 23 | 24 | -------------------------------------------------------------------------------- /bin/core/constants.lua: -------------------------------------------------------------------------------- 1 | MAXX = 78; 2 | MAXY = 20; 3 | MAXAFFECT = 12; 4 | MAX_INV_SIZE = 22; 5 | MAX_EQ_SIZE = 4; 6 | 7 | ENTITY_BEING = 1; 8 | ENTITY_ITEM = 2; 9 | 10 | LFEXPLORED = 0; 11 | LFVISIBLE = 1; 12 | LFLIGHTED = 2; 13 | LFDAMAGE = 3; 14 | LFFRESH = 4; 15 | LFNOSPAWN = 5; 16 | LFPERMANENT= 6; 17 | LFCORNER = 7; 18 | LFBLOOD = 8; 19 | LFMARKER1 = 9; 20 | LFMARKER2 = 10; 21 | LFANIMATING= 11; 22 | 23 | DRL_SPRITESHEET_ENVIRO = 1; 24 | DRL_SPRITESHEET_DOODAD = 2; 25 | DRL_SPRITESHEET_ITEMS = 3; 26 | DRL_SPRITESHEET_BEINGS = 4; 27 | DRL_SPRITESHEET_PLAYER = 5; 28 | DRL_SPRITESHEET_LARGE = 6; 29 | DRL_SPRITESHEET_FX = 7; 30 | 31 | DRL_SENVIRO = DRL_SPRITESHEET_ENVIRO * 100000; 32 | DRL_SDOODAD = DRL_SPRITESHEET_DOODAD * 100000; 33 | DRL_SITEMS = DRL_SPRITESHEET_ITEMS * 100000; 34 | DRL_SBEINGS = DRL_SPRITESHEET_BEINGS * 100000; 35 | DRL_SPLAYER = DRL_SPRITESHEET_PLAYER * 100000; 36 | DRL_SLARGE = DRL_SPRITESHEET_LARGE * 100000; 37 | DRL_SFX = DRL_SPRITESHEET_FX * 100000; 38 | 39 | DRL_COLS = 16; 40 | 41 | HARDSPRITE_PLAYER = DRL_SPLAYER + 1; 42 | HARDSPRITE_HIT = DRL_SFX + 4; 43 | HARDSPRITE_EXPL = DRL_SFX + 8; 44 | HARDSPRITE_SELECT = DRL_SFX + 14; 45 | HARDSPRITE_MARK = DRL_SFX + 15; 46 | HARDSPRITE_GRID = DRL_SFX + DRL_COLS + 16; 47 | 48 | CELLSET_WALLS = 1; 49 | CELLSET_FLOORS = 2; 50 | CELLSET_CORPSES = 3; 51 | 52 | CF_BLOCKMOVE = 1; 53 | CF_BLOCKLOS = 2; 54 | CF_CORPSE = 3; 55 | CF_NOCHANGE = 4; 56 | CF_NORUN = 5; 57 | CF_PUSHABLE = 6; 58 | CF_FRAGILE = 7; 59 | CF_HAZARD = 8; 60 | CF_OVERLAY = 9; 61 | 62 | CF_STICKWALL = 11; 63 | CF_LIQUID = 12; 64 | CF_OPENABLE = 13; 65 | CF_CLOSABLE = 14; 66 | CF_RUNSTOP = 15; 67 | CF_NUKABLE = 16; 68 | CF_CRITICAL = 17; 69 | CF_HIGHLIGHT = 18; 70 | CF_VBLOODY = 20; 71 | CF_STAIRS = 21; 72 | CF_RAISABLE = 22; 73 | CF_STAIRSENSE = 23; 74 | 75 | BF_BOSS = 1; 76 | BF_ENVIROSAFE = 2; 77 | BF_CHARGE = 3; 78 | BF_OPENDOORS = 4; 79 | BF_NODROP = 5; 80 | BF_NOEXP = 6; 81 | BF_QUICKSWAP = 7; 82 | BF_HUNTING = 8; 83 | BF_BACKPACK = 9; 84 | BF_UNIQUENAME = 10; 85 | BF_IMPATIENT = 11; 86 | BF_SHOTTYMAN = 12; 87 | BF_ROCKETMAN = 13; 88 | BF_BERSERKER = 14; 89 | BF_DARKNESS = 15; 90 | BF_DUALGUN = 16; 91 | BF_POWERSENSE = 17; 92 | BF_BEINGSENSE = 18; 93 | BF_LEVERSENSE1 = 19; 94 | BF_LEVERSENSE2 = 20; 95 | BF_NOMELEE = 21; 96 | BF_CLEAVE = 22; 97 | BF_MAXDAMAGE = 23; 98 | BF_SESSILE = 24; 99 | BF_VAMPYRE = 25; 100 | BF_REGENERATE = 26; 101 | BF_ARMYDEAD = 27; 102 | BF_FIREANGEL = 28; 103 | BF_GUNKATA = 29; 104 | BF_AMMOCHAIN = 30; 105 | BF_MASTERDODGE = 31; 106 | BF_INV = 32; 107 | BF_BERSERK = 33; 108 | BF_NORUNPENALTY = 34; 109 | BF_PISTOLMAX = 35; 110 | BF_MEDPLUS = 36; 111 | BF_HARDY = 37; 112 | BF_SCAVENGER = 38; 113 | BF_INSTAUSE = 39; 114 | BF_STAIRSENSE = 40; 115 | BF_POWERBONUS = 41; 116 | BF_MAPEXPERT = 42; 117 | BF_DUALBLADE = 43; 118 | BF_BLADEDEFEND = 44; 119 | BF_BULLETDANCE = 45; 120 | BF_SHOTTYHEAD = 46; 121 | BF_ENTRENCHMENT = 47; 122 | BF_MODEXPERT = 48; 123 | BF_SELFIMMUNE = 49; 124 | BF_KNOCKIMMUNE = 50; 125 | BF_NOHEAL = 51; 126 | BF_GUNRUNNER = 52; 127 | 128 | IF_UNIQUE = 21; 129 | IF_EXOTIC = 22; 130 | IF_MODIFIED = 23; 131 | IF_CURSED = 24; 132 | IF_CHAMBEREMPTY = 25; 133 | IF_HALFKNOCK = 26; 134 | IF_GLOBE = 27; 135 | IF_RECHARGE = 28; 136 | IF_CLEAVE = 29; 137 | IF_NOAMMO = 30; 138 | IF_NECROCHARGE = 31; 139 | IF_PUMPACTION = 32; 140 | IF_SINGLERELOAD = 33; 141 | IF_PISTOL = 34; 142 | IF_SHOTGUN = 35; 143 | IF_ROCKET = 36; 144 | IF_SPREAD = 37; 145 | IF_SCATTER = 38; 146 | IF_SINGLEMOD = 39; 147 | IF_DUALSHOTGUN = 40; 148 | IF_AIHEALPACK = 41; 149 | IF_NOUNLOAD = 42; 150 | IF_NUKERESIST = 43; 151 | IF_NODROP = 44; 152 | IF_AUTOHIT = 45; 153 | IF_SETITEM = 46; 154 | IF_NODURABILITY = 47; 155 | IF_NODESTROY = 48; 156 | IF_NONMODABLE = 49; 157 | IF_NOREPAIR = 50; 158 | IF_ASSEMBLED = 51; 159 | IF_DESTROY = 52; 160 | IF_BLADE = 53; 161 | IF_DESTRUCTIVE = 54; 162 | IF_FARHIT = 55; 163 | IF_UNSEENHIT = 56; 164 | IF_NODEGRADE = 57; 165 | IF_MODABLE = 58; 166 | IF_THROWDROP = 59; 167 | IF_PLURALNAME = 60; 168 | 169 | LF_NOHOMING = 1; 170 | LF_UNIQUEITEM = 2; 171 | LF_BONUS = 3; 172 | LF_SCRIPT = 4; 173 | LF_NORESPAWN = 5; 174 | LF_NUKED = 6; 175 | LF_NONUKE = 7; 176 | LF_ITEMSVISIBLE = 8; 177 | LF_BEINGSVISIBLE = 9; 178 | LF_RESPAWN = 10; 179 | LF_SHARPFLUID = 11; 180 | LF_BOSS = 12; 181 | 182 | SF_LARGE = 1; 183 | SF_OVERLAY = 2; 184 | SF_COSPLAY = 3; 185 | SF_GLOW = 4; 186 | SF_FLOW = 5; 187 | SF_FLUID = 6; 188 | SF_MULTI = 7; 189 | SF_FLOOR = 8; 190 | 191 | EF_NOBLOCK = 0; 192 | EF_NOBEINGS = 1; 193 | EF_NOITEMS = 2; 194 | EF_NOVISION = 3; 195 | EF_NOSTAIRS = 4; 196 | EF_NOTELE = 5; 197 | EF_NOHARM = 6; 198 | EF_NOSAFE = 7; 199 | EF_NOSPAWN = 8; 200 | 201 | DIFF_EASY = 1; 202 | DIFF_MEDIUM = 2; 203 | DIFF_HARD = 3; 204 | DIFF_VERYHARD = 4; 205 | DIFF_NIGHTMARE = 5; 206 | 207 | SLOT_ARMOR = EFTORSO; 208 | SLOT_WEAPON = EFWEAPON; 209 | SLOT_BOOTS = EFBOOTS; 210 | SLOT_PREPARED = EFWEAPON2; 211 | 212 | MF_RAY = 1; 213 | MF_HARD = 2; 214 | MF_EXACT = 3; 215 | MF_IMMIDATE = 4; 216 | 217 | MULTIBLUE = 17; 218 | MULTIYELLOW = 18; 219 | MULTIPORTAL = 20; 220 | 221 | COLOR_WATER = 21; 222 | COLOR_ACID = 22; 223 | COLOR_LAVA = 23; 224 | 225 | FRAME_TIME = 500; 226 | 227 | 228 | -------------------------------------------------------------------------------- /bin/core/functions.lua: -------------------------------------------------------------------------------- 1 | -- utils 2 | function seconds_to_string( secs ) 3 | local function plural( name, v ) 4 | if v == 0 then return nil end 5 | if v > 1 then 6 | return v.." "..name.."s" 7 | else 8 | return v.." "..name 9 | end 10 | end 11 | 12 | if secs <= 0 then return "0 seconds" end 13 | 14 | local sec = plural( "second", secs % 60 ) 15 | local min = plural( "minute", math.floor( secs / 60 ) % 60 ) 16 | local hour = plural( "hour", math.floor( secs / (60*60) ) % 24 ) 17 | local day = plural( "day", math.floor( secs / (60*60*24) ) ) 18 | local arr = {} 19 | if day then table.insert(arr, day) end 20 | if hour then table.insert(arr, hour) end 21 | if min then table.insert(arr, min) end 22 | if sec then table.insert(arr, sec) end 23 | 24 | if #arr > 1 then 25 | arr[ #arr - 1 ] = arr[ #arr - 1 ].." and "..arr[ #arr ] 26 | table.remove( arr ) 27 | end 28 | return table.concat(arr, ", ") 29 | end 30 | 31 | function resolverange(range) 32 | if type(range) == "number" then return range end 33 | if type(range) ~= "table" then error("bad range designation!") end 34 | return range[1] + math.random(range[2]-range[1]+1) - 1 35 | end 36 | -------------------------------------------------------------------------------- /bin/core/item.lua: -------------------------------------------------------------------------------- 1 | table.merge( item, thing ) 2 | 3 | function item:is_damaged() 4 | if self.flags[ IF_NOREPAIR ] then return false end 5 | return self.durability < self.maxdurability 6 | end 7 | 8 | function item:fix( amount ) 9 | if amount == nil then 10 | self.durability = self.maxdurability 11 | return true 12 | else 13 | self.durability = math.min(self.maxdurability, self.durability + amount) 14 | return not self:is_damaged() 15 | end 16 | end 17 | 18 | function item:get_mods() 19 | local mods = {} 20 | for c=string.byte("A"),string.byte("Z") do 21 | local count = self:get_mod(string.char(c)) 22 | if count > 0 then 23 | mods[string.char(c)] = count 24 | end 25 | end 26 | return mods 27 | end 28 | 29 | function item:get_mod_ids() 30 | local mods = {} 31 | 32 | local function find( mod_letter ) 33 | for _,i in ipairs( items ) do 34 | if i.mod_letter == mod_letter then 35 | return i.id 36 | end 37 | end 38 | return nil 39 | end 40 | 41 | for c=string.byte("A"),string.byte("Z") do 42 | local count = self:get_mod(string.char(c)) 43 | if count > 0 then 44 | local id = find( string.char(c) ) 45 | if id then table.insert( mods, id ) end 46 | end 47 | end 48 | return mods 49 | end 50 | 51 | function item:can_overcharge( msg ) 52 | if self.flags[ IF_DESTROY ] then 53 | ui.msg("The "..self.name.." is already overcharged!") 54 | return false 55 | end 56 | if self.ammo ~= self.ammomax then 57 | ui.msg("You need a full magazine to overcharge the "..self.name.."!") 58 | return false 59 | end 60 | if not ui.msg_confirm("Are you sure you want to overcharge the "..self.name.."? "..msg, true) then 61 | ui.msg("Chicken.") 62 | return false 63 | end 64 | self.flags[ IF_DESTROY ] = true 65 | self.flags[ IF_NOUNLOAD ] = true 66 | ui.msg("You overcharge the "..self.name.."!") 67 | self.name = "overcharged "..self.name 68 | return true 69 | end 70 | 71 | function item:check_mod_array( nextmod, techbonus ) 72 | if self.flags[ IF_ASSEMBLED ] then return false end 73 | if not self.flags[ IF_MODIFIED ] then return false end 74 | 75 | local function match( sig,mod_array_proto ) 76 | if sig ~= mod_array_proto.sig then return false end 77 | if mod_array_proto.request_id and mod_array_proto.request_id ~= self.id then return false end 78 | if mod_array_proto.request_type and mod_array_proto.request_type ~= self.itype then return false end 79 | if mod_array_proto.Match and not mod_array_proto.Match(self) then return false end 80 | if mod_array_proto.level and mod_array_proto.level > techbonus then return false end 81 | return true 82 | end 83 | 84 | 85 | local mods = self:get_mods() 86 | if mods[nextmod] then 87 | mods[nextmod] = mods[nextmod] + 1 88 | else 89 | mods[nextmod] = 1 90 | end 91 | local modsig = core.mod_list_signature( mods ) 92 | 93 | 94 | local found_mod_array = nil 95 | for _,ma in ipairs(mod_arrays) do 96 | if match(modsig,ma) then 97 | found_mod_array = ma 98 | break 99 | end 100 | end 101 | 102 | if not found_mod_array then 103 | return false 104 | end 105 | 106 | -- Consider making this string shorter? (e.g. "Special assembly possible! Assemble the "..found_mod_array.name.."?") 107 | if not ui.msg_confirm("Special assembly possible! Do you want to assemble the "..found_mod_array.name.."?") then return false end 108 | ui.msg("You assemble the "..found_mod_array.name..".") 109 | found_mod_array.OnApply(self) 110 | self.color = LIGHTCYAN 111 | self.flags[ IF_MODIFIED ] = false 112 | self.flags[ IF_ASSEMBLED ] = true 113 | self:clear_mods() 114 | player:add_assembly( found_mod_array.id ) 115 | -- Maybe we should add something that handles the correct article 116 | player:add_history("On level @1 he assembled a "..found_mod_array.name.."!") 117 | return true 118 | end 119 | 120 | setmetatable(item,getmetatable(thing)) 121 | -------------------------------------------------------------------------------- /bin/core/player.lua: -------------------------------------------------------------------------------- 1 | function player:remove_medals( medallist ) 2 | if medallist then 3 | for _,v in ipairs( medallist ) do 4 | self:remove_medal( v ) 5 | end 6 | end 7 | end 8 | 9 | function player:remove_award( award ) 10 | self.__props.awards[award] = nil 11 | end 12 | 13 | function player:set_award( award, level ) 14 | self.__props.awards[award] = level 15 | end 16 | 17 | function player:has_award( award, level ) 18 | return self.__props.awards[award] and self.__props.awards[award] >= (level or 1) 19 | end 20 | 21 | function player:get_award( award ) 22 | return self.__props.awards[award] 23 | end 24 | 25 | function player:remove_medal( medal ) 26 | self.__props.medals[medal] = nil 27 | end 28 | 29 | function player:add_medal( medal ) 30 | self.__props.medals[medal] = true 31 | end 32 | 33 | function player:has_medal( medal ) 34 | return self.__props.medals[medal] 35 | end 36 | 37 | function player:remove_badge( badge ) 38 | self.__props.badges[badge] = nil 39 | end 40 | 41 | function player:add_badge( badge ) 42 | self.__props.badges[badge] = true 43 | end 44 | 45 | function player:has_badge( badge ) 46 | return self.__props.badges[badge] 47 | end 48 | 49 | function player:remove_assembly( assembly ) 50 | self.__props.assemblies[assembly] = nil 51 | end 52 | 53 | function player:add_assembly( assembly ) 54 | self.__props.assemblies[assembly] = ( self.__props.assemblies[assembly] or 0 ) + 1 55 | end 56 | 57 | function player:has_assembly( assembly ) 58 | return self.__props.assemblies[assembly] 59 | end 60 | 61 | function player:remove_found_item( found_item_id ) 62 | self.__props.items_found[found_item_id] = nil 63 | end 64 | 65 | function player:add_found_item( found_item_id ) 66 | self.__props.items_found[found_item_id] = true 67 | end 68 | 69 | function player:has_found_item( found_item_id ) 70 | return self.__props.items_found[found_item_id] 71 | end 72 | 73 | function player:add_history( history ) 74 | if history then 75 | table.insert( self.__props.history, (string.gsub( history, "@1", self.depth )) ) 76 | end 77 | end 78 | 79 | table.merge( player, being ) 80 | setmetatable(player,getmetatable(being)) 81 | -------------------------------------------------------------------------------- /bin/core/thing.lua: -------------------------------------------------------------------------------- 1 | table.merge( thing, game_object ) 2 | setmetatable( thing, getmetatable(game_object) ) 3 | -------------------------------------------------------------------------------- /bin/core/ui.lua: -------------------------------------------------------------------------------- 1 | ui.msg_feel = function(msg) 2 | if type(msg) ~= "string" then return end 3 | if level.feeling == "" then 4 | level.feeling = msg 5 | else 6 | level.feeling = level.feeling .. " " .. msg 7 | end 8 | ui.msg(msg) 9 | end 10 | 11 | ui.repeat_feel = function() 12 | ui.msg(level.feeling) 13 | end 14 | 15 | ui.clear_feel = function() 16 | level.feeling = "" 17 | end 18 | -------------------------------------------------------------------------------- /bin/danger_report.pl: -------------------------------------------------------------------------------- 1 | open(FILE,"danger.txt"); 3 | open(CSV,">danger.csv"); 4 | 5 | while ($line = ) { 6 | $line =~ /(\d+).*\[DIFF (\d)\] -- (\d+)/; 7 | print "Level $1 (D$2) -- $3\n"; 8 | push @{ $diff[$2][$1] }, $3; 9 | } 10 | 11 | for $dlevel (1..5) { 12 | if (not defined ($diff[$dlevel][1])) { next; } 13 | print OUT "\nDanger Level $dlevel\n--------------\n"; 14 | 15 | for $level (1..24) { 16 | if (not defined ($diff[$dlevel][$level])) { next; } 17 | 18 | $total = 0; 19 | $row = $diff[$dlevel][$level]; 20 | foreach $item (@$row) { 21 | $total += $item; 22 | } 23 | $avg = int($total / scalar @$row); 24 | print OUT "Average L$level = $avg\n"; 25 | print CSV "$avg,"; 26 | } 27 | print CSV "\n"; 28 | } 29 | 30 | close(FILE); 31 | close(OUT); 32 | close(CSV); 33 | -------------------------------------------------------------------------------- /bin/dkey.inc: -------------------------------------------------------------------------------- 1 | const LoveLace : TIDEAKey = ( 56081, 64896, 64768, 60809, 16384, 8193, 8, 32741, 49151, 47954, 15, 24589, 52020, 61984, 65344, 5780, 1968, 1776, 39319, 65520, 40954, 65025, 55299, 30720, 34697, 63488, 12288, 23832, 444, 40, 23120, 65504, 65532, 20114, 48, 888, 24757, 61440, 65024, 56478, 6145, 48128, 1, 8704, 65528, 26202, 222, 90, 14919, 65425, 65526, 38230 ); 2 | -------------------------------------------------------------------------------- /bin/drl_console.bat: -------------------------------------------------------------------------------- 1 | mode con lines=25 cols=80 2 | mode con cp select=437 3 | drl -console -------------------------------------------------------------------------------- /bin/drl_gnome-terminal: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | gnome-terminal --geometry=80x25 -e "./drl -console" 5 | -------------------------------------------------------------------------------- /bin/drl_konsole: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | # There doesn't seem to be any way to force konsole size. 5 | # --geometry=80x25 doesn't work at all, AFAI can see. 6 | # for older konsole versions, --vt_sz 80x25 should do the trick. 7 | 8 | konsole --workdir=`pwd` -e ./drl -console 9 | -------------------------------------------------------------------------------- /bin/drl_xterm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | xterm -geometry 80x25 -e ./drl -console 5 | -------------------------------------------------------------------------------- /bin/font10x18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/font10x18.png -------------------------------------------------------------------------------- /bin/godmode.lua: -------------------------------------------------------------------------------- 1 | -- ---------------------------------------------------------------------- 2 | -- This is the DoomRL initialization file. Modify at your own risk :). 3 | -- If you mess up something overwrite with a new godmode.lua. 4 | -- ---------------------------------------------------------------------- 5 | 6 | dofile "confighq.lua" 7 | 8 | SoundEngine = "DEFAULT" 9 | 10 | LockBreak = false 11 | LockClose = false 12 | SaveOnCrash = false 13 | 14 | Keytable = {} 15 | 16 | -- God commands 17 | Keytable["W"] = function() 18 | ui.msg('Invulnerability!') 19 | player:set_affect("inv",50) 20 | end 21 | 22 | -- XXX Does this even work? 23 | Keytable["SHIFT+BACKSPACE"] = function() 24 | ui.msg('Supercharge!') 25 | player.hp = 2 * player.hpmax 26 | end 27 | Keytable["BACKSPACE"] = function() 28 | ui.msg('Heal!') 29 | player.hp = player.hpmax 30 | end 31 | Keytable["BQUOTE"] = function() 32 | ui.msg('Home!') 33 | player:phase("stairs") 34 | end 35 | Keytable["SHIFT+3"] = function() 36 | if player:is_affect( "inv" ) then 37 | player:remove_affect( "inv" ) 38 | else 39 | ui.msg('Invulnerability!') 40 | player:set_affect("inv", 5000) 41 | end 42 | end 43 | Keytable["SHIFT+4"] = function() 44 | if player:is_affect( "berserk" ) then 45 | player:remove_affect( "berserk" ) 46 | else 47 | ui.msg('Berserk!') 48 | player:set_affect("berserk", 5000) 49 | end 50 | end 51 | Keytable["SHIFT+5"] = function() 52 | if player:is_affect( "enviro" ) then 53 | player:remove_affect( "enviro" ) 54 | else 55 | ui.msg('Enviro!') 56 | player:set_affect("enviro", 5000) 57 | end 58 | end 59 | 60 | Keytable["F3"] = function() 61 | ui.msg('Next level!') 62 | player:exit() 63 | end 64 | Keytable["F4"] = function() 65 | ui.msg('Endgame!') 66 | -- Different ending floors for different challenges (this should be fairly independent code) 67 | player:exit(table.getn(player.episode)) 68 | end 69 | Keytable["F5"] = function() 70 | ui.msg('+500 Experience!') 71 | player:add_exp(500) 72 | end 73 | Keytable["F6"] = function() 74 | ui.msg('ARMAGEDDON!') 75 | for b in level:beings() do 76 | if not b:is_player() then 77 | b:kill() 78 | end 79 | end 80 | end 81 | Keytable["F7"] = function() 82 | ui.msg('Teleport!') 83 | player:phase() 84 | end 85 | Keytable["F8"] = function() 86 | player.inv:clear() 87 | ui.msg('idkfa!') 88 | player.inv:add( 'ashotgun' ) 89 | player.inv:add( 'unbfg9000') 90 | player.inv:add( 'uberetta') 91 | player.inv:add( 'uberarmor') 92 | player.inv:add( 'utrigun') 93 | player.inv:add( 'urailgun') 94 | player.inv:add( 'udragon') 95 | for i = 1,5 do 96 | player.inv:add( 'cell', { ammo = 50 } ) 97 | end 98 | for i = 1,4 do 99 | player.inv:add( 'shell', { ammo = 50 } ) 100 | end 101 | end 102 | Keytable["BSLASH"] = function() 103 | ui.msg('Visibility!') 104 | level.flags[ LF_BEINGSVISIBLE ] = not level.flags[ LF_BEINGSVISIBLE ] 105 | level.flags[ LF_ITEMSVISIBLE ] = not level.flags[ LF_ITEMSVISIBLE ] 106 | end 107 | -------------------------------------------------------------------------------- /bin/graphics/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/background.png -------------------------------------------------------------------------------- /bin/graphics/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/cursor.png -------------------------------------------------------------------------------- /bin/graphics/doom.ini: -------------------------------------------------------------------------------- 1 | [Char Widths] 2 | 0=12 3 | 1=10 4 | 2=17 5 | 3=20 6 | 4=21 7 | 5=22 8 | 6=20 9 | 7=7 10 | 8=12 11 | 9=11 12 | 10=13 13 | 11=16 14 | 12=8 15 | 13=16 16 | 14=8 17 | 15=17 18 | 16=20 19 | 17=14 20 | 18=20 21 | 19=20 22 | 20=20 23 | 21=20 24 | 22=20 25 | 23=20 26 | 24=20 27 | 25=20 28 | 26=8 29 | 27=8 30 | 28=19 31 | 29=16 32 | 30=19 33 | 31=21 34 | 32=24 35 | 33=24 36 | 34=25 37 | 35=23 38 | 36=25 39 | 37=23 40 | 38=20 41 | 39=25 42 | 40=25 43 | 41=10 44 | 42=18 45 | 43=27 46 | 44=18 47 | 45=27 48 | 46=27 49 | 47=28 50 | 48=25 51 | 49=28 52 | 50=25 53 | 51=25 54 | 52=20 55 | 53=25 56 | 54=27 57 | 55=27 58 | 56=26 59 | 57=26 60 | 58=27 61 | 59=11 62 | 60=17 63 | 61=11 64 | 62=12 65 | 63=23 66 | 64=9 67 | 65=18 68 | 66=18 69 | 67=17 70 | 68=18 71 | 69=17 72 | 70=14 73 | 71=18 74 | 72=18 75 | 73=7 76 | 74=13 77 | 75=19 78 | 76=13 79 | 77=19 80 | 78=19 81 | 79=20 82 | 80=18 83 | 81=20 84 | 82=18 85 | 83=18 86 | 84=14 87 | 85=18 88 | 86=19 89 | 87=19 90 | 88=19 91 | 89=19 92 | 90=19 93 | 91=10 94 | 92=6 95 | 93=10 96 | 94=13 97 | 95=7 98 | 96=13 99 | 97=0 100 | 98=7 101 | 99=13 102 | 100=17 103 | 101=15 104 | 102=16 105 | 103=13 106 | 104=8 107 | 105=22 108 | 106=26 109 | 107=8 110 | 108=22 111 | 109=0 112 | 110=26 113 | 111=0 114 | 112=0 115 | 113=26 116 | 114=26 117 | 115=26 118 | 116=26 119 | 117=8 120 | 118=7 121 | 119=13 122 | 120=0 123 | 121=19 124 | 122=26 125 | 123=8 126 | 124=21 127 | 125=0 128 | 126=26 129 | 127=26 130 | 128=8 131 | 129=7 132 | 130=12 133 | 131=14 134 | 132=15 135 | 133=16 136 | 134=14 137 | 135=5 138 | 136=8 139 | 137=7 140 | 138=9 141 | 139=11 142 | 140=5 143 | 141=11 144 | 142=5 145 | 143=12 146 | 144=14 147 | 145=10 148 | 146=14 149 | 147=14 150 | 148=14 151 | 149=14 152 | 150=14 153 | 151=14 154 | 152=14 155 | 153=14 156 | 154=5 157 | 155=5 158 | 156=14 159 | 157=11 160 | 158=14 161 | 159=15 162 | 160=18 163 | 161=17 164 | 162=18 165 | 163=17 166 | 164=18 167 | 165=17 168 | 166=14 169 | 167=18 170 | 168=18 171 | 169=7 172 | 170=13 173 | 171=20 174 | 172=13 175 | 173=20 176 | 174=20 177 | 175=21 178 | 176=18 179 | 177=21 180 | 178=18 181 | 179=18 182 | 180=14 183 | 181=18 184 | 182=20 185 | 183=20 186 | 184=19 187 | 185=19 188 | 186=20 189 | 187=8 190 | 188=12 191 | 189=8 192 | 190=9 193 | 191=17 194 | 192=6 195 | 193=13 196 | 194=13 197 | 195=12 198 | 196=13 199 | 197=12 200 | 198=10 201 | 199=13 202 | 200=13 203 | 201=5 204 | 202=9 205 | 203=14 206 | 204=9 207 | 205=14 208 | 206=14 209 | 207=14 210 | 208=13 211 | 209=14 212 | 210=13 213 | 211=13 214 | 212=10 215 | 213=13 216 | 214=14 217 | 215=14 218 | 216=14 219 | 217=14 220 | 218=14 221 | 219=7 222 | 220=4 223 | 221=7 224 | 222=9 225 | 223=5 226 | 224=9 227 | 225=0 228 | 226=4 229 | 227=9 230 | 228=12 231 | 229=11 232 | 230=11 233 | 231=9 234 | 232=5 235 | 233=16 236 | 234=19 237 | 235=6 238 | 236=16 239 | 237=0 240 | 238=19 241 | 239=0 242 | 240=0 243 | 241=19 244 | 242=19 245 | 243=19 246 | 244=19 247 | 245=8 248 | 246=6 249 | 247=14 250 | 248=0 251 | 249=14 252 | 250=19 253 | 251=6 254 | 252=15 255 | 253=0 256 | 254=19 257 | 255=19 258 | -------------------------------------------------------------------------------- /bin/graphics/doom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doom.png -------------------------------------------------------------------------------- /bin/graphics/doomguy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doomguy.png -------------------------------------------------------------------------------- /bin/graphics/doomguy_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doomguy_mask.png -------------------------------------------------------------------------------- /bin/graphics/doomguy_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doomguy_shadow.png -------------------------------------------------------------------------------- /bin/graphics/doors_and_decorations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doors_and_decorations.png -------------------------------------------------------------------------------- /bin/graphics/doors_and_decorations_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doors_and_decorations_mask.png -------------------------------------------------------------------------------- /bin/graphics/doors_and_decorations_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/doors_and_decorations_shadow.png -------------------------------------------------------------------------------- /bin/graphics/enemies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/enemies.png -------------------------------------------------------------------------------- /bin/graphics/enemies_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/enemies_big.png -------------------------------------------------------------------------------- /bin/graphics/enemies_big_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/enemies_big_shadow.png -------------------------------------------------------------------------------- /bin/graphics/enemies_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/enemies_shadow.png -------------------------------------------------------------------------------- /bin/graphics/fx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/fx.png -------------------------------------------------------------------------------- /bin/graphics/fx_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/fx_mask.png -------------------------------------------------------------------------------- /bin/graphics/guns_and_pickups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/guns_and_pickups.png -------------------------------------------------------------------------------- /bin/graphics/guns_and_pickups_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/guns_and_pickups_mask.png -------------------------------------------------------------------------------- /bin/graphics/guns_and_pickups_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/guns_and_pickups_shadow.png -------------------------------------------------------------------------------- /bin/graphics/levels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/levels.png -------------------------------------------------------------------------------- /bin/graphics/levels_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/levels_mask.png -------------------------------------------------------------------------------- /bin/graphics/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/logo.png -------------------------------------------------------------------------------- /bin/graphics/lut_berserk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/lut_berserk.png -------------------------------------------------------------------------------- /bin/graphics/lut_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/lut_clear.png -------------------------------------------------------------------------------- /bin/graphics/lut_enviro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/lut_enviro.png -------------------------------------------------------------------------------- /bin/graphics/lut_iddqd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/lut_iddqd.png -------------------------------------------------------------------------------- /bin/graphics/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/bin/graphics/message.png -------------------------------------------------------------------------------- /bin/help/angel.asc: -------------------------------------------------------------------------------- 1 | 2 | @R YXi AII 3 | @R IYAWM, ,AR;@r:it@R. 4 | @R VI@d=+@RIM; #BI#RIW#;,IA+@V, @r:t@R= 5 | @R it;@d=@Vt@d=@RtIB#MYRAAXVtt+ @VI=@d.;@r;@R= 6 | @R =Y=@dY@VIXI@d.@RtYi@VB@GY@R+i@GR@VI@Rit= @V=V= @d..@rt@R; 7 | @R :RY+@dt@VtA#@RV@d:@RY+iBMiIRAY+ :@VI+t: @r:@Rt 8 | @R ,AV@dti@V+I@R#AAA=IYYt=IYt++ti@V:: @r,;@Rt 9 | @R ;@d==@RAIIRAI=+,=;=+,,;,iVAY; @r==@R: 10 | @R ;YBAi====@r;@l#@R#+;M@l#@r:@R=tVBRY+::@r=@R, 11 | @R ,RXAt=@r::+++@lA#@R=:@lMM@r;i+i@R=t==IY, 12 | @R +YW#BI;+@r;;:;+: .++;. @R:YAVV. 13 | @R Y#==: +ti@r;:. , ... @R,+IVt= 14 | @R ;XI: AA@r=:+= .;, :, +=. @RtWAI: 15 | @R V#i YBt@r,;+++: ,=+;==,,@R=XBt, 16 | @R X#M@y#@RWi@r==;;,. :t+@R=t@yW@RBYI, 17 | @R XW@yI=@R+Yt+@r;+ @ri@R=:t@y#@RBIi 18 | @R AMI;@r; @RtY+;t@y+@R+; 19 | @R ,iI+=. YAi; 20 | @R VIi tY; 21 | @R RBY. .AYt: 22 | @R ;#M#t :XAt; 23 | @y ;: @R.@yAIt@RY -------------------------------------------------------------------------------- /bin/help/arachno.asc: -------------------------------------------------------------------------------- 1 | @n :.Sr:.Xr, .. 2 | @n 8887XXaZW7:22ZM0i 3 | @n M;S2SX.77ri;rSrZ2770r 4 | @d BZ8 @nSX0ZZ2X@Bi8r@nrZMM@Bi8r@nM028Mi @d ;80 5 | @d MMMMM@lSM@n0a27XX0i8M7 MMZ,Sri0 @d0MM0Mr 6 | @l Mi...r..aa,@nM7,BWMM8@r.7Xa.@nXMMMa0MM8@l..X:7 77.M 7 | @l .i8...8X...X,Z@n:rZZ.0M@rirr;7X@nZM27ZM.@l....7 .M.WW 8 | @l ;i..7Mi B,.;..:BMMMM @dMXXM@l 8MMM:a. WZM 22.M 9 | @l 2...W., 2M..MMMMMMM@dM@yI00I@dM@lMMMMBBM82SS; ,r.SM 10 | @l W...W. .r:iiMMMMMM@dMXXM@lMMMMMMW. 0ZM 78.M 11 | @l ;8...a2 @d,ZSZ@l 0;Z2 12 | @d WM...:8 @d0MBM0@l i;;@dM 13 | @d SMM:ZMMM7 .MMMMMM M7MM2M 14 | @d M:MM:2M ;MMMaM 15 | @d 8MS8MMZM 16 | -------------------------------------------------------------------------------- /bin/help/arch.asc: -------------------------------------------------------------------------------- 1 | @R ,+ 2 | @R +#A +: 3 | @R M@y#I@Ri, :+Y#A: 4 | @R :@y#M. @R=R@y#@RM. 5 | @R .@yW#Y @R,t=@yW#@R+ 6 | @y ##B t##V 7 | @y =A@L#R @y.,:;,, @L.##@yA 8 | @L =##V @yB@LBW@yA @LI#X 9 | @L Y##i.,#WMW ,i##= 10 | @L :BB####X###M##t 11 | @L ,B##R,B##Y+ 12 | @L ,R=;V YV 13 | @L + IM+. 14 | @L =BYttRA 15 | @L :@y#@LXtiV#MI 16 | @L @y#@LXI@d, @L#@y##@L: 17 | @L B@yM@Lt@d, @L,#@y#@LX 18 | @L :Wt@d, @L.B@y#@LI 19 | @L V@dI @LA@y# 20 | @d ;R; @LR@yt 21 | @d AY. i@L@y#@LI 22 | @d W. B@LR 23 | @d +tWI, V 24 | @d .#B+ -------------------------------------------------------------------------------- /bin/help/barmor.asc: -------------------------------------------------------------------------------- 1 | @d =I@lVt@dt;, 2 | @d +R@lY@b;=+=;@lV@dR 3 | @d @d#@l+:YYMW:+@d# 4 | @b .=#@B##@bRY@lI;ItI;i@bi@BVV@bB:. @d. ,tYt: 5 | @b #WWt@BXt@bXX: ;IXR@BIi@b .=@d,tVMB,, 6 | @b . M :+==;; @d,:;tB= @R = 7 | @R ;R#i:@b, @d+VYt+: :.@R,R## 8 | @R ;iRX; @b:t @d;VIt;, ,: @RVItIi: 9 | @R ,Y##@d#Ytt:;,. ,,:@b,+ 10 | @R ,@d ,,.. .,,.@b= ,= 11 | @d tI @R;I@bYI+.+;:=+: 12 | @b :;=:...:=;:,:i 13 | @b :+:;i. ,,:+=,;i 14 | @b .=;:,.;=:.=; 15 | @b ;,,. =@d+RXI+@b: 16 | @b .@d+;;,@l=;=;=; 17 | @d : i=@l=+=I, 18 | @d =@lt:;+Y: 19 | @d ,, =@ltiii 20 | @d t, .@lii+: 21 | @d @ltB#WWt 22 | 23 | -------------------------------------------------------------------------------- /bin/help/baron.asc: -------------------------------------------------------------------------------- 1 | @R @d0Mr@RMMMMMMMM@da00 2 | @R @d,2 @R i2X2ra @d; 3 | @R aM700XrX. 4 | @R XM, BMi 2:,Z7SMMr 5 | @R :aZ. .Sa2ZiXar.Mi7 6 | @R :0M0;M0Bia,,.78Xr :r7MMW 7 | @R Za@M;MSX2r :Xr. i:i;r2MMM8 8 | @R ::r ..r.,iSi:, @G . @R2@nr:@R8@G, 9 | @R .MZ 2MM . @Gi@nrXS@G2.n 10 | @n @R i8M08ZM i2:r: r @G,@nX7S@G:X 11 | @n ,@R 0MM8 i. .i;8r @G Si 12 | @n M @R ,XMMMMM@G8;i0WZ0 a 13 | @n MZ;,@R @G..:2@n000MMMMM@GB 14 | @n Z8.:iSr;7.,@G;@g7,,:,@G;rSi 15 | @n ai:r;;,rZ0W7Z2i7S2a2: 16 | @n B8:,,,::i : :rXX7;;W 17 | @n 00Sri,i ;:i7,:88 18 | @n ;XXrr7i ,ir@WBBMa 19 | @n ZZa7;i. i;r;rS0a 20 | @n :SX:i,: ;r XB0ZZ 21 | @n r@d7i.i.@ni iSSSZaWa 22 | @n @dr;;:ii;@n ,@d:.i :r@nr 23 | @n @d,:ii;;i; 24 | 25 | -------------------------------------------------------------------------------- /bin/help/cacodemon.asc: -------------------------------------------------------------------------------- 1 | @l X 7 7 2 2 | @l MX BM M2 WB 3 | @l ,M8 MM ,M0 WB 4 | @l rBMX 7MM:@r ,r7rr. @l 2MW: .SMW 5 | @l ;ZBM87@r ,S72X7MBrS2XX @l SBMBa, 6 | @l iM8 .;2BMMM@r.;;:;:i:iii;;@liMMM0Xr :BM 7 | @l ;MMM8; iXXSB@r:;::ir;;r:i:;@l7BXXX@r,.@lX0MMM. 8 | @l ,2WBX@r .,,,,:;;i,i:,iri:,:,,..@lXBWX. 9 | @r rr: .,i::..:;77;:..:r77;,..::i, iri 10 | @r ;7;ii;;.@Riii77:.;@r7rii77i@R iXrii@r::riii7X: 11 | @r i .i.,:@R2aX:;27..,. ..,,XS::2Z7@r,.::. i 12 | @r XSi. ,:@R8BZ8027:.;@g:8@yB8@gB:@R:i,;7a0aWZX,@r ,rai 13 | @r .S:i2i:..@Ri28W8X2BZMa:;0MZZSSWW0;.@r .i.::;2 14 | @r irB2 @l2Ma .@R,,,@R72WBBM82MBBBS:.@l rMB@rX.ii,r 15 | @r i. @bi r @lMS7@R .:,..i:,i ,.:,@l2XM@b.X. ; @r.r 16 | @r rXiS@bB ,,Z:i.@l0Z@b;a@l8a@b2iW@l2@b:@b.2.: .,@rMr;X: 17 | @r r77i0@lrM@b .i;:,::,27:,:,i;:, .r@lMS@rai777 18 | @r ;:i7:@lWi@b:.,i;,i;i;ii;;;i:i,;ri@lX8@r:;i:: 19 | @r ri;;,,;,@b,, Z. .... iX ,.@r..;:,r;;i 20 | @r i7 : .777Si:@lMM@b;.@l8 ,8 XM@ri iS7rr, : X. 21 | @r .7::BS:7r78.;8iiMX8X.7Z:iZr7r:aZ.;7 22 | @r @l2MB@rir7;;r:.;ri::;ri.:ri;r7@l;WM, 23 | @r @l::@r ..r;, ,r .,::,..r .ri @l r 24 | @r ,riXi: 77 i;7ir. 25 | -------------------------------------------------------------------------------- /bin/help/captain.asc: -------------------------------------------------------------------------------- 1 | @n .,,,. 2 | @n iMaX720M 3 | @n 8MXX2SSMS 4 | @n M@R.i@n;ir@R.r@n0 5 | @n @rX@nMrZMWMr2M@r@dr8 6 | @r iMMMMMMMM@nBBW@r00@n8M@r0@d0M@rMMMMM 7 | @r MMB2000Wa;r@nX@rWMa@n7@r8@da8@r0BBZaMM, 8 | @n MSXaB8@dW@rW8ZB8@dXS@raBZa80MSiMZ@na:Z0 9 | @n MMMM8Z@dX;@r80M@dMM@gMMMMMZZ8B@r08 @ni7: 10 | @n 8ir8W@da88M@gMW8B0ZaSrMZaBM @y:...@nM 11 | @n M0Z2@d2;8X0@y0@gM088ZZW8ZaWZM @y..8@nMMM 12 | @n BS@d,:XZS@yX.a@gMMZXX0ZWB8W@yMM.. 13 | @d :aS87:SM@yi.iMMMMMMMM8;..@dB 14 | @d MM8Z828Z0@rMZ@y.....ii....Z@dMM 15 | @d MMMMMM@rMMWMMM8S7rXXMM8@dM; 16 | @d X2 @rMM;i;ZWMMMM888ZM 17 | @r MMB8808WM@r82SXaM 18 | @r aMMWW@d08B@rM8888M 19 | @d MMMW8WM@rZZ8MM 20 | @d ,B@raa@d0W8M@r000M 21 | @r MMMMM@dMM@r8BW0MM 22 | @r ;MMM8 XMB0ZMM 23 | @r 82a20. 24 | -------------------------------------------------------------------------------- /bin/help/commando.asc: -------------------------------------------------------------------------------- 1 | @b =IVtt;, 2 | @b +R@lY@r;=@l+@r=;@lV@bR 3 | @b #@l+:YYMW:+@b# 4 | @b .=#@B##@bRYI;@lItI@b;ii@BVV@bB:. @d. ,tYt: 5 | @b #WWt@BXt@bXX: ;IXR@BIi@b .=@d,tVMB,, 6 | @b . M :+==;; @d,:;tB= @R = 7 | @R ;R#@i:@b, @d+VYt+: :.@R,R## 8 | @R ;iRX; @b:t @d;VIt;, ,: @RVItIi: 9 | @R ,Y##@d#Ytt:;,. ,,:@b,+ 10 | @R ,@d ,,.. .,,.@b= ,= 11 | @d tI @R;I@bYI+.+;:=+: 12 | @b :;=:...:=;:,:i 13 | @b :+:;i. ,,:+=,;i 14 | @b .=;:,.;=:.=; 15 | @b ;,,. =@d+RXI+@b: 16 | @b .@d+;;,@l=;=;=; 17 | @d : i=@l=+=I, 18 | @d =@lt:;+Y: 19 | @d ,, =@ltiii 20 | @d t, .@lii+: 21 | @d @ltB#WWt 22 | 23 | -------------------------------------------------------------------------------- /bin/help/cyberdemon.asc: -------------------------------------------------------------------------------- 1 | @d .,;IV@nRRBRBR@dXt,. 2 | @d :+;+,@ri@Rt@nYYttYY@Rt@ri@d;===. 3 | @d .,..@r.,,@n=Y@rII@nV+@r,,.@d.,.. 4 | @n .;+,,=It+i=@Riiii@n==it, 5 | @n @r,;@niYt+iIVVXXVI@r++@nYXBBBYttVIi. 6 | @n @r,:@ni+,,;::;+tIYVYVIXXVYYI+tYVX; 7 | @n @r:@n:=;,,.,,==:::;+Yi=;:,,:=VXRBV: 8 | @n @rt@n:,..,..;:=++=i=+i++i;::=@lit@dV@lXI. 9 | @n @r;@l=@n,,,. .,=@r:,,:,,:=::@n=;VB@lWM@dR@l#B+ 10 | @n :+=;:, @r ...,,,:..,,.,;;@lX@rX@lXVXii 11 | @l i@ni+;@d, @r ,,,,,,::,,,:,,@lY@dB@lVYRV;; 12 | @l .t@nt@d,,@n ,:@r,,,,,,,:,,,,;;@l:==:;=: 13 | @n ;++ ,i=t+===i+tii++i:,@l.@d..@l,; 14 | @n :;=. ;tIYVYIi:,,,,:;it:+;.@l.... 15 | @n . =tIIBRIi;:,..;=:=;;+=+ 16 | @d .@l;t@nYtYt;,:; .::,,::;=. 17 | @d .@l=Y@n+i=:,,,=. ,,,,,,,,, 18 | @d .@l=Yt@n;;;,,:, .,,,.,,. 19 | @d =@l@rii@li=@n,,;=; .,..,,, 20 | @d ,@l+@rY@lVIIi@n=:: .,,,,,:. 21 | @d :@lYBYt@riI@l+@d:. @n ..,,,,. 22 | @d :@l;VY@rit@lt@d, @n .,;;=;=, 23 | @d ;t@lVM@rBX@rt@d: @n .,,:::, 24 | @d ;i@lMVXI@dt: @n .,,:;:,. 25 | @d ;+@lMVXIt@d: 26 | -------------------------------------------------------------------------------- /bin/help/demon.asc: -------------------------------------------------------------------------------- 1 | @R Xr. 2 | @R :B0ZWZWZM XWXMMMM2 3 | @R i7;8ZBBZ7:B7;7Z80ZZ8B0Zaar 4 | @R ZMWBB0XS2ZZ:2ZWMMW8Sr:X2Za27 5 | @R 2Z8B0ZS;8WM8rSZWWWZ7i,,;i;riri 6 | @R i,;X777;i;SaSiiar, :X. ..:; 7 | @R 7 ir. Xa r0B7rri,;72;,,,, 8 | @R Zr.SB@la8XW@RZW8i0XX7Z@lB0a78MZ@R8:,, 9 | @R 2MW@l00S2;0M@RMW,7SXM@lMMMa.@R ,.;, 10 | @R a7 .::ii.a0rr: 7 ;:.,; 11 | @R Xr 7,@yWMX@R : @yMM8@Rri :i;r 12 | @R 2ZW0XXi :r,:i:,, ,.,: ,:i 13 | @R X20WZ87 .;; @y;@rXi@nB@rS@nS@yS@R X.rr ;iX2 14 | @R 2;XXM7 . ,r Z ,2, .SXSS 15 | @R 7a2Z2 S@r, . . .@RB :2. 16 | @R 88aMMZ: BS@Y7@rM@nX7@rM@YX@R7M :2. 17 | @R i22@M7,W8i0a0X28aWX .S7 18 | @R i;rWZ .. rXZZS; ,77:2W 19 | @R 7Zra,i, .;ZS;aX 20 | @R .,.. .:iBZ;7 21 | @R .i2ai,. ,.;007; 22 | @R @d,i@RS7Z@d7,,@R i;:;0B8X: 23 | @R @d.@R i@d. @dSZM@RSiX@dSS@R2S@dZ0,. 24 | @R @dMMi:@R,X@di8MM@RS;@daaM7 25 | -------------------------------------------------------------------------------- /bin/help/disclaim.hlp: -------------------------------------------------------------------------------- 1 | {rDisclaimer} 2 | 3 | This game is Freeware but with some limitations. Re-distribution 4 | (cd-magazines, other websites) etc. is allowed as long as the author 5 | is informed (admin@chaosforge.org). If you wish to include it in a printed 6 | magazine, I'd be happy to receive a complementary copy in return. 7 | 8 | THERE IS NO WARRANTY OF ANY KIND. I TAKE NO RESPONSIBILTY FOR ANY DAMAGE 9 | CAUSED BY THIS SOFTWARE. USE IT AT YOUR OWN RISK. 10 | 11 | Doom(tm) is a trademark of id Software. Many of the names in this game may 12 | be trademarks of id Software. Using them in this free public production is 13 | not supposed to challenge the rights of id Software. 14 | -------------------------------------------------------------------------------- /bin/help/doomrl.txt: -------------------------------------------------------------------------------- 1 | ## # # # 2 | ###### ##### ##### # ## 3 | ######### ######## ######## #### #### 4 | ### ##### ### #### #### ### ##### ##### 5 | ### ### ### ### ### ### ############ 6 | ### ### ### ### ### ### ### #### ### 7 | ### ### ### ### ### ### ### ## ### 8 | ### ### ### ### ### ### ### ### 9 | ### ### #### #### #### #### ### ### 10 | ### ### ###### ###### ## ### 11 | ##### ## ## # ### 12 | ### ### 13 | # Doom, the Roguelike # 14 | Version 0.9.9.8 15 | (c) 2002-2024 by Kornel Kisielewicz 16 | -------------------------------------------------------------------------------- /bin/help/feedback.hlp: -------------------------------------------------------------------------------- 1 | {rFeedback} 2 | 3 | I await your feedback! Mail me at admin@chaosforge.org. Tell me what you 4 | like, what you don't, and submit the bug reports :). The official webpage 5 | of {rDRL} is 6 | 7 | {B https://drl.chaosforge.org/} 8 | 9 | DRL has it's own forum, that can be found at 10 | 11 | {B https://forum.chaosforge.org/} 12 | 13 | There's a DRL dedicated channel on the Jupiter Hell discord server: 14 | 15 | {B https://discord.gg/jupiterhell} 16 | 17 | ChaosForge and myself also have official X profiles: 18 | 19 | {B https://x.com/chaosforge_org} 20 | {B https://x.com/epyoncf} 21 | 22 | The primary source for DRL guides, information and spoilers is the 23 | DRL Wiki 24 | 25 | {B https://drl.chaosforge.org/wiki/} 26 | 27 | Game Hunter has a great channel full of DRL Tutorials on youtube: 28 | 29 | {B http://www.youtube.com/user/TheUberHunter} 30 | 31 | Announces of new releases will be placed on the official website, X, and 32 | Discord. 33 | 34 | Please visit the site of ChaosForge, to give a try at my other 35 | roguelike games: 36 | 37 | {B https://chaosforge.org/} 38 | 39 | DRL has a commercial version, set in the Jupiter Hell universe, you can 40 | buy it to support the development of both the free and commercial 41 | versions. 42 | 43 | {B https://jupiterhellclassic.com/} 44 | 45 | Jupiter Hell is the spiritual successor to DRL: 46 | 47 | {B https://jupiterhell.com/} 48 | -------------------------------------------------------------------------------- /bin/help/former.asc: -------------------------------------------------------------------------------- 1 | @g .###### 2 | @R R#YX@g;.t. 3 | @R ##@ri@R###@gX 4 | @R =;V=Y@lBXY 5 | @R X:@l XRW##B 6 | @d .;@lMRVBW###i 7 | @d =,;@RiXRV@d=;i 8 | @l .... @RtMXVV@d=.. 9 | @d,XW#@l##@dWRRRRRRBtV@rM##@RBBi@d. ,@l :Y 10 | @d.t:XMB;t+=;:@rIR##@dW+: . @l .X 11 | @r . I;VRti; @d::. .@l:Y#V@dB# 12 | @r :+,; i+: @dt=@l:,;+@d.+ ;: 13 | @d ;+ @lY; ;=@dXW#YVX= 14 | @r W.@d+BIMR:#: 15 | @r =t++@dtMXI 16 | @r = =@d:i 17 | @r IBY@dYiIt. 18 | @g V#Bt@d;,;,+ 19 | @g := =i;@d,:@rti 20 | @g RtIMM@rY=:ii 21 | @r IXi;, =:=i 22 | @r VI,.: i;:+Ii 23 | @r ;i#BV=iit@d=;=..=; 24 | @d ,I=:,.,::; 25 | -------------------------------------------------------------------------------- /bin/help/garmor.asc: -------------------------------------------------------------------------------- 1 | @d =I@lVt@dt;, 2 | @d +R@lY@g;=+=;@lV@dR 3 | @d @d#@l+:YYMW:+@d# 4 | @g .=#@G##@gRY@lI;ItI;i@gi@GVV@gB:. @d. ,tYt: 5 | @g #WWt@GXt@gXX: ;IXR@GIi@g .=@d,tVMB,, 6 | @g . M :+==;; @d,:;tB= @R = 7 | @R ;R#i:@g, @d+VYt+: :.@R,R## 8 | @R ;iRX; @g:t @d;VIt;, ,: @RVItIi: 9 | @R ,Y##@d#Ytt:;,. ,,:@g,+ 10 | @R ,@d ,,.. .,,.@g= ,= 11 | @d tI @R;I@gYI+.+;:=+: 12 | @g :;=:...:=;:,:i 13 | @g :+:;i. ,,:+=,;i 14 | @g .=;:,.;=:.=; 15 | @g ;,,. =@d+RXI+@g: 16 | @g .@d+;;,@l=;=;=; 17 | @d : i=@l=+=I, 18 | @d =@lt:;+Y: 19 | @d ,, =@ltiii 20 | @d t, .@lii+: 21 | @d @ltB#WWt 22 | 23 | -------------------------------------------------------------------------------- /bin/help/imp.asc: -------------------------------------------------------------------------------- 1 | @n ,:,: 2 | @n WMVVVX# 3 | @n ##R=I### 4 | @n #:@R#@r=@nt=@r=@R#@n+ @l:#= 5 | @n @l Y#I@n XXX;B## #BMWBi@l## 6 | @n ,#####W.; @r#@R#@r#@n Y .+BWBWi 7 | @n YVVBI:,@l###@nt=:XXMXi=iB @lW= 8 | @n ,::,IM= =Bi=, ,iXM@lX#X 9 | @n ###MB; ;X:.. :=:Yii:+BMY=V 10 | @n #X@lA@n;=@lA@n tV=:,..:;:::, .; ;. .Y 11 | @n # ##B,Yi YttV,.tVt+= IRWW@lM 12 | @n , @lV@n : ;.=;;i. ,: Y###Xtt@li# 13 | @n i= X;;::==;+iV=YW+, 14 | @n IiY++Xt;,. .=. 15 | @n V+==;: ;iI+Y 16 | @n iItVt;: VWRVIM 17 | @n :I@lit@nI== :XX@lIt@niR 18 | @n i:==,+ +YI+==t 19 | @n ,RM..; I:+=: 20 | @n YM+:,;I i.#Y. 21 | @n +;,i I : B+ 22 | @n +;Y ++ ;: 23 | @n @lW@n#,# i,+ 24 | @n =WM# 25 | @n @l=V@nX@l:@nB@lW 26 | -------------------------------------------------------------------------------- /bin/help/intro.hlp: -------------------------------------------------------------------------------- 1 | {rIntroduction} 2 | 3 | {rDRL} (abbr. for Doom, the Roguelike) is, as the name implies, a 4 | roguelike game. If you don't know what a roguelike is... checkout 5 | wikipedia -- {Bhttp://en.wikipedia.org/wiki/Roguelike}. 6 | 7 | DRL is based on the world from id Software's(tm) game Doom(tm). You're 8 | the sole surviving marine from a squad sent to investigate a distress call 9 | from the moonbase of Phobos. It turns out that all hell has broken loose 10 | on the plant... literally. 11 | 12 | Your quest in DRL is to descend into the moonbase complex, find the 13 | source of this evil outbreak, and destroy it at all costs. 14 | 15 | Unlike many other roguelikes, DRL is intended to be simple and easy to 16 | get into. To that end, there is a limited inventory, maps of the size of 17 | one screen, and one item per tile. The number of keys you need to 18 | remember is also quite small compared to many other games in its genre. 19 | -------------------------------------------------------------------------------- /bin/help/keys.hlp: -------------------------------------------------------------------------------- 1 | {rControls} 2 | 3 | Most keybindings can be redefined via the file Settings menu. The 4 | following set describes the standard layout, and does not reflect 5 | any changes you may have made to your keybindings. 6 | 7 | {!Escape} -- exit menu, or show game menu (Save, Quit, Help, Settings) 8 | {!Arrows} -- Walking around (also PgUp, PgDn, Home, End -- diagonally) 9 | {!.}(period)- Wait 10 | {!h} -- Run on-line help 11 | {!SPACE} -- Action - open doors, close doors, use levers/switches or 12 | go down stairs (you won't be able to come back!) 13 | {!g} -- Pick up item from floor 14 | {!SHIFT-g} -- Use/wield/wear item from floor/pull lever/switch 15 | {!z} -- Swap weapon (with prepared weapon) 16 | {!i} -- Show inventory 17 | {!e} -- Show or change equipment/show traits 18 | {!l} -- Toggle LookMode (Escape to exit) 19 | {!f} -- Fire of equipped weapon 20 | {!SHIFT-f} -- Alternative Fire of equipped weapon (if available) 21 | {!r} -- Reload equipped weapon 22 | {!SHIFT-r} -- Special reload weapon (depending on weapon) 23 | {!u} -- Unload weapon from inventory/from ground 24 | {!p} -- Show screen with character info (parameters of player 25 | and his equipment) 26 | {!t} -- Show character traits 27 | {!a} -- Show known assemblies 28 | {!s} -- Show previous messages 29 | {!,}(comma)-- Run command 30 | {!TAB} -- change tactic 31 | {!1}..{!9} -- weapon quick keys, set them up in the inventory screen 32 | 33 | {rKeys while targeting} 34 | 35 | {!Arrows} -- move target line 36 | {!TAB} -- toggle target 37 | {!m} -- more information 38 | {!f},{!SPACE},{!LMB} -- fire 39 | {!RMB},{!Escape} -- cancel 40 | 41 | 42 | {rMouse (in graphics mode)} 43 | 44 | LMB, MMB, RMB is left/middle/right mouse button: 45 | 46 | {!LMB} -- travel to given destination, open door if next to it, 47 | melee attack if on enemy and next to him. Travel needs 48 | to target explored square, and is automatic as long as 49 | there are no enemies in sight, otherwise just one move 50 | {!LMB} on {!self} -- if on stairs, descend, if on lever - pull, if on item 51 | then pickup, else inventory 52 | {!Alt-LMB} on {!self} -- inventory 53 | 54 | {!RMB} -- fire at the targeted square or enemy, reload if 55 | magazine empty 56 | {!RMB} on {!self} -- reload 57 | 58 | {!MMB} -- swap weapon 59 | {!MMB} on {!self} -- equipment 60 | 61 | {!SCROLLWHEEL} -- change weapon (enters quick weapon choice) 62 | 63 | 64 | {rInventory screen} 65 | 66 | Select item and press Enter to do the default action on a given item. 67 | Wearable items will switch if one is already worn. 68 | 69 | {!Backspace} -- drop selected item 70 | {!1}..{!9} -- mark as quick use/wear/wield 71 | 72 | {rEquipment screen} 73 | 74 | Selecting a worn item will unequip it. Selecting an empty slot will 75 | let you choose an item. Note though, that switching through the 76 | inventory screen is faster. 77 | 78 | {!Backspace} -- drop selected item 79 | {!Tab} -- swap item with item in inventory 80 | -------------------------------------------------------------------------------- /bin/help/knight.asc: -------------------------------------------------------------------------------- 1 | @n @d0Mr@nMMMMMMMM@da00 2 | @n @d,2 @n i2X2ra @d; 3 | @n aM700XrX. 4 | @n XM, BMi 2:,Z7SMMr 5 | @n :aZ. .Sa2ZiXar.Mi7 6 | @n :0M0;M0Bia,,.78Xr :r7MMW 7 | @n Za@M;MSX2r :Xr. i:i;r2MMM8 8 | @n ::r ..r.,iSi:, @G . @n2@nr:@n8@G, 9 | @n .MZ 2MM . @Gi@nrXS@G2.n 10 | @n @n i8M08ZM i2:r: r @G,@nX7S@G:X 11 | @n ,@n 0MM8 i. .i;8r @G Si 12 | @n M @n ,XMMMMM@G8;i0WZ0 a 13 | @n MZ;,@n @G..:2@n000MMMMM@GB 14 | @n Z8.:iSr;7.,@G;@g7,,:,@G;rSi 15 | @n ai:r;;,rZ0W7Z2i7S2a2: 16 | @n B8:,,,::i : :rXX7;;W 17 | @n 00Sri,i ;:i7,:88 18 | @n ;XXrr7i ,ir@WBBMa 19 | @n ZZa7;i. i;r;rS0a 20 | @n :SX:i,: ;r XB0ZZ 21 | @n r@d7i.i.@ni iSSSZaWa 22 | @n @dr;;:ii;@n ,@d:.i :r@nr 23 | @n @d,:ii;;i; 24 | 25 | -------------------------------------------------------------------------------- /bin/help/logo.dat: -------------------------------------------------------------------------------- 1 | @b ### ## 2 | @b ###### #### #### # ### 3 | @b ######### ######## ######## #### #### 4 | @b ### ##### ### #### #### ### ##### ##### 5 | @b ### ##@y# #@b## ### ### ##@y# #@b########### 6 | @b ### #@y## ###@b ### ### @y### ##@b# #### ### 7 | @b ### @y ### ### #@b## ##@y# ### ###@b ## ### 8 | @b ###@y ##@R# #@y## ### ### ##@R# #@y##@b ### 9 | @b ##@y# ##@R# ##@y## #### #### ##@R## ##@y# #@b## 10 | @b #@y## @R### ###### ###### ## @y##@b# 11 | @y ###@R### ## ## # #@y## 12 | @y #@R### ##@y# 13 | @R ## ## 14 | 15 | -------------------------------------------------------------------------------- /bin/help/lostsoul.asc: -------------------------------------------------------------------------------- 1 | @r ::r@Riii@r:iii. 2 | @r Z@Rri@y:;@lXXXWMMM8MMZ77 3 | @r . r@yrr@lS2SW0 BB880BWW8W8MBr 4 | @r ,X72;;2S@Rri;i,@yi7r@lSS8BW8ZSS2a22Z2Z8X 5 | @r .::@Rri@r:;:i:;@RS:2i @y,Xr,.@l7,28aX;7SXrrrSi 6 | @r Xrrr@R;,i@r;7;@Rri.ii:@y,;. ;@lra: ,MMZ7X;7777r 7 | @r i 2r;r7::.,i@R7@r:i7i@RZ8X;r@y;;ir@l, SaZS0W0Zr, , 8 | @ri . i2:X7;ii.i@RXX@r7i77:i;;@Ri:.:@yr.:;@lai:, :iS8Ma 9 | @r,SXiX,r;@Rii@r7:;i,,rii:ir@R;;i:,ra@ySr .@li7;M8B 2ar 10 | @r ;7ir;7r,.r@R;:@r;:.,i,.:@Ri.72a@y7,82i@l 78ZZSXZ;ir. 11 | @r .. . .,Xr,:i7iX@R;;;iri,@yi, ir@l , :,,;,:, 12 | @r SXXXS@RXir;,.,@y.,XX@lir7ZXiiXZM2,88M: 13 | @r . .:;i:;@R;;, ...@ySii:r 14 | @r ., :,ir@R;rii@y.,X2, . 15 | @r :,@Rr@y;7:@lM.M 16 | @r ,i@R:@yi@lir;0. 17 | @r .@R:i, 18 | 19 | -------------------------------------------------------------------------------- /bin/help/make_manual.lua: -------------------------------------------------------------------------------- 1 | local manual_file = io.open( "../manual.txt", "w" ) 2 | local help_files = { "doomrl.txt", "intro.hlp", "start.hlp", "keys.hlp", "feedback.hlp", "credits.hlp", "disclaim.hlp" } 3 | 4 | function write_to_manual( file_name ) 5 | local file = io.open( file_name ) 6 | for l in file:lines() do 7 | l = l:gsub( "{.", "" ):gsub( "}", "" ) 8 | manual_file:write( l.."\n" ) 9 | end 10 | manual_file:write( "\n\n=============================================================================\n\n" ) 11 | end 12 | 13 | manual_file:write( "=============================================================================\n\n" ) 14 | 15 | for _,file in ipairs( help_files ) do 16 | write_to_manual( file ) 17 | end 18 | 19 | manual_file:close() 20 | 21 | -------------------------------------------------------------------------------- /bin/help/mancubus.asc: -------------------------------------------------------------------------------- 1 | @d ,,. 2 | @d :=t==;,.: @n.;tIItt, @d,., 3 | @d ti, ,@nIAY+tAAAIY+,+:,@d,;;itt;, 4 | @d ,+, @n;+=;==it; @gi@nII@gi @n=tIAVY+ @d:ii+. 5 | @d .@n+iARBRI:Ii:.:i:+t=++=,+=I=.,++YYY,@d=: 6 | @d ;@niAWB=; ,=+tI+Y;@r;,;,@n+=.,=; ,AV, ;;. @di. 7 | @d ;@n.,,..:+IttiIVi:+i=i@r,@n;: +;+=VV=+iii=.:@r= 8 | @d ,@n=:,:i;,+YVWWWBV=;+= ;,ttIABRVYAYt;=;,@d, 9 | @r :@n:;iYII; ,++IVYYtt=;YVIi=VBXWRI=;Vt+;@d. 10 | @n ::VBXA+ :;+tYIIIYIAIYIiii;=ii:..VY, .. 11 | @n ..,YA: =+titiiit=tii=ttYt+..+i+ ;=; 12 | @n ,: ; ,:=i=;=;iYYVAYVIVIi . @l+BMA+ 13 | @l .tAWWW+,@n.. :;:,+:;tIiVRMMRYRAI:;; @li#WYWXA#Y 14 | @l.###RBXM#B=@n;:,+=i=;,, .+IYVIttt=; ,@lI#VV:=iIY#R 15 | @l#B,+ ;Vi#R@n :::t===ttIAVtt;+it==+; @lWWII tRY#; 16 | @l#=t; +:RV@n,tti+t;,iBRMMWAiVABWYi+.@l+WI+Wt;==Ri 17 | @lRX=;=V+iBR,@n .;=+;:=AABRViIAWWAY+: @li=Ii=IY; 18 | @l i#MAR##Y,@n ,,::i=i,..;;+,,;=+;:, @l.,. 19 | @l ,,@n ;=+;;+=i.; .. . . 20 | @n .;:ttt;ii;; tIt+, :. 21 | @n , :+: ;t+. :;tit:+t= 22 | @n ,I+ tYI:I=+ @l.W@nR==YRi=IBA. 23 | @l ;BM@n=+YXMttIWX@l ,+M@nt.:@lBR, 24 | @l ;+ ., -------------------------------------------------------------------------------- /bin/help/pain.asc: -------------------------------------------------------------------------------- 1 | 2 | @d .RR @n,;iIRBWVI;.@d ,Mi 3 | @d A#Y; @n:M#MRBMYRAM#ARWIMXYB#t+@d .=M#= 4 | @d ,, XA#MI@nY:WAVAIVAAARIYBVMV:B@dY#XMI : 5 | @d := ;, @nYABI;IR+VB+=RAR; @d= =: 6 | @n :@d++;=;, @n=AYA @r, : @n+RIV. @d:+;++ 7 | @n ;AA=;:. ti+; @r:. ,, @n.+=I+ @d,++@nI 8 | @n ,YYVYIARI+:i, @R,; @y,#R@R ;. @n=+:+IBVYBt 9 | @n ;;.;YtiItI=+, @R+t @yMV@R ;i, @n+=ti+tiYt, 10 | @n ,VAt,,::IBRAYY=+@R;. , :;+@ntVYARY;: iMI 11 | @n YBBA; ,=VIIVABAI+;@R+;=;@n;iYRBYYtY=:.;YVt, 12 | @n :t:.;i=;@r ..@n:itIVVRRWWIVWARAVVIt=@r,,@n.,; .+: 13 | @n AR:,. ;,=W@lY@r,:+,@n+tVVARIABAYY=@r;,=@l:@r+@nVA.; ,t=:. 14 | @n :t; ,.,t +@r tiR@lI@n;@r :@l:@r .. @l+@r t@lI@rW,M@nA:,ii ,::; 15 | @n:RBYi=:+I=@r : @lI@rRII@RI@lA@R+tII=i@lA@n@R+IVR@lI@r ,@n ,tY; ,Y; 16 | @n :;II=i.+#it#, @l,@rtB@l#@RtV#A@yBV@RMXiW@l#@rY, @nYM;RB+i , 17 | @n : .,;,:IB+=,@r.=@l#W@R.B@lM@R+Y@l#@R=:@l#X@r. @n=;IB;,:I .: 18 | @n ,,BXYi:,YAI=@r;=@li@r.+@l+@r .@l=@r, @li@r+@n;tVA=,=tV# ,: 19 | @n ,iVRRItYIBMVY+tIRAIIBAY+tYRMAIItABB 20 | @n .=YtiiYiiBiIRRiYWMWBiIRA=VA+VY+tY; 21 | @n .=IYRR==Ii==tBRi==It+IWAi. 22 | @n ,:==+=t=+iitii=it=+;: 23 | @n ;,;i++;;;.. -------------------------------------------------------------------------------- /bin/help/player.asc: -------------------------------------------------------------------------------- 1 | @d =I@lVt@dt;, 2 | @d +R@lY@L;=+=;@lV@dR 3 | @d @d#@l+:YYMW:+@d# 4 | @l .=#@L##@lRY@lI;ItI;i@li@LVV@lB:. @d. ,tYt: 5 | @l #WWt@LXt@lXX: ;IXR@LIi@l .=@d,tVMB,, 6 | @l . M :+==;; @d,:;tB= @R = 7 | @R ;R#@d:@l, @d+VYt+: :.@R,R## 8 | @R ;iRX; @l:t @d;VIt;, ,: @RVItIi: 9 | @R ,Y##@d#Ytt:;,. ,,:@l,+ 10 | @R ,@d ,,.. .,,.@l= ,= 11 | @d tI @R;I@gYI+.+;:=+: 12 | @g :;=:...:=;:,:i 13 | @g :+:;i. ,,:+=,;i 14 | @g .=;:,.;=:.=; 15 | @g ;,,. =@d+RXI+@g: 16 | @g .@d+;;,@l=;=;=; 17 | @d : i=@l=+=I, 18 | @d =@lt:;+Y: 19 | @d ,, =@ltiii 20 | @d t, .@lii+: 21 | @d @ltB#WWt 22 | 23 | -------------------------------------------------------------------------------- /bin/help/rarmor.asc: -------------------------------------------------------------------------------- 1 | @d =I@lVt@dt;, 2 | @d +R@lY@r;=+=;@lV@dR 3 | @d @d#@l+:YYMW:+@d# 4 | @r .=#@L##@rRY@lI;ItI;i@ri@LVV@rB:. @d. ,tYt: 5 | @r #WWt@LXt@rXX: ;IXR@LIi@r .=@d,tVMB,, 6 | @r . M :+==;; @d,:;tB= @R = 7 | @R ;R#i:@r, @d+VYt+: :.@R,R## 8 | @R ;iRX; @r:t @d;VIt;, ,: @RVItIi: 9 | @R ,Y##@d#Ytt:;,. ,,:@r,+ 10 | @R ,@d ,,.. .,,.@r= ,= 11 | @d tI @R;I@rYI+.+;:=+: 12 | @r :;=:...:=;:,:i 13 | @r :+:;i. ,,:+=,;i 14 | @r .=;:,.;=:.=; 15 | @r ;,,. =@d+RXI+@r: 16 | @r .@d+;;,@l=;=;=; 17 | @d : i=@l=+=I, 18 | @d =@lt:;+Y: 19 | @d ,, =@ltiii 20 | @d t, .@lii+: 21 | @d @ltB#WWt 22 | 23 | -------------------------------------------------------------------------------- /bin/help/revenant.asc: -------------------------------------------------------------------------------- 1 | @n ,;, 2 | @n =RMR+ 3 | @n @n ;;,;:@d:I 4 | @d :WY@n .. ,@dV..A 5 | @d i.,;@L=WWI @n. @d:i@LtW# 6 | @d :Y@L#R;tA#BII=,iX## 7 | @n ;:@L;,X###+###+@n:= 8 | @n iI @L,Y###R+M##i @n:; 9 | @n iY @LVRAAWVIBRI @n,V, 10 | @n iR @L;IAYIi;IA: @ntY 11 | @n=Ai @r. , @n+B: 12 | @n.;t= @r::., ,== @nV+ 13 | @n IAMB@r.,::;:.ii @ntt 14 | @n +i@r: .+i @nIRV 15 | @r .i, ,i; @n,YV. 16 | @r =I; .I. @n,. 17 | @r .YA; IY, 18 | @r :I@ni@r, @n,A@rY. 19 | @n +, ;i+. 20 | @n ;+ ++. 21 | @n =I, i, 22 | @n tt; Y: 23 | @n it, ,A= 24 | @n .VIi -------------------------------------------------------------------------------- /bin/help/sergeant.asc: -------------------------------------------------------------------------------- 1 | @R i8MMM8 2 | @R i@rM@R278WD 3 | @R iM2ZMMM; 4 | @R ZMW8BM@dWS: 5 | @d ,i;rrrr 6 | @d iZr..:rr7rX 7 | @d rXXa2rii.r 8 | @d XMMM8WS:: ir 9 | @d. @r:B8@dXSi7, ,:: 10 | @d.MM@nMB@nZMM@dM@rM8X @gi: 11 | @n ZB@rS:, @d,.Xi@g,,rr:iiMi: 12 | @d @g:rii@d,:.. , 13 | @d , .:@ri@d;S:i;. 14 | @d ,r@rS@d,i@rZ@d:;;, 15 | @d ;@r;7@dXii;@ri@dr 16 | @d :,@rii@dX;., 17 | @d :2@ri@dii:i:, 18 | @d 0X;..:,7 19 | @d 7@dri.., .;, 20 | @r 2:i@dr::,@r.,X 21 | @r Xi@d,:@r.@r : r, 22 | @r ,2X... iii7:i 23 | @r :X0ZX;7r7 24 | -------------------------------------------------------------------------------- /bin/item_report.pl: -------------------------------------------------------------------------------- 1 | open(FILE,"item.txt"); 3 | open(CSV,">item.csv"); 4 | 5 | while ($line = ) { 6 | $line =~ /(\d+).*\[DIFF (\d)\] -- (\d+) - A:(\d+) P:(\d+) W:(\d+) U:(\d+) AR:(\d+)/; 7 | print "Level $1 (D$2) -- $3\n"; 8 | push @{ $count[$2][$1] }, $3; 9 | push @{ $ammo[$2][$1] }, $4; 10 | push @{ $power[$2][$1] }, $5; 11 | push @{ $weapon[$2][$1] }, $6; 12 | push @{ $use[$2][$1] }, $7; 13 | push @{ $armor[$2][$1] }, $8; 14 | } 15 | 16 | for $dlevel (1..5) { 17 | if (not defined ($count[$dlevel][1])) { next; } 18 | print OUT "\nDanger Level $dlevel\n--------------\n"; 19 | 20 | for $level (1..24) { 21 | if (not defined ($count[$dlevel][$level])) { next; } 22 | 23 | $total = 0; 24 | $row = $count[$dlevel][$level]; 25 | foreach $item (@$row) { 26 | $total += $item; 27 | } 28 | $avg = int($total / scalar @$row); 29 | print OUT "Items L$level = $avg "; 30 | 31 | $total = 0; 32 | $row = $ammo[$dlevel][$level]; 33 | foreach $item (@$row) { 34 | $total += $item; 35 | } 36 | $av = int($total / scalar @$row); 37 | print OUT "(ammo - $av) "; 38 | 39 | $total = 0; 40 | $row = $power[$dlevel][$level]; 41 | foreach $item (@$row) { 42 | $total += $item; 43 | } 44 | $av = int($total / scalar @$row); 45 | print OUT "(power - $av) "; 46 | 47 | $total = 0; 48 | $row = $weapon[$dlevel][$level]; 49 | foreach $item (@$row) { 50 | $total += $item; 51 | } 52 | $av = int($total / scalar @$row); 53 | print OUT "(weapon - $av) "; 54 | 55 | $total = 0; 56 | $row = $use[$dlevel][$level]; 57 | foreach $item (@$row) { 58 | $total += $item; 59 | } 60 | $av = int($total / scalar @$row); 61 | print OUT "(use - $av) "; 62 | 63 | $total = 0; 64 | $row = $armor[$dlevel][$level]; 65 | foreach $item (@$row) { 66 | $total += $item; 67 | } 68 | $av = int($total / scalar @$row); 69 | print OUT "(armor - $av) "; 70 | 71 | print OUT "\n"; 72 | print CSV "$avg,"; 73 | } 74 | print CSV "\n"; 75 | } 76 | 77 | close(FILE); 78 | close(OUT); 79 | close(CSV); 80 | -------------------------------------------------------------------------------- /bin/itemscsv.lua: -------------------------------------------------------------------------------- 1 | dofile("lua/constants.lua") 2 | DoomRL = {} 3 | items = {} 4 | 5 | csv,err = io.open("items.csv", "w") 6 | if err then print("Can't open items.csv : "..err) end 7 | 8 | function declare(v,i) 9 | _G[v] = i 10 | end 11 | 12 | function registeritem(ID,sID,name,level,weight,typ,flags) 13 | print(name) 14 | csv:write(ID..", "..name..", "..(level or 0)..", "..(weight or 0)..", "..typ.."\n"); 15 | end 16 | 17 | dofile("lua/items.lua") 18 | 19 | DoomRL.loaditems() 20 | 21 | io.close(csv) 22 | -------------------------------------------------------------------------------- /bin/lua/affects.lua: -------------------------------------------------------------------------------- 1 | function DoomRL.loadaffects() 2 | 3 | register_affect "berserk" 4 | { 5 | name = "brk", 6 | color = LIGHTRED, 7 | color_expire = RED, 8 | message_init = "You feel like a killing machine!", 9 | message_ending = "You feel your anger slowly wearing off...", 10 | message_done = "You feel more calm.", 11 | status_effect = STATUSRED, 12 | status_strength= 5, 13 | 14 | OnAdd = function(being) 15 | being.flags[ BF_BERSERK ] = true 16 | being.speed = being.speed + 50 17 | being.resist.bullet = (being.resist.bullet or 0) + 60 18 | being.resist.melee = (being.resist.melee or 0) + 60 19 | being.resist.shrapnel = (being.resist.shrapnel or 0) + 60 20 | being.resist.acid = (being.resist.acid or 0) + 60 21 | being.resist.fire = (being.resist.fire or 0) + 60 22 | being.resist.plasma = (being.resist.plasma or 0) + 60 23 | end, 24 | OnTick = function(being) 25 | ui.msg("You need to taste blood!") 26 | end, 27 | OnRemove = function(being) 28 | being.flags[ BF_BERSERK ] = false 29 | being.speed = being.speed - 50 30 | being.resist.bullet = (being.resist.bullet or 0) - 60 31 | being.resist.melee = (being.resist.melee or 0) - 60 32 | being.resist.shrapnel = (being.resist.shrapnel or 0) - 60 33 | being.resist.acid = (being.resist.acid or 0) - 60 34 | being.resist.fire = (being.resist.fire or 0) - 60 35 | being.resist.plasma = (being.resist.plasma or 0) - 60 36 | end, 37 | } 38 | 39 | register_affect "inv" 40 | { 41 | name = "inv", 42 | color = WHITE, 43 | color_expire = DARKGRAY, 44 | message_init = "You feel invincible!", 45 | message_ending = "You feel your invincibility fading...", 46 | message_done = "You feel vulnerable again.", 47 | status_effect = STATUSINVERT, 48 | status_strength= 10, 49 | 50 | OnAdd = function(being) 51 | being.flags[ BF_INV ] = true 52 | end, 53 | OnTick = function(being) 54 | if being.hp < being.hpmax and not being.flags[ BF_NOHEAL ] then 55 | being.hp = being.hpmax 56 | end 57 | end, 58 | OnRemove = function(being) 59 | being.flags[ BF_INV ] = false 60 | end, 61 | } 62 | 63 | register_affect "enviro" 64 | { 65 | name = "env", 66 | color = LIGHTGREEN, 67 | color_expire = GREEN, 68 | message_init = "You feel protected!", 69 | message_ending = "You feel your protection fading...", 70 | message_done = "You feel less protected.", 71 | status_effect = STATUSGREEN, 72 | status_strength= 1, 73 | 74 | OnAdd = function(being) 75 | being.resist.acid = (being.resist.acid or 0) + 25 76 | being.resist.fire = (being.resist.fire or 0) + 25 77 | end, 78 | 79 | OnRemove = function(being) 80 | being.resist.acid = (being.resist.acid or 0) - 25 81 | being.resist.fire = (being.resist.fire or 0) - 25 82 | end, 83 | } 84 | 85 | register_affect "light" 86 | { 87 | name = "lit", 88 | color = YELLOW, 89 | color_expire = BROWN, 90 | message_init = "You see further!", 91 | message_ending = "You feel your enhanced vision fading...", 92 | message_done = "Your vision fades.", 93 | 94 | OnAdd = function(being) 95 | being.vision = being.vision + 4 96 | end, 97 | 98 | OnRemove = function(being) 99 | being.vision = being.vision - 4 100 | end, 101 | } 102 | 103 | end 104 | -------------------------------------------------------------------------------- /bin/lua/difficulty.lua: -------------------------------------------------------------------------------- 1 | function DoomRL.load_difficulty() 2 | 3 | register_difficulty "ITYTD" 4 | { 5 | name = "I'm Too Young To Die!", 6 | description = "He was too young to die!", 7 | code = "@GE", 8 | ccode = "{GE}", 9 | tohitbonus = -1, 10 | expfactor = 1.4, 11 | scorefactor = 0.5, 12 | ammofactor = 2, 13 | powerfactor = 2, 14 | challenge = false, 15 | } 16 | 17 | register_difficulty "HNTR" 18 | { 19 | name = "Hey, Not Too Rough", 20 | id = "HNTR", 21 | description = "He didn't like it too rough.", 22 | code = "@BM", 23 | ccode = "{BM}", 24 | expfactor = 1.2, 25 | } 26 | 27 | register_difficulty "HMP" 28 | { 29 | name = "Hurt Me Plenty", 30 | description = "He wasn't afraid to be hurt plenty.", 31 | code = "@RH", 32 | ccode = "{RH}", 33 | scorefactor = 1.5, 34 | ammofactor = 1.25, 35 | } 36 | 37 | register_difficulty "UV" 38 | { 39 | name = "Ultra-Violence", 40 | description = "He was a man of Ultra-Violence!", 41 | code = "@yU", 42 | ccode = "{yU}", 43 | tohitbonus = 2, 44 | scorefactor = 2, 45 | ammofactor = 1.5, 46 | req_skill = 2, 47 | } 48 | 49 | register_difficulty "N!" 50 | { 51 | name = "Nightmare!", 52 | description = "He opposed the Nightmare!", 53 | code = "@rN", 54 | ccode = "{rN}", 55 | tohitbonus = 2, 56 | expfactor = 1.2, 57 | scorefactor = 4, 58 | ammofactor = 2, 59 | powerfactor = 2, 60 | powerbonus = 1.25, 61 | respawn = true, 62 | req_skill = 4, 63 | speed = 1.5, 64 | } 65 | 66 | end 67 | -------------------------------------------------------------------------------- /bin/lua/levels/carnage.lua: -------------------------------------------------------------------------------- 1 | -- HALLS OF CARNAGE ----------------------------------------------------- 2 | 3 | register_level "halls_of_carnage" 4 | { 5 | name = "Halls of Carnage", 6 | entry = "On level @1 he ventured into the Halls of Carnage.", 7 | welcome = "You enter the Halls of Carnage. You feel you need to run!", 8 | level = 14, 9 | 10 | Create = function () 11 | level:set_generator_style( 1 ) 12 | generator.fill( "rwall", area.FULL ) 13 | 14 | local mod1,mod2 = generator.roll_pair{"mod_power","mod_agility","mod_bulk","mod_tech"} 15 | 16 | local translation = { 17 | ['.'] = "floor", 18 | [','] = {"floor", flags = {LFBLOOD} }, 19 | ['#'] = "wall", 20 | ['%'] = { "wall", flags = { LFBLOOD } }, 21 | ['X'] = "rwall", 22 | ['+'] = "door", 23 | ['['] = "ldoor", 24 | ['>'] = "stairs", 25 | ['='] = "lava", 26 | ['6'] = { "floor", being = core.bydiff{"demon","demon","demon","knight","ndemon"} }, 27 | ['8'] = { "floor", being = core.bydiff{"demon","cacodemon","knight","baron","ncacodemon"} }, 28 | ['9'] = { "floor", being = core.bydiff{"cacodemon","knight","baron" } }, 29 | ['|'] = { "floor", item = "ammo" }, 30 | ['}'] = { "floor", item = "ashotgun" }, 31 | ['{'] = { "floor", item = "plasma" }, 32 | ['^'] = { "floor", item = "lhglobe" }, 33 | [':'] = { "floor", item = "bfg9000" }, 34 | ['"'] = { "floor", item = mod1 }, 35 | ['?'] = { "floor", item = mod2 }, 36 | } 37 | 38 | local map = [[ 39 | .................................#.|.".}.|.#...#..===..X.......6............ 40 | ...........................................%...#,.===..X..XXXXXXXXX.XXXXXXX. 41 | ...#%%##+##........#...###%%##...........,,%...[,.===..[..X.........6....... 42 | ...#.,,...#........#.......,,#..........,,,#...#,.===..X..X.XXXX[XXXXXXXX.X. 43 | ...#...............#.........#...#####+#%%##...#..===..X..X6X.8........8X.X. 44 | ...+...............#.........#.................#..===..X..X.X.XXXXXXX[X.X.X. 45 | ...#,..............+...,,,...#.........#.......#..===..X..X.X.X...9...X.[.X6 46 | ...#%#........######..#%%##............#...#...#,.===..X..X.X.X.XXXXX9X.X.X| 47 | .,,,..................#......#........,%...#...[,.=^=..[..X.X.X.X|:|X.X.X..? 48 | ......................#...,,.%.......,,%...%,..#,.===..X6.X.X.X9X.>.X.X.X.X| 49 | ...##%%+######........#...,,,%......,,.#..,%,..#..===..X..X.X.X.X[XXX.X.X.X. 50 | ...#..,......+...........,,..#...##%%%##...%...#..===..X..X.X.X.....9.X.[.X. 51 | ...#......,..#..........##%%%#.............#...#,.===..X..X.X.XXXXXXXXX.X... 52 | ...#.....##%%#........................######...[,.===..[..X.X8.......8..X.X. 53 | ......................................#........#,.===..X..X.XXXXXX[XXXXXX.X. 54 | .,,######..........####%%%##+###......+........#..===..X..X6..............X6 55 | .,,+^|..#..........#,,,,,.............#........#..===..X..XXXXX.XXXXX.XXXXX. 56 | .,,#.|..#..........#.,,,.......................#..===..X.........6.......... 57 | ]] 58 | generator.place_tile( translation, map, 2, 2 ) 59 | 60 | local left = area.new( 2, 2, 48, 19 ) 61 | local middle = area.new( 50, 2, 56, 19 ) 62 | 63 | level:summon{ "former", 8 + DIFFICULTY, area = left } 64 | level:summon{ "sergeant", 8 + 2*DIFFICULTY, area = left } 65 | level:summon{ "lostsoul", 6 + 2*DIFFICULTY, area = middle } 66 | 67 | generator.set_permanence( area.new( 66,9,70,12 ) ) 68 | level:player(8,18) 69 | local tick = core.bydiff{ 80, 60, 50, 30, 20 } 70 | 71 | level.data.event = { 72 | id = "flood_lava_event", 73 | timer = 0, 74 | step = tick, 75 | direction = (math.random(2)*2)-3, 76 | flood_min = 0, 77 | cell = "lava", 78 | } 79 | generator.OnTick = events.flood_lava_event.on_tick 80 | end, 81 | 82 | OnTick = function() 83 | generator.OnTick() 84 | end, 85 | } -------------------------------------------------------------------------------- /bin/lua/levels/containment.lua: -------------------------------------------------------------------------------- 1 | -- CONTAINMENT AREA ----------------------------------------------------- 2 | 3 | register_level "containment_area" 4 | { 5 | name = "Containment Area", 6 | entry = "On level @1 he arrived at the Containment Area.", 7 | welcome = "You enter the Containment Area. You feel something is hidden behind this wall.", 8 | level = 11, 9 | 10 | Create = function () 11 | level:set_generator_style( 2 ) 12 | generator.fill( "wall", area.FULL ) 13 | 14 | local translation = { 15 | ['.'] = "floor", 16 | ['#'] = { "wall", style = 1, }, 17 | ['P'] = { "wall", flags = { LFPERMANENT } }, 18 | ['*'] = "gwall", 19 | [','] = { "floor", flags = { LFBLOOD } }, 20 | ['+'] = "door", 21 | ['L'] = "ldoor", 22 | ['>'] = "stairs", 23 | ['$'] = "crate", 24 | ['&'] = "ycrate", 25 | ['%'] = "crate_ammo", 26 | ['@'] = "crate_armor", 27 | ['i'] = { "floor", being = "imp" }, 28 | ['c'] = { "floor", being = "demon" }, 29 | 30 | 31 | ['^'] = { "floor", item = "backpack" }, 32 | ['!'] = { "floor", item = "umbazooka" }, 33 | ['|'] = { "floor", item = "procket" }, 34 | ['-'] = { "floor", item = "pammo" }, 35 | } 36 | 37 | local map = [[ 38 | ...........######..........&&..................#.................PPP......PP 39 | .>.........######..$$......&&...&&........%%...#...**...**...**..PP........P 40 | ...........######..$$..%%.......&&..&&....%%...#...**...**...**..P.......... 41 | ...........######...&&&%%...$$.$$...&&.....&&..#.................P.......... 42 | ...........######...&&&.....$$.$$..$$..$$..&&..#.................P.......... 43 | ............#####.......$$.........$$..$$..$$..L........,,.................. 44 | ............#####..$$...$$....&&..&&$$&&...$$..L......,,,,,............^.... 45 | ............#####..$$...&&..$$&&..&&$$&&$$.....L.......,,................... 46 | ...........######.....$$@@..$$.....&&...$$.....#.................P.......... 47 | ...........######.....$$@@...&&....&&....&&....#.................P.......... 48 | ...........######..$$........&&...$$.....&&....#...**...**...**..P.......... 49 | ...........######..$$..$$&&..$$...$$..@@....$$.#...**...**...**..PP........P 50 | ...........######......$$&&..$$.......@@....$$.#.................PPP......PP 51 | PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPLPPPPLPPPPLPPPPPPPPPPPPPP 52 | PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP..c.c.P...P.i.i..PPPPPPPPPPP 53 | PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP...-..P.!.P..|...PPPPPPPPPPP 54 | PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP..c.c.P...P.i.i..PPPPPPPPPPP 55 | PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP 56 | ]] 57 | generator.place_tile( translation, map, 2, 2 ) 58 | 59 | level.data.left = area.new( 19, 2, 48, 14 ) 60 | level.data.middle = area.new( 50, 2, 66, 14 ) 61 | level.data.right = area.new( 68, 2, 78, 14 ) 62 | 63 | local total = 5 + 2*DIFFICULTY 64 | level:summon{ "imp", total, area = level.data.left } 65 | 66 | level:player(2,2) 67 | level.status = 0 68 | end, 69 | 70 | OnKillAll = function () 71 | if level.status ~= 3 then return end 72 | ui.msg("I guess I prefered the Wall.") 73 | level.status = 4 74 | if CHALLENGE == "challenge_aohu" then 75 | player:add_medal("everysoldier") 76 | end 77 | end, 78 | 79 | OnTick = function () 80 | local res = level.status 81 | if res > 2 then return end 82 | if res < 2 and level.data.middle:contains( player.position ) then 83 | ui.msg( "\"This is too easy...\"" ) 84 | res = 2 85 | end 86 | if level.data.right:contains( player.position ) then 87 | ui.msg( "\"It's a trap!\"" ) 88 | generator.transmute("ldoor","door") 89 | res = 3 90 | player:play_sound("soldier.phase") 91 | 92 | local total = 8 + DIFFICULTY 93 | local knights = math.max( 9 - (3*( DIFFICULTY - 1 ) ), 0 ) 94 | level:summon{ "knight", knights, area = level.data.middle } 95 | level:summon{ "baron", total - knights, area = level.data.middle } 96 | if DIFFICULTY >= 4 then 97 | level:summon{ "arch", DIFFICULTY-3, area = level.data.middle } 98 | end 99 | player:play_sound("soldier.phase") 100 | player:play_sound("baron.act") 101 | end 102 | level.status = res 103 | end, 104 | 105 | OnKill = function () 106 | if level.status < 1 then 107 | level.status = 1 108 | end 109 | end, 110 | 111 | OnExit = function () 112 | local result = level.status 113 | if result == 0 then 114 | ui.msg("I guess this tincan will stay closed...") 115 | player:add_history("Not knowing what to do, he left.") 116 | elseif result < 4 then 117 | ui.msg("It's way too hairy down here!") 118 | player:add_history("He broke into the Containment Area, but gave up against the overwhelming forces.") 119 | elseif result == 4 then 120 | ui.msg("Luckily it's not as bad as tricks and traps...") 121 | player:add_history("He emerged from the Containment Area victorious!") 122 | player:add_badge("wall1") 123 | if core.is_challenge("challenge_aomr") or core.is_challenge("challenge_aob") or core.is_challenge("challenge_aosh") then 124 | player:add_badge("wall2") 125 | end 126 | end 127 | end, 128 | 129 | OnCompletedCheck = function () 130 | return level.status > 3 131 | end, 132 | } 133 | -------------------------------------------------------------------------------- /bin/lua/levels/lavapits.lua: -------------------------------------------------------------------------------- 1 | -- LAVA PITS ------------------------------------------------------------ 2 | 3 | register_level "the_lava_pits" 4 | { 5 | name = "The Lava Pits", 6 | entry = "On level @1 he entered the Lava Pits.", 7 | welcome = "You descend into the Lava Pits. Dammit, it's hot in here!", 8 | level = 22, 9 | 10 | Create = function () 11 | level:set_generator_style( 1 ) 12 | generator.fill( "plava", area.FULL ) 13 | 14 | local lavapits_armor = { 15 | level = 25, 16 | type = {ITEMTYPE_ARMOR,ITEMTYPE_BOOTS}, 17 | weights = { is_unique = 5, ulavaarmor = 3 }, -- multiplicative! 18 | } 19 | 20 | local translation = { 21 | ['.'] = "floor", 22 | ['='] = "lava", 23 | ['>'] = "stairs", 24 | 25 | ['/'] = { "floor", item = "shell" }, 26 | ['|'] = { "floor", item = "cell" }, 27 | ['-'] = { "floor", item = "rocket" }, 28 | ['!'] = { "floor", item = "epack" }, 29 | ['?'] = { "floor", item = core.ifdiff( 3, nil, "epack" ) }, 30 | ['*'] = { "floor", item = core.ifdiff( 4, nil, "epack" ) }, 31 | 32 | ['A'] = { "floor", being = core.bydiff{ "sergeant", "knight", "mancubus", "revenant" } }, 33 | 34 | ['1'] = { "floor", item = level:roll_item( lavapits_armor ) }, 35 | ['2'] = { "floor", item = level:roll_item( lavapits_armor ) }, 36 | ['3'] = { "floor", item = level:roll_item( lavapits_armor ) }, 37 | ['4'] = { "floor", item = level:roll_item( lavapits_armor ) }, 38 | ['5'] = { "floor", item = level:roll_item( lavapits_armor ) }, 39 | ['6'] = { "floor", item = level:roll_item( lavapits_armor ) }, 40 | ['7'] = { "floor", item = level:roll_item( lavapits_armor ) }, 41 | ['8'] = { "floor", item = level:roll_item( lavapits_armor ) }, 42 | ['9'] = { "floor", item = level:roll_item( lavapits_armor ) }, 43 | ['0'] = { "floor", item = level:roll_item( lavapits_armor ) }, 44 | } 45 | 46 | local map = [=[ 47 | ============================================================================ 48 | ============================================================================ 49 | ==========================A./==============================!8.============== 50 | =========================...-.======================/.=====.A.============== 51 | =========================...|.=====================..-.===================== 52 | ==========================...=======================..============...======= 53 | ===========================.=====================================...0.====== 54 | ==...======================A============================...=======...======= 55 | =.....=====================.===========================../|.================ 56 | =..>..=====================.=============...============...============.|.== 57 | =.....=====================.============.....==========================./.== 58 | ==...======================A============..A..=============================== 59 | ===========================.=============...========../===========...A====== 60 | ==========================...======================..A..=========.....?===== 61 | =========================...|.======================..-===========.A7534==== 62 | =========================...-.===============..====================*621===== 63 | ==========================A./================.9============================= 64 | ============================================================================ 65 | ]=] 66 | generator.place_tile( translation, map, 2, 2 ) 67 | 68 | local second = core.bydiff{ "lostsoul", "cacodemon", "cacodemon", "pain" } 69 | level:summon{ "lostsoul", 14 + 2*DIFFICULTY, cell = "lava" } 70 | level:summon{ second, 5 + DIFFICULTY, cell = "lava" } 71 | 72 | level:player(4,11) 73 | level.status = 0 74 | end, 75 | 76 | OnKillAll = function () 77 | local result = level.status 78 | if result == 0 then 79 | ui.msg("That seems to be all of them... wait! Something is moving there, or is it just lava glow?") 80 | level.status = 1 81 | local element = level:summon("lava_elemental") 82 | element.inv:add( item.new("lava_element") ) 83 | elseif result == 1 then 84 | ui.msg("Tough son of a bitch... now to get that shiny object he left behind...") 85 | level.status = 2 86 | end 87 | end, 88 | 89 | OnExit = function () 90 | local result = level.status 91 | if result == 0 then 92 | ui.msg("Too hot dammit, I'm leaving this party...") 93 | player:add_history("He decided it was too hot there.") 94 | elseif result == 1 then 95 | ui.msg("There goes my beard... at least I'm still alive.") 96 | player:add_history("He fled there from the monstrous lava elemental.") 97 | elseif result == 2 then 98 | ui.msg("Lava elementals my ass. I don't care.") 99 | player:add_badge("lava1") 100 | if core.is_challenge("challenge_aoi") then player:add_badge("lava2") end 101 | player:add_history("He managed to clear the Lava Pits completely!") 102 | end 103 | end, 104 | } 105 | -------------------------------------------------------------------------------- /bin/lua/levels/milibase.lua: -------------------------------------------------------------------------------- 1 | -- MILITARY BASE -------------------------------------------------------- 2 | 3 | register_level "military_base" 4 | { 5 | name = "Military Base", 6 | entry = "On level @1 he marched into the Military Base.", 7 | welcome = "You enter the Military Base. Arriving here again sure takes you back!", 8 | level = 7, 9 | 10 | Create = function () 11 | level:set_generator_style( 1 ) 12 | generator.fill( "rwall", area.FULL ) 13 | 14 | local mod1,mod2 = generator.roll_pair{"mod_power","mod_agility","mod_bulk","mod_tech"} 15 | 16 | local translation = { 17 | ['.'] = "floor", 18 | [','] = { "floor", flags = { LFBLOOD } }, 19 | ['#'] = { "wall", flags = { LFPERMANENT } }, 20 | ['+'] = { "door", flags = { LFPERMANENT } }, 21 | ['L'] = { "ldoor", flags = { LFPERMANENT } }, 22 | ['%'] = "crate", 23 | ['@'] = "ycrate", 24 | ['$'] = "crate_ammo", 25 | ['&'] = "crate_armor", 26 | ['>'] = "stairs", 27 | ['h'] = { "floor", being = "former" }, 28 | ['g'] = { "floor", being = "sergeant" }, 29 | ['j'] = { "floor", being = "captain" }, 30 | ['H'] = { "floor", being = core.ifdiff( 4, "eformer", "former" ) }, 31 | ['G'] = { "floor", being = core.bydiff{ "sergeant", "sergeant", "eformer", "esergeant" } }, 32 | ['J'] = { "floor", being = core.bydiff{ "captain", "eformer", "esergeant", "ecaptain", "ecommando" } }, 33 | ['M'] = { "floor", being = core.bydiff{ "commando", "esergeant", "ecaptain", "ecommando" } }, 34 | ['!'] = { "floor", item = "lhglobe" }, 35 | ['"'] = { "floor", item = "epack" }, 36 | [':'] = { "floor", item = "pmap" }, 37 | ['}'] = { "floor", item = "ashotgun" }, 38 | ['1'] = { "floor", item = mod1 }, 39 | ['2'] = { "floor", item = mod2 }, 40 | 41 | } 42 | 43 | local map = [=[ 44 | ############################################################################## 45 | ##....########.....j....########.....+.,..+...........&&................%%@@!# 46 | #..............########....j.......,,+,,.,+...$$......&&%%.g.@@......&&h%%@@.# 47 | #.##.....j.....########..........,,..+...,+,..$$.####...%%...@@..$$..&&####$$# 48 | #..##.########.....j....########,....+...,+,.....####%%.h........$$.J..####$$# 49 | ##..#############################....#g..g#,...h.####%%..@@....@@....@@####..# 50 | ###.g#.........########.........#....#..,.#..&&..####....@@....@@....@@####..# 51 | ####.#.....##...H.,,..H..##.....#...h#,...#..&&.......h.%%..g...........%%...# 52 | ###..L..#..h...G.,,,,.J......#.1#....#.,..#........@@...%%@@.....G..%%..%%.&&# 53 | ##h..L..#..h....,,,,,,.....M.#.!#....#...,#%%..g...@@$$...@@....@@..%%.....&&# 54 | ##h..L..#..h....,,>,,,.......#.}#....#.,..#%%........$$.j.!%%...@@......H....# 55 | ###..L..#..h...G.,,,,.J......#.2#h...#.,..#....%%...@@...&&%%..%%....G.@@..$$# 56 | ####.#.....##...H.,,..H..##.....#....#,...#..@@%%...@@...&&....%%@@....@@..$$# 57 | ###.g#.........########.........#....#,...#..@@..h....g..####.G..@@...######+# 58 | ##..#############################....#h.,h#.......@@.....####@@.H...$$##!##,.# 59 | #..##.....g....########....g........h#....#.j.....@@.%%..####@@.....$$#"M:#.J# 60 | #.##..########..........########.....#++++#...$$.....%%..####...%%....##,##..# 61 | #.....########..........########....##,,,,##..$$..&&..h....%%..H%%..&&#...J.,# 62 | ##........g....########....g.......##......##.....&&.......%%.......&&#..,...# 63 | ####################################........################################## 64 | ]=] 65 | generator.place_tile( translation, map, 1, 1 ) 66 | 67 | --generator.set_permanence( area.FULL ) 68 | 69 | level:player(38,19) 70 | end, 71 | 72 | OnKillAll = function () 73 | level.status = 2 74 | ui.msg("They can all rest easy now...") 75 | end, 76 | 77 | OnTick = function () 78 | local res = level.status 79 | if res == 0 and player.x < 6 and player.y > 7 and player.y < 14 then 80 | local y 81 | for _, y in ipairs { 9, 10, 11, 12 } do 82 | level.map[coord.new(6,y)] = "floor" 83 | level.map[coord.new(6,y)] = "door" 84 | end 85 | level.status = 1 86 | end 87 | end, 88 | 89 | OnEnter = function () 90 | level.status = 0 91 | end, 92 | 93 | OnExit = function () 94 | local result = level.status 95 | if result < 2 then 96 | ui.msg("Too many memories to go destroying them all...") 97 | player:add_history("He left without a fuss.") 98 | else 99 | ui.msg("Better to end their tortured bodies here and now.") 100 | player:add_history("He purified his fellow comrades.") 101 | end 102 | end, 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /bin/lua/levels/mortuary.lua: -------------------------------------------------------------------------------- 1 | -- THE MORTUARY --------------------------------------------------------- 2 | 3 | register_level "the_mortuary" 4 | { 5 | name = "The Mortuary", 6 | entry = "On level @1 he was foolish enough to enter the Mortuary!", 7 | level = 20, 8 | welcome = "You enter the Mortuary.", 9 | 10 | canGenerate = function () 11 | return DIFFICULTY > 1 12 | end, 13 | 14 | Create = function () 15 | level:set_generator_style( 1 ) 16 | generator.fill( "rwall", area.FULL ) 17 | generator.fill( "floor", area.FULL_SHRINKED ) 18 | generator.set_blood( area.FULL_SHRINKED, true ) 19 | 20 | local translation = { 21 | ['.'] = { "floor", flags = { LFBLOOD } }, 22 | ['>'] = "stairs", 23 | ['X'] = "rwall", 24 | ['1'] = { "floor", flags = { LFBLOOD }, item = "lmed" }, 25 | ['2'] = { "floor", flags = { LFBLOOD }, item = "scglobe" }, 26 | ['3'] = { "floor", flags = { LFBLOOD }, item = "rarmor" }, 27 | ['4'] = { "floor", flags = { LFBLOOD }, item = "ashard" }, 28 | } 29 | 30 | local tile = [[ 31 | X.X.X 32 | ..1.. 33 | X2>3X 34 | ..4.. 35 | X.X.X 36 | ]] 37 | local center = [[ 38 | XX.XX 39 | X3.2X 40 | ..... 41 | X2.3X 42 | XX.XX 43 | ]] 44 | 45 | generator.place_tile( translation, tile, 2, 2 ) 46 | generator.place_tile( translation, tile, 2, 15 ) 47 | generator.place_tile( translation, tile, 73, 2 ) 48 | generator.place_tile( translation, tile, 73, 15 ) 49 | 50 | level:drop_item( "mod_power", coord.new(3, 3) ) 51 | level:drop_item( "mod_bulk", coord.new(76, 18) ) 52 | level:drop_item( "unbfg9000", coord.new(76, 3) ) 53 | level:drop_item( "uashotgun", coord.new(3, 18) ) 54 | 55 | generator.place_tile( translation, center, 36,8 ) 56 | 57 | local corpses = { 58 | "former", "sergeant", "captain", "imp", "demon", "cacodemon", 59 | "baron", "knight", "arachno", "commando", "mancubus", "revenant" 60 | } 61 | 62 | for cnt = 1,DIFFICULTY+25 do 63 | local corpse = corpses[math.random(7+DIFFICULTY)].."corpse"; 64 | generator.scatter(area.FULL_SHRINKED,"floor",corpse,math.random(10)+4) 65 | end 66 | 67 | level:player(38,10) 68 | end, 69 | 70 | OnEnter = function () 71 | ui.msg_feel("The smell of blood! Can this be real?? The floor is") 72 | ui.msg_feel("covered in blood, and there are corpses everywhere!") 73 | 74 | level.status = 0 75 | ui.msg_feel("Suddenly with a wail, arch-viles appear!") 76 | level:summon("arch",3+DIFFICULTY) 77 | player:add_badge("reaper1") 78 | end, 79 | 80 | OnKillAll = function () 81 | if level.status == 0 then 82 | ui.msg("Suddenly everything is peaceful. Rest in peace, damned souls...") 83 | 84 | level.status = 1 85 | 86 | if player:has_medal("hellchampion3") then 87 | ui.msg_enter( "A presence! Of something cursed. How could that be?") 88 | level:drop( "uberarmor" ) 89 | else 90 | ui.msg_enter( "A presence! Of something holy! Here in this hell?") 91 | level:drop( "aarmor" ) 92 | end 93 | 94 | ui.msg("Find it under the corpses!") 95 | end 96 | end, 97 | 98 | OnExit = function () 99 | if level.status == 1 then 100 | ui.msg("As you descend the stairs you hear a wail. They're back...") 101 | ui.msg("There's only one way to end this...") 102 | player:add_history("He managed to clear the Mortuary from evil!") 103 | player:add_medal("mortuary") 104 | player:add_badge("reaper2") 105 | if not level.flags[ LF_NUKED ] then 106 | if statistics.damage_on_level == 0 then 107 | player:add_medal("mortuary2") 108 | if player_data.count('player/medals/medal[@id="mortuary"]') > 0 then 109 | player:remove_medal("mortuary") 110 | end 111 | end 112 | player:add_badge("reaper3") 113 | if DIFFICULTY == DIFF_NIGHTMARE then 114 | player:add_badge("reaper4") 115 | if core.is_challenge("challenge_aocn") then player:add_badge("reaper5") end 116 | end 117 | end 118 | else 119 | ui.msg("You flee! You flee like hell from this cursed place!") 120 | player:add_history("He managed to escape from the Mortuary!") 121 | player:add_badge("reaper2") 122 | end 123 | end, 124 | 125 | } 126 | -------------------------------------------------------------------------------- /bin/lua/levels/skulls.lua: -------------------------------------------------------------------------------- 1 | -- CITY OF SKULLS ------------------------------------------------------- 2 | 3 | register_level "city_of_skulls" 4 | { 5 | name = "City of Skulls", 6 | entry = "On level @1 he found the City of Skulls.", 7 | welcome = "You enter a city made out of bones. You sense a certain tension.", 8 | level = 12, 9 | 10 | Create = function () 11 | level:set_generator_style( 1 ) 12 | generator.fill( "rwall", area.FULL ) 13 | 14 | local translation = { 15 | ['.'] = "floor", 16 | [','] = { "floor", flags = { LFBLOOD } }, 17 | ['#'] = "wall", 18 | ['>'] = "stairs", 19 | 20 | ['O'] = { "floor", being = core.ifdiff( 2, "pain" ) }, 21 | ['s'] = { "floor", being = "lostsoul" }, 22 | 23 | ['/'] = { "floor", item = "shell" }, 24 | ['|'] = { "floor", item = "ammo" }, 25 | ['-'] = { "floor", item = "rocket" }, 26 | ['!'] = { "floor", item = "umbazooka" }, 27 | } 28 | 29 | local map = [[ 30 | ............................,,,,,,,,,,....................,,,............... 31 | ...,,,,,,,,,...,,,,,,,,,....,########,.......,,,,,,,,........,,,...,,,...... 32 | ...,#######,...,#######,....,#|s||s|#,.......,######,.......,,,,,,,,,....... 33 | ...,#|s.-/#,...,#|,s-/#,....,#/.s..s#,.......,#|s-/#,.....,,,#######,....... 34 | ...,#..O.s#,...,#s.,,s#,....,#s.Os..#,.......,#s.s.#,.......,#!|s-/#,....... 35 | ...,#s..s.#,...,#######,....,#.s..s.#,.......,#.s.s#,......,,#s.Os.#,....... 36 | ...,#######,...,,,,,,,,,....,########,.......,######,..,,,,.,#.s..s#,....... 37 | ...,,,,,,,,,...........,,,..,,,,,,,,,,.......,,,,,,,,.......,#######,....... 38 | .........,,,,,.............................,,...............,,,,,,,,,....... 39 | ....,,.......,,,.......,,,.....,,..........,,,.........,,,,................. 40 | .........,,,,,,,,,.........,,,...............................,,,..,,,....>.. 41 | ..,..,,..,#######,...,,......................,....,,,,,,,,,......,,..,...... 42 | ...,,....,#.s.s.#,..........,,,,,,,,,,,....,,,....,#######,...,....,........ 43 | ....,,...,#s|sOs#,...,,.....,#########,...........,#/.s-.#,...,,,,..,....... 44 | .........,#/s-s.#,..........,#s.s.s./#,.......,,..,#s.Os.#,......,,,........ 45 | ..,,,....,#######,....,,,...,#.s|s-s.#,.....,,,...,#.s|.s#,.......,,........ 46 | ...,,,...,,,,,,,,,.,,,......,#########,...,,,.....,#######,....,,,.......... 47 | ...........,...,............,,,,,,,,,,,...........,,,,,,,,,................. 48 | ]] 49 | 50 | generator.place_tile( translation, map, 2,2 ) 51 | local lever = level:drop_item( "lever_walls", coord.new( 35, 11 ) ) 52 | generator.set_permanence( area.FULL ) 53 | level:player(2,2) 54 | level.status = 1 55 | end, 56 | 57 | OnKillAll = function () 58 | if level.status == 3 then return end 59 | 60 | if level.status == 1 and DIFFICULTY < 2 then 61 | level.status = 3 62 | ui.msg("That seems to be all of them, hopefully...") 63 | return 64 | end 65 | 66 | if level.status == 2 then 67 | level.status = 3 68 | ui.msg("That had damn well better be all of them!") 69 | return 70 | end 71 | 72 | if DIFFICULTY == 3 then 73 | ui.msg("Suddenly lost souls appear out of nowhere!") 74 | level:summon("lostsoul",20) 75 | end 76 | if DIFFICULTY > 3 then 77 | ui.msg("Suddenly pain elementals appear out of nowhere!") 78 | level:summon("pain",12) 79 | end 80 | 81 | ui.msg("You hear a howl of agony!") 82 | local agony = level:summon("agony") 83 | for i = 1,3 do 84 | agony.inv:add( item.new(table.random_pick{"ufskull","ubskull","uhskull"}) ) 85 | end 86 | level.status = 2 87 | end, 88 | 89 | OnExit = function () 90 | if level.status == 3 then 91 | player:add_history("He wiped out the City of Skulls.") 92 | player:add_badge("skull1") 93 | if core.is_challenge("challenge_aora") then player:add_badge("skull2") end 94 | else 95 | player:add_history("He fled the City in terror!") 96 | end 97 | end, 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /bin/lua/levels/spider.lua: -------------------------------------------------------------------------------- 1 | -- SPIDER'S LAIR -------------------------------------------------------- 2 | 3 | register_level "spiders_lair" 4 | { 5 | name = "Spider's Lair", 6 | entry = "On level @1 he ventured into the Spider's Lair.", 7 | welcome = "You descend into the Spider's Lair. Mechanical clicks everywhere! Oh my god it's full of spiders!", 8 | level = 14, 9 | 10 | 11 | OnRegister = function () 12 | 13 | register_badge "arachno1" 14 | { 15 | name = "Arachno Bronze Badge", 16 | desc = "Clear Spider's Lair", 17 | level = 1, 18 | } 19 | 20 | register_badge "arachno2" 21 | { 22 | name = "Arachno Silver Badge", 23 | desc = "Clear Spider's Lair on AoD", 24 | level = 2, 25 | } 26 | 27 | register_medal "everyspider" 28 | { 29 | name = "Spider-Killer Cross", 30 | desc = "Clear Spider's Lair on AoHu", 31 | hidden = true, 32 | } 33 | 34 | end, 35 | 36 | 37 | Create = function () 38 | level:set_generator_style( 1 ) 39 | generator.fill( "rwall", area.FULL ) 40 | 41 | local translation = { 42 | ['.'] = "floor", 43 | [','] = { "floor", flags = { LFBLOOD } }, 44 | ['#'] = "wall", 45 | ['X'] = "rwall", 46 | ['>'] = "stairs", 47 | 48 | ['|'] = { "floor", item = "rocket" }, 49 | 50 | ['A'] = { "floor", being = "arachno" }, 51 | ['e'] = { "floor", being = core.ifdiff( 2, "arachno" ) }, 52 | ['m'] = { "floor", being = core.ifdiff( 3, "arachno" ) }, 53 | ['h'] = { "floor", being = core.ifdiff( 4, "arachno" ) }, 54 | 55 | ['1'] = { "floor", item = { "teleport", target = coord.new(8,7) } }, 56 | ['2'] = { "floor", item = { "teleport", target = coord.new(70,7) } }, 57 | ['3'] = { "floor", item = { "teleport", target = coord.new(8,13) } }, 58 | ['4'] = { "floor", item = { "teleport", target = coord.new(70,13) } }, 59 | } 60 | 61 | local map = [[ 62 | #######################.....#####.........#####.....######################## 63 | ############...........####......#####>........####...####......############ 64 | #####.....................m####.....A.###.A........##.m...##...........##### 65 | ##.......#.........#####.......###...,,,.#...........#......##....#.......## 66 | #..4....|X......###.....####......##,,,,,,#..........#........#...X|...3...# 67 | ........|#....##............###A..,,#,,,,,#,,..A....#..........#..#|........ 68 | .........#...#.................##,,,,1,,,2,,,.....##...........#..#......... 69 | ............#...................,,,,,,,,,,,,,,,###..............#........... 70 | ...h.......#.........m........e.,,,,,,,,,,,,,,,.e.........m.....#......h.... 71 | ...........#.................###,,,,,,,,,,,,,,..................#........... 72 | ............#..............##...,,,,,3,,,4,,,,,##..............#............ 73 | .........#..#............##....A.,,,#,,,,,#,,,.A.###..........#...#......... 74 | ........|#...#..........#........,,,#,,,,,,##.......####....##....X|........ 75 | #..2....|#....#........#...........,,#,,.,,..##.........####......X|...1...# 76 | ##.......X.....##.....#....m........A,#...A....###..m.............#.......## 77 | #####............##...#................###........###..................##### 78 | ############.......###.###............>...####.......####.......############ 79 | #######################...######..............#####.######################## 80 | ]] 81 | generator.place_tile( translation, map, 2, 2 ) 82 | level:player(41,10) 83 | level.status = 0 84 | end, 85 | 86 | OnKillAll = function () 87 | if level.status == 0 then 88 | ui.msg("Suddenly the webs fade. From under the webs, items emerge...") 89 | level:drop("cell",4) 90 | level:drop("ashard",2) 91 | level:drop("psboots") 92 | level:drop("scglobe") 93 | level:drop("pcell") 94 | 95 | level:drop_item("bfg9000", coord.new(41,10) ) 96 | level.status = 1 97 | if CHALLENGE == "challenge_aohu" then 98 | player:add_medal("everyspider") 99 | end 100 | end 101 | end, 102 | 103 | OnExit = function () 104 | if level.status == 0 then 105 | ui.msg("Arachnophobia!") 106 | player:add_history("He fled the Lair, knowing how to fear Arachnotrons!") 107 | else 108 | ui.msg("Silence rules the spidery lands...") 109 | player:add_history("He cleared the Lair, kickin' serious spider ass!") 110 | player:add_badge("arachno1") 111 | if core.is_challenge("challenge_aod") then player:add_badge("arachno2") end 112 | end 113 | end, 114 | 115 | } 116 | 117 | -------------------------------------------------------------------------------- /bin/lua/levels/wall.lua: -------------------------------------------------------------------------------- 1 | -- THE WALL ------------------------------------------------------------- 2 | 3 | register_level "the_wall" 4 | { 5 | name = "The Wall", 6 | entry = "On level @1 he witnessed the Wall.", 7 | welcome = "You arrive at the Wall. You feel uneasy.", 8 | level = 11, 9 | 10 | Create = function () 11 | level:set_generator_style( 1 ) 12 | generator.fill( "wall", area.FULL ) 13 | 14 | local translation = { 15 | ['.'] = "floor", 16 | ['#'] = "wall", 17 | ['X'] = "rwall", 18 | ['%'] = { "wall", flags = { LFBLOOD } }, 19 | ['*'] = "bloodpool", 20 | [','] = { "floor", flags = { LFBLOOD } }, 21 | ['+'] = "door", 22 | ['>'] = "stairs", 23 | 24 | ['^'] = { "floor", item = "backpack" }, 25 | ['!'] = { "floor", item = "umbazooka" }, 26 | ['|'] = { "floor", item = "rocket" }, 27 | 28 | ['A'] = { "floor", being = core.ifdiff( 4, "arch" ) }, 29 | } 30 | 31 | local map = [[ 32 | #########################%%######%%######################################### 33 | #########.....,......,,***%######%*,,......................................# 34 | ##..|.##........,.....,,**%######%*,.,.....................................# 35 | #.|....#.A,.......,....,,,%#######,,.......................................# 36 | #...|..#.....,........,,,*#######%*,.,.....................................# 37 | #.|....+.........,...,.,**%######%**,,,....................................# 38 | #...|..#...,...........,**%######%**,,.....................................# 39 | #.|....#......,....,..,,,*%#######*,.,.....................................# 40 | #^!.|..#...............,,,#######%*,,......................................# 41 | #......#.,...,....,..,.,,*%#######,,.,.....................................# 42 | #...|..#..............,,,*%######%*,,,.....................................# 43 | #.|....#.......,......,.,,#######%*,..,....................................# 44 | #...|..+................,,%#######,,.......................................# 45 | #.|....#.A,.......,.....,,#######%,,.,...........................>.........# 46 | #...|..#........,....,.,,*%######%*,,,,....................................# 47 | ##....##..,...........,,**%######%**,,,,...................................# 48 | #########.....,....,.,,***%######%*,,......................................# 49 | ########################%%%######%%%######################################## 50 | ]] 51 | generator.place_tile( translation, map, 2, 2 ) 52 | 53 | local left = area.new( 12, 4, 27, 17 ) 54 | local total = 11 + DIFFICULTY 55 | local knights = math.max( 12 - (6 *( DIFFICULTY - 1 ) ), 0 ) 56 | 57 | level:summon{ "knight", knights, area = left } 58 | level:summon{ "baron", total - knights, area = left } 59 | 60 | level:player(70,5) 61 | level.status = 0 62 | end, 63 | 64 | OnKillAll = function () 65 | if level.status == 2 then return end 66 | ui.msg("Peace comes back to this evil place.") 67 | level.status = 2 68 | if CHALLENGE == "challenge_aohu" then 69 | player:add_medal("everysoldier") 70 | end 71 | end, 72 | 73 | OnKill = function () 74 | level.status = 1 75 | end, 76 | 77 | OnExit = function () 78 | local result = level.status 79 | if result == 0 then 80 | ui.msg("Hearing them scream soothes the soul...") 81 | player:add_history("Not knowing what to do, he left.") 82 | elseif result == 1 then 83 | ui.msg("This must be madness!") 84 | player:add_history("He broke into the Wall, but gave up against the overwhelming forces.") 85 | elseif result == 2 then 86 | ui.msg("All in all, we're just another brick in the wall.") 87 | player:add_history("He massacred the evil behind the Wall!") 88 | player:add_badge("wall1") 89 | if core.is_challenge("challenge_aomr") or core.is_challenge("challenge_aob") or core.is_challenge("challenge_aosh") then 90 | player:add_badge("wall2") 91 | end 92 | end 93 | end, 94 | } 95 | -------------------------------------------------------------------------------- /bin/lua/missiles.lua: -------------------------------------------------------------------------------- 1 | function DoomRL.loadmissiles() 2 | 3 | register_missile "mgun" 4 | { 5 | sound_id = "pistol", 6 | color = LIGHTGRAY, 7 | sprite = SPRITE_SHOT, 8 | delay = 15, 9 | miss_base = 10, 10 | miss_dist = 3, 11 | } 12 | 13 | register_missile "mchaingun" 14 | { 15 | sound_id = "chaingun", 16 | color = WHITE, 17 | sprite = SPRITE_SHOT, 18 | delay = 10, 19 | miss_base = 10, 20 | miss_dist = 3, 21 | } 22 | 23 | register_missile "mplasma" 24 | { 25 | sound_id = "plasma", 26 | ascii = "*", 27 | color = MULTIBLUE, 28 | sprite = SPRITE_PLASMASHOT, 29 | delay = 10, 30 | miss_base = 30, 31 | miss_dist = 3, 32 | } 33 | 34 | register_missile "mrocket" 35 | { 36 | sound_id = "bazooka", 37 | color = BROWN, 38 | sprite = SPRITE_ROCKETSHOT, 39 | delay = 30, 40 | miss_base = 30, 41 | miss_dist = 5, 42 | expl_delay = 40, 43 | expl_color = RED, 44 | } 45 | 46 | register_missile "mrocketjump" 47 | { 48 | sound_id = "bazooka", 49 | color = BROWN, 50 | sprite = SPRITE_ROCKETSHOT, 51 | delay = 30, 52 | miss_base = 30, 53 | miss_dist = 5, 54 | flags = { MF_EXACT }, 55 | range = 1, 56 | expl_delay = 40, 57 | expl_color = RED, 58 | expl_flags = { EFSELFKNOCKBACK, EFSELFHALF }, 59 | } 60 | 61 | register_missile "mexplround" 62 | { 63 | sound_id = "pistol", 64 | color = LIGHTGRAY, 65 | sprite = SPRITE_SHOT, 66 | delay = 15, 67 | miss_base = 10, 68 | miss_dist = 3, 69 | expl_delay = 40, 70 | expl_color = RED, 71 | } 72 | 73 | register_missile "mexplground" 74 | { 75 | sound_id = "pistol", 76 | color = LIGHTGRAY, 77 | sprite = SPRITE_SHOT, 78 | delay = 15, 79 | miss_base = 10, 80 | miss_dist = 3, 81 | expl_delay = 40, 82 | expl_color = GREEN, 83 | } 84 | 85 | register_missile "mbfg" 86 | { 87 | sound_id = "bfg9000", 88 | ascii = "*", 89 | color = WHITE, 90 | sprite = SPRITE_BFGSHOT, 91 | delay = 100, 92 | miss_base = 50, 93 | miss_dist = 10, 94 | flags = { MF_EXACT }, 95 | expl_delay = 33, 96 | expl_color = GREEN, 97 | expl_flags = { EFSELFSAFE, EFAFTERBLINK, EFCHAIN, EFHALFKNOCK, EFNODISTANCEDROP }, 98 | } 99 | 100 | register_missile "mbfgover" 101 | { 102 | sound_id = "bfg9000", 103 | ascii = "*", 104 | color = WHITE, 105 | sprite = SPRITE_BFGSHOT, 106 | delay = 200, 107 | miss_base = 50, 108 | miss_dist = 10, 109 | flags = { MF_EXACT }, 110 | expl_delay = 33, 111 | expl_color = GREEN, 112 | expl_flags = { EFSELFSAFE, EFAFTERBLINK, EFCHAIN, EFHALFKNOCK, EFNODISTANCEDROP }, 113 | } 114 | 115 | register_missile "mblaster" 116 | { 117 | sound_id = "plasma", 118 | color = MULTIYELLOW, 119 | sprite = SPRITE_SHOT, 120 | delay = 10, 121 | miss_base = 30, 122 | miss_dist = 5, 123 | } 124 | 125 | register_missile "mknife" 126 | { 127 | sound_id = "knife", 128 | color = LIGHTGRAY, 129 | sprite = SPRITE_KNIFE, 130 | delay = 50, 131 | miss_base = 10, 132 | miss_dist = 3, 133 | flags = { MF_EXACT }, 134 | range = 5, 135 | } 136 | 137 | register_shotgun "snormal" 138 | { 139 | maxrange = 15, 140 | spread = 3, 141 | reduce = 0.07, 142 | } 143 | 144 | register_shotgun "swide" 145 | { 146 | maxrange = 8, 147 | spread = 3, 148 | reduce = 0.1, 149 | } 150 | 151 | register_shotgun "sfocused" 152 | { 153 | maxrange = 15, 154 | spread = 2, 155 | reduce = 0.05, 156 | } 157 | 158 | register_shotgun "splasma" 159 | { 160 | maxrange = 15, 161 | spread = 3, 162 | reduce = 0.05, 163 | } 164 | end 165 | -------------------------------------------------------------------------------- /bin/lua/plot.lua: -------------------------------------------------------------------------------- 1 | -- DoomRL plot lua script file -- 2 | 3 | function DoomRL.OnIntro( skip ) 4 | if core.game_type() ~= GAMESTANDARD then return end 5 | if skip then return end 6 | ui.blood_slide() 7 | ui.plot_screen([[ 8 | The trip was long -- you thought it would never end. But hell, a marine's job is rarely interesting. You hate the UAC -- nothing ever happens here. Now you've got to sit around and wait for your squadmates, who are supposed to check out what happened on Phobos. 9 | 10 | Not knowing what to do with yourself, you lean back near the comm console and listen for news from your fellow marines. 11 | ]]) 12 | ui.plot_screen([[ 13 | Suddenly... 14 | 15 | "Hell, what a bloodbath!" you hear from the comm. "Corpses Everywhere!" 16 | 17 | "What happened?!" 18 | 19 | "Look, there's someone there!" 20 | 21 | "Oh, no! God!" 22 | 23 | Gunshots. 24 | 25 | More Gunshots.]]) 26 | ui.plot_screen([[ 27 | "This can't be happening!" 28 | 29 | "Help! Help, I'm..." 30 | 31 | "Jake! Where are you?! What happ... oh, fuck!" 32 | 33 | 34 | 35 | Slurp. 36 | 37 | Silence.]]) 38 | end 39 | 40 | function DoomRL.plot_outro_1() 41 | if core.game_type() ~= GAMESTANDARD then return end 42 | ui.blood_slide() 43 | ui.plot_screen([[ 44 | Once you beat the big badasses and clean out the moon base you're supposed to win, aren't you? Aren't you? Where's your fat reward and ticket back home? What the hell is this? It's not supposed to end this way! 45 | 46 | It stinks like rotten meat but it looks like the lost Deimos base. Looks like you're stuck on The Shores of Hell. And the only way out is through... 47 | ]]) 48 | end 49 | 50 | function DoomRL.plot_outro_2() 51 | if core.game_type() ~= GAMESTANDARD then return end 52 | ui.blood_slide() 53 | ui.plot_screen([[ 54 | You've done it! The hideous Cyberdemon lord that ruled the lost Deimos moon base has been slain and you are triumphant! But ... where are you? You clamber to the edge of the moon and look down to see the awful truth. 55 | 56 | Deimos floats above Hell itself! You've never heard of anyone escaping from Hell, but you'll make the bastards sorry they ever heard of you! Quickly, you rappel down to the surface of Hell. 57 | 58 | Now, it's on to the final chapter of DRL -- Inferno!]]) 59 | end 60 | 61 | function DoomRL.plot_outro_3() 62 | if core.game_type() ~= GAMESTANDARD then return end 63 | ui.blood_slide() 64 | ui.plot_screen([[ 65 | The loathsome Spiderdemon that masterminded the invasion of the moon bases and caused so much death has had her ass kicked for all time. 66 | 67 | A hidden doorway opens and you enter. You've proven too tough for Hell to contain, and now Hell at last plays fair -- for you emerge from the door to see the green fields of Earth! Home at last. 68 | 69 | You wonder what's been happening on Earth while you were battling evil unleashed. It's good that no Hellspawn could have come through that door with you... 70 | 71 | Or could it...?]]) 72 | end 73 | 74 | function DoomRL.plot_outro_partial() 75 | if core.game_type() ~= GAMESTANDARD then return end 76 | ui.blood_slide() 77 | ui.plot_screen([[ 78 | The thermonuclear bomb shows the last second, and you know that your life is over. Still as you look at the Spider Mastermind, your eyes meet, and you smile. She is surprised, but after a split-second she understands. 79 | 80 | The thermonuclear explosion erupts, and you laugh knowing that your sacrifice has ended the reign of Hell... 81 | 82 | ...but did you get ALL of them?]]) 83 | end 84 | 85 | function DoomRL.plot_outro_final() 86 | if core.game_type() ~= GAMESTANDARD then return end 87 | if player.hp <= 0 then 88 | DoomRL.plot_outro_final_nuked() 89 | return 90 | elseif player.eq.armor and player.eq.armor.id == "uberarmor" then 91 | DoomRL.plot_outro_special() 92 | return 93 | end 94 | ui.blood_slide() 95 | ui.plot_screen([[ 96 | John Carmack is dead. 97 | 98 | No more evil will ever fall upon this world. Your damned soul rests, knowing that no more hellish forces will threaten Earth. 99 | 100 | Or will they? 101 | 102 | This will be revealed in... 103 | 104 | DRL II : Hell on Earth!]]) 105 | end 106 | 107 | function DoomRL.plot_outro_final_nuked() 108 | if core.game_type() ~= GAMESTANDARD then return end 109 | ui.blood_slide() 110 | ui.plot_screen([[ 111 | The thermonuclear bomb shows the last second, and you know that your life is over. Still as you look at the greatest of evils, your eyes meet, and you smile. To your surprise he smiles back, appearing satisfied. 112 | 113 | The thermonuclear explosion erupts, and although you know that nothing can possibly survive, you also feel that this was a hollow victory. What could he have possibly been smiling for? Perhaps you should have lived long enough to find out...]]) 114 | end 115 | 116 | 117 | function DoomRL.plot_outro_special() 118 | if core.game_type() ~= GAMESTANDARD then return end 119 | ui.blood_slide() 120 | ui.plot_screen([[ 121 | The Apostle is dead. 122 | 123 | You've beaten the forces of Hell, and yet, you've also managed to emerge victorious when reality changed to something else... 124 | 125 | You can rest easily... 126 | At least until... 127 | 128 | DRL II : Hell on Earth!]]) 129 | end 130 | -------------------------------------------------------------------------------- /bin/lua_check_config.lua: -------------------------------------------------------------------------------- 1 | pascal_method_files = { "../src/dfplayer.pas", "../src/dfbeing.pas", "../src/dfitem.pas", "../src/dfthing.pas" } 2 | pascal_function_files = { "../src/doomlua.pas", "../src/dflevel.pas", "../src/dfdungen.pas" } 3 | lua_files = { "lua/main.lua", "lua/core.lua" } 4 | lua_config_files = { "lua/constants.lua", "lua/enum.lua" } 5 | 6 | parse_merges = { 7 | { "item", "thing" }, 8 | { "being", "thing" }, 9 | { "player", "being" }, 10 | { "being", "player" }, 11 | { "self", "player" }, 12 | { "self", "item" }, 13 | } 14 | 15 | parse_libraries = { "string", "table", "math" } 16 | 17 | function parse_globals( global ) 18 | local prop = global:match("PROP_([A-Z_]+)") 19 | if prop then 20 | return "fields", "thing", string.lower(prop) 21 | end 22 | end 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /bin/modules/!readme.txt: -------------------------------------------------------------------------------- 1 | DRL modules 2 | 3 | Drop your module wad files here! 4 | 5 | Check out the ChaosForge DRL Modding subforum for latest mods, and the DRL wiki for more information! 6 | 7 | http://forum.chaosforge.org/ 8 | https://drl.chaosforge.org/wiki/ -------------------------------------------------------------------------------- /bin/modules/classic.module/data/phobos_arena.lua: -------------------------------------------------------------------------------- 1 | register_level "phobos_arena" 2 | { 3 | name = "Phobos Arena", 4 | entry = "Then at last he found the Phobos Arena!", 5 | welcome = "You enter a big arena. There's blood everywhere. You hear heavy mechanical footsteps...", 6 | 7 | Create = function () 8 | generator.fill( "wall", area.FULL ) 9 | generator.fill( "floor", area.FULL_SHRINKED ) 10 | local scatter_area = area.new( 5,3,68,15 ) 11 | local translation = { 12 | ['.'] = { "floor", flags = { LFBLOOD } }, 13 | ['#'] = "gwall", 14 | ['>'] = "stairs", 15 | } 16 | generator.scatter_put(scatter_area,translation, [[ 17 | ..... 18 | .###. 19 | .###. 20 | .###. 21 | ..... 22 | ]],"floor",12) 23 | 24 | level.flags[ LF_NOHOMING ] = true 25 | generator.scatter_blood(area.FULL_SHRINKED,"floor",100) 26 | generator.set_permanence( area.FULL ) 27 | end, 28 | 29 | OnEnter = function () 30 | local boss = level:summon("cyberdemon") 31 | boss.flags[ BF_BOSS ] = true 32 | end, 33 | } 34 | -------------------------------------------------------------------------------- /bin/modules/classic.module/main.lua: -------------------------------------------------------------------------------- 1 | core.declare( "classic", {} ) 2 | 3 | require "classic:data/phobos_arena" 4 | 5 | function classic.OnMortem() 6 | if not player:has_won() then return end 7 | 8 | local is_maxkills = (statistics.kills == statistics.max_kills) 9 | local is_90kills = (statistics.kills >= statistics.max_kills * 0.9) 10 | local is_zerodmg = (statistics.damage_taken == 0) 11 | 12 | if DIFFICULTY >= DIFF_NIGHTMARE then 13 | player:set_award( "classic_module_award", 3 ) 14 | if is_90kills then player:set_award( "classic_module_award", 5 ) end 15 | if is_zerodmg then player:set_award( "classic_module_award", 6 ) end 16 | elseif DIFFICULTY >= DIFF_VERYHARD then 17 | player:set_award( "classic_module_award", 3 ) 18 | if is_maxkills then player:set_award( "classic_module_award", 4 ) end 19 | elseif DIFFICULTY >= DIFF_HARD then 20 | player:set_award( "classic_module_award", 2 ) 21 | else 22 | player:set_award( "classic_module_award", 1 ) 23 | end 24 | end 25 | 26 | function classic.OnMortemPrint(killedby) 27 | if killedby == "defeated the Mastermind" then 28 | killedby = "defeated the Cyberdemon" 29 | end 30 | player:mortem_print( " "..player.name..", level "..player.explevel.." "..klasses[player.klass].name..", "..killedby ) 31 | end 32 | 33 | function classic.OnCreateEpisode() 34 | local BOSS_LEVEL = 10 35 | player.episode = {} 36 | 37 | player.episode[1] = { style = 1, script = "intro" } 38 | for i=2,BOSS_LEVEL-1 do 39 | player.episode[i] = { style = 1, number = i, name = "Phobos", danger = i} 40 | end 41 | player.episode[10] = { style = 1, script = "phobos_arena" } 42 | 43 | statistics.bonus_levels_count = 0 44 | end 45 | 46 | function classic.OnGenerate() 47 | generator.reset() 48 | generator.run( generators.gen_tiled ) 49 | end 50 | 51 | function classic.OnWinGame() 52 | ui.plot_screen([[ 53 | Once you beat the Cyberdemon and clean out the moon 54 | base you're supposed to win, aren't you? Aren't you? 55 | Where's your fat reward and ticket back home? What 56 | the hell is this? It's not supposed to end this way! 57 | 58 | It stinks like rotten meat but it looks like the 59 | lost Deimos base. Looks like you're stuck on 60 | The Shores of Hell. And the only way out is through... 61 | ]]) 62 | end 63 | 64 | -------------------------------------------------------------------------------- /bin/modules/classic.module/module.lua: -------------------------------------------------------------------------------- 1 | module = { 2 | id = "classic", 3 | name = "Classic Mode", 4 | author = "Kornel Kisielewicz", 5 | webpage = "http://chaosforge.org/", 6 | version = {0,3,0}, 7 | drlver = {0,9,9,7}, 8 | type = "episode", 9 | description = "Classic approach to DRL - 10 levels ending with Cyberdemon, no special levels, no klasses or master traits. At the same time an example of a episodic mod. Includes a badge series.", 10 | klass = 4, 11 | challenge = true, 12 | difficulty = true, 13 | gsupport = true, 14 | award = { 15 | name = "Classicist", 16 | levels = { 17 | { name = "Bronze", desc = "Complete on ITYTD" }, 18 | { name = "Silver", desc = "Complete on HMP" }, 19 | { name = "Gold", desc = "Complete on UV" }, 20 | { name = "Platinum", desc = "Complete on UV/100%" }, 21 | { name = "Diamond", desc = "Complete on N!/90%" }, 22 | { name = "Angelic", desc = "Complete on N! w/o damage" }, 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /bin/mortem/!readme.txt: -------------------------------------------------------------------------------- 1 | No files here? 2 | 3 | To activate automatic mortem.txt archivising, please edit the doomrl.ini file and set MORTEMARCHIVE = True; -------------------------------------------------------------------------------- /bin/mp3/!readme.txt: -------------------------------------------------------------------------------- 1 | MP3 files are needed to run the game are downloadable from http://drl.chaosforge.org/ -------------------------------------------------------------------------------- /bin/music.lua: -------------------------------------------------------------------------------- 1 | -- You can get much higher quality Doom MP3 tracks from 2 | -- http://www.sirgalahad.org/paul/doom/ 3 | -- See musicmp3.lua 4 | -- 5 | -- All tracks are from original Doom except: 6 | -- Unholy Cathedral, Final Showdown, Hells Weapons, Something Wicked, 7 | -- Of Skull And Bone, The Brick Song, and Too Hot Down Here tracks composed 8 | -- by Simon Volpert (thanks!) 9 | -- 10 | -- MP3 and OGG versions of Simons tracks can be obtained on 11 | -- the ChaosForge forums: 12 | -- http://forum.chaosforge.org/index.php/topic,3446.0.html 13 | 14 | Music = { 15 | start = "music/0 - intro.mid", 16 | interlude = "music/00 - inter.mid", 17 | bunny = "music/99 - bunny.mid", 18 | intro = "music/11 - hangar.mid", 19 | hellgate = "music/18 - phobos anomaly.mid", 20 | 21 | level2 = "music/12 - nuclear plant.mid", 22 | level3 = "music/13 - toxin refinery.mid", 23 | level4 = "music/17 - computer station.mid", 24 | level5 = "music/15 - phobos lab.mid", 25 | level6 = "music/16 - central processing.mid", 26 | level7 = "music/14 - command control.mid", 27 | level8 = "music/19 - military base.mid", 28 | level9 = "music/11 - hangar.mid", 29 | level10 = "music/12 - nuclear plant.mid", 30 | level11 = "music/13 - toxin refinery.mid", 31 | level12 = "music/14 - command control.mid", 32 | level13 = "music/15 - phobos lab.mid", 33 | level14 = "music/16 - central processing.mid", 34 | level15 = "music/22 - containment area.mid", 35 | level16 = "music/24 - deimos lab.mid", 36 | level17 = "music/26 - halls of the damned.mid", 37 | level18 = "music/27 - spawning vats.mid", 38 | level19 = "music/29 - fortress of mystery.mid", 39 | level20 = "music/32 - slough of despair.mid", 40 | level21 = "music/33 - pandemonium.mid", 41 | level22 = "music/22 - containment area.mid", 42 | level23 = "music/24 - deimos lab.mid", 43 | level24 = "music/26 - halls of the damned.mid", 44 | 45 | hells_arena = "music/32 - slough of despair.mid", 46 | the_chained_court = "music/rage.mid", 47 | military_base = "music/19 - military base.mid", 48 | halls_of_carnage = "music/19 - military base.mid", 49 | hells_armory = "music/hells_weapons.mid", 50 | spiders_lair = "music/27 - spawning vats.mid", 51 | city_of_skulls = "music/of_skull_and_bone.mid", 52 | the_wall = "music/the_brick_song.mid", 53 | unholy_cathedral = "music/unholy_cathedral.mid", 54 | the_mortuary = "music/something_wicked.mid", 55 | the_vaults = "music/dark_secrets.mid", 56 | the_lava_pits = "music/too_hot_down_here.mid", 57 | 58 | phobos_lab = "music/15 - phobos lab.mid", 59 | deimos_lab = "music/24 - deimos lab.mid", 60 | containment_area = "music/22 - containment area.mid", 61 | abyssal_plains = "music/of_skull_and_bone.mid", 62 | limbo = "music/something_wicked.mid", 63 | mt_erebus = "music/too_hot_down_here.mid", 64 | 65 | tower_of_babel = "music/28 - tower of babel.mid", 66 | hell_fortress = "music/final_showdown.mid", 67 | dis = "music/38 - dis.mid", 68 | victory = "music/98 - victory.mid", 69 | } 70 | -------------------------------------------------------------------------------- /bin/music/!readme.txt: -------------------------------------------------------------------------------- 1 | Music files are neede to run the game are downloadable from http://drl.chaosforge.org/ -------------------------------------------------------------------------------- /bin/musichq.lua: -------------------------------------------------------------------------------- 1 | -- High quality remixes of the original Doom music are a courtesy of Sonic 2 | -- Clang ( http://sonicclang.ringdev.com/ ) used with permission. 3 | 4 | -- Doom the Roguelike theme, Unholy Cathedral, Final Showdown, Hells 5 | -- Weapons, Something Wicked, Of Skull And Bone, The Brick Song, and 6 | -- Too Hot Down Here tracks composed by Simon Volpert (thanks!) 7 | 8 | Music = { 9 | start = "mp3/doom_the_roguelike.mp3", 10 | interlude = "mp3/d1inter.mp3", 11 | bunny = "mp3/d1end.mp3", 12 | intro = "mp3/cde1m1.mp3", 13 | hellgate = "mp3/cde1m8.mp3", 14 | 15 | level2 = "mp3/cde1m2.mp3", 16 | level3 = "mp3/cde1m3.mp3", 17 | level4 = "mp3/cde1m7.mp3", 18 | level5 = "mp3/cde1m5.mp3", 19 | level6 = "mp3/cde1m6.mp3", 20 | level7 = "mp3/cde1m4.mp3", 21 | level8 = "mp3/cde1m8.mp3", 22 | level9 = "mp3/cde1m1.mp3", 23 | level10 = "mp3/cde1m2.mp3", 24 | level11 = "mp3/cde1m3.mp3", 25 | level12 = "mp3/cde1m4.mp3", 26 | level13 = "mp3/cde1m5.mp3", 27 | level14 = "mp3/cde1m6.mp3", 28 | level15 = "mp3/cde1m7.mp3", 29 | level16 = "mp3/cde1m9.mp3", 30 | level17 = "mp3/cde1m2.mp3", 31 | level18 = "mp3/cde1m3.mp3", 32 | level19 = "mp3/cde1m4.mp3", 33 | level20 = "mp3/cde1m5.mp3", 34 | level21 = "mp3/cde1m6.mp3", 35 | level22 = "mp3/cde1m7.mp3", 36 | level23 = "mp3/cde1m9.mp3", 37 | level24 = "mp3/cde1m2.mp3", 38 | level25 = "mp3/cde1m3.mp3", 39 | 40 | hells_arena = "mp3/cde1m9.mp3", 41 | the_chained_court = "mp3/rage.mp3", 42 | military_base = "mp3/cde1m9.mp3", 43 | halls_of_carnage = "mp3/cde1m9.mp3", 44 | hells_armory = "mp3/hells_weapons.mp3", 45 | spiders_lair = "mp3/cde1m3.mp3", 46 | city_of_skulls = "mp3/of_skull_and_bone.mp3", 47 | the_wall = "mp3/the_brick_song.mp3", 48 | unholy_cathedral = "mp3/unholy_cathedral.mp3", 49 | the_mortuary = "mp3/something_wicked.mp3", 50 | the_vaults = "mp3/dark_secrets.mp3", 51 | the_lava_pits = "mp3/too_hot_down_here.mp3", 52 | 53 | phobos_lab = "mp3/cde1m5.mp3", 54 | deimos_lab = "mp3/hells_weapons.mp3", 55 | containment_area = "mp3/the_brick_song.mp3", 56 | abyssal_plains = "mp3/of_skull_and_bone.mp3", 57 | limbo = "mp3/something_wicked.mp3", 58 | mt_erebus = "mp3/too_hot_down_here.mp3", 59 | 60 | tower_of_babel = "mp3/cde1m8.mp3", 61 | hell_fortress = "mp3/final_showdown.mp3", 62 | dis = "mp3/cde1m8.mp3", 63 | victory = "mp3/d1readme.mp3", 64 | } 65 | -------------------------------------------------------------------------------- /bin/screenshot/!readme.txt: -------------------------------------------------------------------------------- 1 | No files here? 2 | 3 | Press F10 during the game to do screenshots! -------------------------------------------------------------------------------- /bin/unix_notes.txt: -------------------------------------------------------------------------------- 1 | To run doomrl you'll need lua5.1, timidity, sdl and sdl_mixer installed. 2 | 3 | Known issues with Unix (Linux, FreeBSD) DoomRL versions: 4 | 5 | 1. DoomRL looks for its data files inside current directory, 6 | and it saves it's files (player data, scores etc.) 7 | also inside current directory. Practically, this means that 8 | 9 | a. you should always run doomrl from the directory where the binary is 10 | (e.g. using a script like `cd //; ./doomrl'). 11 | 12 | b. it's not possible to install doomrl system-wide and to allow each 13 | user to have it's own save file. 14 | 15 | 2. It's known that DoomRL upon exit leaves the console in kind of 16 | messy state. This seems to be a problem in FPC Video unit 17 | and so far we didn't manage to find a solution. 18 | 19 | Also, DoomRL requires that your console has size 80x25 or larger. 20 | So make sure to adjust size of your console if needed. 21 | 22 | You can run DoomRL using one of the scripts doomrl_gnome-terminal, 23 | doomrl_konsole, doomrl_xterm etc. provided in the release. 24 | They run the game in new X terminal window (so the 2nd issue is not 25 | noticed), and set window size to be exactly 80x25. 26 | You can add at their beginning a line like 27 | cd // 28 | to somewhat get rid of the 1st issue too. 29 | -------------------------------------------------------------------------------- /bin/wav/!readme.txt: -------------------------------------------------------------------------------- 1 | Sound files are neede to run the game are downloadable from http://drl.chaosforge.org/ -------------------------------------------------------------------------------- /bin/wavhq/!readme.txt: -------------------------------------------------------------------------------- 1 | Sound files are neede to run the game are downloadable from http://drl.chaosforge.org/ -------------------------------------------------------------------------------- /config-linux.lua: -------------------------------------------------------------------------------- 1 | VALKYRIE_ROOT = "/home/epyon/Project/fpcvalkyrie/" 2 | OS = "LINUX" 3 | -------------------------------------------------------------------------------- /config-windows.lua: -------------------------------------------------------------------------------- 1 | VALKYRIE_ROOT = "../fpcvalkyrie/" 2 | OS = "WINDOWS" -------------------------------------------------------------------------------- /doomrl.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "src" 5 | }, 6 | { 7 | "path": "bin\\lua" 8 | }, 9 | { 10 | "path": "..\\fpcvalkyrie\\src" 11 | } 12 | ], 13 | "settings": {} 14 | } -------------------------------------------------------------------------------- /install/install.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/install/install.bmp -------------------------------------------------------------------------------- /install/install_after.txt: -------------------------------------------------------------------------------- 1 | Welcome to DRL! 2 | 3 | You will be running DRL for the first time. I hope you will find this roguelike game as enjoyable as it was for me to write it! 4 | 5 | This release is dedicated to the upcoming DRL total conversion/expansion/commercial version - Jupiter Hell Classic - wishlist it on Steam! 6 | 7 | http://jupiterhellclassic.com/ 8 | 9 | DRL is in active development (again?), and as such please be always sure that you have the most recent version, for bugs are fixed, new features appear, and the game becomes better at every iteration. You can find the lastest version on DRL website: 10 | 11 | https://drl.chaosforge.org/ 12 | 13 | Also, if you enjoy this game, join the Discord and/or the forums: 14 | 15 | http://discord.gg/jupiterhell 16 | http://forum.chaosforge.org/ 17 | 18 | -------------------------------------------------------------------------------- /install/install_license.txt: -------------------------------------------------------------------------------- 1 | This game is Freeware but with some limitations. Re-distribution 2 | (cd-magazines, other websites) etc. is allowed as long as the author 3 | is informed (admin@chaosforge.org). If you wish to include it in a printed 4 | magazine, I'd be happy to receive a complementary copy in return. 5 | 6 | THERE IS NO WARRANTY OF ANY KIND. I TAKE NO RESPONSIBILTY FOR ANY DAMAGE 7 | CAUSED BY THIS SOFTWARE. USE IT AT YOUR OWN RISK. 8 | 9 | Doom(tm) is a trademark of id Software. Many of the names in this game may 10 | be trademarks of id Software. Using them in this free parody production is 11 | not supposed to challenge the rights of id Software. 12 | -------------------------------------------------------------------------------- /install/install_small.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/install/install_small.bmp -------------------------------------------------------------------------------- /makefile.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | xpcall( function() dofile( "config.lua") end, function() end ) 3 | VALKYRIE_ROOT = VALKYRIE_ROOT or os.getenv("FPCVALKYRIE_ROOT") or "../fpcvalkyrie/" 4 | dofile (VALKYRIE_ROOT.."scripts/lua_make.lua") 5 | 6 | makefile = { 7 | name = "drl", 8 | fpc_params = { 9 | "-Fu"..VALKYRIE_ROOT.."src", 10 | "-Fu"..VALKYRIE_ROOT.."libs", 11 | }, 12 | fpc_os_params = { 13 | WINDOWS = {}, 14 | LINUX = { 15 | "-TLINUX", 16 | }, 17 | MACOSX = { 18 | "-dOSX_APP_BUNDLE", 19 | "-k-macosx_version_min -k10.4", 20 | }, 21 | }, 22 | pre_build = function() 23 | local v = make.readversion( "bin/version.txt" ) 24 | local s = make.gitrevision() 25 | make.writeversion( "src/version.inc", v, s ) 26 | --make.svncheck(s) 27 | end, 28 | post_build = function() 29 | os.execute_in_dir( "makewad", "bin" ) 30 | end, 31 | source_files = { "drl.pas", "makewad.pas", "drlwad.pas" }, 32 | publish = { 33 | lq = { 34 | exec = { "drl" }, 35 | files = { "config.lua" }, 36 | os = { 37 | WINDOWS = { "fmod64.dll", "lua5.1.dll", "SDL2.dll", "SDL2_image.dll", "SDL2_mixer.dll", "drl_console.bat" }, 38 | LINUX = { "unix_notes.txt", "drl_gnome-terminal", "drl_konsole", "drl_xterm" }, 39 | MACOSX = { "unix_notes.txt" }, 40 | }, 41 | subdirs = { 42 | backup = "!readme.txt", 43 | mortem = "!readme.txt", 44 | screenshot = "!readme.txt", 45 | modules = "!readme.txt", 46 | wav = "*.wav", 47 | music = "*.mid", 48 | }, 49 | other = { "colors.lua", "sound.lua", "music.lua", "manual.txt", "version.txt", "version_api.txt", "drl.wad", "core.wad" }, 50 | }, 51 | hq = { 52 | exec = { "drl" }, 53 | files = { { "confighq.lua", "config.lua" } }, 54 | os = { 55 | WINDOWS = { "fmod64.dll", "lua5.1.dll", "SDL2.dll", "SDL2_image.dll", "SDL2_mixer.dll", "drl_console.bat" }, 56 | LINUX = { "unix_notes.txt", "drl_gnome-terminal", "drl_konsole", "drl_xterm" }, 57 | MACOSX = { "unix_notes.txt" }, 58 | }, 59 | subdirs = { 60 | backup = "!readme.txt", 61 | mortem = "!readme.txt", 62 | screenshot = "!readme.txt", 63 | modules = "!readme.txt", 64 | wavhq = "*.wav", 65 | mp3 = "*.mp3", 66 | }, 67 | other = { "colors.lua", "soundhq.lua", "musichq.lua", "manual.txt", "version.txt", "version_api.txt", "drl.wad", "core.wad" }, 68 | } 69 | }, 70 | commands = { 71 | lq = function() 72 | make.package( make.publish( (OS_VER_PREFIX or "")..make.version_name().."-lq", "lq" ), PUBLISH_DIR ) 73 | end, 74 | hq = function() 75 | make.package( make.publish( (OS_VER_PREFIX or "")..make.version_name(), "hq" ), PUBLISH_DIR ) 76 | end, 77 | install = function() makefile.commands.installhq() end, 78 | installhq = function() 79 | if OS == "WINDOWS" then 80 | make.generate_iss( "doomrl.iss", "hq", PUBLISH_DIR ) 81 | elseif OS == "MACOSX" then 82 | make.generate_bundle( "hq", PUBLISH_DIR ) 83 | end 84 | end, 85 | installlq = function() 86 | if OS == "WINDOWS" then 87 | make.generate_iss( "doomrl.iss", "lq", PUBLISH_DIR ) 88 | elseif OS == "MACOSX" then 89 | make.generate_bundle( "lq", PUBLISH_DIR ) 90 | end 91 | end, 92 | all = function() 93 | makefile.commands.lq() 94 | makefile.commands.hq() 95 | makefile.commands.install() 96 | end, 97 | alllq = function() 98 | makefile.commands.lq() 99 | makefile.commands.installlq() 100 | end, 101 | }, 102 | install = { 103 | guid = "E78C63C9-9849-45FA-8315-2AE38A293E2E", 104 | name = "DRL", 105 | publisher = "ChaosForge", 106 | license = "install\\install_license.txt", 107 | info_after = "install\\install_after.txt", 108 | iss_icon = "src\\icon.ico", 109 | iss_image = "install\\install.bmp", 110 | iss_simage = "install\\install_small.bmp", 111 | iss_url = "http://www.chaosforge.org/", 112 | iss_nocomp = { "wad", "mp3" }, 113 | iss_eicons = { 114 | { name = "DRL", exe = "drl" }, 115 | { name = "DRL (console mode)", exe = "drl", parameters = "-console" }, 116 | { name = "DRL Manual", file = "manual.txt" }, 117 | { name = "ChaosForge Website", url = "http://www.chaosforge.org/" }, 118 | { name = "DRL Website", url = "https://drl.chaosforge.org/" }, 119 | { name = "DRL Forum", url = "http://forum.chaosforge.org/" }, 120 | }, 121 | dmg_size = 128000, 122 | app_icon = "bin/iconfile.icns", 123 | app_bg = "background.png", 124 | app_fworks = { 125 | "Frameworks/SDL.framework", 126 | "Frameworks/SDL_image.framework", 127 | "Frameworks/SDL_mixer.framework", 128 | }, 129 | app_exefix = function( file ) 130 | os.execute("install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL "..file ) 131 | end, 132 | 133 | } 134 | } 135 | 136 | make.compile() 137 | make.command( arg[1] ) 138 | -------------------------------------------------------------------------------- /makewad.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd bin 3 | makewad.exe 4 | cd .. -------------------------------------------------------------------------------- /mkbin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # $1 must be a version number, like '098-beta4' 5 | 6 | VERSION="$1" 7 | shift 1 8 | 9 | BINDIR=bin 10 | 11 | #if [ -n "$IS_SOUND" ]; then 12 | # SOUND_SUFFIX='' 13 | #else 14 | # SOUND_SUFFIX='-nosound' 15 | #fi 16 | 17 | BIN_BASE_NAME=doomrl-win-"$VERSION" 18 | SRC_BASE_NAME=doomrl-win-"$VERSION"-src 19 | 20 | # Prepare temp dir 21 | DIST_TMP_PATH=pkg/"$BIN_BASE_NAME"/ 22 | 23 | rm -Rf "$DIST_TMP_PATH" 24 | /bin/mkdir "$DIST_TMP_PATH" "$DIST_TMP_PATH"mortem/ "$DIST_TMP_PATH"screenshot/ "$DIST_TMP_PATH"music/ "$DIST_TMP_PATH"wav/ 25 | 26 | # Copy regular files to temp dir 27 | cp -R "$BINDIR"/doomrl.wad \ 28 | "$BINDIR"/manual.txt \ 29 | "$BINDIR"/version.txt \ 30 | "$BINDIR"/doomrl.bat \ 31 | "$BINDIR"/doomrl.exe \ 32 | "$DIST_TMP_PATH" 33 | 34 | cp "$BINDIR"/doomrl_dist.ini "$DIST_TMP_PATH"doomrl.ini 35 | cp "$BINDIR"/sound.ini "$DIST_TMP_PATH"sound.ini 36 | cp "$BINDIR"/music.ini "$DIST_TMP_PATH"music.ini 37 | cp "$BINDIR"/musicmp3.ini "$DIST_TMP_PATH"musicmp3.ini 38 | 39 | cp -R "$BINDIR"/music/*.mid "$DIST_TMP_PATH"/music 40 | cp -R "$BINDIR"/wav/*.wav "$DIST_TMP_PATH"/wav 41 | 42 | cp -R "$BINDIR"/*.dll "$DIST_TMP_PATH" 43 | 44 | cp "$BINDIR"/mortem/'!readme.txt' "$DIST_TMP_PATH"mortem/ 45 | cp "$BINDIR"/screenshot/'!readme.txt' "$DIST_TMP_PATH"screenshot/ 46 | 47 | #if [ -n "$IS_SOUND" ]; then 48 | # cp -R "$BINDIR"/music \ 49 | # "$BINDIR"/wav \ 50 | # "$DIST_TMP_PATH" 51 | #fi 52 | 53 | # Make sure permissions are OK 54 | #find "$DIST_TMP_PATH" -type f -and -exec chmod 644 '{}' ';' 55 | #find "$DIST_TMP_PATH" -type d -and -exec chmod 755 '{}' ';' 56 | 57 | # Copy and set permissions of executable files 58 | #install "$BINDIR"/doomrl \ 59 | # "$BINDIR"/doomrl_gnome-terminal \ 60 | # "$BINDIR"/doomrl_konsole \ 61 | # "$BINDIR"/doomrl_xterm \ 62 | # "$DIST_TMP_PATH" 63 | 64 | # Pack ---------------------------------------- 65 | 66 | DIST_ARCHIVE_NAME="$BIN_BASE_NAME".zip 67 | 68 | cd pkg 69 | rm -f "$DIST_ARCHIVE_NAME" 70 | zip -r "$DIST_ARCHIVE_NAME" "$BIN_BASE_NAME" 71 | cd .. 72 | 73 | #tar czf "$DIST_ARCHIVE_NAME" "$ARCHIVE_BASE_NAME" 74 | #pushd > /dev/null 75 | cp pkg/"$DIST_ARCHIVE_NAME" . 76 | 77 | echo 'Made '"$DIST_ARCHIVE_NAME" -------------------------------------------------------------------------------- /mksrc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # $1 must be a version number, like '098-beta4' 5 | 6 | VERSION="$1" 7 | shift 1 8 | 9 | BINDIR=bin 10 | SRCDIR=src 11 | 12 | #if [ -n "$IS_SOUND" ]; then 13 | # SOUND_SUFFIX='' 14 | #else 15 | # SOUND_SUFFIX='-nosound' 16 | #fi 17 | 18 | SRC_BASE_NAME=doomrl-win-"$VERSION"-src 19 | # Prepare temp dir 20 | DIST_TMP_PATH=pkg/"$SRC_BASE_NAME"/ 21 | 22 | 23 | 24 | rm -Rf "$DIST_TMP_PATH" 25 | /bin/mkdir "$DIST_TMP_PATH" "$DIST_TMP_PATH"bin/ "$DIST_TMP_PATH"src/ "$DIST_TMP_PATH"bin/mortem/ "$DIST_TMP_PATH"bin/screenshot/ 26 | 27 | # Copy regular files to temp dir 28 | cp -R "$BINDIR"/doomrl.wad \ 29 | "$BINDIR"/manual.txt \ 30 | "$BINDIR"/version.txt \ 31 | "$BINDIR"/doomrl.bat \ 32 | "$DIST_TMP_PATH"bin 33 | 34 | cp "$BINDIR"/doomrl_dist.ini "$DIST_TMP_PATH"bin/doomrl.ini 35 | 36 | cp -R "$BINDIR"/music \ 37 | "$BINDIR"/wav \ 38 | "$BINDIR"/data \ 39 | "$BINDIR"/lua \ 40 | "$BINDIR"/helpunzi \ 41 | "$DIST_TMP_PATH"bin 42 | 43 | cp -R "$SRCDIR"/*.pas "$DIST_TMP_PATH"src 44 | cp -R "$SRCDIR"/*.inc "$DIST_TMP_PATH"src 45 | cp -R "$SRCDIR"/*.lpi "$DIST_TMP_PATH"src 46 | cp -R "$SRCDIR"/*.sh "$DIST_TMP_PATH"src 47 | cp -R "$SRCDIR"/Makefile "$DIST_TMP_PATH"src 48 | 49 | cp "$BINDIR"/mortem/'!readme.txt' "$DIST_TMP_PATH"bin/mortem/ 50 | cp "$BINDIR"/screenshot/'!readme.txt' "$DIST_TMP_PATH"bin/screenshot/ 51 | 52 | #if [ -n "$IS_SOUND" ]; then 53 | # cp -R "$BINDIR"/music \ 54 | # "$BINDIR"/wav \ 55 | # "$DIST_TMP_PATH" 56 | #fi 57 | 58 | # Make sure permissions are OK 59 | #find "$DIST_TMP_PATH" -type f -and -exec chmod 644 '{}' ';' 60 | #find "$DIST_TMP_PATH" -type d -and -exec chmod 755 '{}' ';' 61 | 62 | # Copy and set permissions of executable files 63 | #install "$BINDIR"/doomrl \ 64 | # "$BINDIR"/doomrl_gnome-terminal \ 65 | # "$BINDIR"/doomrl_konsole \ 66 | # "$BINDIR"/doomrl_xterm \ 67 | # "$DIST_TMP_PATH" 68 | 69 | # Pack ---------------------------------------- 70 | 71 | DIST_ARCHIVE_NAME="$SRC_BASE_NAME".zip 72 | 73 | cd pkg 74 | rm -f "$DIST_ARCHIVE_NAME" 75 | zip -r "$DIST_ARCHIVE_NAME" "$SRC_BASE_NAME" 76 | cd .. 77 | 78 | #tar czf "$DIST_ARCHIVE_NAME" "$ARCHIVE_BASE_NAME" 79 | #pushd > /dev/null 80 | cp pkg/"$DIST_ARCHIVE_NAME" . 81 | 82 | echo 'Made '"$DIST_ARCHIVE_NAME" -------------------------------------------------------------------------------- /old/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/old/spritesheet.png -------------------------------------------------------------------------------- /old/spritesheet_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/old/spritesheet_color.png -------------------------------------------------------------------------------- /old/spritesheet_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/old/spritesheet_shadow.png -------------------------------------------------------------------------------- /scripts/doomrl_snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # Make doomrl snapshot: svn up, clean build and pack both sound and nosound versions, 5 | # move generated tar.gz to ~/public_html/doomrl-snapshots/... 6 | 7 | DOOMRL_VERSION='snapshot-'`date +%F` 8 | DOOMRL_OS_NAME='linux-i386' 9 | 10 | # Set to non-empty to link statically with lua. 11 | # 12 | # This adds proper options to "make" and checks with ldd afterwards, 13 | # but to actually make it work you also have to make sure /usr/lib/liblua*.so 14 | # do not exist. 15 | # 16 | # TODO: is there any way to do it more intelligently? I was trying 17 | # to set in lua.pas LuaDLL='', then you have to link with -k-lxxx options, 18 | # and make 'FPCOPT=-k--export-dynamic -k-Bstatic -k-llua5.1 -k-Bdynamic' 19 | # should work --- but it doesn't. For now use this hack. 20 | # 21 | LINK_LUA_STATICALLY='t' 22 | 23 | if [ -n "$LINK_LUA_STATICALLY" ]; then 24 | MAKE_FPCOPT='FPCOPT=-k-lm' 25 | else 26 | MAKE_FPCOPT='' 27 | fi 28 | 29 | # log messages and dates in english 30 | export LANG=C 31 | # make sure FPC and utilities is on path 32 | export PATH=/usr/local/bin:"$PATH" 33 | 34 | do_clean_src () 35 | { 36 | # clean doomrl and fpcvalkyrie 37 | find /home/epyon/src/doomrl/trunk/ \ 38 | /home/epyon/src/fpcvalkyrie/trunk/ \ 39 | '(' -iname '*.o' -or -iname '*.ppu' ')' -exec rm -f '{}' ';' 40 | } 41 | 42 | OUTPUT_PATH=~/public_html/doomrl-snapshots/`date +%F`/ 43 | mkdir -p "$OUTPUT_PATH" 44 | 45 | OUTPUT_LOG="$OUTPUT_PATH"snapshot.log 46 | echo 'doomrl_snapshot started at '`date` > "$OUTPUT_LOG" 47 | 48 | # svn up doomrl and fpcvalkyrie 49 | svn up /home/epyon/src/doomrl/trunk/ >> "$OUTPUT_LOG" 50 | svn up /home/epyon/src/fpcvalkyrie/trunk/ >> "$OUTPUT_LOG" 51 | 52 | cd /home/epyon/src/doomrl/trunk/src/ 53 | 54 | # compile nosound version 55 | do_clean_src 56 | sed --in-place --separate -e 's|{$DEFINE SOUND}|{x$DEFINE SOUND}|g' doomrl.inc 57 | make "$MAKE_FPCOPT" >> "$OUTPUT_LOG" 2>&1 58 | 59 | # check nosound version really not linked to SDL, SDL_mixer etc. 60 | ldd ../bin/doomrl > /tmp/doomrl_snapshot_temp.txt 61 | ldd ../bin/makewad >> /tmp/doomrl_snapshot_temp.txt 62 | if grep --quiet -i SDL /tmp/doomrl_snapshot_temp.txt; then 63 | echo 'doomrl_snapshot: Check failed: doomrl or makewad compiled (supposedly) without SOUND are still linked to SDL lib.' 64 | exit 1 65 | fi 66 | 67 | # check nosound version really not dynamically linked to lua, if requested statically. 68 | if [ -n "$LINK_LUA_STATICALLY" ]; then 69 | if grep --quiet -i lua /tmp/doomrl_snapshot_temp.txt; then 70 | echo 'doomrl_snapshot: Check failed: doomrl or makewad are dynamically linked to lua, but requested statically.' 71 | exit 1 72 | fi 73 | fi 74 | 75 | # run makewad to gen doomrl.wad 76 | cd /home/epyon/src/doomrl/trunk/bin/ 77 | ./makewad 78 | cd /home/epyon/src/doomrl/trunk/src/ 79 | 80 | # pack nosound version 81 | ../scripts/mk_unix_dist.sh "$DOOMRL_VERSION" "$DOOMRL_OS_NAME" '' >> "$OUTPUT_LOG" 82 | 83 | # compile sound version 84 | do_clean_src 85 | sed --in-place --separate -e 's|{x$DEFINE SOUND}|{$DEFINE SOUND}|g' doomrl.inc 86 | make "$MAKE_FPCOPT" >> "$OUTPUT_LOG" 2>&1 87 | 88 | # pack sound version 89 | ../scripts/mk_unix_dist.sh "$DOOMRL_VERSION" "$DOOMRL_OS_NAME" 't' >> "$OUTPUT_LOG" 90 | 91 | # now that we created tar.gz packages, move them to appropriate directory at ~/public_html/doomrl-snapshots/ 92 | mv -f doomrl-"$DOOMRL_OS_NAME"-"$DOOMRL_VERSION".tar.gz \ 93 | doomrl-"$DOOMRL_OS_NAME"-"$DOOMRL_VERSION"-nosound.tar.gz \ 94 | "$OUTPUT_PATH" 95 | 96 | # Clean old snapshots, to conserve disk space. 97 | # Keep only snapshots from last couple of days. 98 | cd ~/public_html/doomrl-snapshots/ 99 | set +e 100 | find . -mindepth 1 -maxdepth 1 \ 101 | -type d -and \ 102 | -name '????-??-??' -and \ 103 | '(' -not -iname `date +%F` ')' -and \ 104 | '(' -not -iname `date --date='-1 day' +%F` ')' -and \ 105 | '(' -not -iname `date --date='-2 day' +%F` ')' -and \ 106 | '(' -not -iname `date --date='-3 day' +%F` ')' -and \ 107 | '(' -not -iname `date --date='-4 day' +%F` ')' -and \ 108 | '(' -not -iname `date --date='-5 day' +%F` ')' -and \ 109 | '(' -not -iname `date --date='-6 day' +%F` ')' -and \ 110 | '(' -not -iname `date --date='-7 day' +%F` ')' -and \ 111 | -exec rm -Rf '{}' ';' 112 | set -e 113 | 114 | # Create "latest" link. 115 | rm -f ~/public_html/doomrl-snapshots/latest 116 | ln -s `date +%F` ~/public_html/doomrl-snapshots/latest 117 | -------------------------------------------------------------------------------- /scripts/mk_unix_dist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # Call this inside doomrl src directory, after every file is 5 | # prepared/compiled etc. 6 | # $1 must be a version number, like '0.9.8-beta4' 7 | # $2 must be an OS name, like 'linux' or 'freebsd' 8 | # $3 indicates that this is version with sound if nonempty (pass empty 9 | # string if nosound version wanted) 10 | 11 | VERSION="$1" 12 | OS_NAME="$2" 13 | IS_SOUND="$3" 14 | shift 3 15 | 16 | BINDIR=../bin 17 | 18 | if [ -n "$IS_SOUND" ]; then 19 | SOUND_SUFFIX='' 20 | else 21 | SOUND_SUFFIX='-nosound' 22 | fi 23 | 24 | ARCHIVE_BASE_NAME=doomrl-"$OS_NAME"-"$VERSION""$SOUND_SUFFIX" 25 | 26 | # Prepare temp dir 27 | DIST_TMP_PATH=/tmp/"$ARCHIVE_BASE_NAME"/ 28 | 29 | rm -Rf "$DIST_TMP_PATH" 30 | mkdir "$DIST_TMP_PATH" "$DIST_TMP_PATH"mortem/ "$DIST_TMP_PATH"modules/ "$DIST_TMP_PATH"screenshot/ "$DIST_TMP_PATH"backup/ 31 | 32 | # Copy regular files to temp dir. 33 | # Note: Due to default doomrl_dist.ini, sound/musis* inis are needed even for nosound version. 34 | cp -R "$BINDIR"/doomrl.wad \ 35 | "$BINDIR"/manual.txt \ 36 | "$BINDIR"/version.txt \ 37 | "$BINDIR"/unix_notes.txt \ 38 | "$BINDIR"/colors.lua \ 39 | "$BINDIR"/sound.lua \ 40 | "$BINDIR"/music.lua \ 41 | "$BINDIR"/musicmp3.lua \ 42 | "$BINDIR"/musiccdmp3.lua \ 43 | "$DIST_TMP_PATH" 44 | 45 | cp "$BINDIR"/config.lua "$DIST_TMP_PATH"config.lua 46 | 47 | sed --in-place --separate -e 's|AllowHighAscii = true|AllowHighAscii = false|g' \ 48 | "$DIST_TMP_PATH"config.lua 49 | 50 | cp "$BINDIR"/mortem/'!readme.txt' "$DIST_TMP_PATH"mortem/ 51 | cp "$BINDIR"/screenshot/'!readme.txt' "$DIST_TMP_PATH"screenshot/ 52 | cp "$BINDIR"/backup/'!readme.txt' "$DIST_TMP_PATH"backup/ 53 | cp "$BINDIR"/modules/'!readme.txt' "$DIST_TMP_PATH"modules/ 54 | 55 | if [ -n "$IS_SOUND" ]; then 56 | cp -R "$BINDIR"/music \ 57 | "$BINDIR"/wav \ 58 | "$DIST_TMP_PATH" 59 | fi 60 | 61 | # clean inside 62 | find "$DIST_TMP_PATH" -type d -name .svn -prune -exec rm -Rf '{}' ';' 63 | 64 | # Make sure permissions are OK 65 | find "$DIST_TMP_PATH" -type f -and -exec chmod 644 '{}' ';' 66 | find "$DIST_TMP_PATH" -type d -and -exec chmod 755 '{}' ';' 67 | 68 | # Copy and set permissions of executable files 69 | install "$BINDIR"/doomrl \ 70 | "$BINDIR"/doomrl_gnome-terminal \ 71 | "$BINDIR"/doomrl_konsole \ 72 | "$BINDIR"/doomrl_xterm \ 73 | "$DIST_TMP_PATH" 74 | 75 | # Pack ---------------------------------------- 76 | 77 | DIST_ARCHIVE_NAME="$ARCHIVE_BASE_NAME".tar.gz 78 | 79 | pushd /tmp/ > /dev/null 80 | tar czf "$DIST_ARCHIVE_NAME" "$ARCHIVE_BASE_NAME" 81 | pushd > /dev/null 82 | mv /tmp/"$DIST_ARCHIVE_NAME" . 83 | 84 | echo 'Made '"$DIST_ARCHIVE_NAME" 85 | -------------------------------------------------------------------------------- /src/Makefile.fpc: -------------------------------------------------------------------------------- 1 | [target] 2 | programs=doomrl makewad 3 | 4 | [prerules] 5 | VALKYRIEPATH := ../../fpcvalkyrie/src/ 6 | LIBSPATH := ../../fpcvalkyrie/libs/ 7 | LUAPATH := ../../fpcvalkyrie/lua/ 8 | 9 | [require] 10 | packages= 11 | 12 | [install] 13 | fpcpackage=n 14 | 15 | [compiler] 16 | unitdir=$(VALKYRIEPATH) $(LUAPATH) $(LIBSPATH) 17 | unittargetdir=../temp 18 | includedir=../bin 19 | options=-O2 -S2 20 | targetdir=../bin 21 | version=3.2.2 22 | options=-gl -Mobjfpc 23 | 24 | [dist] 25 | destdir=../ 26 | zipname=doomrl 27 | ziptarget=all 28 | 29 | [clean] 30 | files=$(wildcard *$(OEXT)) $(wildcard *$(PPUEXT)) $(wildcard *$(RSTEXT)) \ 31 | $(wildcard ../temp/*$(OEXT)) $(wildcard ../temp/*$(PPUEXT)) $(wildcard ../temp/*$(RSTEXT)) \ 32 | -------------------------------------------------------------------------------- /src/costest.lpr: -------------------------------------------------------------------------------- 1 | program costest; 2 | {$mode objfpc}{$H+} 3 | uses gl, glu, sdl, vsystems, vsdl, voutput, vsdloutput, vinput, vsdlinput; 4 | 5 | const Colors : array[0..15] of array[0..2] of Real = ( 6 | ( 0, 0, 0 ), 7 | ( 0, 0, 0.625 ), 8 | ( 0, 0.625, 0 ), 9 | ( 0, 0.625, 0.625 ), 10 | ( 0.625, 0, 0 ), 11 | ( 0.625, 0, 0.625 ), 12 | ( 0.625, 0.625, 0 ), 13 | ( 0.75, 0.75, 0.75 ), 14 | ( 0.5, 0.5, 0.5 ), 15 | ( 0, 0, 1.0 ), 16 | ( 0, 1.0, 0 ), 17 | ( 0, 1.0, 1.0 ), 18 | ( 1.0, 0, 0 ), 19 | ( 1.0, 0, 1.0 ), 20 | ( 1.0, 1.0, 0 ), 21 | ( 1.0, 1.0, 1.0 ) 22 | ); 23 | var Color : Byte = 1; 24 | 25 | type 26 | 27 | { TCosOutput } 28 | 29 | TCosOutput = class( TSDLOutput ) 30 | constructor Create; 31 | procedure Update; override; 32 | private 33 | Sprites : TSurface; 34 | SpriteMask : TSurface; 35 | end; 36 | 37 | { TCosOutput } 38 | 39 | constructor TCosOutput.Create; 40 | begin 41 | inherited Create; 42 | Sprites := TSurface.Create('graphics/spritesheet_base.png'); 43 | SpriteMask := TSurface.Create('graphics/spritesheet_mask.png'); 44 | Sprites.SetColorKey(255,0,255); 45 | Sprites.RenderGL(); 46 | SpriteMask.RenderGL(); 47 | SetTitle('DoomRL Cosplay Test','DoomRL Cosplay Test'); 48 | end; 49 | 50 | procedure TCosOutput.Update; 51 | var Idx : Byte; 52 | begin 53 | glEnable( GL_TEXTURE_2D ); 54 | //glDisable( GL_DEPTH_TEST ); 55 | glEnable( GL_BLEND ); 56 | glClearColor(0.0,0.0,0.0,1.0); 57 | glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); 58 | 59 | glMatrixMode( GL_PROJECTION ); 60 | glPushMatrix(); 61 | glLoadIdentity(); 62 | gluOrtho2D(0, ValkyrieSDL.Width-1, ValkyrieSDL.Height-1, 0); 63 | 64 | glMatrixMode( GL_MODELVIEW ); 65 | glPushMatrix(); 66 | glLoadIdentity(); 67 | 68 | glDisable( GL_BLEND ); 69 | 70 | glBindTexture(GL_TEXTURE_2D, 0); 71 | glBegin(GL_QUADS); 72 | Idx := Color; 73 | glColor4f(Colors[Idx][0],Colors[Idx][1],Colors[Idx][2],1.0); 74 | glVertex2i(512,10); 75 | glVertex2i(512,50); 76 | glVertex2i(790,50); 77 | glVertex2i(790,10); 78 | 79 | glColor4f(1,1,1,1.0); 80 | glVertex2i(9+Idx*40, 561); 81 | glVertex2i(9+Idx*40, 583); 82 | glVertex2i(31+Idx*40,583); 83 | glVertex2i(31+Idx*40,561); 84 | 85 | for Idx := 0 to 15 do 86 | begin 87 | glColor4f(Colors[Idx][0],Colors[Idx][1],Colors[Idx][2],1.0); 88 | glVertex2i(10+Idx*40, 562); 89 | glVertex2i(10+Idx*40, 582); 90 | glVertex2i(30+Idx*40, 582); 91 | glVertex2i(30+Idx*40, 562); 92 | end; 93 | 94 | glEnd(); 95 | 96 | glColor4f(1.0,1.0,1.0,1.0); 97 | glEnable( GL_BLEND ); 98 | glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); 99 | 100 | Sprites.DrawGL; 101 | Idx := Color; 102 | glColor4f(Colors[Idx][0],Colors[Idx][1],Colors[Idx][2],1.0); 103 | glBlendFunc( GL_ONE, GL_ONE ); 104 | SpriteMask.DrawGL; 105 | 106 | SDL_GL_SwapBuffers(); 107 | end; 108 | 109 | var Key : Byte; 110 | begin 111 | Systems.Add(Output,TCosOutput.Create); 112 | Systems.Add(Input,TSDLInput.Create); 113 | 114 | repeat 115 | Key := Input.GetKey; 116 | if Key = VKEY_RIGHT then if Color >= 15 then Color := 0 else Inc( Color ); 117 | if Key = VKEY_LEFT then if Color = 0 then Color := 15 else Dec( Color ); 118 | until Key = VKEY_ESCAPE; 119 | 120 | end. 121 | 122 | -------------------------------------------------------------------------------- /src/dfaffect.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit dfaffect; 3 | interface 4 | uses vutil, dfdata; 5 | 6 | type 7 | 8 | { TAffects } 9 | 10 | TAffects = object 11 | List : array[1..MAXAFFECT] of LongInt; 12 | constructor Clear; 13 | procedure Add( affnum : Byte; duration : LongInt ); 14 | function Remove( affnum : Byte ) : boolean; 15 | procedure Tick; 16 | function IsActive( affnum : Byte ) : boolean; 17 | function IsExpiring( affnum : Byte ) : boolean; 18 | function getEffect : TStatusEffect; 19 | function getTime( affnum : Byte ) : longint; 20 | private 21 | procedure Run( affnum : Byte ); 22 | procedure Expire( affnum : Byte ); 23 | 24 | end; 25 | 26 | implementation 27 | 28 | uses vdebug, vluasystem, dfplayer, doomio; 29 | 30 | constructor TAffects.Clear; 31 | var aff : Word; 32 | begin 33 | for aff := 1 to MAXAFFECT do 34 | List[aff] := 0; 35 | end; 36 | 37 | function TAffects.IsActive(affnum : Byte) : boolean; 38 | begin 39 | Exit(List[affnum] <> 0); 40 | end; 41 | 42 | function TAffects.IsExpiring(affnum : Byte): boolean; 43 | begin 44 | Exit(List[affnum] <= 5); 45 | IO.Msg( LuaSystem.Get([ 'affects', affnum, 'message_ending' ],'') ); 46 | end; 47 | 48 | function TAffects.getEffect : TStatusEffect; 49 | var cn : DWord; 50 | st : DWord; 51 | begin 52 | getEffect := StatusNormal; 53 | st := 0; 54 | for cn := 1 to MAXAFFECT do 55 | if List[cn] <> 0 then 56 | if Affects[cn].StatusStr > st then 57 | begin 58 | getEffect := Affects[cn].StatusEff; 59 | st := Affects[cn].StatusStr; 60 | end; 61 | end; 62 | 63 | function TAffects.getTime(affnum : Byte): LongInt; 64 | begin 65 | Exit(List[affnum]); 66 | end; 67 | 68 | procedure TAffects.Add(affnum : Byte; duration : LongInt); 69 | begin 70 | if duration = 0 then Exit; 71 | if List[affnum] = 0 then 72 | begin 73 | IO.Msg( LuaSystem.Get([ 'affects', affnum, 'message_init' ],'') ); 74 | if AffectHookOnAdd in Affects[affnum].Hooks then 75 | LuaSystem.ProtectedCall( [ 'affects',affnum,'OnAdd' ],[Player]); 76 | end; 77 | if List[affnum] >= 0 then 78 | List[affnum] += duration; 79 | end; 80 | 81 | function TAffects.Remove(affnum : Byte) : boolean; 82 | begin 83 | Remove := True; 84 | if List[affnum] = 0 then Exit(false); 85 | Expire( affnum ); 86 | end; 87 | 88 | procedure TAffects.Expire(affnum : Byte); 89 | begin 90 | List[affnum] := 0; 91 | if AffectHookOnRemove in Affects[affnum].Hooks then 92 | LuaSystem.ProtectedCall( [ 'affects',affnum,'OnRemove'],[Player]); 93 | IO.Msg( LuaSystem.Get([ 'affects', affnum, 'message_done' ],'') ); 94 | end; 95 | 96 | procedure TAffects.Tick; 97 | var cn : DWord; 98 | begin 99 | for cn := 1 to MAXAFFECT do 100 | if List[cn] <> 0 then 101 | begin 102 | if List[cn] > 0 then Dec(List[cn]); 103 | if List[cn] = 5 then IO.Msg( LuaSystem.Get([ 'affects', cn, 'message_ending' ],'') ); 104 | if List[cn] <> 0 then Run(cn) 105 | else Expire(cn); 106 | end; 107 | end; 108 | 109 | procedure TAffects.Run(affnum : Byte); 110 | begin 111 | if AffectHookOnTick in Affects[affnum].Hooks then 112 | LuaSystem.ProtectedCall( [ 'affects',affnum,'OnTick' ] ,[Player]); 113 | end; 114 | 115 | end. 116 | -------------------------------------------------------------------------------- /src/dfthing.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | { 3 | ---------------------------------------------------- 4 | DFTHING.PAS -- Basic Thing object for DownFall 5 | Copyright (c) 2002 by Kornel "Anubis" Kisielewicz 6 | ---------------------------------------------------- 7 | } 8 | unit dfthing; 9 | interface 10 | uses SysUtils, Classes, vluaentitynode, vutil, vluatable, dfdata, doomhooks; 11 | 12 | type 13 | 14 | { TThing } 15 | 16 | TThing = class( TLuaEntityNode ) 17 | constructor Create( const aID : AnsiString ); 18 | constructor CreateFromStream( Stream : TStream ); override; 19 | procedure playBasicSound(const SoundID : string); 20 | procedure CallHook( Hook : Byte; const Params : array of Const ); 21 | function CallHookCheck( Hook : Byte; const Params : array of Const ) : Boolean; 22 | function GetSprite : TSprite; virtual; 23 | procedure WriteToStream( Stream : TStream ); override; 24 | protected 25 | procedure LuaLoad( Table : TLuaTable ); virtual; 26 | protected 27 | FSprite : TSprite; 28 | {$TYPEINFO ON} 29 | public 30 | property Sprite : TSprite read FSprite write FSprite; 31 | end; 32 | 33 | implementation 34 | 35 | uses typinfo, variants, 36 | vluasystem, vcolor, vdebug, 37 | doombase, doomio; 38 | 39 | constructor TThing.Create( const aID : AnsiString ); 40 | begin 41 | inherited Create( aID ); 42 | end; 43 | 44 | procedure TThing.LuaLoad(Table: TLuaTable); 45 | var iColorID : AnsiString; 46 | begin 47 | FGylph.ASCII := Table.getChar('ascii'); 48 | FGylph.Color := Table.getInteger('color'); 49 | Name := Table.getString('name'); 50 | FillChar( FSprite, SizeOf( FSprite ), 0 ); 51 | ReadSprite( Table, FSprite ); 52 | 53 | iColorID := FID; 54 | if Table.IsString('color_id') then iColorID := Table.getString('color_id'); 55 | 56 | if ColorOverrides.Exists(iColorID) then 57 | FGylph.Color := ColorOverrides[iColorID]; 58 | 59 | end; 60 | 61 | procedure TThing.playBasicSound(const SoundID: string); 62 | begin 63 | IO.Audio.PlaySound( IO.Audio.ResolveSoundID( [FID+'.'+SoundID, SoundID] ), FPosition ); 64 | end; 65 | 66 | procedure TThing.CallHook ( Hook : Byte; const Params : array of const ) ; 67 | begin 68 | if Hook in FHooks then LuaSystem.ProtectedRunHook(Self, HookNames[Hook], Params ); 69 | if Hook in ChainedHooks then 70 | Doom.Level.CallHook( Hook, ConcatConstArray( [ Self ], Params ) ); 71 | end; 72 | 73 | function TThing.CallHookCheck ( Hook : Byte; const Params : array of const ) : Boolean; 74 | begin 75 | if Hook in ChainedHooks then if not Doom.Level.CallHookCheck( Hook, ConcatConstArray( [ Self ], Params ) ) then Exit( False ); 76 | if Hook in FHooks then if not LuaSystem.ProtectedRunHook(Self, HookNames[Hook], Params ) then Exit( False ); 77 | Exit( True ); 78 | end; 79 | 80 | function TThing.GetSprite: TSprite; 81 | begin 82 | Exit(FSprite); 83 | end; 84 | 85 | procedure TThing.WriteToStream( Stream: TStream ); 86 | begin 87 | inherited WriteToStream( Stream ); 88 | Stream.Write( FSprite, SizeOf( FSprite ) ); 89 | end; 90 | 91 | constructor TThing.CreateFromStream( Stream: TStream ); 92 | begin 93 | inherited CreateFromStream( Stream ); 94 | Stream.Read( FSprite, SizeOf( FSprite ) ); 95 | end; 96 | 97 | end. 98 | -------------------------------------------------------------------------------- /src/doomassemblyview.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomassemblyview; 3 | interface 4 | uses vutil, doomio, dfdata; 5 | 6 | type TAssemblyView = class( TInterfaceLayer ) 7 | constructor Create; 8 | procedure Update( aDTime : Integer ); override; 9 | function IsFinished : Boolean; override; 10 | function IsModal : Boolean; override; 11 | destructor Destroy; override; 12 | protected 13 | procedure ReadAssemblies; 14 | protected 15 | FFinished : Boolean; 16 | FSize : TPoint; 17 | FContent : TStringGArray; 18 | end; 19 | 20 | implementation 21 | 22 | uses sysutils, vluasystem, vtig, dfhof; 23 | 24 | constructor TAssemblyView.Create; 25 | begin 26 | VTIG_EventClear; 27 | FSize := Point( 80, 25 ); 28 | end; 29 | 30 | procedure TAssemblyView.Update( aDTime : Integer ); 31 | var iString : Ansistring; 32 | begin 33 | if FContent = nil then ReadAssemblies; 34 | VTIG_BeginWindow('Known assemblies', 'assembly_view', FSize ); 35 | for iString in FContent do 36 | VTIG_Text( iString ); 37 | VTIG_Scrollbar; 38 | VTIG_End('{l<{!Up},{!Down}> scroll, <{!Enter},{!Escape}> return}'); 39 | if VTIG_EventCancel or VTIG_EventConfirm then 40 | FFinished := True; 41 | IO.RenderUIBackground( PointZero, FSize ); 42 | end; 43 | 44 | 45 | function TAssemblyView.IsFinished : Boolean; 46 | begin 47 | Exit( FFinished ); 48 | end; 49 | 50 | function TAssemblyView.IsModal : Boolean; 51 | begin 52 | Exit( True ); 53 | end; 54 | 55 | destructor TAssemblyView.Destroy; 56 | begin 57 | FreeAndNil( FContent ); 58 | inherited Destroy; 59 | end; 60 | 61 | procedure TAssemblyView.ReadAssemblies; 62 | var iType, iFound, i : DWord; 63 | iString, iID : AnsiString; 64 | const TypeName : array[0..2] of string = ('Basic','Advanced','Master'); 65 | begin 66 | if FContent = nil then FContent := TStringGArray.Create; 67 | FContent.Clear; 68 | for iType := 0 to 2 do 69 | begin 70 | FContent.Push('{y'+TypeName[iType]+' assemblies}'); 71 | FContent.Push(''); 72 | for i := 1 to LuaSystem.Get(['mod_arrays','__counter']) do 73 | if LuaSystem.Get(['mod_arrays',i,'level']) = iType then 74 | begin 75 | iID := LuaSystem.Get(['mod_arrays',i,'id']); 76 | iFound := HOF.GetCounted( 'assemblies','assembly', iID ); 77 | if LuaSystem.Get( [ 'player','__props', 'assemblies', iID ], 0 ) > 0 then Inc( iFound ); 78 | if iFound = 0 79 | then if iType = 0 80 | then iString := ' {d'+LuaSystem.Get(['mod_arrays',i,'name'])+' ({L-})}' 81 | else iString := ' {d -- ? -- ({L-})}' 82 | else iString := ' {y'+Padded(LuaSystem.Get(['mod_arrays',i,'name'])+' ({L'+IntToStr(iFound)+'})}',36) 83 | + '{l' + LuaSystem.Get(['mod_arrays',i,'desc'])+'}'; 84 | FContent.Push( iString ); 85 | end; 86 | if iType <> 2 then FContent.Push(''); 87 | end; 88 | end; 89 | 90 | 91 | end. 92 | 93 | -------------------------------------------------------------------------------- /src/doomcommand.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomcommand; 3 | interface 4 | uses vrltools, dfitem, dfdata; 5 | 6 | type TCommand = object 7 | Command : Byte; 8 | Target : TCoord2D; 9 | Item : TItem; 10 | Slot : TEqSlot; 11 | ID : AnsiString; 12 | 13 | class function Create( aCommand : Byte ) : TCommand; static; 14 | class function Create( aCommand : Byte; aTarget : TCoord2D ) : TCommand; static; 15 | class function Create( aCommand : Byte; aID : AnsiString ) : TCommand; static; 16 | class function Create( aCommand : Byte; aItem : TItem ) : TCommand; static; 17 | class function Create( aCommand : Byte; aItem : TItem; aSlot : TEqSlot ) : TCommand; static; 18 | class function Create( aCommand : Byte; aItem : TItem; aID : AnsiString ) : TCommand; static; 19 | class function Create( aCommand : Byte; aTarget : TCoord2D; aItem : TItem ) : TCommand; static; 20 | end; 21 | 22 | implementation 23 | 24 | class function TCommand.Create( aCommand : Byte ) : TCommand; 25 | begin 26 | Result.Command := aCommand; 27 | Result.Target := NewCoord2D(0,0); 28 | end; 29 | 30 | class function TCommand.Create( aCommand : Byte; aTarget : TCoord2D ) : TCommand; 31 | begin 32 | Result.Command := aCommand; 33 | Result.Target := aTarget; 34 | end; 35 | 36 | class function TCommand.Create( aCommand : Byte; aID : AnsiString ) : TCommand; 37 | begin 38 | Result.Command := aCommand; 39 | Result.Item := nil; 40 | Result.ID := aID; 41 | end; 42 | 43 | class function TCommand.Create( aCommand : Byte; aItem : TItem ) : TCommand; 44 | begin 45 | Result.Command := aCommand; 46 | Result.Item := aItem; 47 | Result.ID := ''; 48 | end; 49 | 50 | class function TCommand.Create( aCommand : Byte; aItem : TItem; aSlot : TEqSlot ) : TCommand; 51 | begin 52 | Result.Command := aCommand; 53 | Result.Item := aItem; 54 | Result.Slot := aSlot; 55 | Result.ID := ''; 56 | end; 57 | 58 | class function TCommand.Create( aCommand : Byte; aItem : TItem; aID : AnsiString ) : TCommand; 59 | begin 60 | Result.Command := aCommand; 61 | Result.Item := aItem; 62 | Result.Id := aID; 63 | end; 64 | 65 | class function TCommand.Create( aCommand : Byte; aTarget : TCoord2D; aItem : TItem ) : TCommand; static; 66 | begin 67 | Result.Command := aCommand; 68 | Result.Target := aTarget; 69 | Result.Item := aItem; 70 | Result.Id := ''; 71 | end; 72 | 73 | end. 74 | -------------------------------------------------------------------------------- /src/doomconfig.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomconfig; 3 | interface 4 | 5 | uses Classes, SysUtils, vluaconfig; 6 | 7 | type 8 | 9 | { TDoomConfig } 10 | 11 | TDoomConfig = class(TLuaConfig) 12 | constructor Create( const FileName : Ansistring; Reload : Boolean ); 13 | end; 14 | 15 | 16 | implementation 17 | 18 | uses vsystems, dfdata, vluastate, vlualibrary, doomlua, doomhelp, dfitem, doomio, doomviews; 19 | 20 | 21 | { TDoomConfig } 22 | 23 | constructor TDoomConfig.Create( const FileName : Ansistring; Reload : Boolean ); 24 | begin 25 | inherited Create; 26 | 27 | SetConstant('VERSION_STRING', VERSION_STRING); 28 | SetConstant('VERSION_BETA', VERSION_BETA); 29 | 30 | LoadMain( FileName ); 31 | 32 | Option_Graphics := Configure('Graphics',Option_Graphics); 33 | Option_Blending := Configure('Blending',Option_Blending); 34 | Option_SaveOnCrash := Configure('SaveOnCrash',Option_SaveOnCrash); 35 | Option_SoundEngine := Configure('SoundEngine',Option_SoundEngine); 36 | 37 | Option_HighASCII := Configure('AllowHighAscii',Option_HighASCII); 38 | Option_AlwaysName := Configure('AlwaysName',Option_AlwaysName); 39 | Option_Music := Configure('GameMusic',Option_Music); 40 | Option_Sound := Configure('GameSound',Option_Sound); 41 | Option_BlindMode := Configure('BlindMode',Option_BlindMode); 42 | Option_ClearMessages := Configure('ClearMessages',Option_ClearMessages);// TODO : Reimplement 43 | Option_MorePrompt := Configure('MorePrompt',Option_MorePrompt); 44 | Option_MessageColoring := Configure('MessageColoring',Option_MessageColoring); 45 | Option_InvFullDrop := Configure('InvFullDrop',Option_InvFullDrop); 46 | Option_MortemArchive := Configure('MortemArchive',Option_MortemArchive); 47 | Option_MenuReturn := Configure('MenuReturn',Option_MenuReturn); 48 | Option_SoundEquipPickup := Configure('SoundEquipPickup',Option_SoundEquipPickup); 49 | Option_ColoredInventory := Configure('ColoredInventory',Option_ColoredInventory); 50 | Option_LockBreak := Configure('LockBreak',Option_LockBreak); 51 | Option_LockClose := Configure('LockClose',Option_LockClose); 52 | Option_TimeStamp := Configure('TimeStamp',Option_TimeStamp); 53 | 54 | Option_PlayerBackups := Configure('PlayerBackups',Option_PlayerBackups); 55 | Option_ScoreBackups := Configure('ScoreBackups',Option_ScoreBackups); 56 | 57 | Option_RunDelay := Configure('RunDelay',Option_RunDelay); 58 | Option_MessageBuffer := Configure('MessageBuffer',Option_MessageBuffer); 59 | 60 | Option_IntuitionColor := Configure('IntuitionColor',Option_IntuitionColor); 61 | Option_IntuitionChar := AnsiString(Configure('IntuitionChar',Option_IntuitionChar))[1]; 62 | 63 | Option_MaxRun := Configure('MaxRun',Option_MaxRun); 64 | Option_MaxWait := Configure('MaxWait',Option_MaxWait); 65 | 66 | if ForceNoAudio then 67 | begin 68 | Option_Sound := False; 69 | Option_Music := False; 70 | Option_SoundEngine := 'NONE'; 71 | end; 72 | 73 | if (not Option_Music) and (not Option_Sound) then Option_SoundEngine := 'NONE'; 74 | if Option_SoundEngine = 'DEFAULT' then 75 | Option_SoundEngine := {$IFDEF WINDOWS}'FMOD'{$ELSE}'SDL'{$ENDIF}; 76 | if (Option_SoundEngine <> 'FMOD') and (Option_SoundEngine <> 'SDL') then 77 | Option_SoundEngine := 'NONE'; 78 | if Option_SoundEngine = 'NONE' then 79 | begin 80 | Option_Music := False; 81 | Option_Sound := False; 82 | SoundVersion := False; 83 | end 84 | else 85 | SoundVersion := True; 86 | 87 | // synchro 88 | if ForceConsole or ForceGraphics then 89 | begin 90 | if ForceConsole 91 | then Option_Graphics := 'CONSOLE' 92 | else Option_Graphics := 'TILES'; 93 | GraphicsVersion := not ForceConsole; 94 | end 95 | else 96 | begin 97 | if (Option_Graphics <> 'TILES') and (Option_Graphics <> 'CONSOLE') then 98 | Option_Graphics := 'TILES'; 99 | if Option_Graphics = 'TILES' 100 | then GraphicsVersion := True 101 | else GraphicsVersion := False; 102 | end; 103 | 104 | TDoomIO.RegisterLuaAPI( State ); 105 | end; 106 | 107 | end. 108 | 109 | -------------------------------------------------------------------------------- /src/doomconfiguration.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomconfiguration; 3 | interface 4 | uses vconfiguration; 5 | 6 | type TDoomConfiguration = class( TConfigurationManager ) 7 | constructor Create; 8 | end; 9 | 10 | var Configuration : TDoomConfiguration; 11 | 12 | implementation 13 | 14 | uses vioevent, doomkeybindings; 15 | 16 | constructor TDoomConfiguration.Create; 17 | var iGroup : TConfigurationGroup; 18 | iInput : TInputKey; 19 | iID : Ansistring; 20 | const CInputGroups : array[1..5] of Ansistring = ( 21 | 'keybindings_movement', 22 | 'keybindings_actions', 23 | 'keybindings_ui', 24 | 'keybindings_helper', 25 | 'keybindings_legacy' 26 | ); 27 | begin 28 | inherited Create; 29 | 30 | iGroup := AddGroup( 'meta' ); 31 | iGroup.AddInteger( 'config_version', 0 ); 32 | 33 | iGroup := AddGroup( 'general' ); 34 | iGroup.AddToggle( 'first_run', True ); 35 | iGroup.AddToggle( 'always_random_name', False ) 36 | .SetName('Always random name') 37 | .SetDescription( 'Setting to {!Enabled} will skip name entry and always supply a random name.') 38 | ; 39 | iGroup.AddToggle( 'skip_intro', False ) 40 | .SetName('Skip intro') 41 | .SetDescription('Setting to {!Enabled} will skip the plot intro text before playing.') 42 | ; 43 | iGroup.AddToggle( 'hide_hints', False ) 44 | .SetName('Hide hints') 45 | .SetDescription('Setting to {!Enabled} will hide the hints in the top right corner.') 46 | ; 47 | iGroup.AddToggle( 'no_flashing', False ) 48 | .SetName('Disable screen flashing') 49 | .SetDescription('Setting to {!Enabled} will disable screen flash FX.') 50 | ; 51 | iGroup.AddToggle( 'empty_confirm', False ) 52 | .SetName('Confirm firing empty weapon') 53 | .SetDescription('Setting to {!Enabled} will make the game wait for confirmation if trying to fire an empty weapon') 54 | ; 55 | iGroup.AddToggle( 'run_over_items', False ) 56 | .SetName('Run over items') 57 | .SetDescription('Setting to {!Enabled} will make the run command not stop on items.') 58 | ; 59 | iGroup.AddToggle( 'unlock_all', False ) 60 | .SetName('Unlock all unlocks') 61 | .SetDescription('For returning players so they don''t have to unlock everything again. Otherwise a cheat!') 62 | ; 63 | 64 | iGroup := AddGroup( 'display' ); 65 | iGroup.AddInteger( 'display_mode', 0 ); 66 | iGroup.AddInteger( 'screen_width', 0 ); 67 | iGroup.AddInteger( 'screen_height', 0 ); 68 | 69 | iGroup.AddToggle( 'fullscreen', True ) 70 | .SetName('Fullscreen') 71 | .SetDescription('Set to {!Disabled} to make the game launch in windowed mode.') 72 | ; 73 | 74 | iGroup.AddInteger( 'font_multiplier', 0 ) 75 | .SetRange(0,3) 76 | .SetName('Font size multiplier') 77 | .SetDescription('Control font size multiplier. Set to {!0} to pick one based on resolution.') 78 | ; 79 | 80 | iGroup.AddInteger( 'tile_multiplier', 0 ) 81 | .SetRange(0,3) 82 | .SetName('Tile size multiplier') 83 | .SetDescription('Control tile size multiplier. Set to {!0} to pick one based on resolution.') 84 | ; 85 | 86 | iGroup.AddInteger( 'minimap_multiplier', 0 ) 87 | .SetRange(0,9) 88 | .SetName('Minimap size multiplier') 89 | .SetDescription('Control minimap size multiplier. Set to {!0} to pick one based on resolution.') 90 | ; 91 | 92 | iGroup := AddGroup( 'audio' ); 93 | iGroup.AddInteger( 'sound_volume', 25 ) 94 | .SetRange(0,25) 95 | .SetName('Sound volume') 96 | .SetDescription('Control sound volume. Set to {!0} to turn off sounds.') 97 | ; 98 | iGroup.AddInteger( 'music_volume', 10 ) 99 | .SetRange(0,25) 100 | .SetName('Music volume') 101 | .SetDescription('Control music volume. Set to {!0} to turn off music.') 102 | ; 103 | iGroup.AddToggle( 'menu_sound', True ) 104 | .SetName('Menu sounds') 105 | .SetDescription('Set to {!Disabled} to disable the chunky menu sounds.') 106 | ; 107 | 108 | iGroup := AddGroup( 'keybindings_hidden' ); 109 | iGroup.AddInteger( 'input_escape', VKEY_ESCAPE ); 110 | iGroup.AddInteger( 'input_ok', VKEY_ENTER ); 111 | 112 | for iID in CInputGroups do 113 | begin 114 | iGroup := AddGroup( iID ); 115 | for iInput in TInputKey do 116 | if KeyInfo[ iInput ].Group = iID then 117 | iGroup.AddInteger( KeyInfo[ iInput ].ID, KeyInfo[ iInput ].Default ) 118 | .SetName(KeyInfo[ iInput ].Name) 119 | .SetDescription(KeyInfo[ iInput ].Description) 120 | ; 121 | end; 122 | end; 123 | 124 | end. 125 | 126 | -------------------------------------------------------------------------------- /src/doomconfirmview.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomconfirmview; 3 | interface 4 | uses vutil, doomio; 5 | 6 | type TOnConfirmObjectCallback = procedure of object; 7 | TOnConfirmRawCallback = procedure; 8 | 9 | type TConfirmView = class( TInterfaceLayer ) 10 | constructor Create; 11 | procedure Update( aDTime : Integer ); override; 12 | function IsFinished : Boolean; override; 13 | function IsModal : Boolean; override; 14 | protected 15 | procedure Initialize; virtual; 16 | procedure OnConfirm; virtual; 17 | procedure OnCancel; virtual; 18 | protected 19 | FSize : TPoint; 20 | FFinished : Boolean; 21 | 22 | FCancel : AnsiString; 23 | FConfirm : AnsiString; 24 | FMessage : AnsiString; 25 | 26 | FOnConfirmObject : TOnConfirmObjectCallback; 27 | FOnConfirmRaw : TOnConfirmRawCallback; 28 | end; 29 | 30 | implementation 31 | 32 | uses vtig, doombase; 33 | 34 | constructor TConfirmView.Create; 35 | begin 36 | Initialize; 37 | end; 38 | 39 | procedure TConfirmView.Initialize; 40 | begin 41 | VTIG_EventClear; 42 | VTIG_ResetSelect( 'confirm_menu' ); 43 | FOnConfirmObject := nil; 44 | FOnConfirmRaw := nil; 45 | FSize := Point( 50, -1 ); 46 | FFinished := False; 47 | FCancel := 'Cancel'; 48 | FConfirm := 'Confirm'; 49 | FMessage := ''; 50 | end; 51 | 52 | procedure TConfirmView.Update( aDTime : Integer ); 53 | var iRect : TRectangle; 54 | iResult : ( None, Cancel, Confirm ); 55 | begin 56 | if IsFinished then Exit; 57 | 58 | iResult := None; 59 | VTIG_Begin('confirm_menu', FSize ); 60 | VTIG_Text( FMessage ); 61 | VTIG_Text( '' ); 62 | iRect := VTIG_GetWindowRect; 63 | if VTIG_Selectable( FCancel ) then iResult := Cancel; 64 | if VTIG_Selectable( FConfirm ) then iResult := Confirm; 65 | VTIG_End; 66 | 67 | IO.RenderUIBackground( iRect.TopLeft, iRect.BottomRight - PointUnit ); 68 | 69 | if VTIG_EventCancel then iResult := Cancel; 70 | case iResult of 71 | Confirm : begin FFinished := True; OnConfirm; end; 72 | Cancel : begin FFinished := True; OnCancel; end; 73 | end; 74 | end; 75 | 76 | function TConfirmView.IsFinished : Boolean; 77 | begin 78 | Exit( FFinished or ( Doom.State <> DSPlaying ) ); 79 | end; 80 | 81 | function TConfirmView.IsModal : Boolean; 82 | begin 83 | Exit( True ); 84 | end; 85 | 86 | procedure TConfirmView.OnConfirm; 87 | begin 88 | if Assigned( FOnConfirmObject ) then FOnConfirmObject; 89 | if Assigned( FOnConfirmRaw ) then FOnConfirmRaw; 90 | end; 91 | 92 | procedure TConfirmView.OnCancel; 93 | begin 94 | end; 95 | 96 | end. 97 | -------------------------------------------------------------------------------- /src/doomhelp.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomhelp; 3 | interface 4 | uses classes, vnode, dfdata, vuitypes; 5 | 6 | const MaxHelpFiles = 20; 7 | const HLetters : string[23] = 'abcdefghijklmnopqrstuvw'; 8 | 9 | type 10 | THelpRecord = record 11 | Text : TUIStringArray; 12 | Desc : string[60]; 13 | end; 14 | PHelpRecord = ^THelpRecord; 15 | 16 | type THelp = class(TVObject) 17 | RegHelps : array[1..MaxHelpFiles] of THelpRecord; 18 | HNum : byte; 19 | constructor Create; 20 | procedure StreamLoader(Stream : TStream; Name : Ansistring; Size : DWord); 21 | destructor Destroy; override; 22 | end; 23 | 24 | var Help : THelp; 25 | 26 | 27 | implementation 28 | 29 | uses SysUtils, vutil, 30 | doomio, doomviews; 31 | 32 | function StripTags( const aInput: AnsiString ): AnsiString; 33 | var i, iLen : Integer; 34 | begin 35 | Result := ''; 36 | i := 1; 37 | iLen := Length(aInput); 38 | while i <= iLen do 39 | begin 40 | if aInput[i] = '{' then 41 | begin 42 | if (i < iLen) then 43 | begin 44 | Inc(i, 2); 45 | Continue; 46 | end; 47 | end 48 | else if aInput[i] = '}' then 49 | begin 50 | Inc(i); 51 | Continue; 52 | end; 53 | Result += aInput[i]; 54 | Inc(i); 55 | end; 56 | end; 57 | 58 | constructor THelp.Create; 59 | var c : byte; 60 | begin 61 | for c := 1 to MaxHelpFiles do RegHelps[c].Text := nil; 62 | HNum := 0; 63 | end; 64 | 65 | {$HINTS OFF} 66 | procedure THelp.StreamLoader(Stream : TStream; Name : Ansistring; Size : DWord); 67 | var Count : DWord; 68 | Amount : DWord; 69 | begin 70 | Log('Registering help file '+Name+'...'); 71 | Inc(HNum); 72 | RegHelps[HNum].text := TUIStringArray.Create; 73 | 74 | Amount := Stream.ReadDWord; 75 | for Count := 1 to Amount do 76 | RegHelps[HNum].Text.Push( Stream.ReadAnsiString ); 77 | 78 | RegHelps[HNum].desc := StripTags( RegHelps[HNum].Text[0] ); 79 | end; 80 | {$HINTS ON} 81 | 82 | destructor THelp.Destroy; 83 | var c : byte; 84 | begin 85 | for c := 1 to MaxHelpFiles do 86 | FreeAndNil(RegHelps[c].Text); 87 | end; 88 | 89 | end. 90 | -------------------------------------------------------------------------------- /src/doomhelpview.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomhelpview; 3 | interface 4 | uses vutil, doomio, 5 | vuielement // deleteme 6 | ; 7 | 8 | type THelpView = class( TInterfaceLayer ) 9 | constructor Create( aDeleteMe : TUINotifyEvent = nil ); 10 | procedure Update( aDTime : Integer ); override; 11 | function IsFinished : Boolean; override; 12 | function IsModal : Boolean; override; 13 | destructor Destroy; override; 14 | protected 15 | procedure UpdateRead; 16 | procedure UpdateMenu; 17 | protected 18 | FMode : ( HELPVIEW_MENU, HELPVIEW_READ, HELPVIEW_DONE ); 19 | FCurrent : Byte; 20 | FSize : TPoint; 21 | 22 | FDeleteMe : TUINotifyEvent; 23 | end; 24 | 25 | implementation 26 | 27 | uses vtig, doomhelp; 28 | 29 | // deleteme 30 | destructor THelpView.Destroy; 31 | begin 32 | inherited Destroy; 33 | if Assigned( FDeleteMe ) then FDeleteMe( nil ); 34 | end; 35 | 36 | constructor THelpView.Create( aDeleteMe : TUINotifyEvent = nil ); 37 | begin 38 | FDeleteMe := aDeleteMe; 39 | 40 | VTIG_EventClear; 41 | VTIG_ResetSelect( 'help_view' ); 42 | 43 | FSize := Point( 80, 25 ); 44 | FMode := HELPVIEW_MENU; 45 | FCurrent := 0; 46 | end; 47 | 48 | procedure THelpView.Update( aDTime : Integer ); 49 | begin 50 | if FMode = HELPVIEW_MENU then UpdateMenu 51 | else if FMode = HELPVIEW_READ then UpdateRead; 52 | IO.RenderUIBackground( PointZero, FSize ); 53 | end; 54 | 55 | function THelpView.IsFinished : Boolean; 56 | begin 57 | Exit( FMode = HELPVIEW_DONE ); 58 | end; 59 | 60 | function THelpView.IsModal : Boolean; 61 | begin 62 | Exit( True ); 63 | end; 64 | 65 | procedure THelpView.UpdateRead; 66 | var iText : Ansistring; 67 | begin 68 | VTIG_BeginWindow( Help.RegHelps[FCurrent].Desc, 'help_view_read', FSize ); 69 | for iText in Help.RegHelps[FCurrent].Text do 70 | VTIG_Text( iText ); 71 | VTIG_Scrollbar; 72 | VTIG_End('{l<{!Up},{!Down}> scroll, <{!Enter},{!Escape}> return}'); 73 | if VTIG_EventCancel or VTIG_EventConfirm then 74 | FMode := HELPVIEW_MENU; 75 | end; 76 | 77 | procedure THelpView.UpdateMenu; 78 | var i,iSelect : Integer; 79 | 80 | begin 81 | VTIG_BeginWindow( 'Help topics', 'help_view', FSize ); 82 | iSelect := 0; 83 | for i := 1 to Help.HNum do 84 | if VTIG_Selectable( ' '+Help.RegHelps[i].Desc ) then 85 | iSelect := i; 86 | if VTIG_Selectable( ' '+'Quit help' ) then 87 | FMode := HELPVIEW_DONE; 88 | 89 | VTIG_Ruler; 90 | 91 | VTIG_Text('Select help topic above. Quick (default) kebindings primer:'); 92 | VTIG_Text(''); 93 | VTIG_Text(' {!Escape} - game menu (Save, Quit, Settings, Help, etc)'); 94 | VTIG_Text(' {!Arrows} - movement (Home,End,PgUp,PgDown - diagonals)'); 95 | VTIG_Text(' {!.}(period) - wait (pass turn)'); 96 | VTIG_Text(' {!SPACE} - action (open,close,press button,descend stairs)'); 97 | VTIG_Text(' {!I},{!E},{!P},{!T} - inventory, equipment etc (left/right to switch while open)'); 98 | VTIG_Text(' {!F} - fire weapon (SHIFT for alternative mode)'); 99 | VTIG_Text(' {!R} - reload weapon (SHIFT for alternative mode)'); 100 | VTIG_Text(' {!G} - get item (pickup) from floor (SHIFT to use)'); 101 | VTIG_Text(' ... see "Controls" entry for the rest'); 102 | 103 | 104 | 105 | 106 | VTIG_End('{l<{!Up},{!Down}> select, <{!Enter}> open, <{!Escape}> exit}'); 107 | if iSelect > 0 then 108 | begin 109 | VTIG_ResetScroll( 'help_view_read' ); 110 | FMode := HELPVIEW_READ; 111 | FCurrent := iSelect; 112 | end; 113 | 114 | if VTIG_EventCancel then 115 | FMode := HELPVIEW_DONE; 116 | end; 117 | 118 | end. 119 | 120 | -------------------------------------------------------------------------------- /src/doomingamemenuview.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomingamemenuview; 3 | interface 4 | uses doomio, doomconfirmview; 5 | 6 | type TInGameMenuView = class( TInterfaceLayer ) 7 | constructor Create; 8 | procedure Update( aDTime : Integer ); override; 9 | function IsFinished : Boolean; override; 10 | function IsModal : Boolean; override; 11 | protected 12 | FFinished : Boolean; 13 | end; 14 | 15 | type TAbandonView = class( TConfirmView ) 16 | constructor Create; 17 | protected 18 | procedure OnConfirm; override; 19 | procedure OnCancel; override; 20 | end; 21 | 22 | implementation 23 | 24 | uses vtig, vutil, vluasystem, dfplayer, doombase, doomhelpview, doomsettingsview; 25 | 26 | constructor TInGameMenuView.Create; 27 | begin 28 | VTIG_EventClear; 29 | VTIG_ResetSelect( 'ingame_menu_abandon' ); 30 | //VTIG_ResetSelect( 'ingame_menu' ); 31 | FFinished := False; 32 | end; 33 | 34 | procedure TInGameMenuView.Update( aDTime : Integer ); 35 | var iRect : TRectangle; 36 | begin 37 | if IsFinished or (Doom.State <> DSPlaying) then Exit; 38 | 39 | VTIG_Begin('ingame_menu', Point( 30, 9 ) ); 40 | iRect := VTIG_GetWindowRect; 41 | if VTIG_Selectable( 'Continue' ) then 42 | begin 43 | FFinished := True; 44 | end; 45 | if VTIG_Selectable( 'Help' ) then 46 | begin 47 | IO.PushLayer( THelpView.Create ); 48 | FFinished := True; 49 | end; 50 | if VTIG_Selectable( 'Settings' ) then 51 | begin 52 | IO.PushLayer( TSettingsView.Create ); 53 | FFinished := True; 54 | end; 55 | if VTIG_Selectable( 'Abandon Run' ) then 56 | begin 57 | FFinished := True; 58 | IO.PushLayer( TAbandonView.Create ); 59 | end; 60 | if VTIG_Selectable( 'Save & Quit' ) then 61 | begin 62 | FFinished := True; 63 | Player.doSave; 64 | end; 65 | VTIG_End; 66 | 67 | IO.RenderUIBackground( iRect.TopLeft, iRect.BottomRight - PointUnit ); 68 | 69 | if VTIG_EventCancel then FFinished := True; 70 | end; 71 | 72 | function TInGameMenuView.IsFinished : Boolean; 73 | begin 74 | Exit( FFinished or ( Doom.State <> DSPlaying ) ); 75 | end; 76 | 77 | function TInGameMenuView.IsModal : Boolean; 78 | begin 79 | Exit( True ); 80 | end; 81 | 82 | constructor TAbandonView.Create; 83 | begin 84 | inherited Create; 85 | FCancel := 'Continue run'; 86 | FConfirm := 'Abandon run'; 87 | FMessage := LuaSystem.ProtectedCall(['DoomRL','quit_message'],[]) + #10 + 88 | '{yAre you sure you want to abandon this run?}'; 89 | FSize := Point( 50, 10 ); 90 | end; 91 | 92 | procedure TAbandonView.OnConfirm; 93 | begin 94 | Player.doQuit( True ); 95 | end; 96 | 97 | procedure TAbandonView.OnCancel; 98 | begin 99 | IO.Msg('Ok, then. Stay and take what''s coming to ya...'); 100 | end; 101 | 102 | end. 103 | 104 | -------------------------------------------------------------------------------- /src/doommoreview.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doommoreview; 3 | interface 4 | uses vutil, doomio, dfdata; 5 | 6 | type TMoreView = class( TInterfaceLayer ) 7 | constructor Create( aSid : Ansistring ); 8 | procedure Update( aDTime : Integer ); override; 9 | function IsFinished : Boolean; override; 10 | function IsModal : Boolean; override; 11 | protected 12 | FFinished : Boolean; 13 | FSize : TPoint; 14 | FSID : Ansistring; 15 | FName : Ansistring; 16 | FDesc : Ansistring; 17 | FASCII : Ansistring; 18 | end; 19 | 20 | implementation 21 | 22 | uses vluasystem, vtig, dfplayer, doombase; 23 | 24 | constructor TMoreView.Create( aSid : Ansistring ); 25 | begin 26 | VTIG_EventClear; 27 | FFinished := False; 28 | FSID := aSid; 29 | FName := Capitalized(LuaSystem.Get(['beings',FSID,'name'])); 30 | FDesc := LuaSystem.Get(['beings',FSID,'desc']); 31 | if FSID = 'soldier' 32 | then FASCII := Player.ASCIIMoreCode 33 | else FASCII := FSID; 34 | FSize := Point( 80, 25 ); 35 | end; 36 | 37 | procedure TMoreView.Update( aDTime : Integer ); 38 | var iString : Ansistring; 39 | iCount : Integer; 40 | begin 41 | VTIG_ClipHack := True; 42 | VTIG_BeginWindow(FName, 'more_view', FSize ); 43 | VTIG_ClipHack := False; 44 | iCount := 0; 45 | if IO.NewAscii.Exists(FASCII) then 46 | for iString in IO.NewAscii[FASCII] do 47 | begin 48 | VTIG_FreeLabel( iString, Point( 2, iCount ) ); 49 | Inc( iCount ); 50 | end 51 | else 52 | VTIG_FreeLabel( 'Picture'#10'N/A', Point( 10, 10 ), LightRed ); 53 | 54 | VTIG_BeginWindow(FName, Point( 38, -1 ), Point( 40,11 ) ); 55 | VTIG_Text( FDesc ); 56 | VTIG_End; 57 | 58 | VTIG_End('{l<{!Escape},{!Enter}> exit}'); 59 | if VTIG_EventCancel or VTIG_EventConfirm then 60 | FFinished := True; 61 | IO.RenderUIBackground( PointZero, FSize ); 62 | end; 63 | 64 | 65 | function TMoreView.IsFinished : Boolean; 66 | begin 67 | Exit( FFinished or ( Doom.State <> DSPlaying ) ); 68 | end; 69 | 70 | function TMoreView.IsModal : Boolean; 71 | begin 72 | Exit( True ); 73 | end; 74 | 75 | end. 76 | 77 | -------------------------------------------------------------------------------- /src/doomrl.inc: -------------------------------------------------------------------------------- 1 | {$MODE OBJFPC} 2 | {$INTERFACES CORBA} 3 | {$COPERATORS ON} 4 | {$INLINE ON} 5 | 6 | {$IFNDEF WINDOWS} 7 | {$OPTIMIZATION OFF} 8 | {.$OPTIMIZATION REGVAR} 9 | {$OPTIMIZATION STACKFRAME} 10 | {$OPTIMIZATION PEEPHOLE} 11 | {$OPTIMIZATION LOOPUNROLL} 12 | {$OPTIMIZATION CSE} 13 | {.$OPTIMIZATION DFA} 14 | {$ELSE} 15 | {$OPTIMIZATION ON} 16 | {$ENDIF} 17 | 18 | {$IFNDEF WINDOWS} 19 | {$LINKLIB m} 20 | {$ENDIF} 21 | 22 | {.$DEFINE MODSERVER} 23 | {.$DEFINE HEAPTRACE} 24 | {.$DEFINE CORNERMAP} 25 | 26 | -------------------------------------------------------------------------------- /src/doomrl.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/src/doomrl.res -------------------------------------------------------------------------------- /src/doomtextures.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomtextures; 3 | interface 4 | uses SysUtils, Classes, vtextures, vimage; 5 | 6 | type TTextureID = vtextures.TTextureID; 7 | 8 | type TDoomTextures = class( TTextureManager ) 9 | constructor Create; 10 | // procedure LoadFont( aFont : TStream; aSize : DWord; aMetrics : TStream ); 11 | procedure PrepareTextures; 12 | private 13 | function GenerateGlow( Shadow : TImage ) : TImage; 14 | end; 15 | 16 | var Textures : TDoomTextures = nil; 17 | 18 | implementation 19 | 20 | uses vmath, vcolor, dfdata; 21 | 22 | { TDoomTextures } 23 | 24 | constructor TDoomTextures.Create; 25 | begin 26 | inherited Create( Option_Blending ); 27 | end; 28 | 29 | { 30 | procedure TDoomTextures.LoadFont ( aFont : TStream; aSize : DWord; aMetrics : TStream ) ; 31 | begin 32 | // GLFonts[1] := TGLBitmapFont.Create( Font, Size, Metrics ); 33 | end; 34 | } 35 | 36 | procedure TDoomTextures.PrepareTextures; 37 | begin 38 | Textures[ 'logo' ].Blend := True; 39 | Textures[ 'background' ].Blend := True; 40 | Textures[ 'lut_clear' ].Blend := True; 41 | Textures[ 'lut_iddqd' ].Blend := True; 42 | Textures[ 'lut_enviro' ].Blend := True; 43 | Textures[ 'lut_berserk' ].Blend := True; 44 | Textures[ 'lut_clear' ].Is3D := True; 45 | Textures[ 'lut_iddqd' ].Is3D := True; 46 | Textures[ 'lut_enviro' ].Is3D := True; 47 | Textures[ 'lut_berserk' ].Is3D := True; 48 | AddImage( 'doomguy_glow', GenerateGlow( Textures['doomguy_shadow'].Image ), Option_Blending ); 49 | AddImage( 'enemies_glow', GenerateGlow( Textures['enemies_shadow'].Image ), Option_Blending ); 50 | AddImage( 'enemies_big_glow', GenerateGlow( Textures['enemies_big_shadow'].Image ), Option_Blending ); 51 | AddImage( 'guns_and_pickups_glow', GenerateGlow( Textures['guns_and_pickups_shadow'].Image ), Option_Blending ); 52 | AddImage( 'doors_and_decorations_glow',GenerateGlow( Textures['doors_and_decorations_shadow'].Image ), Option_Blending ); 53 | 54 | Upload; 55 | end; 56 | 57 | function TDoomTextures.GenerateGlow ( Shadow : TImage ) : TImage; 58 | const GaussSize = 1; 59 | var Glow : TImage; 60 | X,Y,P,XX,YY : Integer; 61 | RX,RY : Integer; 62 | Value : Integer; 63 | begin 64 | Glow := TImage.Create( Shadow.SizeX, Shadow.SizeY ); 65 | Glow.Fill( ColorZero ); 66 | XX := 1 * 4; 67 | YY := Glow.SizeX * 4; 68 | for X := 1 to Glow.SizeX - 2 do 69 | for Y := 1 to Glow.SizeY - 2 do 70 | begin 71 | P := (Integer(Glow.SizeX)*Y + X) * 4; 72 | RX := ( Shadow.Data[ P-YY ] - Shadow.Data[ P+YY ] ); 73 | RY := ( Shadow.Data[ P+XX ] - Shadow.Data[ P-XX ] ); 74 | Value := Clamp( Round( 0.1 * Sqrt( RX * RX + RY * RY ) ), 0, 255 ); 75 | Glow.Data[ P ] := Value; 76 | Glow.Data[ P+1 ] := Value; 77 | Glow.Data[ P+2 ] := Value; 78 | Glow.Data[ P+3 ] := Value; 79 | end; 80 | GenerateGlow := Glow.Clone; 81 | for X := GaussSize to Glow.SizeX - 1 - GaussSize do 82 | for Y := GaussSize to Glow.SizeY - 1 - GaussSize do 83 | begin 84 | Value := 0; 85 | for RX := -GaussSize to GaussSize do 86 | for RY := -GaussSize to GaussSize do 87 | Value += Glow.Data[ (Integer(Glow.SizeX)*(Y+RY) + (X+RX)) * 4 ]; 88 | Value := Clamp( Value div ( GaussSize * GaussSize ), 0, 255 ); 89 | P := (Integer(Glow.SizeX)*Y + X) * 4; 90 | GenerateGlow.Data[ P ] := Value; 91 | GenerateGlow.Data[ P+1 ] := Value; 92 | GenerateGlow.Data[ P+2 ] := Value; 93 | GenerateGlow.Data[ P+3 ] := Value; 94 | end; 95 | FreeAndNil( Glow ); 96 | end; 97 | 98 | end. 99 | 100 | -------------------------------------------------------------------------------- /src/doomtrait.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | unit doomtrait;interface 3 | uses Classes, SysUtils, dfdata; 4 | 5 | const MAXTRAITS = 50; 6 | MAXKLASS = 10; 7 | 8 | type 9 | 10 | { TTraits } 11 | 12 | TTraits = object 13 | Values : array[1..MAXTRAITS] of Byte; 14 | Blocked : array[1..MAXTRAITS] of Boolean; 15 | Order : array[1..MaxPlayerLevel] of Byte; 16 | Count : Byte; 17 | Klass : Byte; 18 | Mastered : Boolean; 19 | procedure Clear; 20 | function GetHistory : AnsiString; 21 | procedure Upgrade ( aTrait : Byte ) ; 22 | function CanPick( aTrait : Byte; aCharLevel : Byte ): Boolean; 23 | class function CanPickInitially( aTrait : Byte; aKlassID : Byte ) : Boolean; static; 24 | end; 25 | PTraits = ^TTraits; 26 | 27 | 28 | implementation 29 | 30 | uses vluasystem, vutil, dfplayer; 31 | 32 | function TTraits.CanPick( aTrait : Byte; aCharLevel : Byte ): Boolean; 33 | var iOther, iValue : DWord; 34 | iVariant : Variant; 35 | iTable : TLuaTable; 36 | begin 37 | if Blocked[ aTrait ] then Exit( False ); 38 | 39 | with LuaSystem.GetTable(['klasses',Klass,'trait',aTrait]) do 40 | try 41 | if (aCharLevel < 12) and (Self.Values[ aTrait ] >= getInteger( 'max', 1 )) then Exit( False ); 42 | if aCharLevel < getInteger( 'reqlevel', 0 ) then Exit( False ); 43 | 44 | if IsTable('blocks') then 45 | begin 46 | with GetTable('blocks') do 47 | try 48 | for iVariant in VariantValues do 49 | if Self.Values[ Word(iVariant) ] >= 1 then Exit( False ); 50 | finally 51 | Free; 52 | end; 53 | end; 54 | 55 | if IsTable('requires') then 56 | for iTable in ITables('requires') do 57 | begin 58 | iOther := iTable.GetValue( 1 ); 59 | iValue := iTable.GetValue( 2 ); 60 | if Self.Values[ iOther ] < iValue then Exit( False ); 61 | end; 62 | finally 63 | Free; 64 | end; 65 | Exit( True ); 66 | end; 67 | 68 | procedure TTraits.Upgrade ( aTrait : Byte ) ; 69 | var i : Byte; 70 | iMax, iMax12 : DWord; 71 | iMaster : Boolean; 72 | iVariant : Variant; 73 | begin 74 | Inc( Values[ aTrait ] ); 75 | Inc( Count ); 76 | 77 | with LuaSystem.GetTable(['klasses',Klass,'trait',aTrait]) do 78 | try 79 | iMax := getInteger( 'max', 1 ); 80 | iMax12 := getInteger( 'max_12', iMax ); 81 | iMaster := getBoolean( 'master', False ); 82 | finally 83 | Free; 84 | end; 85 | 86 | if Values[ aTrait ] >= iMax12 then 87 | Blocked[ aTrait ] := True; 88 | 89 | if iMaster then 90 | begin 91 | Mastered := True; 92 | for i := 1 to MAXTRAITS do 93 | if LuaSystem.Get(['klasses',Klass,'trait',i,'master'], False ) then 94 | Blocked[ i ] := True; 95 | end; 96 | 97 | LuaSystem.ProtectedCall( [ 'traits',aTrait,'OnPick' ], [ Player, Values[ aTrait ] ] ); 98 | 99 | if (Values[ aTrait ] = 1) and LuaSystem.Defined(['klasses',Klass,'trait',aTrait,'blocks']) then 100 | begin 101 | with LuaSystem.GetTable(['klasses',Klass,'trait',aTrait,'blocks']) do 102 | try 103 | for iVariant in VariantValues do 104 | Blocked[ Word(iVariant) ] := True; 105 | finally 106 | Free; 107 | end; 108 | end; 109 | 110 | Order[ Count ] := aTrait; 111 | end; 112 | 113 | class function TTraits.CanPickInitially(aTrait: Byte; aKlassID: Byte): Boolean; 114 | begin 115 | CanPickInitially := True; 116 | 117 | // #5 ReqLevel 118 | with LuaSystem.GetTable(['klasses',aKlassID,'trait',aTrait]) do 119 | try 120 | if IsTable('requires') or (GetInteger('reqlevel',0) > 1) then CanPickInitially := False; 121 | finally 122 | Free; 123 | end; 124 | end; 125 | 126 | procedure TTraits.Clear; 127 | var iCount : Byte; 128 | begin 129 | for iCount := 1 to High(Blocked) do Blocked[iCount] := False; 130 | for iCount := 1 to High(Values) do Values[iCount] := 0; 131 | for iCount := 1 to High(Order) do Order[iCount] := 0; 132 | Count := 0; 133 | Mastered := False; 134 | Klass := 1; 135 | end; 136 | 137 | function TTraits.GetHistory: AnsiString; 138 | var iCount : Byte; 139 | begin 140 | GetHistory := ''; 141 | for iCount := 1 to High(Order) do 142 | if (Order[iCount] > 0) and (Order[iCount] <= High(Values)) then 143 | GetHistory += LuaSystem.Get(['traits',Order[iCount],'abbr'], False )+'->'; 144 | end; 145 | 146 | end. 147 | 148 | -------------------------------------------------------------------------------- /src/drl.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/src/drl.ico -------------------------------------------------------------------------------- /src/drl.pas: -------------------------------------------------------------------------------- 1 | { 2 | ------------------------------------------------------- 3 | DRL.PAS -- Main Program 4 | Copyright (c) 2002-2006 by Kornel "Anubis" Kisielewicz 5 | ------------------------------------------------------- 6 | } 7 | { 8 | [todo] move default value functionality to prototype structures 9 | [todo] blueprints are only for type and range checking 10 | [todo] blueprints can (should?) be turned off if not loading module, or in godmode? 11 | [todo] however, we'd loose the option to run functions if not turned on? 12 | [todo] container structures have meta information __blueprint and __prototype for default 13 | [todo] the upper needs to be handled by core.unregister! 14 | [todo] warning-only mode? 15 | [todo] dryrun possibility of the wad file! for modders and stats generation 16 | 17 | [todo] Copy configs from DataPath to ConfigurationPath if not present 18 | [todo] Set proper paths on unix, create directories if needed 19 | } 20 | 21 | {$INCLUDE doomrl.inc} 22 | 23 | program drl; 24 | uses SysUtils, vsystems, 25 | {$IFDEF HEAPTRACE} heaptrc, {$ENDIF} 26 | {$IFDEF WINDOWS} windows, {$ENDIF} 27 | vdebug, doombase, vlog, vutil, vos, vparams, 28 | dfdata, doommodule, doomio, doomconfig, doomconfiguration; 29 | 30 | {$IFDEF WINDOWS} 31 | var Handle : HWND; 32 | Title : AnsiString; 33 | 34 | function ConsoleEventProc(CtrlType: DWORD): Bool; stdcall; 35 | begin 36 | Result := True; 37 | end; 38 | 39 | {$R *.res} 40 | 41 | {$ENDIF} 42 | 43 | var RootPath : AnsiString = ''; 44 | 45 | begin 46 | try 47 | try 48 | Modules := nil; 49 | Configuration := TDoomConfiguration.Create; 50 | 51 | 52 | {$IFDEF Darwin} 53 | {$IFDEF OSX_APP_BUNDLE} 54 | RootPath := GetResourcesPath(); 55 | DataPath := RootPath; 56 | ConfigurationPath := RootPath + 'config.lua'; 57 | SettingsPath := RootPath + 'settings.lua'; 58 | {$ENDIF} 59 | {$ELSE} 60 | {$IFDEF UNIX} 61 | {$ENDIF} 62 | {$ENDIF} 63 | 64 | {$IFDEF Windows} 65 | RootPath := ExtractFilePath( ParamStr(0) ); 66 | if not FileExists( RootPath + 'config.lua' ) then 67 | RootPath := ''; 68 | DataPath := RootPath; 69 | ConfigurationPath := RootPath + 'config.lua'; 70 | SettingsPath := RootPath + 'settings.lua'; 71 | {$ENDIF} 72 | 73 | {$IFDEF WINDOWS} 74 | Title := 'DRL - D**m, the Roguelike'; 75 | SetConsoleTitle(PChar(Title)); 76 | Sleep(40); 77 | {$ENDIF} 78 | ColorOverrides := nil; 79 | 80 | with TParams.Create do 81 | try 82 | if isSet('god') then 83 | begin 84 | GodMode := True; 85 | ConfigurationPath := RootPath + 'godmode.lua'; 86 | end; 87 | if isSet('config') then ConfigurationPath := get('config'); 88 | if isSet('nosound') then ForceNoAudio := True; 89 | if isSet('graphics') then 90 | begin 91 | GraphicsVersion := True; 92 | ForceGraphics := True; 93 | end; 94 | if isSet('console') then 95 | begin 96 | GraphicsVersion := False; 97 | ForceConsole := True; 98 | end; 99 | 100 | if FileExists( SettingsPath ) 101 | then Configuration.Read( SettingsPath ) 102 | else Configuration.Write( SettingsPath ); 103 | 104 | Config := TDoomConfig.Create( ConfigurationPath, False ); 105 | DataPath := Config.Configure( 'DataPath', DataPath ); 106 | WritePath := Config.Configure( 'WritePath', WritePath ); 107 | ScorePath := Config.Configure( 'ScorePath', ScorePath ); 108 | 109 | if isSet('datapath') then DataPath := get('datapath'); 110 | if isSet('writepath') then WritePath := get('writepath'); 111 | if isSet('scorepath') then ScorePath := get('scorepath'); 112 | if isSet('name') then Option_AlwaysName := get('name'); 113 | finally 114 | Free; 115 | end; 116 | 117 | 118 | {$IFDEF HEAPTRACE} 119 | SetHeapTraceOutput( WritePath + 'heap.txt'); 120 | {$ENDIF} 121 | 122 | Logger.AddSink( TTextFileLogSink.Create( LOGDEBUG, WritePath + 'log.txt', False ) ); 123 | LogSystemInfo(); 124 | Logger.Log( LOGINFO, 'Log path set to - ' + WritePath ); 125 | 126 | if ScorePath = '' then ScorePath := WritePath; 127 | ErrorLogFileName := WritePath + 'error.log'; 128 | 129 | Doom := Systems.Add(TDoom.Create) as TDoom; 130 | 131 | Modules := TDoomModules.Create; 132 | 133 | Randomize; 134 | Doom.CreateIO; 135 | {$IFDEF WINDOWS} 136 | if not GraphicsVersion then 137 | begin 138 | if Option_LockBreak then 139 | begin 140 | SetConsoleCtrlHandler(nil, False); 141 | SetConsoleCtrlHandler(@ConsoleEventProc, True); 142 | end; 143 | if Option_LockClose then 144 | begin 145 | Handle := FindWindow(nil, PChar(Title)); 146 | RemoveMenu(GetSystemMenu( Handle, FALSE), SC_CLOSE , MF_GRAYED); 147 | DrawMenuBar(FindWindow(nil, PChar(Title))); 148 | end; 149 | end; 150 | {$ENDIF} 151 | Doom.Run; 152 | finally 153 | FreeAndNil( Configuration ); 154 | FreeAndNil( Modules ); 155 | FreeAndNil( Systems ); 156 | end; 157 | except on e : Exception do 158 | begin 159 | if not EXCEPTEMMITED then 160 | EmitCrashInfo( e.Message, False ); 161 | raise 162 | end; 163 | end; 164 | 165 | end. 166 | 167 | 168 | -------------------------------------------------------------------------------- /src/drlwad.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | </General> 17 | <BuildModes Count="1"> 18 | <Item1 Name="default" Default="True"/> 19 | </BuildModes> 20 | <PublishOptions> 21 | <Version Value="2"/> 22 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 23 | <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> 24 | </PublishOptions> 25 | <RunParams> 26 | <local> 27 | <FormatVersion Value="1"/> 28 | <LaunchingApplication Use="True" PathPlusParams="C:\Windows\system32\cmd.exe /C "${TargetCmdLine}""/> 29 | </local> 30 | </RunParams> 31 | <Units Count="2"> 32 | <Unit0> 33 | <Filename Value="drlwad.pas"/> 34 | <IsPartOfProject Value="True"/> 35 | <UnitName Value="drlwad"/> 36 | </Unit0> 37 | <Unit1> 38 | <Filename Value="..\bin\constants.inc"/> 39 | <IsPartOfProject Value="True"/> 40 | </Unit1> 41 | </Units> 42 | </ProjectOptions> 43 | <CompilerOptions> 44 | <Version Value="11"/> 45 | <PathDelim Value="\"/> 46 | <Target> 47 | <Filename Value="..\bin\drlwad"/> 48 | </Target> 49 | <SearchPaths> 50 | <OtherUnitFiles Value="..\..\fpcvalkyrie\src;..\..\fpcvalkyrie\lua"/> 51 | <UnitOutputDirectory Value="../tmp"/> 52 | </SearchPaths> 53 | <Parsing> 54 | <SyntaxOptions> 55 | <UseAnsiStrings Value="False"/> 56 | </SyntaxOptions> 57 | </Parsing> 58 | <Other> 59 | <CompilerMessages> 60 | <UseMsgFile Value="True"/> 61 | </CompilerMessages> 62 | <CompilerPath Value="$(CompPath)"/> 63 | </Other> 64 | </CompilerOptions> 65 | </CONFIG> 66 | -------------------------------------------------------------------------------- /src/drlwad.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | program drlwad; 3 | uses Classes, SysUtils, strutils, vpkg, vdf, vutil, dfdata, doommodule; 4 | 5 | var WAD : TVDataCreator; 6 | ModuleID : AnsiString; 7 | Path : AnsiString; 8 | ModuleFile : AnsiString; 9 | 10 | begin 11 | if ParamCount < 1 then 12 | begin 13 | Writeln( 'DRL WAD Creator, Copyright (c) ChaosForge.org' ); 14 | Writeln( 'Usage : drlwad [module_id]' ); 15 | Halt(0); 16 | end; 17 | 18 | ModuleID := ParamStr(1); 19 | Path := 'modules' + DirectorySeparator + ModuleID + '.module'; 20 | 21 | if not DirectoryExists( Path ) then 22 | begin 23 | Writeln( 'Bad module ID "'+ModuleID+'" - directory '+Path+' doesn''t exists!' ); 24 | Halt(1); 25 | end; 26 | Writeln( 'Compiling module "'+ModuleID+'"...' ); 27 | 28 | ModuleFile := 'modules' + DirectorySeparator + ModuleID + '.wad'; 29 | 30 | if FileExists( ModuleFile ) then DeleteFile( ModuleFile ); 31 | 32 | WADMAKE := True; 33 | WAD := TVDataCreator.Create(ModuleFile); 34 | 35 | WAD.Add(Path+'/*.lua',FILETYPE_LUA,[vdfCompressed], '' ); 36 | WAD.Add(Path+'/data/*.lua',FILETYPE_LUA,[vdfCompressed], 'data' ); 37 | WAD.Add(Path+'/ascii/*.asc',FILETYPE_ASCII,[vdfCompressed], 'ascii' ); 38 | WAD.Add(Path+'/music/*.mid',FILETYPE_MUSIC,[], 'music' ); 39 | WAD.Add(Path+'/music/*.mp3',FILETYPE_MUSIC,[], 'music' ); 40 | WAD.Add(Path+'/music/*.ogg',FILETYPE_MUSIC,[], 'music' ); 41 | WAD.Add(Path+'/sound/*.wav',FILETYPE_SOUND,[], 'sound' ); 42 | 43 | FreeAndNil(WAD); 44 | Writeln( 'Done.' ); 45 | end. 46 | -------------------------------------------------------------------------------- /src/gmfplayer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/src/gmfplayer.ico -------------------------------------------------------------------------------- /src/gmfplayer.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <PathDelim Value="\"/> 5 | <Version Value="7"/> 6 | <General> 7 | <Flags> 8 | <MainUnitHasUsesSectionForAllUnits Value="False"/> 9 | <MainUnitHasCreateFormStatements Value="False"/> 10 | <MainUnitHasTitleStatement Value="False"/> 11 | <UseDefaultCompilerOptions Value="True"/> 12 | </Flags> 13 | <SessionStorage Value="InProjectDir"/> 14 | <MainUnit Value="0"/> 15 | <TargetFileExt Value=".exe"/> 16 | <Title Value="GMFPlayer"/> 17 | <Icon Value="0"/> 18 | <UseXPManifest Value="True"/> 19 | </General> 20 | <VersionInfo> 21 | <ProjectVersion Value=""/> 22 | <Language Value=""/> 23 | <CharSet Value=""/> 24 | </VersionInfo> 25 | <PublishOptions> 26 | <Version Value="2"/> 27 | <IgnoreBinaries Value="False"/> 28 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 29 | <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> 30 | </PublishOptions> 31 | <RunParams> 32 | <local> 33 | <FormatVersion Value="1"/> 34 | <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> 35 | </local> 36 | </RunParams> 37 | <Units Count="1"> 38 | <Unit0> 39 | <Filename Value="gmfplayer.lpr"/> 40 | <IsPartOfProject Value="True"/> 41 | <UnitName Value="gmfplayer"/> 42 | </Unit0> 43 | </Units> 44 | </ProjectOptions> 45 | <CompilerOptions> 46 | <Version Value="8"/> 47 | <PathDelim Value="\"/> 48 | <Target> 49 | <Filename Value="../bin/gmfplayer"/> 50 | </Target> 51 | <SearchPaths> 52 | <IncludeFiles Value="..\..\fpcvalkyrie\src\"/> 53 | <OtherUnitFiles Value="..\..\fpcvalkyrie\src\"/> 54 | <UnitOutputDirectory Value="..\tmp"/> 55 | </SearchPaths> 56 | <Other> 57 | <CompilerPath Value="$(CompPath)"/> 58 | </Other> 59 | </CompilerOptions> 60 | <Debugging> 61 | <Exceptions Count="3"> 62 | <Item1> 63 | <Name Value="EAbort"/> 64 | </Item1> 65 | <Item2> 66 | <Name Value="ECodetoolError"/> 67 | </Item2> 68 | <Item3> 69 | <Name Value="EFOpenError"/> 70 | </Item3> 71 | </Exceptions> 72 | </Debugging> 73 | </CONFIG> 74 | -------------------------------------------------------------------------------- /src/gmfplayer.lpr: -------------------------------------------------------------------------------- 1 | program gmfplayer; 2 | uses SysUtils, vsystems, vutil, voutput, vtoutput, vtinput, vinput, keyboard, crt, zstream, vds; 3 | type TPointerArray = specialize TArray<TScreenDump>; 4 | var GMF : TGZFileStream; 5 | Mov : TPointerArray; 6 | Frames : DWord; 7 | Count : DWord; 8 | Frame : TScreenDump; 9 | Cmd : Byte; 10 | Play : Boolean; 11 | DelAmo : Word; 12 | SizeX : Word; 13 | SizeY : Word; 14 | 15 | 16 | begin 17 | Writeln; 18 | Writeln(' gmfplay - GenRogue Movie File player'); 19 | Writeln(' Copyright (c) 2004 by Kornel Kisielewicz' ); 20 | Writeln(' All rights reserved'); 21 | Writeln; 22 | if ParamCount < 1 then 23 | begin 24 | Writeln(' usage : gmfplay [filename]'); 25 | Halt(0); 26 | end; 27 | Systems.Add(Output,TTextModeOutput.Create); 28 | Systems.Add(Input,TTextModeInput.Create); 29 | Mov := TPointerArray.Create(512); 30 | GMF := TGZFileStream.Create(ParamStr(1),gzopenread); 31 | Frames := GMF.ReadDWord; 32 | SizeX := GMF.ReadDWord; 33 | SizeY := GMF.ReadDWord; 34 | for Count := 1 to Frames do 35 | begin 36 | GetMem(Frame,SizeOf(Word)*SizeX*SizeY); 37 | if Frame = nil then begin Writeln('Out of memory while trying to load movie.'); Halt(0); end; 38 | GMF.Read(Frame^,SizeOf(Word)*SizeX*SizeY); 39 | Mov[Count] := Frame; 40 | end; 41 | FreeAndNil( GMF ); 42 | 43 | Count := 1; 44 | DelAmo := 120; 45 | Play := False; 46 | repeat 47 | TTextModeOutput(Output).DrawScreenDump(TScreenDump(Mov[Count])); 48 | Output.DrawString(1,25,DarkGray, 49 | '@d -- @lGMF Viewer@d -- @lFile:@L '+ParamStr(1)+ 50 | '@d -- @l<-,->,Escape,Space @d--'+ 51 | ' @lFrame: @L'+IntToStr(Count)+'@l/@L'+IntToStr(Frames)+'@d --'); 52 | Output.Update; 53 | if Play then 54 | begin 55 | Delay(DelAmo); 56 | Inc(Count); 57 | if Count > Frames then Count := 1; 58 | if PollKeyEvent = 0 then Continue; 59 | end; 60 | cmd := Input.GetKey([VKEY_ESCAPE,Ord(' '),Ord('+'),Ord('-'),VKEY_LEFT,VKEY_RIGHT,VKEY_END,VKEY_HOME]); 61 | case cmd of 62 | Ord(' ') : begin Play := not Play; while PollKeyEvent <> 0 do Input.GetKey; end; 63 | VKEY_LEFT : begin Play := False; if Count > 1 then Dec(Count); end; 64 | VKEY_RIGHT : begin Play := False; if Count < Frames then Inc(Count);end; 65 | VKEY_HOME : begin Play := False; Count := 1; end; 66 | VKEY_END : begin Play := False; Count := Frames; end; 67 | Ord('+') : if DelAmo < 1000 then Inc(DelAmo,20); 68 | Ord('-') : if DelAmo > 21 then Dec(DelAmo,20); 69 | end; 70 | until cmd = VKEY_ESCAPE; 71 | 72 | FreeAndNil( Mov ); 73 | end. 74 | -------------------------------------------------------------------------------- /src/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chaosforgeorg/doomrl/97f1c512ee9178cc903618c389a8617beea91a38/src/icon.ico -------------------------------------------------------------------------------- /src/makerel.pl: -------------------------------------------------------------------------------- 1 | # version.pl 2 | open(FILE, "version.txt"); 3 | open(BAT, ">makerel.bat"); 4 | $ver = readline(FILE); 5 | $ver =~ s/\s.*$//g; 6 | $ver =~ s/\.//g; 7 | close(FILE); 8 | print BAT "\@echo off\n"; 9 | print BAT "cd release\n"; 10 | print BAT "zip doomrl-$ver-windos *.*\n"; 11 | print BAT "cd ..\n"; 12 | close(BAT); 13 | -------------------------------------------------------------------------------- /src/makewad.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="12"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <Flags> 8 | <MainUnitHasUsesSectionForAllUnits Value="False"/> 9 | <MainUnitHasCreateFormStatements Value="False"/> 10 | <MainUnitHasTitleStatement Value="False"/> 11 | <LRSInOutputDirectory Value="False"/> 12 | <CompatibilityMode Value="True"/> 13 | </Flags> 14 | <SessionStorage Value="InProjectDir"/> 15 | <Title Value="MakeWAD"/> 16 | </General> 17 | <BuildModes Count="1"> 18 | <Item1 Name="default" Default="True"/> 19 | </BuildModes> 20 | <PublishOptions> 21 | <Version Value="2"/> 22 | </PublishOptions> 23 | <RunParams> 24 | <local> 25 | <LaunchingApplication Use="True" PathPlusParams="C:\Windows\system32\cmd.exe /C "${TargetCmdLine}""/> 26 | </local> 27 | <FormatVersion Value="2"/> 28 | <Modes Count="1"> 29 | <Mode0 Name="default"> 30 | <local> 31 | <LaunchingApplication Use="True" PathPlusParams="C:\Windows\system32\cmd.exe /C "${TargetCmdLine}""/> 32 | </local> 33 | </Mode0> 34 | </Modes> 35 | </RunParams> 36 | <Units Count="2"> 37 | <Unit0> 38 | <Filename Value="makewad.pas"/> 39 | <IsPartOfProject Value="True"/> 40 | </Unit0> 41 | <Unit1> 42 | <Filename Value="..\bin\constants.inc"/> 43 | <IsPartOfProject Value="True"/> 44 | </Unit1> 45 | </Units> 46 | </ProjectOptions> 47 | <CompilerOptions> 48 | <Version Value="11"/> 49 | <PathDelim Value="\"/> 50 | <Target> 51 | <Filename Value="..\bin\makewad"/> 52 | </Target> 53 | <SearchPaths> 54 | <OtherUnitFiles Value="..\..\fpcvalkyrie\src;..\..\fpcvalkyrie\libs"/> 55 | <UnitOutputDirectory Value="..\tmp"/> 56 | </SearchPaths> 57 | <Parsing> 58 | <SyntaxOptions> 59 | <UseAnsiStrings Value="False"/> 60 | </SyntaxOptions> 61 | </Parsing> 62 | <Linking> 63 | <Debugging> 64 | <DebugInfoType Value="dsDwarf3"/> 65 | </Debugging> 66 | </Linking> 67 | </CompilerOptions> 68 | </CONFIG> 69 | -------------------------------------------------------------------------------- /src/makewad.pas: -------------------------------------------------------------------------------- 1 | {$INCLUDE doomrl.inc} 2 | program makewad; 3 | uses Classes,SysUtils, strutils, vpkg,vdf, vutil, dfdata, idea; 4 | 5 | var WAD : TVDataCreator; 6 | EKey,DKKey : TIDEAKey; 7 | KeyFile : Text; 8 | Count : Byte; 9 | 10 | const UserKey : TIdeaCryptKey = (123,111,10,12,222,90,1,8); 11 | begin 12 | WADMAKE := True; 13 | 14 | EnKeyIdea(UserKey,EKey); 15 | DeKeyIdea(EKey,DKKey); 16 | 17 | WAD := TVDataCreator.Create('drl.wad'); 18 | WAD.SetKey( EKey ); 19 | 20 | WAD.Add('help/*.hlp',FILETYPE_HELP,[vdfCompressed,vdfEncrypted], 'ascii' ); 21 | WAD.Add('help/*.asc',FILETYPE_ASCII,[vdfCompressed,vdfEncrypted], 'ascii' ); 22 | WAD.Add('help/logo.dat', FILETYPE_ASCII, [vdfCompressed,vdfEncrypted], 'ascii' ); 23 | WAD.Add('lua/*.lua',FILETYPE_LUA,[vdfCompressed,vdfEncrypted], '' ); 24 | WAD.Add('lua/levels/*.lua',FILETYPE_LUA,[vdfCompressed,vdfEncrypted], 'levels' ); 25 | WAD.Add('lua/items/*.lua',FILETYPE_LUA,[vdfCompressed,vdfEncrypted], 'items' ); 26 | WAD.Add('font*.png',FILETYPE_IMAGE,[], 'fonts' ); 27 | WAD.Add('graphics/*.png',FILETYPE_IMAGE,[], 'graphics' ); 28 | WAD.Add('graphics/doom.ini', FILETYPE_ASCII, [], '' ); 29 | WAD.Add('graphics/message.xml', FILETYPE_FONT, [], '' ); 30 | 31 | Assign(KeyFile,'dkey.inc'); 32 | Rewrite(KeyFile); 33 | Write(KeyFile,'const LoveLace : TIDEAKey = ( '); 34 | for Count := Low(DKKey) to High(DKKey)-1 do 35 | Write(KeyFile,DKKey[Count],', '); 36 | Writeln(KeyFile,DKKey[High(DKKey)],' );'); 37 | Close(KeyFile); 38 | 39 | FreeAndNil(WAD); 40 | 41 | WAD := TVDataCreator.Create('core.wad'); 42 | WAD.Add('core/*.lua',FILETYPE_LUA,[vdfCompressed], '' ); 43 | FreeAndNil(WAD); 44 | end. 45 | -------------------------------------------------------------------------------- /src/release.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cp release/*.zip archive 3 | rm release/*.* 4 | cp d:\temp\doomrl.exe d:\projekty\doomrl\release 5 | cp d:\temp\makewad.exe d:\projekty\doomrl 6 | makewad 7 | cp doomrl.wad release 8 | perl help/makeman.pl 9 | copy help\manual.txt release 10 | copy version.txt release 11 | perl makerel.pl 12 | call makerel 13 | rm makerel.bat 14 | -------------------------------------------------------------------------------- /src/version.inc: -------------------------------------------------------------------------------- 1 | // Autogenerated by FPC Valkyrie lua_make.lua 2 | VERSION_STRING = '0.9.9.8a'; 3 | VERSION_ARRAY : array[1..4] of byte = (0,9,9,8); 4 | VERSION_BETA = false; 5 | VERSION_REV = 139399954; 6 | --------------------------------------------------------------------------------