Skip to content

Commit

Permalink
Adding events
Browse files Browse the repository at this point in the history
Change related to event methods.
  • Loading branch information
joseluis2g committed Jan 21, 2019
1 parent 2412e3a commit db810e4
Show file tree
Hide file tree
Showing 11 changed files with 1,264 additions and 163 deletions.
28 changes: 28 additions & 0 deletions data/events/events.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<events>
<!-- Creature methods -->
<event class="Creature" method="onChangeOutfit" enabled="0" />
<event class="Creature" method="onAreaCombat" enabled="0" />
<event class="Creature" method="onTargetCombat" enabled="0" />

<!-- Party methods -->
<event class="Party" method="onJoin" enabled="0" />
<event class="Party" method="onLeave" enabled="0" />
<event class="Party" method="onDisband" enabled="0" />
<event class="Party" method="onShareExperience" enabled="1" />

<!-- Player methods -->
<event class="Player" method="onLook" enabled="1" />
<event class="Player" method="onLookInBattleList" enabled="1" />
<event class="Player" method="onLookInTrade" enabled="1" />
<event class="Player" method="onMoveItem" enabled="1" />
<event class="Player" method="onItemMoved" enabled="0" />
<event class="Player" method="onMoveCreature" enabled="0" />
<event class="Player" method="onReportBug" enabled="1" />
<event class="Player" method="onTurn" enabled="0" />
<event class="Player" method="onTradeRequest" enabled="0" />
<event class="Player" method="onTradeAccept" enabled="0" />
<event class="Player" method="onGainExperience" enabled="1" />
<event class="Player" method="onLoseExperience" enabled="0" />
<event class="Player" method="onGainSkillTries" enabled="1" />
</events>
11 changes: 11 additions & 0 deletions data/events/scripts/creature.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function Creature:onChangeOutfit(outfit)
return true
end

function Creature:onAreaCombat(tile, isAggressive)
return RETURNVALUE_NOERROR
end

function Creature:onTargetCombat(target)
return RETURNVALUE_NOERROR
end
35 changes: 35 additions & 0 deletions data/events/scripts/party.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
function Party:onJoin(player)
return true
end

function Party:onLeave(player)
return true
end

function Party:onDisband()
return true
end

function Party:onShareExperience(exp)
local sharedExperienceMultiplier = 1.20 --20%
local vocationsIds = {}

local vocationId = self:getLeader():getVocation():getBase():getId()
if vocationId ~= VOCATION_NONE then
table.insert(vocationsIds, vocationId)
end

for _, member in ipairs(self:getMembers()) do
vocationId = member:getVocation():getBase():getId()
if not table.contains(vocationsIds, vocationId) and vocationId ~= VOCATION_NONE then
table.insert(vocationsIds, vocationId)
end
end

local size = #vocationsIds
if size > 1 then
sharedExperienceMultiplier = 1.0 + ((size * (5 * (size - 1) + 10)) / 100)
end

return (exp * sharedExperienceMultiplier) / (#self:getMembers() + 1)
end
166 changes: 166 additions & 0 deletions data/events/scripts/player.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
function Player:onLook(thing, position, distance)
local description = "You see " .. thing:getDescription(distance)
if self:getGroup():getAccess() then
if thing:isItem() then
description = string.format("%s\nItem ID: %d", description, thing:getId())

local actionId = thing:getActionId()
if actionId ~= 0 then
description = string.format("%s, Action ID: %d", description, actionId)
end

local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_MOVEMENTID)
if uniqueId > 0 and uniqueId < 65536 then
description = string.format("%s, Movement ID: %d", description, uniqueId)
end

local itemType = thing:getType()

local transformEquipId = itemType:getTransformEquipId()
local transformDeEquipId = itemType:getTransformDeEquipId()
if transformEquipId ~= 0 then
description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId)
elseif transformDeEquipId ~= 0 then
description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId)
end

local decayId = itemType:getDecayId()
if decayId ~= -1 then
description = string.format("%s\nDecays to: %d", description, decayId)
end
elseif thing:isCreature() then
local str = "%s\nHealth: %d / %d"
if thing:isPlayer() and thing:getMaxMana() > 0 then
str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana())
end
description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. "."
end

local position = thing:getPosition()
description = string.format(
"%s\nPosition: %d, %d, %d",
description, position.x, position.y, position.z
)

if thing:isCreature() then
if thing:isPlayer() then
description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp()))
end
end
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInBattleList(creature, distance)
local description = "You see " .. creature:getDescription(distance)
if self:getGroup():getAccess() then
local str = "%s\nHealth: %d / %d"
if creature:isPlayer() and creature:getMaxMana() > 0 then
str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana())
end
description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "."

local position = creature:getPosition()
description = string.format(
"%s\nPosition: %d, %d, %d",
description, position.x, position.y, position.z
)

if creature:isPlayer() then
description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp()))
end
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInTrade(partner, item, distance)
self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance))
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
return true
end

function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
end

function Player:onMoveCreature(creature, fromPosition, toPosition)
return true
end

function Player:onReportBug(message, position, category)
if self:getAccountType() == ACCOUNT_TYPE_NORMAL then
return false
end

local name = self:getName()
local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a")

if not file then
self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "There was an error when processing your report, please contact a gamemaster.")
return true
end

io.output(file)
io.write("------------------------------\n")
io.write("Name: " .. name)
if category == BUG_CATEGORY_MAP then
io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", " .. position.z .. "]")
end
local playerPosition = self:getPosition()
io.write(" [Player Position: " .. playerPosition.x .. ", " .. playerPosition.y .. ", " .. playerPosition.z .. "]\n")
io.write("Comment: " .. message .. "\n")
io.close(file)

