2016-07-07 00:46:51 +02:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
*/
/*
* Based on the Reverse Engineering work of Christophe Fontanel ,
* maintainer of the Dungeon Master Encyclopaedia ( http : //dmweb.free.fr/)
*/
# include "projexpl.h"
# include "dungeonman.h"
# include "timeline.h"
# include "group.h"
# include "objectman.h"
# include "movesens.h"
namespace DM {
ProjExpl : : ProjExpl ( DMEngine * vm ) : _vm ( vm ) {
2016-08-26 22:50:01 +02:00
_g364_creatureDamageOutcome = 0 ;
_g363_secondaryDirToOrFromParty = 0 ;
2016-07-07 00:46:51 +02:00
_g361_lastCreatureAttackTime = - 200 ;
2016-08-26 22:50:01 +02:00
_g365_createLanucherProjectile = false ;
_g366_projectilePoisonAttack = 0 ;
_g367_projectileAttackType = 0 ;
_g362_lastPartyMovementTime = 0 ;
2016-07-07 00:46:51 +02:00
}
void ProjExpl : : f212_projectileCreate ( Thing thing , int16 mapX , int16 mapY , uint16 cell , direction dir , byte kineticEnergy , byte attack , byte stepEnergy ) {
Thing L0466_T_ProjectileThing ;
Projectile * L0467_ps_Projectile ;
TimelineEvent L0468_s_Event ;
if ( ( L0466_T_ProjectileThing = _vm - > _dungeonMan - > f166_getUnusedThing ( k14_ProjectileThingType ) ) = = Thing : : _none ) { /* BUG0_16 If the game cannot create a projectile thing because it has run out of such things (60 maximum) then the object being thrown/shot/launched is orphaned. If the game has run out of projectile things it will try to remove a projectile from elsewhere in the dungeon, except in an area of 11x11 squares centered around the party (to make sure the player cannot actually see the thing disappear on screen) */
return ;
}
L0466_T_ProjectileThing = M15_thingWithNewCell ( L0466_T_ProjectileThing , cell ) ;
2016-07-07 23:27:13 +02:00
L0467_ps_Projectile = ( Projectile * ) _vm - > _dungeonMan - > f156_getThingData ( L0466_T_ProjectileThing ) ;
2016-07-07 00:46:51 +02:00
L0467_ps_Projectile - > _slot = thing ;
L0467_ps_Projectile - > _kineticEnergy = MIN ( ( int16 ) kineticEnergy , ( int16 ) 255 ) ;
L0467_ps_Projectile - > _attack = attack ;
_vm - > _dungeonMan - > f163_linkThingToList ( L0466_T_ProjectileThing , Thing ( 0 ) , mapX , mapY ) ; /* Projectiles are added on the square and not 'moved' onto the square. In the case of a projectile launcher sensor, this means that the new projectile traverses the square in front of the launcher without any trouble: there is no impact if it is a wall, the projectile direction is not changed if it is a teleporter. Impacts with creatures and champions are still processed */
M33_setMapAndTime ( L0468_s_Event . _mapTime , _vm - > _dungeonMan - > _g272_currMapIndex , _vm - > _g313_gameTime + 1 ) ;
if ( _g365_createLanucherProjectile ) {
L0468_s_Event . _type = k49_TMEventTypeMoveProjectile ; /* Launcher projectiles can impact immediately */
} else {
L0468_s_Event . _type = k48_TMEventTypeMoveProjectileIgnoreImpacts ; /* Projectiles created by champions or creatures ignore impacts on their first movement */
}
L0468_s_Event . _priority = 0 ;
2016-07-07 23:14:40 +02:00
L0468_s_Event . _B . _slot = L0466_T_ProjectileThing . toUint16 ( ) ;
2016-07-07 00:46:51 +02:00
L0468_s_Event . _C . _projectile . setMapX ( mapX ) ;
L0468_s_Event . _C . _projectile . setMapY ( mapY ) ;
L0468_s_Event . _C . _projectile . setStepEnergy ( stepEnergy ) ;
L0468_s_Event . _C . _projectile . setDir ( dir ) ;
L0467_ps_Projectile - > _eventIndex = _vm - > _timeline - > f238_addEventGetEventIndex ( & L0468_s_Event ) ;
}
bool ProjExpl : : f217_projectileHasImpactOccurred ( int16 impactType , int16 mapXCombo , int16 mapYCombo , int16 cell , Thing projectileThing ) {
# define AP0454_i_ProjectileTargetMapX mapXCombo
# define AP0455_i_ProjectileTargetMapY mapYCombo
# define AP0456_i_ChampionIndex cell
Projectile * L0490_ps_Projectile ;
Group * L0491_ps_Group ;
Thing L0486_T_ProjectileAssociatedThing ;
int16 L0487_i_Multiple ;
# define AL0487_i_DoorState L0487_i_Multiple
# define AL0487_i_IconIndex L0487_i_Multiple
# define AL0487_i_Outcome L0487_i_Multiple
# define AL0487_i_WeaponType L0487_i_Multiple
int16 L0488_i_Attack = 0 ;
Potion * L0492_ps_Potion = nullptr ;
CreatureInfo * L0493_ps_CreatureInfo ;
Door * L0494_ps_Door ;
Weapon * L0495_ps_Weapon ;
uint16 * L0496_pui_CreatureHealth ;
Thing * L0497_pT_GroupSlot ;
Thing L0498_T_ExplosionThing ;
int16 L0499_i_ProjectileMapX ;
int16 L0500_i_ProjectileMapY ;
int16 L0501_i_MapXCombo ;
int16 L0502_i_MapYCombo ;
byte L0503_uc_Square ;
bool L0505_B_CreateExplosionOnImpact ;
int16 L0489_i_ChampionAttack ;
uint16 L0507_ui_Multiple ;
# define AL0507_ui_ExplosionAttack L0507_ui_Multiple
# define AL0507_ui_SoundIndex L0507_ui_Multiple
int16 L0508_i_PotionPower = 0 ;
bool L0509_B_RemovePotion ;
int16 L0510_i_ProjectileAssociatedThingType ;
uint16 L0511_ui_CreatureType ;
uint16 L0512_ui_CreatureIndex ;
2016-07-07 23:27:13 +02:00
L0490_ps_Projectile = ( Projectile * ) _vm - > _dungeonMan - > f156_getThingData ( Thing ( projectileThing ) ) ;
2016-07-07 00:46:51 +02:00
L0501_i_MapXCombo = mapXCombo ;
L0502_i_MapYCombo = mapYCombo ;
L0509_B_RemovePotion = false ;
_g364_creatureDamageOutcome = k0_outcomeKilledNoCreaturesInGroup ;
if ( ( L0510_i_ProjectileAssociatedThingType = ( L0486_T_ProjectileAssociatedThing = L0490_ps_Projectile - > _slot ) . getType ( ) ) = = k8_PotionThingType ) {
2016-07-07 23:27:13 +02:00
L0491_ps_Group = ( Group * ) _vm - > _dungeonMan - > f156_getThingData ( L0486_T_ProjectileAssociatedThing ) ;
switch ( ( ( Potion * ) L0491_ps_Group ) - > getType ( ) ) {
2016-07-07 00:46:51 +02:00
case k3_PotionTypeVen :
L0498_T_ExplosionThing = Thing : : _explPoisonCloud ;
goto T0217004 ;
case k19_PotionTypeFulBomb :
L0498_T_ExplosionThing = Thing : : _explFireBall ;
T0217004 :
L0509_B_RemovePotion = true ;
2016-07-07 23:27:13 +02:00
L0508_i_PotionPower = ( ( Potion * ) L0491_ps_Group ) - > getPower ( ) ;
L0492_ps_Potion = ( Potion * ) L0491_ps_Group ;
2016-07-07 00:46:51 +02:00
}
}
L0505_B_CreateExplosionOnImpact = ( L0510_i_ProjectileAssociatedThingType = = k15_ExplosionThingType ) & & ( L0486_T_ProjectileAssociatedThing ! = Thing : : _explSlime ) & & ( L0486_T_ProjectileAssociatedThing ! = Thing : : _explPoisonBolt ) ;
L0497_pT_GroupSlot = NULL ;
L0489_i_ChampionAttack = 0 ;
if ( mapXCombo < = 255 ) {
L0499_i_ProjectileMapX = mapXCombo ;
L0500_i_ProjectileMapY = mapYCombo ;
} else {
L0499_i_ProjectileMapX = ( mapXCombo > > 8 ) - 1 ;
L0500_i_ProjectileMapY = ( mapYCombo > > 8 ) ;
AP0454_i_ProjectileTargetMapX & = 0x00FF ;
AP0455_i_ProjectileTargetMapY & = 0x00FF ;
}
switch ( impactType ) {
case k4_DoorElemType :
AL0487_i_DoorState = Square ( L0503_uc_Square = _vm - > _dungeonMan - > _g271_currMapData [ AP0454_i_ProjectileTargetMapX ] [ AP0455_i_ProjectileTargetMapY ] ) . getDoorState ( ) ;
2016-07-07 23:27:13 +02:00
L0494_ps_Door = ( Door * ) _vm - > _dungeonMan - > f157_getSquareFirstThingData ( AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY ) ;
2016-07-07 00:46:51 +02:00
if ( ( AL0487_i_DoorState ! = k5_doorState_DESTROYED ) & & ( L0486_T_ProjectileAssociatedThing = = Thing : : _explOpenDoor ) ) {
if ( L0494_ps_Door - > hasButton ( ) ) {
_vm - > _movsens - > f268_addEvent ( k10_TMEventTypeDoor , AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY , 0 , k2_SensorEffToggle , _vm - > _g313_gameTime + 1 ) ;
}
break ;
}
if ( ( AL0487_i_DoorState = = k5_doorState_DESTROYED ) | |
( AL0487_i_DoorState < = k1_doorState_FOURTH ) | |
( getFlag ( _vm - > _dungeonMan - > _g275_currMapDoorInfo [ L0494_ps_Door - > getType ( ) ] . _attributes , k0x0002_MaskDoorInfo_ProjectilesCanPassThrough ) & &
( ( L0510_i_ProjectileAssociatedThingType = = k15_ExplosionThingType ) ?
( L0486_T_ProjectileAssociatedThing . toUint16 ( ) > = Thing : : _explHarmNonMaterial . toUint16 ( ) ) :
( ( L0490_ps_Projectile - > _attack > _vm - > getRandomNumber ( 128 ) ) & &
getFlag ( g237_ObjectInfo [ _vm - > _dungeonMan - > f141_getObjectInfoIndex ( L0486_T_ProjectileAssociatedThing ) ] . getAllowedSlots ( ) , k0x0100_ObjectAllowedSlotPouchPassAndThroughDoors )
& & ( ( L0510_i_ProjectileAssociatedThingType ! = k10_JunkThingType ) | |
( ( AL0487_i_IconIndex = _vm - > _objectMan - > f33_getIconIndex ( L0486_T_ProjectileAssociatedThing ) ) < 0 ) | |
( ! ( ( AL0487_i_IconIndex > = k176_IconIndiceJunkIronKey ) & & ( AL0487_i_IconIndex < = k191_IconIndiceJunkMasterKey ) ) ) )
) ) ) ) { /* ASSEMBLY_COMPILATION_DIFFERENCE jmp */
return false ;
}
L0488_i_Attack = f216_projectileGetImpactAttack ( L0490_ps_Projectile , L0486_T_ProjectileAssociatedThing ) + 1 ;
_vm - > _groupMan - > f232_groupIsDoorDestoryedByAttack ( AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY , L0488_i_Attack + _vm - > getRandomNumber ( L0488_i_Attack ) , false , 0 ) ;
break ;
case kM2_ChampionElemType :
if ( ( AP0456_i_ChampionIndex = _vm - > _championMan - > f285_getIndexInCell ( cell ) ) < 0 ) {
return false ;
}
L0489_i_ChampionAttack = L0488_i_Attack = f216_projectileGetImpactAttack ( L0490_ps_Projectile , L0486_T_ProjectileAssociatedThing ) ;
break ;
case kM1_CreatureElemType :
2016-07-07 23:27:13 +02:00
L0491_ps_Group = ( Group * ) _vm - > _dungeonMan - > f156_getThingData ( _vm - > _groupMan - > f175_groupGetThing ( AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY ) ) ;
2016-07-07 00:46:51 +02:00
if ( ! ( L0512_ui_CreatureIndex = _vm - > _groupMan - > f176_getCreatureOrdinalInCell ( L0491_ps_Group , cell ) ) ) {
return false ;
}
L0512_ui_CreatureIndex - - ;
L0493_ps_CreatureInfo = & g243_CreatureInfo [ L0511_ui_CreatureType = L0491_ps_Group - > _type ] ;
if ( ( L0486_T_ProjectileAssociatedThing = = Thing : : _explFireBall ) & & ( L0511_ui_CreatureType = = k11_CreatureTypeBlackFlame ) ) {
L0496_pui_CreatureHealth = & L0491_ps_Group - > _health [ L0512_ui_CreatureIndex ] ;
* L0496_pui_CreatureHealth = MIN ( 1000 , * L0496_pui_CreatureHealth + f216_projectileGetImpactAttack ( L0490_ps_Projectile , L0486_T_ProjectileAssociatedThing ) ) ;
goto T0217044 ;
}
if ( getFlag ( L0493_ps_CreatureInfo - > _attributes , k0x0040_MaskCreatureInfo_nonMaterial ) & & ( L0486_T_ProjectileAssociatedThing ! = Thing : : _explHarmNonMaterial ) ) {
return false ;
}
if ( L0488_i_Attack = ( uint16 ) ( ( unsigned long ) f216_projectileGetImpactAttack ( L0490_ps_Projectile , L0486_T_ProjectileAssociatedThing ) < < 6 ) / L0493_ps_CreatureInfo - > _defense ) {
if ( ( AL0487_i_Outcome = _vm - > _groupMan - > f190_groupGetDamageCreatureOutcome ( L0491_ps_Group , L0512_ui_CreatureIndex , AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY , L0488_i_Attack + _vm - > _groupMan - > f192_groupGetResistanceAdjustedPoisonAttack ( L0511_ui_CreatureType , _g366_projectilePoisonAttack ) , true ) ) ! = k0_outcomeKilledNoCreaturesInGroup ) {
_vm - > _groupMan - > f209_processEvents29to41 ( AP0454_i_ProjectileTargetMapX , AP0455_i_ProjectileTargetMapY , kM2_TMEventTypeCreateReactionEvent30HitByProjectile , 0 ) ;
}
_g364_creatureDamageOutcome = AL0487_i_Outcome ;
if ( ! L0505_B_CreateExplosionOnImpact & &
( AL0487_i_Outcome = = k0_outcomeKilledNoCreaturesInGroup ) & &
( L0510_i_ProjectileAssociatedThingType = = k5_WeaponThingType ) & &
getFlag ( L0493_ps_CreatureInfo - > _attributes , k0x0400_MaskCreatureInfo_keepThrownSharpWeapon ) ) {
2016-07-07 23:27:13 +02:00
L0495_ps_Weapon = ( Weapon * ) _vm - > _dungeonMan - > f156_getThingData ( L0486_T_ProjectileAssociatedThing ) ;
2016-07-07 00:46:51 +02:00
AL0487_i_WeaponType = L0495_ps_Weapon - > getType ( ) ;
if ( ( AL0487_i_WeaponType = = k8_WeaponTypeDagger ) | | ( AL0487_i_WeaponType = = k27_WeaponTypeArrow ) | | ( AL0487_i_WeaponType = = k28_WeaponTypeSlayer ) | | ( AL0487_i_WeaponType = = k31_WeaponTypePoisonDart ) | | ( AL0487_i_WeaponType = = k32_WeaponTypeThrowingStar ) ) {
L0497_pT_GroupSlot = & L0491_ps_Group - > _slot ;
}
}
}
}
if ( L0489_i_ChampionAttack & & _vm - > _championMan - > f321_addPendingDamageAndWounds_getDamage ( AP0456_i_ChampionIndex , L0488_i_Attack , k0x0004_ChampionWoundHead | k0x0008_ChampionWoundTorso , _g367_projectileAttackType ) & & _g366_projectilePoisonAttack & & _vm - > getRandomNumber ( 2 ) ) {
_vm - > _championMan - > f322_championPoison ( AP0456_i_ChampionIndex , _g366_projectilePoisonAttack ) ;
}
if ( L0505_B_CreateExplosionOnImpact | | L0509_B_RemovePotion
) {
if ( L0509_B_RemovePotion ) {
L0486_T_ProjectileAssociatedThing = L0498_T_ExplosionThing ;
AL0507_ui_ExplosionAttack = L0508_i_PotionPower ;
} else {
AL0507_ui_ExplosionAttack = L0490_ps_Projectile - > _kineticEnergy ;
}
if ( ( L0486_T_ProjectileAssociatedThing = = Thing : : _explLightningBolt ) & & ! ( AL0507_ui_ExplosionAttack > > = 1 ) )
goto T0217044 ;
f213_explosionCreate ( L0486_T_ProjectileAssociatedThing , AL0507_ui_ExplosionAttack , L0501_i_MapXCombo , L0502_i_MapYCombo , ( L0486_T_ProjectileAssociatedThing = = Thing : : _explPoisonCloud ) ? k255_CreatureTypeSingleCenteredCreature : cell ) ;
} else {
if ( ( L0486_T_ProjectileAssociatedThing ) . getType ( ) = = k5_WeaponThingType ) {
AL0507_ui_SoundIndex = k00_soundMETALLIC_THUD ;
} else {
if ( L0486_T_ProjectileAssociatedThing = = Thing : : _explPoisonBolt ) {
AL0507_ui_SoundIndex = k13_soundSPELL ;
} else {
AL0507_ui_SoundIndex = k04_soundWOODEN_THUD_ATTACK_TROLIN_ANTMAN_STONE_GOLEM ;
}
}
warning ( " MISSING CODE: F0064_SOUND_RequestPlay_CPSD " ) ;
}
T0217044 :
if ( L0509_B_RemovePotion ) {
L0492_ps_Potion - > _nextThing = Thing : : _none ;
L0490_ps_Projectile - > _slot = L0498_T_ExplosionThing ;
}
_vm - > _dungeonMan - > f164_unlinkThingFromList ( projectileThing , Thing ( 0 ) , L0499_i_ProjectileMapX , L0500_i_ProjectileMapY ) ;
f215_projectileDelete ( projectileThing , L0497_pT_GroupSlot , L0499_i_ProjectileMapX , L0500_i_ProjectileMapY ) ;
return true ;
}
uint16 ProjExpl : : f216_projectileGetImpactAttack ( Projectile * projectile , Thing thing ) {
WeaponInfo * L0485_ps_WeaponInfo ;
uint16 L0483_ui_Multiple ;
# define AL0483_ui_ThingType L0483_ui_Multiple
# define AL0483_ui_Attack L0483_ui_Multiple
uint16 L0484_ui_KineticEnergy ;
_g366_projectilePoisonAttack = 0 ;
_g367_projectileAttackType = k3_attackType_BLUNT ;
L0484_ui_KineticEnergy = projectile - > _kineticEnergy ;
if ( ( AL0483_ui_ThingType = ( thing ) . getType ( ) ) ! = k15_ExplosionThingType ) {
if ( AL0483_ui_ThingType = = k5_WeaponThingType ) {
L0485_ps_WeaponInfo = _vm - > _dungeonMan - > f158_getWeaponInfo ( thing ) ;
AL0483_ui_Attack = L0485_ps_WeaponInfo - > _kineticEnergy ;
_g367_projectileAttackType = k3_attackType_BLUNT ;
} else {
AL0483_ui_Attack = _vm - > getRandomNumber ( 4 ) ;
}
AL0483_ui_Attack + = _vm - > _dungeonMan - > f140_getObjectWeight ( thing ) > > 1 ;
} else {
if ( thing = = Thing : : _explSlime ) {
AL0483_ui_Attack = _vm - > getRandomNumber ( 16 ) ;
_g366_projectilePoisonAttack = AL0483_ui_Attack + 10 ;
AL0483_ui_Attack + = _vm - > getRandomNumber ( 32 ) ;
} else {
if ( thing . toUint16 ( ) > = Thing : : _explHarmNonMaterial . toUint16 ( ) ) {
_g367_projectileAttackType = k5_attackType_MAGIC ;
if ( thing = = Thing : : _explPoisonBolt ) {
_g366_projectilePoisonAttack = L0484_ui_KineticEnergy ;
return 1 ;
}
return 0 ;
}
_g367_projectileAttackType = k1_attackType_FIRE ;
AL0483_ui_Attack = _vm - > getRandomNumber ( 16 ) + _vm - > getRandomNumber ( 16 ) + 10 ;
if ( thing = = Thing : : _explLightningBolt ) {
_g367_projectileAttackType = k7_attackType_LIGHTNING ;
AL0483_ui_Attack * = 5 ;
}
}
}
AL0483_ui_Attack = ( ( AL0483_ui_Attack + L0484_ui_KineticEnergy ) > > 4 ) + 1 ;
AL0483_ui_Attack + = _vm - > getRandomNumber ( ( AL0483_ui_Attack > > 1 ) + 1 ) + _vm - > getRandomNumber ( 4 ) ;
AL0483_ui_Attack = MAX ( AL0483_ui_Attack > > 1 , AL0483_ui_Attack - ( 32 - ( projectile - > _attack > > 3 ) ) ) ;
return AL0483_ui_Attack ;
}
void ProjExpl : : f213_explosionCreate ( Thing explThing , uint16 attack , uint16 mapXCombo , uint16 mapYCombo , uint16 cell ) {
# define AP0443_ui_ProjectileMapX mapXCombo
# define AP0444_ui_ProjectileMapY mapYCombo
2016-07-10 12:23:27 +02:00
Thing L0473_T_Thing = _vm - > _dungeonMan - > f166_getUnusedThing ( k15_ExplosionThingType ) ;
if ( L0473_T_Thing = = Thing : : _none ) {
2016-07-07 00:46:51 +02:00
return ;
}
2016-07-10 12:23:27 +02:00
Explosion * L0470_ps_Explosion = & ( ( Explosion * ) _vm - > _dungeonMan - > _g284_thingData [ k15_ExplosionThingType ] ) [ ( L0473_T_Thing ) . getIndex ( ) ] ;
int16 L0474_i_ProjectileTargetMapX ;
int16 L0475_i_ProjectileTargetMapY ;
2016-07-07 00:46:51 +02:00
if ( mapXCombo < = 255 ) {
L0474_i_ProjectileTargetMapX = mapXCombo ;
L0475_i_ProjectileTargetMapY = mapYCombo ;
} else {
L0474_i_ProjectileTargetMapX = mapXCombo & 0x00FF ;
L0475_i_ProjectileTargetMapY = mapYCombo & 0x00FF ;
AP0443_ui_ProjectileMapX > > = 8 ;
AP0443_ui_ProjectileMapX - - ;
AP0444_ui_ProjectileMapY > > = 8 ;
}
if ( cell = = k255_CreatureTypeSingleCenteredCreature ) {
L0470_ps_Explosion - > setCentered ( true ) ;
} else {
L0470_ps_Explosion - > setCentered ( false ) ;
L0473_T_Thing = M15_thingWithNewCell ( L0473_T_Thing , cell ) ;
}
L0470_ps_Explosion - > setType ( explThing . toUint16 ( ) - Thing : : _firstExplosion . toUint16 ( ) ) ;
L0470_ps_Explosion - > setAttack ( attack ) ;
if ( explThing . toUint16 ( ) < Thing : : _explHarmNonMaterial . toUint16 ( ) ) {
warning ( " MISING CODE: F0064_SOUND_RequestPlay_CPSD " ) ;
} else {
if ( explThing ! = Thing : : _explSmoke ) {
warning ( " MISSING CODE: F0064_SOUND_RequestPlay_CPSD " ) ;
}
}
_vm - > _dungeonMan - > f163_linkThingToList ( L0473_T_Thing , Thing ( 0 ) , AP0443_ui_ProjectileMapX , AP0444_ui_ProjectileMapY ) ;
2016-07-10 12:23:27 +02:00
TimelineEvent L0476_s_Event ;
2016-07-07 00:46:51 +02:00
M33_setMapAndTime ( L0476_s_Event . _mapTime , _vm - > _dungeonMan - > _g272_currMapIndex , _vm - > _g313_gameTime + ( ( explThing = = Thing : : _explRebirthStep1 ) ? 5 : 1 ) ) ;
L0476_s_Event . _type = k25_TMEventTypeExplosion ;
L0476_s_Event . _priority = 0 ;
2016-07-07 23:14:40 +02:00
L0476_s_Event . _C . _slot = L0473_T_Thing . toUint16 ( ) ;
2016-07-07 00:46:51 +02:00
L0476_s_Event . _B . _location . _mapX = AP0443_ui_ProjectileMapX ;
L0476_s_Event . _B . _location . _mapY = AP0444_ui_ProjectileMapY ;
_vm - > _timeline - > f238_addEventGetEventIndex ( & L0476_s_Event ) ;
if ( ( explThing = = Thing : : _explLightningBolt ) | | ( explThing = = Thing : : _explFireBall ) ) {
AP0443_ui_ProjectileMapX = L0474_i_ProjectileTargetMapX ;
AP0444_ui_ProjectileMapY = L0475_i_ProjectileTargetMapY ;
attack = ( attack > > 1 ) + 1 ;
attack + = _vm - > getRandomNumber ( attack ) + 1 ;
if ( ( explThing = = Thing : : _explFireBall ) | | ( attack > > = 1 ) ) {
if ( ( _vm - > _dungeonMan - > _g272_currMapIndex = = _vm - > _dungeonMan - > _g309_partyMapIndex ) & & ( AP0443_ui_ProjectileMapX = = _vm - > _dungeonMan - > _g306_partyMapX ) & & ( AP0444_ui_ProjectileMapY = = _vm - > _dungeonMan - > _g307_partyMapY ) ) {
_vm - > _championMan - > f324_damageAll_getDamagedChampionCount ( attack , k0x0001_ChampionWoundReadHand | k0x0002_ChampionWoundActionHand | k0x0004_ChampionWoundHead | k0x0008_ChampionWoundTorso | k0x0010_ChampionWoundLegs | k0x0020_ChampionWoundFeet , k1_attackType_FIRE ) ;
} else {
if ( ( L0473_T_Thing = _vm - > _groupMan - > f175_groupGetThing ( AP0443_ui_ProjectileMapX , AP0444_ui_ProjectileMapY ) ) ! = Thing : : _endOfList ) { /* ASSEMBLY_COMPILATION_DIFFERENCE jmp */
2016-07-10 12:23:27 +02:00
Group * L0472_ps_Group = ( Group * ) _vm - > _dungeonMan - > f156_getThingData ( L0473_T_Thing ) ;
CreatureInfo * L0471_ps_CreatureInfo = & g243_CreatureInfo [ L0472_ps_Group - > _type ] ;
int16 L0469_i_CreatureFireResistance = L0471_ps_CreatureInfo - > M60_getFireResistance ( ) ;
if ( L0469_i_CreatureFireResistance ! = k15_immuneToFire ) {
2016-07-07 00:46:51 +02:00
if ( getFlag ( L0471_ps_CreatureInfo - > _attributes , k0x0040_MaskCreatureInfo_nonMaterial ) ) {
attack > > = 2 ;
}
if ( ( attack - = _vm - > getRandomNumber ( ( L0469_i_CreatureFireResistance < < 1 ) + 1 ) ) > 0 ) {
_g364_creatureDamageOutcome = _vm - > _groupMan - > f191_getDamageAllCreaturesOutcome ( L0472_ps_Group , AP0443_ui_ProjectileMapX , AP0444_ui_ProjectileMapY , attack , true ) ;
}
}
}
}
}
}
}
int16 ProjExpl : : f218_projectileGetImpactCount ( int16 impactType , int16 mapX , int16 mapY , int16 cell ) {
Thing L0513_T_Thing ;
int16 L0514_i_ImpactCount ;
L0514_i_ImpactCount = 0 ;
_g364_creatureDamageOutcome = k0_outcomeKilledNoCreaturesInGroup ;
T0218001 :
L0513_T_Thing = _vm - > _dungeonMan - > f161_getSquareFirstThing ( mapX , mapY ) ;
while ( L0513_T_Thing ! = Thing : : _endOfList ) {
if ( ( ( L0513_T_Thing ) . getType ( ) = = k14_ProjectileThingType ) & &
( ( L0513_T_Thing ) . getCell ( ) = = cell ) & &
f217_projectileHasImpactOccurred ( impactType , mapX , mapY , cell , L0513_T_Thing ) ) {
f214_projectileDeleteEvent ( L0513_T_Thing ) ;
L0514_i_ImpactCount + + ;
if ( ( impactType = = kM1_CreatureElemType ) & & ( _g364_creatureDamageOutcome = = k2_outcomeKilledAllCreaturesInGroup ) )
break ;
goto T0218001 ;
}
L0513_T_Thing = _vm - > _dungeonMan - > f159_getNextThing ( L0513_T_Thing ) ;
}
return L0514_i_ImpactCount ;
}
void ProjExpl : : f214_projectileDeleteEvent ( Thing thing ) {
Projectile * L0477_ps_Projectile ;
2016-07-07 23:27:13 +02:00
L0477_ps_Projectile = ( Projectile * ) _vm - > _dungeonMan - > f156_getThingData ( thing ) ;
2016-07-07 00:46:51 +02:00
_vm - > _timeline - > f237_deleteEvent ( L0477_ps_Projectile - > _eventIndex ) ;
}
void ProjExpl : : f215_projectileDelete ( Thing projectileThing , Thing * groupSlot , int16 mapX , int16 mapY ) {
2016-07-10 12:23:27 +02:00
Projectile * L0480_ps_Projectile = ( Projectile * ) _vm - > _dungeonMan - > f156_getThingData ( projectileThing ) ;
Thing L0479_T_Thing = L0480_ps_Projectile - > _slot ;
if ( L0479_T_Thing . getType ( ) ! = k15_ExplosionThingType ) {
2016-07-07 00:46:51 +02:00
if ( groupSlot ! = NULL ) {
2016-07-10 12:23:27 +02:00
Thing L0478_T_PreviousThing = * groupSlot ;
if ( L0478_T_PreviousThing = = Thing : : _endOfList ) {
Thing * L0481_ps_Generic = ( Thing * ) _vm - > _dungeonMan - > f156_getThingData ( L0479_T_Thing ) ;
2016-07-07 00:46:51 +02:00
* L0481_ps_Generic = Thing : : _endOfList ;
* groupSlot = L0479_T_Thing ;
} else {
_vm - > _dungeonMan - > f163_linkThingToList ( L0479_T_Thing , L0478_T_PreviousThing , kM1_MapXNotOnASquare , 0 ) ;
}
} else {
_vm - > _movsens - > f267_getMoveResult ( Thing ( ( L0479_T_Thing ) . getTypeAndIndex ( ) | getFlag ( projectileThing . toUint16 ( ) , 0xC ) ) , - 2 , 0 , mapX , mapY ) ;
}
}
L0480_ps_Projectile - > _nextThing = Thing : : _none ;
}
}