Commit 838be98caea4ce95d7c26471317bee47156067b3

Authored by Otowa Kotori
2 parents 8e4452a5 a22f7184

Merge remote-tracking branch 'upstream/master' into misc174

Showing 100 changed files with 732 additions and 70 deletions

Too many changes to show.

To preserve performance only 100 of 100+ files are displayed.

... ... @@ -627,7 +627,7 @@ end
627 627 function _M:createProfile(loginItem)
628 628 if not loginItem.create then
629 629 self.auth_tried = nil
630   - local d = Dialog:simpleWaiter(_t"Login in...", _t"Please wait...") core.display.forceRedraw()
  630 + local d = Dialog:simpleWaiter(_t"Logging in...", _t"Please wait...") core.display.forceRedraw()
631 631 profile:performlogin(loginItem.login, loginItem.pass)
632 632 profile:waitFirstAuth()
633 633 d:done()
... ...
... ... @@ -274,7 +274,7 @@ function _M:login()
274 274 end
275 275
276 276 function _M:loginSteam()
277   - local d = self:simpleWaiter(_t"Login...", _t"Login in your account, please wait...") core.display.forceRedraw()
  277 + local d = self:simpleWaiter(_t"Login...", _t"Logging in your account, please wait...") core.display.forceRedraw()
278 278 d:timeout(10, function() Dialog:simplePopup("Steam", _t"Steam client not found.") end)
279 279 core.steam.sessionTicket(function(ticket)
280 280 if not ticket then
... ...
... ... @@ -1881,6 +1881,7 @@ function _M:textRank(use_rank)
1881 1881 elseif use_rank == 3.5 then rank, color = _t"unique", "#SANDY_BROWN#"
1882 1882 elseif use_rank == 4 then rank, color = _t"boss", "#ORANGE#"
1883 1883 elseif use_rank == 5 then rank, color = _t"elite boss", "#GOLD#"
  1884 + elseif use_rank == 11 then rank, color = _t"godslayer", "#FF4000#"
1884 1885 elseif use_rank >= 10 then rank, color = _t"god", "#FF4000#"
1885 1886 end
1886 1887 return rank, color
... ... @@ -4817,6 +4818,7 @@ end
4817 4818 function _M:checkTwoHandedPenalty()
4818 4819 self:removeEffect(self.EFF_2H_PENALTY, true, true)
4819 4820 if not self:attr("allow_mainhand_2h_in_1h") then return end
  4821 + if self:attr("allow_mainhand_2h_in_1h_no_penalty") then return end
4820 4822 local mi, oi = self:getInven(self.INVEN_MAINHAND), self:getInven(self.INVEN_OFFHAND)
4821 4823 if not mi or not oi then return end
4822 4824 local mh, oh = mi[1], oi[1]
... ...
... ... @@ -203,7 +203,8 @@ function _M:tooltip(x, y)
203 203 if p.level <= data.level_range[1] - 10 then color = "CRIMSON"
204 204 elseif p.level <= data.level_range[1] - 4 then color = "ORANGE"
205 205 end
206   - tstr:add(true, {"font","bold"}, {"color", color}, _t"Min.level: "..data.level_range[1], {"color", "LAST"}, {"font","normal"}, true)
  206 + tstr:add(true, {"font","bold"}, {"color", color}, _t"Min.level: "..math.floor((data.level_range[1]+(game.state.birth.difficulty_level_add or 0))*(game.state.birth.difficulty_level_mult or 1)), {"color", "LAST"}, {"font","normal"})
  207 + tstr:add(true, {"font","bold"}, {"color", color}, _t"Max.level: "..math.ceil((data.level_range[2]+(game.state.birth.difficulty_level_add or 0))*(game.state.birth.difficulty_level_mult or 1)), {"color", "LAST"}, {"font","normal"}, true)
207 208 end
208 209 end
209 210 end
... ...
... ... @@ -127,7 +127,7 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unarmed)
127 127 -- if ret then return false end
128 128 -- end
129 129
130   - if not target.turn_procs.warding_weapon and target:knowTalent(target.T_WARDING_WEAPON) and target:getTalentLevelRaw(target.T_WARDING_WEAPON) >= 5
  130 + if not target.turn_procs.warding_weapon and target:knowTalent(target.T_WARDING_WEAPON) and target:getTalentLevel(target.T_WARDING_WEAPON) >= 5
