From 2cec24c9891ec802e8259fefd4faab4074df993f Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Mon, 13 May 2024 19:01:20 -0500 Subject: [PATCH 01/37] Three New AOS properties --- source/CPacketSend.cpp | 21 ++++++++++++ source/Changelog.txt | 7 ++++ source/UOXJSPropertyEnums.h | 3 ++ source/UOXJSPropertyFuncs.cpp | 6 ++++ source/UOXJSPropertySpecs.h | 3 ++ source/cBaseObject.cpp | 63 +++++++++++++++++++++++++++++++++++ source/cBaseObject.h | 12 +++++++ source/cChar.cpp | 9 +++++ source/cItem.cpp | 21 ++++++++++++ source/items.cpp | 3 ++ source/ssection.cpp | 6 ++++ source/ssection.h | 3 ++ 12 files changed, 157 insertions(+) diff --git a/source/CPacketSend.cpp b/source/CPacketSend.cpp index e1d8ee4ca..dfcf7cd62 100644 --- a/source/CPacketSend.cpp +++ b/source/CPacketSend.cpp @@ -7657,6 +7657,27 @@ void CPToolTip::CopyItemData( CItem& cItem, size_t &totalStringLen, bool addAmou FinalizeData( tempEntry, totalStringLen ); } + if( cItem.GetBonusHits() > 0 ) + { + tempEntry.stringNum = 1060431; // hit point increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetBonusHits() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetBonusStam() > 0 ) + { + tempEntry.stringNum = 1060484; // stamina increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetBonusStam() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetBonusMana() > 0 ) + { + tempEntry.stringNum = 1060439; // mana increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetBonusMana() ); + FinalizeData( tempEntry, totalStringLen ); + } + if( cItem.GetStrength() > 1 ) { tempEntry.stringNum = 1061170; // strength requirement ~1_val~ diff --git a/source/Changelog.txt b/source/Changelog.txt index 1d779c15f..c695610cd 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,10 @@ +13/05/2024 - Dragon Slayer + Added three More AOS Props + -BONUSHITS=# + -BONUSMANA=# + -BONUSSTAM=# + Add this properties to any weapon/armor/jewlery will give the player more hp/mana/stam why its equiped. depending on number you add with it + 27/04/2024 - Dragon Slayer/Xuri Fixed an issue where non-corpse containers - including treasure chests in dungeons - would decay and leave all their contents on the ground. Converted LOOTDECAYSWITHCORPSE ini setting to two new settings, one for player corpses, one for NPC corpses: diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h index af309d496..f7f187903 100644 --- a/source/UOXJSPropertyEnums.h +++ b/source/UOXJSPropertyEnums.h @@ -516,6 +516,9 @@ enum CI_Properties CIP_ISCONTTYPE, CIP_CARVESECTION, CIP_SPEED, + CIP_BONUSHITS, + CIP_BONUSSTAM, + CIP_BONUSMANA, CIP_MULTI, CIP_AMMOID, CIP_AMMOHUE, diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp index 3823356f9..a492f112a 100644 --- a/source/UOXJSPropertyFuncs.cpp +++ b/source/UOXJSPropertyFuncs.cpp @@ -676,6 +676,9 @@ JSBool CItemProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( RAIN )); break; case CIP_DAMAGESNOW: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( SNOW )); break; case CIP_SPEED: *vp = INT_TO_JSVAL( gPriv->GetSpeed() ); break; + case CIP_BONUSHITS: *vp = INT_TO_JSVAL( gPriv->GetBonusHits() ); break; + case CIP_BONUSSTAM: *vp = INT_TO_JSVAL( gPriv->GetBonusStam() ); break; + case CIP_BONUSMANA: *vp = INT_TO_JSVAL( gPriv->GetBonusMana() ); break; case CIP_NAME2: tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() ); *vp = STRING_TO_JSVAL( tString ); @@ -1321,6 +1324,9 @@ JSBool CItemProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: gPriv->SetWeatherDamage( RAIN, encaps.toBool() ); break; case CIP_DAMAGESNOW: gPriv->SetWeatherDamage( SNOW, encaps.toBool() ); break; case CIP_SPEED: gPriv->SetSpeed( static_cast( encaps.toInt() )); break; + case CIP_BONUSHITS: gPriv->SetBonusHits( static_cast( encaps.toInt() )); break; + case CIP_BONUSSTAM: gPriv->SetBonusStam( static_cast( encaps.toInt() )); break; + case CIP_BONUSMANA: gPriv->SetBonusMana( static_cast( encaps.toInt() )); break; case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break; case CIP_RACE: gPriv->SetRace( static_cast( encaps.toInt() )); break; case CIP_MAXHP: gPriv->SetMaxHP( static_cast( encaps.toInt() )); break; diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index 3149dc0ec..c5a8c8039 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -535,6 +535,9 @@ inline JSPropertySpec CItemProps[] = { "ammoFXHue", CIP_AMMOFXHUE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ammoFXRender", CIP_AMMOFXRENDER, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "speed", CIP_SPEED, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "bonusHits", CIP_BONUSHITS, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "bonusStam", CIP_BONUSSTAM, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "bonusMana", CIP_BONUSMANA, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "multi", CIP_MULTI, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "maxRange", CIP_MAXRANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "baseRange", CIP_BASERANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index 506c247ac..51cbb80ae 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -1631,6 +1631,69 @@ void CBaseObject::SetIntelligence2( SI16 nVal ) } } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetBonusHits() +//| CBaseObject::SetBonusHits() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the health max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetBonusHits( void ) const +{ + return bonusHits; +} +void CBaseObject::SetBonusHits( SI16 nVal ) +{ + bonusHits = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetBonusStam() +//| CBaseObject::SetBonusStam() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the stamina max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetBonusStam( void ) const +{ + return bonusStam; +} +void CBaseObject::SetBonusStam( SI16 nVal ) +{ + bonusStam = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetBonusMana() +//| CBaseObject::SetBonusMana() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Mana max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetBonusMana( void ) const +{ + return bonusMana; +} +void CBaseObject::SetBonusMana( SI16 nVal ) +{ + bonusMana = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::IncStrength() //o------------------------------------------------------------------------------------------------o diff --git a/source/cBaseObject.h b/source/cBaseObject.h index 638e826f7..15563feca 100644 --- a/source/cBaseObject.h +++ b/source/cBaseObject.h @@ -79,6 +79,9 @@ class CBaseObject SI16 st2; SI16 dx2; SI16 in2; + SI16 bonusHits; + SI16 bonusStam; + SI16 bonusMana; mutable SI32 FilePosition; SERIAL tempMulti; std::string name; @@ -256,6 +259,15 @@ class CBaseObject void IncDexterity( SI16 toInc = 1 ); void IncIntelligence( SI16 toInc = 1 ); + SI16 GetBonusHits( void ) const; + virtual void SetBonusHits( SI16 nVal ); + + SI16 GetBonusStam( void ) const; + virtual void SetBonusStam( SI16 nVal ); + + SI16 GetBonusMana( void ) const; + virtual void SetBonusMana( SI16 nVal ); + virtual void PostLoadProcessing( void ); virtual bool LoadRemnants( void ) = 0; diff --git a/source/cChar.cpp b/source/cChar.cpp index 7aa03f6fa..6e4d4f6d2 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,6 +2920,10 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); + SetFixedMaxHP( GetMaxHP() + itemLayers[tLayer]->GetBonusHits()); + SetFixedMaxStam( GetMaxStam() + itemLayers[tLayer]->GetBonusStam()); + SetFixedMaxMana( GetMaxMana() + itemLayers[tLayer]->GetBonusMana()); + if( toWear->IsPostLoaded() ) { if( itemLayers[tLayer]->GetPoisoned() ) @@ -2979,6 +2983,11 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncStrength2( -itemLayers[Layer]->GetStrength2() ); IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); + + SetFixedMaxHP( GetMaxHP() -itemLayers[Layer]->GetBonusHits()); + SetFixedMaxStam( GetMaxStam() -itemLayers[Layer]->GetBonusStam()); + SetFixedMaxMana( GetMaxMana() -itemLayers[Layer]->GetBonusMana()); + if( itemLayers[Layer]->GetPoisoned() ) { if( itemLayers[Layer]->GetPoisoned() > GetPoisoned() ) diff --git a/source/cItem.cpp b/source/cItem.cpp index 3c6523d5d..45850e6f7 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1654,6 +1654,9 @@ auto CItem::CopyData( CItem *target ) -> void target->SetWeightMax( GetWeightMax() ); target->SetBaseWeight( GetBaseWeight() ); target->SetMaxItems( GetMaxItems() ); + target->SetBonusHits( GetBonusHits() ); + target->SetBonusStam( GetBonusStam() ); + target->SetBonusMana( GetBonusMana() ); //target->SetWipeable( IsWipeable() ); target->SetPriv( GetPriv() ); target->SetBaseRange( GetBaseRange() ); @@ -1737,6 +1740,9 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "MaxItems=" + std::to_string( GetMaxItems() ) + newLine; outStream << "MaxHP=" + std::to_string( GetMaxHP() ) + newLine; outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; + outStream << "BonusHits=" + std::to_string( GetBonusHits() ) + newLine; + outStream << "BonusStam=" + std::to_string( GetBonusStam() ) + newLine; + outStream << "BonusMana=" + std::to_string( GetBonusMana() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; outStream << "Value=" + std::to_string( GetBuyValue() ) + "," + std::to_string( GetSellValue() ) + "," + std::to_string( GetVendorPrice() ) + newLine; @@ -1820,6 +1826,21 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) bools = static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )); rValue = true; } + else if( UTag == "BONUSHITS" ) + { + SetBonusHits( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); + rValue = true; + } + else if( UTag == "BONUSSTAM" ) + { + SetBonusStam( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); + rValue = true; + } + else if( UTag == "BONUSMANA" ) + { + SetBonusMana( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); + rValue = true; + } break; case 'C': if( UTag == "CONT" ) diff --git a/source/items.cpp b/source/items.cpp index 1cd4a2aaf..3bb17bb66 100644 --- a/source/items.cpp +++ b/source/items.cpp @@ -139,6 +139,9 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect break; case DFNTAG_AC: applyTo->SetArmourClass( static_cast( ndata )); break; case DFNTAG_BASERANGE: applyTo->SetBaseRange( static_cast( ndata )); break; + case DFNTAG_BONUSHITS: applyTo->SetBonusHits( static_cast( ndata )); break; + case DFNTAG_BONUSSTAM: applyTo->SetBonusStam( static_cast( ndata )); break; + case DFNTAG_BONUSMANA: applyTo->SetBonusMana( static_cast( ndata )); break; case DFNTAG_CREATOR: applyTo->SetCreator( ndata ); break; case DFNTAG_COLOUR: applyTo->SetColour( static_cast( ndata )); break; case DFNTAG_COLOURLIST: applyTo->SetColour( AddRandomColor( cdata )); break; diff --git a/source/ssection.cpp b/source/ssection.cpp index c2a563b47..dbfc8a475 100644 --- a/source/ssection.cpp +++ b/source/ssection.cpp @@ -215,6 +215,9 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_STRING, // DFNTAG_SPAWNOBJ, DFN_STRING, // DFNTAG_SPAWNOBJLIST, DFN_NUMERIC, // DFNTAG_SPD, + DFN_NUMERIC, // DFNTAG_BONUSHITS, + DFN_NUMERIC, // DFNTAG_BONUSSTAM, + DFN_NUMERIC, // DFNTAG_BONUSMANA, DFN_STRING, // DFNTAG_SPELLS, DFN_DOUBLENUMERIC, // DFNTAG_SPELLWEAVING, DFN_DOUBLENUMERIC, // DFNTAG_SPIRITSPEAK, @@ -283,6 +286,9 @@ const std::map strToDFNTag {"BLACKSMITHING"s, DFNTAG_BLACKSMITHING}, {"BOWCRAFT"s, DFNTAG_BOWCRAFT}, {"BUSHIDO"s, DFNTAG_BUSHIDO}, + {"BONUSHITS"s, DFNTAG_BONUSHITS}, + {"BONUSSTAM"s, DFNTAG_BONUSSTAM}, + {"BONUSMANA"s, DFNTAG_BONUSMANA}, {"CAMPING"s, DFNTAG_CAMPING}, {"CARPENTRY"s, DFNTAG_CARPENTRY}, {"CARTOGRAPHY"s, DFNTAG_CARTOGRAPHY}, diff --git a/source/ssection.h b/source/ssection.h index a2a660aec..8ffc1edc9 100644 --- a/source/ssection.h +++ b/source/ssection.h @@ -222,6 +222,9 @@ enum DFNTAGS DFNTAG_SPAWNOBJ, DFNTAG_SPAWNOBJLIST, DFNTAG_SPD, + DFNTAG_BONUSHITS, + DFNTAG_BONUSSTAM, + DFNTAG_BONUSMANA, DFNTAG_SPELLS, DFNTAG_SPELLWEAVING, DFNTAG_SPIRITSPEAK, From 230fa75b4131624ddaac382d1550abcf61dbb2d4 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 26 May 2024 00:16:03 -0500 Subject: [PATCH 02/37] Update cItem.cpp --- source/cItem.cpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/source/cItem.cpp b/source/cItem.cpp index 45850e6f7..c345ecdc2 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1740,9 +1740,7 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "MaxItems=" + std::to_string( GetMaxItems() ) + newLine; outStream << "MaxHP=" + std::to_string( GetMaxHP() ) + newLine; outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; - outStream << "BonusHits=" + std::to_string( GetBonusHits() ) + newLine; - outStream << "BonusStam=" + std::to_string( GetBonusStam() ) + newLine; - outStream << "BonusMana=" + std::to_string( GetBonusMana() ) + newLine; + outStream << "BonusStats=" + std::to_string( GetBonusHits() ) + "," + std::to_string( GetBonusStam() ) + "," + std::to_string( GetBonusMana() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; outStream << "Value=" + std::to_string( GetBuyValue() ) + "," + std::to_string( GetSellValue() ) + "," + std::to_string( GetVendorPrice() ) + newLine; @@ -1826,20 +1824,12 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) bools = static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )); rValue = true; } - else if( UTag == "BONUSHITS" ) + else if( UTag == "BONUSSTATS" ) { - SetBonusHits( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); - rValue = true; - } - else if( UTag == "BONUSSTAM" ) - { - SetBonusStam( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); - rValue = true; - } - else if( UTag == "BONUSMANA" ) - { - SetBonusMana( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); - rValue = true; + SetBonusHits( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[0], "//" )), nullptr, 0 ))); + SetBonusStam( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[1], "//" )), nullptr, 0 ))); + SetBonusMana( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[2], "//" )), nullptr, 0 ))); + rValue = true; } break; case 'C': From a32f192b1f6d9b3b674b58fff3f2e5ac0fec6f4b Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Mon, 27 May 2024 15:08:23 -0500 Subject: [PATCH 03/37] Fixed the Bonus add ons Now they will not save on world save --- source/cChar.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++------ source/cChar.h | 9 +++++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/source/cChar.cpp b/source/cChar.cpp index 6e4d4f6d2..530053021 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,9 +2920,9 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); - SetFixedMaxHP( GetMaxHP() + itemLayers[tLayer]->GetBonusHits()); - SetFixedMaxStam( GetMaxStam() + itemLayers[tLayer]->GetBonusStam()); - SetFixedMaxMana( GetMaxMana() + itemLayers[tLayer]->GetBonusMana()); + IncBonusHits( itemLayers[tLayer]->GetBonusHits() ); + IncBonusStam( itemLayers[tLayer]->GetBonusStam() ); + IncBonusMana( itemLayers[tLayer]->GetBonusMana() ); if( toWear->IsPostLoaded() ) { @@ -2984,9 +2984,9 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); - SetFixedMaxHP( GetMaxHP() -itemLayers[Layer]->GetBonusHits()); - SetFixedMaxStam( GetMaxStam() -itemLayers[Layer]->GetBonusStam()); - SetFixedMaxMana( GetMaxMana() -itemLayers[Layer]->GetBonusMana()); + IncBonusHits( -itemLayers[Layer]->GetBonusHits() ); + IncBonusStam( -itemLayers[Layer]->GetBonusStam() ); + IncBonusMana( -itemLayers[Layer]->GetBonusMana() ); if( itemLayers[Layer]->GetPoisoned() ) { @@ -3796,7 +3796,7 @@ UI16 CChar::GetMaxHP( void ) oldRace = GetRace(); } - return maxHP; + return maxHP + GetBonusHits(); } void CChar::SetMaxHP( UI16 newmaxhp, UI16 newoldstr, RACEID newoldrace ) { @@ -3839,7 +3839,7 @@ void CChar::SetFixedMaxHP( SI16 newmaxhp ) SI16 CChar::GetMaxMana( void ) { if(( maxMana_oldint != GetIntelligence() || oldRace != GetRace() ) && !GetMaxManaFixed() ) - //if int/race changed since last calculation, recalculate maxHp + //if int/race changed since last calculation, recalculate maxMana { CRace *pRace = Races->Race( GetRace() ); @@ -3856,7 +3856,7 @@ SI16 CChar::GetMaxMana( void ) oldRace = GetRace(); } - return maxMana; + return maxMana + GetBonusMana(); } void CChar::SetMaxMana( SI16 newmaxmana, UI16 newoldint, RACEID newoldrace ) { @@ -3898,7 +3898,7 @@ void CChar::SetFixedMaxMana( SI16 newmaxmana ) //o------------------------------------------------------------------------------------------------o SI16 CChar::GetMaxStam( void ) { - // If dex/race changed since last calculation, recalculate maxHp + // If dex/race changed since last calculation, recalculate maxStam if(( maxStam_olddex != GetDexterity() || oldRace != GetRace() ) && !GetMaxStamFixed() ) { CRace *pRace = Races->Race( GetRace() ); @@ -3916,7 +3916,7 @@ SI16 CChar::GetMaxStam( void ) oldRace = GetRace(); } - return maxStam; + return maxStam + GetBonusStam(); } void CChar::SetMaxStam( SI16 newmaxstam, UI16 newolddex, RACEID newoldrace ) { @@ -5602,6 +5602,75 @@ void CChar::SetIntelligence2( SI16 nVal ) UpdateRegion(); } +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetBonusHits() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Hits stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetBonusHits( SI16 nVal ) +{ + CBaseObject::SetBonusHits( nVal ); + Dirty( UT_HITPOINTS ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetBonusStam() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Stam stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetBonusStam( SI16 nVal ) +{ + CBaseObject::SetBonusStam( nVal ); + Dirty( UT_STAMINA ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetBonusMana() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Mana stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetBonusMana( SI16 nVal ) +{ + CBaseObject::SetBonusMana( nVal ); + Dirty( UT_MANA ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncBonusHits() +//| Date - 26 May 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetBonusHits (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncBonusHits( SI16 toAdd ) +{ + SetBonusHits( static_cast( GetBonusHits() + toAdd )); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncBonusStam() +//| Date - 26 May 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetBonusStam (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncBonusStam( SI16 toAdd ) +{ + SetBonusStam( static_cast( GetBonusStam() + toAdd )); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncBonusMana() +//| Date - 26 May 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetBonusMana (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncBonusMana( SI16 toAdd ) +{ + SetBonusMana( static_cast( GetBonusMana() + toAdd )); +} + //o------------------------------------------------------------------------------------------------o //| Function - CChar::IncStamina() //o------------------------------------------------------------------------------------------------o diff --git a/source/cChar.h b/source/cChar.h index ed4cc90ba..3156340ff 100644 --- a/source/cChar.h +++ b/source/cChar.h @@ -628,6 +628,15 @@ class CChar : public CBaseObject virtual void SetStrength2( SI16 newValue ) override; virtual void SetDexterity2( SI16 newValue ) override; virtual void SetIntelligence2( SI16 newValue ) override; + + virtual void SetBonusHits( SI16 newValue ) override; + virtual void SetBonusStam( SI16 newValue ) override; + virtual void SetBonusMana( SI16 newValue ) override; + + void IncBonusHits( SI16 toAdd = 1 ); + void IncBonusStam( SI16 toAdd = 1 ); + void IncBonusMana( SI16 toAdd = 1 ); + void IncStamina( SI16 toInc ); void IncMana( SI16 toInc ); void SetMaxLoyalty( UI16 newMaxLoyalty ); From 12d3e6686ae8e4f9dae14143b4b0365ff927db10 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Mon, 27 May 2024 16:58:40 -0500 Subject: [PATCH 04/37] Missing Wand ID's --- data/js/server/data/weapontypes.js | 4 ++++ source/Changelog.txt | 3 +++ source/combat.cpp | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/data/js/server/data/weapontypes.js b/data/js/server/data/weapontypes.js index 42fe15a2b..0a6940e56 100644 --- a/data/js/server/data/weapontypes.js +++ b/data/js/server/data/weapontypes.js @@ -208,6 +208,10 @@ function GetWeaponType( mChar, itemID ) case 0x48B3: //gargish axe - SA weaponType = "TWOHND_AXES"; break; // Default Maces + case 0x0DF2: // Wand + case 0x0DF3: // Wand + case 0x0DF4: // Wand + case 0x0DF5: // Wand case 0x0FB4: //sledge hammer case 0x0FB5: //sledge hammer case 0x0F5C: //mace diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..424b6f5f6 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,6 @@ +27/05/2024 - Dragon Slayer + Added Missing Wand ID's to combat weapon type in core and in js. + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. diff --git a/source/combat.cpp b/source/combat.cpp index 8817d7b3d..b38953b35 100644 --- a/source/combat.cpp +++ b/source/combat.cpp @@ -801,6 +801,10 @@ UI08 CHandleCombat::GetWeaponType( CItem *i ) case 0x48B3: //gargish axe - SA return TWOHND_AXES; // Default Maces + case 0x0DF2: // Wand + case 0x0DF3: // Wand + case 0x0DF4: // Wand + case 0x0DF5: // Wand case 0x13E3: //smith's hammer case 0x13E4: //smith's hammer case 0x13B3: //club From e7c87950800fad4fdd5ec02e67a5a5ac3c845f13 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Wed, 29 May 2024 14:07:29 -0500 Subject: [PATCH 05/37] Fixed House Addons in Homes House add-on deeds are now returned when an add-on is present in the house. --- data/js/server/house/houseCommands.js | 11 ++++++++++- source/Changelog.txt | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/data/js/server/house/houseCommands.js b/data/js/server/house/houseCommands.js index e27bef044..2c7afd3f3 100644 --- a/data/js/server/house/houseCommands.js +++ b/data/js/server/house/houseCommands.js @@ -1522,8 +1522,17 @@ function DemolishHouse( pSocket, iMulti ) iMulti.RemoveTrashCont( itemInHouse ); itemInHouse.Delete(); } - else if( itemInHouse.movable == 2 ) // items placed as part of the house itself like forge/anvil in smithy + else if( itemInHouse.movable == 2 || itemInHouse.GetTag( "deed" )) // items placed as part of the house itself like forge/anvil in smithy or the addon deed { + var addonDeed = itemInHouse.GetTag( "deed" ); + if( addonDeed ) + { + var newDeed = CreateDFNItem( pSocket, pSocket.currentChar, addonDeed, 1, "ITEM", true ); + if( newDeed ) + { + pSocket.SysMessage( GetDictionaryEntry( 1970, pSocket.language )); // A deed for the house add-on has been placed in your backpack. + } + } itemInHouse.Delete(); } else if( itemInHouse.isLockedDown ) diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..43a0869d2 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,6 @@ +29/05/2024 - Dragon Slayer + House add-on deeds are now returned when an add-on is present in the house. + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From 7735b0ce567b05812a5484657ca64613c02aa994 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Wed, 29 May 2024 14:08:34 -0500 Subject: [PATCH 06/37] Update Changelog.txt --- source/Changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Changelog.txt b/source/Changelog.txt index 43a0869d2..016465bc7 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,5 +1,5 @@ 29/05/2024 - Dragon Slayer - House add-on deeds are now returned when an add-on is present in the house. + House add-on deeds are now returned when an add-on is present in the house on demolish. 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. From f0189f361dcbbc89fba5d2ed619c95ca0a275232 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:38:02 -0500 Subject: [PATCH 07/37] Fixed Expansion Settings Fixed Accepting bods, When the expansion is to to lbr or later. --- data/js/npc/ai/vendor_bdo_dispenser.js | 2 +- source/Changelog.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data/js/npc/ai/vendor_bdo_dispenser.js b/data/js/npc/ai/vendor_bdo_dispenser.js index 0b5739539..9d069ea22 100644 --- a/data/js/npc/ai/vendor_bdo_dispenser.js +++ b/data/js/npc/ai/vendor_bdo_dispenser.js @@ -302,7 +302,7 @@ function onSpeech( myString, pUser, myNPC ) { if( CheckBodTimers( pUser, myNPC.GetTag( "bodType" ) )) { - if( EraStringToNum( GetServerSetting( "CoreShardEra" )) <= EraStringToNum( "lbr" )) + if( EraStringToNum( GetServerSetting( "CoreShardEra" )) >= EraStringToNum( "lbr" )) { myNPC.SetTimer( Timer.MOVETIME, 1000 ); // Pause NPC in their tracks for a second myNPC.TurnToward( pUser ); diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..c8413e9c6 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,6 @@ +6/06/2024 - Dragon Slayer + Fixed Accepting bods, When the expansion is to to lbr or later. + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From 90c9a5f8354b98ac932d96b11bf7487125fbe49b Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Tue, 11 Jun 2024 23:31:55 -0500 Subject: [PATCH 08/37] Small Fixes to Get Fixed items handling correct target Added Getting the resist on chars --- data/js/commands/targeting/get.js | 36 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/data/js/commands/targeting/get.js b/data/js/commands/targeting/get.js index 365d3a2b3..b07305bd5 100644 --- a/data/js/commands/targeting/get.js +++ b/data/js/commands/targeting/get.js @@ -294,30 +294,27 @@ function HandleGetItem( socket, ourItem, uKey ) case "DESC": socket.SysMessage( ourItem.desc ); break; - case "DEF": - socket.SysMessage( ourItem.Resist( 1 )); - break; case "DEF": case "RESISTARMOR": - socket.SysMessage( ourObj.Resist( 1 )); + socket.SysMessage( ourItem.Resist( 1 )); break; case "RESISTLIGHT": - socket.SysMessage( ourObj.Resist( 2 )); + socket.SysMessage( ourItem.Resist( 2 )); break; case "RESISTWATER": - socket.SysMessage( ourObj.Resist( 3 )); + socket.SysMessage( ourItem.Resist( 3 )); break; case "RESISTCOLD": - socket.SysMessage( ourObj.Resist( 4 )); + socket.SysMessage( ourItem.Resist( 4 )); break; case "RESISTFIRE": - socket.SysMessage( ourObj.Resist( 5 )); + socket.SysMessage( ourItem.Resist( 5 )); break; case "RESISTENERGY": - socket.SysMessage( ourObj.Resist( 6 )); + socket.SysMessage( ourItem.Resist( 6 )); break; case "RESISTPOISON": - socket.SysMessage( ourObj.Resist( 7 )); + socket.SysMessage( ourItem.Resist( 7 )); break; case "ARMORCLASS": case "ARMOURCLASS": @@ -598,8 +595,27 @@ function HandleGetChar( socket, ourChar, uKey ) break; case "ARMOUR": case "ARMOR": + case "RESISTARMOR": socket.SysMessage( ourChar.Resist( 1 )); break; + case "RESISTLIGHT": + socket.SysMessage( ourChar.Resist( 2 )); + break; + case "RESISTWATER": + socket.SysMessage( ourChar.Resist( 3 )); + break; + case "RESISTCOLD": + socket.SysMessage( ourChar.Resist( 4 )); + break; + case "RESISTFIRE": + socket.SysMessage( ourChar.Resist( 5 )); + break; + case "RESISTENERGY": + socket.SysMessage( ourChar.Resist( 6 )); + break; + case "RESISTPOISON": + socket.SysMessage( ourChar.Resist( 7 )); + break; case "MAXHP": socket.SysMessage( ourChar.maxhp ); break; From 363ce296c459a21253c67b783fe85e2ef91c2786 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:38:03 -0500 Subject: [PATCH 09/37] Hit/Defense Chance Properties --- source/CPacketSend.cpp | 14 ++++++++ source/UOXJSPropertyEnums.h | 2 ++ source/UOXJSPropertyFuncs.cpp | 4 +++ source/UOXJSPropertySpecs.h | 2 ++ source/cBaseObject.cpp | 62 +++++++++++++++++++++++++++++++++++ source/cBaseObject.h | 11 +++++++ source/cChar.cpp | 7 ++++ source/cItem.cpp | 14 ++++++++ source/combat.cpp | 6 ++-- source/items.cpp | 2 ++ source/ssection.cpp | 4 +++ source/ssection.h | 2 ++ 12 files changed, 127 insertions(+), 3 deletions(-) diff --git a/source/CPacketSend.cpp b/source/CPacketSend.cpp index e1d8ee4ca..04d145b29 100644 --- a/source/CPacketSend.cpp +++ b/source/CPacketSend.cpp @@ -7657,6 +7657,20 @@ void CPToolTip::CopyItemData( CItem& cItem, size_t &totalStringLen, bool addAmou FinalizeData( tempEntry, totalStringLen ); } + if( cItem.GetHitChance() > 0 ) + { + tempEntry.stringNum = 1060415; // hit chance increase ~1_val~% + tempEntry.ourText = oldstrutil::number( cItem.GetHitChance() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetDefenseChance() > 0 ) + { + tempEntry.stringNum = 1060408; // defense chance increase ~1_val~% + tempEntry.ourText = oldstrutil::number( cItem.GetDefenseChance() ); + FinalizeData( tempEntry, totalStringLen ); + } + if( cItem.GetStrength() > 1 ) { tempEntry.stringNum = 1061170; // strength requirement ~1_val~ diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h index af309d496..f471df16e 100644 --- a/source/UOXJSPropertyEnums.h +++ b/source/UOXJSPropertyEnums.h @@ -461,6 +461,8 @@ enum CI_Properties CIP_DAMAGEPOISON, CIP_DAMAGERAIN, CIP_DAMAGESNOW, + CIP_HITCHANCE, + CIP_DEFENSECHANCE, CIP_NAME2, CIP_ISITEM, CIP_ISCHAR, diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp index 3823356f9..02ff0cbb2 100644 --- a/source/UOXJSPropertyFuncs.cpp +++ b/source/UOXJSPropertyFuncs.cpp @@ -676,6 +676,8 @@ JSBool CItemProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( RAIN )); break; case CIP_DAMAGESNOW: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( SNOW )); break; case CIP_SPEED: *vp = INT_TO_JSVAL( gPriv->GetSpeed() ); break; + case CIP_HITCHANCE: *vp = INT_TO_JSVAL( gPriv->GetHitChance() ); break; + case CIP_DEFENSECHANCE: *vp = INT_TO_JSVAL( gPriv->GetDefenseChance() ); break; case CIP_NAME2: tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() ); *vp = STRING_TO_JSVAL( tString ); @@ -1321,6 +1323,8 @@ JSBool CItemProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: gPriv->SetWeatherDamage( RAIN, encaps.toBool() ); break; case CIP_DAMAGESNOW: gPriv->SetWeatherDamage( SNOW, encaps.toBool() ); break; case CIP_SPEED: gPriv->SetSpeed( static_cast( encaps.toInt() )); break; + case CIP_HITCHANCE: gPriv->SetHitChance( static_cast( encaps.toInt() )); break; + case CIP_DEFENSECHANCE: gPriv->SetDefenseChance( static_cast( encaps.toInt() )); break; case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break; case CIP_RACE: gPriv->SetRace( static_cast( encaps.toInt() )); break; case CIP_MAXHP: gPriv->SetMaxHP( static_cast( encaps.toInt() )); break; diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index 3149dc0ec..b77c023aa 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -535,6 +535,8 @@ inline JSPropertySpec CItemProps[] = { "ammoFXHue", CIP_AMMOFXHUE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ammoFXRender", CIP_AMMOFXRENDER, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "speed", CIP_SPEED, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "hitChance", CIP_HITCHANCE, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "defenseChance", CIP_DEFENSECHANCE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "multi", CIP_MULTI, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "maxRange", CIP_MAXRANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "baseRange", CIP_BASERANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index 506c247ac..bfb143b5d 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -1036,6 +1036,48 @@ void CBaseObject::IncHP( SI16 amtToChange ) SetHP( hitpoints + amtToChange ); } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetHitChance() +//| CBaseObject::SetHitChance() +//| Date - 14 June, 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Defense Chance of the Item Equiped +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetHitChance( void ) const +{ + return hitChance; +} +void CBaseObject::SetHitChance( SI16 newValue ) +{ + hitChance = newValue; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetDefenseChance() +//| CBaseObject::SetDefenseChance() +//| Date - 14 June, 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Defense Chance of the Item Equiped +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetDefenseChance( void ) const +{ + return defenseChance; +} +void CBaseObject::SetDefenseChance( SI16 newValue ) +{ + defenseChance = newValue; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::GetDir() //| CBaseObject::SetDir() @@ -1661,6 +1703,26 @@ void CBaseObject::IncIntelligence( SI16 toInc ) SetIntelligence( intelligence + toInc ); } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::IncHitChance() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments the object's Hit Chance value +//o------------------------------------------------------------------------------------------------o +void CBaseObject::IncHitChance( SI16 toInc ) +{ + SetHitChance( hitChance + toInc ); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::IncDefenseChance() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments the object's Hit Chance value +//o------------------------------------------------------------------------------------------------o +void CBaseObject::IncDefenseChance( SI16 toInc ) +{ + SetDefenseChance( defenseChance + toInc ); +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::DumpFooter() //o------------------------------------------------------------------------------------------------o diff --git a/source/cBaseObject.h b/source/cBaseObject.h index 638e826f7..4b5c66329 100644 --- a/source/cBaseObject.h +++ b/source/cBaseObject.h @@ -69,6 +69,8 @@ class CBaseObject SI16 dexterity; SI16 intelligence; SI16 hitpoints; + SI16 hitChance; + SI16 defenseChance; VisibleTypes visible; SI16 hiDamage; SI16 loDamage; @@ -223,6 +225,12 @@ class CBaseObject virtual void SetHP( SI16 newValue ); void IncHP( SI16 amtToChange ); + virtual SI16 GetHitChance( void ) const; + virtual void SetHitChance( SI16 newValue ); + + virtual SI16 GetDefenseChance( void ) const; + virtual void SetDefenseChance( SI16 newValue ); + void SetDir( UI08 newDir, bool sendUpdate = true ); UI08 GetDir( void ) const; @@ -256,6 +264,9 @@ class CBaseObject void IncDexterity( SI16 toInc = 1 ); void IncIntelligence( SI16 toInc = 1 ); + void IncHitChance( SI16 toInc = 1 ); + void IncDefenseChance( SI16 toInc = 1 ); + virtual void PostLoadProcessing( void ); virtual bool LoadRemnants( void ) = 0; diff --git a/source/cChar.cpp b/source/cChar.cpp index 7aa03f6fa..6bb36cb56 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,6 +2920,9 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); + IncHitChance( itemLayers[tLayer]->GetHitChance() ); + IncDefenseChance( itemLayers[tLayer]->GetDefenseChance() ); + if( toWear->IsPostLoaded() ) { if( itemLayers[tLayer]->GetPoisoned() ) @@ -2979,6 +2982,10 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncStrength2( -itemLayers[Layer]->GetStrength2() ); IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); + + IncHitChance( -itemLayers[Layer]->GetHitChance() ); + IncDefenseChance( -itemLayers[Layer]->GetDefenseChance() ); + if( itemLayers[Layer]->GetPoisoned() ) { if( itemLayers[Layer]->GetPoisoned() > GetPoisoned() ) diff --git a/source/cItem.cpp b/source/cItem.cpp index 3c6523d5d..5843cfb86 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1638,6 +1638,8 @@ auto CItem::CopyData( CItem *target ) -> void target->SetRndValueRate( GetRndValueRate() ); target->SetSpawn( GetSpawn() ); target->SetSpeed( GetSpeed() ); + target->SetHitChance( GetHitChance() ); + target->SetDefenseChance( GetDefenseChance() ); target->SetSpell( 0, GetSpell( 0 )); target->SetSpell( 1, GetSpell( 1 )); target->SetSpell( 2, GetSpell( 2 )); @@ -1736,6 +1738,8 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "BaseWeight=" + std::to_string( GetBaseWeight() ) + newLine; outStream << "MaxItems=" + std::to_string( GetMaxItems() ) + newLine; outStream << "MaxHP=" + std::to_string( GetMaxHP() ) + newLine; + outStream << "HitChance=" + std::to_string( GetHitChance() ) + newLine; + outStream << "DefenseChance=" + std::to_string( GetDefenseChance() ) + newLine; outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; @@ -1859,6 +1863,11 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) SetDye( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ); rValue = true; } + else if( UTag == "DEFENSECHANCE" ) + { + SetDefenseChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); + rValue = true; + } break; case 'E': if( UTag == "ENTRYMADEFROM" ) @@ -1905,6 +1914,11 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) SetWeatherDamage( HEAT, static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ); rValue = true; } + else if( UTag == "HITCHANCE" ) + { + SetHitChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 ))); + rValue = true; + } break; case 'L': if( UTag == "LAYER" ) diff --git a/source/combat.cpp b/source/combat.cpp index 8817d7b3d..066e3e80e 100644 --- a/source/combat.cpp +++ b/source/combat.cpp @@ -2883,9 +2883,9 @@ bool CHandleCombat::HandleCombat( CSocket *mSock, CChar& mChar, CChar *ourTarg ) maxAttHitChanceBonus = 50; } - // Fetch bonuses to hitChance/defenseChance from AoS item properties, when implemented - //attHitChanceBonus = GetAttackerHitChanceBonus(); - //defDefenseChanceBonus = GetDefenderDefenseChanceBonus(); + // Fetch bonuses to hitChance/defenseChance from AoS item properties + attHitChanceBonus = mChar.GetHitChance(); + defDefenseChanceBonus = mChar.GetDefenseChance(); R32 attackerHitChance = ( static_cast( attackSkill / 10 ) + 20 ) * ( 100 + std::min( attHitChanceBonus, static_cast( maxAttHitChanceBonus ))); R32 defenderDefenseChance = ( static_cast( defendSkill / 10 ) + 20 ) * ( 100 + std::min( defDefenseChanceBonus, static_cast( 45 ))); diff --git a/source/items.cpp b/source/items.cpp index 1cd4a2aaf..5c4726c11 100644 --- a/source/items.cpp +++ b/source/items.cpp @@ -229,6 +229,7 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect case DFNTAG_DISPELLABLE: applyTo->SetDispellable( true ); break; case DFNTAG_DISABLED: applyTo->SetDisabled( ndata != 0 ); break; case DFNTAG_DOORFLAG: break; + case DFNTAG_DEFENSECHANCE: applyTo->SetDefenseChance( static_cast( ndata )); break; case DFNTAG_GOOD: applyTo->SetGood( static_cast( ndata )); break; case DFNTAG_GLOW: applyTo->SetGlow( ndata ); break; case DFNTAG_GLOWBC: applyTo->SetGlowColour( static_cast( ndata )); break; @@ -338,6 +339,7 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect } break; case DFNTAG_HIDAMAGE: applyTo->SetHiDamage( static_cast( ndata )); break; + case DFNTAG_HITCHANCE: applyTo->SetHitChance( static_cast( ndata )); break; case DFNTAG_HEAT: applyTo->SetWeatherDamage( HEAT, ndata != 0 ); break; case DFNTAG_ID: // applyTo->SetId( static_cast( ndata )); break; if( ssecs.size() == 1 ) diff --git a/source/ssection.cpp b/source/ssection.cpp index c2a563b47..73bb2e94b 100644 --- a/source/ssection.cpp +++ b/source/ssection.cpp @@ -66,6 +66,7 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_NUMERIC, // DFNTAG_DOORFLAG, DFN_NUMERIC, // DFNTAG_DYE, DFN_NUMERIC, // DFNTAG_DYEBEARD, + DFN_NUMERIC, // DFNTAG_DEFENSECHANCE, DFN_NUMERIC, // DFNTAG_DYEHAIR, DFN_STRING, // DFNTAG_ELEMENTRESIST, DFN_STRING, // DFNTAG_ERBONUS, @@ -111,6 +112,7 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_NUMERIC, // DFNTAG_HEAT, DFN_DOUBLENUMERIC, // DFNTAG_HERDING, DFN_NUMERIC, // DFNTAG_HIDAMAGE, + DFN_NUMERIC, // DFNTAG_HITCHANCE, DFN_DOUBLENUMERIC, // DFNTAG_HIDING, DFN_NODATA, // DFNTAG_HIRELING, DFN_DOUBLENUMERIC, // DFNTAG_HP, @@ -321,6 +323,7 @@ const std::map strToDFNTag {"DYEABLE"s, DFNTAG_DYE}, {"DYEHAIR"s, DFNTAG_DYEHAIR}, {"DYEBEARD"s, DFNTAG_DYEBEARD}, + {"DEFENSECHANCE"s, DFNTAG_DEFENSECHANCE}, {"ELEMENTRESIST"s, DFNTAG_ELEMENTRESIST}, {"ERBONUS"s, DFNTAG_ERBONUS}, {"EMOTECOLOR"s, DFNTAG_EMOTECOLOUR}, @@ -366,6 +369,7 @@ const std::map strToDFNTag {"HEAT"s, DFNTAG_HEAT}, {"HERDING"s, DFNTAG_HERDING}, {"HIDAMAGE"s, DFNTAG_HIDAMAGE}, + {"HITCHANCE"s, DFNTAG_HITCHANCE}, {"HIDING"s, DFNTAG_HIDING}, {"HIRELING"s, DFNTAG_HIRELING}, {"HP"s, DFNTAG_HP}, diff --git a/source/ssection.h b/source/ssection.h index a2a660aec..beaa359ab 100644 --- a/source/ssection.h +++ b/source/ssection.h @@ -71,6 +71,7 @@ enum DFNTAGS DFNTAG_DISPELLABLE, DFNTAG_DISABLED, DFNTAG_DOORFLAG, + DFNTAG_DEFENSECHANCE, DFNTAG_DYE, DFNTAG_DYEBEARD, DFNTAG_DYEHAIR, @@ -118,6 +119,7 @@ enum DFNTAGS DFNTAG_HEAT, DFNTAG_HERDING, DFNTAG_HIDAMAGE, + DFNTAG_HITCHANCE, DFNTAG_HIDING, DFNTAG_HIRELING, DFNTAG_HP, From 8863f5de2726fbc5e34a1e56f229063a0935c1d1 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:42:36 -0500 Subject: [PATCH 10/37] Changelog --- source/Changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..348b45e14 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,9 @@ +14/06/2024 - Dragon Slayer + Added two new DFN tags for Items: + HITCHANCE=# // Increases the player's chance to hit a target with wrestling, melee and ranged weapons. + DEFENSECHANCE=# // Increases the wearer's chance that his opponents' swings (or arrows/bolts) will miss. + These are also available as JS Engine object properties: .hitChance, .defenseChance + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From b63ceaeeb6445e113199dc61d4bbb7367f1fb576 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 02:04:48 -0500 Subject: [PATCH 11/37] Update cBaseObject.cpp --- source/cBaseObject.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index bfb143b5d..b0e7a538f 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -1039,7 +1039,6 @@ void CBaseObject::IncHP( SI16 amtToChange ) //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::GetHitChance() //| CBaseObject::SetHitChance() -//| Date - 14 June, 2024 //o------------------------------------------------------------------------------------------------o //| Purpose - Gets/Sets the Defense Chance of the Item Equiped //o------------------------------------------------------------------------------------------------o @@ -1060,7 +1059,6 @@ void CBaseObject::SetHitChance( SI16 newValue ) //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::GetDefenseChance() //| CBaseObject::SetDefenseChance() -//| Date - 14 June, 2024 //o------------------------------------------------------------------------------------------------o //| Purpose - Gets/Sets the Defense Chance of the Item Equiped //o------------------------------------------------------------------------------------------------o From f6989ca218146962e9cef0f932fffd0e1d13cd3c Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 02:48:12 -0500 Subject: [PATCH 12/37] Update cBaseObject.cpp --- source/cBaseObject.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index b0e7a538f..9eedebfff 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -94,6 +94,8 @@ const SI16 DEFBASE_KILLS = 0; const UI16 DEFBASE_RESIST = 0; const bool DEFBASE_NAMEREQUESTACTIVE = 0; const ExpansionRuleset DEFBASE_ORIGIN = ER_UO; +const SI16 DEFBASE_HITCHANCE = 0; +const SI16 DEFBASE_DEFENSECHANCE = 0; //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject constructor @@ -110,7 +112,8 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ), mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ), in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ), poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ), -fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ) +fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ), +hitChance( DEFBASE_HITCHANCE ), defenseChance( DEFBASE_DEFENSECHANCE ) { multis = nullptr; tempMulti = INVALIDSERIAL; From e514b688a9e91776da581aa98858476f1ec286bb Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:00:52 -0500 Subject: [PATCH 13/37] Update cBaseObject.cpp --- source/cBaseObject.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index 51cbb80ae..abeb8590f 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -94,6 +94,9 @@ const SI16 DEFBASE_KILLS = 0; const UI16 DEFBASE_RESIST = 0; const bool DEFBASE_NAMEREQUESTACTIVE = 0; const ExpansionRuleset DEFBASE_ORIGIN = ER_UO; +const SI16 DEFBASE_BONUSHEALTH = 0; +const SI16 DEFBASE_BONUSSTAMINA = 0; +const SI16 DEFBASE_BONUSMANA = 0; //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject constructor @@ -110,7 +113,8 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ), mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ), in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ), poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ), -fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ) +fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ), +bonusHits( DEFBASE_BONUSHEALTH ),bonusStam( DEFBASE_BONUSSTAMINA ), bonusMana( DEFBASE_BONUSMANA ) { multis = nullptr; tempMulti = INVALIDSERIAL; From 2694dbc502d90e85eb5a94009a372c8766b5fa1d Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 18:57:27 -0500 Subject: [PATCH 14/37] Match uox3 Style --- source/CPacketSend.cpp | 12 ++++---- source/UOXJSPropertyEnums.h | 6 ++-- source/UOXJSPropertyFuncs.cpp | 12 ++++---- source/UOXJSPropertySpecs.h | 6 ++-- source/cBaseObject.cpp | 44 +++++++++++++-------------- source/cBaseObject.h | 18 +++++------ source/cChar.cpp | 57 +++++++++++++++++------------------ source/cChar.h | 12 ++++---- source/cItem.cpp | 14 ++++----- source/items.cpp | 6 ++-- source/ssection.cpp | 12 ++++---- source/ssection.h | 6 ++-- 12 files changed, 102 insertions(+), 103 deletions(-) diff --git a/source/CPacketSend.cpp b/source/CPacketSend.cpp index dfcf7cd62..c95dbf5fd 100644 --- a/source/CPacketSend.cpp +++ b/source/CPacketSend.cpp @@ -7657,24 +7657,24 @@ void CPToolTip::CopyItemData( CItem& cItem, size_t &totalStringLen, bool addAmou FinalizeData( tempEntry, totalStringLen ); } - if( cItem.GetBonusHits() > 0 ) + if( cItem.GetHealthBonus() > 0 ) { tempEntry.stringNum = 1060431; // hit point increase ~1_val~ - tempEntry.ourText = oldstrutil::number( cItem.GetBonusHits() ); + tempEntry.ourText = oldstrutil::number( cItem.GetHealthBonus() ); FinalizeData( tempEntry, totalStringLen ); } - if( cItem.GetBonusStam() > 0 ) + if( cItem.GetStaminaBonus() > 0 ) { tempEntry.stringNum = 1060484; // stamina increase ~1_val~ - tempEntry.ourText = oldstrutil::number( cItem.GetBonusStam() ); + tempEntry.ourText = oldstrutil::number( cItem.GetStaminaBonus() ); FinalizeData( tempEntry, totalStringLen ); } - if( cItem.GetBonusMana() > 0 ) + if( cItem.GetManaBonus() > 0 ) { tempEntry.stringNum = 1060439; // mana increase ~1_val~ - tempEntry.ourText = oldstrutil::number( cItem.GetBonusMana() ); + tempEntry.ourText = oldstrutil::number( cItem.GetManaBonus() ); FinalizeData( tempEntry, totalStringLen ); } diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h index f7f187903..2b4bf3091 100644 --- a/source/UOXJSPropertyEnums.h +++ b/source/UOXJSPropertyEnums.h @@ -516,9 +516,9 @@ enum CI_Properties CIP_ISCONTTYPE, CIP_CARVESECTION, CIP_SPEED, - CIP_BONUSHITS, - CIP_BONUSSTAM, - CIP_BONUSMANA, + CIP_HEALTHBONUS, + CIP_STAMINABONUS, + CIP_MANABONUS, CIP_MULTI, CIP_AMMOID, CIP_AMMOHUE, diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp index a492f112a..8771f2688 100644 --- a/source/UOXJSPropertyFuncs.cpp +++ b/source/UOXJSPropertyFuncs.cpp @@ -676,9 +676,9 @@ JSBool CItemProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( RAIN )); break; case CIP_DAMAGESNOW: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( SNOW )); break; case CIP_SPEED: *vp = INT_TO_JSVAL( gPriv->GetSpeed() ); break; - case CIP_BONUSHITS: *vp = INT_TO_JSVAL( gPriv->GetBonusHits() ); break; - case CIP_BONUSSTAM: *vp = INT_TO_JSVAL( gPriv->GetBonusStam() ); break; - case CIP_BONUSMANA: *vp = INT_TO_JSVAL( gPriv->GetBonusMana() ); break; + case CIP_HEALTHBONUS: *vp = INT_TO_JSVAL( gPriv->GetHealthBonus() ); break; + case CIP_STAMINABONUS: *vp = INT_TO_JSVAL( gPriv->GetStaminaBonus() ); break; + case CIP_MANABONUS: *vp = INT_TO_JSVAL( gPriv->GetManaBonus() ); break; case CIP_NAME2: tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() ); *vp = STRING_TO_JSVAL( tString ); @@ -1324,9 +1324,9 @@ JSBool CItemProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: gPriv->SetWeatherDamage( RAIN, encaps.toBool() ); break; case CIP_DAMAGESNOW: gPriv->SetWeatherDamage( SNOW, encaps.toBool() ); break; case CIP_SPEED: gPriv->SetSpeed( static_cast( encaps.toInt() )); break; - case CIP_BONUSHITS: gPriv->SetBonusHits( static_cast( encaps.toInt() )); break; - case CIP_BONUSSTAM: gPriv->SetBonusStam( static_cast( encaps.toInt() )); break; - case CIP_BONUSMANA: gPriv->SetBonusMana( static_cast( encaps.toInt() )); break; + case CIP_HEALTHBONUS: gPriv->SetHealthBonus( static_cast( encaps.toInt() )); break; + case CIP_STAMINABONUS: gPriv->SetStaminaBonus( static_cast( encaps.toInt() )); break; + case CIP_MANABONUS: gPriv->SetManaBonus( static_cast( encaps.toInt() )); break; case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break; case CIP_RACE: gPriv->SetRace( static_cast( encaps.toInt() )); break; case CIP_MAXHP: gPriv->SetMaxHP( static_cast( encaps.toInt() )); break; diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index c5a8c8039..8b33d4bc8 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -535,9 +535,9 @@ inline JSPropertySpec CItemProps[] = { "ammoFXHue", CIP_AMMOFXHUE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ammoFXRender", CIP_AMMOFXRENDER, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "speed", CIP_SPEED, JSPROP_ENUMANDPERM, nullptr, nullptr }, - { "bonusHits", CIP_BONUSHITS, JSPROP_ENUMANDPERM, nullptr, nullptr }, - { "bonusStam", CIP_BONUSSTAM, JSPROP_ENUMANDPERM, nullptr, nullptr }, - { "bonusMana", CIP_BONUSMANA, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "healthBonus", CIP_HEALTHBONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "staminaBonus", CIP_STAMINABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "manaBonus", CIP_MANABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "multi", CIP_MULTI, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "maxRange", CIP_MAXRANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "baseRange", CIP_BASERANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index abeb8590f..131f0417b 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -94,9 +94,9 @@ const SI16 DEFBASE_KILLS = 0; const UI16 DEFBASE_RESIST = 0; const bool DEFBASE_NAMEREQUESTACTIVE = 0; const ExpansionRuleset DEFBASE_ORIGIN = ER_UO; -const SI16 DEFBASE_BONUSHEALTH = 0; -const SI16 DEFBASE_BONUSSTAMINA = 0; -const SI16 DEFBASE_BONUSMANA = 0; +const SI16 DEFBASE_HEALTHBONUS = 0; +const SI16 DEFBASE_STAMINABONOS = 0; +const SI16 DEFBASE_MANABONUS = 0; //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject constructor @@ -114,7 +114,7 @@ mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ), poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ), fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ), -bonusHits( DEFBASE_BONUSHEALTH ),bonusStam( DEFBASE_BONUSSTAMINA ), bonusMana( DEFBASE_BONUSMANA ) +healthBonus( DEFBASE_HEALTHBONUS ),staminaBonus( DEFBASE_STAMINABONOS ), manaBonus( DEFBASE_MANABONUS ) { multis = nullptr; tempMulti = INVALIDSERIAL; @@ -1636,19 +1636,19 @@ void CBaseObject::SetIntelligence2( SI16 nVal ) } //o------------------------------------------------------------------------------------------------o -//| Function - CBaseObject::GetBonusHits() -//| CBaseObject::SetBonusHits() +//| Function - CBaseObject::GetHealthBonus() +//| CBaseObject::SetHealthBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Gets/Sets the health max var associated with the object. For chars, it's the //| bonuses (via armour and such) //o------------------------------------------------------------------------------------------------o -SI16 CBaseObject::GetBonusHits( void ) const +SI16 CBaseObject::GetHealthBonus( void ) const { - return bonusHits; + return healthBonus; } -void CBaseObject::SetBonusHits( SI16 nVal ) +void CBaseObject::SetHealthBonus( SI16 nVal ) { - bonusHits = nVal; + healthBonus = nVal; if( CanBeObjType( OT_ITEM )) { @@ -1657,19 +1657,19 @@ void CBaseObject::SetBonusHits( SI16 nVal ) } //o------------------------------------------------------------------------------------------------o -//| Function - CBaseObject::GetBonusStam() -//| CBaseObject::SetBonusStam() +//| Function - CBaseObject::GetStaminaBonus() +//| CBaseObject::SetStaminaBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Gets/Sets the stamina max var associated with the object. For chars, it's the //| bonuses (via armour and such) //o------------------------------------------------------------------------------------------------o -SI16 CBaseObject::GetBonusStam( void ) const +SI16 CBaseObject::GetStaminaBonus( void ) const { - return bonusStam; + return staminaBonus; } -void CBaseObject::SetBonusStam( SI16 nVal ) +void CBaseObject::SetStaminaBonus( SI16 nVal ) { - bonusStam = nVal; + staminaBonus = nVal; if( CanBeObjType( OT_ITEM )) { @@ -1678,19 +1678,19 @@ void CBaseObject::SetBonusStam( SI16 nVal ) } //o------------------------------------------------------------------------------------------------o -//| Function - CBaseObject::GetBonusMana() -//| CBaseObject::SetBonusMana() +//| Function - CBaseObject::GetManaBonus() +//| CBaseObject::SetManaBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Gets/Sets the Mana max var associated with the object. For chars, it's the //| bonuses (via armour and such) //o------------------------------------------------------------------------------------------------o -SI16 CBaseObject::GetBonusMana( void ) const +SI16 CBaseObject::GetManaBonus( void ) const { - return bonusMana; + return manaBonus; } -void CBaseObject::SetBonusMana( SI16 nVal ) +void CBaseObject::SetManaBonus( SI16 nVal ) { - bonusMana = nVal; + manaBonus = nVal; if( CanBeObjType( OT_ITEM )) { diff --git a/source/cBaseObject.h b/source/cBaseObject.h index 15563feca..b3c7e98f9 100644 --- a/source/cBaseObject.h +++ b/source/cBaseObject.h @@ -79,9 +79,9 @@ class CBaseObject SI16 st2; SI16 dx2; SI16 in2; - SI16 bonusHits; - SI16 bonusStam; - SI16 bonusMana; + SI16 healthBonus; + SI16 staminaBonus; + SI16 manaBonus; mutable SI32 FilePosition; SERIAL tempMulti; std::string name; @@ -259,14 +259,14 @@ class CBaseObject void IncDexterity( SI16 toInc = 1 ); void IncIntelligence( SI16 toInc = 1 ); - SI16 GetBonusHits( void ) const; - virtual void SetBonusHits( SI16 nVal ); + SI16 GetHealthBonus( void ) const; + virtual void SetHealthBonus( SI16 nVal ); - SI16 GetBonusStam( void ) const; - virtual void SetBonusStam( SI16 nVal ); + SI16 GetStaminaBonus( void ) const; + virtual void SetStaminaBonus( SI16 nVal ); - SI16 GetBonusMana( void ) const; - virtual void SetBonusMana( SI16 nVal ); + SI16 GetManaBonus( void ) const; + virtual void SetManaBonus( SI16 nVal ); virtual void PostLoadProcessing( void ); virtual bool LoadRemnants( void ) = 0; diff --git a/source/cChar.cpp b/source/cChar.cpp index 530053021..bcd9e90f6 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,9 +2920,9 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); - IncBonusHits( itemLayers[tLayer]->GetBonusHits() ); - IncBonusStam( itemLayers[tLayer]->GetBonusStam() ); - IncBonusMana( itemLayers[tLayer]->GetBonusMana() ); + IncHealthBonus( itemLayers[tLayer]->GetHealthBonus() ); + IncStaminaBonus( itemLayers[tLayer]->GetStaminaBonus() ); + IncManaBonus( itemLayers[tLayer]->GetManaBonus() ); if( toWear->IsPostLoaded() ) { @@ -2984,9 +2984,9 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); - IncBonusHits( -itemLayers[Layer]->GetBonusHits() ); - IncBonusStam( -itemLayers[Layer]->GetBonusStam() ); - IncBonusMana( -itemLayers[Layer]->GetBonusMana() ); + IncHealthBonus( -itemLayers[Layer]->GetHealthBonus() ); + IncStaminaBonus( -itemLayers[Layer]->GetStaminaBonus() ); + IncManaBonus( -itemLayers[Layer]->GetManaBonus() ); if( itemLayers[Layer]->GetPoisoned() ) { @@ -3796,7 +3796,7 @@ UI16 CChar::GetMaxHP( void ) oldRace = GetRace(); } - return maxHP + GetBonusHits(); + return maxHP + GetHealthBonus(); } void CChar::SetMaxHP( UI16 newmaxhp, UI16 newoldstr, RACEID newoldrace ) { @@ -3856,7 +3856,7 @@ SI16 CChar::GetMaxMana( void ) oldRace = GetRace(); } - return maxMana + GetBonusMana(); + return maxMana + GetManaBonus(); } void CChar::SetMaxMana( SI16 newmaxmana, UI16 newoldint, RACEID newoldrace ) { @@ -3916,7 +3916,7 @@ SI16 CChar::GetMaxStam( void ) oldRace = GetRace(); } - return maxStam + GetBonusStam(); + return maxStam + GetStaminaBonus(); } void CChar::SetMaxStam( SI16 newmaxstam, UI16 newolddex, RACEID newoldrace ) { @@ -5603,72 +5603,71 @@ void CChar::SetIntelligence2( SI16 nVal ) } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::SetBonusHits() +//| Function - CChar::SetHealthBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Sets bonus Hits stat for character //o------------------------------------------------------------------------------------------------o -void CChar::SetBonusHits( SI16 nVal ) +void CChar::SetHealthBonus( SI16 nVal ) { - CBaseObject::SetBonusHits( nVal ); + CBaseObject::SetHealthBonus( nVal ); Dirty( UT_HITPOINTS ); UpdateRegion(); } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::SetBonusStam() +//| Function - CChar::SetStaminaBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Sets bonus Stam stat for character //o------------------------------------------------------------------------------------------------o -void CChar::SetBonusStam( SI16 nVal ) +void CChar::SetStaminaBonus( SI16 nVal ) { - CBaseObject::SetBonusStam( nVal ); + CBaseObject::SetStaminaBonus( nVal ); Dirty( UT_STAMINA ); UpdateRegion(); } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::SetBonusMana() +//| Function - CChar::SetManaBonus() //o------------------------------------------------------------------------------------------------o //| Purpose - Sets bonus Mana stat for character //o------------------------------------------------------------------------------------------------o -void CChar::SetBonusMana( SI16 nVal ) +void CChar::SetManaBonus( SI16 nVal ) { - CBaseObject::SetBonusMana( nVal ); + CBaseObject::SetManaBonus( nVal ); Dirty( UT_MANA ); UpdateRegion(); } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::IncBonusHits() -//| Date - 26 May 2024 +//| Function - CChar::IncHealthBonus() //o------------------------------------------------------------------------------------------------o -//| Purpose - Increments GetBonusHits (modifications) by toAdd +//| Purpose - Increments GetHealthBonus (modifications) by toAdd //o------------------------------------------------------------------------------------------------o -void CChar::IncBonusHits( SI16 toAdd ) +void CChar::IncHealthBonus( SI16 toAdd ) { - SetBonusHits( static_cast( GetBonusHits() + toAdd )); + SetHealthBonus( static_cast( GetHealthBonus() + toAdd )); } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::IncBonusStam() +//| Function - CChar::IncStaminaBonus() //| Date - 26 May 2024 //o------------------------------------------------------------------------------------------------o //| Purpose - Increments GetBonusStam (modifications) by toAdd //o------------------------------------------------------------------------------------------------o -void CChar::IncBonusStam( SI16 toAdd ) +void CChar::IncStaminaBonus( SI16 toAdd ) { - SetBonusStam( static_cast( GetBonusStam() + toAdd )); + SetStaminaBonus( static_cast( GetStaminaBonus() + toAdd )); } //o------------------------------------------------------------------------------------------------o -//| Function - CChar::IncBonusMana() +//| Function - CChar::IncManaBonus() //| Date - 26 May 2024 //o------------------------------------------------------------------------------------------------o //| Purpose - Increments GetBonusMana (modifications) by toAdd //o------------------------------------------------------------------------------------------------o -void CChar::IncBonusMana( SI16 toAdd ) +void CChar::IncManaBonus( SI16 toAdd ) { - SetBonusMana( static_cast( GetBonusMana() + toAdd )); + SetManaBonus( static_cast( GetManaBonus() + toAdd )); } //o------------------------------------------------------------------------------------------------o diff --git a/source/cChar.h b/source/cChar.h index 3156340ff..ae387a58c 100644 --- a/source/cChar.h +++ b/source/cChar.h @@ -629,13 +629,13 @@ class CChar : public CBaseObject virtual void SetDexterity2( SI16 newValue ) override; virtual void SetIntelligence2( SI16 newValue ) override; - virtual void SetBonusHits( SI16 newValue ) override; - virtual void SetBonusStam( SI16 newValue ) override; - virtual void SetBonusMana( SI16 newValue ) override; + virtual void SetHealthBonus( SI16 newValue ) override; + virtual void SetStaminaBonus( SI16 newValue ) override; + virtual void SetManaBonus( SI16 newValue ) override; - void IncBonusHits( SI16 toAdd = 1 ); - void IncBonusStam( SI16 toAdd = 1 ); - void IncBonusMana( SI16 toAdd = 1 ); + void IncHealthBonus( SI16 toAdd = 1 ); + void IncStaminaBonus( SI16 toAdd = 1 ); + void IncManaBonus( SI16 toAdd = 1 ); void IncStamina( SI16 toInc ); void IncMana( SI16 toInc ); diff --git a/source/cItem.cpp b/source/cItem.cpp index c345ecdc2..e19ff45d1 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1654,9 +1654,9 @@ auto CItem::CopyData( CItem *target ) -> void target->SetWeightMax( GetWeightMax() ); target->SetBaseWeight( GetBaseWeight() ); target->SetMaxItems( GetMaxItems() ); - target->SetBonusHits( GetBonusHits() ); - target->SetBonusStam( GetBonusStam() ); - target->SetBonusMana( GetBonusMana() ); + target->SetHealthBonus( GetHealthBonus() ); + target->SetStaminaBonus( GetStaminaBonus() ); + target->SetManaBonus( GetManaBonus() ); //target->SetWipeable( IsWipeable() ); target->SetPriv( GetPriv() ); target->SetBaseRange( GetBaseRange() ); @@ -1740,7 +1740,7 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "MaxItems=" + std::to_string( GetMaxItems() ) + newLine; outStream << "MaxHP=" + std::to_string( GetMaxHP() ) + newLine; outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; - outStream << "BonusStats=" + std::to_string( GetBonusHits() ) + "," + std::to_string( GetBonusStam() ) + "," + std::to_string( GetBonusMana() ) + newLine; + outStream << "BonusStats=" + std::to_string( GetHealthBonus() ) + "," + std::to_string( GetStaminaBonus() ) + "," + std::to_string( GetManaBonus() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; outStream << "Value=" + std::to_string( GetBuyValue() ) + "," + std::to_string( GetSellValue() ) + "," + std::to_string( GetVendorPrice() ) + newLine; @@ -1826,9 +1826,9 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) } else if( UTag == "BONUSSTATS" ) { - SetBonusHits( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[0], "//" )), nullptr, 0 ))); - SetBonusStam( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[1], "//" )), nullptr, 0 ))); - SetBonusMana( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[2], "//" )), nullptr, 0 ))); + SetHealthBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[0], "//" )), nullptr, 0 ))); + SetStaminaBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[1], "//" )), nullptr, 0 ))); + SetManaBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[2], "//" )), nullptr, 0 ))); rValue = true; } break; diff --git a/source/items.cpp b/source/items.cpp index 3bb17bb66..60c6468b7 100644 --- a/source/items.cpp +++ b/source/items.cpp @@ -139,9 +139,9 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect break; case DFNTAG_AC: applyTo->SetArmourClass( static_cast( ndata )); break; case DFNTAG_BASERANGE: applyTo->SetBaseRange( static_cast( ndata )); break; - case DFNTAG_BONUSHITS: applyTo->SetBonusHits( static_cast( ndata )); break; - case DFNTAG_BONUSSTAM: applyTo->SetBonusStam( static_cast( ndata )); break; - case DFNTAG_BONUSMANA: applyTo->SetBonusMana( static_cast( ndata )); break; + case DFNTAG_HEALTHBONUS: applyTo->SetHealthBonus( static_cast( ndata )); break; + case DFNTAG_STAMINABONUS: applyTo->SetStaminaBonus( static_cast( ndata )); break; + case DFNTAG_MANABONUS: applyTo->SetManaBonus( static_cast( ndata )); break; case DFNTAG_CREATOR: applyTo->SetCreator( ndata ); break; case DFNTAG_COLOUR: applyTo->SetColour( static_cast( ndata )); break; case DFNTAG_COLOURLIST: applyTo->SetColour( AddRandomColor( cdata )); break; diff --git a/source/ssection.cpp b/source/ssection.cpp index dbfc8a475..52f73da5d 100644 --- a/source/ssection.cpp +++ b/source/ssection.cpp @@ -215,9 +215,9 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_STRING, // DFNTAG_SPAWNOBJ, DFN_STRING, // DFNTAG_SPAWNOBJLIST, DFN_NUMERIC, // DFNTAG_SPD, - DFN_NUMERIC, // DFNTAG_BONUSHITS, - DFN_NUMERIC, // DFNTAG_BONUSSTAM, - DFN_NUMERIC, // DFNTAG_BONUSMANA, + DFN_NUMERIC, // DFNTAG_HEALTHBONUS, + DFN_NUMERIC, // DFNTAG_STAMINABONUS, + DFN_NUMERIC, // DFNTAG_MANABONUS, DFN_STRING, // DFNTAG_SPELLS, DFN_DOUBLENUMERIC, // DFNTAG_SPELLWEAVING, DFN_DOUBLENUMERIC, // DFNTAG_SPIRITSPEAK, @@ -286,9 +286,9 @@ const std::map strToDFNTag {"BLACKSMITHING"s, DFNTAG_BLACKSMITHING}, {"BOWCRAFT"s, DFNTAG_BOWCRAFT}, {"BUSHIDO"s, DFNTAG_BUSHIDO}, - {"BONUSHITS"s, DFNTAG_BONUSHITS}, - {"BONUSSTAM"s, DFNTAG_BONUSSTAM}, - {"BONUSMANA"s, DFNTAG_BONUSMANA}, + {"HEALTHBONUS"s, DFNTAG_HEALTHBONUS}, + {"STAMINABONUS"s, DFNTAG_STAMINABONUS}, + {"MANABONUS"s, DFNTAG_MANABONUS}, {"CAMPING"s, DFNTAG_CAMPING}, {"CARPENTRY"s, DFNTAG_CARPENTRY}, {"CARTOGRAPHY"s, DFNTAG_CARTOGRAPHY}, diff --git a/source/ssection.h b/source/ssection.h index 8ffc1edc9..ca227c23b 100644 --- a/source/ssection.h +++ b/source/ssection.h @@ -222,9 +222,9 @@ enum DFNTAGS DFNTAG_SPAWNOBJ, DFNTAG_SPAWNOBJLIST, DFNTAG_SPD, - DFNTAG_BONUSHITS, - DFNTAG_BONUSSTAM, - DFNTAG_BONUSMANA, + DFNTAG_HEALTHBONUS, + DFNTAG_STAMINABONUS, + DFNTAG_MANABONUS, DFNTAG_SPELLS, DFNTAG_SPELLWEAVING, DFNTAG_SPIRITSPEAK, From 7c101e668290939e1fe3956163b02b1c16934c47 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 18:58:24 -0500 Subject: [PATCH 15/37] Update Changelog.txt --- source/Changelog.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Changelog.txt b/source/Changelog.txt index c695610cd..61554e478 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,8 +1,8 @@ 13/05/2024 - Dragon Slayer Added three More AOS Props - -BONUSHITS=# - -BONUSMANA=# - -BONUSSTAM=# + -HEALTHBONUS=# + -MANABONUS=# + -STAMINABONUS=# Add this properties to any weapon/armor/jewlery will give the player more hp/mana/stam why its equiped. depending on number you add with it 27/04/2024 - Dragon Slayer/Xuri From c8bceabc303c0ab2e05383f8d409dd9c72f64086 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 16 Jun 2024 19:00:03 -0500 Subject: [PATCH 16/37] Update Changelog.txt --- source/Changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Changelog.txt b/source/Changelog.txt index 61554e478..eb4a9d532 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -4,6 +4,7 @@ -MANABONUS=# -STAMINABONUS=# Add this properties to any weapon/armor/jewlery will give the player more hp/mana/stam why its equiped. depending on number you add with it + These are also available as JS Engine object properties: .healthBonus, .staminaBonus, .manaBonus 27/04/2024 - Dragon Slayer/Xuri Fixed an issue where non-corpse containers - including treasure chests in dungeons - would decay and leave all their contents on the ground. From da9267ac987cc2a09e51208a74e9a93fd454c4fd Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:28:50 -0500 Subject: [PATCH 17/37] Added AOS Leech Properties --- data/js/combat/leechstats.js | 60 ++++++++++++++++++++ data/js/jse_fileassociations.scp | 1 + source/CPacketSend.cpp | 22 ++++++++ source/UOXJSPropertyEnums.h | 4 +- source/UOXJSPropertyFuncs.cpp | 6 ++ source/UOXJSPropertySpecs.h | 3 + source/cBaseObject.cpp | 96 +++++++++++++++++++++++++++++++- source/cBaseObject.h | 16 ++++++ source/cChar.cpp | 8 +++ source/cItem.cpp | 11 ++++ source/items.cpp | 3 + source/ssection.cpp | 6 ++ source/ssection.h | 3 + 13 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 data/js/combat/leechstats.js diff --git a/data/js/combat/leechstats.js b/data/js/combat/leechstats.js new file mode 100644 index 000000000..6663958ba --- /dev/null +++ b/data/js/combat/leechstats.js @@ -0,0 +1,60 @@ +function onEquip( pEquipper, iEquipped ) +{ + pEquipper.AddScriptTrigger( 7003 ); +} + +// Remove script trigger on unequip +function onUnequip( pUnequipper, iUnequipped ) +{ + pUnequipper.RemoveScriptTrigger( 7003 ); +} + +function onDamageDeal( attacker, damaged, damageValue, damageType ) +{ + // Fetch weapon in main hand or secondary hand + var iWeapon = attacker.FindItemLayer( 0x01 ); + if( !ValidateObject( iWeapon )) + { + iWeapon = attacker.FindItemLayer( 0x02 ); + } + + if( ValidateObject( iWeapon )) + { // Apply leech effects based on weapon properties + ApplyLeech( attacker, damaged, damageValue, iWeapon, 'healthLeech', 30 ); + ApplyLeech( attacker, damaged, damageValue, iWeapon, 'staminaLeech', 100 ); + ApplyLeech( attacker, damaged, damageValue, iWeapon, 'manaLeech', 40 ); + } + + return true; +} + +function ApplyLeech( attacker, damaged, damageValue, weapon, leechType, multiplier ) +{ + // Get the leech amount for the specified leech type from the weapon + var leechAmount = weapon[ leechType ]; + if( leechAmount > 0 ) + { // Calculate the minimum and maximum leech values + var minLeech = Math.round( damageValue * ( leechAmount / 100 ) * ( multiplier/100 )); + var maxLeech = Math.round( ( ( weapon.speed / 100 ) * 2500 ) / ( 100 + weapon.speedIncrease )); + var leechAmt = RandomNumber( minLeech, maxLeech ); + + // Apply the leech effect based on the leech type + switch( leechType ) + { + case 'healthLeech': + attacker.Heal( leechAmt ); + damaged.health -= leechAmt; + break; + case 'staminaLeech': + attacker.stamina += leechAmt; + damaged.stamina -= leechAmt; + break; + case 'manaLeech': + attacker.mana += leechAmt; + damaged.mana -= leechAmt; + break; + } + + attacker.SoundEffect( 0x44D, true ); + } +} \ No newline at end of file diff --git a/data/js/jse_fileassociations.scp b/data/js/jse_fileassociations.scp index 2cbb8e3d5..7b16b631a 100644 --- a/data/js/jse_fileassociations.scp +++ b/data/js/jse_fileassociations.scp @@ -329,6 +329,7 @@ // Combat Scripts [7000-7499] //------------------------------------------- 7000=combat/peacemake_effect.js +7003=combat/leechstats.js //------------------------------------------- // Misc Player Scripts [8000-8499] diff --git a/source/CPacketSend.cpp b/source/CPacketSend.cpp index e1d8ee4ca..28f3a2a40 100644 --- a/source/CPacketSend.cpp +++ b/source/CPacketSend.cpp @@ -7465,6 +7465,28 @@ void CPToolTip::CopyItemData( CItem& cItem, size_t &totalStringLen, bool addAmou tempEntry.ourText = oldstrutil::number( cItem.GetTempVar( CITV_MOREZ )); FinalizeData( tempEntry, totalStringLen ); } + + if( cItem.GetManaLeech() > 0 ) + { + tempEntry.stringNum = 1060427; // hit mana leech ~1_val~% + tempEntry.ourText = oldstrutil::number( cItem.GetManaLeech() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetStaminaLeech() > 0 ) + { + tempEntry.stringNum = 1060430; // hit stamina leech ~1_val~% + tempEntry.ourText = oldstrutil::number( cItem.GetStaminaLeech() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetHealthLeech() > 0 ) + { + tempEntry.stringNum = 1060422; // hit life leech ~1_val~% + tempEntry.ourText = oldstrutil::number( cItem.GetHealthLeech() ); + FinalizeData( tempEntry, totalStringLen ); + } + if( cItem.GetType() == IT_SPELLCHANNELING ) { tempEntry.stringNum = 1060482; // spell channeling diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h index af309d496..ada680894 100644 --- a/source/UOXJSPropertyEnums.h +++ b/source/UOXJSPropertyEnums.h @@ -495,7 +495,9 @@ enum CI_Properties CIP_SECTIONALIST, CIP_MININTERVAL, CIP_MAXINTERVAL, - + CIP_HEALTHLEECH, + CIP_STAMINALEECH, + CIP_MANALEECH, CIP_ISNEWBIE, CIP_ISDISPELLABLE, CIP_MADEWITH, diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp index 3823356f9..2e210e2d0 100644 --- a/source/UOXJSPropertyFuncs.cpp +++ b/source/UOXJSPropertyFuncs.cpp @@ -676,6 +676,9 @@ JSBool CItemProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( RAIN )); break; case CIP_DAMAGESNOW: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( SNOW )); break; case CIP_SPEED: *vp = INT_TO_JSVAL( gPriv->GetSpeed() ); break; + case CIP_HEALTHLEECH: *vp = INT_TO_JSVAL( gPriv->GetHealthLeech() ); break; + case CIP_STAMINALEECH: *vp = INT_TO_JSVAL( gPriv->GetStaminaLeech() ); break; + case CIP_MANALEECH: *vp = INT_TO_JSVAL( gPriv->GetManaLeech() ); break; case CIP_NAME2: tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() ); *vp = STRING_TO_JSVAL( tString ); @@ -1321,6 +1324,9 @@ JSBool CItemProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: gPriv->SetWeatherDamage( RAIN, encaps.toBool() ); break; case CIP_DAMAGESNOW: gPriv->SetWeatherDamage( SNOW, encaps.toBool() ); break; case CIP_SPEED: gPriv->SetSpeed( static_cast( encaps.toInt() )); break; + case CIP_HEALTHLEECH: gPriv->SetHealthLeech( static_cast( encaps.toInt() )); break; + case CIP_STAMINALEECH: gPriv->SetStaminaLeech( static_cast( encaps.toInt() )); break; + case CIP_MANALEECH: gPriv->SetManaLeech( static_cast( encaps.toInt() )); break; case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break; case CIP_RACE: gPriv->SetRace( static_cast( encaps.toInt() )); break; case CIP_MAXHP: gPriv->SetMaxHP( static_cast( encaps.toInt() )); break; diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index 3149dc0ec..15795c036 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -535,6 +535,9 @@ inline JSPropertySpec CItemProps[] = { "ammoFXHue", CIP_AMMOFXHUE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ammoFXRender", CIP_AMMOFXRENDER, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "speed", CIP_SPEED, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "healthLeech", CIP_HEALTHLEECH, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "staminaLeech", CIP_STAMINALEECH, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "manaLeech", CIP_MANALEECH, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "multi", CIP_MULTI, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "maxRange", CIP_MAXRANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "baseRange", CIP_BASERANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index 506c247ac..2c5ce0b89 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -94,6 +94,9 @@ const SI16 DEFBASE_KILLS = 0; const UI16 DEFBASE_RESIST = 0; const bool DEFBASE_NAMEREQUESTACTIVE = 0; const ExpansionRuleset DEFBASE_ORIGIN = ER_UO; +const SI16 DEFBASE_HEALTHLEECH = 0; +const SI16 DEFBASE_STAMINALEECH = 0; +const SI16 DEFBASE_MANALEECH = 0; //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject constructor @@ -110,7 +113,8 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ), mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ), in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ), poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ), -fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ) +fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ), +healthLeech( DEFBASE_HEALTHLEECH ), staminaLeech( DEFBASE_STAMINALEECH ), manaLeech( DEFBASE_MANALEECH ) { multis = nullptr; tempMulti = INVALIDSERIAL; @@ -1631,6 +1635,66 @@ void CBaseObject::SetIntelligence2( SI16 nVal ) } } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetHealthLeech() +//| CBaseObject::SetHealthLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Health Leech +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetHealthLeech( void ) const +{ + return healthLeech; +} +void CBaseObject::SetHealthLeech( SI16 nVal ) +{ + healthLeech = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetStaminaLeech() +//| CBaseObject::SetStaminaLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Stamina Leech +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetStaminaLeech( void ) const +{ + return staminaLeech; +} +void CBaseObject::SetStaminaLeech( SI16 nVal ) +{ + staminaLeech = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetManaLeech() +//| CBaseObject::SetManaLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Mana Leech +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetManaLeech( void ) const +{ + return manaLeech; +} +void CBaseObject::SetManaLeech( SI16 nVal ) +{ + manaLeech = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::IncStrength() //o------------------------------------------------------------------------------------------------o @@ -1661,6 +1725,36 @@ void CBaseObject::IncIntelligence( SI16 toInc ) SetIntelligence( intelligence + toInc ); } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::IncHealthLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments the object's Health Leech Points value +//o------------------------------------------------------------------------------------------------o +void CBaseObject::IncHealthLeech( SI16 toInc ) +{ + SetHealthLeech( healthLeech + toInc ); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::IncStaminaLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments the object's Stamina Leech Points value +//o------------------------------------------------------------------------------------------------o +void CBaseObject::IncStaminaLeech( SI16 toInc ) +{ + SetStaminaLeech( staminaLeech + toInc ); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::IncManaLeech() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments the object's Mana Leech Points value +//o------------------------------------------------------------------------------------------------o +void CBaseObject::IncManaLeech( SI16 toInc ) +{ + SetManaLeech( manaLeech + toInc ); +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::DumpFooter() //o------------------------------------------------------------------------------------------------o diff --git a/source/cBaseObject.h b/source/cBaseObject.h index 638e826f7..316cd2530 100644 --- a/source/cBaseObject.h +++ b/source/cBaseObject.h @@ -75,6 +75,9 @@ class CBaseObject SI32 weight; SI16 mana; SI16 stamina; + SI16 healthLeech; + SI16 staminaLeech; + SI16 manaLeech; UI16 scriptTrig; SI16 st2; SI16 dx2; @@ -256,6 +259,19 @@ class CBaseObject void IncDexterity( SI16 toInc = 1 ); void IncIntelligence( SI16 toInc = 1 ); + SI16 GetHealthLeech( void ) const; + virtual void SetHealthLeech( SI16 nVal ); + + SI16 GetStaminaLeech( void ) const; + virtual void SetStaminaLeech( SI16 nVal ); + + SI16 GetManaLeech( void ) const; + virtual void SetManaLeech( SI16 nVal ); + + void IncHealthLeech( SI16 toInc = 1 ); + void IncStaminaLeech( SI16 toInc = 1 ); + void IncManaLeech( SI16 toInc = 1 ); + virtual void PostLoadProcessing( void ); virtual bool LoadRemnants( void ) = 0; diff --git a/source/cChar.cpp b/source/cChar.cpp index 7aa03f6fa..439a72527 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,6 +2920,10 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); + IncHealthLeech( itemLayers[tLayer]->GetHealthLeech() ); + IncStaminaLeech( itemLayers[tLayer]->GetStaminaLeech() ); + IncManaLeech( itemLayers[tLayer]->GetManaLeech() ); + if( toWear->IsPostLoaded() ) { if( itemLayers[tLayer]->GetPoisoned() ) @@ -2979,6 +2983,10 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncStrength2( -itemLayers[Layer]->GetStrength2() ); IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); + + IncHealthLeech( -itemLayers[Layer]->GetHealthLeech() ); + IncStaminaLeech( -itemLayers[Layer]->GetStaminaLeech() ); + IncManaLeech( -itemLayers[Layer]->GetManaLeech() ); if( itemLayers[Layer]->GetPoisoned() ) { if( itemLayers[Layer]->GetPoisoned() > GetPoisoned() ) diff --git a/source/cItem.cpp b/source/cItem.cpp index 3c6523d5d..672ece4dd 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1644,6 +1644,9 @@ auto CItem::CopyData( CItem *target ) -> void target->SetStamina( GetStamina() ); target->SetStrength( GetStrength() ); target->SetStrength2( GetStrength2() ); + target->SetHealthLeech( GetHealthLeech() ); + target->SetStaminaLeech( GetStaminaLeech() ); + target->SetManaLeech( GetManaLeech() ); target->SetTitle( GetTitle() ); target->SetType( GetType() ); target->SetBuyValue( GetBuyValue() ); @@ -1739,6 +1742,7 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; + outStream << "LeechStats=" + std::to_string( GetHealthLeech() ) + "," + std::to_string( GetStaminaLeech() ) + "," + std::to_string( GetManaLeech() ) + newLine; outStream << "Value=" + std::to_string( GetBuyValue() ) + "," + std::to_string( GetSellValue() ) + "," + std::to_string( GetVendorPrice() ) + newLine; outStream << "Restock=" + std::to_string( GetRestock() ) + newLine; outStream << "AC=" + std::to_string( GetArmourClass() ) + newLine; @@ -1922,6 +1926,13 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) SetWeatherDamage( LIGHTNING, static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ); rValue = true; } + else if( UTag == "LEECHSTATS" ) + { + SetHealthLeech( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[0], "//" )), nullptr, 0 ))); + SetStaminaLeech( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[1], "//" )), nullptr, 0 ))); + SetManaLeech( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[2], "//" )), nullptr, 0 ))); + rValue = true; + } break; case 'M': if( UTag == "MAXITEMS" ) diff --git a/source/items.cpp b/source/items.cpp index 1cd4a2aaf..a3cec1199 100644 --- a/source/items.cpp +++ b/source/items.cpp @@ -138,6 +138,9 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect } break; case DFNTAG_AC: applyTo->SetArmourClass( static_cast( ndata )); break; + case DFNTAG_HEALTHLEECH: applyTo->SetHealthLeech( static_cast( ndata )); break; + case DFNTAG_STAMINALEECH: applyTo->SetStaminaLeech( static_cast( ndata )); break; + case DFNTAG_MANALEECH: applyTo->SetManaLeech( static_cast( ndata )); break; case DFNTAG_BASERANGE: applyTo->SetBaseRange( static_cast( ndata )); break; case DFNTAG_CREATOR: applyTo->SetCreator( ndata ); break; case DFNTAG_COLOUR: applyTo->SetColour( static_cast( ndata )); break; diff --git a/source/ssection.cpp b/source/ssection.cpp index c2a563b47..2ed0d8b70 100644 --- a/source/ssection.cpp +++ b/source/ssection.cpp @@ -115,6 +115,7 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_NODATA, // DFNTAG_HIRELING, DFN_DOUBLENUMERIC, // DFNTAG_HP, DFN_DOUBLENUMERIC, // DFNTAG_HPMAX, + DFN_NUMERIC, // DFNTAG_HEALTHLEECH, DFN_UPPERSTRING, // DFNTAG_ID, DFN_DOUBLENUMERIC, // DFNTAG_IMBUING, DFN_NUMERIC, // DFNTAG_INTADD, @@ -140,6 +141,7 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_DOUBLENUMERIC, // DFNTAG_MAGICRESISTANCE, DFN_DOUBLENUMERIC, // DFNTAG_MANA, DFN_DOUBLENUMERIC, // DFNTAG_MANAMAX, + DFN_NUMERIC, // DFNTAG_MANALEECH, DFN_NUMERIC, // DFNTAG_MAXHP, DFN_NUMERIC, // DFNTAG_MAXITEMS, DFN_NUMERIC, // DFNTAG_MAXLOYALTY, @@ -222,6 +224,7 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_NUMERIC, // DFNTAG_SPLITCHANCE, DFN_DOUBLENUMERIC, // DFNTAG_STAMINA, DFN_DOUBLENUMERIC, // DFNTAG_STAMINAMAX, + DFN_NUMERIC, // DFNTAG_STAMINALEECH, DFN_DOUBLENUMERIC, // DFNTAG_STRENGTH, DFN_NUMERIC, // DFNTAG_STRADD, DFN_NUMERIC, // DFNTAG_STEALABLE, @@ -370,6 +373,7 @@ const std::map strToDFNTag {"HIRELING"s, DFNTAG_HIRELING}, {"HP"s, DFNTAG_HP}, {"HPMAX"s, DFNTAG_HPMAX}, + {"HEALTHLEECH"s, DFNTAG_HEALTHLEECH}, {"ID"s, DFNTAG_ID}, {"IMBUING"s, DFNTAG_IMBUING}, {"IN"s, DFNTAG_INTELLIGENCE}, @@ -399,6 +403,7 @@ const std::map strToDFNTag {"MAGICRESISTANCE"s, DFNTAG_MAGICRESISTANCE}, {"MANA"s, DFNTAG_MANA}, {"MANAMAX"s, DFNTAG_MANAMAX}, + {"MANALEECH"s, DFNTAG_MANALEECH}, {"MAXHP"s, DFNTAG_MAXHP}, {"MAXITEMS"s, DFNTAG_MAXITEMS}, {"MAXLOYALTY"s, DFNTAG_MAXLOYALTY}, @@ -483,6 +488,7 @@ const std::map strToDFNTag {"ST"s, DFNTAG_STRENGTH}, {"STAMINA"s, DFNTAG_STAMINA}, {"STAMINAMAX"s, DFNTAG_STAMINAMAX}, + {"STAMINALEECH"s, DFNTAG_STAMINALEECH}, {"STR"s, DFNTAG_STRENGTH}, {"STRENGTH"s, DFNTAG_STRENGTH}, {"ST2"s, DFNTAG_STRADD}, diff --git a/source/ssection.h b/source/ssection.h index a2a660aec..be29b8d36 100644 --- a/source/ssection.h +++ b/source/ssection.h @@ -122,6 +122,7 @@ enum DFNTAGS DFNTAG_HIRELING, DFNTAG_HP, DFNTAG_HPMAX, + DFNTAG_HEALTHLEECH, DFNTAG_ID, DFNTAG_IMBUING, DFNTAG_INTADD, @@ -147,6 +148,7 @@ enum DFNTAGS DFNTAG_MAGICRESISTANCE, DFNTAG_MANA, DFNTAG_MANAMAX, + DFNTAG_MANALEECH, DFNTAG_MAXHP, DFNTAG_MAXITEMS, DFNTAG_MAXLOYALTY, @@ -229,6 +231,7 @@ enum DFNTAGS DFNTAG_SPLITCHANCE, DFNTAG_STAMINA, DFNTAG_STAMINAMAX, + DFNTAG_STAMINALEECH, DFNTAG_STRENGTH, DFNTAG_STRADD, DFNTAG_STEALABLE, From 03c2ba6dc03a5c130d097f25e9356677410e6ccb Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:36:04 -0500 Subject: [PATCH 18/37] changelog --- source/Changelog.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..ca3c53f46 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,12 @@ +18/06/2024 - Dragon Slayer + Added three new DFN tags for Items: + HEALTHLEECH=# // It gives an attacker the ability to leech health from his opponent every time he successfully delivers a hit adds it to himself. + STAMINALEECH=# // It gives an attacker the ability to leech Stamina from his opponent every time he successfully delivers a hit adds it to himself. + MANALEECH=# // It gives an attacker the ability to leech Mana from his opponent every time he successfully delivers a hit adds it to himself. + These are also available as JS Engine object properties: .healthLeech, .staminaLeech and .manaLeech + Added leechstats.js file that controls the combat for the properties. (script 7003) + To add this script to a weapon only. add in SCRIPT=7003, HEALTHLEECH=# or STAMINALEECH=# or MANALEECH=# it can also be all three on the weapon. + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From d28b8daf166b51c599972fdf055e0c652b1f9cbd Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sat, 22 Jun 2024 17:53:00 -0500 Subject: [PATCH 19/37] Update leechstats.js --- data/js/combat/leechstats.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/data/js/combat/leechstats.js b/data/js/combat/leechstats.js index 6663958ba..fc1086fdf 100644 --- a/data/js/combat/leechstats.js +++ b/data/js/combat/leechstats.js @@ -31,27 +31,23 @@ function onDamageDeal( attacker, damaged, damageValue, damageType ) function ApplyLeech( attacker, damaged, damageValue, weapon, leechType, multiplier ) { // Get the leech amount for the specified leech type from the weapon - var leechAmount = weapon[ leechType ]; - if( leechAmount > 0 ) - { // Calculate the minimum and maximum leech values - var minLeech = Math.round( damageValue * ( leechAmount / 100 ) * ( multiplier/100 )); - var maxLeech = Math.round( ( ( weapon.speed / 100 ) * 2500 ) / ( 100 + weapon.speedIncrease )); - var leechAmt = RandomNumber( minLeech, maxLeech ); + var leechPercentVal = weapon[ leechType ]; + if( leechPercentVal > 0 ) + { + // Calculate the percent of health restored to the attacker + var leechAmt = Math.round( damageValue * ( leechPercentVal / 100 ) * ( multiplier/100 )); // Apply the leech effect based on the leech type switch( leechType ) { case 'healthLeech': attacker.Heal( leechAmt ); - damaged.health -= leechAmt; break; case 'staminaLeech': attacker.stamina += leechAmt; - damaged.stamina -= leechAmt; break; case 'manaLeech': attacker.mana += leechAmt; - damaged.mana -= leechAmt; break; } From 91dd7b936da0bc58c2037b711ef1f30777f98edb Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:43:22 -0500 Subject: [PATCH 20/37] Cleaver ID added Missing Cleaver ID out of the jse_objectassionations.scp --- data/js/jse_objectassociations.scp | 2 ++ source/Changelog.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/data/js/jse_objectassociations.scp b/data/js/jse_objectassociations.scp index 93f7c41d5..25cce9751 100644 --- a/data/js/jse_objectassociations.scp +++ b/data/js/jse_objectassociations.scp @@ -580,6 +580,8 @@ 0x10a4=15007 // Swords +0x0EC2=5009 //cleaver +0x0EC3=5009 //cleaver 0x0EC4=5009 //skinning knife 0x0EC5=5009 //skinning knife 0x0F60=5009 //longsword diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..8fa5103ab 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,5 @@ +4/07/2024 - Dragon Slayer + Fixed Cleaver ID missing in the jse_objectassociations.scp or carving corpses 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From 36f2478be16865ac82b8b62bf88028cb17babaf3 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:01:56 -0500 Subject: [PATCH 21/37] Flipped Imbuing and Mysticism Skill --- data/dfndata/skills/skills.dfn | 8 ++++---- source/Changelog.txt | 2 ++ source/UOXJSPropertySpecs.h | 2 +- source/enums.h | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/data/dfndata/skills/skills.dfn b/data/dfndata/skills/skills.dfn index b28b32a15..28d129929 100644 --- a/data/dfndata/skills/skills.dfn +++ b/data/dfndata/skills/skills.dfn @@ -1206,10 +1206,10 @@ SKILLPOINT=990,5,0 SKILLPOINT=1000,0,0 } -// Imbuing +// Mysticism [SKILL 55] { -NAME=IMBUING +NAME=MYSTICISM STR=0 DEX=0 INT=0 @@ -1227,10 +1227,10 @@ SKILLPOINT=990,5,0 SKILLPOINT=1000,0,0 } -// Mysticism +// Imbuing [SKILL 56] { -NAME=MYSTICISM +NAME=IMBUING STR=0 DEX=0 INT=0 diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..246193482 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,5 @@ +12/08/2024 - Dragon Slayer + Flipped Imbuing and Mysticism Skill around. 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index 3149dc0ec..8a8ecbc47 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -675,8 +675,8 @@ inline JSPropertySpec CSkillsProps[] = { "bushido", BUSHIDO, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ninjitsu", NINJITSU, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "spellweaving", SPELLWEAVING, JSPROP_ENUMANDPERM, nullptr, nullptr }, - { "imbuing", IMBUING, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "mysticism", MYSTICISM, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "imbuing", IMBUING, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "throwing", THROWING, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "allskills", ALLSKILLS, JSPROP_ENUMANDPERM, nullptr, nullptr }, { nullptr, static_cast(0), static_cast(0), nullptr, nullptr } diff --git a/source/enums.h b/source/enums.h index 75e8786ae..cbfe20548 100644 --- a/source/enums.h +++ b/source/enums.h @@ -373,8 +373,8 @@ enum Skills BUSHIDO, NINJITSU, SPELLWEAVING, - IMBUING, MYSTICISM, + IMBUING, THROWING, ALLSKILLS, // #skills+1 From 5d7ea2bbb625a5f1de5ee1381e95acfbcb3e8bb0 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:38:17 -0500 Subject: [PATCH 22/37] update lootlists Missing lootlists for treasure maps --- data/dfndata/items/lootlists.dfn | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/data/dfndata/items/lootlists.dfn b/data/dfndata/items/lootlists.dfn index 7a62a53fd..0638b0eee 100644 --- a/data/dfndata/items/lootlists.dfn +++ b/data/dfndata/items/lootlists.dfn @@ -962,4 +962,53 @@ 100|PaintedPlagueMask 100|PaintedDaemonMask 100|PaintedEvilClownMask +} + +// Treasure Map Level 0 +[LOOTLIST TreasureMapLvl0Loot] +{//approximately 1% +990|blank +10|treasuremaplvl0 +} + +// Treasure Map Level 1 +[LOOTLIST TreasureMapLvl1Loot] +{//approximately 1% +990|blank +10|treasuremaplvl1 +} + +// Treasure Map Level 2 +[LOOTLIST TreasureMapLvl2Loot] +{//approximately 1% +990|blank +10|treasuremaplvl2 +} + +// Treasure Map Level 3 +[LOOTLIST TreasureMapLvl3Loot] +{//approximately 1% +990|blank +10|treasuremaplvl3 +} + +// Treasure Map Level 4 +[LOOTLIST TreasureMapLvl4Loot] +{//approximately 1% +990|blank +10|treasuremaplvl4 +} + +// Treasure Map Level 5 +[LOOTLIST TreasureMapLvl5Loot] +{//approximately 1% +990|blank +10|treasuremaplvl5 +} + +// Treasure Map Level 6 +[LOOTLIST TreasureMapLvl6Loot] +{//approximately 1% +990|blank +10|treasuremaplvl6 } \ No newline at end of file From 16a2b4a822881c75f73a6e7082a28e57458b2fb4 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:15:13 -0500 Subject: [PATCH 23/37] just small details cleanup remove couple extra test msgs and fixed spacing --- data/js/item/holidays/addondeedgump.js | 2 +- data/js/item/holidays/candy.js | 2 -- data/js/item/holidays/halloweenmasks.js | 2 +- data/js/item/holidays/headonaspike.js | 6 +++--- data/js/item/holidays/holidaypottedplant.js | 8 ++++---- data/js/item/holidays/pumpkins.js | 20 ++++++++++---------- data/js/item/holidays/snowpile.js | 6 +++--- 7 files changed, 22 insertions(+), 24 deletions(-) diff --git a/data/js/item/holidays/addondeedgump.js b/data/js/item/holidays/addondeedgump.js index 36e94e3e3..1f0851f6e 100644 --- a/data/js/item/holidays/addondeedgump.js +++ b/data/js/item/holidays/addondeedgump.js @@ -181,7 +181,7 @@ function CheckForNearbyDoors( myTarget, itemToCheck, pSocket ) } } - if( myTarget.DistanceTo(itemToCheck) <= 2 ) + if( myTarget.DistanceTo( itemToCheck ) <= 2 ) { return true; } diff --git a/data/js/item/holidays/candy.js b/data/js/item/holidays/candy.js index cbe3cdae9..ed007641a 100644 --- a/data/js/item/holidays/candy.js +++ b/data/js/item/holidays/candy.js @@ -18,7 +18,6 @@ function onUseChecked(pUser, iUsed) } else { - socket.SysMessage("test 1"); if( Acidity <= 30 ) { pUser.SetTempTag( "Acidity", Acidity += 5 ); @@ -26,7 +25,6 @@ function onUseChecked(pUser, iUsed) if ( Toothach == 0) { - socket.SysMessage("test 2"); pUser.SetTempTag( "toothach", 1 ); pUser.StartTimer( 1000, 0, true ); } diff --git a/data/js/item/holidays/halloweenmasks.js b/data/js/item/holidays/halloweenmasks.js index ac1919dd4..f1f031843 100644 --- a/data/js/item/holidays/halloweenmasks.js +++ b/data/js/item/holidays/halloweenmasks.js @@ -3,7 +3,7 @@ function onCreateDFN( objMade, objType ) if( objType == 0 ) { var maskname = ""; - switch(objMade.GetTag( "paintedmask" )) + switch( objMade.GetTag( "paintedmask" )) { case 1: maskname = "A Evil Clown Mask"; break; case 2: maskname = "A Daemon Mask"; break; diff --git a/data/js/item/holidays/headonaspike.js b/data/js/item/holidays/headonaspike.js index 8da857603..44b8b6192 100644 --- a/data/js/item/holidays/headonaspike.js +++ b/data/js/item/holidays/headonaspike.js @@ -4,7 +4,7 @@ function onUseChecked( pUser, iUsed ) var headspike = new Gump; var head = 0; - switch (iUsed.sectionID) + switch( iUsed.sectionID ) { case "MrsTroubleMakersHeadOnASpike": head = 30522; break; case "BrutrinsHeadOnASpike": head = 30522; break; @@ -20,7 +20,7 @@ function onUseChecked( pUser, iUsed ) default: head = 30522; } - headspike.AddGump(100, 100, head); - headspike.Send(pUser); + headspike.AddGump( 100, 100, head ); + headspike.Send( pUser ); headspike.Free(); } \ No newline at end of file diff --git a/data/js/item/holidays/holidaypottedplant.js b/data/js/item/holidays/holidaypottedplant.js index 0cc81122f..df0948203 100644 --- a/data/js/item/holidays/holidaypottedplant.js +++ b/data/js/item/holidays/holidaypottedplant.js @@ -11,14 +11,14 @@ function onUseChecked( pUser, iUsed ) PottedPlantGump( pUser, iUsed ); } -function PottedPlantGump(pUser, iUsed) +function PottedPlantGump( pUser, iUsed ) { var socket = pUser.socket; socket.tempObj = iUsed; var pottedPlant = new Gump; pottedPlant.AddPage( 0 ); - pottedPlant.AddBackground(0, 0, 360, 195, 0xA28); + pottedPlant.AddBackground( 0, 0, 360, 195, 0xA28 ); pottedPlant.AddPage( 1 ); pottedPlant.AddText( 45, 15, 0, "Choose a Potted Plant:" ); @@ -35,7 +35,7 @@ function PottedPlantGump(pUser, iUsed) pottedPlant.Free(); } -function onGumpPress(pSock, pButton, gumpData) +function onGumpPress( pSock, pButton, gumpData ) { var pUser = pSock.currentChar; var iUsed = pSock.tempObj; @@ -48,7 +48,7 @@ function onGumpPress(pSock, pButton, gumpData) } var pottedplant = ""; - if ( pButton >= 1 && pButton <= 5 ) + if( pButton >= 1 && pButton <= 5 ) { var plantIds = [0x11C8, 0x11C9, 0x11CA, 0x11CB, 0x11CC]; pottedplant = "0x" + ( plantIds[pButton - 1] ).toString( 16 ); diff --git a/data/js/item/holidays/pumpkins.js b/data/js/item/holidays/pumpkins.js index e63df2678..68cb883a8 100644 --- a/data/js/item/holidays/pumpkins.js +++ b/data/js/item/holidays/pumpkins.js @@ -16,7 +16,7 @@ function onCreateDFN( objMade, objType ) if( objMade.id == 0x0C6A || objMade.id == 0x0C6B ) { - objMade.weight = Math.floor(Math.random() * ( 2500 - 1200 + 1 ) + 1200); + objMade.weight = Math.floor( Math.random() * ( 2500 - 1200 + 1 ) + 1200 ); } else if( objMade.id == 0x0C6C ) { @@ -72,22 +72,22 @@ function onUseChecked( pUser, iUsed ) // Randomize countdown length, if enabled if( randomizePumpkinCountdown ) { - iUsed.speed = RandomNumber(iUsed.speed - 1, iUsed.speed + 1); + iUsed.speed = RandomNumber( iUsed.speed - 1, iUsed.speed + 1 ); } // Item's speed forms the basis of the countdownTime var countdownTime = iUsed.speed * 1000; // Start the initial timer that shows the first number over the character/object's head - iUsed.StartTimer(200, 1, true); + iUsed.StartTimer( 200, 1, true ); // Start timers with IDs from 2, and count until we reach item's speed + 1 var iCount = 2; - for (iCount = 2; iCount < (iUsed.speed + 2); iCount++) + for( iCount = 2; iCount < ( iUsed.speed + 2 ); iCount++ ) { - iUsed.StartTimer((iCount - 1) * 1000, iCount, true); + iUsed.StartTimer(( iCount - 1) * 1000, iCount, true ); } - socket.CustomTarget(0, GetDictionaryEntry(1348, socket.language)); //Now would be a good time to throw it! + socket.CustomTarget( 0, GetDictionaryEntry( 1348, socket.language )); //Now would be a good time to throw it! } return false; } @@ -96,7 +96,7 @@ function onCallback0( socket, ourObj ) { var mChar = socket.currentChar; var iUsed = socket.tempObj; - if ( mChar && mChar.isChar && iUsed && iUsed.isItem ) + if( mChar && mChar.isChar && iUsed && iUsed.isItem ) { var StrangeByte = socket.GetWord( 1 ); if( StrangeByte == 0 && ourObj ) @@ -107,7 +107,7 @@ function onCallback0( socket, ourObj ) iUsed.container = null; iUsed.Teleport( ourObj ); } - else + else { socket.SysMessage( GetDictionaryEntry( 1646, socket.language )); // You cannot see that @@ -252,7 +252,7 @@ function ApplyExplosionDamage( timerObj, targetChar ) return; // Deal damage, and do criminal check for source character! - targetChar.Damage(RandomNumber( timerObj.lodamage, timerObj.hidamage ), 5, sourceChar, true ); + targetChar.Damage( RandomNumber( timerObj.lodamage, timerObj.hidamage ), 5, sourceChar, true ); // If target is an NPC, make them attack the person who threw the potion! if( targetChar.npc && targetChar.target == null && targetChar.atWar == false ) @@ -299,7 +299,7 @@ function onPickup( iPickedUp, pGrabber, containerObj ) else if( iPickedUp.GetTag( "Named" ) == 0 ) { iPickedUp.name = pGrabber.name + " Pumpkin"; - iPickedUp.SetTag("Named", 1); + iPickedUp.SetTag( "Named", 1 ); } } return true; diff --git a/data/js/item/holidays/snowpile.js b/data/js/item/holidays/snowpile.js index c2e92ecc9..58d289745 100644 --- a/data/js/item/holidays/snowpile.js +++ b/data/js/item/holidays/snowpile.js @@ -59,7 +59,7 @@ function onCallback0( socket, myTarget ) pUser.visible = 0; } - if (!socket.GetWord(1) && myTarget.isChar && myTarget.socket ) + if( !socket.GetWord( 1 ) && myTarget.isChar && myTarget.socket ) { pUser.DoAction( 0x9 ); pUser.SoundEffect( 0x145, true ); @@ -73,10 +73,10 @@ function onCallback0( socket, myTarget ) } } -function onTimer( pUser, timerID ) +function onTimer( pUser, timerID ) { var socket = pUser.socket; - if( pUser.visible == 1 || pUser.visible == 2 ) + if( pUser.visible == 1 || pUser.visible == 2 ) { pUser.visible = 0; } From 5724bb8c11f57be5b0db4e87d4c32df796f9b023 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:45:18 -0600 Subject: [PATCH 24/37] Updaed 0xf1 packet The packet now reflects the current CUO Web Ping and remains backward compatible with older ping statuses. --- .../network/0xf1_freeshardServerPoll.js | 42 +++++++++++++++++-- source/Changelog.txt | 3 ++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/data/js/server/network/0xf1_freeshardServerPoll.js b/data/js/server/network/0xf1_freeshardServerPoll.js index 4b278c240..33e2f1434 100644 --- a/data/js/server/network/0xf1_freeshardServerPoll.js +++ b/data/js/server/network/0xf1_freeshardServerPoll.js @@ -1,6 +1,6 @@ // Handler for Freeshard Server Poll requests from // CUO Web (https://play.classicuo.org) -// Last Updated: 5. September, 2022 +// Last Updated: 3. Decemeber, 2024 function PacketRegistration() { @@ -27,7 +27,18 @@ function onPacketReceive( pSocket, packetNum, subCommand ) else { Console.Print( "Freeshard Server Poll Packet detected, responding..." ); - SendServerPollInfo( pSocket ); + SendServerPollInfoCompact( pSocket ); + } + break; + case 0xFF: + if( !GetServerSetting( "FREESHARDSERVERPOLL" )) + { + Console.Print( "Freeshard Server Poll Packet detected; response disabled via FREESHARDPOLL ini-setting.\n" ); + } + else + { + Console.Print( "Freeshard Server Poll Packet detected, responding..." ); + SendServerPollInfoExtended( pSocket ); } break; default: @@ -36,7 +47,7 @@ function onPacketReceive( pSocket, packetNum, subCommand ) return; } -function SendServerPollInfo( pSocket ) +function SendServerPollInfoCompact( pSocket ) { var uptime = Math.floor( GetCurrentClock() / 1000 ) - Math.floor( GetStartTime() / 1000 ); var totalAccounts = GetAccountCount(); @@ -55,8 +66,31 @@ function SendServerPollInfo( pSocket ) toSend.WriteLong( 15, uptime ); // Server Uptime toSend.WriteLong( 19, memoryHigh ); // Max memory usage - no need to send toSend.WriteLong( 23, memoryLow ); // Min memory usage - no need to send - pSocket.Send( toSend ); + pSocket.Send(toSend); toSend.Free(); Console.Print( "Done!\n" ); Console.Log( "Response sent to Freeshard Server Poll Packet (totalOnline: " + totalOnline + ", upTimeInSeconds: " + uptime ); } + +function SendServerPollInfoExtended( pSocket ) +{ + var protocolVersion = 2; + var shardName = GetServerSetting( "SERVERNAME" ); + var uptime = Math.floor( GetCurrentClock() / 1000 ) - Math.floor( GetStartTime() / 1000 ); + var totalOnline = GetPlayerCount(); + var totalItems = 0; + var totalChars = 0; + var totalMemory = 0; + var statsStr = "UOX3, Name=" + shardName + ", Age=" + Math.round( uptime / 60 / 60 ) + ", Clients=" + totalOnline + ", Items=" + totalItems + ", Chars=" + totalChars + ", Mem=" + totalMemory + "K, Ver=" + protocolVersion; + var toSend = new Packet; + + toSend.ReserveSize( statsStr.length + 2 ); + toSend.WriteByte( 0, 0x53 ); // PacketID + toSend.WriteShort( 1, statsStr.length ); // Length + toSend.WriteString( 3, statsStr, statsStr.length ); + toSend.WriteByte( statsStr.length + 1, 0x00 ); // null terminated + pSocket.Send( toSend ); + toSend.Free(); + Console.Print( "Done!\n" ); + Console.Log( "Response sent to Freeshard Server Poll Packet (totalOnline: " + totalOnline + ", upTimeInSeconds: " + uptime ); +} \ No newline at end of file diff --git a/source/Changelog.txt b/source/Changelog.txt index f64afbc32..205fd42de 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,6 @@ +07/12/2024 - Dragon Slayer +Updated the packet 0xf1 to reflect the current CUO Web Ping while maintaining backward compatibility with older ping statuses. (0xf1_freeshardServerPoll.js) (Thanks Karasho and Xuri) + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. From 45405e9db4b1cb02ced7151c946ae373e4cb939c Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Fri, 20 Dec 2024 20:04:43 -0600 Subject: [PATCH 25/37] onSpellTargetSelect, two parameters corrected onSpellTargetSelect had two parameters are in the wrong order in docs now been corerected. (Thanks Xuri --- docs/jsdocs.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/jsdocs.html b/docs/jsdocs.html index 8dbe347a8..8665ea36c 100644 --- a/docs/jsdocs.html +++ b/docs/jsdocs.html @@ -4018,7 +4018,7 @@

January 9th, 2022

Prototype

-

function onSpellTargetSelect( pCaster, myTarget, spellID )

+

function onSpellTargetSelect( myTarget, pCaster, spellID )

Purpose

@@ -4043,7 +4043,7 @@

January 9th, 2022

Example of usage

// Script attached to an NPC that's immune to magic, where event returns 2 to reject spell being cast
-function onSpellTargetSelect( pCaster, myTarget, spellID )
+function onSpellTargetSelect( myTarget, pCaster, spellID )
 {
 	var socket = pCaster.socket;
 	if( socket != null )

From cd35741ff276118143e46d1f023851059bc20a36 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Tue, 14 Jan 2025 21:44:16 -0600
Subject: [PATCH 26/37] Update

Updated so they work directly on chars for the DCI and HCI just like retail AOS
---
 source/UOXJSPropertyEnums.h   |  2 ++
 source/UOXJSPropertyFuncs.cpp |  4 ++++
 source/UOXJSPropertySpecs.h   |  2 ++
 source/cChar.cpp              | 16 +++++++++++++++-
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h
index f471df16e..a99bd3628 100644
--- a/source/UOXJSPropertyEnums.h
+++ b/source/UOXJSPropertyEnums.h
@@ -339,6 +339,8 @@ enum CC_Properties
 	CCP_SPAWNSERIAL,
 	CCP_SPATTACK,
 	CCP_SPDELAY,
+	CCP_HITCHANCE,
+	CCP_DEFENSECHANCE,
 	CCP_AITYPE,
 	CCP_SPLIT,
 	CCP_SPLITCHANCE,
diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp
index 02ff0cbb2..ef170971c 100644
--- a/source/UOXJSPropertyFuncs.cpp
+++ b/source/UOXJSPropertyFuncs.cpp
@@ -1998,6 +1998,8 @@ JSBool CCharacterProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsva
 			case CCP_HOUSEICONS:	*vp = BOOLEAN_TO_JSVAL( gPriv->ViewHouseAsIcon() );			break;
 			case CCP_SPATTACK:		*vp = INT_TO_JSVAL( gPriv->GetSpAttack() );					break;
 			case CCP_SPDELAY:		*vp = INT_TO_JSVAL( gPriv->GetSpDelay() );					break;
+			case CCP_HITCHANCE:		*vp = INT_TO_JSVAL( gPriv->GetHitChance() );				break;
+			case CCP_DEFENSECHANCE:	*vp = INT_TO_JSVAL( gPriv->GetDefenseChance() );			break;
 			case CCP_AITYPE:		*vp = INT_TO_JSVAL( gPriv->GetNpcAiType() );				break;
 			case CCP_SPLIT:			*vp = INT_TO_JSVAL( gPriv->GetSplit() );					break;
 			case CCP_SPLITCHANCE:	*vp = INT_TO_JSVAL( gPriv->GetSplitChance() );				break;
@@ -2503,6 +2505,8 @@ JSBool CCharacterProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsva
 			case CCP_HOUSEICONS:	gPriv->SetViewHouseAsIcon( encaps.toBool() );				break;
 			case CCP_SPATTACK:		gPriv->SetSpAttack( static_cast( encaps.toInt() ));	break;
 			case CCP_SPDELAY:		gPriv->SetSpDelay( static_cast( encaps.toInt() ));	break;
+			case CCP_HITCHANCE:		gPriv->SetHitChance( static_cast( encaps.toInt() ));	break;
+			case CCP_DEFENSECHANCE:	gPriv->SetDefenseChance( static_cast( encaps.toInt() ));	break;
 			case CCP_AITYPE:		gPriv->SetNPCAiType( static_cast( encaps.toInt() ));	break;
 			case CCP_SPLIT:			gPriv->SetSplit( static_cast( encaps.toInt() ));		break;
 			case CCP_SPLITCHANCE:	gPriv->SetSplitChance( static_cast( encaps.toInt() ));break;
diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h
index b77c023aa..1585d151a 100644
--- a/source/UOXJSPropertySpecs.h
+++ b/source/UOXJSPropertySpecs.h
@@ -357,6 +357,8 @@ inline JSPropertySpec CCharacterProps[] =
 	{ "houseicons",		CCP_HOUSEICONS,		JSPROP_ENUMANDPERM, nullptr, nullptr },
 	{ "spattack",		CCP_SPATTACK,		JSPROP_ENUMANDPERM, nullptr, nullptr },
 	{ "spdelay",		CCP_SPDELAY,		JSPROP_ENUMANDPERM, nullptr, nullptr },
+	{ "hitChance",		CCP_HITCHANCE,		JSPROP_ENUMANDPERM, nullptr, nullptr },
+	{ "defenseChance",	CCP_DEFENSECHANCE,	JSPROP_ENUMANDPERM, nullptr, nullptr },
 	{ "aitype",			CCP_AITYPE,			JSPROP_ENUMANDPERM, nullptr, nullptr },
 	{ "split",			CCP_SPLIT,			JSPROP_ENUMANDPERM, nullptr, nullptr },
 	{ "splitchance",	CCP_SPLITCHANCE,	JSPROP_ENUMANDPERM, nullptr, nullptr },
diff --git a/source/cChar.cpp b/source/cChar.cpp
index 6bb36cb56..eb70922f6 100644
--- a/source/cChar.cpp
+++ b/source/cChar.cpp
@@ -2411,6 +2411,8 @@ void CChar::CopyData( CChar *target )
 	target->SetNextAct( nextAct );
 	target->SetSquelched( GetSquelched() );
 	target->SetMeditating( IsMeditating() );
+	target->SetHitChance( GetHitChance() );
+	target->SetDefenseChance( GetDefenseChance() );
 	target->SetStealth( stealth );
 	target->SetRunning( running );
 	target->SetRace( GetRace() );
@@ -3141,6 +3143,8 @@ bool CChar::DumpBody( std::ostream &outStream ) const
 	//-------------------------------------------------------------------------------------------
 	outStream << "CanRun=" + std::to_string((( CanRun() && IsNpc() ) ? 1 : 0 )) + newLine;
 	outStream << "CanAttack=" + std::to_string(( GetCanAttack() ? 1 : 0 )) + newLine;
+	outStream << "HitChance=" + std::to_string( GetHitChance() ) + newLine;
+	outStream << "DefChance=" + std::to_string( GetDefenseChance() ) + newLine;
 	outStream << "AllMove=" + std::to_string(( AllMove() ? 1 : 0 )) + newLine;
 	outStream << "IsNpc=" + std::to_string(( IsNpc() ? 1 : 0 )) + newLine;
 	outStream << "IsShop=" + std::to_string(( IsShop() ? 1 : 0 )) + newLine;
@@ -4379,6 +4383,11 @@ bool CChar::HandleLine( std::string &UTag, std::string &data )
 					SetDead(( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ));
 					rValue = true;
 				}
+				else if( UTag == "DEFCHANCE" )
+				{
+					SetDefenseChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )));
+					rValue = true;
+				}
 				break;
 			case 'E':
 				if( UTag == "EMOTION" )
