Modding:Tutorial/The Infinite Arena/Source

From DoomRL Wiki

Revision as of 16:48, 8 April 2012 by Game Hunter (Talk | contribs)

Jump to: navigation, search

core.declare("inf_arena", {} )

--enemy scaling for each wave: note that game difficulty will modify scaling independently local mob_scale_factor = 0.5 --customize min_lev/max_lev/weight of each enemy (defaults given) --for names of beings, check Object IDs in the modding documentation --be aware that JC auto-ends the game unless modified directly local mobGenStats = {

   { being = "former",         min_lev = 0,   max_lev = 12,  weight = 10 },
   { being = "sergeant",       min_lev = 2,   max_lev = 15,  weight = 10 },
   { being = "captain",        min_lev = 8,   max_lev = 15,  weight = 10 },
   { being = "imp",            min_lev = 0,   max_lev = 17,  weight = 8  },
   { being = "demon",          min_lev = 4,   max_lev = 20,  weight = 6  },
   { being = "lostsoul",       min_lev = 6,   max_lev = 16,  weight = 10 },
   { being = "knight",         min_lev = 9,   max_lev = 15,  weight = 6  },
   { being = "cacodemon",      min_lev = 10,  max_lev = 50,  weight = 6  },
   { being = "commando",       min_lev = 12,  max_lev = 17,  weight = 6  },
   { being = "pain",           min_lev = 12,  max_lev = 17,  weight = 2  },
   { being = "baron",          min_lev = 12,  max_lev = 200, weight = 6  },
   { being = "arachno",        min_lev = 13,  max_lev = 50,  weight = 4  },
   { being = "revenant",       min_lev = 13,  max_lev = 200, weight = 5  },
   { being = "mancubus",       min_lev = 15,  max_lev = 200, weight = 7  },
   { being = "arch",           min_lev = 16,  max_lev = 200, weight = 4  },
   { being = "nimp",           min_lev = 30,  max_lev = 60,  weight = 8  },
   { being = "ndemon",         min_lev = 40,  max_lev = 200, weight = 6  },
   { being = "ncacodemon",     min_lev = 51,  max_lev = 200, weight = 6  },
   { being = "narachno",       min_lev = 50,  max_lev = 200, weight = 5  },
   { being = "narch",          min_lev = 90,  max_lev = 200, weight = 3  },
   { being = "bruiser",        min_lev = 50,  max_lev = 200, weight = 6  },
   { being = "lava_elemental", min_lev = 70,  max_lev = 200, weight = 1  },
   { being = "shambler",       min_lev = 80,  max_lev = 200, weight = 3  },
   { being = "agony",          min_lev = 80,  max_lev = 200, weight = 1  },
   { being = "cyberdemon",     min_lev = 80,  max_lev = 200, weight = 1  },
   { being = "arenamaster",    min_lev = 0,   max_lev = 0,   weight = 0  },
   { being = "angel",          min_lev = 0,   max_lev = 0,   weight = 0  },
   { being = "jc",             min_lev = 0,   max_lev = 0,   weight = 0  },

}