131 131 and rng.percent(target:callTalent(target.T_WARDING_WEAPON, "getChance")) then
132 132 local t = self:getTalentFromId(self.T_WARDING_WEAPON)
133 133 if target:getPsi() >= t.psi then
... ...
... ... @@ -117,6 +117,21 @@ newAchievement{
117 117 desc = _t[[Won ToME by closing the Void portal and letting yourself be killed by Aeryn to prevent the Way to enslave every sentient being on Eyal.]],
118 118 }
119 119 newAchievement{
  120 + name = "This is how the world ends: swallowed in fire, but not in darkness.", id = "AOADS_BURN",
  121 + show = "name", huge=true,
  122 + desc = _t[["Won" ToME by sacrificing yourself for your patron Distant Sun, opening a portal for it to burn and consume the world.]],
  123 +}
  124 +newAchievement{
  125 + name = "Last Instant of Sanity", id = "AOADS_SELFLESS",
  126 + show = "name", huge=true,
  127 + desc = _t[[Won ToME by closing the Void portal and letting yourself be killed by Aeryn to prevent your mad patron sun from burning the world in a searing flash.]],
  128 +}
  129 +newAchievement{
  130 + name = "They Came Back For Eyal", id = "AOADS_SHERTUL",
  131 + show = "name", huge=true,
  132 + desc = _t[[Won ToME thanks to a Sher'tul stopping you at the last moment from opening a portal to your mad patron sun.]],
  133 +}
  134 +newAchievement{
120 135 name = "Tactical master", id = "SORCERER_NO_PORTAL",
121 136 show = "name", huge=true,
122 137 desc = _t[[Fought the two Sorcerers without closing any invocation portals.]],
... ...
... ... @@ -123,7 +123,11 @@ newBirthDescriptor{
123 123 resolvers.inventorybirth{ id=true,
124 124 {type="weapon", subtype="greatsword", name="iron greatsword", autoreq=true, ego_chance= -1000},
125 125 },
126   -
  126 + resolvers.generic(function(self)
  127 + if not profile.mod.allow_build.paladin_avatar then
  128 + self:learnTalent(self.T_AVATAR_DISTANT_SUN_UNLOCK_CHECKER, true)
  129 + end
  130 + end),
127 131 },
128 132 copy_add = {
129 133 life_rating = 2,
... ...
... ... @@ -161,6 +161,7 @@ newBirthDescriptor
161 161 confusion_immune = 0.35,
162 162 max_air = 200,
163 163 moddable_tile = "yeek",
  164 + moddable_tile_nude = 1,
164 165 random_name_def = "yeek_#sex#",
165 166 },
166 167 experience = 0.85,
... ...
  1 +{
  2 + "22": {
  3 + "id": 22,
  4 + "name": "chat",
  5 + "data": {
  6 + "chatid": "welcome",
  7 + "chat": "**DO NOT TRANSLATE YET**\n<<<You feel a gentle warmth in your mind. Something speaks directly to your mind!>>>\n#YELLOW#WELL MET FRIEND! I AM A FAR AWAY STAR, AND VERY FRIENDLY, ALSO LIBERTY NEEDS TO WRITE ME!\n#LAST#",
  8 + "answer1": "sOUNDS COOL!"
  9 + },
  10 + "class": "chat",
  11 + "html": "chat1",
  12 + "typenode": true,
  13 + "inputs": {
  14 + "input_1": {
  15 + "connections": []
  16 + }
  17 + },
  18 + "outputs": {
  19 + "output_1": {
  20 + "connections": [
  21 + {
  22 + "node": "24",
  23 + "output": "input_1"
  24 + }
  25 + ]
  26 + }
  27 + },
  28 + "pos_x": 213,
  29 + "pos_y": 362
  30 + },
  31 + "24": {
  32 + "id": 24,
  33 + "name": "lua-code",
  34 + "data": {
  35 + "code": "player:callTalent(player.T_AVATAR_DISTANT_SUN_UNLOCK_CHECKER, \"doUnlock\")"
  36 + },
  37 + "class": "lua-code",
  38 + "html": "lua-code",
  39 + "typenode": true,
  40 + "inputs": {
  41 + "input_1": {
  42 + "connections": [
  43 + {
  44 + "node": "22",
  45 + "input": "output_1"
  46 + }
  47 + ]
  48 + }
  49 + },
  50 + "outputs": {
  51 + "output_1": {
  52 + "connections": []
  53 + }
  54 + },
  55 + "pos_x": 775,
  56 + "pos_y": 381
  57 + }
  58 +}
\ No newline at end of file
... ...
  1 +{
  2 + "25": {
  3 + "id": 25,
  4 + "name": "chat",
  5 + "data": {
  6 + "chatid": "chat4",
  7 + "chat": "#YELLOW#YOU ARE A CURIOUS ONE.",
  8 + "answer1": "[...]"
  9 + },
  10 + "class": "chat",
  11 + "html": "chat1",
  12 + "typenode": true,
  13 + "inputs": {
  14 + "input_1": {
  15 + "connections": [
  16 + {
  17 + "node": "32",
  18 + "input": "output_1"
  19 + }
  20 + ]
  21 + }
  22 + },
  23 + "outputs": {
  24 + "output_1": {
  25 + "connections": [
  26 + {
  27 + "node": "32",
  28 + "output": "input_1"
  29 + }
  30 + ]
  31 + }
  32 + },
  33 + "pos_x": 1564,
  34 + "pos_y": 207
  35 + },
  36 + "27": {
  37 + "id": 27,
  38 + "name": "chat",
  39 + "data": {
  40 + "chatid": "chat6",
  41 + "chat": "#YELLOW#YOU HAVE MADE THE RIGHT CHOICE. TOGETHER, WE SHALL BRING ABOUT THE DESTRUCTION OF OUR ENEMIES.",
  42 + "answer1": "#GOLD#[you are now an Avatar of a Distant Sun]"
  43 + },
  44 + "class": "chat",
  45 + "html": "chat1",
  46 + "typenode": true,
  47 + "inputs": {
  48 + "input_1": {
  49 + "connections": [
  50 + {
  51 + "node": "29",
  52 + "input": "output_1"
  53 + },
  54 + {
  55 + "node": "36",
  56 + "input": "output_1"
  57 + }
  58 + ]
  59 + }
  60 + },
  61 + "outputs": {
  62 + "output_1": {
  63 + "connections": [
  64 + {
  65 + "node": "39",
  66 + "output": "input_1"
  67 + }
  68 + ]
  69 + }
  70 + },
  71 + "pos_x": 2507,
  72 + "pos_y": -110
  73 + },
  74 + "29": {
  75 + "id": 29,
  76 + "name": "chat",
  77 + "data": {
  78 + "chatid": "welcome",
  79 + "chat": "<<<You feel the gentle warmth of your Distant Sun patron. It speaks directly to your mind!>>>\n#YELLOW#I AM HERE. DO YOU DESIRE TO SMITE EVIL, DESTROY THE DARKNESS AND SCOUR THE EARTH? I SHALL AID YOU IN THIS QUEST. TOGETHER, WE WILL BE UNSTOPPABLE. ALL DARKNESS SHALL BE CONSUMED BY OUR LIGHT.\n#LAST#",
  80 + "answer1": "Yes, give me your power!",
  81 + "answer2": "Who... Who are you?"
  82 + },
  83 + "class": "chat",
  84 + "html": "chat2",
  85 + "typenode": true,
  86 + "inputs": {
  87 + "input_1": {
  88 + "connections": []
  89 + }
  90 + },
  91 + "outputs": {
  92 + "output_1": {
  93 + "connections": [
  94 + {
  95 + "node": "27",
  96 + "output": "input_1"
  97 + }
  98 + ]
  99 + },
  100 + "output_2": {
  101 + "connections": [
  102 + {
  103 + "node": "32",
  104 + "output": "input_1"
  105 + }
  106 + ]
  107 + }
  108 + },
  109 + "pos_x": 92,
  110 + "pos_y": 131
  111 + },
  112 + "32": {
  113 + "id": 32,
  114 + "name": "chat",
  115 + "data": {
  116 + "chatid": "chat7",
  117 + "chat": "#YELLOW#I AM YOUR FRIEND. IT IS GOOD TO HAVE FRIENDS, ISN'T IT?",
  118 + "answer1": "But how are you speaking to me?",
  119 + "answer2": "You still haven't told me who or what you are.",
  120 + "answer3": "But what are you getting out of this?",
  121 + "answer4": "That doesn't tell me anything."
  122 + },
  123 + "class": "chat",
  124 + "html": "chat4",
  125 + "typenode": true,
  126 + "inputs": {
  127 + "input_1": {
  128 + "connections": [
  129 + {
  130 + "node": "29",
  131 + "input": "output_2"
  132 + },
  133 + {
  134 + "node": "25",
  135 + "input": "output_1"
  136 + },
  137 + {
  138 + "node": "33",
  139 + "input": "output_1"
  140 + },
  141 + {
  142 + "node": "34",
  143 + "input": "output_1"
  144 + }
  145 + ]
  146 + }
  147 + },
  148 + "outputs": {
  149 + "output_1": {
  150 + "connections": [
  151 + {
  152 + "node": "25",
  153 + "output": "input_1"
  154 + }
  155 + ]
  156 + },
  157 + "output_2": {
  158 + "connections": [
  159 + {
  160 + "node": "33",
  161 + "output": "input_1"
  162 + }
  163 + ]
  164 + },
  165 + "output_3": {
  166 + "connections": [
  167 + {
  168 + "node": "34",
  169 + "output": "input_1"
  170 + }
  171 + ]
  172 + },
  173 + "output_4": {
  174 + "connections": [
  175 + {
  176 + "node": "36",
  177 + "output": "input_1"
  178 + }
  179 + ]
  180 + }
  181 + },
  182 + "pos_x": 721,
  183 + "pos_y": 330
  184 + },
  185 + "33": {
  186 + "id": 33,
  187 + "name": "chat",
  188 + "data": {
  189 + "chatid": "chat8",
  190 + "chat": "#YELLOW#YOU NEED NOT CONCERN YOURSELF WITH SUCH THINGS. I KNOW YOU CRAVE POWER. I KNOW THE WEIGHT OF THE WORLD IS ON YOUR SHOULDERS. SO, ACCEPT MY BOONS. ALLOW ME TO HELP YOU.\n",
  191 + "answer1": "[...]"
  192 + },
  193 + "class": "chat",
  194 + "html": "chat1",
  195 + "typenode": true,
  196 + "inputs": {
  197 + "input_1": {
  198 + "connections": [
  199 + {
  200 + "node": "32",
  201 + "input": "output_2"
  202 + }
  203 + ]
  204 + }
  205 + },
  206 + "outputs": {
  207 + "output_1": {
  208 + "connections": [
  209 + {
  210 + "node": "32",
  211 + "output": "input_1"
  212 + }
  213 + ]
  214 + }
  215 + },
  216 + "pos_x": 1558,
  217 + "pos_y": 415
  218 + },
  219 + "34": {
  220 + "id": 34,
  221 + "name": "chat",
  222 + "data": {
  223 + "chatid": "chat9",
  224 + "chat": "#YELLOW#I AM GETTING PLENTY OUT OF THIS.",
  225 + "answer1": "[...]"
  226 + },
  227 + "class": "chat",
  228 + "html": "chat1",
  229 + "typenode": true,
  230 + "inputs": {
  231 + "input_1": {
  232 + "connections": [
  233 + {
  234 + "node": "32",
  235 + "input": "output_3"
  236 + }
  237 + ]
  238 + }
  239 + },
  240 + "outputs": {
  241 + "output_1": {
  242 + "connections": [
  243 + {
  244 + "node": "32",
  245 + "output": "input_1"
  246 + }
  247 + ]
  248 + }
  249 + },
  250 + "pos_x": 1559,
  251 + "pos_y": 776
  252 + },
  253 + "36": {
  254 + "id": 36,
  255 + "name": "chat",
  256 + "data": {
  257 + "chatid": "chat10",
  258 + "chat": "#YELLOW#I TIRE OF YOUR NAGGING QUESTIONS. TALK, TALK, TALK. YOU HAVE A SIMPLE CHOICE BEFORE YOU. WILL YOU BECOME POWERFUL? OR WILL YOU BE WEAK AND ALONE?",
  259 + "answer1": "Yes, give me your power!",
  260 + "answer2": "I don't trust you. Please go away."
  261 + },
  262 + "class": "chat",
  263 + "html": "chat2",
  264 + "typenode": true,
  265 + "inputs": {
  266 + "input_1": {
  267 + "connections": [
  268 + {
  269 + "node": "32",
  270 + "input": "output_4"
  271 + }
  272 + ]
  273 + }
  274 + },
  275 + "outputs": {
  276 + "output_1": {
  277 + "connections": [
  278 + {
  279 + "node": "27",
  280 + "output": "input_1"
  281 + }
  282 + ]
  283 + },
  284 + "output_2": {
  285 + "connections": [
  286 + {
  287 + "node": "37",
  288 + "output": "input_1"
  289 + }
  290 + ]
  291 + }
  292 + },
  293 + "pos_x": 1557,
  294 + "pos_y": 1046
  295 + },
  296 + "37": {
  297 + "id": 37,
  298 + "name": "chat",
  299 + "data": {
  300 + "chatid": "chat11",
  301 + "chat": "#YELLOW#I HAVE LITTLE PATIENCE FOR TIME WASTERS. THIS SHALL BE THE LAST TIME WE SPEAK.",
  302 + "answer1": "#GRAY#[prodigy point refunded]"
  303 + },
  304 + "class": "chat",
  305 + "html": "chat1",
  306 + "typenode": true,
  307 + "inputs": {
  308 + "input_1": {
  309 + "connections": [
  310 + {
  311 + "node": "36",
  312 + "input": "output_2"
  313 + }
  314 + ]
  315 + }
  316 + },
  317 + "outputs": {
  318 + "output_1": {
  319 + "connections": [
  320 + {
  321 + "node": "40",
  322 + "output": "input_1"
  323 + }
  324 + ]
  325 + }
  326 + },
  327 + "pos_x": 2017,
  328 + "pos_y": 1318
  329 + },
  330 + "39": {
  331 + "id": 39,
  332 + "name": "lua-code",
  333 + "data": {
  334 + "code": "player:callTalent(player.T_AVATAR_OF_A_DISTANT_SUN, \"becomeAvatar\")"
  335 + },
  336 + "class": "lua-code",
  337 + "html": "lua-code",
  338 + "typenode": true,
  339 + "inputs": {
  340 + "input_1": {
  341 + "connections": [
  342 + {
  343 + "node": "27",
  344 + "input": "output_1"
  345 + }
  346 + ]
  347 + }
  348 + },
  349 + "outputs": {
  350 + "output_1": {
  351 + "connections": []
  352 + }
  353 + },
  354 + "pos_x": 2859.4285714285716,
  355 + "pos_y": -43.42857142857143
  356 + },
  357 + "40": {
  358 + "id": 40,
  359 + "name": "lua-code",
  360 + "data": {
  361 + "code": "player:unlearnTalent(player.T_AVATAR_OF_A_DISTANT_SUN)\nplayer.unused_prodigies = player.unused_prodigies + 1\nplayer:attr(\"pissed_of_distant_sun\", 1)"
  362 + },
  363 + "class": "lua-code",
  364 + "html": "lua-code",
  365 + "typenode": true,
  366 + "inputs": {
  367 + "input_1": {
  368 + "connections": [
  369 + {
  370 + "node": "37",
  371 + "input": "output_1"
  372 + }
  373 + ]
  374 + }
  375 + },
  376 + "outputs": {
  377 + "output_1": {
  378 + "connections": []
  379 + }
  380 + },
  381 + "pos_x": 2477,
  382 + "pos_y": 1329
  383 + }
  384 +}
\ No newline at end of file
... ...
... ... @@ -21,6 +21,7 @@ local p = game.party:findMember{main=true}
21 21
22 22 local function void_portal_open(npc, player)
23 23 -- Charred scar was successful
  24 + -- do return false end
24 25 if player:hasQuest("charred-scar") and player:hasQuest("charred-scar"):isCompleted("stopped") then return false end
25 26 return true
26 27 end
... ... @@ -32,6 +33,100 @@ end
32 33
33 34
34 35 --------------------------------------------------------
  36 +-- Distant Sun is not exactly benevolent after all
  37 +--------------------------------------------------------
  38 +if p:attr("sun_paladin_avatar") then
  39 +newChat{ id="welcome",
  40 + text = ([[<<<The two Sorcerers lie dead before you.
  41 +Their bodies vanish in a small cloud of mist, quickly fading away.
  42 +You feel you the gentle warmth of your Distant Sun patron. It speaks directly to your mind!>>>
  43 +#YELLOW#YOU HAVE DONE WELL %s! YOU DESERVE A REWARD!#LAST#
  44 +<<<You can feel your mind filling with warmth and desire to serve your patron>>>
  45 +#YELLOW#BUT YOU MUST DO ONE MORE TASK!#LAST#
  46 +<<<The warmth in your head is getting intense, too intense. You feel your sanity burning away!>>>
  47 +#YELLOW#THROW YOURSELF INTO THE PORTAL! OPEN THE WAY FOR MY POWER TO RADIATE OVER YOUR WORLD! #CRIMSON#DO IT!#LAST#
  48 +<<<Those last words are compelling. You can not resist!>>>
  49 +]]):tformat(p.name:upper()),
  50 + answers = {
  51 + {_t"#YELLOW#[sacrifice yourself to bring forth your patron to Eyal!]", action=function(npc, player)
  52 + player.no_resurrect = true
  53 + player:die(player, {special_death_msg=("sacrificing %s to bring the fiery wrath of the Distant Sun"):tformat(string.his_her_self(player))})
  54 + player:setQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun")
  55 + player:hasQuest("high-peak"):win("distant-sun")
  56 + end},
  57 + {_t"Nnnnnooo! Get.. get out of my head!", jump="distant-sun-unsure"},
  58 + }
  59 +}
  60 +
  61 +local shertul = game.zone:makeEntityByName(game.level, "actor", "CALDIZAR_AOADS", true)
  62 +newChat{ id="distant-sun-unsure",
  63 + text = _t[[<<<The warmth in your mind turns into searing pain!>>>
  64 +#CRIMSON#YOU WILL DO AS YOU ARE TOLD! YOU ARE MY TOOL AND I INTEND TO USE IT!
  65 +]],
  66 + answers = {
  67 + {_t"#LIGHT_GREEN#[sacrifice yourself to bring forth your patron to Eyal!]", action=function(npc, player)
  68 + player.no_resurrect = true
  69 + player:die(player, {special_death_msg=("sacrificing %s to bring the fiery wrath of the Distant Sun"):tformat(string.his_her_self(player))})
  70 + player:setQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun")
  71 + player:hasQuest("high-peak"):win("distant-sun")
  72 + end},
  73 + {_t"#LIGHT_GREEN#[In a last incredible display of willpower you fight the Distant Sun for a few seconds, letting you project your thoughts to Aeryn.]#WHITE# High Lady! Kill me #{bold}#NOW#{normal}#",
  74 + cond=function(npc, player) return not void_portal_open(nil, player) and aeryn_alive(npc, player) and player:getWil() >= 55 end, switch_npc=aeryn_alive(), jump="distant-sun-stab"
  75 + },
  76 + {_t"#LIGHT_GREEN#[In a last incredible display of willpower you fight the Distant Sun for a few seconds, unsure how to stop it.]#WHITE##{bold}#NO!#{normal}#",
  77 + switch_npc=shertul, cond=function(npc, player) return not void_portal_open(nil, player) and not aeryn_alive(npc, player) and player:getWil() >= 55 end, jump="distant-sun-shertul"
  78 + },
  79 + }
  80 +}
  81 +
  82 +newChat{ id="distant-sun-stab",
  83 + text = _t[[<<<Through your mind Aeryn sees what the Distant Sun is planning.>>>
  84 +You were a precious ally and a friend. The world will remember your last act of selfless sacrifice. I swear it.
  85 +<<<As she says this she pierces your body with a mighty thrust of her sword, ending the plans of your mad patron.>>>
  86 +]],
  87 + answers = {
  88 + {_t"#LIGHT_GREEN#[slip peacefully into death.]", action=function(npc, player)
  89 + player.no_resurrect = true
  90 + player:die(player, {special_death_msg=("sacrificing %s to stop the mad sun's plans"):tformat(string.his_her_self(player))})
  91 + player:setQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun-stab")
  92 + player:hasQuest("high-peak"):win("distant-sun-selfless")
  93 + end},
  94 + }
  95 +}
  96 +
  97 +newChat{ id="distant-sun-shertul",
  98 + text = _t[[<<<The precious seconds fly by, but as you feel your mind breaking and burning you see a strange figure appearing in front of you, it radiates of immense power.>>>
  99 +<<<The strange, amorphous figure in front of you remains completely silent. With a gesture of one of its tendrils, the staff is ripped from your hands. A surge of energy goes through the room as it grips the staff. Then you remember the old myth of the Godslayers. This is none other than a ***Sher'Tul***#{italic}#, and it knows you have been colluding with a god. That alone tells you everything you need to know.>>>
  100 +]],
  101 + answers = {
  102 + {_t"#CRIMSON#[Your mind is burnt by your patron sun! Fight for your sun god now!]", action=function(npc, player)
  103 + player.no_resurrect = true
  104 + game.level.data.no_worldport = true
  105 + game.zone.no_worldport = true
  106 + local who, o, item, inven_id = game.party:findInAllInventoriesBy("define_as", "STAFF_ABSORPTION_AWAKENED")
  107 + if who and o then
  108 + who:removeObject(inven_id, item, true)
  109 + end
  110 + local x, y = util.findFreeGrid(player.x, player.y, 100, true, {[engine.Map.ACTOR]=true})
  111 + if x then
  112 + game.zone:addEntity(game.level, shertul, "actor", x, y)
  113 + shertul:setTarget(player)
  114 + shertul:setPersonalReaction(player, -100)
  115 + end
  116 + player.on_die = function()
  117 + game:onTickEnd(function()
  118 + player:setQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun-shertul")
  119 + player:hasQuest("high-peak"):win("distant-sun-shertul")
  120 + end)
  121 + end
  122 + end},
  123 + }
  124 +}
  125 +
  126 +return "welcome"
  127 +end
  128 +
  129 +--------------------------------------------------------
35 130 -- Yeeks have a .. plan
36 131 --------------------------------------------------------
37 132 if p.descriptor.race == "Yeek" then
... ... @@ -68,7 +163,7 @@ You will do as asked, for the good of all Yeeks! The Way is always right.
68 163 player:hasQuest("high-peak"):win("yeek-sacrifice")
69 164 end},
70 165 {_t"#LIGHT_GREEN#[In a last incredible display of willpower you fight the Way for a few seconds, letting you project your thoughts to Aeryn.]#WHITE# High Lady! Kill me #{bold}#NOW#{normal}#",
71   - cond=function(npc, player) return not void_portal_open(nil, player) and aeryn_alive(npc, player) and player:getWil() >= 55 end, jump="yeek-stab"
  166 + cond=function(npc, player) return not void_portal_open(nil, player) and aeryn_alive(npc, player) and player:getWil() >= 55 end, switch_npc=aeryn_alive(), jump="yeek-stab"
72 167 },
73 168 }
74 169 }
... ... @@ -103,7 +198,7 @@ newChat{ id="welcome",
103 198 But the portal to the Void is already open. It must be closed before the Creator can come through or all will have been in vain!
104 199 After searching the remains of the Sorcerers you find a note explaining that the portal can only be closed with a sentient being's sacrifice.]],
105 200 answers = {
106   - {_t"Aeryn, I am sorry but one of us needs to be sacrificed for the world to go on. #LIGHT_GREEN#[sacrifice Aeryn for the sake of the world]", jump="aeryn-sacrifice", cond=aeryn_alive},
  201 + {_t"Aeryn, I am sorry but one of us needs to be sacrificed for the world to go on. #LIGHT_GREEN#[sacrifice Aeryn for the sake of the world]", jump="aeryn-sacrifice", switch_npc=aeryn_alive(), cond=aeryn_alive},
107 202 {_t"I will close it. #LIGHT_GREEN#[sacrifice yourself for the sake of the world]", action=function(npc, player)
108 203 player.no_resurrect = true
109 204 player:die(player, {special_death_msg=("sacrificing %s for the sake of the world"):tformat(string.his_her_self(player))})
... ... @@ -135,7 +230,7 @@ newChat{ id="welcome",
135 230 You have won the game!
136 231 Both Maj'Eyal and the Far East are safe from the dark schemes of the Sorcerers and their God.]],
137 232 answers = {
138   - {_t"Aeryn, are you well?", jump="aeryn-ok", cond=aeryn_alive},
  233 + {_t"Aeryn, are you well?", jump="aeryn-ok", switch_npc=aeryn_alive(), cond=aeryn_alive},
139 234 {_t"[leave]", action=function(npc, player) player:hasQuest("high-peak"):win("full") end},
140 235 }
141 236 }
... ...
... ... @@ -81,7 +81,7 @@ He who felt great sorrow for this world. He who shall now shatter the barriers o
81 81 The staff has allowed us to drain enough energy from this world to open the portal to the Void and summon Him through!
82 82 It is already too late. He is coming through as we speak -- it is only a matter of hours!]],
83 83 answers = {
84   - {_t"I *WILL* stop you! The world will not end today!", jump="aeryn", switch_npc={name=_t"High Sun Paladin Aeryn"}, action=aeryn_comes, cond=aeryn_alive},
  84 + {_t"I *WILL* stop you! The world will not end today!", jump="aeryn", switch_npc={name=_t"High Sun Paladin Aeryn", image="npc/humanoid_human_high_sun_paladin_aeryn.png"}, action=aeryn_comes, cond=aeryn_alive},
85 85 {_t"I *WILL* stop you! The world will not end today!", cond=aeryn_dead},
86 86 }
87 87 }
... ... @@ -92,7 +92,7 @@ He who felt great sorrow for this world. He who shall now shatter the barriers o
92 92 The staff will allow us to drain enough energy from this world to open the portal to the Void and summon Him through!
93 93 You cannot stop us now!]],
94 94 answers = {
95   - {_t"I *WILL* stop you! The world will not end today!", jump="aeryn", switch_npc={name=_t"High Sun Paladin Aeryn"}, action=aeryn_comes, cond=aeryn_alive},
  95 + {_t"I *WILL* stop you! The world will not end today!", jump="aeryn", switch_npc={name=_t"High Sun Paladin Aeryn", image="npc/humanoid_human_high_sun_paladin_aeryn.png"}, action=aeryn_comes, cond=aeryn_alive},
96 96 {_t"I *WILL* stop you! The world will not end today!", cond=aeryn_dead},
97 97 }
98 98 }
... ...
... ... @@ -59,6 +59,7 @@ local changer = function(id)
59 59 ambient_music = "World of Ice.ogg",
60 60 reload_lists = false,
61 61 persistent = "zone",
  62 + in_orbit = true,
