• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • 2026 staff recruitment is open! Check it out and consider applying!

War System!

Enkiie

New Member
Joined
Apr 19, 2015
Messages
10
Reaction score
0
Hello, today I tried to compile trunk.r3777, and tried to add war system with it, changed the

" OPTIONAL_FLAGS="" "
to
" OPTIONAL_FLAGS="-D__WAR_SYSTEM__" "

and started the compiler and added all these scripts

[WAR-file]

function onSay(cid, words, param, channel)
local guild = getPlayerGuildId(cid)
if(not guild or getPlayerGuildLevel(cid) < GUILDLEVEL_LEADER) then
doPlayerSendChannelMessage(cid, "", "You cannot execute this talkaction.", TALKTYPE_CHANNEL_W, 0)
return true
end
local t = string.explode(param, ",")
if(not t[2]) then
doPlayerSendChannelMessage(cid, "", "Not enough param(s).", TALKTYPE_CHANNEL_W, 0)
return true
end
local enemy = getGuildId(t[2])
if(not enemy) then
doPlayerSendChannelMessage(cid, "", "Guild \"" .. t[2] .. "\" does not exists.", TALKTYPE_CHANNEL_W, 0)
return true
end
if(enemy == guild) then
doPlayerSendChannelMessage(cid, "", "You cannot perform war action on your own guild.", TALKTYPE_CHANNEL_W, 0)
return true
end
local enemyName, tmp = "", db.getResult("SELECT `name` FROM `guilds` WHERE `id` = " .. enemy)
if(tmp:getID() ~= -1) then
enemyName = tmp:getDataString("name")
tmp:free()
end
if(isInArray({"accept", "reject", "cancel"}, t[1])) then
local query = "`guild_id` = " .. enemy .. " AND `enemy_id` = " .. guild
if(t[1] == "cancel") then
query = "`guild_id` = " .. guild .. " AND `enemy_id` = " .. enemy
end
tmp = db.getResult("SELECT `id`, `begin`, `end`, `payment` FROM `guild_wars` WHERE " .. query .. " AND `status` = 0")
if(tmp:getID() == -1) then
doPlayerSendChannelMessage(cid, "", "Currently there's no pending invitation for a war with " .. enemyName .. ".", TALKTYPE_CHANNEL_W, 0)
return true
end
if(t[1] == "accept") then
local _tmp = db.getResult("SELECT `balance` FROM `guilds` WHERE `id` = " .. guild)
local state = _tmp:getID() < 0 or _tmp:getDataInt("balance") < tmp:getDataInt("payment")
_tmp:free()
if(state) then
doPlayerSendChannelMessage(cid, "", "Your guild balance is too low to accept this invitation.", TALKTYPE_CHANNEL_W, 0)
return true
end
db.executeQuery("UPDATE `guilds` SET `balance` = `balance` - " .. tmp:getDataInt("payment") .. " WHERE `id` = " .. guild)
end
query = "UPDATE `guild_wars` SET "
local msg = "accepted " .. enemyName .. " invitation to war."
if(t[1] == "reject") then
query = query .. "`end` = " .. os.time() .. ", `status` = 2"
msg = "rejected " .. enemyName .. " invitation to war."
elseif(t[1] == "cancel") then
query = query .. "`end` = " .. os.time() .. ", `status` = 3"
msg = "canceled invitation to a war with " .. enemyName .. "."
else
query = query .. "`begin` = " .. os.time() .. ", `end` = " .. (tmp:getDataInt("end") > 0 and (os.time() + ((tmp:getDataInt("begin") - tmp:getDataInt("end")) / 86400)) or 0) .. ", `status` = 1"
end
query = query .. " WHERE `id` = " .. tmp:getDataInt("id")
if(t[1] == "accept") then
doGuildAddEnemy(guild, enemy, tmp:getDataInt("id"), WAR_GUILD)
doGuildAddEnemy(enemy, guild, tmp:getDataInt("id"), WAR_ENEMY)
end
tmp:free()
db.executeQuery(query)
doBroadcastMessage(getPlayerGuildName(cid) .. " has " .. msg, MESSAGE_EVENT_ADVANCE)
return true
end
if(t[1] == "invite") then
local str = ""
tmp = db.getResult("SELECT `guild_id`, `status` FROM `guild_wars` WHERE `guild_id` IN (" .. guild .. "," .. enemy .. ") AND `enemy_id` IN (" .. enemy .. "," .. guild .. ") AND `status` IN (0, 1)")
if(tmp:getID() ~= -1) then
if(tmp:getDataInt("status") == 0) then
if(tmp:getDataInt("guild_id") == guild) then
str = "You have already invited " .. enemyName .. " to war."
else
str = enemyName .. " have already invited you to war."
end
else
str = "You are already on a war with " .. enemyName .. "."
end
tmp:free()
end
if(str ~= "") then
doPlayerSendChannelMessage(cid, "", str, TALKTYPE_CHANNEL_W, 0)
return true
end
local frags = tonumber(t[3])
if(frags ~= nil) then
frags = math.max(10, math.min(1000, frags))
else
frags = 100
end
local payment = tonumber(t[4])
if(payment ~= nil) then
payment = math.max(100000, math.min(1000000000, payment))
tmp = db.getResult("SELECT `balance` FROM `guilds` WHERE `id` = " .. guild)
local state = tmp:getID() < 0 or tmp:getDataInt("balance") < payment
tmp:free()
if(state) then
doPlayerSendChannelMessage(cid, "", "Your guild balance is too low for such payment.", TALKTYPE_CHANNEL_W, 0)
return true
end
db.executeQuery("UPDATE `guilds` SET `balance` = `balance` - " .. payment .. " WHERE `id` = " .. guild)
else
payment = 0
end
local begining, ending = os.time(), tonumber(t[5])
if(ending ~= nil and ending ~= 0) then
ending = begining + (ending * 86400)
else
ending = 0
end
db.executeQuery("INSERT INTO `guild_wars` (`guild_id`, `enemy_id`, `begin`, `end`, `frags`, `payment`) VALUES (" .. guild .. ", " .. enemy .. ", " .. begining .. ", " .. ending .. ", " .. frags .. ", " .. payment .. ");")
doBroadcastMessage(getPlayerGuildName(cid) .. " has invited " .. enemyName .. " to war till " .. frags .. " frags.", MESSAGE_EVENT_ADVANCE)
return true
end
if(not isInArray({"end", "finish"}, t[1])) then
return false
end
local status = (t[1] == "end" and 1 or 4)
tmp = db.getResult("SELECT `id` FROM `guild_wars` WHERE `guild_id` = " .. guild .. " AND `enemy_id` = " .. enemy .. " AND `status` = " .. status)
if(tmp:getID() ~= -1) then
local query = "UPDATE `guild_wars` SET `end` = " .. os.time() .. ", `status` = 5 WHERE `id` = " .. tmp:getDataInt("id")
tmp:free()
doGuildRemoveEnemy(guild, enemy)
doGuildRemoveEnemy(enemy, guild)
db.executeQuery(query)
doBroadcastMessage(getPlayerGuildName(cid) .. " has " .. (status == 4 and "mend fences" or "ended up a war") .. " with " .. enemyName .. ".", MESSAGE_EVENT_ADVANCE)
return true
end
if(status == 4) then
doPlayerSendChannelMessage(cid, "", "Currently there's no pending war truce from " .. enemyName .. ".", TALKTYPE_CHANNEL_W, 0)
return true
end
tmp = db.getResult("SELECT `id`, `end` FROM `guild_wars` WHERE `guild_id` = " .. enemy .. " AND `enemy_id` = " .. guild .. " AND `status` = 1")
if(tmp:getID() ~= -1) then
if(tmp:getDataInt("end") > 0) then
tmp:free()
doPlayerSendChannelMessage(cid, "", "You cannot request ending for war with " .. enemyName .. ".", TALKTYPE_CHANNEL_W, 0)
return true
end
local query = "UPDATE `guild_wars` SET `status` = 4, `end` = " .. os.time() .. " WHERE `id` = " .. tmp:getDataInt("id")
tmp:free()
db.executeQuery(query)
doBroadcastMessage(getPlayerGuildName(cid) .. " has signed an armstice declaration on a war with " .. enemyName .. ".", MESSAGE_EVENT_ADVANCE)
return true
end
doPlayerSendChannelMessage(cid, "", "Currently there's no active war with " .. enemyName .. ".", TALKTYPE_CHANNEL_W, 0)
return true
end
 
