Skip to content
Snippets Groups Projects
Commit 5291ffc5 authored by dg's avatar dg
Browse files

Improved dialogs drawing code, should be a tad faster

git-svn-id: http://svn.net-core.org/repos/t-engine4@988 51575b47-30f0-44d4-a5cc-537603b46e54
parent 5218c38f
No related branches found
No related tags found
No related merge requests found
......@@ -96,7 +96,7 @@ function _M:init(title, w, h, x, y, alpha, font)
self.iw, self.ih = w - 2 * 5, h - 8 - 16 - 3
self.internal_surface = core.display.newSurface(self.iw, self.ih)
self.surface:alpha(alpha or 220)
self.texture = self.surface:glTexture()
self.texture, self.texture_w, self.texture_h = self.surface:glTexture()
self.changed = true
end
......@@ -123,35 +123,42 @@ function _M:display()
local tw, th = self.font:size(self.title)
s:drawColorStringBlended(self.font, self.title, (self.w - tw) / 2, 4, 255,255,255)
self.internal_surface:erase()
self:drawDialog(self.internal_surface)
s:merge(self.internal_surface, 5, 20 + 3)
-- Update texture
self.surface:updateTexture(self.texture)
return self.surface
end
function _M:addControl(control)
function _M:toScreen(x, y)
self.texture:toScreenFull(x, y, self.w, self.h, self.texture_w, self.texture_h)
end
function _M:addControl(control)
control.tabindex = self.tabindex
self.tabindex = self.tabindex + 1
self.controls[control.name] = control
self.tabindex = self.tabindex + 1
self.controls[control.name] = control
table.sort(self.controls, function(a,b) return a.tabindex<b.tabindex end)
end
function _M:changeFocus(up)
local add = 1
local add = 1
if not up then add = -1 end
self.currenttabindex = self.currenttabindex + add
if (self.currenttabindex==self.tabindex) then self.currenttabindex = 0 end
if (self.currenttabindex==self.tabindex) then self.currenttabindex = 0 end
if self.currenttabindex==-1 then self.currenttabindex=self.tabindex-1 end
local name = ""
for i, cntrl in pairs(self.controls) do
if cntrl.tabindex==self.currenttabindex then
if cntrl.tabindex==self.currenttabindex then
if self.controls[self.state] and self.controls[self.state].unFocus then self.controls[self.state]:unFocus() end
cntrl.focused=true
name=i
cntrl.focused=true
name=i
end
end
end
return name
end
......@@ -161,29 +168,25 @@ function _M:focusControl(focusOn)
for i, cntrl in pairs(self.controls) do
if i==focusOn then cntrl.focused=true self.state=i self.currenttabindex=cntrl.tabindex end
if i==oldstate and cntrl.unFocus then cntrl:unFocus() end
end
end
end
function _M:databind()
local result = { }
for i, cntrl in pairs(self.controls or { }) do
local result = { }
for i, cntrl in pairs(self.controls or { }) do
if cntrl.type and cntrl.type=="TextBox" then
result[cntrl.name] = cntrl.text
end
end
end
return result
end
function _M:drawControls(s)
for i, cntrl in pairs(self.controls or { }) do
function _M:drawControls(s)
for i, cntrl in pairs(self.controls or { }) do
cntrl:drawControl(s)
end
end
function _M:toScreen(x,y)
self.surface:toScreenWithTexture(self.texture,x,y)
end
end
function _M:drawDialog(s)
......
-- ToME - Tales of Middle-Earth
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local DamageType = require "engine.DamageType"
local Map = require "engine.Map"
local Chat = require "engine.Chat"
local Target = require "engine.Target"
local Talents = require "engine.interface.ActorTalents"
--- Interface to add ToME archery combat system
module(..., package.seeall, class.make)
--- Look for possible archery targets
-- Take care of removing enough ammo
function _M:archeryAcquireTargets(tg, params)
local weapon, ammo = self:hasArcheryWeapon()
if not weapon then
game.logPlayer(self, "You must wield a bow or a sling (%s)!", ammo)
return nil
end
params = params or {}
print("[ARCHERY AQUIRE TARGETS WITH]", weapon.name, ammo.name)
local realweapon = weapon
weapon = weapon.combat
local tg = tg or {type="bolt"}
if not tg.range then tg.range=weapon.range or 10 end
tg.display = tg.display or {display='/'}
tg.speed = tg.speed or 20
local x, y = self:getTarget(tg)
if not x or not y then return nil end
-- Find targets to know how many ammo we use
local targets = {}
if params.one_shot then
local ammo = self:removeObject(self:getInven("QUIVER"), 1)
if ammo then
targets = {{x=x, y=y, ammo=ammo.combat}}
end
else
local limit_shots = params.limit_shots
self:project(tg, x, y, function(tx, ty)
local target = game.level.map(tx, ty, game.level.map.ACTOR)
if not target then return end
if tx == self.x and ty == self.y then return end
if limit_shots then
if limit_shots <= 0 then return end
limit_shots = limit_shots - 1
end
for i = 1, params.multishots or 1 do
local ammo = self:removeObject(self:getInven("QUIVER"), 1)
if ammo then targets[#targets+1] = {x=tx, y=ty, ammo=ammo.combat}
else break end
end
end)
end
if #targets > 0 then
local sound = weapon.sound
local speed = self:combatSpeed(weapon)
print("[SHOOT] speed", speed or 1, "=>", game.energy_to_act * (speed or 1))
self:useEnergy(game.energy_to_act * (speed or 1))
if sound then game:playSoundNear(targets[1], sound) end
if ammo:getNumber() < 10 or ammo:getNumber() == 50 or ammo:getNumber() == 40 or ammo:getNumber() == 25 then
game.logPlayer(self, "You only have %d %s left!", ammo:getNumber(), ammo.name)
end
return targets
else
return nil
end
end
--- Archery projectile code
local function archery_projectile(tx, ty, tg, self)
local weapon, ammo = tg.archery.weapon, tg.archery.ammo
local target = game.level.map(tx, ty, game.level.map.ACTOR)
if not target then return end
local talent = self:getTalentFromId(tg.talent_id)
local damtype = tg.archery.damtype or ammo.damtype or DamageType.PHYSICAL
local mult = tg.archery.mult or 1
-- Does the blow connect? yes .. complex :/
local atk, def = self:combatAttack(weapon), target:combatDefenseRanged()
local dam, apr, armor = self:combatDamage(ammo), self:combatAPR(ammo), target:combatArmor()
print("[ATTACK ARCHERY] to ", target.name, " :: ", dam, apr, armor, "::", mult)
if not self:canSee(target) then atk = atk / 3 end
-- If hit is over 0 it connects, if it is 0 we still have 50% chance
local hitted = false
if self:checkHit(atk, def) then
apr = apr + (tg.archery.apr or 0)
print("[ATTACK ARCHERY] raw dam", dam, "versus", armor, "with APR", apr)
local dam = math.max(0, dam - math.max(0, armor - apr))
local damrange = self:combatDamageRange(ammo)
dam = rng.range(dam, dam * damrange)
print("[ATTACK ARCHERY] after range", dam)
local crit
if tg.archery.crit_chance then self.combat_physcrit = self.combat_physcrit + tg.archery.crit_chance end
dam, crit = self:physicalCrit(dam, ammo, target)
if tg.archery.crit_chance then self.combat_physcrit = self.combat_physcrit - tg.archery.crit_chance end
print("[ATTACK ARCHERY] after crit", dam)
dam = dam * mult
print("[ATTACK ARCHERY] after mult", dam)
if crit then game.logSeen(self, "%s performs a critical strike!", self.name:capitalize()) end
DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam))
game.level.map:particleEmitter(target.x, target.y, 1, "archery")
hitted = true
if talent.archery_onhit then talent.archery_onhit(self, talent, target, target.x, target.y) end
else
local srcname = game.level.map.seens(self.x, self.y) and self.name:capitalize() or "Something"
game.logSeen(target, "%s misses %s.", srcname, target.name)
end
-- Ranged project
if hitted and not target.dead then for typ, dam in pairs(self.ranged_project) do
if dam > 0 then
DamageType:get(typ).projector(self, target.x, target.y, typ, dam)
end
end end
-- Regen on being hit
if hitted and not target.dead and target:attr("stamina_regen_on_hit") then target:incStamina(target.stamina_regen_on_hit) end
if hitted and not target.dead and target:attr("mana_regen_on_hit") then target:incMana(target.mana_regen_on_hit) end
end
--- Shoot at one target
function _M:archeryShoot(targets, talent, tg, params)
local weapon, ammo = self:hasArcheryWeapon()
if not weapon then
game.logPlayer(self, "You must wield a bow or a sling (%s)!", ammo)
return nil
end
print("[SHOOT WITH]", weapon.name, ammo.name)
local realweapon = weapon
weapon = weapon.combat
local tg = tg or {type="bolt"}
tg.talent = tg.talent or talent
if not tg.range then tg.range=weapon.range or 10 end
tg.display = tg.display or {display='/'}
tg.speed = tg.speed or 20
tg.archery = params or {}
tg.archery.weapon = weapon
for i = 1, #targets do
local tg = table.clone(tg)
tg.archery.ammo = targets[i].ammo
print("******........ firing target", targets[i].x, targets[i].y, "from", self.x, self.y)
self:projectile(tg, targets[i].x, targets[i].y, archery_projectile)
end
end
--- Check if the actor has a bow or sling and corresponding ammo
function _M:hasArcheryWeapon()
if not self:getInven("MAINHAND") then return nil, "no shooter" end
if not self:getInven("QUIVER") then return nil, "no ammo" end
local weapon = self:getInven("MAINHAND")[1]
local ammo = self:getInven("QUIVER")[1]
if not weapon or not weapon.archery then
return nil, "no shooter"
end
if not ammo or not ammo.archery_ammo or weapon.archery ~= ammo.archery_ammo then
return nil, "bad or no ammo"
end
return weapon, ammo
end
......@@ -820,7 +820,7 @@ static GLenum sdl_gl_texture_format(SDL_Surface *s) {
// allocate memory for a texture without copying pixels in
// caller binds texture
static void make_texture_for_surface(SDL_Surface *s) {
static void make_texture_for_surface(SDL_Surface *s, int *fw, int *fh) {
// Paramtrage de la texture.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
......@@ -837,6 +837,8 @@ static void make_texture_for_surface(SDL_Surface *s) {
while (realw < s->w) realw *= 2;
while (realh < s->h) realh *= 2;
if (fw) *fw = realw;
if (fh) *fh = realh;
//printf("request size (%d,%d), producing size (%d,%d)\n",s->w,s->h,realw,realh);
glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, realw, realh, 0, texture_format, GL_UNSIGNED_BYTE, NULL);
......@@ -877,7 +879,7 @@ static int sdl_surface_toscreen(lua_State *L)
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
make_texture_for_surface(*s);
make_texture_for_surface(*s, NULL, NULL);
copy_surface_to_texture(*s);
draw_textured_quad(x,y,(*s)->w,(*s)->h);
......@@ -913,6 +915,17 @@ static int sdl_surface_toscreen_with_texture(lua_State *L)
return 0;
}
static int sdl_surface_update_texture(lua_State *L)
{
SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1);
GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 2);
glBindTexture(GL_TEXTURE_2D, *t);
copy_surface_to_texture(*s);
return 0;
}
static int sdl_surface_to_texture(lua_State *L)
{
SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1);
......@@ -923,10 +936,14 @@ static int sdl_surface_to_texture(lua_State *L)
glGenTextures(1, t);
glBindTexture(GL_TEXTURE_2D, *t);
make_texture_for_surface(*s);
int fw, fh;
make_texture_for_surface(*s, &fw, &fh);
copy_surface_to_texture(*s);
return 1;
lua_pushnumber(L, fw);
lua_pushnumber(L, fh);
return 3;
}
static int sdl_surface_merge(lua_State *L)
......@@ -986,6 +1003,39 @@ static int sdl_texture_toscreen(lua_State *L)
return 0;
}
static int sdl_texture_toscreen_full(lua_State *L)
{
GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int w = luaL_checknumber(L, 4);
int h = luaL_checknumber(L, 5);
int rw = luaL_checknumber(L, 6);
int rh = luaL_checknumber(L, 7);
if (lua_isnumber(L, 8))
{
float r = luaL_checknumber(L, 9);
float g = luaL_checknumber(L, 10);
float b = luaL_checknumber(L, 11);
float a = luaL_checknumber(L, 12);
glColor4f(r, g, b, a);
}
glBindTexture(GL_TEXTURE_2D, *t);
GLfloat texw = (GLfloat)w/rw;
GLfloat texh = (GLfloat)h/rh;
glBegin( GL_QUADS );
glTexCoord2f(0,0); glVertex2f(0 + x, 0 + y);
glTexCoord2f(0,texh); glVertex2f(0 + x, h + y);
glTexCoord2f(texw,texh); glVertex2f(w + x, h + y);
glTexCoord2f(texw,0); glVertex2f(w + x, 0 + y);
glEnd( );
if (lua_isnumber(L, 8)) glColor4f(1, 1, 1, 1);
return 0;
}
static bool _CheckGL_Error(const char* GLcall, const char* file, const int line)
{
GLenum errCode;
......@@ -1294,6 +1344,7 @@ static const struct luaL_reg sdl_surface_reg[] =
{"merge", sdl_surface_merge},
{"toScreen", sdl_surface_toscreen},
{"toScreenWithTexture", sdl_surface_toscreen_with_texture},
{"updateTexture", sdl_surface_update_texture},
{"putChar", lua_display_char},
{"drawString", sdl_surface_drawstring},
{"drawStringBlended", sdl_surface_drawstring_aa},
......@@ -1307,6 +1358,7 @@ static const struct luaL_reg sdl_texture_reg[] =
{"__gc", sdl_free_texture},
{"close", sdl_free_texture},
{"toScreen", sdl_texture_toscreen},
{"toScreenFull", sdl_texture_toscreen_full},
{"makeOutline", sdl_texture_outline},
{"toSurface", gl_texture_to_sdl},
{NULL, NULL},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment