Skip to content

Commit 20da698

Browse files
authored
Merge pull request #1344 from Sphereserver/dev
Merge dev to master
2 parents bb06831 + 29e9ddc commit 20da698

File tree

12 files changed

+147
-48
lines changed

12 files changed

+147
-48
lines changed

Changelog.txt

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3915,16 +3915,6 @@ Added: 'H' shortcut for variables to get the value as hexadecimal.
39153915
13-10-2024, Jhobean
39163916
- Added: @PetRelease trigger work like @petdesert and return 1 to prevent the pet from being released.
39173917

3918-
26-10-2024, canerksk
3919-
- Fixed: Memory OnTick link char if not, the skill will not fail.
3920-
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.
3921-
3922-
- Fixed: The entity was jumping frames in flooded pet commands (come, guard)
3923-
3924-
08-11-2024
3925-
- Fixed: ITEMMEMORYEQUIP is not triggered in many default memories.
3926-
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.
3927-
39283918
27-11-2024, canerksk
39293919
- Added: All skills that have a distance query have been adjusted to take the RANGE values ​​of that skill.
39303920
All skills to be used in RANGE;
@@ -3944,3 +3934,32 @@ Added: 'H' shortcut for variables to get the value as hexadecimal.
39443934
- 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.
39453935
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.
39463936
- 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)
3937+
3938+
27-11-2024, Gladie
3939+
- 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.
3940+
3941+
2-12-2024, canerksk
3942+
- Fixed: Memory OnTick link char if not, the skill will not fail.
3943+
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.
3944+
- Fixed: The entity was jumping frames in flooded pet commands (come, guard).
3945+
- Fixed: ITEMMEMORYEQUIP is not triggered in many default memories.
3946+
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.
3947+
3948+
02-12-2024, raydie
3949+
- 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).
3950+
3951+
3-12-2024, canerksk
3952+
- 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.
3953+
@HitReactive
3954+
Local.Sound (r/w) =Sound ID, If it is blank or zero, no sound is produced. (Default: 01F1)
3955+
Local.EffectID (r/w) = Effect ID, If it is empty or zero, no effect will occur. (Default: 0374a)
3956+
Local.Damage (r/w) = This is the more1l, or PolyStr, value coming from the reactive armor spell to i_rune_reactive_armor.
3957+
LOCAL.ReflectDamage (r/w) = The amount of damage that will be reflected to this other party
3958+
LOCAL.ReduceDamage (r/w) = Amount to be deducted from damage received
3959+
LOCAL.DamageType (r/w) = Type of damage received (Default: DAMAGE_FIXED andDAMAGE_REACTIVE)
3960+
NOTE;
3961+
1. If no ReflectDamage or ReduceDamage values ​​are entered, the system defaults to the Reactive Armor Effect value.
3962+
2. No damage amount can be less than 1.
3963+
3964+
4-12-2024, canerksk
3965+
- Fixed: Sphere crash troubleshooting if a player has no CHATNAME value and remove a channel

src/game/CObjBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,7 @@ enum CTRIG_TYPE : short
10881088
CTRIG_HitIgnore, // I should ignore this target, just giving a record to scripts.
10891089
CTRIG_HitMiss, // I just missed.
10901090
CTRIG_HitParry, // I succesfully parried an hit.
1091+
CTRIG_HitReactive, // Reactive damage trigger
10911092
CTRIG_HitTry, // I am trying to hit someone. starting swing.
10921093
CTRIG_HouseDesignBegin, // Starting to customize.
10931094
CTRIG_HouseDesignCommit, // I committed a new house design

src/game/chars/CChar.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ lpctstr const CChar::sm_szTrigName[CTRIG_QTY+1] = // static
8787
"@HitIgnore", // I'm going to avoid a target (attacker.n.ignore=1) , should I un-ignore him?.
8888
"@HitMiss", // I just missed.
8989
"@HitParry", // I succesfully parried an hit.
90+
"@HitReactive", // Reactive damage trigger
9091
"@HitTry", // I am trying to hit someone. starting swing.
9192
"@HouseDesignBegin", // Starting to customize.
9293
"@HouseDesignCommit", // I committed a new house design.

