Commit 202b374c30da5ba7e3c8afd9b596b86487a8b732

Authored by dg
1 parent bde8b5ba

bearscape!


git-svn-id: http://svn.net-core.org/repos/t-engine4@5136 51575b47-30f0-44d4-a5cc-537603b46e54
  1 +-- ToME - Tales of Maj'Eyal
  2 +-- Copyright (C) 2009, 2010, 2011, 2012 Nicolas Casalini
  3 +--
  4 +-- This program is free software: you can redistribute it and/or modify
  5 +-- it under the terms of the GNU General Public License as published by
  6 +-- the Free Software Foundation, either version 3 of the License, or
  7 +-- (at your option) any later version.
  8 +--
  9 +-- This program is distributed in the hope that it will be useful,
  10 +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +-- GNU General Public License for more details.
  13 +--
  14 +-- You should have received a copy of the GNU General Public License
  15 +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
  16 +--
  17 +-- Nicolas Casalini "DarkGod"
  18 +-- darkgod@te4.org
  19 +
  20 +require "engine.class"
  21 +local Dialog = require "engine.ui.Dialog"
  22 +local ListColumns = require "engine.ui.ListColumns"
  23 +local TextzoneList = require "engine.ui.TextzoneList"
  24 +local Separator = require "engine.ui.Separator"
  25 +local Image = require "engine.ui.Image"
  26 +
  27 +module(..., package.seeall, class.inherit(Dialog))
  28 +
  29 +function _M:init()
  30 + Dialog.init(self, "Download charball", game.w * 0.8, game.h * 0.8)
  31 +
  32 + self:generateList()
  33 +
  34 + self.c_list = ListColumns.new{width=math.floor(self.iw - 10), height=self.ih - 10, scrollbar=true, sortable=true, columns={
  35 + {name="Player", width=30, display_prop="player", sort="player"},
  36 + {name="Character", width=70, display_prop="character", sort="character"},
  37 + }, list=self.list, fct=function(item) self:importCharball(item) end, select=function(item, sel) self:select(item) end}
  38 +
  39 + self:loadUI{
  40 + {left=0, top=0, ui=self.c_list},
  41 + }
  42 + self:setFocus(self.c_list)
  43 + self:setupUI()
  44 + self:select(self.list[1])
  45 +
  46 + self.key:addBinds{
  47 + EXIT = function() game:unregisterDialog(self) end,
  48 + }
  49 +end
  50 +
  51 +function _M:generateList()
  52 + profile.chat:selectChannel("tome")
  53 +
  54 + -- Makes up the list
  55 + local list = {}
  56 + for login, user in pairs(profile.chat.channels.tome.users) do
  57 + if user.valid == "validate" and user.current_char_data and user.current_char_data.uuid then
  58 + list[#list+1] = { player=user.name, character=user.current_char, id=user.id, uuid=user.current_char_data.uuid }
  59 + end
  60 + end
  61 + -- Add known artifacts
  62 + table.sort(list, function(a, b) return a.character < b.character end)
  63 + self.list = list
  64 +end
  65 +
  66 +function _M:select(item)
  67 + if item then
  68 + end
  69 +end
  70 +
  71 +function _M:importCharball(item)
  72 + if not item or not item.uuid then return end
  73 +
  74 + local data = profile:getCharball(item.id, item.uuid)
  75 + local f = fs.open("/charballs/__import.charball", "w")
  76 + f:write(data)
  77 + f:close()
  78 +
  79 + savefile_pipe:ignoreSaveToken(true)
  80 + local ep = savefile_pipe:doLoad("__import", "entity", "engine.CharacterBallSave", "__import")
  81 + savefile_pipe:ignoreSaveToken(false)
  82 + for a, _ in pairs(ep.members) do
  83 + if a.__CLASSNAME == "mod.class.Player" then
  84 + mod.class.NPC.castAs(a)
  85 + engine.interface.ActorAI.init(a, a)
  86 + a.quests = {}
  87 + a.ai = "tactical"
  88 + a.ai_state = {talent_in=1}
  89 + a.no_drops = true
  90 + a.energy.value = 0
  91 + a.player = nil
  92 + a.faction = "enemies"
  93 + game.zone:addEntity(game.level, a, "actor", game.player.x, game.player.y-1)
  94 +
  95 + game:unregisterDialog(self)
  96 + end
  97 + end
  98 +end
... ...
  1 +if game.state.has_bearscape then return end
  2 +game.state.has_bearscape = true
  3 +
  4 +game:onLevelLoad("wilderness-1", function(wzone, level)
  5 + local changer = function()
  6 + local npcs = mod.class.NPC:loadList{"/data/general/npcs/bear.lua"}
  7 + local DamageType = engine.DamageType
  8 + local Talents = engine.interface.ActorTalents
  9 + npcs.BORIUS = mod.class.NPC.new{
  10 + name="Borius, Avatar of Bearness",
  11 + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/animal_bear_norgos_the_guardian.png", display_h=2, display_y=-1}}},
  12 + type = "animal", subtype = "bear", unique = true,
  13 + display = "q", color=colors.VIOLET,
  14 + desc = [[This creature has the form of a bear, only times bigger. It represents all that is bear in the bearscape!]],
  15 + level_range = {15, nil}, exp_worth = 1,
  16 + max_life = 230, life_rating = 22, fixed_rating = true,
  17 + stats = { str=25, dex=10, cun=8, mag=20, wil=20, con=35 },
  18 + rank = 3.5,
  19 + size_category = 4,
  20 + combat_armor = 25, combat_def = 6,
  21 + infravision = 10,
  22 + instakill_immune = 1,
  23 + stun_immune = 1,
  24 + move_others=true,
  25 + combat = { dam=resolvers.levelup(resolvers.rngavg(30,190), 1, 2), atk=resolvers.rngavg(25,70), apr=35, dammod={str=1.1} },
  26 + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
  27 + resolvers.drops{chance=100, nb=1, {defined="BEAR_PAW"}, },
  28 + resolvers.drops{chance=100, nb=3, {tome_drops="boss"} },
  29 + resolvers.talents{
  30 + [Talents.T_CRUSHING_HOLD]={base=3, every=7},
  31 + [Talents.T_CLINCH]={base=5, every=7},
  32 + [Talents.T_MAIM]={base=4, every=7},
  33 + [Talents.T_TAKE_DOWN]={base=3, every=7},
  34 + [Talents.T_UPPERCUT]={base=3, every=7},
  35 + [Talents.T_VICIOUS_STRIKES]={base=3, every=7},
  36 + [Talents.T_UNARMED_MASTERY]={base=3, every=7},
  37 + [Talents.T_COMBO_STRING]={base=3, every=7},
  38 + [Talents.T_SHATTERING_SHOUT]={base=3, every=7},
  39 + },
  40 + resolvers.sustains_at_birth(),
  41 +
  42 + autolevel = "warrior",
  43 + ai = "tactical", ai_state = { talent_in=1, ai_move="move_astar", },
  44 + resolvers.inscriptions(2, "infusion"),
  45 + }
  46 +
  47 + local objects = mod.class.Object:loadList("/data/general/objects/objects.lua")
  48 + objects.BEAR_PAW = mod.class.Object.new{
  49 + power_source = {nature=true},
  50 + unique = true,
  51 + slot = "TOOL",
  52 + type = "misc", subtype="animal",
  53 + unided_name = "bear paw",
  54 + name = "Essence of Bearness", image = "object/bear_paw.png",
  55 + level_range = {20, 35},
  56 + display = "*", color=colors.GREEN,
  57 + encumber = 3,
  58 + desc = [[The very essence of bearness!]],
  59 +
  60 + max_power = 100, power_regen = 1,
  61 + use_power = { name = "invoke your inner bearness", power = 100, use = function(self, who)
  62 + who:setEmote(require("engine.Emote").new("GROOOOOWWWLLLLL!!!!", 80))
  63 + who:setEffect(who.EFF_PAIN_SUPPRESSION, 5, {power=25})
  64 + return {id=true, used=true}
  65 + end },
  66 + }
  67 +
  68 + local zone = engine.Zone.new("bearscape", {
  69 + name = "Bearscape",
  70 + level_range = {12, 35},
  71 + level_scheme = "player",
  72 + max_level = 3,
  73 + actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
  74 + width = 50, height = 50,
  75 + ambient_music = "Rainy Day.ogg",
  76 + reload_lists = false,
  77 + generator = {
  78 + map = {
  79 + class = "engine.generator.map.Forest",
  80 + edge_entrances = {4,6},
  81 + zoom = 4,
  82 + sqrt_percent = 30,
  83 + noise = "fbm_perlin",
  84 + floor = "GRASS",
  85 + wall = "TREE",
  86 + up = "GRASS_UP4",
  87 + down = "GRASS_DOWN6",
  88 + door = "GRASS",
  89 + do_ponds = {
  90 + nb = {0, 2},
  91 + size = {w=25, h=25},
  92 + pond = {{0.6, "DEEP_WATER"}, {0.8, "DEEP_WATER"}},
  93 + },
  94 + },
  95 + actor = {
  96 + class = "mod.class.generator.actor.Random",
  97 + nb_npc = {35, 45},
  98 + guardian = "BORIUS",
  99 + randelite = 3,
  100 + },
  101 + object = {
  102 + class = "engine.generator.object.Random",
  103 + nb_object = {6, 9},
  104 + },
  105 + trap = {
  106 + class = "engine.generator.trap.Random",
  107 + nb_trap = {6, 9},
  108 + },
  109 + },
  110 + levels = { [1] = { generator = { map = { up = "GRASS", }, }, }, },
  111 + npc_list = npcs,
  112 + grid_list = mod.class.Grid:loadList{"/data/general/grids/basic.lua", "/data/general/grids/forest.lua", "/data/general/grids/water.lua"},
  113 + object_list = objects,
  114 + trap_list = mod.class.Trap:loadList("/data/general/traps/natural_forest.lua"),
  115 + all_lited=true,
  116 +
  117 + post_process = function(level)
  118 + if not config.settings.tome.weather_effects then return end
  119 +
  120 + local Map = require "engine.Map"
  121 + level.foreground_particle = require("engine.Particles").new("raindrops", 1, {width=Map.viewport.width, height=Map.viewport.height})
  122 +
  123 + game.state:makeWeather(level, 6, {max_nb=3, chance=1, dir=110, speed={0.1, 0.6}, alpha={0.3, 0.5}, particle_name="weather/dark_cloud_%02d"})
  124 +
  125 + game.state:makeAmbientSounds(level, {
  126 + wind={ chance=120, volume_mod=1.9, pitch=2, random_pos={rad=10}, files={"ambient/forest/wind1","ambient/forest/wind2","ambient/forest/wind3","ambient/forest/wind4"}},
  127 + creature={ chance=2500, volume_mod=0.6, pitch=0.5, random_pos={rad=10}, files={"creatures/bears/bear_growl_2", "creatures/bears/bear_growl_3", "creatures/bears/bear_moan_2"}},
  128 + })
  129 + end,
  130 + foreground = function(level, x, y, nb_keyframes)
  131 + if not config.settings.tome.weather_effects or not level.foreground_particle then return end
  132 + level.foreground_particle.ps:toScreen(x, y, true, 1)
  133 + end,
  134 + })
  135 + return zone
  136 + end
  137 +
  138 + local find = {type="world-encounter", subtype="maj-eyal"}
  139 + local where = game.level:pickSpotRemove(find)
  140 + while where and (game.level.map:checkAllEntities(where.x, where.y, "block_move") or not game.level.map:checkAllEntities(where.x, where.y, "can_encounter")) do where = game.level:pickSpotRemove(find) end
  141 + local x, y = mod.class.Encounter:findSpot(where)
  142 + print("Bearscape at ", x, y)
  143 + if not x then return end
  144 +
  145 + local g = game.level.map(x, y, engine.Map.TERRAIN):cloneFull()
  146 + g.name = "Portal to the Bearscape"
  147 + g.display='>' g.color_r=0 g.color_g=0 g.color_b=255 g.notice = true
  148 + g.change_level=1 g.change_zone="bearscape" g.glow=true
  149 + g.add_displays = g.add_displays or {}
  150 + g.add_displays[#g.add_displays+1] = mod.class.Grid.new{image="terrain/demon_portal4.png", z=5}
  151 + g.nice_tiler = nil
  152 + g:initGlow()
  153 + g.real_change = changer
  154 + g.change_level_check = function(self)
  155 + if game.visited_zones["bearscape"] then game.log("#VIOLET#The portal seems to be inactive now.")
  156 + else game:changeLevel(1, self.real_change()) end
  157 + return true
  158 + end
  159 + game.zone:addEntity(game.level, g, "terrain", x, y)
  160 + print("Bearscape portal added")
  161 +end)
  162 +local msg = "Message from #GOLD#DarkGod#WHITE#: Grooooowwwlll. The Bearscape has come!\nThis is an event you got to enjoy because you were logged in at the right time, look for a portal on your worldmap!\nBeware, Bears are cute but this zone might not be that easy! Level 15 recommended."
  163 +game.log(msg)
  164 +require("engine.ui.Dialog"):simpleLongPopup("Bears?!", msg, 500)
... ...
... ... @@ -99,7 +99,7 @@ game:onLevelLoad("wilderness-1", function(wzone, level)
99 99 },
100 100 },
101 101 actor = {
102   - class = "engine.generator.actor.Random",
  102 + class = "mod.class.generator.actor.Random",
103 103 nb_npc = {20, 30},
104 104 guardian = "KELAD",
105 105 },
... ...