Skip to content

Commit

Permalink
feat: options 'frags' and 'payment' to war system (#1982)
Browse files Browse the repository at this point in the history
When declaring war, the guild leader chooses their opponent and defines
the conditions: duration (from 7 to 180 days), frags limit (up to
1,000), a penalty to be paid in case of loss (up to 2kkk), among others.

Based on the information above, we can add the columns "frags_limit,"
"payment," and "duration_days" to the 'guild wars' table so that the
websites can interact correctly according to the system.

Resolves #2121
  • Loading branch information
Luan Luciano authored Mar 1, 2024
1 parent ca96af8 commit 59b7abd
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 18 deletions.
4 changes: 2 additions & 2 deletions data-otservbr-global/migrations/41.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ function onUpdateDatabase()

db.query([[
ALTER TABLE `players`
MODIFY `xpboost_stamina` smallint(5) UNSIGNED DEFAULT NULL,
MODIFY `xpboost_value` tinyint(4) UNSIGNED DEFAULT NULL
MODIFY `xpboost_stamina` smallint(5) UNSIGNED DEFAULT NULL,
MODIFY `xpboost_value` tinyint(4) UNSIGNED DEFAULT NULL
]])

return true
Expand Down
11 changes: 10 additions & 1 deletion data-otservbr-global/migrations/43.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
logger.info("Updating database to version 43 (feat frags_limit, payment and duration_days in guild wars)")

db.query([[
ALTER TABLE `guild_wars`
ADD `frags_limit` smallint(4) UNSIGNED NOT NULL DEFAULT '0',
ADD `payment` bigint(13) UNSIGNED NOT NULL DEFAULT '0',
ADD `duration_days` tinyint(3) UNSIGNED NOT NULL DEFAULT '0'
]])

return true
end
3 changes: 3 additions & 0 deletions data-otservbr-global/migrations/44.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
end
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,52 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi

if byPlayer == 1 then
local targetGuild = player:getGuild()
targetGuild = targetGuild and targetGuild:getId() or 0
if targetGuild ~= 0 then
local targetGuildId = targetGuild and targetGuild:getId() or 0
if targetGuildId ~= 0 then
local killerGuild = killer:getGuild()
killerGuild = killerGuild and killerGuild:getId() or 0
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(player:getId(), killer.uid) then
local killerGuildId = killerGuild and killerGuild:getId() or 0
if killerGuildId ~= 0 and targetGuildId ~= killerGuildId and isInWar(player:getId(), killer:getId()) then
local warId = false
resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND \z
((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR \z
(`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))")
if resultId ~= false then
((`guild1` = " .. killerGuildId .. " AND `guild2` = " .. targetGuildId .. ") OR \z
(`guild1` = " .. targetGuildId .. " AND `guild2` = " .. killerGuildId .. "))")
if resultId then
warId = Result.getNumber(resultId, "id")
Result.free(resultId)
end

if warId ~= false then
if warId then
local playerName = player:getName()
db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) \z
VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(player:getName()) .. ", " .. killerGuild .. ", \z
" .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")")
VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(playerName) .. ", " .. killerGuildId .. ", \z
" .. targetGuildId .. ", " .. os.time() .. ", " .. warId .. ")")

resultId = db.storeQuery("SELECT `guild_wars`.`id`, `guild_wars`.`frags_limit`, (SELECT COUNT(1) FROM `guildwar_kills` \z
WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) AS guild1_kills, \z
(SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) AS guild2_kills \z
FROM `guild_wars` WHERE (`guild1` = " .. killerGuildId .. " OR `guild2` = " .. killerGuildId .. ") AND `status` = 1 AND `id` = " .. warId)

if resultId then
local guild1_kills = Result.getNumber(resultId, "guild1_kills")
local guild2_kills = Result.getNumber(resultId, "guild2_kills")
local frags_limit = Result.getNumber(resultId, "frags_limit")
Result.free(resultId)

local members = killerGuild:getMembersOnline()
for i = 1, #members do
members[i]:sendChannelMessage(members[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
end

local enemyMembers = targetGuild:getMembersOnline()
for i = 1, #enemyMembers do
enemyMembers[i]:sendChannelMessage(enemyMembers[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
end

if guild1_kills >= frags_limit or guild2_kills >= frags_limit then
db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. os.time() .. " WHERE `status` = 1 AND `id` = " .. warId)
Game.broadcastMessage(string.format("%s has just won the war against %s.", killerGuild:getName(), targetGuild:getName()))
end
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
local guildWar = GlobalEvent("guildwar")

function guildWar.onThink(interval)
local time = os.time()
db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. time .. " WHERE `status` = 1 AND (`started` + 5 * 60 * 60) < " .. time)
db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. time .. " WHERE `status` = 1 AND `ended` != 0 AND `ended` < " .. time)
return true
end

guildWar:interval(100000)
guildWar:interval(60000)
guildWar:register()
7 changes: 5 additions & 2 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `server_config` (
CONSTRAINT `server_config_pk` PRIMARY KEY (`config`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '43'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '44'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');

-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
Expand Down Expand Up @@ -312,9 +312,12 @@ CREATE TABLE IF NOT EXISTS `guild_wars` (
`guild2` int(11) NOT NULL DEFAULT '0',
`name1` varchar(255) NOT NULL,
`name2` varchar(255) NOT NULL,
`status` tinyint(2) NOT NULL DEFAULT '0',
`status` tinyint(2) UNSIGNED NOT NULL DEFAULT '0',
`started` bigint(15) NOT NULL DEFAULT '0',
`ended` bigint(15) NOT NULL DEFAULT '0',
`frags_limit` smallint(4) UNSIGNED NOT NULL DEFAULT '0',
`payment` bigint(13) UNSIGNED NOT NULL DEFAULT '0',
`duration_days` tinyint(3) UNSIGNED NOT NULL DEFAULT '0',
INDEX `guild1` (`guild1`),
INDEX `guild2` (`guild2`),
CONSTRAINT `guild_wars_pk` PRIMARY KEY (`id`)
Expand Down
2 changes: 1 addition & 1 deletion src/io/ioguild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ uint32_t IOGuild::getGuildIdByName(const std::string &name) {

void IOGuild::getWarList(uint32_t guildId, GuildWarVector &guildWarVector) {
std::ostringstream query;
query << "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = " << guildId << " OR `guild2` = " << guildId << ") AND `ended` = 0 AND `status` = 1";
query << "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = " << guildId << " OR `guild2` = " << guildId << ") AND `status` = 1";

DBResult_ptr result = Database::getInstance().storeQuery(query.str());
if (!result) {
Expand Down

0 comments on commit 59b7abd

Please sign in to comment.