[BALANCE-file]

local function isValidMoney(value)
if(value == nil) then
return false
end

return (value > 0 and value <= 99999999999999)
end

function onSay(cid, words, param, channel)
local guild = getPlayerGuildId(cid)
if(guild == 0) then
return false
end

local t = string.explode(param, ' ', 1)
if(getPlayerGuildLevel(cid) == GUILDLEVEL_LEADER and isInArray({ 'pick' }, t[1])) then
if(t[1] == 'pick') then
local money = { tonumber(t[2]) }
if(not isValidMoney(money[1])) then
doPlayerSendChannelMessage(cid, '', 'Invalid amount of money specified.', TALKTYPE_CHANNEL_W, 0)
return true
end

local result = db.getResult('SELECT `balance` FROM `guilds` WHERE `id` = ' .. guild)
if(result:getID() == -1) then
return false
end

money[2] = result:getDataLong('balance')
result:free()

if(money[1] > money[2]) then
doPlayerSendChannelMessage(cid, '', 'The balance is too low for such amount.', TALKTYPE_CHANNEL_W, 0)
return true
end

if(not db.executeQuery('UPDATE `guilds` SET `balance` = `balance` - ' .. money[1] .. ' WHERE `id` = ' .. guild .. ' LIMIT 1;')) then
return false
end

