commit newest tfs branch only for compare

This commit is contained in:
ErikasKontenis
2020-01-02 19:39:21 +02:00
parent 0b0624a20b
commit 1f7dcd7347
160 changed files with 24900 additions and 10996 deletions

View File

@@ -1,6 +1,6 @@
/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
* The Forgotten Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 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
@@ -25,6 +25,10 @@
#include "configmanager.h"
#include "scheduler.h"
double Creature::speedA = 857.36;
double Creature::speedB = 261.29;
double Creature::speedC = -4795.01;
extern Game g_game;
extern ConfigManager g_config;
extern CreatureEvents* g_creatureEvents;
@@ -38,8 +42,7 @@ Creature::~Creature()
{
for (Creature* summon : summons) {
summon->setAttackedCreature(nullptr);
summon->setMaster(nullptr);
summon->decrementReferenceCounter();
summon->removeMaster();
}
for (Condition* condition : conditions) {
@@ -227,7 +230,7 @@ void Creature::onWalk(Direction& dir)
if (r < DIRECTION_DIAGONAL_MASK) {
dir = static_cast<Direction>(r);
}
g_game.internalCreatureSay(this, TALKTYPE_SAY, "Hicks!", false);
g_game.internalCreatureSay(this, TALKTYPE_MONSTER_SAY, "Hicks!", false);
}
}
}
@@ -307,7 +310,7 @@ void Creature::updateMapCache()
void Creature::updateTileCache(const Tile* tile, int32_t dx, int32_t dy)
{
if (std::abs(dx) <= maxWalkCacheWidth && std::abs(dy) <= maxWalkCacheHeight) {
localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx] = tile && tile->queryAdd(0, *this, 1, FLAG_PATHFINDING) == RETURNVALUE_NOERROR;
localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx] = tile && tile->queryAdd(0, *this, 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR;
}
}
@@ -409,7 +412,7 @@ void Creature::onRemoveCreature(Creature* creature, bool)
onCreatureDisappear(creature, true);
if (creature == this) {
if (master && !master->isRemoved()) {
master->removeSummon(this);
setMaster(nullptr);
}
} else if (isMapLoaded) {
if (creature->getPosition().z == getPosition().z) {
@@ -582,11 +585,6 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos
if (creature == followCreature || (creature == this && followCreature)) {
if (hasFollowPath) {
isUpdatingPath = true;
// this updates following walking
if (lastWalkUpdate == 0 || OTSYS_TIME() - lastWalkUpdate >= 250) {
g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game, getID())));
lastWalkUpdate = OTSYS_TIME();
}
}
if (newPos.z != oldPos.z || !canSee(followCreature->getPosition())) {
@@ -619,8 +617,7 @@ void Creature::onDeath()
if (lastHitCreature) {
lastHitUnjustified = lastHitCreature->onKilledCreature(this);
lastHitCreatureMaster = lastHitCreature->getMaster();
}
else {
} else {
lastHitCreatureMaster = nullptr;
}
@@ -642,6 +639,7 @@ void Creature::onDeath()
uint64_t gainExp = getGainedExperience(attacker);
if (Player* attackerPlayer = attacker->getPlayer()) {
attackerPlayer->removeAttacked(getPlayer());
Party* party = attackerPlayer->getParty();
if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
attacker = party->getLeader();
@@ -651,8 +649,7 @@ void Creature::onDeath()
auto tmpIt = experienceMap.find(attacker);
if (tmpIt == experienceMap.end()) {
experienceMap[attacker] = gainExp;
}
else {
} else {
tmpIt->second += gainExp;
}
}
@@ -676,7 +673,7 @@ void Creature::onDeath()
death(lastHitCreature);
if (master) {
master->removeSummon(this);
setMaster(nullptr);
}
if (droppedCorpse) {
@@ -686,41 +683,53 @@ void Creature::onDeath()
bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
Item* splash;
switch (getRace()) {
case RACE_VENOM:
splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_SLIME);
break;
if (!lootDrop && getMonster()) {
if (master) {
//scripting event - onDeath
const CreatureEventList& deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);
for (CreatureEvent* deathEvent : deathEvents) {
deathEvent->executeOnDeath(this, nullptr, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
}
}
case RACE_BLOOD:
splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
break;
g_game.addMagicEffect(getPosition(), CONST_ME_POFF);
} else {
Item* splash;
switch (getRace()) {
case RACE_VENOM:
splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_SLIME);
break;
default:
splash = nullptr;
break;
}
case RACE_BLOOD:
splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
break;
Tile* tile = getTile();
default:
splash = nullptr;
break;
}
if (splash) {
g_game.internalAddItem(tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
g_game.startDecay(splash);
}
Tile* tile = getTile();
Item* corpse = getCorpse(lastHitCreature, mostDamageCreature);
if (corpse) {
g_game.internalAddItem(tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
g_game.startDecay(corpse);
}
if (splash) {
g_game.internalAddItem(tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
g_game.startDecay(splash);
}
//scripting event - onDeath
for (CreatureEvent* deathEvent : getCreatureEvents(CREATURE_EVENT_DEATH)) {
deathEvent->executeOnDeath(this, corpse, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
}
Item* corpse = getCorpse(lastHitCreature, mostDamageCreature);
if (corpse) {
g_game.internalAddItem(tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
g_game.startDecay(corpse);
}
if (corpse) {
dropLoot(corpse->getContainer(), lastHitCreature);
//scripting event - onDeath
for (CreatureEvent* deathEvent : getCreatureEvents(CREATURE_EVENT_DEATH)) {
deathEvent->executeOnDeath(this, corpse, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
}
if (corpse) {
dropLoot(corpse->getContainer(), lastHitCreature);
}
}
return true;
@@ -781,28 +790,6 @@ BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int3
damage = 0;
blockType = BLOCK_IMMUNITY;
} else if (checkDefense || checkArmor) {
if (checkDefense && OTSYS_TIME() >= earliestDefendTime) {
damage -= getDefense();
earliestDefendTime = lastDefendTime + 2000;
lastDefendTime = OTSYS_TIME();
if (damage <= 0) {
damage = 0;
blockType = BLOCK_DEFENSE;
}
}
if (checkArmor) {
if (damage > 0 && combatType == COMBAT_PHYSICALDAMAGE) {
damage -= getArmor();
if (damage <= 0) {
damage = 0;
blockType = BLOCK_ARMOR;
}
}
}
bool hasDefense = false;
if (blockCount > 0) {
@@ -810,6 +797,30 @@ BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int3
hasDefense = true;
}
if (checkDefense && hasDefense && canUseDefense) {
int32_t defense = getDefense();
damage -= uniform_random(defense / 2, defense);
if (damage <= 0) {
damage = 0;
blockType = BLOCK_DEFENSE;
checkArmor = false;
}
}
if (checkArmor) {
int32_t armor = getArmor();
if (armor > 3) {
damage -= uniform_random(armor / 2, armor - (armor % 2 + 1));
} else if (armor > 0) {
--damage;
}
if (damage <= 0) {
damage = 0;
blockType = BLOCK_ARMOR;
}
}
if (hasDefense && blockType != BLOCK_NONE) {
onBlockHit();
}
@@ -833,16 +844,6 @@ bool Creature::setAttackedCreature(Creature* creature)
return false;
}
if (isSummon() && master) {
if (Monster* monster = master->getMonster()) {
if (monster->mType->info.targetDistance <= 1) {
if (!monster->hasFollowPath && !monster->followCreature) {
return false;
}
}
}
}
attackedCreature = creature;
onAttackedCreature(attackedCreature);
attackedCreature->onAttacked();
@@ -1026,9 +1027,21 @@ void Creature::onTickCondition(ConditionType_t type, bool& bRemove)
case CONDITION_POISON:
bRemove = (field->getCombatType() != COMBAT_EARTHDAMAGE);
break;
case CONDITION_FREEZING:
bRemove = (field->getCombatType() != COMBAT_ICEDAMAGE);
break;
case CONDITION_DAZZLED:
bRemove = (field->getCombatType() != COMBAT_HOLYDAMAGE);
break;
case CONDITION_CURSED:
bRemove = (field->getCombatType() != COMBAT_DEATHDAMAGE);
break;
case CONDITION_DROWN:
bRemove = (field->getCombatType() != COMBAT_DROWNDAMAGE);
break;
case CONDITION_BLEEDING:
bRemove = (field->getCombatType() != COMBAT_PHYSICALDAMAGE);
break;
default:
break;
}
@@ -1051,15 +1064,8 @@ void Creature::onAttackedCreatureDrainHealth(Creature* target, int32_t points)
bool Creature::onKilledCreature(Creature* target, bool)
{
if (latestKillEvent == target->getID()) {
return false;
}
latestKillEvent = target->getID();
if (master) {
master->onKilledCreature(target);
return false;
}
//scripting event - onKill
@@ -1079,28 +1085,43 @@ void Creature::onGainExperience(uint64_t gainExp, Creature* target)
gainExp /= 2;
master->onGainExperience(gainExp, target);
g_game.addAnimatedText(position, TEXTCOLOR_WHITE_EXP, std::to_string(gainExp));
}
void Creature::addSummon(Creature* creature)
{
creature->setDropLoot(false);
creature->setLossSkill(false);
creature->setMaster(this);
creature->incrementReferenceCounter();
summons.push_back(creature);
}
void Creature::removeSummon(Creature* creature)
{
auto cit = std::find(summons.begin(), summons.end(), creature);
if (cit != summons.end()) {
creature->setDropLoot(true);
creature->setLossSkill(true);
creature->setMaster(nullptr);
creature->decrementReferenceCounter();
summons.erase(cit);
SpectatorVec spectators;
g_game.map.getSpectators(spectators, position, false, true);
if (spectators.empty()) {
return;
}
TextMessage message(MESSAGE_EXPERIENCE_OTHERS, ucfirst(getNameDescription()) + " gained " + std::to_string(gainExp) + (gainExp != 1 ? " experience points." : " experience point."));
message.position = position;
message.primary.color = TEXTCOLOR_WHITE_EXP;
message.primary.value = gainExp;
for (Creature* spectator : spectators) {
spectator->getPlayer()->sendTextMessage(message);
}
}
bool Creature::setMaster(Creature* newMaster) {
if (!newMaster && !master) {
return false;
}
if (newMaster) {
incrementReferenceCounter();
newMaster->summons.push_back(this);
}
Creature* oldMaster = master;
master = newMaster;
if (oldMaster) {
auto summon = std::find(oldMaster->summons.begin(), oldMaster->summons.end(), this);
if (summon != oldMaster->summons.end()) {
oldMaster->summons.erase(summon);
decrementReferenceCounter();
}
}
return true;
}
bool Creature::addCondition(Condition* condition, bool force/* = false*/)
@@ -1259,20 +1280,21 @@ Condition* Creature::getCondition(ConditionType_t type, ConditionId_t conditionI
void Creature::executeConditions(uint32_t interval)
{
auto it = conditions.begin(), end = conditions.end();
while (it != end) {
Condition* condition = *it;
ConditionList tempConditions{ conditions };
for (Condition* condition : tempConditions) {
auto it = std::find(conditions.begin(), conditions.end(), condition);
if (it == conditions.end()) {
continue;
}
if (!condition->executeCondition(this, interval)) {
ConditionType_t type = condition->getType();
it = conditions.erase(it);
condition->endCondition(this);
delete condition;
onEndCondition(type);
} else {
++it;
it = std::find(conditions.begin(), conditions.end(), condition);
if (it != conditions.end()) {
conditions.erase(it);
condition->endCondition(this);
onEndCondition(condition->getType());
delete condition;
}
}
}
}
@@ -1289,7 +1311,7 @@ bool Creature::hasCondition(ConditionType_t type, uint32_t subId/* = 0*/) const
continue;
}
if (condition->getEndTime() >= timeNow) {
if (condition->getEndTime() >= timeNow || condition->getTicks() == -1) {
return true;
}
}
@@ -1326,8 +1348,18 @@ int64_t Creature::getStepDuration() const
return 0;
}
uint32_t calculatedStepSpeed;
uint32_t groundSpeed;
int32_t stepSpeed = getStepSpeed();
if (stepSpeed > -Creature::speedB) {
calculatedStepSpeed = floor((Creature::speedA * log((stepSpeed / 2) + Creature::speedB) + Creature::speedC) + 0.5);
if (calculatedStepSpeed == 0) {
calculatedStepSpeed = 1;
}
} else {
calculatedStepSpeed = 1;
}
Item* ground = tile->getGround();
if (ground) {
@@ -1339,12 +1371,12 @@ int64_t Creature::getStepDuration() const
groundSpeed = 150;
}
double duration = std::floor(1000 * groundSpeed) / stepSpeed;
double duration = std::floor(1000 * groundSpeed / calculatedStepSpeed);
int64_t stepDuration = std::ceil(duration / 50) * 50;
const Monster* monster = getMonster();
if (monster && monster->isTargetNearby() && !monster->isFleeing() && !monster->getMaster()) {
stepDuration *= 3;
stepDuration *= 2;
}
return stepDuration;
@@ -1364,15 +1396,18 @@ int64_t Creature::getEventStepTicks(bool onlyDelay) const
return ret;
}
void Creature::getCreatureLight(LightInfo& light) const
LightInfo Creature::getCreatureLight() const
{
light = internalLight;
return internalLight;
}
void Creature::setCreatureLight(LightInfo lightInfo) {
internalLight = std::move(lightInfo);
}
void Creature::setNormalCreatureLight()
{
internalLight.level = 0;
internalLight.color = 0;
internalLight = {};
}
bool Creature::registerCreatureEvent(const std::string& name)
@@ -1440,6 +1475,10 @@ CreatureEventList Creature::getCreatureEvents(CreatureEventType_t type)
}
for (CreatureEvent* creatureEvent : eventsList) {
if (!creatureEvent->isLoaded()) {
continue;
}
if (creatureEvent->getEventType() == type) {
tmpEventList.push_back(creatureEvent);
}