@@ -4467,7 +4476,12 @@ bool CChar::HandleLine( std::string &UTag, std::string &data )
 				}
 				break;
 			case 'H':
-				if( UTag == "HUNGER" )
+				if( UTag == "HITCHANCE" )
+				{
+					SetHitChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )));
+					rValue = true;
+				}
+				else if( UTag == "HUNGER" )
 				{
 					SetHunger( static_cast( std::stoi( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )));
 					rValue = true;

From 9b9f90d8b0a94efb6da4a33fdb96f6afdabdf73e Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Tue, 14 Jan 2025 23:28:03 -0600
Subject: [PATCH 27/37] update

---
 source/cBaseObject.cpp |  4 ++--
 source/cChar.cpp       |  2 +-
 source/combat.cpp      | 12 +++++++++---
 source/npcs.cpp        |  2 ++
 4 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp
index 9eedebfff..e98c3c693 100644
--- a/source/cBaseObject.cpp
+++ b/source/cBaseObject.cpp
@@ -1043,7 +1043,7 @@ void CBaseObject::IncHP( SI16 amtToChange )
 //|	Function	-	CBaseObject::GetHitChance()
 //|					CBaseObject::SetHitChance()
 //o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Defense Chance of the Item Equiped
+//|	Purpose		-	Gets/Sets the Defense Chance of the Item(s) Equiped or Character
 //o------------------------------------------------------------------------------------------------o
 SI16 CBaseObject::GetHitChance( void ) const
 {
@@ -1063,7 +1063,7 @@ void CBaseObject::SetHitChance( SI16 newValue )
 //|	Function	-	CBaseObject::GetDefenseChance()
 //|					CBaseObject::SetDefenseChance()
 //o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Defense Chance of the Item Equiped
+//|	Purpose		-	Gets/Sets the Defense Chance of the Item(s) Equiped or Character
 //o------------------------------------------------------------------------------------------------o
 SI16 CBaseObject::GetDefenseChance( void ) const
 {
diff --git a/source/cChar.cpp b/source/cChar.cpp
index eb70922f6..3ae819d15 100644
--- a/source/cChar.cpp
+++ b/source/cChar.cpp
@@ -4383,7 +4383,7 @@ bool CChar::HandleLine( std::string &UTag, std::string &data )
 					SetDead(( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ));
 					rValue = true;
 				}
-				else if( UTag == "DEFCHANCE" )
+				else if( UTag == "DEFENSECHANCE" )
 				{
 					SetDefenseChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )));
 					rValue = true;