--item scaling for each wave local item_scale_factor = 0.5 --customize level/weight of items (defaults given) --for names of items, check Object IDs in the modding documentation local itemGenStats = {

   --Commons
   
   --weapons
   { item = "knife",        level = 1,  weight = 640 },
   { item = "pistol",       level = 1,  weight = 70  },
   { item = "shotgun",      level = 2,  weight = 180 },
   { item = "ashotgun",     level = 2,  weight = 160 },
   { item = "dshotgun",     level = 4,  weight = 100 },
   { item = "chaingun",     level = 5,  weight = 200 },
   { item = "bazooka",      level = 7,  weight = 200 },
   { item = "plasma",       level = 12, weight = 70  },
   --ammo/ammo packs
   { item = "ammo",         level = 1,  weight = 500 },
   { item = "pammo",        level = 3,  weight = 700 },
   { item = "shell",        level = 2,  weight = 400 },
   { item = "pshell",       level = 4,  weight = 200 },
   { item = "rocket",       level = 5,  weight = 60  },
   { item = "procket",      level = 7,  weight = 60  },
   { item = "cell",         level = 8,  weight = 36  },
   { item = "pcell",        level = 10, weight = 18  },
   --armor/boots
   { item = "garmor",       level = 1,  weight = 400 },
   { item = "barmor",       level = 4,  weight = 240 },
   { item = "rarmor",       level = 7,  weight = 150 },
   { item = "sboots",       level = 4,  weight = 240 },
   { item = "pboots",       level = 7,  weight = 150 },
   { item = "psboots",      level = 11, weight = 80  },
   --consumables
   { item = "smed",         level = 1,  weight = 600 },
   { item = "lmed",         level = 5,  weight = 400 },
   { item = "phase",        level = 5,  weight = 200 },
   { item = "hphase",       level = 7,  weight = 100 },
   { item = "epack",        level = 5,  weight = 100 },
   { item = "nuke",         level = 10, weight = 40  },
   { item = "lava_element", level = 23, weight = 0   },
   { item = "mod_power",    level = 7,  weight = 120 },
   { item = "mod_tech",     level = 6,  weight = 120 },
   { item = "mod_bulk",     level = 6,  weight = 120 },
   { item = "mod_agility",  level = 5,  weight = 120 },
   --powerups
   { item = "shglobe",      level = 1,  weight = 900 },
   { item = "lhglobe",      level = 6,  weight = 330 },
   { item = "scglobe",      level = 4,  weight = 150 },
   { item = "bpack",        level = 1,  weight = 200 },
   { item = "iglobe",       level = 7,  weight = 200 },
   { item = "msglobe",      level = 16, weight = 60  },
   { item = "map",          level = 1,  weight = 200 },
   { item = "pmap",         level = 1,  weight = 80  },
   { item = "ashard",       level = 5,  weight = 700 },
   { item = "backpack",     level = 7,  weight = 0   },
   
   --Exotics
   
   --weapons
   { item = "chainsaw",        level = 12, weight = 3  },
   { item = "ublaster",        level = 8,  weight = 2  },
   { item = "ucpistol",        level = 4,  weight = 6  },
   { item = "uashotgun",       level = 6,  weight = 6  },
   { item = "upshotgun",       level = 12, weight = 4  },
   { item = "udshotgun",       level = 10, weight = 5  },
   { item = "uminigun",        level = 10, weight = 6  },
   { item = "umbazooka",       level = 10, weight = 6  },
   { item = "unapalm",         level = 10, weight = 6  },
   { item = "ulaser",          level = 12, weight = 5  },
   { item = "unplasma",        level = 15, weight = 4  },
   { item = "utristar",        level = 12, weight = 4  },
   { item = "bfg9000",         level = 20, weight = 2  },
   { item = "unbfg9000",       level = 22, weight = 2  },
   { item = "utrans",          level = 14, weight = 3  },
   --armor/boots
   { item = "uoarmor",         level = 7,  weight = 4  },
   { item = "uparmor",         level = 10, weight = 6  },
   { item = "upboots",         level = 8,  weight = 6  },
   { item = "ugarmor",         level = 15, weight = 6  },
   { item = "ugboots",         level = 10, weight = 6  },
   { item = "umedarmor",       level = 5,  weight = 6  },
   { item = "uduelarmor",      level = 5,  weight = 6  },
   { item = "ubulletarmor",    level = 2,  weight = 4  },
   { item = "uballisticarmor", level = 2,  weight = 5  },
   { item = "ueshieldarmor",   level = 5,  weight = 3  },
   { item = "uplasmashield",   level = 10, weight = 3  },
   { item = "uenergyshield",   level = 8,  weight = 3  },
   { item = "ubalshield",      level = 6,  weight = 3  },
   { item = "uacidboots",      level = 8,  weight = 5  },
   --consumables
   { item = "uswpack",         level = 5,  weight = 10 },
   { item = "ubskull",         level = 5,  weight = 8  },
   { item = "ufskull",         level = 7,  weight = 8  },
   { item = "uhskull",         level = 9,  weight = 8  },
   { item = "umod_firestorm",  level = 10, weight = 4  },
   { item = "umod_sniper",     level = 10, weight = 4  },
   { item = "umod_nano",       level = 10, weight = 4  },
   { item = "umod_onyx",       level = 10, weight = 4  },
   
   --Uniques
   
   --weapons	
   { item = "ubutcher",     level = 1,  weight = 2 },
   { item = "spear",        level = 16, weight = 0 },
   { item = "uscythe",      level = 16, weight = 0 },
   { item = "udragon",      level = 16, weight = 1 },
   { item = "utrigun",      level = 8,  weight = 2 },
   { item = "ujackal",      level = 10, weight = 2 },
   { item = "uberetta",     level = 6,  weight = 3 },
   { item = "usjack",       level = 12, weight = 2 },
   { item = "urbazooka",    level = 12, weight = 2 },
   { item = "uacid",        level = 12, weight = 3 },
   { item = "urailgun",     level = 15, weight = 2 },
   { item = "ubfg10k",      level = 20, weight = 1 },
   --armor/boots
   { item = "umarmor",      level = 15, weight = 3 },
   { item = "ucarmor",      level = 10, weight = 2 },
   { item = "unarmor",      level = 10, weight = 3 },
   { item = "umedparmor",   level = 10, weight = 2 },
   { item = "ulavaarmor",   level = 12, weight = 2 },
   { item = "uenviroboots", level = 10, weight = 2 },
   { item = "ushieldarmor", level = 10, weight = 2 },
   { item = "uberarmor",    level = 10, weight = 1 },
   { item = "aarmor",       level = 22, weight = 0 },
   --consumables
   { item = "uhwpack",      level = 10, weight = 4 },
   { item = "umodstaff",    level = 15, weight = 4 },
   { item = "uarenastaff",  level = 4,  weight = 0 },

}