src/game/chars/CCharFight.cpp

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -943,19 +943,59 @@ int CChar::OnTakeDamage( int iDmg, CChar * pSrc, DAMAGE_TYPE uiType, int iDmgPhy
943943
{
944944
CItem* pReactive = LayerFind(LAYER_SPELL_Reactive);
945945

946-
if (pReactive)
947-
{
948-
int iReactiveDamage = (iDmg * pReactive->m_itSpell.m_PolyStr) / 100;
949-
if (iReactiveDamage < 1)
950-
{
951-
iReactiveDamage = 1;
952-
}
953-
954-
iDmg -= iReactiveDamage;
955-
pSrc->OnTakeDamage(iReactiveDamage, this, (DAMAGE_TYPE)(DAMAGE_FIXED | DAMAGE_REACTIVE), iDmgPhysical, iDmgFire, iDmgCold, iDmgPoison, iDmgEnergy,(SPELL_TYPE)pReactive->m_itSpell.m_spell);
956-
pSrc->Sound(0x1F1);
957-
pSrc->Effect(EFFECT_OBJ, ITEMID_FX_CURSE_EFFECT, this, 10, 16);
958-
}
946+
if (pReactive)
947+
{
948+
int iReactiveDamage = (iDmg * pReactive->m_itSpell.m_PolyStr) / 100;
949+
int iReactiveRefDam = iReactiveDamage;
950+
int iReactiveRedDam = iReactiveDamage;
951+
SOUND_TYPE ReactiveSnd = 0x1F1;
952+
ITEMID_TYPE ReactiveEffectID = ITEMID_FX_CURSE_EFFECT;
953+
DAMAGE_TYPE ReactiveDamType = (DAMAGE_FIXED | DAMAGE_REACTIVE);
954+
955+
if (IsTrigUsed(TRIGGER_HITREACTIVE))
956+
{
957+
CScriptTriggerArgs HitReactiveArgs;
958+
HitReactiveArgs.m_VarsLocal.SetNum("Sound", ReactiveSnd); // SOUND
959+
HitReactiveArgs.m_VarsLocal.SetNum("EffectID", ReactiveEffectID); // EFFECTID
960+
HitReactiveArgs.m_VarsLocal.SetNum("Damage", iReactiveDamage); // DAMAGE VALUE
961+
HitReactiveArgs.m_VarsLocal.SetNum("ReflectDamage", iReactiveRefDam); // REFLECTED DAM
962+
HitReactiveArgs.m_VarsLocal.SetNum("ReduceDamage", iReactiveRedDam); // REDUCED DAM
963+
HitReactiveArgs.m_VarsLocal.SetNum("DamageType", ReactiveDamType); // DAMAGE TYPE
964+
OnTrigger(CTRIG_HitReactive, pSrc, &HitReactiveArgs);
965+
966+
ReactiveSnd = (SOUND_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("Sound"); // SOUND
967+
ReactiveEffectID = (ITEMID_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("EffectID"); // EFFECTID
968+
iReactiveDamage = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("Damage"); // DAMAGE VALUE
969+
iReactiveRefDam = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("ReflectDamage"); // REFLECTED DAMAGE VALUE
970+
iReactiveRedDam = (int)HitReactiveArgs.m_VarsLocal.GetKeyNum("ReduceDamage"); // REDUCED DAMAGE VALUE
971+
ReactiveDamType = (DAMAGE_TYPE)HitReactiveArgs.m_VarsLocal.GetKeyNum("DamageType"); // DAMAGE TYPE
972+
// should it be zero ?
973+
//if (iReactiveDamage < 1)
974+
// iReactiveDamage = 1;
975+
976+
//if (iReactiveRedDam < 1)
977+
// iReactiveRedDam = 1;
978+
979+
//if (iReactiveRefDam < 1)
980+
// iReactiveRefDam = 1;
981+
}
982+
983+
// reduce
984+
if (iReactiveRedDam > 0 || iReactiveDamage > 0)
985+
iDmg -= iReactiveRedDam ? iReactiveRedDam : iReactiveDamage;
986+
987+
// reflect
988+
if (iReactiveRefDam > 0 || iReactiveDamage > 0)
989+
pSrc->OnTakeDamage(iReactiveRefDam ? iReactiveRefDam : iReactiveDamage, this, ReactiveDamType, iDmgPhysical, iDmgFire, iDmgCold,
990+
iDmgPoison, iDmgEnergy, (SPELL_TYPE)pReactive->m_itSpell.m_spell);
991+
992+
if (ReactiveSnd)
993+
pSrc->Sound(ReactiveSnd);
994+
995+
if (ReactiveEffectID)
996+
pSrc->Effect(EFFECT_OBJ, ReactiveEffectID, this, 10, 16);
997+
998+
}
959999
}
9601000
}
9611001
// Check if REFLECTPHYSICALDAM will reflect some damage back.

src/game/chars/CCharSpell.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,14 @@ bool CChar::Spell_Equip_OnTick( CItem * pItem )
18941894
break;
18951895
}
18961896

1897+
case SPELL_Explosion:
1898+
{
1899+
iEffect = iLevel;
1900+
iDmgType = DAMAGE_MAGIC | DAMAGE_FIRE;
1901+
Effect(EFFECT_OBJ, ITEMID_FX_EXPLODE_3, pItem->m_uidLink.CharFind(), 10, 16);
1902+
}
1903+
break;
1904+
18971905
case SPELL_Strangle:
18981906
{
18991907
/*
@@ -2047,6 +2055,10 @@ CItem * CChar::Spell_Effect_Create( SPELL_TYPE spell, LAYER_TYPE layer, int iEff
20472055
if ( layer == LAYER_SPELL_STATS && spell != pSpellPrev->m_itSpell.m_spell && IsSetMagicFlags(MAGICF_STACKSTATS) )
20482056
continue;
20492057

2058+
// If spell is explosion and there's already an explosion timer, dont remove it
2059+
if ( spell == SPELL_Explosion && layer == LAYER_SPELL_Explosion )
2060+
continue;
2061+
20502062
pSpellPrev->Delete();
20512063
break;
20522064
}
@@ -2055,15 +2067,16 @@ CItem * CChar::Spell_Effect_Create( SPELL_TYPE spell, LAYER_TYPE layer, int iEff
20552067
CItem *pSpell = CItem::CreateBase(pSpellDef ? pSpellDef->m_idSpell : ITEMID_RHAND_POINT_NW);
20562068
ASSERT(pSpell);
20572069

2058-
switch ( layer )
2059-
{
2060-
case LAYER_FLAG_Criminal: pSpell->SetName("Criminal Timer"); break;
2061-
case LAYER_FLAG_PotionUsed: pSpell->SetName("Potion Cooldown"); break;
2062-
case LAYER_FLAG_Drunk: pSpell->SetName("Drunk Effect"); break;
2063-
case LAYER_FLAG_Hallucination: pSpell->SetName("Hallucination Effect"); break;
2064-
case LAYER_FLAG_Murders: pSpell->SetName("Murder Decay"); break;
2065-
default: break;
2066-
}
2070+
switch ( layer )
2071+
{
2072+
case LAYER_FLAG_Criminal: pSpell->SetName("Criminal Timer"); break;
2073+
case LAYER_FLAG_PotionUsed: pSpell->SetName("Potion Cooldown"); break;
2074+
case LAYER_FLAG_Drunk: pSpell->SetName("Drunk Effect"); break;
2075+
case LAYER_FLAG_Hallucination: pSpell->SetName("Hallucination Effect"); break;
2076+
case LAYER_FLAG_Murders: pSpell->SetName("Murder Decay"); break;
2077+
case LAYER_SPELL_Explosion: pSpell->SetName("Explosion Timer"); break;
2078+
default: break;
2079+
}
20672080

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

3927+
case SPELL_Explosion:
3928+
// if not a potion and have duration, create effect
3929+
if (!fPotion && iDuration > 0)
3930+
Spell_Effect_Create( SPELL_Explosion, LAYER_SPELL_Explosion, iEffect, iDuration, pCharSrc );
3931+
break;
3932+
39143933
case SPELL_Invis:
39153934
Spell_Effect_Create( spell, fPotion ? LAYER_FLAG_Potion : LAYER_SPELL_Invis, iEffect, iDuration, pCharSrc );
39163935
break;

src/game/chars/CCharStatus.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1996,7 +1996,7 @@ bool CChar::CanStandAt(CPointMap *ptDest, const CRegion* pArea, uint64 uiMyMovem
19961996
if (!fPathfinding && (g_Cfg.m_iDebugFlags & DEBUGF_WALK))
19971997
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);
19981998

1999-
if ((uiMyHeight + ptDest->m_z >= blockingState->m_Top.m_z) && g_Cfg.m_iMountHeight && !IsPriv(PRIV_GM) && !IsPriv(PRIV_ALLMOVE))
1999+
if (IsStatFlag(STATF_ONHORSE) && (uiMyHeight + ptDest->m_z >= blockingState->m_Top.m_z) && g_Cfg.m_iMountHeight && !IsPriv(PRIV_GM) && !IsPriv(PRIV_ALLMOVE))
20002000
{
20012001
if (!fPathfinding)
20022002
SysMessageDefault(DEFMSG_MSG_MOUNT_CEILING);

src/game/clients/CChatChanMember.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ lpctstr CChatChanMember::GetChatName() const
197197
ADDTOCALLSTACK("CChatChanMember::GetChatName");
198198
const CClient *pClient = GetClientActive();
199199

200-
if (pClient)
200+
if (pClient && pClient->GetAccount() && !pClient->GetAccount()->m_sChatName.IsEmpty())
201201
return(pClient->GetAccount()->m_sChatName);
202202
return "";
203203
}

src/game/clients/CClientUse.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
158158

159159
case IT_SHAFT:
160160
case IT_FEATHER:
161+
case IT_FLETCHING:
161162
return Skill_Menu(SKILL_BOWCRAFT, "sm_bolts", pItem->GetID());
162163

163164
case IT_FISH_POLE: // Just be near water ?
@@ -185,7 +186,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
185186
}
186187
else // I have the key but i need to use it to unlock the container.
187188
{
188-
SysMessageDefault(DEFMSG_LOCK_HAS_KEY);
189+
SysMessageDefault(DEFMSG_LOCK_HAS_KEY);
189190
return false;
190191
}
191192
break;
@@ -194,7 +195,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
194195
SysMessageDefault(DEFMSG_ITEMUSE_LOCKED);
195196
if ( !m_pChar->GetPackSafe()->ContentFindKeyFor(pItem) ) // I don't have the hold key
196197
{
197-
198+
198199
SysMessageDefault(DEFMSG_LOCK_HOLD_NO_KEY);
199200
if ( !IsPriv(PRIV_GM) )
200201
return false;
@@ -225,7 +226,7 @@ bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
225226
if ( m_pChar->CheckCorpseCrime(pCorpseItem, true, true) )
226227
SysMessageDefault(DEFMSG_LOOT_CRIMINAL_ACT);
227228
}
228-
229+
229230
return true;
230231
}
231232

@@ -849,7 +850,7 @@ int CClient::Cmd_Skill_Menu_Build( const CResourceID& rid, int iSelect, CMenuIte
849850
{
850851
if ( (iSelect < -1) && (iShowCount >= 1) ) // just a test. so we are done.
851852
return 1;
852-
853+
853854
CMenuItem miTest;
854855
if ( !miTest.ParseLine(s.GetArgRaw(), nullptr, m_pChar) )
855856
{
@@ -1150,7 +1151,7 @@ bool CClient::Cmd_Skill_Tracking( uint track_sel, bool fExec )
11501151
When the Tracking skill starts and the Effect property is defined on the Tracking skill use it
11511152
instead of the hardcoded formula for the maximum distance.
11521153
*/
1153-
1154+
11541155
if (m_pChar->m_Act_Effect >= 0)
11551156
m_pChar->m_atTracking.m_dwDistMax = (dword)m_pChar->m_Act_Effect;
11561157
else //This is default Sphere maximum tracking distance.

src/game/items/CItemMulti.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ int16 CItemMulti::GetMultiCount() const
11741174
return _iMultiCount;
11751175
}
11761176

1177-
void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
1177+
void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidRedeedingChar)
11781178
{
11791179
ADDTOCALLSTACK("CItemMulti::Redeed");
11801180
if (GetKeyNum("REMOVED") > 0) // Just don't pass from here again, to avoid duplicated deeds.
@@ -1209,7 +1209,7 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
12091209
args.m_iN3 = fMoveToBank; // Transfer the Moving Crate to the owner's bank.
12101210
if (IsTrigUsed(TRIGGER_REDEED))
12111211
{
1212-
tRet = OnTrigger(ITRIG_Redeed, uidChar.CharFind(), &args);
1212+
tRet = OnTrigger(ITRIG_Redeed, uidRedeedingChar.CharFind(), &args);
12131213
if (args.m_iN2 == 0)
12141214
{
12151215
fMoveToBank = false;
@@ -1230,7 +1230,8 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
12301230
}
12311231

12321232
CChar* pOwner = GetOwner().CharFind();
1233-
if (!pOwner || !pOwner->m_pPlayer)
1233+
CChar* pChar = uidRedeedingChar.CharFind();
1234+
if ((!pChar || !pChar->m_pPlayer) && (!pOwner || !pOwner->m_pPlayer))
12341235
{
12351236
return;
12361237
}
@@ -1256,11 +1257,26 @@ void CItemMulti::Redeed(bool fDisplayMsg, bool fMoveToBank, CUID uidChar)
12561257
}
12571258
if (fMoveToBank)
12581259
{
1259-
pOwner->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
1260+
if (pOwner)
1261+
{
1262+
pOwner->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
1263+
}
1264+
else
1265+
{
1266+
pChar->GetBank(LAYER_BANKBOX)->ContentAdd(pDeed);
1267+
}
1268+
12601269
}
12611270
else
12621271
{
1263-
pOwner->ItemBounce(pDeed, fDisplayMsg);
1272+
if (pOwner)
1273+
{
1274+
pOwner->ItemBounce(pDeed, fDisplayMsg);
1275+
}
1276+
else
1277+
{
1278+
pChar->ItemBounce(pDeed, fDisplayMsg);
1279+
}
12641280
}
12651281
}
12661282
SetKeyNum("REMOVED", 1);

src/game/items/item_types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ enum IT_TYPE : int32_t // double click type action.
173173
IT_TRAIN_DUMMY, // 156
174174
IT_TRAIN_PICKPOCKET, // 157
175175
IT_BEDROLL, // 158
176-
IT_UNUSED_159, // 159
176+
IT_FLETCHING, // 159
177177
IT_HIDE, // 160 = hides are cured to make leather.
178178
IT_CLOTH_BOLT, // 161 = must be cut up to make cloth squares.
179179
IT_BOARD, // 162 = logs are plained into decent lumber
@@ -214,7 +214,7 @@ enum IT_TYPE : int32_t // double click type action.
214214
IT_PILOT, // 197 = ship's pilot (PacketWheelMove)
215215
IT_ROPE, // 198 = t_rope (working like t_ship_plank but without id changes)
216216
IT_WEAPON_WHIP, // 199
217-
217+
218218
// New SphereX hardcoded types starting from 300
219219
IT_SPAWN_CHAMPION = 300,// 300 = t_spawn_champion
220220
IT_MULTI_ADDON, // 301 = t_multi_addon

0 commit comments

Comments
 (0)