diff --git a/source/combat.cpp b/source/combat.cpp
index 066e3e80e..256f04c3c 100644
--- a/source/combat.cpp
+++ b/source/combat.cpp
@@ -2877,18 +2877,24 @@ bool CHandleCombat::HandleCombat( CSocket *mSock, CChar& mChar, CChar *ourTarg )
 				R32 attHitChanceBonus = 0;
 				R32 defDefenseChanceBonus = 0;
 				R32 maxAttHitChanceBonus = 45;
+
 				if( cwmWorldState->ServerData()->ExpansionCombatHitChance() >= ER_SA && mChar.GetBodyType() == BT_GARGOYLE )
 				{
 					// If attacker is a Gargoyle player, and ExpansionCombatHitChance is ER_SA or higher, use 50 as hitchance bonus cap instead of 45
 					maxAttHitChanceBonus = 50;
 				}
 				
-				// Fetch bonuses to hitChance/defenseChance from AoS item properties
+				// Fetch bonuses to hitChance/defenseChance from AoS item properties or characters
 				attHitChanceBonus = mChar.GetHitChance();
 				defDefenseChanceBonus = mChar.GetDefenseChance();
 
-				R32 attackerHitChance = ( static_cast( attackSkill / 10 ) + 20 ) * ( 100 + std::min( attHitChanceBonus, static_cast( maxAttHitChanceBonus )));
-				R32 defenderDefenseChance = ( static_cast( defendSkill / 10 ) + 20 ) * ( 100 + std::min( defDefenseChanceBonus, static_cast( 45 )));
+				// Clamp to ensure valid bonus ranges (e.g., no multiplier below 1)
+				R32 effectiveAttHitChanceBonus = std::max(-99.0f, std::min( attHitChanceBonus, maxAttHitChanceBonus )); // Cap at -99 and maxAttHitChanceBonus
+				R32 effectiveDefDefenseChanceBonus = std::max(-99.0f, std::min( defDefenseChanceBonus, 45.0f )); // Cap at -99 and 45
+
+				// Calculate the attacker's hit chance and defender's defense chance
+				R32 attackerHitChance = ( static_cast( attackSkill / 10 ) + 20 ) * ( 100 + effectiveAttHitChanceBonus );
+				R32 defenderDefenseChance = ( static_cast( defendSkill / 10 ) + 20 ) * ( 100 + effectiveDefDefenseChanceBonus );
 				hitChance = ( attackerHitChance / ( defenderDefenseChance * 2 )) * 100;
 
 				// Always leave at least 2% chance to hit
diff --git a/source/npcs.cpp b/source/npcs.cpp
index 36005b420..a749b95aa 100644
--- a/source/npcs.cpp
+++ b/source/npcs.cpp
@@ -1541,6 +1541,8 @@ auto CCharStuff::ApplyNpcSection( CChar *applyTo, CScriptSection *NpcCreation, s
 			case DFNTAG_NAMELIST:			SetRandomName( applyTo, cdata );		break;
 			case DFNTAG_NECROMANCY:			skillToSet = NECROMANCY;				break;
 			case DFNTAG_NINJITSU:			skillToSet = NINJITSU;					break;
+			case DFNTAG_HITCHANCE:			applyTo->SetHitChance( static_cast( ndata ));		break;
+			case DFNTAG_DEFENSECHANCE:		applyTo->SetDefenseChance( static_cast( ndata ));		break;
 			case DFNTAG_NPCWANDER:
 				if( !isGate )
 				{

From 41c7ee467664ed3242d8c40603f4be83e8e4a571 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Thu, 16 Jan 2025 18:36:53 -0600
Subject: [PATCH 28/37] Moved Leech Props

Moved Leech props to just items
---
 source/cBaseObject.cpp | 96 +-----------------------------------------
 source/cBaseObject.h   | 16 -------
 source/cItem.cpp       | 83 +++++++++++++++++++++++++++++++++++-
 source/cItem.h         | 16 +++++++
 4 files changed, 99 insertions(+), 112 deletions(-)

diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp
index 2c5ce0b89..506c247ac 100644
--- a/source/cBaseObject.cpp
+++ b/source/cBaseObject.cpp
@@ -94,9 +94,6 @@ const SI16			DEFBASE_KILLS		= 0;
 const UI16			DEFBASE_RESIST 		= 0;
 const bool			DEFBASE_NAMEREQUESTACTIVE = 0;
 const ExpansionRuleset	DEFBASE_ORIGIN	= ER_UO;
-const SI16			DEFBASE_HEALTHLEECH = 0;
-const SI16			DEFBASE_STAMINALEECH = 0;
-const SI16			DEFBASE_MANALEECH = 0;
 
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject constructor
@@ -113,8 +110,7 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ),
 mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ),
 in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ),
 poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ),
-fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ),
-healthLeech( DEFBASE_HEALTHLEECH ), staminaLeech( DEFBASE_STAMINALEECH ), manaLeech( DEFBASE_MANALEECH )
+fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN )
 {
 	multis = nullptr;
 	tempMulti = INVALIDSERIAL;
@@ -1635,66 +1631,6 @@ void CBaseObject::SetIntelligence2( SI16 nVal )
 	}
 }
 
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::GetHealthLeech()
-//|					CBaseObject::SetHealthLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Health Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CBaseObject::GetHealthLeech( void ) const
-{
-	return healthLeech;
-}
-void CBaseObject::SetHealthLeech( SI16 nVal )
-{
-	healthLeech = nVal;
-
-	if( CanBeObjType( OT_ITEM ))
-	{
-		( static_cast( this ))->UpdateRegion();
-	}
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::GetStaminaLeech()
-//|					CBaseObject::SetStaminaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Stamina Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CBaseObject::GetStaminaLeech( void ) const
-{
-	return staminaLeech;
-}
-void CBaseObject::SetStaminaLeech( SI16 nVal )
-{
-	staminaLeech = nVal;
-
-	if( CanBeObjType( OT_ITEM ))
-	{
-		( static_cast( this ))->UpdateRegion();
-	}
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::GetManaLeech()
-//|					CBaseObject::SetManaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Mana Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CBaseObject::GetManaLeech( void ) const
-{
-	return manaLeech;
-}
-void CBaseObject::SetManaLeech( SI16 nVal )
-{
-	manaLeech = nVal;
-
-	if( CanBeObjType( OT_ITEM ))
-	{
-		( static_cast( this ))->UpdateRegion();
-	}
-}
-
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject::IncStrength()
 //o------------------------------------------------------------------------------------------------o
@@ -1725,36 +1661,6 @@ void CBaseObject::IncIntelligence( SI16 toInc )
 	SetIntelligence( intelligence + toInc );
 }
 
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::IncHealthLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Health Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CBaseObject::IncHealthLeech( SI16 toInc )
-{
-	SetHealthLeech( healthLeech + toInc );
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::IncStaminaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Stamina Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CBaseObject::IncStaminaLeech( SI16 toInc )
-{
-	SetStaminaLeech( staminaLeech + toInc );
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CBaseObject::IncManaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Mana Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CBaseObject::IncManaLeech( SI16 toInc )
-{
-	SetManaLeech( manaLeech + toInc );
-}
-
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject::DumpFooter()
 //o------------------------------------------------------------------------------------------------o
diff --git a/source/cBaseObject.h b/source/cBaseObject.h
index 316cd2530..638e826f7 100644
--- a/source/cBaseObject.h
+++ b/source/cBaseObject.h
@@ -75,9 +75,6 @@ class CBaseObject
 	SI32				weight;
 	SI16				mana;
 	SI16				stamina;
-	SI16				healthLeech;
-	SI16				staminaLeech;
-	SI16				manaLeech;
 	UI16				scriptTrig;
 	SI16				st2;
 	SI16				dx2;
@@ -259,19 +256,6 @@ class CBaseObject
 	void					IncDexterity( SI16 toInc = 1 );
 	void					IncIntelligence( SI16 toInc = 1 );
 
-	SI16					GetHealthLeech( void ) const;
-	virtual void			SetHealthLeech( SI16 nVal );
-
-	SI16					GetStaminaLeech( void ) const;
-	virtual void			SetStaminaLeech( SI16 nVal );
-
-	SI16					GetManaLeech( void ) const;
-	virtual void			SetManaLeech( SI16 nVal );
-
-	void					IncHealthLeech( SI16 toInc = 1 );
-	void					IncStaminaLeech( SI16 toInc = 1 );
-	void					IncManaLeech( SI16 toInc = 1 );
-
 	virtual void			PostLoadProcessing( void );
 	virtual bool			LoadRemnants( void ) = 0;
 
diff --git a/source/cItem.cpp b/source/cItem.cpp
index 672ece4dd..45559d0a9 100644
--- a/source/cItem.cpp
+++ b/source/cItem.cpp
@@ -93,6 +93,9 @@ const UI16			DEFITEM_MAXUSES			= 0;
 const UI16			DEFITEM_REGIONNUM 		= 255;
 const UI16			DEFITEM_TEMPLASTTRADED	= 0;
 const SI08			DEFITEM_STEALABLE	 	= 1;
+const SI16			DEFITEM_HEALTHLEECH		= 0;
+const SI16			DEFITEM_STAMINALEECH	= 0;
+const SI16			DEFITEM_MANALEECH		= 0;
 
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem()
@@ -107,7 +110,7 @@ spd( DEFITEM_SPEED ), maxHp( DEFITEM_MAXHP ), amount( DEFITEM_AMOUNT ),
 layer( DEFITEM_LAYER ), type( DEFITEM_TYPE ), offspell( DEFITEM_OFFSPELL ), entryMadeFrom( DEFITEM_ENTRYMADEFROM ),
 creator( DEFITEM_CREATOR ), gridLoc( DEFITEM_GRIDLOC ), weightMax( DEFITEM_WEIGHTMAX ), baseWeight( DEFITEM_BASEWEIGHT ), maxItems( DEFITEM_MAXITEMS ),
 maxRange( DEFITEM_MAXRANGE ), baseRange( DEFITEM_BASERANGE ), maxUses( DEFITEM_MAXUSES ), usesLeft( DEFITEM_USESLEFT ), regionNum( DEFITEM_REGIONNUM ), 
-tempLastTraded( DEFITEM_TEMPLASTTRADED ), stealable( DEFITEM_STEALABLE )
+tempLastTraded( DEFITEM_TEMPLASTTRADED ), stealable( DEFITEM_STEALABLE ), healthLeech( DEFITEM_HEALTHLEECH ), staminaLeech( DEFITEM_STAMINALEECH ), manaLeech( DEFITEM_MANALEECH )
 {
 	spells[0]	= spells[1] = spells[2] = 0;
 	value[0]	= value[1] = value[2] = 0;
@@ -542,6 +545,54 @@ auto CItem::SetSpawnerList( bool newValue ) -> void
 	UpdateRegion();
 }
 
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::GetHealthLeech()
+//|					CItem::SetHealthLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Health Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CItem::GetHealthLeech( void ) const
+{
+	return healthLeech;
+}
+void CItem::SetHealthLeech( SI16 nVal )
+{
+	healthLeech = nVal;
+	UpdateRegion();
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::GetStaminaLeech()
+//|					CItem::SetStaminaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Stamina Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CItem::GetStaminaLeech( void ) const
+{
+	return staminaLeech;
+}
+void CItem::SetStaminaLeech( SI16 nVal )
+{
+	staminaLeech = nVal;
+	UpdateRegion();
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::GetManaLeech()
+//|					CItem::SetManaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Mana Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CItem::GetManaLeech( void ) const
+{
+	return manaLeech;
+}
+void CItem::SetManaLeech( SI16 nVal )
+{
+	manaLeech = nVal;
+	UpdateRegion();
+}
+
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem::GetName2()
 //|					CItem::SetName2()
@@ -1340,6 +1391,36 @@ auto CItem::SetWeightMax( SI32 newValue ) -> void
 	UpdateRegion();
 }
 
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::IncHealthLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Health Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CItem::IncHealthLeech( SI16 toInc )
+{
+	SetHealthLeech( healthLeech + toInc );
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::IncStaminaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Stamina Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CItem::IncStaminaLeech( SI16 toInc )
+{
+	SetStaminaLeech( staminaLeech + toInc );
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CItem::IncManaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Mana Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CItem::IncManaLeech( SI16 toInc )
+{
+	SetManaLeech( manaLeech + toInc );
+}
+
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem::GetBaseWeight()
 //|					CItem::SetBaseWeight()
diff --git a/source/cItem.h b/source/cItem.h
index 3a3b60e5d..542aa62d6 100644
--- a/source/cItem.h
+++ b/source/cItem.h
@@ -41,6 +41,9 @@ class CItem : public CBaseObject
 	TIMERVAL		decayTime;
 	UI08			spd;			// The speed of the weapon
 	UI16			maxHp;			// Max number of hit points an item can have.
+	SI16			healthLeech;
+	SI16			staminaLeech;
+	SI16			manaLeech;
 	UI16			amount;			// Amount of items in pile
 	ItemLayers		layer;			// Layer if equipped on paperdoll
 	ItemTypes		type;			// For things that do special things on doubleclicking
@@ -166,6 +169,19 @@ class CItem : public CBaseObject
 
 	auto			InDungeon() -> bool;
 
+	virtual SI16	GetHealthLeech( void ) const;
+	virtual void	SetHealthLeech( SI16 nVal );
+
+	virtual SI16	GetStaminaLeech( void ) const;
+	virtual void	SetStaminaLeech( SI16 nVal );
+
+	virtual SI16	GetManaLeech( void ) const;
+	virtual void	SetManaLeech( SI16 nVal );
+
+	void			IncHealthLeech( SI16 toInc = 1 );
+	void			IncStaminaLeech( SI16 toInc = 1 );
+	void			IncManaLeech( SI16 toInc = 1 );
+
 	auto			GetLayer() const -> ItemLayers;
 	auto			SetLayer( ItemLayers newValue ) -> void;
 

From 6583a518dfbafc305a5adf4aad156478dedd849d Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Thu, 16 Jan 2025 19:09:59 -0600
Subject: [PATCH 29/37] Revert "Moved Leech Props"

This reverts commit 41c7ee467664ed3242d8c40603f4be83e8e4a571.
---
 source/cBaseObject.cpp | 96 +++++++++++++++++++++++++++++++++++++++++-
 source/cBaseObject.h   | 16 +++++++
 source/cItem.cpp       | 83 +-----------------------------------
 source/cItem.h         | 16 -------
 4 files changed, 112 insertions(+), 99 deletions(-)

diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp
index 506c247ac..2c5ce0b89 100644
--- a/source/cBaseObject.cpp
+++ b/source/cBaseObject.cpp
@@ -94,6 +94,9 @@ const SI16			DEFBASE_KILLS		= 0;
 const UI16			DEFBASE_RESIST 		= 0;
 const bool			DEFBASE_NAMEREQUESTACTIVE = 0;
 const ExpansionRuleset	DEFBASE_ORIGIN	= ER_UO;
+const SI16			DEFBASE_HEALTHLEECH = 0;
+const SI16			DEFBASE_STAMINALEECH = 0;
+const SI16			DEFBASE_MANALEECH = 0;
 
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject constructor
@@ -110,7 +113,8 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ),
 mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ),
 in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ),
 poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ),
-fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN )
+fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ),
+healthLeech( DEFBASE_HEALTHLEECH ), staminaLeech( DEFBASE_STAMINALEECH ), manaLeech( DEFBASE_MANALEECH )
 {
 	multis = nullptr;
 	tempMulti = INVALIDSERIAL;
@@ -1631,6 +1635,66 @@ void CBaseObject::SetIntelligence2( SI16 nVal )
 	}
 }
 
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::GetHealthLeech()
+//|					CBaseObject::SetHealthLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Health Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CBaseObject::GetHealthLeech( void ) const
+{
+	return healthLeech;
+}
+void CBaseObject::SetHealthLeech( SI16 nVal )
+{
+	healthLeech = nVal;
+
+	if( CanBeObjType( OT_ITEM ))
+	{
+		( static_cast( this ))->UpdateRegion();
+	}
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::GetStaminaLeech()
+//|					CBaseObject::SetStaminaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Stamina Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CBaseObject::GetStaminaLeech( void ) const
+{
+	return staminaLeech;
+}
+void CBaseObject::SetStaminaLeech( SI16 nVal )
+{
+	staminaLeech = nVal;
+
+	if( CanBeObjType( OT_ITEM ))
+	{
+		( static_cast( this ))->UpdateRegion();
+	}
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::GetManaLeech()
+//|					CBaseObject::SetManaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Gets/Sets the Mana Leech
+//o------------------------------------------------------------------------------------------------o
+SI16 CBaseObject::GetManaLeech( void ) const
+{
+	return manaLeech;
+}
+void CBaseObject::SetManaLeech( SI16 nVal )
+{
+	manaLeech = nVal;
+
+	if( CanBeObjType( OT_ITEM ))
+	{
+		( static_cast( this ))->UpdateRegion();
+	}
+}
+
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject::IncStrength()
 //o------------------------------------------------------------------------------------------------o
@@ -1661,6 +1725,36 @@ void CBaseObject::IncIntelligence( SI16 toInc )
 	SetIntelligence( intelligence + toInc );
 }
 
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::IncHealthLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Health Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CBaseObject::IncHealthLeech( SI16 toInc )
+{
+	SetHealthLeech( healthLeech + toInc );
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::IncStaminaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Stamina Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CBaseObject::IncStaminaLeech( SI16 toInc )
+{
+	SetStaminaLeech( staminaLeech + toInc );
+}
+
+//o------------------------------------------------------------------------------------------------o
+//|	Function	-	CBaseObject::IncManaLeech()
+//o------------------------------------------------------------------------------------------------o
+//|	Purpose		-	Increments the object's Mana Leech Points value
+//o------------------------------------------------------------------------------------------------o
+void CBaseObject::IncManaLeech( SI16 toInc )
+{
+	SetManaLeech( manaLeech + toInc );
+}
+
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CBaseObject::DumpFooter()
 //o------------------------------------------------------------------------------------------------o
diff --git a/source/cBaseObject.h b/source/cBaseObject.h
index 638e826f7..316cd2530 100644
--- a/source/cBaseObject.h
+++ b/source/cBaseObject.h
@@ -75,6 +75,9 @@ class CBaseObject
 	SI32				weight;
 	SI16				mana;
 	SI16				stamina;
+	SI16				healthLeech;
+	SI16				staminaLeech;
+	SI16				manaLeech;
 	UI16				scriptTrig;
 	SI16				st2;
 	SI16				dx2;
@@ -256,6 +259,19 @@ class CBaseObject
 	void					IncDexterity( SI16 toInc = 1 );
 	void					IncIntelligence( SI16 toInc = 1 );
 
+	SI16					GetHealthLeech( void ) const;
+	virtual void			SetHealthLeech( SI16 nVal );
+
+	SI16					GetStaminaLeech( void ) const;
+	virtual void			SetStaminaLeech( SI16 nVal );
+
+	SI16					GetManaLeech( void ) const;
+	virtual void			SetManaLeech( SI16 nVal );
+
+	void					IncHealthLeech( SI16 toInc = 1 );
+	void					IncStaminaLeech( SI16 toInc = 1 );
+	void					IncManaLeech( SI16 toInc = 1 );
+
 	virtual void			PostLoadProcessing( void );
 	virtual bool			LoadRemnants( void ) = 0;
 
diff --git a/source/cItem.cpp b/source/cItem.cpp
index 45559d0a9..672ece4dd 100644
--- a/source/cItem.cpp
+++ b/source/cItem.cpp
@@ -93,9 +93,6 @@ const UI16			DEFITEM_MAXUSES			= 0;
 const UI16			DEFITEM_REGIONNUM 		= 255;
 const UI16			DEFITEM_TEMPLASTTRADED	= 0;
 const SI08			DEFITEM_STEALABLE	 	= 1;
-const SI16			DEFITEM_HEALTHLEECH		= 0;
-const SI16			DEFITEM_STAMINALEECH	= 0;
-const SI16			DEFITEM_MANALEECH		= 0;
 
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem()
@@ -110,7 +107,7 @@ spd( DEFITEM_SPEED ), maxHp( DEFITEM_MAXHP ), amount( DEFITEM_AMOUNT ),
 layer( DEFITEM_LAYER ), type( DEFITEM_TYPE ), offspell( DEFITEM_OFFSPELL ), entryMadeFrom( DEFITEM_ENTRYMADEFROM ),
 creator( DEFITEM_CREATOR ), gridLoc( DEFITEM_GRIDLOC ), weightMax( DEFITEM_WEIGHTMAX ), baseWeight( DEFITEM_BASEWEIGHT ), maxItems( DEFITEM_MAXITEMS ),
 maxRange( DEFITEM_MAXRANGE ), baseRange( DEFITEM_BASERANGE ), maxUses( DEFITEM_MAXUSES ), usesLeft( DEFITEM_USESLEFT ), regionNum( DEFITEM_REGIONNUM ), 
-tempLastTraded( DEFITEM_TEMPLASTTRADED ), stealable( DEFITEM_STEALABLE ), healthLeech( DEFITEM_HEALTHLEECH ), staminaLeech( DEFITEM_STAMINALEECH ), manaLeech( DEFITEM_MANALEECH )
+tempLastTraded( DEFITEM_TEMPLASTTRADED ), stealable( DEFITEM_STEALABLE )
 {
 	spells[0]	= spells[1] = spells[2] = 0;
 	value[0]	= value[1] = value[2] = 0;
@@ -545,54 +542,6 @@ auto CItem::SetSpawnerList( bool newValue ) -> void
 	UpdateRegion();
 }
 
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::GetHealthLeech()
-//|					CItem::SetHealthLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Health Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CItem::GetHealthLeech( void ) const
-{
-	return healthLeech;
-}
-void CItem::SetHealthLeech( SI16 nVal )
-{
-	healthLeech = nVal;
-	UpdateRegion();
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::GetStaminaLeech()
-//|					CItem::SetStaminaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Stamina Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CItem::GetStaminaLeech( void ) const
-{
-	return staminaLeech;
-}
-void CItem::SetStaminaLeech( SI16 nVal )
-{
-	staminaLeech = nVal;
-	UpdateRegion();
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::GetManaLeech()
-//|					CItem::SetManaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Gets/Sets the Mana Leech
-//o------------------------------------------------------------------------------------------------o
-SI16 CItem::GetManaLeech( void ) const
-{
-	return manaLeech;
-}
-void CItem::SetManaLeech( SI16 nVal )
-{
-	manaLeech = nVal;
-	UpdateRegion();
-}
-
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem::GetName2()
 //|					CItem::SetName2()
@@ -1391,36 +1340,6 @@ auto CItem::SetWeightMax( SI32 newValue ) -> void
 	UpdateRegion();
 }
 
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::IncHealthLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Health Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CItem::IncHealthLeech( SI16 toInc )
-{
-	SetHealthLeech( healthLeech + toInc );
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::IncStaminaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Stamina Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CItem::IncStaminaLeech( SI16 toInc )
-{
-	SetStaminaLeech( staminaLeech + toInc );
-}
-
-//o------------------------------------------------------------------------------------------------o
-//|	Function	-	CItem::IncManaLeech()
-//o------------------------------------------------------------------------------------------------o
-//|	Purpose		-	Increments the object's Mana Leech Points value
-//o------------------------------------------------------------------------------------------------o
-void CItem::IncManaLeech( SI16 toInc )
-{
-	SetManaLeech( manaLeech + toInc );
-}
-
 //o------------------------------------------------------------------------------------------------o
 //|	Function	-	CItem::GetBaseWeight()
 //|					CItem::SetBaseWeight()
diff --git a/source/cItem.h b/source/cItem.h
index 542aa62d6..3a3b60e5d 100644
--- a/source/cItem.h
+++ b/source/cItem.h
@@ -41,9 +41,6 @@ class CItem : public CBaseObject
 	TIMERVAL		decayTime;
 	UI08			spd;			// The speed of the weapon
 	UI16			maxHp;			// Max number of hit points an item can have.
-	SI16			healthLeech;
-	SI16			staminaLeech;
-	SI16			manaLeech;
 	UI16			amount;			// Amount of items in pile
 	ItemLayers		layer;			// Layer if equipped on paperdoll
 	ItemTypes		type;			// For things that do special things on doubleclicking
@@ -169,19 +166,6 @@ class CItem : public CBaseObject
 
 	auto			InDungeon() -> bool;
 
-	virtual SI16	GetHealthLeech( void ) const;
-	virtual void	SetHealthLeech( SI16 nVal );
-
-	virtual SI16	GetStaminaLeech( void ) const;
-	virtual void	SetStaminaLeech( SI16 nVal );
-
-	virtual SI16	GetManaLeech( void ) const;
-	virtual void	SetManaLeech( SI16 nVal );
-
-	void			IncHealthLeech( SI16 toInc = 1 );
-	void			IncStaminaLeech( SI16 toInc = 1 );
-	void			IncManaLeech( SI16 toInc = 1 );
-
 	auto			GetLayer() const -> ItemLayers;
 	auto			SetLayer( ItemLayers newValue ) -> void;
 

From 127da5ccb8d4936e2c49a234e8a7b4160a4517da Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Sat, 18 Jan 2025 13:25:57 -0600
Subject: [PATCH 30/37] fix

---
 source/cChar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/cChar.cpp b/source/cChar.cpp
index 3ae819d15..eb70922f6 100644
--- a/source/cChar.cpp
+++ b/source/cChar.cpp
@@ -4383,7 +4383,7 @@ bool CChar::HandleLine( std::string &UTag, std::string &data )
 					SetDead(( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )) == 1 ));
 					rValue = true;
 				}
-				else if( UTag == "DEFENSECHANCE" )
+				else if( UTag == "DEFCHANCE" )
 				{
 					SetDefenseChance( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )));
 					rValue = true;

