Hi
I've been trying to install dual wielding to TFS 1.3 8.60 and been having problems.
used this dual-wielding.patch file
config.lua.rej
configmanager.cpp.rej
configmanager.h.rej
player.cpp.rej
player.h.rej
vocation.cpp.rej
vocation.h.rej
I've been trying to install dual wielding to TFS 1.3 8.60 and been having problems.
Feature - True dual wielding for TFS 1.x
I have seen a few dual wielding systems in the past but none of them was complete and simple to use. I started one from scratch that intends to be both simple, work out of the box and be easy to configure. As I am developing my own server, I want to share some of my patches with the community...
otland.net
dual-wielding.patch
drive.google.com
config.lua.rej
Code:
*************** maxMessageBuffer = 4
*** 71,76 ****
emoteSpells = false
classicEquipmentSlots = false
-- Rates
-- NOTE: rateExp is not used if you have enabled stages in data/XML/stages.xml
rateExp = 5
--- 71,84 ----
emoteSpells = false
classicEquipmentSlots = false
+ -- Dual wielding
+ -- NOTE: the rate are the percentage of the single-wielding values, for
+ -- example, if dualWieldingSpeedFactor is 200 then dual wielding attack will
+ -- be twice as fast. It makes no sense to set dualWieldingSpeedRate under 100.
+ allowDualWielding = false
+ dualWieldingSpeedRate = 200
+ dualWieldingDamageRate = 60
+
-- Rates
-- NOTE: rateExp is not used if you have enabled stages in data/XML/stages.xml
rateExp = 5
configmanager.cpp.rej
Code:
*************** bool ConfigManager::load()
*** 88,93 ****
boolean[WARN_UNSAFE_SCRIPTS] = getGlobalBoolean(L, "warnUnsafeScripts", true);
boolean[CONVERT_UNSAFE_SCRIPTS] = getGlobalBoolean(L, "convertUnsafeScripts", true);
boolean[CLASSIC_EQUIPMENT_SLOTS] = getGlobalBoolean(L, "classicEquipmentSlots", false);
string[DEFAULT_PRIORITY] = getGlobalString(L, "defaultPriority", "high");
string[SERVER_NAME] = getGlobalString(L, "serverName", "");
--- 88,94 ----
boolean[WARN_UNSAFE_SCRIPTS] = getGlobalBoolean(L, "warnUnsafeScripts", true);
boolean[CONVERT_UNSAFE_SCRIPTS] = getGlobalBoolean(L, "convertUnsafeScripts", true);
boolean[CLASSIC_EQUIPMENT_SLOTS] = getGlobalBoolean(L, "classicEquipmentSlots", false);
+ boolean[ALLOW_DUAL_WIELDING] = getGlobalBoolean(L, "allowDualWielding", false);
string[DEFAULT_PRIORITY] = getGlobalString(L, "defaultPriority", "high");
string[SERVER_NAME] = getGlobalString(L, "serverName", "");
configmanager.h.rej
Code:
*************** class ConfigManager
*** 44,49 ****
WARN_UNSAFE_SCRIPTS,
CONVERT_UNSAFE_SCRIPTS,
CLASSIC_EQUIPMENT_SLOTS,
LAST_BOOLEAN_CONFIG /* this must be the last one */
};
--- 44,50 ----
WARN_UNSAFE_SCRIPTS,
CONVERT_UNSAFE_SCRIPTS,
CLASSIC_EQUIPMENT_SLOTS,
+ ALLOW_DUAL_WIELDING,
LAST_BOOLEAN_CONFIG /* this must be the last one */
};
player.cpp.rej
Code:
*************** Player::Player(ProtocolGame* p) :
*** 108,113 ****
lastAttackBlockType = BLOCK_NONE;
addAttackSkillPoint = false;
lastAttack = 0;
blessings = 0;
--- 108,114 ----
lastAttackBlockType = BLOCK_NONE;
addAttackSkillPoint = false;
lastAttack = 0;
+ lastAttackHand = HAND_LEFT;
blessings = 0;
*************** void Player::getShieldAndWeapon(const Item*& shield, const Item*& weapon) const
*** 303,333 ****
shield = nullptr;
weapon = nullptr;
- for (uint32_t slot = CONST_SLOT_RIGHT; slot <= CONST_SLOT_LEFT; slot++) {
- Item* item = inventory[slot];
- if (!item) {
- continue;
}
- switch (item->getWeaponType()) {
- case WEAPON_NONE:
- break;
- case WEAPON_SHIELD: {
- if (!shield || (shield && item->getDefense() > shield->getDefense())) {
- shield = item;
}
- break;
- }
- default: { // weapons that are not shields
- weapon = item;
- break;
}
}
}
}
int32_t Player::getDefense() const
{
int32_t baseDefense = 5;
--- 309,358 ----
shield = nullptr;
weapon = nullptr;
+ if (isDualWielding()) {
+ if (lastAttackHand == HAND_LEFT) {
+ shield = inventory[CONST_SLOT_RIGHT];
+ weapon = inventory[CONST_SLOT_LEFT];
+ } else {
+ shield = inventory[CONST_SLOT_LEFT];
+ weapon = inventory[CONST_SLOT_RIGHT];
}
+ } else {
+ for (uint32_t slot = CONST_SLOT_RIGHT; slot <= CONST_SLOT_LEFT; slot++) {
+ Item *item = inventory[slot];
+ if (!item) {
+ continue;
+ }
+ switch (item->getWeaponType()) {
+ case WEAPON_NONE:
+ break;
+ case WEAPON_SHIELD: {
+ if (!shield || (shield && item->getDefense() > shield->getDefense())) {
+ shield = item;
+ }
+ break;
}
+ default: { // weapons that are not shields
+ weapon = item;
+ break;
+ }
}
}
}
}
+ bool Player::isDualWielding() const
+ {
+ /* Not checking dual wield because the player can't wear two weapons worn without it */
+ if (this->getWeapon(CONST_SLOT_LEFT, true) && this->getWeapon(CONST_SLOT_RIGHT, true)) {
+ return true;
+ }
+ return false;
+ }
+
int32_t Player::getDefense() const
{
int32_t baseDefense = 5;
player.h.rej
Code:
*************** class Player final : public Creature, public Cylinder
*** 1223,1228 ****
chaseMode_t chaseMode;
fightMode_t fightMode;
AccountType_t accountType;
bool secureMode;
bool inMarket;
--- 1241,1248 ----
chaseMode_t chaseMode;
fightMode_t fightMode;
AccountType_t accountType;
+ attackHand_t lastAttackHand;
+ bool blockSkillAdvance;
bool secureMode;
bool inMarket;
vocation.cpp.rej
Code:
*************** Vocation::Vocation(uint16_t id)
*** 193,198 ****
clientId = 0;
fromVocation = VOCATION_NONE;
gainCap = 500;
gainMana = 5;
--- 197,203 ----
clientId = 0;
fromVocation = VOCATION_NONE;
+ dualWield = true;
gainCap = 500;
gainMana = 5;
vocation.h.rej
Code:
*************** class Vocation
*** 86,91 ****
return fromVocation;
}
float meleeDamageMultiplier, distDamageMultiplier, defenseMultiplier, armorMultiplier;
protected:
--- 86,95 ----
return fromVocation;
}
+ bool canDualWield() const {
+ return dualWield;
+ }
+
float meleeDamageMultiplier, distDamageMultiplier, defenseMultiplier, armorMultiplier;
protected: