You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rebalance: port the "Summer Update 2025" combat & vocation overhaul to Crystal Server (15.25)
Tracking issue to implement the official Tibia balancing update (Combat Mode removal, stance rework, new spells, AoE rune/ammo changes, mitigation rework, Mana Buffer, etc.) on Crystal Server.
Source: official Tibia patch notes (Summer Update 2025 balancing changes). Values below are taken verbatim and must be matched exactly.
Cross-cutting systems -- design these FIRST
Important
These touch shared C++/combat code and are reused by many per-vocation tasks. Land them before the spell/value tweaks.
All characters: attack value +20%(Player::getAttackFactor 1.0->1.2)
All shields: defense value +30%(getDefense isSpellBook split x130/100)
All spellbooks: defense value +60%(getDefense isSpellBook split x160/100)
Where
parseFightModes in src/server/network/protocol/protocolgame.cpp; fightMode / attack-factor logic in src/creatures/players/player.cpp + src/creatures/combat/combat.cpp; shield/spellbook defense in data/items/items.xml.
Stance system
Replaces several spells (see per-vocation). Requirements:
Persist active stance(s) across sessions (return with the stance you logged out with) (Player::persistStances -> KV scoped "stance" (primary+elemental) in setStance/setElementalStance bindings; restored in login.lua via player:setStance/setElementalStance)
Allow no stance active (STANCE_NONE)
Only one stance active at a time -- except Sorcerer (one elemental + one crippling simultaneously) (server: separate slots m_stancePrimary[crippling] / m_stanceElemental, done; client: 2 frames at once DONE 2026-06-19, verified in-game -- 0xC1 sub-0x02 [u8 count][LE-u16 id]xN, whole-replace set)
Stance skill bonuses must affect total skill (including gear/potion bonuses), not just base (Lua CONDITION_PARAM_SKILL_*PERCENT flows through getSkillLevel = total)
Where
New C++ (conditions/flags on Player) + client UI hook; reuse the prior stance work if present.
Real 15.25 spell-ids extracted from the client (spells.json = zlib inside client.exe -> spells_1525.json): Protector 132, Blood Rage 133, Sharpshooter 313, Divine Defiance 314, Master of Flames/Thunder/Decay 304/305/306, Aura of Sapped/Exposed Strength/Weakness 311/312, Shared Conservation 309, Elemental Synthesis 319.
WORKS: highlight frames for all stances (toggle on); Sorcerer 2 frames at once (elemental + crippling); toggle-off removes only that frame; clear sends count 0 (never id 0) so no empty-slot lighting; skill%/buffs for Knight (Blood Rage, Protector) + Sharpshooter.
RESOLVED 2026-06-19 (RE wf_80e0a388 + in-game): dual-stance carrier = 0xC1 sub-0x02 [count][u16 ids] (NOT 0x5F SkillWheel; client whole-replaces the set -> resend full set every change). Empty-slot/clear bug fixed (count 0). Cooldown-group fix: crippling stances moved from group stance -> group crippling (Sap/Expose) so the elemental 30s stance group cooldown no longer blocks toggling crippling off; elemental stays on support+stance. (Lua: aura_of_*spell:group("support","crippling").)
Also fixed 2026-06-19: Cyclopedia DefenceStats (0xDA type 14) crash -- was a desync (server over-sent 7 bytes + a Winter-Update block the type-14 parser never reads); removed extra u16 0, the 6th mitigation double, and the Winter block.
TODO (effects -- separate C++ hooks): Sorcerer elemental conversions/crit, crippling aura-debuff, Divine Defiance dodge/holy-ML, Druid 2nd-party heal + ice/earth ML. Plus persistence (Phase 2).
Mana Buffer (Sorcerer + Druid)
If incoming damage would exceed current HP, the overkill is x8 and subtracted from mana; additionally 25% of max mana is consumed (this extra drain can trigger at most once per 2s). If mana runs out -> death (Sorc/Druid; game.cpp applyHealthChange; Player::m_manaBufferTaxTime gates the 25% to once/2s)
Re-tune the mitigation formula for the removed combat modes (fightFactor switch 0.8/1.0/1.2 -> fixed 1.0 in PlayerWheel::calculateMitigation; removes the attack-mode penalty)
Weapon type now has a much larger impact on mitigation (one-handed weapon now contributes its FULL getDefense() to mitigation, not just extraDefense — like two-handed; calculateMitigation)
Dedication perks: 0.03% -> 0.075% mitigation multiplier per promotion point (#define MITIGATION_INCREASE io_wheel.cpp:27)
Monster mitigation increased (Monster::getMitigation ×1.5 + cap 30->45)
Where
Player::getMitigation() / src/creatures/combat/combat.cpp; gems in src/creatures/players/wheel/wheel_gems.cpp; monster data in data/monster/.
New targeting modes
Build once, reuse for every new spell that needs it:
crosshair / cursor position / below-target (or below-self when no target) (WORKS in-game, needPosition architecture: the client appends the aim tile to the END of the say packet 0x96 [aimMode:u8][x:u16][y:u16][z][seq] (aimMode 1=cursor, 2=crosshair) — parseSay reads it → player; Spells::playerSaySpell passes it as the to parameter down to InstantSpell::playerCastInstant → branch else if (needPosition && to.x != 0) { var.pos = to } (VARIANT_POSITION) + playerInstantSpellCheck (range/LoS). needPosition flag = spells.hpp/cpp + spell_functions (Lua setter spell:needPosition(true)). 5 spells (Death Echo/Divine Barrage/Ethereal Barrage/Thousand Fist/Divine Grenade): needPosition(true) + onCastSpell = combat:execute(creature, var); Divine Grenade validates walkable/PZ via var:getPosition() + Tile:isWalkable(true). Patch D:\OTS\0001-feat-crosshair-cursor-position-spell-cast-15.25.patch = PRE-refactor [old getSpellAimPosition approach], needs regenerating. Temp debug g_logger().info("Test position") in playerCastInstant to be removed.)
Where
Spell targeting in src/creatures/combat/spells.cpp + protocol.
Wheel of Destiny augment swaps
Many spells swap augment slots -- do all wheel edits together(io_wheel.cpp: ALL feasible augment-value changes + 5 slot renames DONE+built (Shield Slam/Ethereal Barrage/Divine Barrage/Death Echo/Thousand Fist). DEFERRED: perks (Battle Healing, Combat Mastery, Beam Mastery, Lord of Destruction, Focus Mastery, Healing Link, Blessing of Grove, Sanctuary), area-enlarge Lua, Special Spells/Forked, Shield Slam II dmg-reduction)
AoE rune base power = 50 (areas unchanged): Avalanche (avalanche_rune.lua), Great Fireball, Thunderstorm, Stone Shower
Explosion rune area increased 5 -> 9 squares (explosion_rune.lua)
Charm double-proc fix: gate applyOffensiveCharmRune + Fatal Hold to attackedCreature (main target only) (Fatal Hold refined 2026-06-22: restriction applies ONLY to multi-target AoE damage.affected>1; single-target casts always proc on the actual hit target)
Gift of Life: additionally recovers 20 / 25 / 30% of max mana (checkGiftOfLife + combatChangeMana)
Group XP bonus: 2 different vocations 30% -> 35%; 3 different vocations 60% -> 70%
Energy Ring: consumes 2 mana per point of damage (was 1) (combatChangeHealth, manaShield==0 = ring)
Ultimate Healing rune and Intense Healing rune can no longer be used on other characters (self-only)
Potions
New Superior Mana Potion: 254 gold, 240-360 mana, level 100, usable by paladin/monk/sorcerer/druid (53162)
New Distilled Superior Mana Potion and Distilled Ultimate Mana Potion -- same effect as non-distilled, usable by all vocations, cost +50% gold (53163/53164, 381g/732g)
Great Mana Potions now usable by all vocations (item 238; kegs/casks separate -- TODO)
Knight
Stances (from promotion)
Bloodrage: +30% sword/axe/club fighting, +15% damage taken (affects total skill) -- toggle-stance utito tempo (id 133); SKILL_MELEEPERCENT=130 + BUFF_DAMAGERECEIVED=115 + DISABLE_DEFENSE; frame works
Protector: +30% shielding, -15% damage taken and -15% damage done -- toggle-stance utamo tempo (id 132); SKILL_SHIELDPERCENT=130 + BUFF_DAMAGEDEALT=85 + BUFF_DAMAGERECEIVED=85; frame works
Remove the old Bloodrage / Protector spells (replaced by stances) -- converted in place to toggle-stances
Mana cost
Berserk: 115 -> 125
Fierce Berserk: 340 -> 360
Groundshaker: 160 -> 200 (groundshaker.lua)
New spells (require a wielded shield)
Shield Bash: 55 base power, 4s cd, 30 mana, level 18. Hits target; damage based on shield defense; reduces target's next auto-attack damage by 50% (within 10s) (id 315, debuff = BUFF_DAMAGEDEALT 50 / 10s flat; dmg coeffs TUNABLE)
Shield Slam: 52 base power, 6s cd, 110 mana, level 30. Hits all adjacent enemies; same debuff as Shield Bash (id 316, self-area 3x3)
Healing
(now scales with magic level + shielding; base powers down, proficiency perks doubled)
Bruise Bane: base power 15(+shielding scaling, TUNABLE coeffs)
Wound Cleansing: base power 70(+shielding scaling, TUNABLE)
Fair Wound Cleansing: base power 225(+shielding scaling, TUNABLE)
Intense Wound Cleansing: base power 500, cooldown 10 -> 2 min (augment-80% cd = wheel, pending)
All knight healing spells: group cooldown 1s -> 2s
Existing spells
Chivalrous Challenge: jump range -> 7, now hits +1 additional target (5->6 targets, dist 7)
Front Sweep: base power 72 -> 80 (front_sweep.lua)
Wheel of Destiny
Front Sweep augments: I -> +40% base power; II -> shape +2 squares to the sides (total 5 affected squares) (I +40% io_wheel knight[0]; II area via combatWOD + getWheelSpellAdditionalArea in front_sweep.lua)
Shield Slam augments: I -> +15% life leech; II -> +25% damage reduction (total 75%). These replace Chivalrous Challenge I/II (I +15% leech + slots repointed io_wheel knight[2]; II via shield_slam.lua hook: upgradeSpellsWOD>=2 raises debuff to -75% (BUFF_DAMAGEDEALT 25))
Groundshaker: swap augment I <-> II; swap the wheel positions of Groundshaker and Shield Slam augments (swap I<->II DONE io_wheel knight[1]; slot position-swap = TODO)
Battle Healing reworked: +10% healing effect (x3 while wearing a shield); no longer heals when challenging (applyWheelOfDestinyHealing ×1.10/×1.30 via hasRealShield, ORIGIN_SPELL gate; heal-on-challenge removed from monster.cpp)
Combat Mastery reworked: take 1% less damage per 12/10/8% missing HP (doubled while wielding a shield); deal 1% more damage per 12/10/8% of target's missing HP (doubled while wielding a two-handed weapon) (rewrite in combatChangeHealth missing-HP; ×2 two-hand / real-shield, reduction capped 50%; old checkCombatMastery zeroed out)
Paladin
Stances (from promotion)
Sharpshooter: +40% distance fighting (affects total skill). Replaces the Sharpshooter spell (removed) -- toggle-stance utori con (id 313); SKILL_DISTANCEPERCENT=140; frame works
Divine Defiance: grants 7.5% of distance fighting as holy and healing magic level, plus 15% dodge against non-adjacent enemies -- toggle-stance utori hur (id 314); holy + healing ML DONE(getSpecializedMagicLevel: +7.5% SKILL_DISTANCE added when COMBAT_HOLYDAMAGE/HEALING); toggle effect-id 299; 15% dodge vs non-adjacent = still TODO
Swift Foot: now allows attacking/casting while active but damage -30%; individual cd 10 -> 4s, secondary group cd 10 -> 2s(BUFF_DAMAGEDEALT=70 at base grade)
Divine Caldera: base power 140 -> 160 (divine_caldera.lua)
Divine Barrage augments: I +10% base damage, II +15% base damage. Replace Swift Foot I/II (io_wheel paladin[3] + slots)
Ethereal Barrage augments: I +10% life leech, II +10% crit chance. Replace Sharpshooter I/II (io_wheel paladin[0] + slots)
Divine Dazzle augments: I now +2 targets (was +1); II now -8s cd (was -4s) (io_wheel paladin[2])
Sorcerer
Elemental stances (from promotion -- pick one)
Master of Flames: fire spells +4% base power; casting a fire spell converts the next non-fire spell to fire damage -- toggle-stance (id 304, uteta flam, effect-id 5); effect DONE(combat.cpp applyElementalStance: +base-power grade-scaled by Lord of Destruction; next-spell conversion via Player::m_pendingElementConversion state machine)
Master of Thunder: energy spells +4% crit chance; casting an energy spell converts the next non-energy spell to energy damage -- toggle-stance (id 305, uteta vis, effect-id 287); effect DONE(applyElementalStance: +crit chance grade-scaled; conversion via m_pendingElementConversion)
Master of Decay: death spells +30% crit extra damage; casting a death spell converts the next non-death spell to death damage -- toggle-stance (id 306, uteta mort, effect-id 285); effect DONE(applyElementalStance: +crit extra-damage grade-scaled; conversion via m_pendingElementConversion)
Note
Stance-VARIANT mechanic (user extension, 2026-06-22): beyond the +%/conversion above, every Sorcerer attack spell now reshapes its element + impact effect (+ missile) to match the active Master stance (e.g. Rage of the Skies energy->fire eff339 / death eff340; Flame Strike->energy/death; Death Strike->fire/energy, etc.). 18 spells done; Energy Beam(22) + Lightning(149) stay base. Pattern = rage_of_the_skies.lua; per-spell effect/missile table = D:\OTS\sorcerer_stance_variants.txt. Beams/echo retune element via setParameter per cast (single Combat, no callback-name collision); strikes/waves use per-variant Combats with unique callbacks. fire-strike variants emit TWO impact effects (COMBAT_PARAM_EFFECT + CALLBACK_PARAM_TARGETCREATURE).
Crippling stances (unlock at level 175 -- pick one; can be active alongside one elemental stance)
Sap Strength: your spells/runes/auto-attacks apply Sap Strength (target deals -10% damage) -- toggle-stance Aura of Sapped Strengthexori moe tempo (id 311, effect-id 311); aura DONE(combat.cpp applyCripplingStanceAura: CONDITION_PARAM_BUFF_DAMAGEDEALT=90 on every enemy you damage)
Expose Weakness: your spells/runes/auto-attacks apply Expose Weakness (attackers gain +8% elemental pierce) -- toggle-stance Aura of Exposed Weaknessexori kor tempo (id 312, effect-id 288); aura DONE *(applyCripplingStanceAura: ABSORB_PERCENT=-8 on every enemy you damage)
Remove the old Sap Strength / Expose Weakness spells (replaced by stances) -- old exori moe/exori kor reverted to plain debuff spells (NOT removed); new Aura stances added as separate spells
New spell (3 targeting modes)
Death Echo: 85 base power, 6s cd, 155 mana, level 120. Hits a 5x5 area; after a 1s delay the same area is hit again for 50% of the initial damage (id 310, echo via addEvent 1000ms, 2nd hit independent 50% roll)
Existing spells
Great Death Beam: becomes a regular spell, learnable from level 66 (great_death_beam.lua) (WoD-gate removed)
Lightning: now chains to 2 additional targets; base power 70 -> 110, range 5 -> 7 (lightning.lua) (CHAIN_EFFECT + getChainValue 3,5)
Strong Energy Strike: base 90 -> 125, range 3 -> 7
Strong Flame Strike: base 90 -> 125, range 3 -> 7
Ultimate Energy Strike: base 150 -> 210, range 3 -> 7
Ultimate Flame Strike: base 150 -> 210, range 3 -> 7
Wands
Remove the numerous Strike imbuement limitations (items.xml: normalized 44 wand/rod imbuement sets to crit / life leech / mana leech / skillboost magic level)
Attacks generate mana instead of consuming it (weapons.cpp onUsedWeapon: wand/rod adds mana = old per-shot cost)
Increase range (already matched Tibiopedia ranges in items.xml -- verified)
Wheel of Destiny
Special Spells augments: I -4s cd, II +50% base damage. Replace Magic Shield I/II (io_wheel: Any_Special_Mage_Spell case + m_specialSpells (Strong/Ultimate Energy/Flame/Ice/Terra Strike); sorcerer[0] + slots repointed Magic Shield -> Any_Special_Mage_Spell)
Death Echo augments: I -2s cd, II +8% base damage. Replace Sap Strength I/II (io_wheel sorcerer[1] + slots)
Beam Mastery reworked: beam now hits adjacent squares for 40/60/80% of initial damage; still increases damage & reduces cd based on targets hit by the central beam (per user: two identical parallel beams left+right of the main one; second flank combat per beam spell scaled 40/60/80% by revelationStageWOD("Beam Mastery"); great_death_beam/energy_beam/great_energy_beam. Orthogonal flank; diagonal energy-beam casts approximate)
Lord of Destruction replaces Drain Body -- improves elemental-stance buffs: Master of Flames +2/3/4% base power (total +6/7/8%); Master of Thunder +2/3/4% crit chance (total +6/7/8%); Master of Decay +15/22.5/30% crit extra damage (total 45/52.5/60%) (combat.cpp applyElementalStance grade-scales via getStage(DRAIN_BODY) 0..3, grade 0 = base; Drain Body leech REMOVED 2026-06-22 -- checkDrainBodyLeech() -> 0, the Drain Body stage now ONLY scales the elemental stances, no more life/mana leech)
Focus Mastery: additionally reduces focus-spell group cd by 2s (spells.cpp: -2000ms on SPELLGROUP_FOCUS secondary-group cd when Focus Mastery active)
Energy Wave augments I/II switched: I -> area enlarged; II -> +10% base damage (was 5%) (io_wheel sorcerer[2]; II +10% DONE, I area=true set)
Druid
Stances (from promotion)
Shared Conservation: Heal Friend and Nature's Embrace also heal a secondary party target in the game window for 30% of their healing (cannot be the same target); +10% self-healing -- toggle-stance (id 309, utura sio, effect-id 287); effect DONE(2nd-party 30% heal in heal_friend.lua + nature's_embrace.lua via Variant(best:getId()); +10% self in player.cpp)
Elemental Synthesis: grants 10% of magic level as additional ice & earth magic level -- toggle-stance (id 319, utito dru, effect-id 388); effect DONE(getSpecializedMagicLevel: +10% magic level when COMBAT_ICEDAMAGE/EARTHDAMAGE)
Wrath of Nature: base damage 150 -> 175 (wrath_of_nature.lua) — value done; "more consistent" (min/max narrowing) NOT done
Rods
Remove the numerous Strike imbuement limitations (items.xml: normalized 44 wand/rod imbuement sets to crit / life leech / mana leech / skillboost magic level)
Attacks generate mana instead of consuming it (weapons.cpp onUsedWeapon: wand/rod adds mana = old per-shot cost)
Increase range (already matched Tibiopedia ranges in items.xml -- verified)
Wheel of Destiny
Forked Spells augments: I -2s cd, II +1 target -- improve both Forked Glacier & Forked Thorns (io_wheel: Any_Forked_Spell case + druid[2] repurposed (Nature's Embrace removed from new wheel); +1 target via getWheelSpellAdditionalTarget in forked_.lua)*
Heal Friend augments: I +4% base heal, II +6% base heal (io_wheel druid[4])
Terra Wave augment II -> 10% life leech (was 5%) (io_wheel druid[3])
Strong Ice Wave augments: I +6% base damage, II area enlarged (I +6% io_wheel druid[0]; II area via combatWOD + getWheelSpellAdditionalArea in strong_ice_wave.lua)
Healing Link now heals you for 25% of Nature's Embrace / Heal Friend (was 10%) (player_wheel.cpp: damage.healingLink 10 -> 25)
Blessing of the Grove: healing spells can now critically heal (use crit chance + crit extra damage); extra healing 5 / 7.5 / 10% vs targets below 60% HP, doubled vs targets below 30% HP (checkBlessingGroveHealingByTarget int32_t->double 5/7.5/10 & 10/15/20; crit-heal roll in applyWheelOfDestinyHealing, damage.critical=true; crit-heal VISUAL DONE 2026-06-22 -- CONST_ME_CRITICAL_DAMAGE shown in combatChangeHealth heal branch when damage.critical)
Monk
Virtues -- now also buff nearby party members
Knight present: -3% damage received. Paladin: +6% auto-attack damage. Sorcerer: +6% spell & rune damage. Druid: +12% healing done (interpretation A per user: each party member within 5 tiles of the monk gets the buff for THEIR OWN vocation; serene monk gets the union. Player::m_monkAuraVocMask + Game::projectMonkVirtueAura on the 1s serene tick; buffs applied in combatChangeHealth + applyImproveMonkHealing)
Remove Mentor Other (compensation for the above) (mentor_other.lua spell unregistered)
While serene, the monk benefits from the same bonuses as long as the respective vocation is present (projectMonkVirtueAura sets the monk's own mask to the union of present vocations only when isSerene())
New spell (3 targeting modes)
Thousand Fist Blows: 62 base power, 12s cd, 145 mana, level 120. Builder spell; hits target + surrounding area (id 301, addHarmony(1), elemental-bond phys/energy/earth, AREA_CIRCLE3X3, words "exori mas amp pug")
Other
Way of the Monk quest bonuses expanded: in addition to up to 100% increased auto-attack damage, each shrine now grants +2% damage reduction vs melee auto-attacks, up to 20% total (per user: ONLY the +2%/shrine melee reduction added (cap 20%, 10 shrines), NOT the +100% auto-attack. combatChangeHealth: monk targetPlayer + ORIGIN_MELEE; Player::getMonkShrineCount reads quests/the_way_of_the_monk_quest/shrineCounter)
Mass Spirit Mend: no longer a spender spell (adjust cd, base power, icon accordingly); caster receives only a lesser effect (~ a regular Spirit Mend) (de-spender DONE: removed spell:harmony(true) + harmony multiplier + harmonySpells membership; caster gets Spirit-Mend formula. Icon / cd / exact base power = decision pending)
Mystic Repulse: base power 72 -> 85, cooldown 20 -> 12s (mystic_repulse.lua)
Chained Penance & Spiritual Outburst: jump range +1; now chain to the closest target (was highest health %) (chained_penance.lua, spiritual_outburst.lua) (range 2->3; both already select closest by path length)
Monk familiar is now better at hitting enemies with its spells (higher cast chance + range on its spell attacks: energy 45->65% range 5->6, physical 15->35% range 6, wave 30->45%; data-global/monster/familiars/monk_familiar.lua)
Wheel of Destiny
Thousand Fist Blows augments: I +40% crit extra damage, II -6s cd. Replace Sweeping Takedown I/II (io_wheel monk[4] + slots)
Flurry of Blows augment I -> enlarges the affected area (was +5% life leech) (area via combatWOD + getWheelSpellAdditionalArea in flurry_of_blows.lua, io_wheel monk[3])
Guiding Presence: now shares 100% of the mantra effect (was 50%) (already 100% in code: Player::getMantraAbsorbPercent multiplier = 1.0f)
[~] Sanctuary: additionally +10% damage to adjacent enemies and +10% healing to adjacent allies (adjacency ×1.10 LAYERED on the existing harmony Sanctuary in both applyWheelOfDestinyEffectsToDamage + applyWheelOfDestinyHealing, Chebyshev<=1 to the monk; layer-vs-replace decision pending)
Mystic Repulse augment I -> -6s cd (was -4s) (io_wheel monk[1])
Mass Spirit Mend augment II -> -4s cd (was area enlarge) (io_wheel monk[0])
Suggested implementation order
Section 0 cross-cutting systems (combat mode removal, stance framework, mana buffer, mitigation, targeting modes, wheel-edit pass)
General value tweaks (runes, potions, rings, charms, group XP) -- mostly data/Lua, low risk
Per-vocation spell value changes (base power / mana / cd / range) -- data/Lua
New spells (use the targeting-mode framework) + new items (ammo, potions)
Rebalance: port the "Summer Update 2025" combat & vocation overhaul to Crystal Server (15.25)
Source: official Tibia patch notes (Summer Update 2025 balancing changes). Values below are taken verbatim and must be matched exactly.
Cross-cutting systems -- design these FIRST
Important
These touch shared C++/combat code and are reused by many per-vocation tasks. Land them before the spell/value tweaks.
Combat Mode removal
Fight modes (offensive / balanced / defensive) are gone. Compensation, applied globally:
Where
parseFightModesinsrc/server/network/protocol/protocolgame.cpp; fightMode / attack-factor logic insrc/creatures/players/player.cpp+src/creatures/combat/combat.cpp; shield/spellbook defense indata/items/items.xml.Stance system
Replaces several spells (see per-vocation). Requirements:
m_stancePrimary[crippling] /m_stanceElemental, done; client: 2 frames at once DONE 2026-06-19, verified in-game -- 0xC1 sub-0x02[u8 count][LE-u16 id]xN, whole-replace set)CONDITION_PARAM_SKILL_*PERCENTflows through getSkillLevel = total)Where
New C++ (conditions/flags on
Player) + client UI hook; reuse the prior stance work if present.Note
Implementation progress -- Stance system (Phase 1, 2026-06-17; dual-stance frames + clear DONE & verified in-game 2026-06-19).
enum Stance_t,Player::m_stancePrimary+m_stanceElemental(Sorcerer dual-slot),setStance/setElementalStance,getStanceSpellId(REAL 15.25 client ids),sendStanceProtocol(std::vector<uint16_t>)(0xC1 sub-0x02,[u8 count][LE-u16 id]xN, whole-replace set),Player::buildActiveStanceSpellIds()(collects primary+elemental, skips STANCE_NONE/0),SPELLGROUP_STANCE, Lua bindings. Stance spells are toggles indata/scripts/spells/support/.client.exe->spells_1525.json): Protector 132, Blood Rage 133, Sharpshooter 313, Divine Defiance 314, Master of Flames/Thunder/Decay 304/305/306, Aura of Sapped/Exposed Strength/Weakness 311/312, Shared Conservation 309, Elemental Synthesis 319.[count][u16 ids](NOT 0x5F SkillWheel; client whole-replaces the set -> resend full set every change). Empty-slot/clear bug fixed (count 0). Cooldown-group fix: crippling stances moved from groupstance-> groupcrippling(Sap/Expose) so the elemental 30sstancegroup cooldown no longer blocks toggling crippling off; elemental stays onsupport+stance. (Lua:aura_of_*spell:group("support","crippling").)u16 0, the 6th mitigation double, and the Winter block.Mana Buffer (Sorcerer + Druid)
Where
Creature::onTakeDamage/Player::blockHit/Combat::doCombatHealth.Mitigation rework (after combat-mode removal)
PlayerWheel::calculateMitigation; removes the attack-mode penalty)getDefense()to mitigation, not just extraDefense — like two-handed;calculateMitigation)0.03%->0.075%mitigation multiplier per promotion point (#define MITIGATION_INCREASEio_wheel.cpp:27)5 / 5.5 / 6 / 7.5%->20 / 22 / 24 / 30%mitigation multiplier (wheel_gems.cpp500*mult->2000*mult; /100 w getMitigationMultiplier)Monster::getMitigation×1.5 + cap 30->45)Where
Player::getMitigation()/src/creatures/combat/combat.cpp; gems insrc/creatures/players/wheel/wheel_gems.cpp; monster data indata/monster/.New targeting modes
Build once, reuse for every new spell that needs it:
[aimMode:u8][x:u16][y:u16][z][seq](aimMode 1=cursor, 2=crosshair) — parseSay reads it → player;Spells::playerSaySpellpasses it as thetoparameter down toInstantSpell::playerCastInstant→ branchelse if (needPosition && to.x != 0) { var.pos = to }(VARIANT_POSITION) + playerInstantSpellCheck (range/LoS).needPositionflag = spells.hpp/cpp + spell_functions (Lua setterspell:needPosition(true)). 5 spells (Death Echo/Divine Barrage/Ethereal Barrage/Thousand Fist/Divine Grenade):needPosition(true)+ onCastSpell =combat:execute(creature, var); Divine Grenade validates walkable/PZ viavar:getPosition()+Tile:isWalkable(true). PatchD:\OTS\0001-feat-crosshair-cursor-position-spell-cast-15.25.patch= PRE-refactor [old getSpellAimPosition approach], needs regenerating. Temp debugg_logger().info("Test position")in playerCastInstant to be removed.)Where
Spell targeting in
src/creatures/combat/spells.cpp+ protocol.Wheel of Destiny augment swaps
Where
src/creatures/players/wheel/player_wheel.cpp,wheel_definitions.hpp,src/enums/player_wheel.hpp.Where things live (quick map)
data/scripts/spells/{attack,healing,support}/*.luadata/scripts/spells/conjuring/*_rune.lua, rune items indata/items/items.xmldata/XML/vocations.xmldata/items/items.xml, shops indata/npc/*.luasrc/creatures/players/wheel/,src/enums/player_wheel.hpp,src/io/io_wheel.cppsrc/creatures/combat/combat.cpp,src/creatures/players/player.cppsrc/creatures/players/GENERAL General
avalanche_rune.lua), Great Fireball, Thunderstorm, Stone Shower5->9squares (explosion_rune.lua)damage.affected>1; single-target casts always proc on the actual hit target)20 / 25 / 30%of max mana (checkGiftOfLife + combatChangeMana)30%->35%; 3 different vocations60%->70%Potions
Knight
Stances (from promotion)
utito tempo(id 133); SKILL_MELEEPERCENT=130 + BUFF_DAMAGERECEIVED=115 + DISABLE_DEFENSE; frame worksutamo tempo(id 132); SKILL_SHIELDPERCENT=130 + BUFF_DAMAGEDEALT=85 + BUFF_DAMAGERECEIVED=85; frame worksMana cost
115->125340->360160->200(groundshaker.lua)New spells (require a wielded shield)
Healing
(now scales with magic level + shielding; base powers down, proficiency perks doubled)
10->2min (augment-80% cd = wheel, pending)1s->2sExisting spells
72->80(front_sweep.lua)Wheel of Destiny
Paladin
Stances (from promotion)
utori con(id 313); SKILL_DISTANCEPERCENT=140; frame worksutori hur(id 314); holy + healing ML DONE (getSpecializedMagicLevel: +7.5% SKILL_DISTANCE added when COMBAT_HOLYDAMAGE/HEALING); toggle effect-id 299; 15% dodge vs non-adjacent = still TODONew spells (3 targeting modes: crosshair / cursor / below target)
New AoE ammunition (hits 13 squares)
(items in
items.xml+ shops)Existing spells
10->4s, secondary group cd10->2s(BUFF_DAMAGEDEALT=70 at base grade)140->160(divine_caldera.lua)400->500divine_grenade.lua) (aim crosshair/cursor/direction + walkable/PZ validation (Tile:isWalkable(true)) + isAggressive + WoD gate removed + needPosition)Wheel of Destiny
Sorcerer
Elemental stances (from promotion -- pick one)
uteta flam, effect-id 5); effect DONE (combat.cpp applyElementalStance: +base-power grade-scaled by Lord of Destruction; next-spell conversion via Player::m_pendingElementConversion state machine)uteta vis, effect-id 287); effect DONE (applyElementalStance: +crit chance grade-scaled; conversion via m_pendingElementConversion)uteta mort, effect-id 285); effect DONE (applyElementalStance: +crit extra-damage grade-scaled; conversion via m_pendingElementConversion)Note
Stance-VARIANT mechanic (user extension, 2026-06-22): beyond the +%/conversion above, every Sorcerer attack spell now reshapes its element + impact effect (+ missile) to match the active Master stance (e.g. Rage of the Skies energy->fire eff339 / death eff340; Flame Strike->energy/death; Death Strike->fire/energy, etc.). 18 spells done; Energy Beam(22) + Lightning(149) stay base. Pattern =
rage_of_the_skies.lua; per-spell effect/missile table =D:\OTS\sorcerer_stance_variants.txt. Beams/echo retune element viasetParameterper cast (single Combat, no callback-name collision); strikes/waves use per-variant Combats with unique callbacks. fire-strike variants emit TWO impact effects (COMBAT_PARAM_EFFECT + CALLBACK_PARAM_TARGETCREATURE).Crippling stances (unlock at level 175 -- pick one; can be active alongside one elemental stance)
exori moe tempo(id 311, effect-id 311); aura DONE (combat.cpp applyCripplingStanceAura: CONDITION_PARAM_BUFF_DAMAGEDEALT=90 on every enemy you damage)exori kor tempo(id 312, effect-id 288); aura DONE *(applyCripplingStanceAura: ABSORB_PERCENT=-8 on every enemy you damage)exori moe/exori korreverted to plain debuff spells (NOT removed); new Aura stances added as separate spellsNew spell (3 targeting modes)
Existing spells
great_death_beam.lua) (WoD-gate removed)70->110, range5->7(lightning.lua) (CHAIN_EFFECT + getChainValue 3,5)90->125, range3->790->125, range3->7150->210, range3->7150->210, range3->7Wands
Wheel of Destiny
Druid
Stances (from promotion)
utura sio, effect-id 287); effect DONE (2nd-party 30% heal in heal_friend.lua + nature's_embrace.lua via Variant(best:getId()); +10% self in player.cpp)utito dru, effect-id 388); effect DONE (getSpecializedMagicLevel: +10% magic level when COMBAT_ICEDAMAGE/EARTHDAMAGE)Healing
650->2000New spells
Existing spells
90->115, range3->790->115, range3->7150->195, range3->7150->195, range3->74s, size increased (strong_ice_wave.lua) (SHORTWAVE3 -> SQUAREWAVE5)150->175(wrath_of_nature.lua) — value done; "more consistent" (min/max narrowing) NOT doneRods
Wheel of Destiny
Monk
Virtues -- now also buff nearby party members
New spell (3 targeting modes)
Other
72->85, cooldown20->12s(mystic_repulse.lua)chained_penance.lua,spiritual_outburst.lua) (range 2->3; both already select closest by path length)Wheel of Destiny
Suggested implementation order
Suggested labels
rebalance|vocations|spells|wheel-of-destiny|combat|items|needs-design(Section 0)