From 492ef70fcb4360c70e7932558df7e47c96808fde Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Tue, 21 Jan 2025 13:58:04 -0600
Subject: [PATCH 31/37] Fix for Defense

Neg Damage Does not take into account the attacker skill no longer. Only the Armor perc
---
 source/combat.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/combat.cpp b/source/combat.cpp
index 8817d7b3d..4c56399c9 100644
--- a/source/combat.cpp
+++ b/source/combat.cpp
@@ -2645,7 +2645,7 @@ SI16 CHandleCombat::ApplyDefenseModifiers( WeatherType damageType, CChar *mChar,
 
 	if( getDef > 0 )
 	{
-		damage -= static_cast(( static_cast( getDef ) * static_cast( attSkill )) / 750 );
+		damage -= static_cast( getDef );
 	}
 
 	return static_cast( std::round( damage ));

From 544327d441c16b85c136d3d0ddb21e77da6ad600 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Tue, 21 Jan 2025 21:54:13 -0600
Subject: [PATCH 32/37] changelog

---
 source/Changelog.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index b0801d426..36abce5fe 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -1,3 +1,6 @@
+21/01/2025 - Dragon Slayer
+	Removed the skill check for damage being adjusted at the end. (combat.cpp)
+
 13/05/2024 - Dragon Slayer
 	Added New Shield Type 107 so shield ID's no longer have to be in hard code for shields to work properly
 

From 95fa7a8ee139648e7729c657f9c36a8d8ccaf3b4 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Fri, 24 Jan 2025 10:46:05 -0600
Subject: [PATCH 33/37] Update Changelog.txt

---
 source/Changelog.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index 36abce5fe..ed820bfda 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -1,5 +1,5 @@
 21/01/2025 - Dragon Slayer
-	Removed the skill check for damage being adjusted at the end. (combat.cpp)
+	Fixed damage dealt in combat was incorrectly modified while applying defense modifiers. (combat.cpp)
 
 13/05/2024 - Dragon Slayer
 	Added New Shield Type 107 so shield ID's no longer have to be in hard code for shields to work properly

From 0bf54f87db7d21a189e1f8a4094cb1fcb5223cce Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Fri, 24 Jan 2025 18:50:38 -0600
Subject: [PATCH 34/37] Update Changelog.txt

---
 source/Changelog.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index b0801d426..fb3168ad2 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -1,6 +1,10 @@
 13/05/2024 - Dragon Slayer
 	Added New Shield Type 107 so shield ID's no longer have to be in hard code for shields to work properly
 
+11/05/2024 - Dragon Slayer
+	Fixed items handling correct target for resists.
+	Added Getting the resists on chars.
+
 09/05/2024 - Dragon Slayer
 	Added ArtifactRarity AOS Property for items
 	-ARTIFACTRARITY=#

From 2ca6b335c7abc88ff1db84576bfdbc3a584d60aa Mon Sep 17 00:00:00 2001
From: Geir Ove Alnes 
Date: Sat, 25 Jan 2025 15:29:21 +0800
Subject: [PATCH 35/37] Update Changelog.txt

---
 source/Changelog.txt | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index fb3168ad2..f62b29102 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -2,8 +2,7 @@
 	Added New Shield Type 107 so shield ID's no longer have to be in hard code for shields to work properly
 
 11/05/2024 - Dragon Slayer
-	Fixed items handling correct target for resists.
-	Added Getting the resists on chars.
+	Updated 'get command (js/commands/targeting/get.js) to use correct object reference when getting resist values for items, and added support for getting resist values for chars
 
 09/05/2024 - Dragon Slayer
 	Added ArtifactRarity AOS Property for items

From f9b3a33723507f982780a9f4ff5393daaab5677c Mon Sep 17 00:00:00 2001
From: Geir Ove Alnes 
Date: Sat, 25 Jan 2025 17:03:25 +0800
Subject: [PATCH 36/37] Update Changelog.txt

---
 source/Changelog.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index b21847d8b..02b53eb87 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -1,5 +1,5 @@
 12/08/2024 - Dragon Slayer
-	Flipped Imbuing and Mysticism Skill around.
+	Fixed an issue where Imbuing and Mysticism skills were listed in wrong order in skills.dfn and enums.h
 
 4/07/2024 - Dragon Slayer
 	Fixed Cleaver ID missing in the jse_objectassociations.scp for carving corpses

From 1ef451f7168b2ffea8a32932ee2a797a46a3bf34 Mon Sep 17 00:00:00 2001
From: Geir Ove Alnes 
Date: Sat, 25 Jan 2025 17:16:46 +0800
Subject: [PATCH 37/37] Update Changelog.txt

---
 source/Changelog.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/Changelog.txt b/source/Changelog.txt
index 4cb968502..c9dea30cf 100644
--- a/source/Changelog.txt
+++ b/source/Changelog.txt
@@ -1,5 +1,5 @@
 07/12/2024 - Dragon Slayer
-Updated the packet 0xf1 to reflect the current CUO Web Ping while maintaining backward compatibility with older ping statuses. (0xf1_freeshardServerPoll.js) (Thanks Karasho and Xuri)
+	Updated the packet 0xf1 to reflect the current CUO Web Ping while maintaining backward compatibility with older ping statuses. (0xf1_freeshardServerPoll.js) (Thanks Karasho and Xuri)
 
 12/08/2024 - Dragon Slayer
 	Fixed an issue where Imbuing and Mysticism skills were listed in wrong order in skills.dfn and enums.h