• 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!

Dual wield, extra attack and speed.

Drakens

New Member
Joined
Jul 10, 2008
Messages
19
Reaction score
0
Hi.
On another OT forum i have found this script by nfries88

in player.h, after:

Code:
virtual uint32_t getAttackSpeed();

add:

Code:
#ifdef __ITEMS_EXT__
	Item* nextWeapon;
	void findNextWeapon();
	Item* getWeaponLeft() const;
	Item* getWeaponRight() const;
	Item* getWeaponAmmo() const;
	int32_t getAttack() const;
	friend class WeaponMelee;
#endif //__ITEMS_EXT__

in item.h, after:

Code:
virtual void __startDecaying();

add:

Code:
#ifdef __ITEMS_EXT__
	bool isDualWield() const { return items[id].dualWield; }
	int getAttackSpeed() const { return items[id].atkSpeed; };
	int getExtraAtk() const {return items[id].extraAtk;}
#endif //__ITEMS_EXT__

in item.cpp (function Item::getDescription), replace:

Code:
if(getExtraDef()){
					s << " (Atk:" << (int)getAttack() << " Def:" << (int)getDefense() << " " << std::showpos << (int)getExtraDef() << ")" << std::noshowpos;
				}
				else{
					s << " (Atk:" << (int)getAttack() << " Def:" << (int)getDefense() << ")";
				}

with:

Code:
#ifndef __ITEMS_EXT__
				if(getExtraDef()){
					s << " (Atk:" << (int)getAttack() << " Def:" << (int)getDefense() << " " << std::showpos << (int)getExtraDef() << ")" << std::noshowpos;
				}
				else{
					s << " (Atk:" << (int)getAttack() << " Def:" << (int)getDefense() << ")";
				}
				#else
				s << "(Atk:" << (int)getAttack() << " ";
				if(getExtraAtk()) s << std::showpos << (int)getExtraAtk() << std::noshowpos << " ";
				s << "Def:" << (int)getDefense();
				if(getExtraDef()) s << " " << std::showpos << (int)getExtraDef() << std::noshowpos;
				s << ")";
				#endif //__ITEMS_EXT__
in player.cpp (function Player::player), after:

Code:
#ifdef __SKULLSYSTEM__
redSkullTicks = 0;
skull = SKULL_NONE;
#endif

add:


Code:
#ifdef __ITEMS_EXT__
    nextWeapon = NULL;
#endif //__ITEMS_EXT__

in player.cpp, replace the function Player::getWeapon with:

Code:
Item* Player::getWeapon()
{
	#ifndef __ITEMS_EXT__
    Item* item;

	for(uint32_t slot = SLOT_RIGHT; slot <= SLOT_LEFT; slot++){
		item = getInventoryItem((slots_t)slot);
		if(!item){
			continue;
		}

		switch(item->getWeaponType()){
			case WEAPON_SWORD:
			case WEAPON_AXE:
			case WEAPON_CLUB:
			case WEAPON_WAND:
			{
				const Weapon* weapon = g_weapons->getWeapon(item);
				if(weapon){
					return item;
				}

				break;
			}

			case WEAPON_DIST:
			{
				if(item->getAmuType() != AMMO_NONE){
					Item* ammuItem = getInventoryItem(SLOT_AMMO);

					if(ammuItem && ammuItem->getAmuType() == item->getAmuType()){
						const Weapon* weapon = g_weapons->getWeapon(ammuItem);
						if(weapon){
							shootRange = item->getShootRange();
							return ammuItem;
						}
					}
				}
				else{
					const Weapon* weapon = g_weapons->getWeapon(item);
					if(weapon){
						return item;
					}
				}
			}

			default:
				break;
		}
	}

	return NULL;
	#else
	Item* ammoWeapon = getWeaponAmmo();
	if(ammoWeapon) return ammoWeapon;
    return nextWeapon;
	#endif //__ITEMS_EXT__
}
in player.cpp, replace the function Player::getShieldAndWeapon with:

Code:
void Player::getShieldAndWeapon(const Item* &shield, const Item* &weapon) const
{
	#ifndef __ITEMS_EXT__
    Item* item;
	shield = NULL;
	weapon = NULL;
	for(uint32_t slot = SLOT_RIGHT; slot <= SLOT_LEFT; slot++){
		item = getInventoryItem((slots_t)slot);
		if(item){
			switch(item->getWeaponType()){
			case WEAPON_NONE:
				break;
			case WEAPON_SHIELD:
				shield = item;
				break;
			default: // weapons that are not shields
				weapon = item;
				break;
			}
		}
	}
	return;
	#else
	shield = (nextWeapon == getWeaponLeft()) ? getWeaponRight() : getWeaponLeft();
	weapon = nextWeapon;
	#endif //__ITEMS_EXT__
}