--changes the generation stats of enemies based on mobGenStats for _,v in ipairs(mobGenStats) do

   beings[v.being].min_lev = v.min_lev
   beings[v.being].max_lev = v.max_lev
   beings[v.being].weight = v.weight

end

--changes the generation stats of items based on itemGenStats for _,v in ipairs(itemGenStats) do

   items[v.item].level  = v.level
   items[v.item].weight = v.weight

end

--add your own announcer lines here local anncrMsg = {

   --displays whenever player completes wave
   success = {
       {
       "The voice booms, \"Congratulations mortal!",
       "The voice booms, \"Impressive mortal!",
       "The voice booms, \"Most impressive.",
       "The voice booms, \"You are a formidable warrior!",
       },
       {
       "Each of your triumphs is a work of art!",
       "Your ability to survive is incredible!",
       "You've given us a great show!",
       "You would make a terrific hell warrior!",
       },
       {
       "But can you keep going?\"",
       "How much longer can you go?\"",
       "Will you fight with us a little more?\"",
       "I can let you go now if you like, or...\"",
       }
   },
   --displays whenever player decides to continue to another wave
   choice = {
       {
       "The voice booms, \"I like it! Let the show go on!\"",
       "The voice booms, \"Excellent! May the fight begin!!!\"",
       },
       {
       "You hear screams everywhere! \"More Blood! More BLOOD!\"",
       "You hear screams everywhere! \"Kill, Kill, KILL!\"",
       }
   }

}

--add your own crowd lines here --displays whenever enemy is killed local crowdMsg = {

   "The crowd goes wild! \"BLOOD! BLOOD!\"",
   "The crowd cheers! \"Blood! Blood!\"",
   "The crowd cheers! \"Kill! Kill!\"",
   "The crowd hisses. \"We came for a REAL fight!\"",
   "The crowd boos. \"No skill, no kill!\"",

}

local function build_announcerMsg(MSG)

   for _,msgNum in ipairs(MSG) do
       ui.msg(table.random_pick(msgNum))
   end

end

--from Skulltag Arena, credit goes to yaflhdztioxo --initializes table of cells that contains only corpses local corpseCells = {}

local function get_corpses()

   for i = 1, #cells do
       if cells[i] and cells[i].flags then
           if cells[i].flag_set[CF_CORPSE] == true then
               table.insert(corpseCells, i) --i == sID's numeric value
           end
       end
   end

end

--removes corpses and blood-like cells local function clear_corpses()

   --fade away all blood
   Generator.transmute("blood", "floor")
   Generator.transmute("bloodpool", "blood")
   --changes corpses to blood
   for i = 1, #corpseCells do
       Generator.transmute(corpseCells[i], "bloodpool")
   end

end

--changes player equipment --add "nil" for any slot that should be empty --always refreshes all slots: do not use to change only one equipment slot local function build_gear(weap,prep,body,foot)

   player.eq:clear()
   if weap then player.eq.weapon   = item.new(weap) end --main weapon
   if prep then player.eq.prepared = item.new(prep) end --prepared weapon	
   if body then player.eq.armor    = item.new(body) end --body armor
   if foot then player.eq.boots    = item.new(foot) end --boots

end

--changes player inventory --always refreshes all slots: do not use to change only one equipment slot --[[ input is an array of tables with two fields: -name is the identifier of the item that goes in the inventory -amt is how many items should be added (or how many units of ammo) example table (based on default inventory):

local starter_pack = {

   {name = "ammo", amt = 24},
   {name = "smed", amt = 2},

} --]] local function build_pack(itemPack)

   player.inv:clear()
   for _,part in ipairs(itemPack) do
       if items[part.name].type == ITEMTYPE_AMMO then
           --ammo is handled separately, loops for however many stacks are needed
           for n=1,math.ceil(part.amt/items[part.name].ammomax) do
               local pack = item.new(part.name)
               if part.amt < pack.ammomax then
                   --remainder (or single) stack
                   pack.ammo = part.amt
               else
                   --filled (and/or multiple) stacks
                   pack.ammo = pack.ammomax
                   part.amt = part.amt - pack.ammomax
               end
               player.inv:add(pack)
           end
       else
           --loops for however many items are needed
           for n=1,part.amt do
               player.inv:add(part.name)
           end
       end
   end

end


function inf_arena.OnEnter()

   --inventory table used for build_pack()
   local itemPack = {
       {name = "smed",  amt = 2},
       {name = "shell", amt = 50},
   }
   --set up starting eq/inv
   build_gear("shotgun","pistol",nil,nil)
   build_pack(itemPack)
   
   --Print announcer messages
   ui.msg("A devilish voice announces: \"Welcome to Hell's Arena, mortal! " ..
          "\"You are either very brave or very foolish. Either way I like it! " ..
          "\"And so do the crowds!\" Suddenly you hear screams everywhere! " ..
          "\"Blood! Blood! BLOOD!\" \"Kill all enemies and I shall reward thee!\"")
   --spawn first wave
   Level.flood_monsters(Generator.being_weight()*mob_scale_factor)
   Level.result(1)

end

function inf_arena.OnKill(being)

   --random message from crowdMsg array
   ui.msg(table.random_pick(crowdMsg))

end