self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Your report has been sent to " .. configManager.getString(configKeys.SERVER_NAME) .. ".")
return true
end

function Player:onTurn(direction)
return true
end

function Player:onTradeRequest(target, item)
return true
end

function Player:onTradeAccept(target, item, targetItem)
return true
end

local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)

function Player:onGainExperience(source, exp, rawExp)
if not source or source:isPlayer() then
return exp
end

-- Soul regeneration
local vocation = self:getVocation()
if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
self:addCondition(soulCondition)
end

-- Apply experience stage multiplier
exp = exp * Game.getExperienceStage(self:getLevel())

return exp
end

function Player:onLoseExperience(exp)
return exp
end

function Player:onGainSkillTries(skill, tries)
if APPLY_SKILL_MULTIPLIER == false then
return tries
end

if skill == SKILL_MAGLEVEL then
return tries * configManager.getNumber(configKeys.RATE_MAGIC)
end
return tries * configManager.getNumber(configKeys.RATE_SKILL)
end
100 changes: 52 additions & 48 deletions src/combat.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2017 Alejandro Mujica <alejandrodemujica@gmail.com>
* Copyright (C) 2018 Alejandro Mujica <alejandrodemujica@gmail.com> and Mark Samman <mark.samman@gmail.com>
*
* 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
Expand All @@ -24,9 +24,11 @@
#include "game.h"
#include "configmanager.h"
#include "monster.h"
#include "events.h"

extern Game g_game;
extern ConfigManager g_config;
extern Events* g_events;

CombatDamage Combat::getCombatDamage(Creature* creature) const
{
Expand Down Expand Up @@ -204,7 +206,7 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive)
return RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE;
}

return RETURNVALUE_NOERROR;
return g_events->eventCreatureOnAreaCombat(caster, tile, aggressive);
}

bool Combat::isInPvpZone(const Creature* attacker, const Creature* target)
Expand All @@ -228,74 +230,76 @@ bool Combat::isProtected(const Player* attacker, const Player* target)

ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target)
{
if (attacker) {
if (const Player* targetPlayer = target->getPlayer()) {
if (targetPlayer->hasFlag(PlayerFlag_CannotBeAttacked)) {
if (!attacker) {
return g_events->eventCreatureOnTargetCombat(attacker, target);
}

if (const Player* targetPlayer = target->getPlayer()) {
if (targetPlayer->hasFlag(PlayerFlag_CannotBeAttacked)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

if (const Player* attackerPlayer = attacker->getPlayer()) {
if (attackerPlayer->hasFlag(PlayerFlag_CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

if (const Player* attackerPlayer = attacker->getPlayer()) {
if (attackerPlayer->hasFlag(PlayerFlag_CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
if (isProtected(attackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

if (isProtected(attackerPlayer, targetPlayer)) {
//nopvp-zone
const Tile* targetPlayerTile = targetPlayer->getTile();
if (targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
} else if (attackerPlayer->getTile()->hasFlag(TILESTATE_NOPVPZONE) && !targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE | TILESTATE_PROTECTIONZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}
}

if (attacker->isSummon()) {
if (const Player* masterAttackerPlayer = attacker->getMaster()->getPlayer()) {
if (masterAttackerPlayer->hasFlag(PlayerFlag_CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

//nopvp-zone
const Tile* targetPlayerTile = targetPlayer->getTile();
if (targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
} else if (attackerPlayer->getTile()->hasFlag(TILESTATE_NOPVPZONE) && !targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE | TILESTATE_PROTECTIONZONE)) {
if (targetPlayer->getTile()->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}
}

if (attacker->isSummon()) {
if (const Player* masterAttackerPlayer = attacker->getMaster()->getPlayer()) {
if (masterAttackerPlayer->hasFlag(PlayerFlag_CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

if (targetPlayer->getTile()->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}

if (isProtected(masterAttackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
if (isProtected(masterAttackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
}
} else if (target->getMonster()) {
if (const Player* attackerPlayer = attacker->getPlayer()) {
if (attackerPlayer->hasFlag(PlayerFlag_CannotAttackMonster)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
}
} else if (target->getMonster()) {
if (const Player* attackerPlayer = attacker->getPlayer()) {
if (attackerPlayer->hasFlag(PlayerFlag_CannotAttackMonster)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}

if (target->isSummon() && target->getMaster()->getPlayer() && target->getZone() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}
if (target->isSummon() && target->getMaster()->getPlayer() && target->getZone() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}
}
}

if (g_game.getWorldType() == WORLD_TYPE_NO_PVP) {
if (attacker->getPlayer() || (attacker->isSummon() && attacker->getMaster()->getPlayer())) {
if (target->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
if (g_game.getWorldType() == WORLD_TYPE_NO_PVP) {
if (attacker->getPlayer() || (attacker->isSummon() && attacker->getMaster()->getPlayer())) {
if (target->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
}

if (target->isSummon() && target->getMaster()->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
if (target->isSummon() && target->getMaster()->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
}
}
}
return RETURNVALUE_NOERROR;
return g_events->eventCreatureOnTargetCombat(attacker, target);
}

void Combat::setPlayerCombatValues(formulaType_t formulaType, double mina, double minb, double maxa, double maxb)
Expand Down
Loading

0 comments on commit db810e4

Please sign in to comment.