Skip to content

Commit

Permalink
Merge pull request #1344 from Sphereserver/dev
Browse files Browse the repository at this point in the history
Merge dev to master
  • Loading branch information
raydienull authored Dec 4, 2024
2 parents bb06831 + 29e9ddc commit 20da698
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 48 deletions.
39 changes: 29 additions & 10 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3915,16 +3915,6 @@ Added: 'H' shortcut for variables to get the value as hexadecimal.
13-10-2024, Jhobean
- Added: @PetRelease trigger work like @petdesert and return 1 to prevent the pet from being released.

26-10-2024, canerksk
- Fixed: Memory OnTick link char if not, the skill will not fail.
If the memory owner is not present, skills do not fail when taking damage, but if the memory owner is alive, skills fail when taking damage.

- Fixed: The entity was jumping frames in flooded pet commands (come, guard)

08-11-2024
- Fixed: ITEMMEMORYEQUIP is not triggered in many default memories.
Previously, many memories did not have morex information, but now for some reason many memories have morex information and for this reason the trigger was not triggered in almost most of the memories, the morex query was removed. Also, the slang did not represent the memory item.

27-11-2024, canerksk
- Added: All skills that have a distance query have been adjusted to take the RANGE values ​​of that skill.
All skills to be used in RANGE;
Expand All @@ -3944,3 +3934,32 @@ Added: 'H' shortcut for variables to get the value as hexadecimal.
- Added: Added NOREJOIN tag for corpses, If the NOREJOIN tag is one, the player cannot come back to life on that corpse. That is, the player comes back to life but not on the corpse.
This tag does not prevent the player from coming back to life, it just prevents them from respawning on that corpse. The player always comes back to life, but not on that corpse.
- Fixed: If you are around an entity that you own and you are trying to open a bank next to a bank, the "bank" command is perceived as a pet command and the bank does not open. There is no problem when you type "bank" after mounting the mount, but "bank" does not work when you dismount. (Issue #1331)

27-11-2024, Gladie
- Fixed: Redeeding t_multi_addon outside of housing system. Before it was only looking for owner of the multi, but in our case we need to know uid of the redeeding char.

2-12-2024, canerksk
- Fixed: Memory OnTick link char if not, the skill will not fail.
If the memory owner is not present, skills do not fail when taking damage, but if the memory owner is alive, skills fail when taking damage.
- Fixed: The entity was jumping frames in flooded pet commands (come, guard).
- Fixed: ITEMMEMORYEQUIP is not triggered in many default memories.
Previously, many memories did not have morex information, but now for some reason many memories have morex information and for this reason the trigger was not triggered in almost most of the memories, the morex query was removed. Also, the slang did not represent the memory item.

02-12-2024, raydie
- Added: Add LAYER_SPELL_Explosion for use delayed explosion spell. Now if set Duration to spell explosion, these duration is the delay to execute the explosion (From UOGuide, explosion spell: 2 second delay between targetting and explosion).

3-12-2024, canerksk
- Added: New trigger @HitReactive Reactive Armor plays a key role in the action mechanism and is currently under very fixed rules. It has been added as a new trigger with some variables to make it a bit more flexible.
@HitReactive
Local.Sound (r/w) =Sound ID, If it is blank or zero, no sound is produced. (Default: 01F1)
Local.EffectID (r/w) = Effect ID, If it is empty or zero, no effect will occur. (Default: 0374a)
Local.Damage (r/w) = This is the more1l, or PolyStr, value coming from the reactive armor spell to i_rune_reactive_armor.
LOCAL.ReflectDamage (r/w) = The amount of damage that will be reflected to this other party
LOCAL.ReduceDamage (r/w) = Amount to be deducted from damage received
LOCAL.DamageType (r/w) = Type of damage received (Default: DAMAGE_FIXED andDAMAGE_REACTIVE)
NOTE;
1. If no ReflectDamage or ReduceDamage values ​​are entered, the system defaults to the Reactive Armor Effect value.
2. No damage amount can be less than 1.

4-12-2024, canerksk
- Fixed: Sphere crash troubleshooting if a player has no CHATNAME value and remove a channel
1 change: 1 addition & 0 deletions src/game/CObjBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,7 @@ enum CTRIG_TYPE : short
CTRIG_HitIgnore, // I should ignore this target, just giving a record to scripts.
CTRIG_HitMiss, // I just missed.
CTRIG_HitParry, // I succesfully parried an hit.
CTRIG_HitReactive, // Reactive damage trigger
CTRIG_HitTry, // I am trying to hit someone. starting swing.
CTRIG_HouseDesignBegin, // Starting to customize.
CTRIG_HouseDesignCommit, // I committed a new house design
Expand Down
1 change: 1 addition & 0 deletions src/game/chars/CChar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ lpctstr const CChar::sm_szTrigName[CTRIG_QTY+1] = // static
"@HitIgnore", // I'm going to avoid a target (attacker.n.ignore=1) , should I un-ignore him?.
"@HitMiss", // I just missed.
"@HitParry", // I succesfully parried an hit.
"@HitReactive", // Reactive damage trigger
"@HitTry", // I am trying to hit someone. starting swing.
"@HouseDesignBegin", // Starting to customize.
"@HouseDesignCommit", // I committed a new house design.
Expand Down
66 changes: 53 additions & 13 deletions src/game/chars/CCharFight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,19 +943,59 @@ int CChar::OnTakeDamage( int iDmg, CChar * pSrc, DAMAGE_TYPE uiType, int iDmgPhy
{
CItem* pReactive = LayerFind(LAYER_SPELL_Reactive);

if (pReactive)
{
int iReactiveDamage = (iDmg * pReactive->m_itSpell.m_PolyStr) / 100;
if (iReactiveDamage < 1)
{
iReactiveDamage = 1;
}

iDmg -= iReactiveDamage;
pSrc->OnTakeDamage(iReactiveDamage, this, (DAMAGE_TYPE)(DAMAGE_FIXED | DAMAGE_REACTIVE), iDmgPhysical, iDmgFire, iDmgCold, iDmgPoison, iDmgEnergy,(SPELL_TYPE)pReactive->m_itSpell.m_spell);
pSrc->Sound(0x1F1);
pSrc->Effect(EFFECT_OBJ, ITEMID_FX_CURSE_EFFECT, this, 10, 16);
}
if (pReactive)
{
int iReactiveDamage = (iDmg * pReactive->m_itSpell.m_PolyStr) / 100;
int iReactiveRefDam = iReactiveDamage;
int iReactiveRedDam = iReactiveDamage;
SOUND_TYPE ReactiveSnd = 0x1F1;
ITEMID_TYPE ReactiveEffectID = ITEMID_FX_CURSE_EFFECT;
DAMAGE_TYPE ReactiveDamType = (DAMAGE_FIXED | DAMAGE_REACTIVE);

if (IsTrigUsed(TRIGGER_HITREACTIVE))
{
CScriptTriggerArgs HitReactiveArgs;
HitReactiveArgs.m_VarsLocal.SetNum("Sound", ReactiveSnd); // SOUND
HitReactiveArgs.m_VarsLocal.SetNum("EffectID", ReactiveEffectID); // EFFECTID
HitReactiveArgs.m_VarsLocal.SetNum("Damage", iReactiveDamage); // DAMAGE VALUE
HitReactiveArgs.m_VarsLocal.SetNum("ReflectDamage", iReactiveRefDam); // REFLECTED DAM
HitReactiveArgs.m_VarsLocal.SetNum("ReduceDamage", iReactiveRedDam); // REDUCED DAM
HitReactiveArgs.m_VarsLocal.SetNum("DamageType", ReactiveDamType); // DAMAGE TYPE
OnTrigger(CTRIG_HitReactive, pSrc, &HitReactiveArgs);

ReactiveSnd = (SOUND_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("Sound"); // SOUND
ReactiveEffectID = (ITEMID_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("EffectID"); // EFFECTID
iReactiveDamage = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("Damage"); // DAMAGE VALUE
iReactiveRefDam = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("ReflectDamage"); // REFLECTED DAMAGE VALUE
iReactiveRedDam = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("ReduceDamage"); // REDUCED DAMAGE VALUE
ReactiveDamType = (DAMAGE_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("DamageType"); // DAMAGE TYPE
// should it be zero ?
//if (iReactiveDamage < 1)
// iReactiveDamage = 1;

//if (iReactiveRedDam < 1)
// iReactiveRedDam = 1;

//if (iReactiveRefDam < 1)
// iReactiveRefDam = 1;
}

// reduce
if (iReactiveRedDam > 0 || iReactiveDamage > 0)
iDmg -= iReactiveRedDam ? iReactiveRedDam : iReactiveDamage;

// reflect
if (iReactiveRefDam > 0 || iReactiveDamage > 0)
pSrc->OnTakeDamage(iReactiveRefDam ? iReactiveRefDam : iReactiveDamage, this, ReactiveDamType, iDmgPhysical, iDmgFire, iDmgCold,
iDmgPoison, iDmgEnergy, (SPELL_TYPE)pReactive->m_itSpell.m_spell);

if (ReactiveSnd)
pSrc->Sound(ReactiveSnd);

if (ReactiveEffectID)
pSrc->Effect(EFFECT_OBJ, ReactiveEffectID, this, 10, 16);

}
}
}
// Check if REFLECTPHYSICALDAM will reflect some damage back.
Expand Down
37 changes: 28 additions & 9 deletions src/game/chars/CCharSpell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,14 @@ bool CChar::Spell_Equip_OnTick( CItem * pItem )
break;
}

case SPELL_Explosion:
{
iEffect = iLevel;
iDmgType = DAMAGE_MAGIC | DAMAGE_FIRE;
Effect(EFFECT_OBJ, ITEMID_FX_EXPLODE_3, pItem->m_uidLink.CharFind(), 10, 16);
}
break;

case SPELL_Strangle:
{
/*
Expand Down Expand Up @@ -2047,6 +2055,10 @@ CItem * CChar::Spell_Effect_Create( SPELL_TYPE spell, LAYER_TYPE layer, int iEff
if ( layer == LAYER_SPELL_STATS && spell != pSpellPrev->m_itSpell.m_spell && IsSetMagicFlags(MAGICF_STACKSTATS) )
continue;

// If spell is explosion and there's already an explosion timer, dont remove it
if ( spell == SPELL_Explosion && layer == LAYER_SPELL_Explosion )
continue;

pSpellPrev->Delete();
break;
}
Expand All @@ -2055,15 +2067,16 @@ CItem * CChar::Spell_Effect_Create( SPELL_TYPE spell, LAYER_TYPE layer, int iEff
CItem *pSpell = CItem::CreateBase(pSpellDef ? pSpellDef->m_idSpell : ITEMID_RHAND_POINT_NW);
ASSERT(pSpell);

switch ( layer )
{
case LAYER_FLAG_Criminal: pSpell->SetName("Criminal Timer"); break;
case LAYER_FLAG_PotionUsed: pSpell->SetName("Potion Cooldown"); break;
case LAYER_FLAG_Drunk: pSpell->SetName("Drunk Effect"); break;
case LAYER_FLAG_Hallucination: pSpell->SetName("Hallucination Effect"); break;
case LAYER_FLAG_Murders: pSpell->SetName("Murder Decay"); break;
default: break;
}
switch ( layer )
{
case LAYER_FLAG_Criminal: pSpell->SetName("Criminal Timer"); break;
case LAYER_FLAG_PotionUsed: pSpell->SetName("Potion Cooldown"); break;
case LAYER_FLAG_Drunk: pSpell->SetName("Drunk Effect"); break;
case LAYER_FLAG_Hallucination: pSpell->SetName("Hallucination Effect"); break;
case LAYER_FLAG_Murders: pSpell->SetName("Murder Decay"); break;
case LAYER_SPELL_Explosion: pSpell->SetName("Explosion Timer"); break;
default: break;
}

g_World.m_uidNew = pSpell->GetUID();
pSpell->SetAttr(pSpellDef ? ATTR_NEWBIE|ATTR_MAGIC : ATTR_NEWBIE);
Expand Down Expand Up @@ -3911,6 +3924,12 @@ bool CChar::OnSpellEffect( SPELL_TYPE spell, CChar * pCharSrc, int iSkillLevel,
}
break;

case SPELL_Explosion:
// if not a potion and have duration, create effect
if (!fPotion && iDuration > 0)
Spell_Effect_Create( SPELL_Explosion, LAYER_SPELL_Explosion, iEffect, iDuration, pCharSrc );
break;

case SPELL_Invis:
Spell_Effect_Create( spell, fPotion ? LAYER_FLAG_Potion : LAYER_SPELL_Invis, iEffect, iDuration, pCharSrc );
break;
Expand Down
2 changes: 1 addition & 1 deletion src/game/chars/CCharStatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1996,7 +1996,7 @@ bool CChar::CanStandAt(CPointMap *ptDest, const CRegion* pArea, uint64 uiMyMovem
if (!fPathfinding && (g_Cfg.m_iDebugFlags & DEBUGF_WALK))
g_Log.EventWarn("GetHeightMount() %hhu, block.m_Top.m_z %hhd, ptDest.m_z %hhd.\n", uiMyHeight, blockingState->m_Top.m_z, ptDest->m_z);

if ((uiMyHeight + ptDest->m_z >= blockingState->m_Top.m_z) && g_Cfg.m_iMountHeight && !IsPriv(PRIV_GM) && !IsPriv(PRIV_ALLMOVE))
if (IsStatFlag(STATF_ONHORSE) && (uiMyHeight + ptDest->m_z >= blockingState->m_Top.m_z) && g_Cfg.m_iMountHeight && !IsPriv(PRIV_GM) && !IsPriv(PRIV_ALLMOVE))
{
if (!fPathfinding)
SysMessageDefault(DEFMSG_MSG_MOUNT_CEILING);
Expand Down
2 changes: 1 addition & 1 deletion src/game/clients/CChatChanMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ lpctstr CChatChanMember::GetChatName() const
ADDTOCALLSTACK("CChatChanMember::GetChatName");
const CClient *pClient = GetClientActive();

if (pClient)
if (pClient && pClient->GetAccount() && !pClient->GetAccount()->m_sChatName.IsEmpty())
return(pClient->GetAccount()->m_sChatName);
return "";
}
Expand Down
11 changes: 6 additions & 5 deletions src/game/clients/CClientUse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )

case IT_SHAFT:
case IT_FEATHER:
case IT_FLETCHING:
return Skill_Menu(SKILL_BOWCRAFT, "sm_bolts", pItem->GetID());

case IT_FISH_POLE: // Just be near water ?
Expand Down Expand Up @@ -185,7 +186,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
}
else // I have the key but i need to use it to unlock the container.
{
SysMessageDefault(DEFMSG_LOCK_HAS_KEY);
SysMessageDefault(DEFMSG_LOCK_HAS_KEY);
return false;
}
break;
Expand All @@ -194,7 +195,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
SysMessageDefault(DEFMSG_ITEMUSE_LOCKED);
if ( !m_pChar->GetPackSafe()->ContentFindKeyFor(pItem) ) // I don't have the hold key
{

SysMessageDefault(DEFMSG_LOCK_HOLD_NO_KEY);
if ( !IsPriv(PRIV_GM) )
return false;
Expand Down Expand Up @@ -225,7 +226,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
if ( m_pChar->CheckCorpseCrime(pCorpseItem, true, true) )
SysMessageDefault(DEFMSG_LOOT_CRIMINAL_ACT);
}

return true;
}

Expand Down Expand Up @@ -849,7 +850,7 @@ int CClient::Cmd_Skill_Menu_Build( const CResourceID& rid, int iSelect, CMenuIte
{
if ( (iSelect < -1) && (iShowCount >= 1) ) // just a test. so we are done.
return 1;

CMenuItem miTest;
if ( !miTest.ParseLine(s.GetArgRaw(), nullptr, m_pChar) )
{
Expand Down Expand Up @@ -1150,7 +1151,7 @@ bool CClient::Cmd_Skill_Tracking( uint track_sel, bool fExec )
When the Tracking skill starts and the Effect property is defined on the Tracking skill use it
instead of the hardcoded formula for the maximum distance.
*/

if (m_pChar->m_Act_Effect >= 0)
m_pChar->m_atTracking.m_dwDistMax = (dword)m_pChar->m_Act_Effect;
else //This is default Sphere maximum tracking distance.
Expand Down
26 changes: 21 additions & 5 deletions src/game/items/CItemMulti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ int16 CItemMulti::GetMultiCount() const
return _iMultiCount;
}

void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidRedeedingChar)
{
ADDTOCALLSTACK("CItemMulti::Redeed");
if (GetKeyNum("REMOVED") > 0) // Just don't pass from here again, to avoid duplicated deeds.
Expand Down Expand Up @@ -1209,7 +1209,7 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
args.m_iN3 = fMoveToBank; // Transfer the Moving Crate to the owner's bank.
if (IsTrigUsed(TRIGGER_REDEED))
{
tRet = OnTrigger(ITRIG_Redeed, uidChar.CharFind(), &args);
tRet = OnTrigger(ITRIG_Redeed, uidRedeedingChar.CharFind(), &args);
if (args.m_iN2 == 0)
{
fMoveToBank = false;
Expand All @@ -1230,7 +1230,8 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
}

CChar* pOwner = GetOwner().CharFind();
if (!pOwner || !pOwner->m_pPlayer)
CChar* pChar = uidRedeedingChar.CharFind();
if ((!pChar || !pChar->m_pPlayer) && (!pOwner || !pOwner->m_pPlayer))
{
return;
}
Expand All @@ -1256,11 +1257,26 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
}
if (fMoveToBank)
{
pOwner->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
if (pOwner)
{
pOwner->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
}
else
{
pChar->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
}

}
else
{
pOwner->ItemBounce(pDeed, fDisplayMsg);
if (pOwner)
{
pOwner->ItemBounce(pDeed, fDisplayMsg);
}
else
{
pChar->ItemBounce(pDeed, fDisplayMsg);
}
}
}
SetKeyNum("REMOVED", 1);
Expand Down
4 changes: 2 additions & 2 deletions src/game/items/item_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ enum IT_TYPE : int32_t // double click type action.
IT_TRAIN_DUMMY, // 156
IT_TRAIN_PICKPOCKET, // 157
IT_BEDROLL, // 158
IT_UNUSED_159, // 159
IT_FLETCHING, // 159
IT_HIDE, // 160 = hides are cured to make leather.
IT_CLOTH_BOLT, // 161 = must be cut up to make cloth squares.
IT_BOARD, // 162 = logs are plained into decent lumber
Expand Down Expand Up @@ -214,7 +214,7 @@ enum IT_TYPE : int32_t // double click type action.
IT_PILOT, // 197 = ship's pilot (PacketWheelMove)
IT_ROPE, // 198 = t_rope (working like t_ship_plank but without id changes)
IT_WEAPON_WHIP, // 199

// New SphereX hardcoded types starting from 300
IT_SPAWN_CHAMPION = 300,// 300 = t_spawn_champion
IT_MULTI_ADDON, // 301 = t_multi_addon
Expand Down
5 changes: 3 additions & 2 deletions src/game/uo_files/uofiles_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,9 +654,10 @@ enum LAYER_TYPE : unsigned char // defined by UO. Only one item can be in a slot

//Individual Spell Layers
LAYER_SPELL_Mana_Drain,
LAYER_SPELL_Explosion,

LAYER_STORAGE, //80 New Storage layer, can equip t_container and t_container_locked.
LAYER_STABLE, //81 New stable layer, now stabled pets will be stored in this layer of the player instead of npc's itself.
LAYER_STORAGE, // New Storage layer, can equip t_container and t_container_locked.
LAYER_STABLE, // New stable layer, now stabled pets will be stored in this layer of the player instead of npc's itself.
LAYER_QTY
};

Expand Down
1 change: 1 addition & 0 deletions src/tables/triggers.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ ADD(HITCHECK)
ADD(HITIGNORE)
ADD(HITMISS)
ADD(HITPARRY)
ADD(HITREACTIVE)
ADD(HITTRY)
ADD(HOUSEDESIGNBEGIN)
ADD(HOUSEDESIGNCOMMIT)
Expand Down

0 comments on commit 20da698

Please sign in to comment.