Showing
31 changed files
with
269 additions
and
20 deletions
... | ... | @@ -18,7 +18,6 @@ |
18 | 18 | -- darkgod@te4.org |
19 | 19 | |
20 | 20 | require "engine.class" |
21 | -require "engine.dialogs.Chat" | |
22 | 21 | require "Json2" |
23 | 22 | local slt2 = require "slt2" |
24 | 23 | |
... | ... | @@ -26,6 +25,7 @@ local slt2 = require "slt2" |
26 | 25 | -- @classmod engine.Chat |
27 | 26 | module(..., package.seeall, class.make) |
28 | 27 | |
28 | +_M.chat_dialog = "engine.dialogs.Chat" | |
29 | 29 | _M.chat_context_strings = {"#{italic}##LIGHT_GREEN#", "#LAST##{normal}#"} |
30 | 30 | _M.chat_bold_strings = {"#{bold}#", "#{normal}#"} |
31 | 31 | |
... | ... | @@ -413,7 +413,7 @@ function _M:invoke(id) |
413 | 413 | local hd = {"Chat:invoke", id = id or self.default_id } |
414 | 414 | self:triggerHook(hd) |
415 | 415 | |
416 | - local d = engine.dialogs.Chat.new(self, hd.id, self.force_dialog_width or 500) | |
416 | + local d = require(self.chat_dialog).new(self, hd.id, self.force_dialog_width or 500) | |
417 | 417 | game:registerDialog(d) |
418 | 418 | return d |
419 | 419 | end | ... | ... |
... | ... | @@ -37,17 +37,29 @@ function _M:init(chat, id, width) |
37 | 37 | self.npc = chat.npc |
38 | 38 | self.player = chat.player |
39 | 39 | self.no_offscreen = "bottom" |
40 | - Dialog.init(self, self.npc.getName and self.npc:getName() or self.npc.name, width or 500, 400) | |
40 | + Dialog.init(self, self.force_title or (self.npc.getName and self.npc:getName() or self.npc.name), width or 500, 400) | |
41 | 41 | |
42 | + self:generateList() | |
43 | + | |
44 | + self:makeUI() | |
45 | + | |
46 | + self.key:addCommands{ | |
47 | + __TEXTINPUT = function(c) | |
48 | + if self.list and self.list.chars[c] then | |
49 | + self:use(self.list[self.list.chars[c]]) | |
50 | + end | |
51 | + end, | |
52 | + } | |
53 | +end | |
54 | + | |
55 | +function _M:makeUI() | |
42 | 56 | local xoff = 0 |
43 | 57 | if self.show_portraits then |
44 | 58 | xoff = 64 |
45 | 59 | end |
46 | 60 | |
47 | - self:generateList() | |
48 | - | |
49 | - self.c_desc = Textzone.new{font=chat.dialog_text_font, width=self.iw - 10 - xoff, height=1, auto_height=true, text=self.text.."\n"} | |
50 | - self.c_list = VariableList.new{font=chat.dialog_answer_font, width=self.iw - 10 - xoff, max_height=game.h * 0.70 - self.c_desc.h, list=self.list, fct=function(item) self:use(item) end, select=function(item) self:select(item) end} | |
61 | + self.c_desc = Textzone.new{font=self.chat.dialog_text_font, width=self.iw - 10 - xoff, height=1, auto_height=true, text=self.text.."\n", can_focus=false} | |
62 | + self.c_list = VariableList.new{font=self.chat.dialog_answer_font, width=self.iw - 10 - xoff, max_height=game.h * 0.70 - self.c_desc.h, list=self.list, fct=function(item) self:use(item) end, select=function(item) self:select(item) end} | |
51 | 63 | |
52 | 64 | local uis = { |
53 | 65 | {left=0, top=0, ui=self.c_desc}, |
... | ... | @@ -64,14 +76,6 @@ function _M:init(chat, id, width) |
64 | 76 | self:loadUI(uis) |
65 | 77 | self:setFocus(self.c_list) |
66 | 78 | self:setupUI(false, true) |
67 | - | |
68 | - self.key:addCommands{ | |
69 | - __TEXTINPUT = function(c) | |
70 | - if self.list and self.list.chars[c] then | |
71 | - self:use(self.list[self.list.chars[c]]) | |
72 | - end | |
73 | - end, | |
74 | - } | |
75 | 79 | end |
76 | 80 | |
77 | 81 | function _M:on_register() |
... | ... | @@ -121,7 +125,7 @@ function _M:use(item, a) |
121 | 125 | end |
122 | 126 | |
123 | 127 | function _M:regen() |
124 | - local d = new(self.chat, self.cur_id, self.force_width) | |
128 | + local d = require(self.chat.chat_dialog).new(self.chat, self.cur_id, self.force_width) | |
125 | 129 | d.__showup = false |
126 | 130 | game:replaceDialog(self, d) |
127 | 131 | self.next_dialog = d | ... | ... |
... | ... | @@ -29,6 +29,8 @@ function _M:init(t) |
29 | 29 | self.actor = assert(t.actor, "no actorframe actor") |
30 | 30 | self.w = assert(t.w, "no actorframe w") |
31 | 31 | self.h = assert(t.h, "no actorframe h") |
32 | + self.allow_cb = t.allow_cb | |
33 | + self.allow_shader = t.allow_shader | |
32 | 34 | self.tiles = t.tiles or Tiles.new(self.w, self.h, nil, nil, true, nil) |
33 | 35 | |
34 | 36 | Base.init(self, t) |
... | ... | @@ -45,9 +47,9 @@ function _M:display(x, y, nb_keyframes, ox, oy) |
45 | 47 | local o = self.actor |
46 | 48 | if o and o.toScreen then |
47 | 49 | if o.image then |
48 | - o:toScreen(self.tiles, x, y, self.w, self.h) | |
50 | + o:toScreen(self.tiles, x, y, self.w, self.h, nil, self.allow_cb, self.allow_shader) | |
49 | 51 | elseif o.image and o.add_mos then |
50 | - o:toScreen(self.tiles, x, y - h, self.w, self.h * 2) | |
52 | + o:toScreen(self.tiles, x, y - h, self.w, self.h * 2, nil, self.allow_cb, self.allow_shader) | |
51 | 53 | end |
52 | 54 | end |
53 | 55 | ... | ... |
... | ... | @@ -399,6 +399,8 @@ function _M:init(title, w, h, x, y, alpha, font, showup, skin) |
399 | 399 | self.frame.ox2 = self.frame.ox2 or conf.frame_ox2 |
400 | 400 | self.frame.oy1 = self.frame.oy1 or conf.frame_oy1 |
401 | 401 | self.frame.oy2 = self.frame.oy2 or conf.frame_oy2 |
402 | + if not self.force_min_w and conf.force_min_w then self.force_min_w = conf.force_min_w end | |
403 | + if not self.force_min_h and conf.force_min_h then self.force_min_h = conf.force_min_h end | |
402 | 404 | |
403 | 405 | if self.frame.dialog_h_middles then |
404 | 406 | local t = type(self.frame.dialog_h_middles) == "table" and table.clone(self.frame.dialog_h_middles) or {} |
... | ... | @@ -589,6 +591,17 @@ function _M:setupUI(resizex, resizey, on_resize, addmw, addmh) |
589 | 591 | |
590 | 592 | mh = mh + addh + 5 + 22 + 3 + (addmh or 0) + th + padding |
591 | 593 | |
594 | + if self.force_min_h then | |
595 | + mh = mh - self.frame.oy1 + self.frame.oy2 | |
596 | + mh = math.max(mh, self.force_min_h) | |
597 | + mh = mh + self.frame.oy1 - self.frame.oy2 | |
598 | + end | |
599 | + if self.force_min_w then | |
600 | + mw = mw - self.frame.ox1 + self.frame.ox2 | |
601 | + mw = math.max(mw, self.force_min_w) | |
602 | + mw = mw + self.frame.ox1 - self.frame.ox2 | |
603 | + end | |
604 | + | |
592 | 605 | if on_resize then on_resize(resizex and mw or self.w, resizey and mh or self.h) end |
593 | 606 | nw, nh = resizex and mw or self.w, resizey and mh or self.h |
594 | 607 | else | ... | ... |
... | ... | @@ -2078,11 +2078,14 @@ function _M:setupCommands() |
2078 | 2078 | print("===============") |
2079 | 2079 | end end, |
2080 | 2080 | [{"_g","ctrl"}] = function() if config.settings.cheat then |
2081 | + package.loaded["engine.ui.Dialog"] = nil | |
2081 | 2082 | package.loaded["engine.dialogs.Chat"] = nil |
2083 | + package.loaded["mod.dialogs.Chat"] = nil | |
2084 | + package.loaded["mod.dialogs.elements.ChatPortrait"] = nil | |
2082 | 2085 | package.loaded["engine.Chat"] = nil |
2083 | 2086 | local Chat = require "engine.Chat" |
2084 | - engine.dialogs.Chat.show_portraits = true | |
2085 | - local chat = Chat.new("tareyal+test", game.player, game.player) | |
2087 | + Chat.chat_dialog = "mod.dialogs.Chat" | |
2088 | + local chat = Chat.new("tareyal+test", engine.Entity.new{name=_t"Imperium courrier", image="npc/undead_risen_mistress_vira.png"}, game.player) | |
2086 | 2089 | chat:invoke() |
2087 | 2090 | do return end |
2088 | 2091 | DamageType:get(DamageType.ACID).projector(game.player, game.player.x, game.player.y, DamageType.ACID, 100) | ... | ... |
... | ... | @@ -423,6 +423,7 @@ function _M:act() |
423 | 423 | if self:enoughEnergy() then |
424 | 424 | game.paused = true |
425 | 425 | if game.uiset.logdisplay:getNewestLine() ~= "" then game.log("") end |
426 | + if config.settings.cheat then game.log("Game Turn %d", game.turn) end | |
426 | 427 | end |
427 | 428 | elseif not self.player then |
428 | 429 | self:useEnergy() | ... | ... |

5.8 KB

5.45 KB

5.76 KB

5.55 KB

5.45 KB

5.66 KB

5.82 KB

5.43 KB

5.79 KB

31.9 KB

35.9 KB

1.94 KB

1.65 KB

1.96 KB

1.41 KB

1.25 KB

1.4 KB

1.97 KB

2.05 KB

1.94 KB
1 | +-- ToME - Tales of Maj'Eyal | |
2 | +-- Copyright (C) 2009 - 2019 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 | +chat = { | |
21 | + frame_alpha = 1, | |
22 | + frame_darkness = 0.6, | |
23 | + frame_ox1 = -64, | |
24 | + frame_ox2 = 64, | |
25 | + frame_oy1 = -5, | |
26 | + frame_oy2 = 10, | |
27 | + -- force_min_w = 64 * 4, | |
28 | + -- force_min_h = 64 * 4, | |
29 | +} | ... | ... |
game/modules/tome/dialogs/Chat.lua
0 → 100644
1 | +-- TE4 - T-Engine 4 | |
2 | +-- Copyright (C) 2009 - 2019 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 Chat = require "engine.dialogs.Chat" | |
22 | +local VariableList = require "engine.ui.VariableList" | |
23 | +local Textzone = require "engine.ui.Textzone" | |
24 | +local Separator = require "engine.ui.Separator" | |
25 | +local ChatPortrait = require "mod.dialogs.elements.ChatPortrait" | |
26 | +local Map = require "engine.Map" | |
27 | +local Entity = require "engine.Entity" | |
28 | + | |
29 | +module(..., package.seeall, class.inherit(Chat)) | |
30 | + | |
31 | +function _M:init(chat, id, width) | |
32 | + self.ui = "chat" | |
33 | + self.force_title = "" | |
34 | + self.force_min_h = 256 | |
35 | + | |
36 | + Chat.init(self, chat, id, math.max(width, game.w * 0.4)) | |
37 | +end | |
38 | + | |
39 | +function _M:makeUI() | |
40 | + self.c_desc = Textzone.new{has_box=true, ui="chat", font=self.chat.dialog_text_font, width=self.iw, height=1, auto_height=true, text=self.text, can_focus=false} | |
41 | + self.c_list = VariableList.new{font=self.chat.dialog_answer_font, width=self.iw, max_height=game.h * 0.70 - self.c_desc.h, list=self.list, fct=function(item) self:use(item) end, select=function(item) self:select(item) end} | |
42 | + local npc_frame = ChatPortrait.new{ui="chat", actor=self:getActorPortrait(self.npc.chat_display_entity or self.npc)} | |
43 | + local player_frame = ChatPortrait.new{ui="chat", actor=self:getActorPortrait(self.player.chat_display_entity or self.player)} | |
44 | + | |
45 | + local uis = { | |
46 | + {hcenter=0, top=-12, ui=self.c_desc}, | |
47 | + {right=0, bottom=0, ui=self.c_list}, | |
48 | + {left=-player_frame.w+self.frame.ox1-5, vcenter=-self.ix-4, ui=player_frame, ignore_size=true}, | |
49 | + {right=-npc_frame.w-self.frame.ox2-5, vcenter=-self.ix-4, ui=npc_frame, ignore_size=true}, | |
50 | + } | |
51 | + | |
52 | + self:loadUI(uis) | |
53 | + self:setFocus(self.c_list) | |
54 | + self:setupUI(false, true, function(w, h) | |
55 | + self.force_x = game.w / 2 - w / 2 | |
56 | + self.force_y = game.h - h - 20 | |
57 | + end) | |
58 | +end | |
59 | + | |
60 | +function _M:getActorPortrait(actor) | |
61 | + local actor = actor.replace_display or actor | |
62 | + | |
63 | + -- Moddable tiles are already portrait sized | |
64 | + if actor.moddable_tile and Map.tiles.no_moddable_tiles then return actor end | |
65 | + | |
66 | + -- No need for anything special | |
67 | + if actor.image:find("^portrait/") then return actor end | |
68 | + | |
69 | + -- Find the npc portrait | |
70 | + if actor.image == "invis.png" and actor.add_mos and actor.add_mos[1] and actor.add_mos[1].image and actor.add_mos[1].image:find("^npc/") and fs.exists("/data/gfx/shockbolt/"..actor.add_mos[1].image:gsub("^npc/", "portrait/")) then | |
71 | + return Entity.new{name=actor.name, image=actor.add_mos[1].image:gsub("^npc/", "portrait/")} | |
72 | + elseif actor.image:find("^npc/") and fs.exists("/data/gfx/shockbolt/"..actor.image:gsub("^npc/", "portrait/")) then | |
73 | + return Entity.new{name=actor.name, image=actor.image:gsub("^npc/", "portrait/")} | |
74 | + end | |
75 | + | |
76 | + -- Last resort, use it as it is | |
77 | + return actor | |
78 | +end | ... | ... |
1 | +-- TE4 - T-Engine 4 | |
2 | +-- Copyright (C) 2009 - 2019 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 Tiles = require "engine.Tiles" | |
22 | +local Base = require "engine.ui.Base" | |
23 | +local ActorFrame = require "engine.ui.ActorFrame" | |
24 | + | |
25 | +--- A generic UI image | |
26 | +-- @classmod engine.ui.Image | |
27 | +module(..., package.seeall, class.inherit(Base)) | |
28 | + | |
29 | +function _M:init(t) | |
30 | + assert(t.actor, "no ChatPortrait actor") | |
31 | + | |
32 | + self.name = t.actor.getName and t.actor:getName() or _t(t.actor.name) | |
33 | + if t.actor.moddable_tile then | |
34 | + self.actor_frame = ActorFrame.new{actor=t.actor, w=128, h=128, allow_cb=false, allow_shader=false} | |
35 | + elseif t.actor.image == "invis.png" and t.actor.add_mos and t.actor.add_mos[1] and t.actor.add_mos[1].image then | |
36 | + self.image = Tiles:loadImage(t.actor.add_mos[1].image) | |
37 | + else | |
38 | + self.image = Tiles:loadImage(t.actor.image) | |
39 | + end | |
40 | + if self.image then | |
41 | + local iw, ih = self.image:getSize() | |
42 | + if iw <= 64 then iw, ih = iw * 2, ih * 2 end | |
43 | + self.iw, self.ih = iw, ih | |
44 | + if self.image.getEmptyMargins then | |
45 | + local x1, x2, y1, y2 = self.image:getEmptyMargins() | |
46 | + self.iy = y1 | |
47 | + else | |
48 | + self.iy = 0 | |
49 | + end | |
50 | + else | |
51 | + self.iy = 0 | |
52 | + self.iw, self.ih = 128, 128 | |
53 | + end | |
54 | + | |
55 | + Base.init(self, t) | |
56 | +end | |
57 | + | |
58 | +function _M:generate() | |
59 | + self.mouse:reset() | |
60 | + self.key:reset() | |
61 | + | |
62 | + self.front = self:getUITexture("ui/portrait_frame_front.png") | |
63 | + self.back = self:getUITexture("ui/portrait_frame_back.png") | |
64 | + self.w, self.h = self.front.w, self.front.h | |
65 | + | |
66 | + if self.image then self.item = {self.image:glTexture(Tiles.sharp_scaling)} end | |
67 | + | |
68 | + self.name_tex = self:drawFontLine(self.font, self.name, nil, 0xff, 0xee, 0xcb) | |
69 | +end | |
70 | + | |
71 | +function _M:display(x, y, nb_keyframes, screen_x, screen_y) | |
72 | + self.back.t:toScreenFull(x, y, self.back.w, self.back.h, self.back.tw, self.back.th) | |
73 | + core.display.glScissor(true, screen_x + 15, screen_y + 15, 128, 192) | |
74 | + local dx, dy = x + 15 + (128 - self.iw) / 2, y + 15 + (192 - self.ih) / 2 | |
75 | + if self.actor_frame then | |
76 | + self.actor_frame:display(dx, dy - self.iy) | |
77 | + elseif self.item then | |
78 | + self.item[1]:toScreen(dx, dy - self.iy, self.iw, self.ih) | |
79 | + end | |
80 | + core.display.glScissor(false) | |
81 | + self.front.t:toScreenFull(x, y, self.front.w, self.front.h, self.front.tw, self.front.th) | |
82 | + | |
83 | + core.display.glScissor(true, screen_x + 4, screen_y + 229, 152, 23) | |
84 | + -- Center if it fits, left align is not | |
85 | + if self.name_tex.w <= 229 then | |
86 | + self:textureToScreen(self.name_tex, x + 80 - self.name_tex.w / 2, y + 240 - self.name_tex.h / 2) | |
87 | + else | |
88 | + self:textureToScreen(self.name_tex, x + 4, y + 240 - self.name_tex.h / 2) | |
89 | + end | |
90 | + core.display.glScissor(false) | |
91 | +end | ... | ... |
... | ... | @@ -243,6 +243,7 @@ Store:loadStores("/data/general/stores/basic.lua") |
243 | 243 | |
244 | 244 | -- Configure chat dialogs |
245 | 245 | require("engine.dialogs.Chat").show_portraits = true |
246 | +require("engine.Chat").chat_dialog = "mod.dialogs.Chat" | |
246 | 247 | |
247 | 248 | -- Inventory tabs |
248 | 249 | InventoryUI.default_tabslist = function(self) | ... | ... |
... | ... | @@ -1809,6 +1809,32 @@ static int sdl_load_image_mem(lua_State *L) |
1809 | 1809 | return 3; |
1810 | 1810 | } |
1811 | 1811 | |
1812 | +static int sdl_find_empty_margins(lua_State *L) { | |
1813 | + SDL_Surface **ss = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); | |
1814 | + SDL_Surface *s = *ss; | |
1815 | + | |
1816 | + int x1 = s->w, x2 = 0, y1 = s->h, y2 = 0; | |
1817 | + | |
1818 | + for (int x = 0; x < s->w; x++) { | |
1819 | + for (int y = 0; y < s->h; y++) { | |
1820 | + Uint32 *const target_pixel = (Uint32 *)((Uint8 *)s->pixels + y * s->pitch + x * s->format->BytesPerPixel); | |
1821 | + Uint8 r, g, b, a; | |
1822 | + SDL_GetRGBA(*target_pixel, s->format, &r, &g, &b, &a); | |
1823 | + if (a != 0) { | |
1824 | + if (x < x1) x1 = x; | |
1825 | + if (y > x2) x2 = x; | |
1826 | + if (y < y1) y1 = y; | |
1827 | + if (y > y2) y2 = y; | |
1828 | + } | |
1829 | + } | |
1830 | + } | |
1831 | + lua_pushnumber(L, x1); | |
1832 | + lua_pushnumber(L, x2); | |
1833 | + lua_pushnumber(L, y1); | |
1834 | + lua_pushnumber(L, y2); | |
1835 | + return 4; | |
1836 | +} | |
1837 | + | |
1812 | 1838 | static int sdl_free_surface(lua_State *L) |
1813 | 1839 | { |
1814 | 1840 | SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); |
... | ... | @@ -3534,6 +3560,7 @@ static const struct luaL_Reg sdl_surface_reg[] = |
3534 | 3560 | {"close", sdl_free_surface}, |
3535 | 3561 | {"erase", sdl_surface_erase}, |
3536 | 3562 | {"getSize", sdl_surface_get_size}, |
3563 | + {"getEmptyMargins", sdl_find_empty_margins}, | |
3537 | 3564 | {"merge", sdl_surface_merge}, |
3538 | 3565 | {"toScreen", sdl_surface_toscreen}, |
3539 | 3566 | {"toScreenWithTexture", sdl_surface_toscreen_with_texture}, | ... | ... |
-
Please register or login to post a comment