introduce extra def and extra atk and inq several items

This commit is contained in:
ErikasKontenis 2022-04-16 11:56:43 +03:00
parent c7c4a194c1
commit 0ca1c4013c
18 changed files with 130 additions and 37 deletions

File diff suppressed because one or more lines are too long

View File

@ -4889,3 +4889,50 @@ Found work dir at 'C:/Users/erika/source/repos/Sabrehaven/800OTClient/'
OTCv8 3.1 rev 163 (dev) made by otclient.net built on Mar 31 2022 for arch x86
Connecting to: 127.0.0.1:7171
Login to 127.0.0.1:7172
Exiting application..
GPU Radeon RX 580 Series (ATI Technologies Inc.)
OpenGL 4.6.13596 Compatibility Profile Context 20.10.35.02 27.20.1034.6
[Atlas] Texture size is: 4096x4096 (max: 16384x16384)
ERROR: unable to open audio device
Found work dir at 'C:/Users/erika/source/repos/Sabrehaven/800OTClient/'
== application started at Apr 16 2022 10:22:19
OTCv8 3.1 rev 163 (dev) made by otclient.net built on Mar 31 2022 for arch x86
Connecting to: 127.0.0.1:7171
Login to 127.0.0.1:7172
Exiting application..
GPU Radeon RX 580 Series (ATI Technologies Inc.)
OpenGL 4.6.13596 Compatibility Profile Context 20.10.35.02 27.20.1034.6
[Atlas] Texture size is: 4096x4096 (max: 16384x16384)
ERROR: unable to open audio device
Found work dir at 'C:/Users/erika/source/repos/Sabrehaven/800OTClient/'
== application started at Apr 16 2022 10:27:57
OTCv8 3.1 rev 163 (dev) made by otclient.net built on Mar 31 2022 for arch x86
Connecting to: 127.0.0.1:7171
Login to 127.0.0.1:7172
Exiting application..
GPU Radeon RX 580 Series (ATI Technologies Inc.)
OpenGL 4.6.13596 Compatibility Profile Context 20.10.35.02 27.20.1034.6
[Atlas] Texture size is: 4096x4096 (max: 16384x16384)
ERROR: unable to open audio device
Found work dir at 'C:/Users/erika/source/repos/Sabrehaven/800OTClient/'
== application started at Apr 16 2022 10:43:38
OTCv8 3.1 rev 163 (dev) made by otclient.net built on Mar 31 2022 for arch x86
Connecting to: 127.0.0.1:7171
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Exiting application..
GPU Radeon RX 580 Series (ATI Technologies Inc.)
OpenGL 4.6.13596 Compatibility Profile Context 20.10.35.02 27.20.1034.6
[Atlas] Texture size is: 4096x4096 (max: 16384x16384)
ERROR: unable to open audio device
Found work dir at 'C:/Users/erika/source/repos/Sabrehaven/800OTClient/'
== application started at Apr 16 2022 11:02:37
OTCv8 3.1 rev 163 (dev) made by otclient.net built on Mar 31 2022 for arch x86
Connecting to: 127.0.0.1:7171
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172
Exiting application..

View File

@ -86,7 +86,7 @@
<action actionid="83" script="nostalrius/83.lua" />
<!-- Inquisition -->
<action itemid="7478" script="inquisition/holyWater.lua" />
<action itemid="133" script="inquisition/holyWater.lua" />
<!-- Pits of Inferno -->
<action actionid="17642" script="pits_of_inferno/oil.lua" />

View File

@ -214,9 +214,10 @@ Flags = {Bank,Unmove}
Attributes = {Waypoints=160}
TypeID = 133
Name = "sand"
Flags = {Bank,Unmove}
Attributes = {Waypoints=160}
Name = "a special flask"
Description = "It contains holy water from the white raven monastery"
Flags = {Take}
Attributes = {Weight=180}
TypeID = 134
Name = "dirt"
@ -26206,7 +26207,7 @@ TypeID = 5803
Name = "an arbalest"
Description = "It is a bit heavy due to the iron mounting, but very precise"
Flags = {Take,Distance}
Attributes = {Weight=9500,SlotType=TWOHANDED,Range=7,AmmoType=BOLT}
Attributes = {Weight=9500,SlotType=TWOHANDED,Range=6,AmmoType=BOLT,ExtraHitChance=3,Attack=2}
TypeID = 5804
Name = "a nose ring"
@ -33623,8 +33624,8 @@ Attributes = {Weight=2100,WeaponType=CLUB,Attack=37,Defense=18}
TypeID = 7438
Name = "an elvish bow"
Description = "This beautifully ornamented bow was made by a skilled elvish bowmaker"
Flags = {Take}
Attributes = {Weight=3900,WeaponType=DISTANCE,SlotType=TWOHANDED}
Flags = {Take,Distance}
Attributes = {Weight=3900,SlotType=TWOHANDED,Range=6,AmmoType=ARROW,ExtraHitChance=5}
TypeID = 7439
Name = "a berserk potion"
@ -33803,17 +33804,17 @@ TypeID = 7475
Name = "a sarcophagus"
Flags = {Bottom,Unpass,Unmove}
TypeID = 7476
TypeID = 8023
Name = "a royal crossbow"
Description = "It is a bit heavy due to the iron mounting, but very precise"
Flags = {Take,Distance}
Attributes = {Weight=12000,SlotType=TWOHANDED,Range=6,AmmoType=BOLT,ExtraHitChance=3,Attack=5}
TypeID = 12902
Name = "your inbox"
Flags = {Container,Unmove}
Attributes = {Capacity=30}
TypeID = 7477
TypeID = 12903
Name = "the market"
Flags = {Unmove}
TypeID = 7478
Name = "a special flask"
Description = "It contains holy water from the white raven monastery"
Flags = {Take}
Attributes = {Weight=180}
Flags = {Unmove}

View File

@ -57,6 +57,6 @@ topic=2 -> "I expected better from you."
"mission",QuestValue(12160)=3 -> "Listen, we have information about a heretic coven that hides in a mountain called the Big Old One. The witches reach this cursed place on flying brooms and think they are safe there. ...",
"I've arranged a flying carpet that will bring you to their hideout. Travel to Femor Hills and tell the carpet pilot the codeword 'eclipse' ...",
"He'll bring you to your destination. At their meeting place, you'll find a cauldron in which they cook some forbidden brew ...",
"Use this vial of holy water to destroy the brew. Also steal their grimoire and bring it to me.",SetQuestValue(12160,4),SetQuestValue(12162,1),Create(7478)
"Use this vial of holy water to destroy the brew. Also steal their grimoire and bring it to me.",SetQuestValue(12160,4),SetQuestValue(12162,1),Create(133)
"mission",QuestValue(12160)=4 -> "Your current mission is to destroy the brew in the eclipse."
}

View File

@ -55,17 +55,6 @@ CREATE TABLE `account_bans` (
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `player_inboxitems` (
`player_id` int NOT NULL,
`sid` int NOT NULL,
`pid` int NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`count` smallint NOT NULL DEFAULT '0',
`attributes` blob NOT NULL,
UNIQUE KEY `player_id_2` (`player_id`, `sid`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `market_history` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`player_id` int NOT NULL,

View File

@ -1035,6 +1035,9 @@ bool Combat::rangeAttack(Creature* attacker, Creature* target, fightMode_t fight
specialEffect = weapon->getWeaponSpecialEffect();
attackStrength = weapon->getAttackStrength();
attackVariation = weapon->getAttackVariation();
hitChance += Item::items.getItemType(weapon->getID()).extraHitChance;
if (weapon->getFragility()) {
if (normal_random(0, 99) <= weapon->getFragility()) {
uint16_t count = weapon->getItemCount();
@ -1054,6 +1057,9 @@ bool Combat::rangeAttack(Creature* attacker, Creature* target, fightMode_t fight
specialEffect = ammunition->getWeaponSpecialEffect();
attackStrength = ammunition->getAttackStrength();
attackVariation = ammunition->getAttackVariation();
hitChance += Item::items.getItemType(ammunition->getID()).extraHitChance;
if (normal_random(0, 100) <= ammunition->getFragility()) {
uint16_t count = ammunition->getItemCount();
if (count > 1) {
@ -1233,27 +1239,27 @@ void Combat::getAttackValue(Creature* creature, uint32_t& attackValue, uint32_t&
switch (weapon->getWeaponType()) {
case WEAPON_AXE: {
skill = SKILL_AXE;
attackValue = weapon->getAttack();
attackValue = weapon->getAttack() + Item::items.getItemType(weapon->getID()).extraAttack;
break;
}
case WEAPON_SWORD: {
skill = SKILL_SWORD;
attackValue = weapon->getAttack();
attackValue = weapon->getAttack() + Item::items.getItemType(weapon->getID()).extraAttack;
break;
}
case WEAPON_CLUB: {
skill = SKILL_CLUB;
attackValue = weapon->getAttack();
attackValue = weapon->getAttack() + Item::items.getItemType(weapon->getID()).extraAttack;
break;
}
case WEAPON_DISTANCE: {
skill = SKILL_DISTANCE;
attackValue = weapon->getAttack();
attackValue = weapon->getAttack() + Item::items.getItemType(weapon->getID()).extraAttack;
if (weapon->getAmmoType() != AMMO_NONE) {
Item* ammunition = player->getAmmunition();
if (ammunition && ammunition->getAmmoType() == weapon->getAmmoType()) {
attackValue += ammunition->getAttack();
attackValue += ammunition->getAttack() + Item::items.getItemType(ammunition->getID()).extraAttack;
}
}
break;

View File

@ -283,7 +283,7 @@ enum item_t : uint16_t {
ITEM_DEPOT = 3502,
ITEM_LOCKER1 = 3497,
ITEM_MARKET = 7477,
ITEM_MARKET = 12903,
ITEM_MALE_CORPSE = 4240,
ITEM_FEMALE_CORPSE = 4247,

View File

@ -881,9 +881,26 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance,
}
else if (it.weaponType != WEAPON_NONE) {
if (it.weaponType == WEAPON_DISTANCE && it.ammoType != AMMO_NONE) {
if (item->getAttack() != 0) {
s << ", Atk" << std::showpos << item->getAttack() << std::noshowpos;
s << " (";
if (item->getShootRange() != 0) {
s << "Range:" << static_cast<int>(item->getShootRange());
}
if (item->getAttack() != 0) {
if (item->getShootRange() != 0)
s << ", ";
s << "Atk" << std::showpos << item->getAttack() << std::noshowpos;
}
if (item->getExtraHitChance() != 0) {
if (item->getAttack() != 0 || item->getShootRange() != 0)
s << ", ";
s << "Hit%+" << static_cast<int>(item->getExtraHitChance());
}
s << ")";
}
else if (it.weaponType != WEAPON_WAND && (item->getAttack() != 0 || item->getDefense() != 0)) {
s << " (";

View File

@ -605,6 +605,9 @@ class Item : virtual public Thing
}
return items[id].shootRange;
}
uint8_t getExtraHitChance() const {
return items[id].extraHitChance;
}
uint8_t getMissileType() const {
return items[id].shootType;
}

View File

@ -421,6 +421,10 @@ bool Items::loadItems()
items[id].lightLevel = script.readNumber();
} else if (identifier == "lightcolor") {
items[id].lightColor = script.readNumber();
} else if (identifier == "extrahitchance") {
items[id].extraHitChance = script.readNumber();
} else if (identifier == "extraattack") {
items[id].extraAttack = script.readNumber();
} else if (identifier == "totalexpiretime") {
items[id].decayTime = script.readNumber();
} else if (identifier == "expiretarget") {

View File

@ -252,6 +252,8 @@ class ItemType
uint8_t lightColor = 0;
uint8_t shootRange = 1;
uint8_t weaponSpecialEffect = 0;
uint8_t extraHitChance = 0;
uint8_t extraAttack = 0;
bool collisionEvent = false;
bool separationEvent = false;

View File

@ -1052,6 +1052,15 @@ void LuaScriptInterface::registerFunctions()
registerEnum(ACCOUNT_TYPE_GAMEMASTER)
registerEnum(ACCOUNT_TYPE_GOD)
registerEnum(AMMO_NONE)
registerEnum(AMMO_BOLT)
registerEnum(AMMO_ARROW)
registerEnum(AMMO_SPEAR)
registerEnum(AMMO_THROWINGSTAR)
registerEnum(AMMO_THROWINGKNIFE)
registerEnum(AMMO_STONE)
registerEnum(AMMO_SNOWBALL)
registerEnum(CALLBACK_PARAM_LEVELMAGICVALUE)
registerEnum(CALLBACK_PARAM_SKILLVALUE)
registerEnum(CALLBACK_PARAM_TARGETTILE)
@ -2291,6 +2300,7 @@ void LuaScriptInterface::registerFunctions()
registerMethod("ItemType", "getCapacity", LuaScriptInterface::luaItemTypeGetCapacity);
registerMethod("ItemType", "getWeight", LuaScriptInterface::luaItemTypeGetWeight);
registerMethod("ItemType", "getHitChance", LuaScriptInterface::luaItemTypeGetHitChance);
registerMethod("ItemType", "getShootRange", LuaScriptInterface::luaItemTypeGetShootRange);
registerMethod("ItemType", "getAttack", LuaScriptInterface::luaItemTypeGetAttack);
@ -10540,6 +10550,19 @@ int LuaScriptInterface::luaItemTypeGetWeight(lua_State* L)
return 1;
}
int LuaScriptInterface::luaItemTypeGetHitChance(lua_State* L)
{
// itemType:getHitChance()
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
if (itemType) {
lua_pushnumber(L, itemType->extraHitChance);
}
else {
lua_pushnil(L);
}
return 1;
}
int LuaScriptInterface::luaItemTypeGetShootRange(lua_State* L)
{
// itemType:getShootRange()

View File

@ -1097,6 +1097,7 @@ class LuaScriptInterface
static int luaItemTypeGetCapacity(lua_State* L);
static int luaItemTypeGetWeight(lua_State* L);
static int luaItemTypeGetHitChance(lua_State* L);
static int luaItemTypeGetShootRange(lua_State* L);
static int luaItemTypeGetAttack(lua_State* L);
static int luaItemTypeGetDefense(lua_State* L);