function inf_arena.OnKillAll()

   --print more announcer stuff
   if Level.result() == 1 then
       ui.msg("The voice booms, \"Not bad mortal! For a weakling that you are, " ..
              "you show some determination.\" You hear screams everywhere! " ..
              "\"More Blood! More BLOOD!\" The voice continues, \"I can now " ..
              "let you go free, or you may try to complete the challenge!\"")
   elseif Level.result() == 2 then
       ui.msg("The voice booms, \"Impressive mortal! Your determination to " ..
              "survive makes me excited!\" You hear screams everywhere! " ..
              "\"More Blood! More BLOOD!\" \"I can let you go now, and give you " ..
              "a small reward, or you can choose to fight an additional challenge!\"")
   else
       --random message from anncrMsg.success array
       build_announcerMsg(anncrMsg.success)
   end
   
   local choice = ui.msg_confirm("Round " .. Level.result() + 1 .. " awaits. " ..
                                 "Do you want to continue the fight?")
   if choice == true then --continuing
       --random message from anncrMsg.choice array
       build_announcerMsg(anncrMsg.choice)
       --set up the danger level for the next wave
       Level.result(Level.result() + 1);
       Level.danger_level = Level.result();
       --spawn items for next wave
       Level.flood_items(Generator.item_amount()*item_scale_factor)
       --spawn enemies for next wave
       Level.flood_monsters(Generator.being_weight()*mob_scale_factor)
   
   else --quitting
       if Level.result() == 1 then
           ui.msg("The voice booms, \"Coward!\" You hear screams everywhere! " ..
                  "\"Coward! Coward! COWARD!\"")
       elseif Level.result() == 2 then
           ui.msg("The voice booms, \"Too bad, you won't make it far then...!\" " ..
                  "You hear screams everywhere! \"Boooo...\"")
       elseif Level.result() < 10 then
           ui.msg("The voice booms, \"An impressive run, Mortal!  We appreciate " ..
                  "it!\" The crowd starts to chant! \"Encore! Encore!\"")
       else
           ui.msg("\"Ladies and gentlemen, your champion, "
                  .. Player.get_name() .. ". He survived " .. Level.result() ..
                  " rounds in our arena! That has to be some sort of record. " ..
                  "Give him a hand folks!\" The crowd starts to chant your name " ..
                  "and they begin throwing items into the ring!")
           Level.flood_items(Generator.item_weight())
       end
   end

end

function inf_arena.OnExit()

   if Level.result() < 10 then
       ui.msg("The voice laughs, \"Flee mortal, flee! There's no hiding in hell!\"")
   else
       ui.msg("The voice laughs, \"Remember to come back once you return to Hell " ..
              "for the extended stay\"")
   end
   --used in .OnMortem()
   inf_arena.result = "had enough of the gauntlet at wave "..Level.result()

end

function inf_arena.OnMortem()

   local kill = player.killedby --calls kill descriptions from beings
   if inf_arena.result then kill = inf_arena.result end
       player:mortem_print( " "..player.name..", level "..player.explevel.." "
                            .." "..klasses[player.klass].name..", "..kill )
       --e.g., "Cool Guy, level 1 Marine, had enough of the gauntlet at wave 8"
       player:mortem_print(" in the Infinite Arena...")

end

--Creation of Infinite Arena function inf_arena.run()

   Level.name = "Infinite Arena"
   Level.name_number = 0
   Level.fill("rwall")
   
   local translation = {
   ["."] = "floor",
   ["#"] = {"rwall", LFPERMANENT = true},
   ["X"] = "rwall",
   [","] = "blood",
   [">"] = "stairs",
   }
   local map = [[
                                              1. .............................########################
                      1. .....................................................############
          1. ..................................................................#####
    1. ........................................................................##
  1. ..........................................................................#

....,....................................................................... .................................,...,...................................... .,.....................................,.................................... ..,>.,..........................,........................................... .,..,.................................,.,................................... ................................,..,...,.................................... ............................................................................ ............................................................................

  1. ..........................................................................#
    1. ........................................................................##
          1. ..................................................................#####
                      1. .....................................................############
                                              1. .............................########################

]]

   --change up the column types
   local column = {
   [[

,..,., ,XXXX. .X##X, .XXXX. ,..,.,

   ]],
   [[

,..,., ,X##X. .####, .X##X. ,..,.,

   ]],
   [[

,..,., ,####. .####, .####. ,..,.,

   ]]
   }
   
   Level.place_tile(translation,map,2,2)
   for i=1,11 + math.random(4) do
       Level.scatter_put( area.new(5,3,68,15), translation, table.random_pick(column), "floor", 1)
   end
   Level.scatter(area.FULL_SHRINKED, "floor", "blood", 100)
   Level.player(38, 10)

end

Personal tools