Skip to content

Commit

Permalink
Merge pull request #290 from DragonSlayer62/Hit/Defense-Chance-Bonus
Browse files Browse the repository at this point in the history
Hit/Defense Chance Properties
  • Loading branch information
Xoduz authored Jan 25, 2025
2 parents efa6bcc + c3f153f commit 0c14fe6
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 26 deletions.
52 changes: 33 additions & 19 deletions source/CPacketSend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ using namespace std::string_literals;
//| BYTE[2] unknown5 (0x0)
//| BYTE[4] unknown6 (0x0)
//|
//| Note: Only send once after login. It’s mandatory to send it once.
//| Note: Only send once after login. It’s mandatory to send it once.
//o------------------------------------------------------------------------------------------------o
void CPCharLocBody::Log( std::ostream &outStream, bool fullHeader )
{
Expand Down Expand Up @@ -1411,7 +1411,7 @@ CPPaperdoll &CPPaperdoll::operator = ( CChar &toCopy )
//|
//| Packet Build
//| BYTE cmd
//| BYTE type (0x00 – “It starts to rain”, 0x01 – “A fierce storm approaches.”, 0x02 – “It begins to snow”, 0x03 - “A storm is brewing.”, 0xFF – None (turns off sound effects), 0xFE (no effect?? Set temperature?)
//| BYTE type (0x00 – “It starts to rain”, 0x01 – “A fierce storm approaches.”, 0x02 – “It begins to snow”, 0x03 - “A storm is brewing.”, 0xFF – None (turns off sound effects), 0xFE (no effect?? Set temperature?)
//| BYTE num (number of weather effects on screen)
//| BYTE temperature
//|
Expand All @@ -1422,8 +1422,8 @@ CPPaperdoll &CPPaperdoll::operator = ( CChar &toCopy )
//| Note: Weather messages are only displayed when weather starts.
//| Note: Weather will end automatically after 6 minutes without any weather change packets.
//| Note: You can totally end weather (to display a new message) by teleporting.
//| I think it’s either the 0x78 or 0x20 messages that reset it, though I
//| haven’t checked to be sure (other possibilities, 0x4F or 0x4E)
//| I think it’s either the 0x78 or 0x20 messages that reset it, though I
//| haven’t checked to be sure (other possibilities, 0x4F or 0x4E)
//o------------------------------------------------------------------------------------------------o
void CPWeather::InternalReset( void )
{
Expand Down Expand Up @@ -2043,7 +2043,7 @@ void CPOpenGump::Serial( SERIAL toSet )
//| BYTE unknown (0x00)
//| BYTE click zLoc
//| BYTE[2] model # (if a static tile, 0 if a map/landscape tile)
//| Note: the model # shouldn’t be trusted.
//| Note: the model # shouldn’t be trusted.
//o------------------------------------------------------------------------------------------------o
CPTargetCursor::CPTargetCursor()
{
Expand Down Expand Up @@ -2601,7 +2601,7 @@ void CPStatWindow::TithingPoints( UI32 value )
//| 0x07 idle
//| 0x05 another character is online
//| "Another character from this account is currently online in this world.
//| You must either log in as that character or wait for it to time out.”
//| You must either log in as that character or wait for it to time out.”
//o------------------------------------------------------------------------------------------------o
void CPIdleWarning::InternalReset( void )
{
Expand Down Expand Up @@ -3107,12 +3107,12 @@ CPMultiPlacementView::CPMultiPlacementView( SERIAL toSet )
//| 0 neither T2A NOR LBR, equal to not sending it at all,
//| 1 is T2A, chatbutton,
//| 2 is LBR without chatbutton,
//| 3 is LBR with chatbutton…
//| 3 is LBR with chatbutton…
//| 8013 LBR + chatbutton + AOS enabled
//|
//| Note1: this message is send immediately after login.
//| Note2: on OSI servers this controls features OSI enables/disables via “upgrade codes.”
//| Note3: a 3 doesn’t seem to “hurt” older (NON LBR) clients.
//| Note2: on OSI servers this controls features OSI enables/disables via “upgrade codes.”
//| Note3: a 3 doesn’t seem to “hurt” older (NON LBR) clients.
//o------------------------------------------------------------------------------------------------o
CPEnableClientFeatures::CPEnableClientFeatures( CSocket *mSock )
{
Expand Down Expand Up @@ -6118,7 +6118,7 @@ void CPObjectInfo::Objects( CItem& mItem, CChar& mChar )
//| BYTE[2] Font
//| BYTE[4] Language
//| BYTE[30] Name
//| BYTE[?][2] Msg – Null Terminated (blockSize - 48)
//| BYTE[?][2] Msg – Null Terminated (blockSize - 48)
//|
//| The various types of text is as follows:
//| 0x00 - Normal
Expand Down Expand Up @@ -6294,7 +6294,7 @@ void CPUnicodeSpeech::GhostIt( [[maybe_unused]] UI08 method )
//| BYTE[2] Font
//| BYTE[4] Language
//| BYTE[30] Name
//| BYTE[?][2] Msg – Null Terminated (blockSize - 48)
//| BYTE[?][2] Msg – Null Terminated (blockSize - 48)
//|
//| The various types of text is as follows:
//| 0x00 - Normal
Expand Down Expand Up @@ -6572,7 +6572,7 @@ void CPSecureTrading::Name( const std::string& nameFollowing )
//o------------------------------------------------------------------------------------------------o
//| Purpose - Handles outgoing packet with server response to all names request
//o------------------------------------------------------------------------------------------------o
//| Notes - Packet: 0x98 (All-names “3D”)
//| Notes - Packet: 0x98 (All-names “3D”)
//| Size: Variable
//|
//| Packet Build
Expand All @@ -6588,7 +6588,7 @@ void CPSecureTrading::Name( const std::string& nameFollowing )
//| Client asks for name of object with ID x.
//| Server has to reply with ID + name
//| Client automatically knows names of items.
//| Hence it only asks only for NPC/Player names nearby, but shows bars of items plus NPC’s.
//| Hence it only asks only for NPC/Player names nearby, but shows bars of items plus NPC’s.
//|
//| Client request has 7 bytes, server-reply 37
//| Triggered by Crtl + Shift.
Expand Down Expand Up @@ -6641,7 +6641,7 @@ void CPAllNames3D::Object( CBaseObject& obj )
//| BYTE[var] null terminated line
//| Note:
//| server side: # of pages equals value given in 0x93/0xd4
//| EACH page # given. If empty: # lines: 0 + terminator (=3 0’s)
//| EACH page # given. If empty: # lines: 0 + terminator (=3 0’s)
//| client side: # of pages always 1. if 2 pages changed, client generates 2 packets.
//o------------------------------------------------------------------------------------------------o
void CPBookPage::IncLength( UI08 amount )
Expand Down Expand Up @@ -7009,7 +7009,7 @@ bool CPNewSpellBook::ClientCanReceive( CSocket *mSock )
//| BYTE[4] Serial
//| BYTE Damage // how much damage was done ?
//|
//| Note: displays damage above the npc/player’s head.
//| Note: displays damage above the npc/player’s head.
//o------------------------------------------------------------------------------------------------o
void CPDisplayDamage::InternalReset( void )
{
Expand Down Expand Up @@ -7665,6 +7665,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.GetHealthBonus() > 0 )
{
tempEntry.stringNum = 1060431; // hit point increase ~1_val~
Expand Down Expand Up @@ -8057,9 +8071,9 @@ bool CPSellList::CanSellItems( CChar &mChar, CChar &vendor )
//| BYTE[2] len
//| BYTE subcmd
//| BYTE[ len - 4 ] submessage
//| Submessage 0 – Display Bulletin Board
//| Submessage 0 – Display Bulletin Board
//| BYTE[4] Board serial
//| BYTE[22] board name (default is “bulletin board”, the rest nulls)
//| BYTE[22] board name (default is “bulletin board”, the rest nulls)
//| BYTE[4] unknown/ID?
//| BYTE[4] zero (0)
//o------------------------------------------------------------------------------------------------o
Expand Down Expand Up @@ -8139,7 +8153,7 @@ CPOpenMessageBoard::CPOpenMessageBoard( CSocket *mSock )
//| BYTE subjectLen
//| BYTE[subjectLen] subject (null terminated string)
//| BYTE timeLen
//| BYTE[timeLen] time (null terminated string with time of posting) (“Day 1 @ 11:28”)
//| BYTE[timeLen] time (null terminated string with time of posting) (“Day 1 @ 11:28”)
//o------------------------------------------------------------------------------------------------o
//| Subcommand: 0x2 (Message Summary)
//| Size: Variable
Expand All @@ -8156,7 +8170,7 @@ CPOpenMessageBoard::CPOpenMessageBoard( CSocket *mSock )
//| BYTE subjectLen
//| BYTE[subjectLen] subject (null terminated string)
//| BYTE timeLen
//| BYTE[timeLen] time (null terminated string with time of posting) (“Day 1 @ 11:28”)
//| BYTE[timeLen] time (null terminated string with time of posting) (“Day 1 @ 11:28”)
//| BYTE[5] Unknown (01 90 03 F7 00)
//| BYTE numlines
//| For each line:
Expand Down
6 changes: 6 additions & 0 deletions source/Changelog.txt
Original file line number Diff line number Diff line change
@@ -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

13/06/2024 - Dragon Slayer
Added three More AOS Props
-HEALTHBONUS=#
Expand Down
5 changes: 5 additions & 0 deletions source/UOXJSPropertyEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ enum CC_Properties
CCP_SPAWNSERIAL,
CCP_SPATTACK,
CCP_SPDELAY,
CCP_HITCHANCE,
CCP_DEFENSECHANCE,
CCP_AITYPE,
CCP_SPLIT,
CCP_SPLITCHANCE,
Expand Down Expand Up @@ -461,6 +463,9 @@ enum CI_Properties
CIP_DAMAGEPOISON,
CIP_DAMAGERAIN,
CIP_DAMAGESNOW,
CIP_HITCHANCE,
CIP_DEFENSECHANCE,

CIP_ARTIFACTRARITY,
CIP_NAME2,
CIP_ISITEM,
Expand Down
10 changes: 10 additions & 0 deletions source/UOXJSPropertyFuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,10 +676,13 @@ 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_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_ARTIFACTRARITY: *vp = INT_TO_JSVAL( gPriv->GetArtifactRarity() ); break;

case CIP_NAME2:
tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() );
*vp = STRING_TO_JSVAL( tString );
Expand Down Expand Up @@ -1325,10 +1328,13 @@ 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<UI08>( encaps.toInt() )); break;
case CIP_HITCHANCE: gPriv->SetHitChance( static_cast<SI16>( encaps.toInt() )); break;
case CIP_DEFENSECHANCE: gPriv->SetDefenseChance( static_cast<SI16>( encaps.toInt() )); break;
case CIP_HEALTHBONUS: gPriv->SetHealthBonus( static_cast<SI16>( encaps.toInt() )); break;
case CIP_STAMINABONUS: gPriv->SetStaminaBonus( static_cast<SI16>( encaps.toInt() )); break;
case CIP_MANABONUS: gPriv->SetManaBonus( static_cast<SI16>( encaps.toInt() )); break;
case CIP_ARTIFACTRARITY: gPriv->SetArtifactRarity( static_cast<SI16>( encaps.toInt() )); break;

case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break;
case CIP_RACE: gPriv->SetRace( static_cast<RACEID>( encaps.toInt() )); break;
case CIP_MAXHP: gPriv->SetMaxHP( static_cast<SI16>( encaps.toInt() )); break;
Expand Down Expand Up @@ -2002,6 +2008,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;
Expand Down Expand Up @@ -2507,6 +2515,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<SI16>( encaps.toInt() )); break;
case CCP_SPDELAY: gPriv->SetSpDelay( static_cast<SI08>( encaps.toInt() )); break;
case CCP_HITCHANCE: gPriv->SetHitChance( static_cast<SI16>( encaps.toInt() )); break;
case CCP_DEFENSECHANCE: gPriv->SetDefenseChance( static_cast<SI16>( encaps.toInt() )); break;
case CCP_AITYPE: gPriv->SetNPCAiType( static_cast<SI16>( encaps.toInt() )); break;
case CCP_SPLIT: gPriv->SetSplit( static_cast<UI08>( encaps.toInt() )); break;
case CCP_SPLITCHANCE: gPriv->SetSplitChance( static_cast<UI08>( encaps.toInt() ));break;
Expand Down
7 changes: 7 additions & 0 deletions source/UOXJSPropertySpecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down Expand Up @@ -535,10 +537,15 @@ 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 },

{ "healthBonus", CIP_HEALTHBONUS, JSPROP_ENUMANDPERM, nullptr, nullptr },
{ "staminaBonus", CIP_STAMINABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr },
{ "manaBonus", CIP_MANABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr },
{ "artifactRarity", CIP_ARTIFACTRARITY, 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 },
Expand Down
66 changes: 65 additions & 1 deletion source/cBaseObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ 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;

const SI16 DEFBASE_HEALTHBONUS = 0;
const SI16 DEFBASE_STAMINABONOS = 0;
const SI16 DEFBASE_MANABONUS = 0;
Expand All @@ -114,7 +118,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 ),
healthBonus( DEFBASE_HEALTHBONUS ),staminaBonus( DEFBASE_STAMINABONOS ), manaBonus( DEFBASE_MANABONUS )
healthBonus( DEFBASE_HEALTHBONUS ),staminaBonus( DEFBASE_STAMINABONOS ), manaBonus( DEFBASE_MANABONUS ), hitChance( DEFBASE_HITCHANCE ), defenseChance( DEFBASE_DEFENSECHANCE )
{
multis = nullptr;
tempMulti = INVALIDSERIAL;
Expand Down Expand Up @@ -1040,6 +1044,46 @@ void CBaseObject::IncHP( SI16 amtToChange )
SetHP( hitpoints + amtToChange );
}

//o------------------------------------------------------------------------------------------------o
//| Function - CBaseObject::GetHitChance()
//| CBaseObject::SetHitChance()
//o------------------------------------------------------------------------------------------------o
//| Purpose - Gets/Sets the Defense Chance of the Item(s) Equiped or Character
//o------------------------------------------------------------------------------------------------o
SI16 CBaseObject::GetHitChance( void ) const
{
return hitChance;
}
void CBaseObject::SetHitChance( SI16 newValue )
{
hitChance = newValue;

if( CanBeObjType( OT_ITEM ))
{
( static_cast<CItem *>( this ))->UpdateRegion();
}
}

//o------------------------------------------------------------------------------------------------o
//| Function - CBaseObject::GetDefenseChance()
//| CBaseObject::SetDefenseChance()
//o------------------------------------------------------------------------------------------------o
//| Purpose - Gets/Sets the Defense Chance of the Item(s) Equiped or Character
//o------------------------------------------------------------------------------------------------o
SI16 CBaseObject::GetDefenseChance( void ) const
{
return defenseChance;
}
void CBaseObject::SetDefenseChance( SI16 newValue )
{
defenseChance = newValue;

if( CanBeObjType( OT_ITEM ))
{
( static_cast<CItem *>( this ))->UpdateRegion();
}
}

//o------------------------------------------------------------------------------------------------o
//| Function - CBaseObject::GetDir()
//| CBaseObject::SetDir()
Expand Down Expand Up @@ -1728,6 +1772,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
Expand Down
Loading

0 comments on commit 0c14fe6

Please sign in to comment.