doPlayerAddMoney(cid, money[1])
doPlayerSendChannelMessage(cid, '', 'You have just picked ' .. money[1] .. ' money from your guild balance.', TALKTYPE_CHANNEL_W, 0)
else
doPlayerSendChannelMessage(cid, '', 'Invalid sub-command.', TALKTYPE_CHANNEL_W, 0)
end
elseif(t[1] == 'donate') then
local money = tonumber(t[2])
if(not isValidMoney(money)) then
doPlayerSendChannelMessage(cid, '', 'Invalid amount of money specified.', TALKTYPE_CHANNEL_W, 0)
return true
end

if(getPlayerMoney(cid) < money) then
doPlayerSendChannelMessage(cid, '', 'You don\'t have enough money.', TALKTYPE_CHANNEL_W, 0)
return true
end

if(not doPlayerRemoveMoney(cid, money)) then
return false
end

db.executeQuery('UPDATE `guilds` SET `balance` = `balance` + ' .. money .. ' WHERE `id` = ' .. guild .. ' LIMIT 1;')
doPlayerSendChannelMessage(cid, '', 'You have transfered ' .. money .. ' money to your guild balance.', TALKTYPE_CHANNEL_W, 0)
else
local result = db.getResult('SELECT `name`, `balance` FROM `guilds` WHERE `id` = ' .. guild)
if(result:getID() == -1) then
return false
end

doPlayerSendChannelMessage(cid, '', 'Current balance of guild ' .. result:getDataString('name') .. ' is: ' .. result:getDataLong('balance') .. ' bronze coins.', TALKTYPE_CHANNEL_W, 0)
result:free()
end

return true
end

and to lib I added

WAR_GUILD = 0
WAR_ENEMY = 1

but then when I invite the other guild to an war it works but it does not work to accept it, and then this error comes:
pR5Vkuv.png


Can someone help me out?

Note: This is compiled with CodeBlocks and it is for 0.4!

The message was to long so I had to do it like this!
 
Check luascript.cpp if it contains (if not add it)
Code:
#ifdef __WAR_SYSTEM__

   //doGuildAddEnemy(guild, enemy, war, type)
   lua_register(m_luaState, "doGuildAddEnemy", LuaScriptInterface::luaDoGuildAddEnemy);

   //doGuildRemoveEnemy(guild, enemy)
   lua_register(m_luaState, "doGuildRemoveEnemy", LuaScriptInterface::luaDoGuildRemoveEnemy);
#endif

Code:
#ifdef __WAR_SYSTEM__

int32_t LuaScriptInterface::luaDoGuildAddEnemy(lua_State* L)
{
   //doGuildAddEnemy(guild, enemy, war, type)
   War_t war;
   war.type = (WarType_t)popNumber(L);
   war.war = popNumber(L);

   uint32_t enemy = popNumber(L), guild = popNumber(L), count = 0;
   for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
   {
     if(it->second->isRemoved() || it->second->getGuildId() != guild)
       continue;

     ++count;
     it->second->addEnemy(enemy, war);
     g_game.updateCreatureEmblem(it->second);
   }

   lua_pushnumber(L, count);
   return 1;
}

int32_t LuaScriptInterface::luaDoGuildRemoveEnemy(lua_State* L)
{
   //doGuildRemoveEnemy(guild, enemy)
   uint32_t enemy = popNumber(L), guild = popNumber(L), count = 0;
   for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
   {
     if(it->second->isRemoved() || it->second->getGuildId() != guild)
       continue;

     ++count;
     it->second->removeEnemy(enemy);
     g_game.updateCreatureEmblem(it->second);
   }

   lua_pushnumber(L, count);
   return 1;
}
#endif

luascript.h
Code:
#ifdef __WAR_SYSTEM__
     static int32_t luaDoGuildAddEnemy(lua_State* L);
     static int32_t luaDoGuildRemoveEnemy(lua_State* L);
#endif
 
Check luascript.cpp if it contains (if not add it)
Code:
#ifdef __WAR_SYSTEM__

   //doGuildAddEnemy(guild, enemy, war, type)
   lua_register(m_luaState, "doGuildAddEnemy", LuaScriptInterface::luaDoGuildAddEnemy);

   //doGuildRemoveEnemy(guild, enemy)
   lua_register(m_luaState, "doGuildRemoveEnemy", LuaScriptInterface::luaDoGuildRemoveEnemy);
#endif

Code:
#ifdef __WAR_SYSTEM__

int32_t LuaScriptInterface::luaDoGuildAddEnemy(lua_State* L)
{
   //doGuildAddEnemy(guild, enemy, war, type)
   War_t war;
   war.type = (WarType_t)popNumber(L);
   war.war = popNumber(L);

   uint32_t enemy = popNumber(L), guild = popNumber(L), count = 0;
   for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
   {
     if(it->second->isRemoved() || it->second->getGuildId() != guild)
       continue;

     ++count;
     it->second->addEnemy(enemy, war);
     g_game.updateCreatureEmblem(it->second);
   }

   lua_pushnumber(L, count);
   return 1;
}

int32_t LuaScriptInterface::luaDoGuildRemoveEnemy(lua_State* L)
{
   //doGuildRemoveEnemy(guild, enemy)
   uint32_t enemy = popNumber(L), guild = popNumber(L), count = 0;
   for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
   {
     if(it->second->isRemoved() || it->second->getGuildId() != guild)
       continue;

     ++count;
     it->second->removeEnemy(enemy);
     g_game.updateCreatureEmblem(it->second);
   }

   lua_pushnumber(L, count);
   return 1;
}
#endif

luascript.h
Code:
#ifdef __WAR_SYSTEM__
     static int32_t luaDoGuildAddEnemy(lua_State* L);
     static int32_t luaDoGuildRemoveEnemy(lua_State* L);
#endif
It all already exists. :<
 
remove the #ifdef __WAR_SYSTEM__ and #endif and compile again (only in luascript.cpp / h)
Your console says a nil value, which usually means the function does not exist..
I removed it, and it comes a bounch of errors now when compileing. Double checked and it all exists.
 
Do you have the tables in your database?
Code:
CREATE TABLE IF NOT EXISTS `guild_wars` (
`id` INT NOT NULL AUTO_INCREMENT,
`guild_id` INT NOT NULL,
`enemy_id` INT NOT NULL,
`begin` BIGINT NOT NULL DEFAULT '0',
`end` BIGINT NOT NULL DEFAULT '0',
`frags` INT UNSIGNED NOT NULL DEFAULT '0',
`payment` BIGINT UNSIGNED NOT NULL DEFAULT '0',
`guild_kills` INT UNSIGNED NOT NULL DEFAULT '0',
`enemy_kills` INT UNSIGNED NOT NULL DEFAULT '0',
`status` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `status` (`status`),
KEY `guild_id` (`guild_id`),
KEY `enemy_id` (`enemy_id`)
) ENGINE=InnoDB;

Try to create a test code in talkaction something like
Code:
function onSay(cid, words, param, channel)
local guild = 1 -- enter a guild id here here to test with
local enemy = 2 -- enter enemy guild id to test with
doGuildAddEnemy(guild, enemy, 1, WAR_GUILD)
end
 
Do you have the tables in your database?
Code:
CREATE TABLE IF NOT EXISTS `guild_wars` (
`id` INT NOT NULL AUTO_INCREMENT,
`guild_id` INT NOT NULL,
`enemy_id` INT NOT NULL,
`begin` BIGINT NOT NULL DEFAULT '0',
`end` BIGINT NOT NULL DEFAULT '0',
`frags` INT UNSIGNED NOT NULL DEFAULT '0',
`payment` BIGINT UNSIGNED NOT NULL DEFAULT '0',
`guild_kills` INT UNSIGNED NOT NULL DEFAULT '0',
`enemy_kills` INT UNSIGNED NOT NULL DEFAULT '0',
`status` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `status` (`status`),
KEY `guild_id` (`guild_id`),
KEY `enemy_id` (`enemy_id`)
) ENGINE=InnoDB;

Try to create a test code in talkaction something like
Code:
function onSay(cid, words, param, channel)
local guild = 1 -- enter a guild id here here to test with
local enemy = 2 -- enter enemy guild id to test with
doGuildAddEnemy(guild, enemy, 1, WAR_GUILD)
end

I added the table, didnt work same error.
 
Back
Top