in player.cpp, at the end of function Player:nRemoveInventoryItem, add:

Code:
#ifdef __ITEMS_EXT__
	if(item == nextWeapon)
	{
	   nextWeapon = NULL;
       findNextWeapon();
       attackTicks = getAttackSpeed();
    }
#endif //__ITEMS_EXT__
in player.cpp, before the function Player::__queryAdd , add:

Code:
#ifdef __ITEMS_EXT__
#define ISREALLYAWEAPON(__item__)\
(__item__->getWeaponType() != WEAPON_AMMO && __item__->getWeaponType() != WEAPON_SHIELD && __item__->getWeaponType() != WEAPON_NONE)
#endif //__ITEMS_EXT__

in player.cpp, replace:

Code:
//check if weapon, can only carry one weapon
						else if(item != inventory[SLOT_LEFT] && inventory[SLOT_LEFT]->isWeapon() &&
							(inventory[SLOT_LEFT]->getWeaponType() != WEAPON_SHIELD) &&
							(inventory[SLOT_LEFT]->getWeaponType() != WEAPON_AMMO) &&
							item->isWeapon() && (item->getWeaponType() != WEAPON_SHIELD) && (item->getWeaponType() != WEAPON_AMMO)){
								ret = RET_CANONLYUSEONEWEAPON;
						}

with:

Code:
#ifndef __ITEMS_EXT__
						//check if weapon, can only carry one weapon
						else if(item != inventory[SLOT_LEFT] && inventory[SLOT_LEFT]->isWeapon() &&
							(inventory[SLOT_LEFT]->getWeaponType() != WEAPON_SHIELD) &&
							(inventory[SLOT_LEFT]->getWeaponType() != WEAPON_AMMO) &&
							item->isWeapon() && (item->getWeaponType() != WEAPON_SHIELD) && (item->getWeaponType() != WEAPON_AMMO)){
								ret = RET_CANONLYUSEONEWEAPON;
						}
#else
						else if(item != inventory[SLOT_LEFT] && item->isWeapon())
						{
							Item* i = getWeaponLeft();
							if(i && ((!item->isDualWield() && ISREALLYAWEAPON(item))
                             && (!i->isDualWield() && ISREALLYAWEAPON(i))))
								ret = RET_CANONLYUSEONEWEAPON;
							else
								ret = RET_NOERROR;
						}
#endif //__ITEMS_EXT__

and replace:

Code:
//check if weapon, can only carry one weapon
						else if(item != inventory[SLOT_RIGHT] && inventory[SLOT_RIGHT]->isWeapon() &&
							(inventory[SLOT_RIGHT]->getWeaponType() != WEAPON_SHIELD) &&
							(inventory[SLOT_RIGHT]->getWeaponType() != WEAPON_AMMO) &&
							item->isWeapon() && (item->getWeaponType() != WEAPON_SHIELD) && (item->getWeaponType() != WEAPON_AMMO)){
								ret = RET_CANONLYUSEONEWEAPON;
						}

with:

Code:
#ifndef __ITEMS_EXT__
						//check if weapon, can only carry one weapon
						else if(item != inventory[SLOT_RIGHT] && inventory[SLOT_RIGHT]->isWeapon() &&
							(inventory[SLOT_RIGHT]->getWeaponType() != WEAPON_SHIELD) &&
							(inventory[SLOT_RIGHT]->getWeaponType() != WEAPON_AMMO) &&
							item->isWeapon() && (item->getWeaponType() != WEAPON_SHIELD) && (item->getWeaponType() != WEAPON_AMMO)){
								ret = RET_CANONLYUSEONEWEAPON;
						}
#else
						else if(item != inventory[SLOT_RIGHT] && item->isWeapon())
						{
							Item* i = getWeaponRight();
							if(i && ((!item->isDualWield() && ISREALLYAWEAPON(item))
                             && (!i->isDualWield() && ISREALLYAWEAPON(i))))
								ret = RET_CANONLYUSEONEWEAPON;
							else
								ret = RET_NOERROR;
						}
#endif //__ITEMS_EXT__

in player.cpp, replace the function Player::getAttackSpeed with:

Code:
uint32_t Player::getAttackSpeed()
{
#ifndef __FAST_ATTACK__
#define ATTK_DELAY 2000
#else
#define ATTK_DELAY g_config.getNumber(ConfigManager::ATTACK_DELAY)
#endif //__FAST_ATTACK__
#ifndef __ITEMS_EXT__
	return ATTK_DELAY;
#else
	return nextWeapon?nextWeapon->getAttackSpeed():ATTK_DELAY; //todo: individual weapon speeds
#endif //__ITEMS_EXT__
}

in player.cpp, after:

Code:
if(weapon && weapon->checkLastAction(this, 100)){
			attackTicks = 0;
			result = weapon->useWeapon(this, tool, attackedCreature);
		}
		else{
			attackTicks = 0;
			result = Weapon::useFist(this, attackedCreature);
		}

add:

Code:
#ifdef __ITEMS_EXT__
		findNextWeapon();
#endif //__ITEMS_EXT__

at the bottom of player.cpp, add:

Code:
#ifdef __ITEMS_EXT__
Item* Player::getWeaponLeft() const
{
	Item* item = inventory[SLOT_LEFT];
	if(item){
		switch(item->getWeaponType()){
			case WEAPON_NONE: case WEAPON_AMMO:
				break;
			default:
				return item;
				break;
		}
	}
	return NULL;
}
Item* Player::getWeaponRight() const
{
	Item* item = inventory[SLOT_RIGHT];
	if(item){
		switch(item->getWeaponType()){
			case WEAPON_NONE: case WEAPON_AMMO:
				break;
			default:
				return item;
				break;
		}
	}
	return NULL;
}

void Player::findNextWeapon()
{
	Item* left = getWeaponLeft();
	Item* right = getWeaponRight();
	if((right != NULL) && (nextWeapon == left || (left == NULL) || left->getWeaponType() == WEAPON_SHIELD)) {
		nextWeapon = right;
	} else if((left != NULL) && (nextWeapon == right || (right == NULL) || right->getWeaponType() == WEAPON_SHIELD)) {
		nextWeapon = left;
	} else {
		nextWeapon = NULL;
	}
	if((nextWeapon != NULL)) {
		shootRange = nextWeapon->getShootRange();
	}
}

Item* Player::getWeaponAmmo() const
{
	if(!nextWeapon) return NULL;
	if(nextWeapon->getAmuType() != AMMO_NONE){
		Item* ammuItem = getInventoryItem(SLOT_AMMO);

		if(ammuItem && ammuItem->getAmuType() == nextWeapon->getAmuType()){
			const Weapon* weapon = g_weapons->getWeapon(ammuItem);
			if(weapon){
				return ammuItem;
			}
		}
	}
	return NULL;
}

int32_t Player::getAttack() const
{
    int32_t attack = 0;
	int32_t extraAtk = 0;
	int32_t defenseSkill = 0;
	const Item* weapon;
	const Item* shield;
	getShieldAndWeapon(shield, weapon);

	if(weapon){
		attack = weapon->getAttack();
	
		if(shield) // dual wield / shield attack bonus
			extraAtk = shield->getExtraAtk();
		else // wield one-handed weapon with two hands bonus
			extraAtk = weapon->getExtraAtk();
	}
	
	Item* ammo = getWeaponAmmo();
	if(ammo)
	{ 
		attack += ammo->getAttack();
	}

	return attack + extraAtk;
}
#endif //__ITEMS_EXT__
in weapons.cpp, replace:

Code:
int32_t attackValue = item->getAttack();

with:


Code:
#ifndef __ITEMS_EXT__
	int32_t attackValue = item->getAttack();
#else
	int32_t attackValue = player->getAttack();
#endif //__ITEMS_EXT__

in items.cpp, at the end of function ItemType::ItemType(), add:

Code:
#ifdef __ITEMS_EXT__
	dualWield = false;
	extraAtk = 0;
	atkSpeed = 2000;
#endif //__ITEMS_EXT__

in items.cpp, after:

Code:
else if(strcasecmp(strValue.c_str(), "attack") == 0){
								if(readXMLInteger(itemAttributesNode, "value", intValue)){
									it.attack = intValue;
								}
							}
add:

Code:
#ifdef __ITEMS_EXT__
							else if(strcasecmp(strValue.c_str(), "extraatk") == 0){
								if(readXMLInteger(itemAttributesNode, "value", intValue)){
									it.extraAtk = intValue;
								}
							}
							else if(strcasecmp(strValue.c_str(), "dualwield") == 0){
								if(readXMLInteger(itemAttributesNode, "value", intValue)){
									it.dualWield = (intValue != 0);
								}
							}
							else if(strcasecmp(strValue.c_str(), "attackspeed") == 0){
								if(readXMLInteger(itemAttributesNode, "value", intValue)){
									it.atkSpeed = (intValue > 100) ? intValue : 2000;
								}
							}
#endif //__ITEMS_EXT__

in items.h, after:

Code:
bool replaceable;

add:

Code:
#ifdef __ITEMS_EXT__
	bool dualWield;
	int extraAtk;
	int atkSpeed;
#endif //__ITEMS_EXT__
add -D__ITEMS_EXT__ to compiler definitions (C++ Compiler under Parameters in Project Options for Dev-C++ users) and rebuild all.

He says it's broken and it realy is. I tried to repair this code but 0 results. My request is to repair this code.

Drakens
 
Last edited:
Back
Top