Skip to content
Snippets Groups Projects
Commit 6b311b06 authored by dg's avatar dg
Browse files

secret project!

git-svn-id: http://svn.net-core.org/repos/t-engine4@1627 51575b47-30f0-44d4-a5cc-537603b46e54
parent 5c306956
No related branches found
No related tags found
No related merge requests found
Showing
with 559 additions and 74 deletions
......@@ -63,15 +63,15 @@ function _M:generateList()
local i = 0
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text="Display resolution."}
list[#list+1] = { zone=zone, name="#GOLD##{bold}#Resolution#WHITE##{normal}#", status=function(item)
list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Resolution#WHITE##{normal}#", status=function(item)
return config.settings.window.size
end, fct=function(item)
local menu = require("engine.dialogs.DisplayResolution").new(function() self.c_list:drawItem(item) end)
game:registerDialog(menu)
end,}
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text="Controls the particle effects density.\nThis option allows to change the density of the many particle effects in the game.\nIf the game is slow when displaying spell effects try to lower this setting.#WHITE#"}
list[#list+1] = { zone=zone, name="#GOLD##{bold}#Particle effects density#WHITE##{normal}#", status=function(item)
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"Controls the particle effects density.\nThis option allows to change the density of the many particle effects in the game.\nIf the game is slow when displaying spell effects try to lower this setting.#WHITE#"}
list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Particle effects density#WHITE##{normal}#", status=function(item)
return tostring(config.settings.particles_density)
end, fct=function(item)
game:registerDialog(GetQuantity.new("Enter density", "From 0 to 100", config.settings.particles_density, 100, function(qty)
......@@ -81,8 +81,8 @@ function _M:generateList()
end))
end,}
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text="Activates antialiased texts.\nTexts will look nicer but it can be slower on some computers.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name="#GOLD##{bold}#Antialiased texts#WHITE##{normal}#", status=function(item)
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"Activates antialiased texts.\nTexts will look nicer but it can be slower on some computers.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Antialiased texts#WHITE##{normal}#", status=function(item)
return tostring(core.display.getTextBlended() and "enabled" or "disabled")
end, fct=function(item)
local state = not core.display.getTextBlended()
......@@ -91,8 +91,8 @@ function _M:generateList()
self.c_list:drawItem(item)
end,}
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text="Activates framebuffers.\nThis option allows for some special graphical effects.\nIf you encounter weird graphical glitches try to disable it.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name="#GOLD##{bold}#Framebuffers#WHITE##{normal}#", status=function(item)
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"Activates framebuffers.\nThis option allows for some special graphical effects.\nIf you encounter weird graphical glitches try to disable it.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Framebuffers#WHITE##{normal}#", status=function(item)
return tostring(config.settings.fbo_active and "enabled" or "disabled")
end, fct=function(item)
config.settings.fbo_active = not config.settings.fbo_active
......@@ -100,8 +100,8 @@ function _M:generateList()
self.c_list:drawItem(item)
end,}
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text="Activates OpenGL Shaders.\nThis option allows for some special graphical effects.\nIf you encounter weird graphical glitches try to disable it.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name="#GOLD##{bold}#OpenGL Shaders#WHITE##{normal}#", status=function(item)
local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"Activates OpenGL Shaders.\nThis option allows for some special graphical effects.\nIf you encounter weird graphical glitches try to disable it.\n\n#LIGHT_RED#You must restart the game for it to take effect.#WHITE#"}
list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#OpenGL Shaders#WHITE##{normal}#", status=function(item)
return tostring(config.settings.shaders_active and "enabled" or "disabled")
end, fct=function(item)
config.settings.shaders_active = not config.settings.shaders_active
......
......@@ -28,7 +28,6 @@ require "engine.interface.ActorStats"
require "engine.interface.ActorTalents"
require "engine.interface.ActorResource"
require "engine.interface.ActorFOV"
require "mod.class.interface.Combat"
local Map = require "engine.Map"
module(..., package.seeall, class.inherit(
......@@ -40,8 +39,7 @@ module(..., package.seeall, class.inherit(
engine.interface.ActorStats,
engine.interface.ActorTalents,
engine.interface.ActorResource,
engine.interface.ActorFOV,
mod.class.interface.Combat
engine.interface.ActorFOV
))
function _M:init(t, no_default)
......@@ -52,6 +50,9 @@ function _M:init(t, no_default)
t.power_regen = t.power_regen or 1
t.life_regen = t.life_regen or 0.25 -- Life regen real slow
t.esp = {}
t.speed = t.speed or 0
-- Default melee barehanded damage
self.combat = { dam=1 }
......@@ -64,6 +65,8 @@ function _M:init(t, no_default)
engine.interface.ActorStats.init(self, t)
engine.interface.ActorLevel.init(self, t)
engine.interface.ActorFOV.init(self, t)
self:computeEnergyMod()
end
function _M:act()
......@@ -95,6 +98,70 @@ function _M:move(x, y, force)
return moved
end
local extract_energy =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 7, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 36, 37, 37,
38, 38, 39, 39, 40, 40, 40, 41, 41, 41,
42, 42, 42, 43, 43, 43, 44, 44, 44, 44,
45, 45, 45, 45, 45, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 48, 48, 48, 48, 48,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
}
--- Compute energy mod based on speed
function _M:computeEnergyMod()
self.energy.mod = extract_energy[self.speed + 111] / 10
end
--- Called when a temporary value changes (added or deleted)
-- Takes care to compute energy mod
-- @param prop the property changing
-- @param sub the sub element of the property if it is a table, or nil
-- @param v the value of the change
function _M:onTemporaryValueChange(prop, sub, v)
if prop == "speed" then
self:computeEnergyMod()
end
end
--- How much experience is this actor worth
-- @param target to whom is the exp rewarded
-- @return the experience rewarded
function _M:worthExp(target)
return self.exp_worth
end
--- Reveals location surrounding the actor
function _M:magicMap(radius, x, y)
x = x or self.x
y = y or self.y
radius = math.floor(radius)
local ox, oy
self.x, self.y, ox, oy = x, y, self.x, self.y
self:computeFOV(radius, "block_sense", function(x, y)
game.level.map.remembers(x, y, true)
game.level.map.has_seens(x, y, true)
end, true, true, true)
self.x, self.y = ox, oy
end
function _M:tooltip()
return ([[%s%s
#00ffff#Level: %d
......@@ -276,7 +343,6 @@ function _M:canBe(what)
if what == "blind" and rng.percent(100 * (self:attr("blind_immune") or 0)) then return false end
if what == "stun" and rng.percent(100 * (self:attr("stun_immune") or 0)) then return false end
if what == "fear" and rng.percent(100 * (self:attr("fear_immune") or 0)) then return false end
if what == "knockback" and rng.percent(100 * (self:attr("knockback_immune") or 0)) then return false end
if what == "instakill" and rng.percent(100 * (self:attr("instakill_immune") or 0)) then return false end
return true
end
......@@ -95,7 +95,7 @@ function _M:newGame()
self:setupDisplayMode()
self.creating_player = true
local birth = Birther.new(self.player, {"base" }, function()
local birth = Birther.new(self.player, {"base", "race" }, function()
self:changeLevel(1, "dungeon")
print("[PLAYER BIRTH] resolve...")
self.player:resolve()
......@@ -168,6 +168,8 @@ function _M:changeLevel(lev, zone)
self.player:move(self.level.default_down.x, self.level.default_down.y, true)
end
self.level:addEntity(self.player)
self.level.map:setZoom(1.2, self.player.x, self.player.y)
end
function _M:getPlayer()
......
......@@ -19,10 +19,11 @@
require "engine.class"
local ActorAI = require "engine.interface.ActorAI"
local MonsterCombat = require "mod.class.interface.MonsterCombat"
local Faction = require "engine.Faction"
require "mod.class.Actor"
module(..., package.seeall, class.inherit(mod.class.Actor, engine.interface.ActorAI))
module(..., package.seeall, class.inherit(mod.class.Actor, engine.interface.ActorAI, MonsterCombat))
function _M:init(t, no_default)
mod.class.Actor.init(self, t, no_default)
......
......@@ -29,6 +29,7 @@ local ActorTalents = require "engine.interface.ActorTalents"
local DeathDialog = require "mod.dialogs.DeathDialog"
local Astar = require"engine.Astar"
local DirectPath = require"engine.DirectPath"
require "mod.class.interface.Combat"
--- Defines the player
-- It is a normal actor, with some redefined methods to handle user interaction.<br/>
......@@ -38,7 +39,8 @@ module(..., package.seeall, class.inherit(
engine.interface.PlayerRest,
engine.interface.PlayerRun,
engine.interface.PlayerMouse,
engine.interface.PlayerHotkeys
engine.interface.PlayerHotkeys,
mod.class.interface.Combat
))
function _M:init(t, no_default)
......@@ -89,11 +91,16 @@ end
function _M:playerFOV()
-- Clean FOV before computing it
game.level.map:cleanFOV()
-- Compute ESP FOV, using cache
self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true, true)
-- Compute both the normal and the lite FOV, using cache
self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist)
game.level.map:apply(x, y, fovdist[sqdist])
end, true, false, true)
self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true)
if self.lite <= 0 then game.level.map:applyLite(self.x, self.y)
else self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true) end
end
--- Called before taking a hit, overload mod.class.Actor:onTakeHit() to stop resting and running
......
-- 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 Mouse = require "engine.Mouse"
local TooltipsData = require "mod.class.interface.TooltipsData"
module(..., package.seeall, class.inherit(TooltipsData))
function _M:init(x, y, w, h, bgcolor)
self.display_x = x
self.display_y = y
self.w, self.h = w, h
self.bgcolor = bgcolor
self.font = core.display.newFont("/data/font/VeraMono.ttf", 14)
self.mouse = Mouse.new()
self:resize(x, y, w, h)
end
--- Resize the display area
function _M:resize(x, y, w, h)
self.display_x, self.display_y = x, y
self.mouse.delegate_offset_x = x
self.mouse.delegate_offset_y = y
self.w, self.h = w, h
self.font_h = self.font:lineSkip()
self.font_w = self.font:size(" ")
self.bars_x = self.font_w * 9
self.bars_w = self.w - self.bars_x - 5
self.surface = core.display.newSurface(w, h)
self.texture, self.texture_w, self.texture_h = self.surface:glTexture()
local tex_bg = core.display.loadImage("/data/gfx/ui/player-display.png")
local tex_up = core.display.loadImage("/data/gfx/ui/player-display-top.png")
local bw, bh = tex_bg:getSize()
self.bg_surface = core.display.newSurface(w, h)
local i = 0
while i < h do
self.bg_surface:merge(tex_bg, 0, i)
i = i + bh
end
self.bg_surface:merge(tex_up, 0, 0)
end
function _M:mouseTooltip(text, _, _, _, w, h, x, y)
self.mouse:registerZone(x, y, w, h, function(button) game.tooltip_x, game.tooltip_y = 1, 1; game.tooltip:displayAtMap(nil, nil, game.w, game.h, text) end)
end
-- Displays the stats
function _M:display()
local player = game.player
if not player or not player.changed then return self.surface end
self.mouse:reset()
local s = self.surface
if self.bg_surface then
s:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
s:merge(self.bg_surface, 0, 0)
else
s:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
end
local cur_exp, max_exp = player.exp, player:getExpChart(player.level+1)
local h = 6
local x = 2
self:mouseTooltip(self.TOOLTIP_LEVEL, s:drawColorStringBlended(self.font, "Level: #00ff00#"..player.level, x, h, 255, 255, 255)) h = h + self.font_h
self:mouseTooltip(self.TOOLTIP_LEVEL, s:drawColorStringBlended(self.font, ("Exp: #00ff00#%2d%%"):format(100 * cur_exp / max_exp), x, h, 255, 255, 255)) h = h + self.font_h
self:mouseTooltip(self.TOOLTIP_GOLD, s:drawColorStringBlended(self.font, ("Gold: #00ff00#%0.2f"):format(player.money or 0), x, h, 255, 255, 255)) h = h + self.font_h
h = h + self.font_h
if game.level and game.level.turn_counter then
s:drawColorStringBlended(self.font, ("Turns remaining: %d"):format(game.level.turn_counter / 10), x, h, 255, 0, 0) h = h + self.font_h
h = h + self.font_h
end
if player:getAir() < player.max_air then
self:mouseTooltip(self.TOOLTIP_AIR, s:drawColorStringBlended(self.font, ("Air level: %d/%d"):format(player:getAir(), player.max_air), x, h, 255, 0, 0)) h = h + self.font_h
h = h + self.font_h
end
if player:attr("encumbered") then
self:mouseTooltip(self.TOOLTIP_ENCUMBERED, s:drawColorStringBlended(self.font, "Encumbered!", x, h, 255, 0, 0)) h = h + self.font_h
h = h + self.font_h
end
self:mouseTooltip(self.TOOLTIP_STRDEXCON, s:drawColorStringBlended(self.font, ("Str/Dex/Con: #00ff00#%3d/%3d/%3d"):format(player:getStr(), player:getDex(), player:getCon()), x, h, 255, 255, 255)) h = h + self.font_h
self:mouseTooltip(self.TOOLTIP_MAGWILCUN, s:drawColorStringBlended(self.font, ("Mag/Wil/Cun: #00ff00#%3d/%3d/%3d"):format(player:getMag(), player:getWil(), player:getCun()), x, h, 255, 255, 255)) h = h + self.font_h
h = h + self.font_h
s:erase(colors.VERY_DARK_RED.r, colors.VERY_DARK_RED.g, colors.VERY_DARK_RED.b, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(colors.DARK_RED.r, colors.DARK_RED.g, colors.DARK_RED.b, 255, self.bars_x, h, self.bars_w * player.life / player.max_life, self.font_h)
self:mouseTooltip(self.TOOLTIP_LIFE, s:drawColorStringBlended(self.font, ("#c00000#Life: #ffffff#%d/%d"):format(player.life, player.max_life), x, h, 255, 255, 255)) h = h + self.font_h
if player.alchemy_golem and not player.alchemy_golem.dead then
s:erase(colors.VERY_DARK_RED.r, colors.VERY_DARK_RED.g, colors.VERY_DARK_RED.b, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(colors.DARK_RED.r, colors.DARK_RED.g, colors.DARK_RED.b, 255, self.bars_x, h, self.bars_w * player.alchemy_golem.life / player.alchemy_golem.max_life, self.font_h)
self:mouseTooltip(self.TOOLTIP_LIFE, s:drawColorStringBlended(self.font, ("#c00000#Golem: #ffffff#%d/%d"):format(player.alchemy_golem.life, player.alchemy_golem.max_life), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_STAMINA_POOL) then
s:erase(0xff / 6, 0xcc / 6, 0x80 / 6, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(0xff / 3, 0xcc / 3, 0x80 / 3, 255, self.bars_x, h, self.bars_w * player:getStamina() / player.max_stamina, self.font_h)
self:mouseTooltip(self.TOOLTIP_STAMINA, s:drawColorStringBlended(self.font, ("#ffcc80#Stamina: #ffffff#%d/%d"):format(player:getStamina(), player.max_stamina), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_MANA_POOL) then
s:erase(0x7f / 5, 0xff / 5, 0xd4 / 5, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(0x7f / 2, 0xff / 2, 0xd4 / 2, 255, self.bars_x, h, self.bars_w * player:getMana() / player.max_mana, self.font_h)
self:mouseTooltip(self.TOOLTIP_MANA, s:drawColorStringBlended(self.font, ("#7fffd4#Mana: #ffffff#%d/%d"):format(player:getMana(), player.max_mana), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_EQUILIBRIUM_POOL) then
s:erase(0x00 / 5, 0xff / 5, 0x74 / 5, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(0x00 / 2, 0xff / 2, 0x74 / 2, 255, self.bars_x, h, self.bars_w * math.min(1, math.log(1 + player:getEquilibrium() / 100)), self.font_h)
self:mouseTooltip(self.TOOLTIP_EQUILIBRIUM, s:drawColorStringBlended(self.font, ("#00ff74#Equi: #ffffff#%d"):format(player:getEquilibrium()), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_POSITIVE_POOL) then
s:erase(colors.GOLD.r / 5, colors.GOLD.g / 5, colors.GOLD.b / 5, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(colors.GOLD.r / 2, colors.GOLD.g / 2, colors.GOLD.b / 2, 255, self.bars_x, h, self.bars_w * player:getPositive() / player.max_positive, self.font_h)
self:mouseTooltip(self.TOOLTIP_POSITIVE, s:drawColorStringBlended(self.font, ("#7fffd4#Positive:#ffffff#%d/%d"):format(player:getPositive(), player.max_positive), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_NEGATIVE_POOL) then
s:erase(colors.GREY.r / 5, colors.GREY.g / 5, colors.GREY.b / 5, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(colors.GREY.r / 2, colors.GREY.g / 2, colors.GREY.b / 2, 255, self.bars_x, h, self.bars_w * player:getNegative() / player.max_negative, self.font_h)
self:mouseTooltip(self.TOOLTIP_NEGATIVE, s:drawColorStringBlended(self.font, ("#7fffd4#Negative:#ffffff#%d/%d"):format(player:getNegative(), player.max_negative), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_VIM_POOL) then
s:erase(0x90 / 6, 0x40 / 6, 0x10 / 6, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(0x90 / 3, 0x40 / 3, 0x10 / 3, 255, self.bars_x, h, self.bars_w * player:getVim() / player.max_vim, self.font_h)
self:mouseTooltip(self.TOOLTIP_VIM, s:drawColorStringBlended(self.font, ("#904010#Vim: #ffffff#%d/%d"):format(player:getVim(), player.max_vim), x, h, 255, 255, 255)) h = h + self.font_h
end
if player:knowTalent(player.T_HATE_POOL) then
s:erase(colors.GREY.r / 5, colors.GREY.g / 5, colors.GREY.b / 5, 255, self.bars_x, h, self.bars_w, self.font_h)
s:erase(colors.GREY.r / 2, colors.GREY.g / 2, colors.GREY.b / 2, 255, self.bars_x, h, self.bars_w * player:getHate() / 10, self.font_h)
self:mouseTooltip(self.TOOLTIP_HATE, s:drawColorStringBlended(self.font, ("#F53CBE#Hate: #ffffff#%.1f/%d"):format(player:getHate(), 10), x, h, 255, 255, 255)) h = h + self.font_h
end
if savefile_pipe.saving then h = h + self.font_h s:drawColorStringBlended(self.font, "#YELLOW#Saving...", x, h, 255, 255, 255) h = h + self.font_h end
h = h + self.font_h
for tid, act in pairs(player.sustain_talents) do
if act then
local t = player:getTalentFromId(tid)
local desc = "#GOLD##{bold}#"..t.name.."#{normal}##WHITE#\n"..tostring(player:getTalentFullDescription(t))
self:mouseTooltip(desc, s:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(t.name), x, h, 255, 255, 255)) h = h + self.font_h
end
end
for eff_id, p in pairs(player.tmp) do
local e = player.tempeffect_def[eff_id]
local desc = e.long_desc(player, p)
if e.status == "detrimental" then
self:mouseTooltip(desc, s:drawColorStringBlended(self.font, ("#LIGHT_RED#%s"):format(e.desc), x, h, 255, 255, 255)) h = h + self.font_h
else
self:mouseTooltip(desc, s:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(e.desc), x, h, 255, 255, 255)) h = h + self.font_h
end
end
s:updateTexture(self.texture)
return s
end
function _M:toScreen()
self:display()
self.texture:toScreenFull(self.display_x, self.display_y, self.w, self.h, self.texture_w, self.texture_h)
end
......@@ -45,5 +45,6 @@ function _M:callback(e)
e.does_block_move = true
e.block_sight = true
end
if not e.boring then e.always_remember = true end
if e.door then e.door_opened = "OPEN_DOOR" end
end
......@@ -28,8 +28,8 @@ info_format =
{
N = { "ang_id", "name", new_entity=true },
G = { "display", "color" },
I = { "speed", "life", "sight", "ac", "alertness", all_numbers=true },
W = { "level", "rarity", "_", "exp", all_numbers=true },
I = { "speed", "max_life", "sight", "ac", "alertness", all_numbers=true },
W = { "level", "rarity", "_", "exp_worth", all_numbers=true },
B = { "method", "effect", "damage", ignore_count=true, addtable="blows", },
S = { "spells", flags_parse="spells" },
F = { "flags", flags_parse="self" },
......@@ -37,16 +37,27 @@ info_format =
}
function _M:callback(e)
if e.name == "<player>" then return end
e.define_as = e.name:upper():gsub("[^A-Z0-9]", "_")
if not e.unique then
e[#e+1] = resolvers.generic(function(e)
local std_dev = (((e.max_life * 10) / 8) + 5) / 10
if e.max_life > 1 then std_dev = std_dev + 1 end
e.max_life = rng.normal(e.max_life, std_dev)
end)
end
e.color = colors[self.color_codes[e.color]]
e.level_range = {e.level, e.level}
e.speed = (e.speed or 100) - 100
e.speed = (e.speed or 110) - 110
if e.blows then
for i = 1, #e.blows do
if e.blows[i].damage then
local s = e.blows[i].damage:split(":")
local s = e.blows[i].damage:split("d")
e.blows[i].damage = {tonumber(s[1]), tonumber(s[2])}
else e.blows[i].damage = {0, 0} end
end
end
e.ai = "angband"
end
......@@ -81,10 +81,12 @@ function _M:parseLine(l, line_nb, ret, e)
if linfo.addtable then
e[linfo.addtable] = e[linfo.addtable] or {}
table.insert(e[linfo.addtable], {})
elseif linfo.intable then
e[linfo.intable] = e[linfo.intable] or {}
end
do
local e = (linfo.addtable) and e[linfo.addtable][#e[linfo.addtable]] or e
local e = (linfo.addtable) and e[linfo.addtable][#e[linfo.addtable]] or ((linfo.intable) and e[linfo.intable] or e)
if linfo.unsplit then
table.remove(data, 1)
if linfo.concat then e[linfo[1]] = (e[linfo[1]] or "")..table.concat(data, ":")
......
......@@ -26,26 +26,19 @@ module(..., package.seeall, class.inherit(Parser))
-- Tell the parser what fields to retrieve & match
info_format =
{
N = { "ang_id", "name", new_entity=true },
G = { "display", "color" },
I = { "speed", "life", "sight", "ac", "alertness", all_numbers=true },
W = { "level", "rarity", "_", "exp", all_numbers=true },
B = { "method", "effect", "damage", ignore_count=true, addtable="blows", },
S = { "spells", flags_parse="spells" },
F = { "flags", flags_parse="self" },
D = { "desc", ignore_count=true, unsplit=true, concat=true },
N = { "race_ang_id", "name" },
S = { "str", "int", "wis", "dex", "con", "chr", all_numbers=true },
R = { "dis", "dev", "sav", "stl", "srh", "fos", "thn", "thb", "throw", "dig", all_numbers=true },
X = { "hitdie", "expbase", "infra", all_numbers=true },
I = { "history", "agebase", "agemod", all_numbers=true },
H = { "hgtmale", "modhgtmale", "hgtfemale", "modhgtfemale", all_numbers=true },
W = { "wgtmale", "modwgtmale", "wgtfemale", "modwgtfemale", all_numbers=true },
N = { "race_ang_id", "name", new_entity=true },
S = { "str", "int", "wis", "dex", "con", "cha", intable="stats", all_numbers=true },
R = { "skill_dis", "skill_dev", "skill_sav", "skill_stl", "skill_srh", "skill_fos", "skill_thn", "skill_thb", "skill_throw", "skill_dig", intable="copy", all_numbers=true },
X = { "hitdie", "expbase", "infra", intable="copy", all_numbers=true },
I = { "history", "agebase", "agemod", intable="__unused", all_numbers=true },
H = { "hgtmale", "modhgtmale", "hgtfemale", "modhgtfemale", intable="__unused", all_numbers=true },
W = { "wgtmale", "modwgtmale", "wgtfemale", "modwgtfemale", intable="__unused", all_numbers=true },
F = { "racial flags", flags_parse="copy" },
C = { "classes (numeric)" },
}
function _M:callback(e)
e.type = "race"
e.desc = ""
print("callback", e.name)
end
-- 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"
--- Interface to add angband monster combat system
module(..., package.seeall, class.make)
--- Checks what to do with the target
-- Talk ? attack ? displace ?
function _M:bumpInto(target)
local reaction = self:reactionToward(target)
if reaction < 0 then
return self:attackTarget(target)
elseif reaction >= 0 then
if self.move_others then
-- Displace
game.level.map:remove(self.x, self.y, Map.ACTOR)
game.level.map:remove(target.x, target.y, Map.ACTOR)
game.level.map(self.x, self.y, Map.ACTOR, target)
game.level.map(target.x, target.y, Map.ACTOR, self)
self.x, self.y, target.x, target.y = target.x, target.y, self.x, self.y
end
end
end
function _M:testHit(chance, ac, vis)
local k
-- Percentile dice
k = rng.range(0, 99)
-- Hack -- Instant miss or hit
if (k < 10) then return (k < 5) end
-- Penalize invisible targets
if (not vis) then chance = chance / 2 end
-- Power competes against armor
if ((chance > 0) and (rng.range(0, chance-1) >= (ac * 3 / 4))) then return true end
-- Assume miss
return false
end
--- Determine if a monster attack against the player succeeds.
function _M:checkHit(power, level, ac)
local chance
-- Calculate the "attack quality"
chance = (power + (level * 3))
-- Check if the player was hit
return self:testHit(chance, ac, true)
end
local methods = {
HIT = { miss="misses you", hit="hits you.", do_cut=1, do_stun=1 },
TOUCH = { miss="misses you", hit = "touches you.", },
PUNCH = { miss="misses you", hit = "punches you.",do_stun = 1, },
KICK = { miss="misses you", hit = "kicks you.",do_stun = 1, },
CLAW = { miss="misses you", hit = "claws you.",do_cut = 1,},
BITE = { miss="misses you", hit = "bites you.",do_cut = 1,},
STING = { miss="misses you", hit = "stings you.",},
BUTT = { miss="misses you", hit = "butts you.",do_stun = 1,},
CRUSH = { miss="misses you", hit = "crushes you.",do_stun = 1,},
ENGULF = { miss="misses you", hit = "engulfs you.",},
CRAWL = { miss="misses you", hit = "crawls on you.",},
DROOL = { miss="misses you", hit = "drools on you.",},
SPIT = { miss="misses you", hit = "spits on you.",},
GAZE = { miss="misses you", hit = "gazes at you.",},
WAIL = { miss="misses you", hit = "wails at you.",},
SPORE = { miss="misses you", hit = "releases spores at you.",},
BEG = { miss="misses you", hit = "begs you for money.",},
INSULT = { miss="misses you", hit = "insults you.",},
MOAN = { miss="misses you", hit = "moams.", },
}
local effects = {
HURT = { power=60, act=function(self, target, dam, ac)
dam = dam - (dam * math.min(ac, 240) / 400)
DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam)
end },
POISON = { power=5, act=function(self, target, dam, ac)
DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam)
if target:canBe("poison") then target:setEffect(target.EFF_POISON, rng.range(1, self.level) + 5, {src=self}) end
end },
}
--- Makes the death happen!
function _M:attackTarget(target, mult)
if self:attr("never_blow") then return end
if not self.blows then return end
local ac = (target.ac or 0) + (target.to_a or 0)
local rlev = math.max(1, self.level)
for i, blow in ipairs(self.blows) do
if blow.method and blow.effect then
local meth = methods[blow.method]
local eff = effects[blow.effect]
if not meth then game.log("#LIGHT_RED#Method %s not defined yet!", blow.method) meth = methods.HIT end
if not eff then game.log("#LIGHT_RED#Effect %s not defined yet!", blow.effect) eff = effects.HURT end
local power = eff.power
if self:checkHit(power, rlev, ac) then
local dam = rng.dice(blow.damage[1], blow.damage[2])
game.logPlayer(target, "%s %s", self.name, meth.hit)
eff.act(self, target, dam, ac)
end
end
end
-- We use up our own energy
self:useEnergy(game.energy_to_act)
end
......@@ -36,4 +36,4 @@ local PlayerRaces = require("mod.class.info.PlayerRaces")
local list = PlayerRaces:parse("/data/angband_edits/p_race.txt")
-- Feed them to the zone
for i = 1, #list do newEntity(list[i]) end
for i = 1, #list do if list[i].name then newBirthDescriptor(list[i]) end end
......@@ -25,17 +25,17 @@ setDefaultProjector(function(src, x, y, type, dam)
if target == game.player then flash = game.flash.BAD end
if src == game.player then flash = game.flash.GOOD end
game.logSeen(target, flash, "%s hits %s for %s%0.2f %s damage#LAST#.", src.name:capitalize(), target.name, DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name)
-- game.logSeen(target, flash, "%s hits %s for %s%0.2f %s damage#LAST#.", src.name:capitalize(), target.name, DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name)
local sx, sy = game.level.map:getTileToScreen(x, y)
if target:takeHit(dam, src) then
if src == game.player or target == game.player then
game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, "Kill!", {255,0,255})
-- game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, "Kill!", {255,0,255})
end
else
if src == game.player then
game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, tostring(-math.ceil(dam)), {0,255,0})
-- game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, tostring(-math.ceil(dam)), {0,255,0})
elseif target == game.player then
game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, tostring(-math.ceil(dam)), {255,0,0})
-- game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -3, tostring(-math.ceil(dam)), {255,0,0})
end
end
return dam
......
......@@ -23,4 +23,4 @@ local Grids = require("mod.class.info.Grids")
local list = Grids:parse("/data/angband_edits/terrain.txt")
-- Feed them to the zone
for i = 1, #list do newEntity(list[i]) end
for i = 1, #list do if list[i].name then newEntity(list[i]) end end
......@@ -23,4 +23,4 @@ local Monsters = require("mod.class.info.Monsters")
local list = Monsters:parse("/data/angband_edits/monster.txt")
-- Feed them to the zone
for i = 1, #list do newEntity(list[i]) end
for i = 1, #list do if list[i].name then newEntity(list[i]) end end
......@@ -20,14 +20,38 @@
local Stats = require "engine.interface.ActorStats"
newEffect{
name = "ACIDBURN",
desc = "Burning from acid",
name = "POISONED",
desc = "Poisoned",
long_desc = function(self, eff) return ("The target is poisoned, doing 1 damage per turn.") end,
type = "poison",
status = "detrimental",
parameters = { },
on_gain = function(self, err) return "#Target# is poisoned!", "+Poison" end,
on_lose = function(self, err) return "#Target# stops being poisoned.", "-Poison" end,
on_merge = function(self, old_eff, new_eff)
old_eff.dur = dur + new_eff.dur
return old_eff
end,
on_timeout = function(self, eff)
DamageType:get(DamageType.PHYSICAL).projector(eff.src, self.x, self.y, DamageType.PHYSICAL, 1)
end,
}
newEffect{
name = "CUT",
desc = "Bleeding",
long_desc = function(self, eff) return ("Huge cut that bleeds blood, doing %d damage per turn."):format((eff.dur > 200) and 3 or ((eff.dur > 100) and 2 or 1)) end,
type = "physical",
status = "detrimental",
parameters = { power=1 },
on_gain = function(self, err) return "#Target# is covered in acid!", "+Acid" end,
on_lose = function(self, err) return "#Target# is free from the acid.", "-Acid" end,
parameters = { },
on_gain = function(self, err) return "#Target# starts to bleed.", "+Bleeds" end,
on_lose = function(self, err) return "#Target# stops bleeding.", "-Bleeds" end,
on_merge = function(self, old_eff, new_eff)
old_eff.dur = dur + new_eff.dur
return old_eff
end,
on_timeout = function(self, eff)
DamageType:get(DamageType.ACID).projector(eff.src or self, self.x, self.y, DamageType.ACID, eff.power)
local dam = (eff.dur > 200) and 3 or ((eff.dur > 100) and 2 or 1)
DamageType:get(DamageType.PHYSICAL).projector(eff.src, self.x, self.y, DamageType.PHYSICAL, dam)
end,
}
......@@ -21,7 +21,9 @@ return {
name = "Angband",
level_range = {1, 1},
max_level = 50,
width = 198, height = 66,
all_remembered = true,
all_lited = true,
width = 98, height = 66,
generator = {
map = {
class = "engine.generator.map.Roomer",
......@@ -36,7 +38,7 @@ return {
},
actor = {
class = "engine.generator.actor.Random",
nb_npc = {80, 100},
nb_npc = {30, 40},
},
},
levels =
......
......@@ -55,6 +55,61 @@ ActorStats:defineStat("Charisma", "cha", 10, 1, 100, "Charisma defines your char
-- Actor AIs
ActorAI:loadDefinition("/engine/ai/")
ActorAI:loadDefinition("/mod/ai/")
ActorLevel:defineExperienceChart{
0,
10,
25,
45,
70,
100,
140,
200,
280,
380,
500,
650,
850,
1100,
1400,
1800,
2300,
2900,
3600,
4400,
5400,
6800,
8400,
10200,
12500,
17500,
25000,
35000,
50000,
75000,
100000,
150000,
200000,
275000,
350000,
450000,
550000,
700000,
850000,
1000000,
1250000,
1500000,
1800000,
2100000,
2400000,
2700000,
3000000,
3500000,
4000000,
4500000,
5000000
}
-- Birther descriptor
Birther:loadDefinition("/data/birth/descriptors.lua")
......
......@@ -29,27 +29,7 @@ Map.updateMapDisplay = function(self, x, y, mos)
local a = self(x, y, Map.ACTOR)
local t = self(x, y, Map.TRAP)
if a then
-- Handles invisibility and telepathy and other such things
if not self.actor_player or self.actor_player:canSee(a) then
local r = self.actor_player:reactionToward(a)
mm = mm + (r > 0 and Map.MM_FRIEND or (r == 0 and Map.MM_NEUTRAL or Map.MM_HOSTILE))
a:getMapObjects(self.tiles, mos, 1)
end
elseif o then
o:getMapObjects(self.tiles, mos, 1)
if self.object_stack_count then
local mo = o:getMapStackMO(self, x, y)
if mo then mos[2] = mo end
end
mm = mm + Map.MM_OBJECT
elseif t then
-- Handles trap being known
if not self.actor_player or t:knownBy(self.actor_player) then
t:getMapObjects(self.tiles, mos, 1)
mm = mm + Map.MM_TRAP
end
elseif g then
if g then
-- Update path caches from path strings
for i = 1, #self.path_strings do
local ps = self.path_strings[i]
......@@ -60,5 +40,28 @@ Map.updateMapDisplay = function(self, x, y, mos)
mm = mm + (g:check("change_level") and Map.MM_LEVEL_CHANGE or 0)
g:getMapObjects(self.tiles, mos, 1)
end
if t then
-- Handles trap being known
if not self.actor_player or t:knownBy(self.actor_player) then
t:getMapObjects(self.tiles, mos, 1)
mm = mm + Map.MM_TRAP
end
end
if o then
o:getMapObjects(self.tiles, mos, 1)
if self.object_stack_count then
local mo = o:getMapStackMO(self, x, y)
if mo then mos[2] = mo end
end
mm = mm + Map.MM_OBJECT
end
if a then
-- Handles invisibility and telepathy and other such things
if not self.actor_player or self.actor_player:canSee(a) then
local r = self.actor_player:reactionToward(a)
mm = mm + (r > 0 and Map.MM_FRIEND or (r == 0 and Map.MM_NEUTRAL or Map.MM_HOSTILE))
a:getMapObjects(self.tiles, mos, 1)
end
end
return mm
end
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