diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp index a9684111b01..a84ccb811dc 100644 --- a/engines/dm/champion.cpp +++ b/engines/dm/champion.cpp @@ -1163,6 +1163,32 @@ int16 ChampionMan::f310_getMovementTicks(Champion* champ) { return L0933_i_Ticks; } +bool ChampionMan::f294_isAmmunitionCompatibleWithWeapon(uint16 champIndex, uint16 weaponSlotIndex, uint16 ammunitionSlotIndex) { + Champion* L0874_ps_Champion; + WeaponInfo* L0875_ps_WeaponInfo; + Thing L0878_T_Thing; + int16 L0879_i_WeaponClass; + + L0874_ps_Champion = &_vm->_championMan->_gK71_champions[champIndex]; + L0878_T_Thing = L0874_ps_Champion->_slots[weaponSlotIndex]; + if (L0878_T_Thing.getType() != k5_WeaponThingType) { + return false; + } + L0875_ps_WeaponInfo = _vm->_dungeonMan->f158_getWeaponInfo(L0878_T_Thing); + if ((L0875_ps_WeaponInfo->_class >= k16_WeaponClassFirstBow) && (L0875_ps_WeaponInfo->_class <= k31_WeaponClassLastBow)) { + L0879_i_WeaponClass = k10_WeaponClassBowAmmunition; + } else { + if ((L0875_ps_WeaponInfo->_class >= k32_WeaponClassFirstSling) && (L0875_ps_WeaponInfo->_class <= k47_WeaponClassLastSling)) { + L0879_i_WeaponClass = k11_WeaponClassSlingAmmunition; + } else { + return false; + } + } + L0878_T_Thing = L0874_ps_Champion->_slots[ammunitionSlotIndex]; + L0875_ps_WeaponInfo = _vm->_dungeonMan->f158_getWeaponInfo(L0878_T_Thing); + return ((L0878_T_Thing.getType() == k5_WeaponThingType) && (L0875_ps_WeaponInfo->_class == L0879_i_WeaponClass)); +} + ChampionIndex ChampionMan::f285_getIndexInCell(int16 cell) { for (uint16 i = 0; i < _g305_partyChampionCount; ++i) { if ((_gK71_champions[i]._cell == cell) && _gK71_champions[i]._currHealth) diff --git a/engines/dm/champion.h b/engines/dm/champion.h index 16c53c8c587..17686f91f9c 100644 --- a/engines/dm/champion.h +++ b/engines/dm/champion.h @@ -521,7 +521,8 @@ public: void f317_addScentStrength(int16 mapX, int16 mapY, int32 cycleCount); // @ F0317_CHAMPION_AddScentStrength void f297_putObjectInLeaderHand(Thing thing, bool setMousePointer); // @ F0297_CHAMPION_PutObjectInLeaderHand int16 f310_getMovementTicks(Champion *champ); // @ F0310_CHAMPION_GetMovementTicks - + bool f294_isAmmunitionCompatibleWithWeapon(uint16 champIndex, uint16 weaponSlotIndex, + uint16 ammunitionSlotIndex); // @ F0294_CHAMPION_IsAmmunitionCompatibleWithWeapon diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp index a34fc4921df..85aadcbb672 100644 --- a/engines/dm/timeline.cpp +++ b/engines/dm/timeline.cpp @@ -37,6 +37,52 @@ namespace DM { +signed char g495_actionDefense[44] = { // @ G0495_ac_Graphic560_ActionDefense + 0, /* N */ + 36, /* BLOCK */ + 0, /* CHOP */ + 0, /* X */ + -4, /* BLOW HORN */ + -10, /* FLIP */ + -10, /* PUNCH */ + -5, /* KICK */ + 4, /* WAR CRY */ + -20, /* STAB */ + -15, /* CLIMB DOWN */ + -10, /* FREEZE LIFE */ + 16, /* HIT */ + 5, /* SWING */ + -15, /* STAB */ + -17, /* THRUST */ + -5, /* JAB */ + 29, /* PARRY */ + 10, /* HACK */ + -10, /* BERZERK */ + -7, /* FIREBALL */ + -7, /* DISPELL */ + -7, /* CONFUSE */ + -7, /* LIGHTNING */ + -7, /* DISRUPT */ + -5, /* MELEE */ + -15, /* X */ + -9, /* INVOKE */ + 4, /* SLASH */ + 0, /* CLEAVE */ + 0, /* BASH */ + 5, /* STUN */ + -15, /* SHOOT */ + -7, /* SPELLSHIELD */ + -7, /* FIRESHIELD */ + 8, /* FLUXCAGE */ + -20, /* HEAL */ + -5, /* CALM */ + 0, /* LIGHT */ + -15, /* WINDOW */ + -7, /* SPIT */ + -4, /* BRANDISH */ + 0, /* THROW */ + 8}; /* FUSE */ + Timeline::Timeline(DMEngine* vm) : _vm(vm) { _g369_eventMaxCount = 0; _g370_events = nullptr; @@ -280,7 +326,7 @@ void Timeline::f261_processTimeline() { } break; case k11_TMEventTypeEnableChampionAction: - //F0253_TIMELINE_ProcessEvent11Part1_EnableChampionAction(L0682_s_Event._priority); + f253_timelineProcessEvent11Part1_enableChampionAction(L0682_s_Event._priority); if (L0682_s_Event._B._slotOrdinal) { //F0259_TIMELINE_ProcessEvent11Part2_MoveWeaponFromQuiverToSlot(L0682_s_Event._priority, _vm->M1_ordinalToIndex(L0682_s_Event._B._slotOrdinal)); } @@ -877,4 +923,33 @@ void Timeline::f246_timelineProcesEvent65_enableGroupGenerator(TimelineEvent* ev L0620_T_Thing = _vm->_dungeonMan->f159_getNextThing(L0620_T_Thing); } } + +void Timeline::f253_timelineProcessEvent11Part1_enableChampionAction(uint16 champIndex) { + int16 L0660_i_SlotIndex; + int16 L0661_i_QuiverSlotIndex; + Champion* L0662_ps_Champion; + + L0662_ps_Champion = &_vm->_championMan->_gK71_champions[champIndex]; + L0662_ps_Champion->_enableActionEventIndex = -1; + clearFlag(L0662_ps_Champion->_attributes, k0x0008_ChampionAttributeDisableAction); + if (L0662_ps_Champion->_actionIndex != k255_ChampionActionNone) { + L0662_ps_Champion->_actionDefense -= g495_actionDefense[L0662_ps_Champion->_actionDefense]; + } + if (L0662_ps_Champion->_currHealth) { + if ((L0662_ps_Champion->_actionIndex == k32_ChampionActionShoot) && (L0662_ps_Champion->_slots[k0_ChampionSlotReadyHand] == Thing::_none)) { + if (_vm->_championMan->f294_isAmmunitionCompatibleWithWeapon(champIndex, k1_ChampionSlotActionHand, L0660_i_SlotIndex = k12_ChampionSlotQuiverLine_1_1)) { +T0253002: + _vm->_championMan->f301_addObjectInSlot((ChampionIndex)champIndex, _vm->_championMan->f300_getObjectRemovedFromSlot(champIndex, L0660_i_SlotIndex), k0_ChampionSlotReadyHand); + } else { + for (L0661_i_QuiverSlotIndex = 0; L0661_i_QuiverSlotIndex < 3; L0661_i_QuiverSlotIndex++) { + if (_vm->_championMan->f294_isAmmunitionCompatibleWithWeapon(champIndex, k1_ChampionSlotActionHand, L0660_i_SlotIndex = L0661_i_QuiverSlotIndex + k7_ChampionSlotQuiverLine_2_1)) + goto T0253002; + } + } + } + setFlag(L0662_ps_Champion->_attributes, k0x8000_ChampionAttributeActionHand); + _vm->_championMan->f292_drawChampionState((ChampionIndex)champIndex); + } + L0662_ps_Champion->_actionIndex = k255_ChampionActionNone; +} } diff --git a/engines/dm/timeline.h b/engines/dm/timeline.h index 02e13a5e956..f6f61ee808c 100644 --- a/engines/dm/timeline.h +++ b/engines/dm/timeline.h @@ -94,6 +94,8 @@ k82_TMEventTypeMagicMap_C82 = 82, // @ C82_EVENT_MAGIC_MAP k83_TMEventTypeMagicMap_C83 = 83 // @ C83_EVENT_MAGIC_MAP }; +extern signed char g495_actionDefense[44]; + class TimelineEvent { public: int32 _mapTime; @@ -175,6 +177,7 @@ public: void f245_timlineProcessEvent5_squareCorridor(TimelineEvent *event); // @ F0245_TIMELINE_ProcessEvent5_Square_Corridor void f252_timelineProcessEvents60to61_moveGroup(TimelineEvent *event); // @ F0252_TIMELINE_ProcessEvents60to61_MoveGroup void f246_timelineProcesEvent65_enableGroupGenerator(TimelineEvent *event); // @ F0246_TIMELINE_ProcessEvent65_EnableGroupGenerator + void f253_timelineProcessEvent11Part1_enableChampionAction(uint16 champIndex); // @ F0253_TIMELINE_ProcessEvent11Part1_EnableChampionAction };