62 63
63 64 no_worldport = game.zone.no_worldport,
64 65 min_material_level = util.getval(game.zone.min_material_level),
... ...
... ... @@ -283,8 +283,8 @@ newEntity{ base = "BASE_LITE", define_as = "WINTERTIDE_PHIAL",
283 283 material_level = 2,
284 284
285 285 wielder = {
286   - lite = 1,
287   - infravision = 6,
  286 + lite = 2,
  287 + infravision = 7,
288 288 },
289 289
290 290 max_power = 60, power_regen = 1,
... ...
... ... @@ -501,7 +501,7 @@ newEntity{ base = "BASE_KNIFE",
501 501 dam = 45,
502 502 apr = 11,
503 503 physcrit = 18,
504   - dammod = {dex=0.55,str=0.35},
  504 + dammod = {dex=0.5,str=0.5},
505 505 },
506 506 wielder = {
507 507 lite = 1,
... ... @@ -1176,7 +1176,7 @@ newEntity{ base = "BASE_KNIFE", -- Thanks Grayswandir!
1176 1176 dam = 20,
1177 1177 apr = 10,
1178 1178 physcrit = 12,
1179   - dammod = {dex=0.45,str=0.45,},
  1179 + dammod = {dex=0.5,str=0.5,},
1180 1180 lifesteal = 6,
1181 1181 melee_project = {
1182 1182 [DamageType.FIRE] = 20,
... ...
... ... @@ -370,6 +370,7 @@ newEntity{ base = "BASE_LITE", define_as = "SUMMERTIDE_PHIAL",
370 370 desc = _t[[A small crystal phial that captured Sunlight during the Summertide.]],
371 371 special_desc = function(self) return _t"When attacking in melee, deals 15 light damage and lights tiles in radius 1." end,
372 372 cost = 200,
  373 + material_level = 1,
373 374
374 375 max_power = 15, power_regen = 1,
375 376 use_power = {
... ... @@ -848,7 +849,7 @@ newEntity{ base = "BASE_KNIFE",
848 849 dam = 25,
849 850 apr = 10,
850 851 physcrit = 8,
851   - dammod = {dex=0.55,str=0.35},
  852 + dammod = {dex=0.65,str=0.35},
852 853 no_stealth_break = true,
853 854 no_garrote = true,
854 855 melee_project={[DamageType.RANDOM_SILENCE] = 10},
... ... @@ -2966,7 +2967,7 @@ newEntity{ base = "BASE_KNIFE",
2966 2967 dam = 25,
2967 2968 apr = 10,
2968 2969 physcrit = 9,
2969   - dammod = {dex=0.45,str=0.45, mag=0.1},
  2970 + dammod = {dex=0.5,str=0.5, mag=0.15},
2970 2971 convert_damage = {
2971 2972 [DamageType.DARKNESS] = 50,
2972 2973 },
... ... @@ -6140,7 +6141,7 @@ Passed on and on, this blade has developed a thirst of its own.]],
6140 6141 dam = 27,
6141 6142 apr = 8,
6142 6143 physcrit = 9,
6143   - dammod = {str=0.45, dex=0.55, mag=0.05},
  6144 + dammod = {str=0.35, dex=0.55, mag=0.2},
6144 6145 talent_on_hit = { T_DISPERSE_MAGIC = {level=1, chance=15},},
6145 6146 special_on_hit = {desc=_t"steals up to 50 mana from the target", fct=function(combat, who, target)
6146 6147 local manadrain = util.bound(target:getMana(), 0, 50)
... ... @@ -8221,7 +8222,7 @@ Their killing spree ended when one of the victims got lucky and managed to stab
8221 8222 dam = 35,
8222 8223 apr = 10,
8223 8224 physcrit = 15,
8224   - dammod = {str=0.45, dex=0.45},
  8225 + dammod = {str=0.5, dex=0.5},
8225 8226 melee_project = { [DamageType.COLD]=30 },
8226 8227 special_on_crit = {desc=_t"freezes the target", fct=function(combat, who, target)
8227 8228 if not target or target == self then return end
... ...
... ... @@ -35,7 +35,7 @@ return {
35 35 system_rotation = dir, system_rotationv = 0,
36 36 generator = function()
37 37 return {
38   - life = 42,
  38 + life = 15,
39 39 --size = 30, sizev = 2.1*64*radius/16, sizea = 0,
40 40 size = 3.5*64*radius, sizev = 0, sizea = 0,
41 41
... ... @@ -47,7 +47,7 @@ return {
47 47 r = 1, rv = 0, ra = 0,
48 48 g = 1, gv = 0, ga = 0,
49 49 b = 1, bv = 0, ba = 0,
50   - a = 1, av = 0, aa = 0,
  50 + a = 0.7, av = 0, aa = 0,
51 51 }
52 52 end, },
53 53 function(self)
... ...
... ... @@ -51,7 +51,7 @@ defineTile('2', "FLOOR", {random_filter={type="ammo", add_levels=10, tome_mod="v
51 51
52 52 return {
53 53 [[XXXXXXXXXXXXXXXXX]],
54   -[[XE$..#.....#..$EX]],
  54 +[[XE$...........$EX]],
55 55 [[X$2$##..P..##$2$X]],
56 56 [[X.$##.......##$.X]],
57 57 [[X.##...X^X...##.X]],
... ... @@ -61,7 +61,7 @@ return {
61 61 [[X.T.^.#1D1#.^.T.X]],
62 62 [[X...XXX111XXX...X]],
63 63 [[X......X#X......X]],
64   -[[X##..e.X.X.e..##X]],
  64 +[[X.#..e.X.X.e..#.X]],
65 65 [[X.##...X^X...##.X]],
66 66 [[X.$##.......##$.X]],
67 67 [[X$2$##..P..##$2$X]],
... ...
... ... @@ -55,19 +55,19 @@ defineTile('O', "FLOOR", nil, {random_filter={add_levels=15, name="orc necromanc
55 55 defineTile('K', "FLOOR", nil, {random_filter={add_levels=5, type="undead", subtype="giant", special_rarity="bonegiant_rarity"}})
56 56
57 57 return {
58   -[[...............................]],
59   -[[.#############################.]],
60   -[[.#...................+...+.K\#.]],
61   -[[.#.......o....o......#####.o\#.]],
62   -[[.#......................K#.K\#.]],
63   -[[.#.....o.................#####.]],
64   -[[.#~~~.....o...###........#o.K#.]],
65   -[[.#~O~..o......%$#........+...X.]],
66   -[[.#~~~.........###........#o.K#.]],
67   -[[.#.......o..o............#####.]],
68   -[[.#......................K#.K(#.]],
69   -[[.#....o....o.........#####.o(#.]],
70   -[[.#...................+...+.K(#.]],
71   -[[.#############################.]],
72   -[[...............................]],
  58 +[[...........................]],
  59 +[[.#########################.]],
  60 +[[.#...............+...+.K\#.]],
  61 +[[.#......o...o....#####.o\#.]],
  62 +[[.#..................K#.K\#.]],
  63 +[[.#.....o.............#####.]],
  64 +[[.#~~~...o...###......#o.K#.]],
  65 +[[.#~O~..o.....$#......+...X.]],
  66 +[[.#~~~.......###......#o.K#.]],
  67 +[[.#.....o..o..........#####.]],
  68 +[[.#..................K#.K(#.]],
  69 +[[.#...o...o.......#####.o(#.]],
  70 +[[.#...............+...+.K(#.]],
  71 +[[.#########################.]],
  72 +[[...........................]],
73 73 }
... ...
... ... @@ -50,17 +50,17 @@ defineTile('d', "FLOOR", {random_filter={add_levels=15, tome_mod="gvault"}}, {ra
50 50 return {
51 51
52 52 [[########################]],
53   -[[#$$a/##.........c##d...#]],
  53 +[[#$$a/##.........c..d...#]],
54 54 [[#$$a##.........a.a##...#]],
55   -[[#ca##....^^^^^^.c.b%%..#]],
56   -[[#c%%.....^^^^^^.a.a.##.#]],
57   -[[###......^^^^^^c.a.ba###]],
58   -[[##.......^^^/^^.caaa...X]],
59   -[[###......^^^~^^caa.b.###]],
  55 +[[#ca##....^^^^^^.c.b##..#]],
  56 +[[#c##.....^^^^^^.a.a.##.#]],
  57 +[[#.#......^^^^^^c.a.ba###]],
  58 +[[#........^^^/^^.caaa...X]],
  59 +[[#.#......^^^~^^caa.b.###]],
60 60 [[#$##.....^~~~^^a..ba##d#]],
61 61 [[#$$##....^~^^^^.c.a##..#]],
62   -[[#aaa##............%%...#]],
63   -[[#aacc%%.........c##....#]],
  62 +[[#aaa##............##...#]],
  63 +[[#aacc##.........c......#]],
64 64 [[########################]],
65 65
66 66 }
\ No newline at end of file
... ...
... ... @@ -78,20 +78,21 @@ defineTile('!', "DOOR_VAULT")
78 78 defineTile('>', "DYNAMIC_ZONE_EXIT")
79 79
80 80
81   -defineTile('b', "FLOOR", {random_filter={add_levels=20, tome_mod="gvault"}}, {random_filter={add_levels=5, name="skeleton magus"}})
  81 +defineTile('b', "FLOOR", {random_filter={add_levels=15, tome_mod="gvault"}}, {random_filter={add_levels=5, name="skeleton magus"}})
82 82 defineTile('$', "FLOOR", {random_filter={add_levels=25, type="money"}})
83   -defineTile('j', "FLOOR", {random_filter={add_levels=10, type="jewelry", tome_mod="gvault"}})
84   -defineTile('t', "FLOOR", {random_filter={add_levels=5, tome_mod="gvault"}}, turret())
  83 +defineTile('j', "FLOOR", {random_filter={add_levels=5, type="jewelry", tome_mod="vault"}})
  84 +defineTile('J', "FLOOR", {random_filter={add_levels=10, type="jewelry", tome_mod="gvault"}})
  85 +defineTile('t', "FLOOR", {random_filter={add_levels=5, tome_mod="vault"}}, turret())
85 86
86 87 local def = {
87 88 [[##############]],
88   -[[#tjj##########]],
  89 +[[#tjJ##########]],
89 90 [[#b$$##########]],
90 91 [[##.##t$..t####]],
91 92 [[#t.+...>..####]],
92 93 [[##.##...$.####]],
93 94 [[#b$$#$...t####]],
94   -[[#tjj##########]],
  95 +[[#tjJ##########]],
95 96 [[##############]],
96 97 }
97 98
... ...
... ... @@ -74,7 +74,7 @@ next_combat = function(self)
74 74
75 75 if not self:isEnded() then
76 76 local Chat = require "engine.Chat"
77   - local chat = Chat.new("antimagic-end", {name=_t"Grim-looking fighter"}, game.player)
  77 + local chat = Chat.new("antimagic-end", {name=_t"Grim-looking fighter", image="portrait/antimagic.png"}, game.player)
78 78 chat:invoke()
79 79 end
80 80 end
... ...
... ... @@ -123,6 +123,9 @@ function win(self, how)
123 123 elseif how == "self-sacrifice" then world:gainAchievement("WIN_SACRIFICE", game.player)
124 124 elseif how == "yeek-sacrifice" then world:gainAchievement("YEEK_SACRIFICE", game.player)
125 125 elseif how == "yeek-selfless" then world:gainAchievement("YEEK_SELFLESS", game.player)
  126 + elseif how == "distant-sun" then world:gainAchievement("AOADS_BURN", game.player)
  127 + elseif how == "distant-sun-selfless" then world:gainAchievement("AOADS_SELFLESS", game.player)
  128 + elseif how == "distant-sun-shertul" then world:gainAchievement("AOADS_SHERTUL", game.player)
126 129 end
127 130
128 131 local p = game:getPlayer(true)
... ... @@ -177,6 +180,24 @@ function onWin(self, who)
177 180 desc[#desc+1] = _t"The Sorcerers are dead, and the Orc Pride lies in ruins, thanks to your efforts."
178 181 desc[#desc+1] = _t""
179 182
  183 + -- Avatars are special
  184 + if who:isQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun") then
  185 + desc[#desc+1] = _t"Your patron's plan worked. As your body was crushed by the raw forces of the void portal it opened wide. In an instant the connection was made and waves of heat came through."
  186 + desc[#desc+1] = _t"The mad sun brought forth all its power through the portal, turning the High Peak into a giant searing needle!"
  187 + desc[#desc+1] = _t"A few minutes later the whole world was set ablaze, nothing survived except Faeros elementals."
  188 + return 0, desc
  189 + elseif who:isQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun-stab") then
  190 + desc[#desc+1] = _t"In the aftermath of the battle the Distant Sun tried to force you to open the portal to bring it forth onto Eyal."
  191 + desc[#desc+1] = _t"Through an incredible display of willpower you resisted long enough to ask Aeryn to kill you."
  192 + desc[#desc+1] = _t"She sadly agreed and ran her sword through you, enabling you to do the last sacrifice you could for the world."
  193 + return 0, desc
  194 + elseif who:isQuestStatus("high-peak", engine.Quest.COMPLETED, "distant-sun-shertul") then
  195 + desc[#desc+1] = _t"In the aftermath of the battle the Distant Sun tried to force you to open the portal to bring it forth onto Eyal."
  196 + desc[#desc+1] = _t"Through an incredible display of willpower you resisted for a few decisive seconds. During this time a Sher'tul appeared, took the Staff and killed you."
  197 + desc[#desc+1] = _t"Though you succumbed to the fight, your mind was already gone, burnt to ashes by your mad patron sun. But the world was saved."
  198 + return 0, desc
  199 + end
  200 +
180 201 -- Yeeks are special
181 202 if who:isQuestStatus("high-peak", engine.Quest.COMPLETED, "yeek") then
182 203 desc[#desc+1] = _t"Your sacrifice worked. Your mental energies were imbued with farportal energies. The Way radiated from the High Peak toward the rest of Eyal like a mental tidal wave."
... ...
... ... @@ -77,7 +77,7 @@ kill_one = function(self)
77 77
78 78 if self.kill_count >= self.max_count then
79 79 local Chat = require "engine.Chat"
80   - local chat = Chat.new("derth-attack-over", {name=_t"Scared Halfling"}, game.player)
  80 + local chat = Chat.new("derth-attack-over", {name=_t"Scared Halfling", image="portrait/derth_attack_over.png"}, game.player)
81 81 chat:invoke()
82 82
83 83 if not game.zone.unclean_derth_savior then
... ...
... ... @@ -20,7 +20,7 @@
20 20 name = _t"Following The Way"
21 21 desc = function(self, who)
22 22 local desc = {}
23   - desc[#desc+1] = _t"You have been tasked to remove at leastg one of the threats to the yeeks.\n"
  23 + desc[#desc+1] = _t"You have been tasked to remove at least one of the threats to the yeeks.\n"
24 24 desc[#desc+1] = _t"Protect the Way, and vanquish your foes.\n"
25 25 if self:isCompleted("murgol") then
26 26 if self:isCompleted("murgol-invaded") then
... ...
... ... @@ -18,6 +18,48 @@
18 18 -- darkgod@te4.org
19 19
20 20 newTalent{
  21 + name = "Gravitic Effulgence",
  22 + type = {"celestial/other", 1},
  23 + mode = "sustained",
  24 + points = 1,
  25 + cooldown = 10,
  26 + tactical = { BUFF = 2 },
  27 + range = 10,
  28 + getShieldFlat = function(self, t)
  29 + return t.getDamage(self, t)
  30 + end,
  31 + activate = function(self, t)
  32 + game:onTickEnd(function()
  33 + if self:isTalentActive(self.T_WEAPON_OF_LIGHT) then
  34 + self.turn_procs.resetting_talents = true
  35 + self:forceUseTalent(self.T_WEAPON_OF_LIGHT, {ignore_energy=true, ignore_cd=true, no_talent_fail=true})
  36 + self:forceUseTalent(self.T_WEAPON_OF_LIGHT, {ignore_energy=true, ignore_cd=true, no_talent_fail=true, talent_reuse=true})
  37 + self.turn_procs.resetting_talents = nil
  38 + end
  39 + end)
  40 +
  41 + game:playSoundNear(self, "talents/spell_generic2")
  42 + local ret = {}
  43 + return ret
  44 + end,
  45 + deactivate = function(self, t, p)
  46 + game:onTickEnd(function()
  47 + if self:isTalentActive(self.T_WEAPON_OF_LIGHT) then
  48 + self.turn_procs.resetting_talents = true
  49 + self:forceUseTalent(self.T_WEAPON_OF_LIGHT, {ignore_energy=true, ignore_cd=true, no_talent_fail=true})
  50 + self:forceUseTalent(self.T_WEAPON_OF_LIGHT, {ignore_energy=true, ignore_cd=true, no_talent_fail=true, talent_reuse=true})
  51 + self.turn_procs.resetting_talents = nil
  52 + end
  53 + end)
  54 +
  55 + return true
  56 + end,
  57 + info = function(self, t)
  58 + return ([[Your Weapon of Light nows pulls in all foes in radius 5.]]):tformat()
  59 + end,
  60 +}
  61 +
  62 +newTalent{
21 63 name = "Weapon of Light",
22 64 type = {"celestial/combat", 1},
23 65 mode = "sustained",
... ... @@ -27,19 +69,18 @@ newTalent{
27 69 sustain_positive = 10,
28 70 tactical = { BUFF = 2 },
29 71 range = 10,
30   - getDamage = function(self, t) return 7 + self:combatSpellpower(0.092) * self:combatTalentScale(t, 1, 7) end,
  72 + getDamage = function(self, t) return (7 + self:combatSpellpower(0.092) * self:combatTalentScale(t, 1, 7)) end,
31 73 getShieldFlat = function(self, t)
32 74 return t.getDamage(self, t)
33 75 end,
34 76 activate = function(self, t)
35 77 game:playSoundNear(self, "talents/spell_generic2")
36   - local ret = {
37   - dam = self:addTemporaryValue("melee_project", {[DamageType.LIGHT]=t.getDamage(self, t)}),
38   - }
  78 + local ret = {}
  79 + if not self:isTalentActive(self.T_GRAVITIC_EFFULGENCE) then ret.dam = self:addTemporaryValue("melee_project", {[DamageType.LIGHT]=t.getDamage(self, t)}) end
39 80 return ret
40 81 end,
41 82 deactivate = function(self, t, p)
42   - self:removeTemporaryValue("melee_project", p.dam)
  83 + if p.dam then self:removeTemporaryValue("melee_project", p.dam) end
43 84 return true
44 85 end,
45 86 callbackOnMeleeAttack = function(self, t, target, hitted, crit, weapon, damtype, mult, dam)
... ... @@ -55,6 +96,14 @@ newTalent{
55 96 self.damage_shield_absorb_max = self.damage_shield_absorb_max + shield_power
56 97 shield.dur = math.max(2, shield.dur)
57 98 end
  99 + if hitted and self:isTalentActive(self.T_GRAVITIC_EFFULGENCE) then
  100 + local list = table.values(self:projectCollect({type="ball", radius=5, x=target.x, y=target.y, friendlyfire=false}, target.x, target.y, Map.ACTOR))
  101 + table.sort(list, "dist")
  102 + for _, l in ipairs(list) do
  103 + if l.target:canBe("knockback") then l.target:pull(target.x, target.y, 5) end
  104 + end
  105 + self:project({type="ball", radius=2, x=target.x, y=target.y, friendlyfire=false}, target.x, target.y, DamageType.LIGHT, t.getDamage(self, t))
  106 + end
58 107 end,
59 108 info = function(self, t)
60 109 local damage = t.getDamage(self, t)
... ...
... ... @@ -227,3 +227,29 @@ newTalent{
227 227 tformat(weapon, shield, cooldown, cleanse)
228 228 end,
229 229 }
  230 +
  231 +
  232 +
  233 +newTalent{
  234 + name = "Avatar Distant Sun Unlock Checker", short_name = "AVATAR_DISTANT_SUN_UNLOCK_CHECKER", image = "talents/avatar_of_a_distant_sun.png",
  235 + type = {"celestial/other",1},
  236 + mode = "passive",
  237 + hide = "always",
  238 + no_unlearn_last = true,
  239 + callbackOnAct = function(self, t)
  240 + if not game.zone or not game.zone.in_orbit then return end
  241 + if not rng.chance(30) then return end
  242 +
  243 + local chat = require("engine.Chat").new("avatar-distant-sun-unlock", t, self)
  244 + chat:invoke()
  245 + end,
  246 + doUnlock = function(self, t)
  247 + game:setAllowedBuild("paladin_avatar", true)
  248 + self:unlearnTalent(self.T_AVATAR_DISTANT_SUN_UNLOCK_CHECKER)
  249 + self:project({type="ball", radius=20, friendlyfire=false}, self.x, self.y, DamageType.FIRE, 5000)
  250 + game.level.map:particleEmitter(x, y, 20, "fireflash", {radius=20, proj_x=self.x, proj_y=self.y, src_x=self.x, src_y=self.y})
  251 + end,
  252 + info = function(self, t)
  253 + return "Move along, nothing to see" -- No need to translate
  254 + end,
  255 +}
... ...
... ... @@ -112,8 +112,8 @@ newTalent{
112 112 range = function(self) return radianceRadius(self) end,
113 113 tactical = { ATTACKAREA = {LIGHT=1} },
114 114 sustain_positive = 10,
115   - getDamage = function(self, t) return self:combatTalentSpellDamage(t, 3, 35) end,
116   - getDaze = function(self, t) return self:combatTalentLimit(t, 35, 8, 25) end,
  115 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 3, 35) * (self:attr("sun_paladin_avatar") and 2 or 1) end,
  116 + getDaze = function(self, t) return self:combatTalentLimit(t, 35, 8, 25) * (self:attr("sun_paladin_avatar") and 2 or 1) end,
117 117 updateParticle = function(self, t)
118 118 local p = self:isTalentActive(self.T_SEARING_SIGHT)
119 119 if not p then return end
... ...
... ... @@ -152,6 +152,9 @@ newTalent{
152 152 if self.talents_cd[self.T_SUN_BEAM] <= 0 then self.talents_cd[self.T_SUN_BEAM] = nil end
153 153 else
154 154 self:setEffect(self.EFF_SUN_VENGEANCE, 2, {})
  155 + if self:attr("sun_paladin_avatar") then
  156 + self:alterTalentCoolingdown(self.T_JUDGEMENT, -6)
  157 + end
155 158 end
156 159 end,
157 160 info = function(self, t)
... ...
... ... @@ -41,7 +41,7 @@ newTalent{
41 41 return true
42 42 end,
43 43 info = function(self, t)
44   - return ([[Increases your spell critical damage multiplier by %d%%.
  44 + return ([[Increases your critical damage multiplier by %d%%.
45 45 The multiplier will increase with your Spellpower.]]):
46 46 tformat(self:combatTalentSpellDamage(t, 20, 50))
47 47 end,
... ...
... ... @@ -162,8 +162,8 @@ newTalent{
162 162 range = 1,
163 163 target = function(self, t) return {type="hit", range=self:getTalentRange(t)}<