Variable naming, part 2 (#320)

This commit is contained in:
Vlad 2024-01-16 14:33:08 +01:00 committed by GitHub
parent c6565ac96a
commit 59af02cca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 501 additions and 498 deletions

View File

@ -88,7 +88,7 @@ static int _is_next_to(Object* a1, Object* a2);
static int _action_climb_ladder(Object* a1, Object* a2);
static int _action_use_skill_in_combat_error(Object* critter);
static int _pick_fall(Object* obj, int anim);
static int _report_explosion(Attack* attack, Object* a2);
static int _report_explosion(Attack* attack, Object* sourceObj);
static int _finished_explosion(Object* a1, Object* a2);
static int _compute_explosion_damage(int min, int max, Object* defender, int* knockbackDistancePtr);
static int _can_talk_to(Object* a1, Object* a2);
@ -1579,9 +1579,9 @@ bool _action_explode_running()
// action_explode
// 0x412CF4
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6)
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate)
{
if (a6 && _action_in_explode) {
if (animate && _action_in_explode) {
return -2;
}
@ -1656,7 +1656,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
attackComputeDeathFlags(attack);
if (a6) {
if (animate) {
_action_in_explode = true;
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
@ -1678,7 +1678,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
animationRegisterHideObjectForced(adjacentExplosions[rotation]);
}
animationRegisterCallbackForced(attack, a5, (AnimationCallback*)_report_explosion, -1);
animationRegisterCallbackForced(attack, sourceObj, (AnimationCallback*)_report_explosion, -1);
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_finished_explosion, -1);
if (reg_anim_end() == -1) {
_action_in_explode = false;
@ -1709,7 +1709,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
}
}
_report_explosion(attack, a5);
_report_explosion(attack, sourceObj);
_combat_explode_scenery(explosion, NULL);
@ -1724,7 +1724,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
}
// 0x413144
int _report_explosion(Attack* attack, Object* a2)
int _report_explosion(Attack* attack, Object* sourceObj)
{
bool mainTargetWasDead;
if (attack->defender != NULL) {
@ -1744,27 +1744,27 @@ int _report_explosion(Attack* attack, Object* a2)
Object* anyDefender = NULL;
int xp = 0;
if (a2 != NULL) {
if (attack->defender != NULL && attack->defender != a2) {
if (sourceObj != NULL) {
if (attack->defender != NULL && attack->defender != sourceObj) {
if ((attack->defender->data.critter.combat.results & DAM_DEAD) != 0) {
if (a2 == gDude && !mainTargetWasDead) {
if (sourceObj == gDude && !mainTargetWasDead) {
xp += critterGetExp(attack->defender);
}
} else {
_critter_set_who_hit_me(attack->defender, a2);
_critter_set_who_hit_me(attack->defender, sourceObj);
anyDefender = attack->defender;
}
}
for (int index = 0; index < attack->extrasLength; index++) {
Object* critter = attack->extras[index];
if (critter != a2) {
if (critter != sourceObj) {
if ((critter->data.critter.combat.results & DAM_DEAD) != 0) {
if (a2 == gDude && !extrasWasDead[index]) {
if (sourceObj == gDude && !extrasWasDead[index]) {
xp += critterGetExp(critter);
}
} else {
_critter_set_who_hit_me(critter, a2);
_critter_set_who_hit_me(critter, sourceObj);
if (anyDefender == NULL) {
anyDefender = critter;
@ -1775,15 +1775,15 @@ int _report_explosion(Attack* attack, Object* a2)
if (anyDefender != NULL) {
if (!isInCombat()) {
STRUCT_664980 combat;
CombatStartData combat;
combat.attacker = anyDefender;
combat.defender = a2;
combat.defender = sourceObj;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = INT_MAX;
combat.field_1C = 0;
combat.overrideAttackResults = 0;
scriptsRequestCombat(&combat);
}
}
@ -1792,7 +1792,7 @@ int _report_explosion(Attack* attack, Object* a2)
internal_free(attack);
gameUiEnable();
if (a2 == gDude) {
if (sourceObj == gDude) {
_combat_give_exps(xp);
}

View File

@ -15,10 +15,10 @@ int actionPickUp(Object* critter, Object* item);
int _action_loot_container(Object* critter, Object* container);
int _action_skill_use(int a1);
int actionUseSkill(Object* a1, Object* a2, int skill);
bool _is_hit_from_front(Object* a1, Object* a2);
bool _is_hit_from_front(Object* attacker, Object* defender);
bool _can_see(Object* a1, Object* a2);
bool _action_explode_running();
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6);
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate);
int actionTalk(Object* a1, Object* a2);
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
bool actionCheckPush(Object* a1, Object* a2);

View File

@ -94,13 +94,13 @@ static bool _combat_safety_invalidate_weapon_func(Object* attacker, Object* weap
static void _combatInitAIInfoList();
static int aiInfoCopy(int srcIndex, int destIndex);
static int _combatAIInfoSetLastMove(Object* object, int move);
static void _combat_begin(Object* a1);
static void _combat_begin_extra(Object* a1);
static void _combat_begin(Object* attacker);
static void _combat_begin_extra(Object* attacker);
static void _combat_update_critters_in_los(bool a1);
static void _combat_over();
static void _combat_add_noncoms();
static int _compare_faster(const void* a1, const void* a2);
static void _combat_sequence_init(Object* a1, Object* a2);
static int _compare_faster(const void* critter1Ptr, const void* critter2Ptr);
static void _combat_sequence_init(Object* attacker, Object* defender);
static void _combat_sequence();
static void combatAttemptEnd();
static int _combat_input();
@ -161,7 +161,7 @@ unsigned int gCombatState = COMBAT_STATE_0x02;
static CombatAiInfo* _aiInfoList = NULL;
// 0x51094C
static STRUCT_664980* _gcsd = NULL;
static CombatStartData* _gcsd = NULL;
// 0x510950
static bool _combat_call_display = false;
@ -2560,7 +2560,7 @@ static int _combatAIInfoSetLastMove(Object* object, int move)
}
// 0x421A34
static void _combat_begin(Object* a1)
static void _combat_begin(Object* attacker)
{
_combat_turn_running = 0;
animationStop();
@ -2610,7 +2610,7 @@ static void _combat_begin(Object* a1)
gameUiDisable(0);
gameMouseSetCursor(MOUSE_CURSOR_WAIT_WATCH);
_combat_ending_guy = NULL;
_combat_begin_extra(a1);
_combat_begin_extra(attacker);
_caiTeamCombatInit(_combat_list, _list_total);
interfaceBarEndButtonsShow(true);
_gmouse_enable_scrolling();
@ -2636,15 +2636,15 @@ static void _combat_begin(Object* a1)
}
// 0x421C8C
static void _combat_begin_extra(Object* a1)
static void _combat_begin_extra(Object* attacker)
{
for (int index = 0; index < _list_total; index++) {
_combat_update_critter_outline_for_los(_combat_list[index], 0);
}
attackInit(&_main_ctd, a1, NULL, 4, 3);
attackInit(&_main_ctd, attacker, NULL, 4, 3);
_combat_turn_obj = a1;
_combat_turn_obj = attacker;
_combat_ai_begin(_list_total, _combat_list);
@ -2933,21 +2933,21 @@ static void _combat_add_noncoms()
// Compares critters by sequence.
//
// 0x4223C8
static int _compare_faster(const void* a1, const void* a2)
static int _compare_faster(const void* critter1Ptr, const void* critter2Ptr)
{
Object* v1 = *(Object**)a1;
Object* v2 = *(Object**)a2;
Object* critter1 = *(Object**)critter1Ptr;
Object* critter2 = *(Object**)critter2Ptr;
int sequence1 = critterGetStat(v1, STAT_SEQUENCE);
int sequence2 = critterGetStat(v2, STAT_SEQUENCE);
int sequence1 = critterGetStat(critter1, STAT_SEQUENCE);
int sequence2 = critterGetStat(critter2, STAT_SEQUENCE);
if (sequence1 > sequence2) {
return -1;
} else if (sequence1 < sequence2) {
return 1;
}
int luck1 = critterGetStat(v1, STAT_LUCK);
int luck2 = critterGetStat(v2, STAT_LUCK);
int luck1 = critterGetStat(critter1, STAT_LUCK);
int luck2 = critterGetStat(critter2, STAT_LUCK);
if (luck1 > luck2) {
return -1;
} else if (luck1 < luck2) {
@ -2957,14 +2957,17 @@ static int _compare_faster(const void* a1, const void* a2)
return 0;
}
// Initializes combat sequence for the first round.
//
// 0x42243C
static void _combat_sequence_init(Object* a1, Object* a2)
static void _combat_sequence_init(Object* attacker, Object* defender)
{
// Always place attacker first (swap with critter at 0 index).
int next = 0;
if (a1 != NULL) {
if (attacker != NULL) {
for (int index = 0; index < _list_total; index++) {
Object* obj = _combat_list[index];
if (obj == a1) {
if (obj == attacker) {
Object* temp = _combat_list[next];
_combat_list[index] = temp;
_combat_list[next] = obj;
@ -2974,10 +2977,11 @@ static void _combat_sequence_init(Object* a1, Object* a2)
}
}
if (a2 != NULL) {
// Place defender second.
if (defender != NULL) {
for (int index = 0; index < _list_total; index++) {
Object* obj = _combat_list[index];
if (obj == a2) {
if (obj == defender) {
Object* temp = _combat_list[next];
_combat_list[index] = temp;
_combat_list[next] = obj;
@ -2987,7 +2991,8 @@ static void _combat_sequence_init(Object* a1, Object* a2)
}
}
if (a1 != gDude && a2 != gDude) {
// Place dude third, if he's neither attacker, nor defender.
if (attacker != gDude && defender != gDude) {
for (int index = 0; index < _list_total; index++) {
Object* obj = _combat_list[index];
if (obj == gDude) {
@ -3003,15 +3008,17 @@ static void _combat_sequence_init(Object* a1, Object* a2)
_list_com = next;
_list_noncom -= next;
if (a1 != NULL) {
_critter_set_who_hit_me(a1, a2);
if (attacker != NULL) {
_critter_set_who_hit_me(attacker, defender);
}
if (a2 != NULL) {
_critter_set_who_hit_me(a2, a1);
if (defender != NULL) {
_critter_set_who_hit_me(defender, attacker);
}
}
// Updates combat sequence for the next round.
//
// 0x422580
static void _combat_sequence()
{
@ -3019,6 +3026,7 @@ static void _combat_sequence()
int count = _list_com;
// Remove dead critters from the combatant list.
for (int index = 0; index < count; index++) {
Object* critter = _combat_list[index];
if ((critter->data.critter.combat.results & DAM_DEAD) != 0) {
@ -3033,6 +3041,7 @@ static void _combat_sequence()
}
}
// Move knocked out and disengaged critters to non-combatant list.
for (int index = 0; index < count; index++) {
Object* critter = _combat_list[index];
if (critter != gDude) {
@ -3050,6 +3059,7 @@ static void _combat_sequence()
}
}
// Sort combatant list based on Sequence stat.
if (count != 0) {
_list_com = count;
qsort(_combat_list, count, sizeof(*_combat_list), _compare_faster);
@ -3212,16 +3222,16 @@ static void _combat_set_move_all()
}
// 0x42299C
static int _combat_turn(Object* a1, bool a2)
static int _combat_turn(Object* obj, bool a2)
{
_combat_turn_obj = a1;
_combat_turn_obj = obj;
attackInit(&_main_ctd, a1, NULL, HIT_MODE_PUNCH, HIT_LOCATION_TORSO);
attackInit(&_main_ctd, obj, NULL, HIT_MODE_PUNCH, HIT_LOCATION_TORSO);
if ((a1->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD | DAM_LOSE_TURN)) != 0) {
a1->data.critter.combat.results &= ~DAM_LOSE_TURN;
if ((obj->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD | DAM_LOSE_TURN)) != 0) {
obj->data.critter.combat.results &= ~DAM_LOSE_TURN;
} else {
if (a1 == gDude) {
if (obj == gDude) {
keyboardReset();
interfaceRenderArmorClass(true);
_combat_free_move = 2 * perkGetRank(gDude, PERK_BONUS_MOVE);
@ -3231,13 +3241,13 @@ static int _combat_turn(Object* a1, bool a2)
}
bool scriptOverrides = false;
if (a1->sid != -1) {
scriptSetObjects(a1->sid, NULL, NULL);
scriptSetFixedParam(a1->sid, 4);
scriptExecProc(a1->sid, SCRIPT_PROC_COMBAT);
if (obj->sid != -1) {
scriptSetObjects(obj->sid, NULL, NULL);
scriptSetFixedParam(obj->sid, 4);
scriptExecProc(obj->sid, SCRIPT_PROC_COMBAT);
Script* scr;
if (scriptGetScript(a1->sid, &scr) != -1) {
if (scriptGetScript(obj->sid, &scr) != -1) {
scriptOverrides = scr->scriptOverrides;
}
@ -3247,11 +3257,11 @@ static int _combat_turn(Object* a1, bool a2)
}
if (!scriptOverrides) {
if (!a2 && _critter_is_prone(a1)) {
_combat_standup(a1);
if (!a2 && _critter_is_prone(obj)) {
_combat_standup(obj);
}
if (a1 == gDude) {
if (obj == gDude) {
gameUiEnable();
_gmouse_3d_refresh();
@ -3275,7 +3285,7 @@ static int _combat_turn(Object* a1, bool a2)
if (_combat_input() == -1) {
gameUiDisable(1);
gameMouseSetCursor(MOUSE_CURSOR_WAIT_WATCH);
a1->data.critter.combat.damageLastTurn = 0;
obj->data.critter.combat.damageLastTurn = 0;
interfaceBarEndButtonsRenderRedLights();
_combat_outline_off();
interfaceRenderActionPoints(-1, -1);
@ -3285,18 +3295,18 @@ static int _combat_turn(Object* a1, bool a2)
}
} else {
Rect rect;
if (objectEnableOutline(a1, &rect) == 0) {
tileWindowRefreshRect(&rect, a1->elevation);
if (objectEnableOutline(obj, &rect) == 0) {
tileWindowRefreshRect(&rect, obj->elevation);
}
_combat_ai(a1, _gcsd != NULL ? _gcsd->defender : NULL);
_combat_ai(obj, _gcsd != NULL ? _gcsd->defender : NULL);
}
}
// NOTE: Uninline.
_combat_turn_run();
if (a1 == gDude) {
if (obj == gDude) {
gameUiDisable(1);
gameMouseSetCursor(MOUSE_CURSOR_WAIT_WATCH);
interfaceBarEndButtonsRenderRedLights();
@ -3307,8 +3317,8 @@ static int _combat_turn(Object* a1, bool a2)
_combat_turn_obj = gDude;
} else {
Rect rect;
if (objectDisableOutline(a1, &rect) == 0) {
tileWindowRefreshRect(&rect, a1->elevation);
if (objectDisableOutline(obj, &rect) == 0) {
tileWindowRefreshRect(&rect, obj->elevation);
}
}
}
@ -3317,7 +3327,7 @@ static int _combat_turn(Object* a1, bool a2)
return -1;
}
if (a1 != gDude || _combat_elev == gDude->elevation) {
if (obj != gDude || _combat_elev == gDude->elevation) {
_combat_free_move = 0;
return 0;
}
@ -3365,23 +3375,23 @@ static bool _combat_should_end()
}
// 0x422D2C
void _combat(STRUCT_664980* attack)
void _combat(CombatStartData* csd)
{
ScopedGameMode gm(GameMode::kCombat);
if (attack == NULL
|| (attack->attacker == NULL || attack->attacker->elevation == gElevation)
|| (attack->defender == NULL || attack->defender->elevation == gElevation)) {
int v3 = gCombatState & 0x01;
if (csd == NULL
|| (csd->attacker == NULL || csd->attacker->elevation == gElevation)
|| (csd->defender == NULL || csd->defender->elevation == gElevation)) {
bool wasInCombat = (gCombatState & 0x01) != 0;
_combat_begin(NULL);
int v6;
int curIndex;
// TODO: Not sure.
if (v3 != 0) {
// If we loaded a save in combat, we need to force dude turn and then continue with the next combatant.
if (wasInCombat) {
if (_combat_turn(gDude, true) == -1) {
v6 = -1;
curIndex = -1;
} else {
int index;
for (index = 0; index < _list_com; index++) {
@ -3389,33 +3399,33 @@ void _combat(STRUCT_664980* attack)
break;
}
}
v6 = index + 1;
curIndex = index + 1;
}
_gcsd = NULL;
} else {
Object* v3;
Object* v9;
if (attack != NULL) {
v3 = attack->defender;
v9 = attack->attacker;
Object* defender;
Object* attacker;
if (csd != NULL) {
defender = csd->defender;
attacker = csd->attacker;
} else {
v3 = NULL;
v9 = NULL;
defender = NULL;
attacker = NULL;
}
_combat_sequence_init(v9, v3);
_gcsd = attack;
v6 = 0;
_combat_sequence_init(attacker, defender);
_gcsd = csd;
curIndex = 0;
}
do {
if (v6 == -1) {
if (curIndex == -1) {
break;
}
_combat_set_move_all();
for (; v6 < _list_com; v6++) {
if (_combat_turn(_combat_list[v6], false) == -1) {
for (; curIndex < _list_com; curIndex++) {
if (_combat_turn(_combat_list[curIndex], false) == -1) {
break;
}
@ -3426,12 +3436,12 @@ void _combat(STRUCT_664980* attack)
_gcsd = NULL;
}
if (v6 < _list_com) {
if (curIndex < _list_com) {
break;
}
_combat_sequence();
v6 = 0;
curIndex = 0;
_combatNumTurns += 1;
} while (!_combat_should_end());
@ -3503,11 +3513,11 @@ int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocat
_main_ctd.defenderDamage = _gcsd->maxDamage;
}
if (_gcsd->field_1C) {
if (_gcsd->overrideAttackResults) {
// FIXME: looks like a bug, two different fields are used to set
// one field.
_main_ctd.defenderFlags = _gcsd->field_20;
_main_ctd.defenderFlags = _gcsd->field_24;
_main_ctd.defenderFlags = _gcsd->attackerResults;
_main_ctd.defenderFlags = _gcsd->targetResults;
}
}
@ -5700,9 +5710,9 @@ bool _combat_to_hit(Object* target, int* accuracy)
}
// 0x4267CC
void _combat_attack_this(Object* a1)
void _combat_attack_this(Object* target)
{
if (a1 == NULL) {
if (target == NULL) {
return;
}
@ -5721,7 +5731,7 @@ void _combat_attack_this(Object* a1)
char formattedText[80];
const char* sfx;
int rc = _combat_check_bad_shot(gDude, a1, hitMode, aiming);
int rc = _combat_check_bad_shot(gDude, target, hitMode, aiming);
switch (rc) {
case COMBAT_BAD_SHOT_NO_AMMO:
item = critterGetWeaponForHitMode(gDude, hitMode);
@ -5771,21 +5781,21 @@ void _combat_attack_this(Object* a1)
}
if (!isInCombat()) {
STRUCT_664980 stru;
stru.attacker = gDude;
stru.defender = a1;
stru.actionPointsBonus = 0;
stru.accuracyBonus = 0;
stru.damageBonus = 0;
stru.minDamage = 0;
stru.maxDamage = INT_MAX;
stru.field_1C = 0;
_combat(&stru);
CombatStartData combat;
combat.attacker = gDude;
combat.defender = target;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = INT_MAX;
combat.overrideAttackResults = 0;
_combat(&combat);
return;
}
if (!aiming) {
_combat_attack(gDude, a1, hitMode, HIT_LOCATION_UNCALLED);
_combat_attack(gDude, target, hitMode, HIT_LOCATION_UNCALLED);
return;
}
@ -5794,8 +5804,8 @@ void _combat_attack_this(Object* a1)
}
int hitLocation;
if (calledShotSelectHitLocation(a1, &hitLocation, hitMode) != -1) {
_combat_attack(gDude, a1, hitMode, hitLocation);
if (calledShotSelectHitLocation(target, &hitLocation, hitMode) != -1) {
_combat_attack(gDude, target, hitMode, hitLocation);
}
}

View File

@ -33,7 +33,7 @@ void _combat_update_critter_outline_for_los(Object* critter, bool a2);
void _combat_over_from_load();
void _combat_give_exps(int exp_points);
void _combat_turn_run();
void _combat(STRUCT_664980* attack);
void _combat(CombatStartData* csd);
void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode, int hitLocation);
int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocation);
int _combat_bullet_start(const Object* attacker, const Object* target);
@ -48,7 +48,7 @@ void _combat_anim_begin();
void _combat_anim_finished();
int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool aiming);
bool _combat_to_hit(Object* target, int* accuracy);
void _combat_attack_this(Object* a1);
void _combat_attack_this(Object* target);
void _combat_outline_on();
void _combat_outline_off();
void _combat_highlight_change();

View File

@ -3496,22 +3496,22 @@ void _combatai_check_retaliation(Object* a1, Object* a2)
}
// 0x42BA04
bool isWithinPerception(Object* a1, Object* a2)
bool isWithinPerception(Object* critter, Object* target)
{
if (a2 == NULL) {
if (target == NULL) {
return false;
}
int distance = objectGetDistanceBetween(a2, a1);
int perception = critterGetStat(a1, STAT_PERCEPTION);
int sneak = skillGetValue(a2, SKILL_SNEAK);
if (_can_see(a1, a2)) {
int distance = objectGetDistanceBetween(target, critter);
int perception = critterGetStat(critter, STAT_PERCEPTION);
int sneak = skillGetValue(target, SKILL_SNEAK);
if (_can_see(critter, target)) {
int maxDistance = perception * 5;
if ((a2->flags & OBJECT_TRANS_GLASS) != 0) {
if ((target->flags & OBJECT_TRANS_GLASS) != 0) {
maxDistance /= 2;
}
if (a2 == gDude) {
if (target == gDude) {
if (dudeIsSneaking()) {
maxDistance /= 4;
if (sneak > 120) {
@ -3534,7 +3534,7 @@ bool isWithinPerception(Object* a1, Object* a2)
maxDistance = perception;
}
if (a2 == gDude) {
if (target == gDude) {
if (dudeIsSneaking()) {
maxDistance /= 4;
if (sneak > 120) {

View File

@ -86,7 +86,7 @@ typedef enum HitLocation {
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
} HitLocation;
typedef struct STRUCT_664980 {
typedef struct CombatStartData {
Object* attacker;
Object* defender;
int actionPointsBonus;
@ -94,10 +94,10 @@ typedef struct STRUCT_664980 {
int damageBonus;
int minDamage;
int maxDamage;
int field_1C; // probably bool, indicating field_20 and field_24 used
int field_20; // flags on attacker
int field_24; // flags on defender
} STRUCT_664980;
int overrideAttackResults;
int attackerResults;
int targetResults;
} CombatStartData;
typedef struct Attack {
Object* attacker;

View File

@ -1868,27 +1868,27 @@ static void opAttackComplex(Program* program)
combatData->whoHitMe = target;
}
} else {
STRUCT_664980 attack;
attack.attacker = self;
attack.defender = target;
attack.actionPointsBonus = 0;
attack.accuracyBonus = data[4];
attack.damageBonus = 0;
attack.minDamage = data[3];
attack.maxDamage = data[2];
CombatStartData combat;
combat.attacker = self;
combat.defender = target;
combat.actionPointsBonus = 0;
combat.accuracyBonus = data[4];
combat.damageBonus = 0;
combat.minDamage = data[3];
combat.maxDamage = data[2];
// TODO: Something is probably broken here, why it wants
// flags to be the same? Maybe because both of them
// are applied to defender because of the bug in 0x422F3C?
if (data[1] == data[0]) {
attack.field_1C = 1;
attack.field_24 = data[0];
attack.field_20 = data[1];
combat.overrideAttackResults = 1;
combat.targetResults = data[0];
combat.attackerResults = data[1];
} else {
attack.field_1C = 0;
combat.overrideAttackResults = 0;
}
scriptsRequestCombat(&attack);
scriptsRequestCombat(&combat);
}
program->flags &= ~PROGRAM_FLAG_0x20;
@ -4455,17 +4455,17 @@ static void opAttackSetup(Program* program)
attacker->data.critter.combat.whoHitMe = defender;
}
} else {
STRUCT_664980 attack;
attack.attacker = attacker;
attack.defender = defender;
attack.actionPointsBonus = 0;
attack.accuracyBonus = 0;
attack.damageBonus = 0;
attack.minDamage = 0;
attack.maxDamage = INT_MAX;
attack.field_1C = 0;
CombatStartData combat;
combat.attacker = attacker;
combat.defender = defender;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = INT_MAX;
combat.overrideAttackResults = 0;
scriptsRequestCombat(&attack);
scriptsRequestCombat(&combat);
}
}

View File

@ -238,6 +238,12 @@ typedef struct InventoryCursorData {
CacheEntry* frmHandle;
} InventoryCursorData;
typedef enum InventoryMoveResult {
INVENTORY_MOVE_RESULT_FAILED,
INVENTORY_MOVE_RESULT_CAUGHT_STEALING,
INVENTORY_MOVE_RESULT_SUCCESS,
};
static int inventoryMessageListInit();
static int inventoryMessageListFree();
static bool _setup_inventory(int inventoryWindowType);
@ -260,7 +266,7 @@ static int _inven_from_button(int a1, Object** a2, Object*** a3, Object** a4);
static void inventoryRenderItemDescription(char* string);
static void inventoryExamineItem(Object* critter, Object* item);
static void inventoryWindowOpenContextMenu(int eventCode, int inventoryWindowType);
static int _move_inventory(Object* a1, int a2, Object* a3, bool a4);
static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object* targetObj, bool isPlanting);
static int _barter_compute_value(Object* a1, Object* a2);
static int _barter_attempt_transaction(Object* a1, Object* a2, Object* a3, Object* a4);
static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Object* a5, Object* a6, bool a7);
@ -1549,38 +1555,38 @@ static void _exit_inventory(bool shouldEnableIso)
_gmouse_enable();
if (_dropped_explosive) {
Attack v1;
attackInit(&v1, gDude, NULL, HIT_MODE_PUNCH, HIT_LOCATION_TORSO);
v1.attackerFlags = DAM_HIT;
v1.tile = gDude->tile;
_compute_explosion_on_extras(&v1, 0, 0, 1);
Attack attack;
attackInit(&attack, gDude, NULL, HIT_MODE_PUNCH, HIT_LOCATION_TORSO);
attack.attackerFlags = DAM_HIT;
attack.tile = gDude->tile;
_compute_explosion_on_extras(&attack, 0, 0, 1);
Object* v2 = NULL;
for (int index = 0; index < v1.extrasLength; index++) {
Object* critter = v1.extras[index];
Object* watcher = NULL;
for (int index = 0; index < attack.extrasLength; index++) {
Object* critter = attack.extras[index];
if (critter != gDude
&& critter->data.critter.combat.team != gDude->data.critter.combat.team
&& statRoll(critter, STAT_PERCEPTION, 0, NULL) >= ROLL_SUCCESS) {
_critter_set_who_hit_me(critter, gDude);
if (v2 == NULL) {
v2 = critter;
if (watcher == NULL) {
watcher = critter;
}
}
}
if (v2 != NULL) {
if (watcher != NULL) {
if (!isInCombat()) {
STRUCT_664980 v3;
v3.attacker = v2;
v3.defender = gDude;
v3.actionPointsBonus = 0;
v3.accuracyBonus = 0;
v3.damageBonus = 0;
v3.minDamage = 0;
v3.maxDamage = INT_MAX;
v3.field_1C = 0;
scriptsRequestCombat(&v3);
CombatStartData combat;
combat.attacker = watcher;
combat.defender = gDude;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = INT_MAX;
combat.overrideAttackResults = 0;
scriptsRequestCombat(&combat);
}
}
@ -4036,7 +4042,7 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
}
// 0x473904
int inventoryOpenLooting(Object* a1, Object* a2)
int inventoryOpenLooting(Object* looter, Object* target)
{
int arrowFrmIds[INVENTORY_ARROW_FRM_COUNT];
FrmImage arrowFrmImages[INVENTORY_ARROW_FRM_COUNT];
@ -4044,14 +4050,14 @@ int inventoryOpenLooting(Object* a1, Object* a2)
memcpy(arrowFrmIds, gInventoryArrowFrmIds, sizeof(gInventoryArrowFrmIds));
if (a1 != _inven_dude) {
if (looter != _inven_dude) {
return 0;
}
ScopedGameMode gm(GameMode::kLoot);
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
if (_critter_flag_check(a2->pid, CRITTER_NO_STEAL)) {
if (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER) {
if (_critter_flag_check(target->pid, CRITTER_NO_STEAL)) {
// You can't find anything to take from that.
messageListItem.num = 50;
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
@ -4061,11 +4067,11 @@ int inventoryOpenLooting(Object* a1, Object* a2)
}
}
if (FID_TYPE(a2->fid) == OBJ_TYPE_ITEM) {
if (itemGetType(a2) == ITEM_TYPE_CONTAINER) {
if (a2->frame == 0) {
if (FID_TYPE(target->fid) == OBJ_TYPE_ITEM) {
if (itemGetType(target) == ITEM_TYPE_CONTAINER) {
if (target->frame == 0) {
CacheEntry* handle;
Art* frm = artLock(a2->fid, &handle);
Art* frm = artLock(target->fid, &handle);
if (frm != NULL) {
int frameCount = artGetFrameCount(frm);
artUnlock(handle);
@ -4079,8 +4085,8 @@ int inventoryOpenLooting(Object* a1, Object* a2)
int sid = -1;
if (!_gIsSteal) {
if (_obj_sid(a2, &sid) != -1) {
scriptSetObjects(sid, a1, NULL);
if (_obj_sid(target, &sid) != -1) {
scriptSetObjects(sid, looter, NULL);
scriptExecProc(sid, SCRIPT_PROC_PICKUP);
Script* script;
@ -4096,36 +4102,36 @@ int inventoryOpenLooting(Object* a1, Object* a2)
return 0;
}
_target_pud = &(a2->data.inventory);
_target_pud = &(target->data.inventory);
_target_curr_stack = 0;
_target_stack_offset[0] = 0;
_target_stack[0] = a2;
_target_stack[0] = target;
Object* a1a = NULL;
if (objectCreateWithFidPid(&a1a, 0, 467) == -1) {
Object* hiddenBox = NULL;
if (objectCreateWithFidPid(&hiddenBox, 0, PROTO_ID_JESSE_CONTAINER) == -1) {
return 0;
}
itemMoveAllHidden(a2, a1a);
itemMoveAllHidden(target, hiddenBox);
Object* item1 = NULL;
Object* item2 = NULL;
Object* armor = NULL;
if (_gIsSteal) {
item1 = critterGetItem1(a2);
item1 = critterGetItem1(target);
if (item1 != NULL) {
itemRemove(a2, item1, 1);
itemRemove(target, item1, 1);
}
item2 = critterGetItem2(a2);
item2 = critterGetItem2(target);
if (item2 != NULL) {
itemRemove(a2, item2, 1);
itemRemove(target, item2, 1);
}
armor = critterGetArmor(a2);
armor = critterGetArmor(target);
if (armor != NULL) {
itemRemove(a2, armor, 1);
itemRemove(target, armor, 1);
}
}
@ -4135,8 +4141,8 @@ int inventoryOpenLooting(Object* a1, Object* a2)
int critterCount = 0;
int critterIndex = 0;
if (!_gIsSteal) {
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
critterCount = objectListCreate(a2->tile, a2->elevation, OBJ_TYPE_CRITTER, &critters);
if (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER) {
critterCount = objectListCreate(target->tile, target->elevation, OBJ_TYPE_CRITTER, &critters);
int endIndex = critterCount - 1;
for (int index = 0; index < critterCount; index++) {
Object* critter = critters[index];
@ -4213,7 +4219,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
}
for (int index = 0; index < critterCount; index++) {
if (a2 == critters[index]) {
if (target == critters[index]) {
critterIndex = index;
}
}
@ -4223,7 +4229,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(a2->fid, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(target->fid, INVENTORY_WINDOW_TYPE_LOOT);
inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND);
bool isCaughtStealing = false;
@ -4252,11 +4258,11 @@ int inventoryOpenLooting(Object* a1, Object* a2)
if (keyCode == KEY_UPPERCASE_A) {
if (!_gIsSteal) {
int maxCarryWeight = critterGetStat(a1, STAT_CARRY_WEIGHT);
int currentWeight = objectGetInventoryWeight(a1);
int newInventoryWeight = objectGetInventoryWeight(a2);
int maxCarryWeight = critterGetStat(looter, STAT_CARRY_WEIGHT);
int currentWeight = objectGetInventoryWeight(looter);
int newInventoryWeight = objectGetInventoryWeight(target);
if (newInventoryWeight <= maxCarryWeight - currentWeight) {
itemMoveAll(a2, a1);
itemMoveAll(target, looter);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
} else {
@ -4280,14 +4286,14 @@ int inventoryOpenLooting(Object* a1, Object* a2)
critterIndex = critterCount - 1;
}
a2 = critters[critterIndex];
_target_pud = &(a2->data.inventory);
_target_stack[0] = a2;
target = critters[critterIndex];
_target_pud = &(target->data.inventory);
_target_stack[0] = target;
_target_curr_stack = 0;
_target_stack_offset[0] = 0;
_display_target_inventory(0, -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(a2->fid, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(target->fid, INVENTORY_WINDOW_TYPE_LOOT);
}
} else if (keyCode == KEY_ARROW_DOWN) {
if (_stack_offset[_curr_stack] + gInventorySlotsCount < _pud->length) {
@ -4302,14 +4308,14 @@ int inventoryOpenLooting(Object* a1, Object* a2)
critterIndex = 0;
}
a2 = critters[critterIndex];
_target_pud = &(a2->data.inventory);
_target_stack[0] = a2;
target = critters[critterIndex];
_target_pud = &(target->data.inventory);
_target_stack[0] = target;
_target_curr_stack = 0;
_target_stack_offset[0] = 0;
_display_target_inventory(0, -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(a2->fid, INVENTORY_WINDOW_TYPE_LOOT);
_display_body(target->fid, INVENTORY_WINDOW_TYPE_LOOT);
}
} else if (keyCode == KEY_CTRL_ARROW_UP) {
if (_target_stack_offset[_target_curr_stack] > 0) {
@ -4337,16 +4343,16 @@ int inventoryOpenLooting(Object* a1, Object* a2)
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_LOOT);
} else {
int v40 = keyCode - 1000;
if (v40 + _stack_offset[_curr_stack] < _pud->length) {
int slotIndex = keyCode - 1000;
if (slotIndex + _stack_offset[_curr_stack] < _pud->length) {
_gStealCount += 1;
_gStealSize += itemGetSize(_stack[_curr_stack]);
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (v40 + _stack_offset[_curr_stack] + 1)]);
int rc = _move_inventory(inventoryItem->item, v40, _target_stack[_target_curr_stack], true);
if (rc == 1) {
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (slotIndex + _stack_offset[_curr_stack] + 1)]);
InventoryMoveResult rc = _move_inventory(inventoryItem->item, slotIndex, _target_stack[_target_curr_stack], true);
if (rc == INVENTORY_MOVE_RESULT_CAUGHT_STEALING) {
isCaughtStealing = true;
} else if (rc == 2) {
} else if (rc == INVENTORY_MOVE_RESULT_SUCCESS) {
stealingXp += stealingXpBonus;
stealingXpBonus += 10;
}
@ -4361,16 +4367,16 @@ int inventoryOpenLooting(Object* a1, Object* a2)
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_LOOT);
} else {
int v46 = keyCode - 2000;
if (v46 + _target_stack_offset[_target_curr_stack] < _target_pud->length) {
int slotIndex = keyCode - 2000;
if (slotIndex + _target_stack_offset[_target_curr_stack] < _target_pud->length) {
_gStealCount += 1;
_gStealSize += itemGetSize(_stack[_curr_stack]);
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (v46 + _target_stack_offset[_target_curr_stack] + 1)]);
int rc = _move_inventory(inventoryItem->item, v46, _target_stack[_target_curr_stack], false);
if (rc == 1) {
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (slotIndex + _target_stack_offset[_target_curr_stack] + 1)]);
InventoryMoveResult rc = _move_inventory(inventoryItem->item, slotIndex, _target_stack[_target_curr_stack], false);
if (rc == INVENTORY_MOVE_RESULT_CAUGHT_STEALING) {
isCaughtStealing = true;
} else if (rc == 2) {
} else if (rc == INVENTORY_MOVE_RESULT_SUCCESS) {
stealingXp += stealingXpBonus;
stealingXpBonus += 10;
}
@ -4432,43 +4438,37 @@ int inventoryOpenLooting(Object* a1, Object* a2)
if (_gIsSteal) {
if (item1 != NULL) {
item1->flags |= OBJECT_IN_LEFT_HAND;
itemAdd(a2, item1, 1);
itemAdd(target, item1, 1);
}
if (item2 != NULL) {
item2->flags |= OBJECT_IN_RIGHT_HAND;
itemAdd(a2, item2, 1);
itemAdd(target, item2, 1);
}
if (armor != NULL) {
armor->flags |= OBJECT_WORN;
itemAdd(a2, armor, 1);
itemAdd(target, armor, 1);
}
}
itemMoveAll(a1a, a2);
objectDestroy(a1a, NULL);
itemMoveAll(hiddenBox, target);
objectDestroy(hiddenBox, NULL);
if (_gIsSteal) {
if (!isCaughtStealing) {
if (stealingXp > 0) {
if (!objectIsPartyMember(a2)) {
stealingXp = std::min(300 - skillGetValue(a1, SKILL_STEAL), stealingXp);
debugPrint("\n[[[%d]]]", 300 - skillGetValue(a1, SKILL_STEAL));
if (_gIsSteal && !isCaughtStealing && stealingXp > 0 && !objectIsPartyMember(target)) {
stealingXp = std::min(300 - skillGetValue(looter, SKILL_STEAL), stealingXp);
debugPrint("\n[[[%d]]]", 300 - skillGetValue(looter, SKILL_STEAL));
// SFALL: Display actual xp received.
int xpGained;
pcAddExperience(stealingXp, &xpGained);
// SFALL: Display actual xp received.
int xpGained;
pcAddExperience(stealingXp, &xpGained);
// You gain %d experience points for successfully using your Steal skill.
messageListItem.num = 29;
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
char formattedText[200];
snprintf(formattedText, sizeof(formattedText), messageListItem.text, xpGained);
displayMonitorAddMessage(formattedText);
}
}
}
// You gain %d experience points for successfully using your Steal skill.
messageListItem.num = 29;
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
char formattedText[200];
snprintf(formattedText, sizeof(formattedText), messageListItem.text, xpGained);
displayMonitorAddMessage(formattedText);
}
}
@ -4477,36 +4477,30 @@ int inventoryOpenLooting(Object* a1, Object* a2)
// NOTE: Uninline.
inventoryCommonFree();
if (_gIsSteal) {
if (isCaughtStealing) {
if (_gStealCount > 0) {
if (_obj_sid(a2, &sid) != -1) {
scriptSetObjects(sid, a1, NULL);
scriptExecProc(sid, SCRIPT_PROC_PICKUP);
if (_gIsSteal && isCaughtStealing && _gStealCount > 0 && _obj_sid(target, &sid) != -1) {
scriptSetObjects(sid, looter, NULL);
scriptExecProc(sid, SCRIPT_PROC_PICKUP);
// TODO: Looks like inlining, script is not used.
Script* script;
scriptGetScript(sid, &script);
}
}
}
// TODO: Looks like inlining, script is not used.
Script* script;
scriptGetScript(sid, &script);
}
return 0;
}
// 0x4746A0
int inventoryOpenStealing(Object* a1, Object* a2)
int inventoryOpenStealing(Object* thief, Object* target)
{
if (a1 == a2) {
if (thief == target) {
return -1;
}
_gIsSteal = PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER && critterIsActive(a2);
_gIsSteal = PID_TYPE(thief->pid) == OBJ_TYPE_CRITTER && critterIsActive(target);
_gStealCount = 0;
_gStealSize = 0;
int rc = inventoryOpenLooting(a1, a2);
int rc = inventoryOpenLooting(thief, target);
_gIsSteal = 0;
_gStealCount = 0;
@ -4516,37 +4510,37 @@ int inventoryOpenStealing(Object* a1, Object* a2)
}
// 0x474708
static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object* targetObj, bool isPlanting)
{
bool v38 = true;
bool needRefresh = true;
Rect rect;
int quantity;
if (a4) {
if (isPlanting) {
rect.left = INVENTORY_LOOT_LEFT_SCROLLER_X;
rect.top = INVENTORY_SLOT_HEIGHT * a2 + INVENTORY_LOOT_LEFT_SCROLLER_Y;
rect.top = INVENTORY_SLOT_HEIGHT * slotIndex + INVENTORY_LOOT_LEFT_SCROLLER_Y;
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (a2 + _stack_offset[_curr_stack] + 1)]);
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (slotIndex + _stack_offset[_curr_stack] + 1)]);
quantity = inventoryItem->quantity;
if (quantity > 1) {
_display_inventory(_stack_offset[_curr_stack], a2, INVENTORY_WINDOW_TYPE_LOOT);
v38 = false;
_display_inventory(_stack_offset[_curr_stack], slotIndex, INVENTORY_WINDOW_TYPE_LOOT);
needRefresh = false;
}
} else {
rect.left = INVENTORY_LOOT_RIGHT_SCROLLER_X;
rect.top = INVENTORY_SLOT_HEIGHT * a2 + INVENTORY_LOOT_RIGHT_SCROLLER_Y;
rect.top = INVENTORY_SLOT_HEIGHT * slotIndex + INVENTORY_LOOT_RIGHT_SCROLLER_Y;
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (a2 + _target_stack_offset[_target_curr_stack] + 1)]);
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (slotIndex + _target_stack_offset[_target_curr_stack] + 1)]);
quantity = inventoryItem->quantity;
if (quantity > 1) {
_display_target_inventory(_target_stack_offset[_target_curr_stack], a2, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
_display_target_inventory(_target_stack_offset[_target_curr_stack], slotIndex, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
windowRefresh(gInventoryWindow);
v38 = false;
needRefresh = false;
}
}
if (v38) {
if (needRefresh) {
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
FrmImage backgroundFrmImage;
@ -4566,7 +4560,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
}
FrmImage itemInventoryFrmImage;
int itemInventoryFid = itemGetInventoryFid(a1);
int itemInventoryFid = itemGetInventoryFid(item);
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
int width = itemInventoryFrmImage.getWidth();
int height = itemInventoryFrmImage.getHeight();
@ -4589,28 +4583,28 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
soundPlayFile("iputdown");
}
int rc = 0;
InventoryMoveResult result = INVENTORY_MOVE_RESULT_FAILED;
MessageListItem messageListItem;
if (a4) {
if (isPlanting) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_RIGHT_SCROLLER_X, INVENTORY_LOOT_RIGHT_SCROLLER_Y, INVENTORY_LOOT_RIGHT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_RIGHT_SCROLLER_Y)) {
int quantityToMove;
if (quantity > 1) {
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, a1, quantity);
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
} else {
quantityToMove = 1;
}
if (quantityToMove != -1) {
if (_gIsSteal) {
if (skillsPerformStealing(_inven_dude, a3, a1, true) == 0) {
rc = 1;
if (skillsPerformStealing(_inven_dude, targetObj, item, true) == 0) {
result = INVENTORY_MOVE_RESULT_CAUGHT_STEALING;
}
}
if (rc != 1) {
if (itemMove(_inven_dude, a3, a1, quantityToMove) != -1) {
rc = 2;
if (result != INVENTORY_MOVE_RESULT_CAUGHT_STEALING) {
if (itemMove(_inven_dude, targetObj, item, quantityToMove) != -1) {
result = INVENTORY_MOVE_RESULT_SUCCESS;
} else {
// There is no space left for that item.
messageListItem.num = 26;
@ -4625,27 +4619,27 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_LEFT_SCROLLER_X, INVENTORY_LOOT_LEFT_SCROLLER_Y, INVENTORY_LOOT_LEFT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_LEFT_SCROLLER_Y)) {
int quantityToMove;
if (quantity > 1) {
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, a1, quantity);
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
} else {
quantityToMove = 1;
}
if (quantityToMove != -1) {
if (_gIsSteal) {
if (skillsPerformStealing(_inven_dude, a3, a1, false) == 0) {
rc = 1;
if (skillsPerformStealing(_inven_dude, targetObj, item, false) == 0) {
result = INVENTORY_MOVE_RESULT_CAUGHT_STEALING;
}
}
if (rc != 1) {
if (itemMove(a3, _inven_dude, a1, quantityToMove) == 0) {
if ((a1->flags & OBJECT_IN_RIGHT_HAND) != 0) {
a3->fid = buildFid(FID_TYPE(a3->fid), a3->fid & 0xFFF, FID_ANIM_TYPE(a3->fid), 0, a3->rotation + 1);
if (result != INVENTORY_MOVE_RESULT_CAUGHT_STEALING) {
if (itemMove(targetObj, _inven_dude, item, quantityToMove) == 0) {
if ((item->flags & OBJECT_IN_RIGHT_HAND) != 0) {
targetObj->fid = buildFid(FID_TYPE(targetObj->fid), targetObj->fid & 0xFFF, FID_ANIM_TYPE(targetObj->fid), 0, targetObj->rotation + 1);
}
a3->flags &= ~OBJECT_EQUIPPED;
targetObj->flags &= ~OBJECT_EQUIPPED;
rc = 2;
result = INVENTORY_MOVE_RESULT_SUCCESS;
} else {
// You cannot pick that up. You are at your maximum weight capacity.
messageListItem.num = 25;
@ -4660,7 +4654,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND);
return rc;
return result;
}
// 0x474B2C
@ -5022,67 +5016,67 @@ static void inventoryWindowRenderInnerInventories(int win, Object* a2, Object* a
}
// 0x4757F0
void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object* bartererTable, int barterMod)
{
ScopedGameMode gm(GameMode::kBarter);
_barter_mod = a5;
_barter_mod = barterMod;
if (inventoryCommonInit() == -1) {
return;
}
Object* armor = critterGetArmor(a2);
Object* armor = critterGetArmor(barterer);
if (armor != NULL) {
itemRemove(a2, armor, 1);
itemRemove(barterer, armor, 1);
}
Object* item1 = NULL;
Object* item2 = critterGetItem2(a2);
Object* item2 = critterGetItem2(barterer);
if (item2 != NULL) {
itemRemove(a2, item2, 1);
itemRemove(barterer, item2, 1);
} else {
if (!gGameDialogSpeakerIsPartyMember) {
item1 = _inven_find_type(a2, ITEM_TYPE_WEAPON, NULL);
item1 = _inven_find_type(barterer, ITEM_TYPE_WEAPON, NULL);
if (item1 != NULL) {
itemRemove(a2, item1, 1);
itemRemove(barterer, item1, 1);
}
}
}
Object* a1a = NULL;
if (objectCreateWithFidPid(&a1a, 0, 467) == -1) {
Object* hiddenBox = NULL;
if (objectCreateWithFidPid(&hiddenBox, 0, PROTO_ID_JESSE_CONTAINER) == -1) {
return;
}
_pud = &(_inven_dude->data.inventory);
_btable = a4;
_ptable = a3;
_btable = bartererTable;
_ptable = playerTable;
_ptable_offset = 0;
_btable_offset = 0;
_ptable_pud = &(a3->data.inventory);
_btable_pud = &(a4->data.inventory);
_ptable_pud = &(playerTable->data.inventory);
_btable_pud = &(bartererTable->data.inventory);
_barter_back_win = win;
_target_curr_stack = 0;
_target_pud = &(a2->data.inventory);
_target_pud = &(barterer->data.inventory);
_target_stack[0] = a2;
_target_stack[0] = barterer;
_target_stack_offset[0] = 0;
bool isoWasEnabled = _setup_inventory(INVENTORY_WINDOW_TYPE_TRADE);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[0], -1, INVENTORY_WINDOW_TYPE_TRADE);
_display_body(a2->fid, INVENTORY_WINDOW_TYPE_TRADE);
_display_body(barterer->fid, INVENTORY_WINDOW_TYPE_TRADE);
windowRefresh(_barter_back_win);
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND);
int modifier;
int npcReactionValue = reactionGetValue(a2);
int npcReactionValue = reactionGetValue(barterer);
int npcReactionType = reactionTranslateValue(npcReactionValue);
switch (npcReactionType) {
case NPC_REACTION_BAD:
@ -5115,19 +5109,19 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
break;
}
_barter_mod = a5 + modifier;
_barter_mod = barterMod + modifier;
if (keyCode == KEY_LOWERCASE_T || modifier <= -30) {
itemMoveAll(a4, a2);
itemMoveAll(a3, gDude);
itemMoveAll(bartererTable, barterer);
itemMoveAll(playerTable, gDude);
_barter_end_to_talk_to();
break;
} else if (keyCode == KEY_LOWERCASE_M) {
if (a3->data.inventory.length != 0 || _btable->data.inventory.length != 0) {
if (_barter_attempt_transaction(_inven_dude, a3, a2, a4) == 0) {
if (playerTable->data.inventory.length != 0 || _btable->data.inventory.length != 0) {
if (_barter_attempt_transaction(_inven_dude, playerTable, barterer, bartererTable) == 0) {
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
// Ok, that's a good trade.
MessageListItem messageListItem;
@ -5147,7 +5141,7 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
} else if (keyCode == KEY_PAGE_UP) {
if (_ptable_offset > 0) {
_ptable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (keyCode == KEY_ARROW_DOWN) {
if (_stack_offset[_curr_stack] + gInventorySlotsCount < _pud->length) {
@ -5157,17 +5151,17 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
} else if (keyCode == KEY_PAGE_DOWN) {
if (_ptable_offset + gInventorySlotsCount < _ptable_pud->length) {
_ptable_offset += 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (keyCode == KEY_CTRL_PAGE_DOWN) {
if (_btable_offset + gInventorySlotsCount < _btable_pud->length) {
_btable_offset++;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (keyCode == KEY_CTRL_PAGE_UP) {
if (_btable_offset > 0) {
_btable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (keyCode == KEY_CTRL_ARROW_UP) {
if (_target_stack_offset[_target_curr_stack] > 0) {
@ -5194,16 +5188,16 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
if (keyCode >= 1000 && keyCode <= 1000 + gInventorySlotsCount) {
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, a3, NULL, -1);
inventoryWindowRenderInnerInventories(win, playerTable, NULL, -1);
} else {
int v30 = keyCode - 1000;
if (v30 + _stack_offset[_curr_stack] < _pud->length) {
int v31 = _stack_offset[_curr_stack];
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (v30 + v31 + 1)]);
_barter_move_inventory(inventoryItem->item, inventoryItem->quantity, v30, v31, a2, a3, true);
int slotIndex = keyCode - 1000;
if (slotIndex + _stack_offset[_curr_stack] < _pud->length) {
int stackOffset = _stack_offset[_curr_stack];
InventoryItem* inventoryItem = &(_pud->items[_pud->length - (slotIndex + stackOffset + 1)]);
_barter_move_inventory(inventoryItem->item, inventoryItem->quantity, slotIndex, stackOffset, barterer, playerTable, true);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, a3, NULL, -1);
inventoryWindowRenderInnerInventories(win, playerTable, NULL, -1);
}
}
@ -5211,16 +5205,16 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
} else if (keyCode >= 2000 && keyCode <= 2000 + gInventorySlotsCount) {
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, NULL, a4, -1);
inventoryWindowRenderInnerInventories(win, NULL, bartererTable, -1);
} else {
int v35 = keyCode - 2000;
if (v35 + _target_stack_offset[_target_curr_stack] < _target_pud->length) {
int v36 = _target_stack_offset[_target_curr_stack];
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (v35 + v36 + 1)]);
_barter_move_inventory(inventoryItem->item, inventoryItem->quantity, v35, v36, a2, a4, false);
int slotIndex = keyCode - 2000;
if (slotIndex + _target_stack_offset[_target_curr_stack] < _target_pud->length) {
int stackOffset = _target_stack_offset[_target_curr_stack];
InventoryItem* inventoryItem = &(_target_pud->items[_target_pud->length - (slotIndex + stackOffset + 1)]);
_barter_move_inventory(inventoryItem->item, inventoryItem->quantity, slotIndex, stackOffset, barterer, bartererTable, false);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, NULL, a4, -1);
inventoryWindowRenderInnerInventories(win, NULL, bartererTable, -1);
}
}
@ -5228,15 +5222,15 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
} else if (keyCode >= 2300 && keyCode <= 2300 + gInventorySlotsCount) {
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, a3, NULL, -1);
inventoryWindowRenderInnerInventories(win, playerTable, NULL, -1);
} else {
int v41 = keyCode - 2300;
if (v41 < _ptable_pud->length) {
InventoryItem* inventoryItem = &(_ptable_pud->items[_ptable_pud->length - (v41 + _ptable_offset + 1)]);
_barter_move_from_table_inventory(inventoryItem->item, inventoryItem->quantity, v41, a2, a3, true);
int itemIndex = keyCode - 2300;
if (itemIndex < _ptable_pud->length) {
InventoryItem* inventoryItem = &(_ptable_pud->items[_ptable_pud->length - (itemIndex + _ptable_offset + 1)]);
_barter_move_from_table_inventory(inventoryItem->item, inventoryItem->quantity, itemIndex, barterer, playerTable, true);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, a3, NULL, -1);
inventoryWindowRenderInnerInventories(win, playerTable, NULL, -1);
}
}
@ -5244,15 +5238,15 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
} else if (keyCode >= 2400 && keyCode <= 2400 + gInventorySlotsCount) {
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, NULL, a4, -1);
inventoryWindowRenderInnerInventories(win, NULL, bartererTable, -1);
} else {
int v45 = keyCode - 2400;
if (v45 < _btable_pud->length) {
InventoryItem* inventoryItem = &(_btable_pud->items[_btable_pud->length - (v45 + _btable_offset + 1)]);
_barter_move_from_table_inventory(inventoryItem->item, inventoryItem->quantity, v45, a2, a4, false);
_barter_move_from_table_inventory(inventoryItem->item, inventoryItem->quantity, v45, barterer, bartererTable, false);
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
inventoryWindowRenderInnerInventories(win, NULL, a4, -1);
inventoryWindowRenderInnerInventories(win, NULL, bartererTable, -1);
}
}
@ -5281,12 +5275,12 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
if (wheelY > 0) {
if (_ptable_offset > 0) {
_ptable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (wheelY < 0) {
if (_ptable_offset + gInventorySlotsCount < _ptable_pud->length) {
_ptable_offset += 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) {
@ -5313,12 +5307,12 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
if (wheelY > 0) {
if (_btable_offset > 0) {
_btable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
} else if (wheelY < 0) {
if (_btable_offset + gInventorySlotsCount < _btable_pud->length) {
_btable_offset++;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
inventoryWindowRenderInnerInventories(win, playerTable, bartererTable, -1);
}
}
}
@ -5329,21 +5323,21 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
sharedFpsLimiter.throttle();
}
itemMoveAll(a1a, a2);
objectDestroy(a1a, NULL);
itemMoveAll(hiddenBox, barterer);
objectDestroy(hiddenBox, NULL);
if (armor != NULL) {
armor->flags |= OBJECT_WORN;
itemAdd(a2, armor, 1);
itemAdd(barterer, armor, 1);
}
if (item2 != NULL) {
item2->flags |= OBJECT_IN_RIGHT_HAND;
itemAdd(a2, item2, 1);
itemAdd(barterer, item2, 1);
}
if (item1 != NULL) {
itemAdd(a2, item1, 1);
itemAdd(barterer, item1, 1);
}
_exit_inventory(isoWasEnabled);

View File

@ -23,9 +23,9 @@ int _inven_wield(Object* a1, Object* a2, int a3);
int _invenWieldFunc(Object* a1, Object* a2, int a3, bool a4);
int _inven_unwield(Object* critter_obj, int a2);
int _invenUnwieldFunc(Object* obj, int a2, int a3);
int inventoryOpenLooting(Object* a1, Object* a2);
int inventoryOpenStealing(Object* a1, Object* a2);
void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5);
int inventoryOpenLooting(Object* looter, Object* target);
int inventoryOpenStealing(Object* thief, Object* target);
void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object* bartererTable, int barterMod);
int _inven_set_timer(Object* a1);
Object* inven_get_current_target_obj();

View File

@ -43,8 +43,8 @@ namespace fallout {
static int _item_load_(File* stream);
static void _item_compact(int inventoryItemIndex, Inventory* inventory);
static int _item_move_func(Object* a1, Object* a2, Object* a3, int quantity, bool a5);
static bool _item_identical(Object* a1, Object* a2);
static int _item_move_func(Object* source, Object* target, Object* item, int quantity, bool force);
static bool _item_identical(Object* item1, Object* item2);
static int stealthBoyTurnOn(Object* object);
static int stealthBoyTurnOff(Object* critter, Object* item);
static int _insert_drug_effect(Object* critter_obj, Object* item_obj, int a3, int* stats, int* mods);
@ -301,7 +301,7 @@ int itemAttemptAdd(Object* owner, Object* itemToAdd, int quantity)
return -5;
}
if ((proto->critter.flags & 0x02) == 0) {
if ((proto->critter.flags & CRITTER_BARTER) == 0) {
return -5;
}
}
@ -475,36 +475,36 @@ static void _item_compact(int inventoryItemIndex, Inventory* inventory)
}
// 0x477608
static int _item_move_func(Object* a1, Object* a2, Object* a3, int quantity, bool a5)
static int _item_move_func(Object* source, Object* target, Object* item, int quantity, bool force)
{
if (itemRemove(a1, a3, quantity) == -1) {
if (itemRemove(source, item, quantity) == -1) {
return -1;
}
int rc;
if (a5) {
rc = itemAdd(a2, a3, quantity);
if (force) {
rc = itemAdd(target, item, quantity);
} else {
rc = itemAttemptAdd(a2, a3, quantity);
rc = itemAttemptAdd(target, item, quantity);
}
if (rc != 0) {
if (itemAdd(a1, a3, quantity) != 0) {
Object* owner = objectGetOwner(a1);
if (itemAdd(source, item, quantity) != 0) {
Object* owner = objectGetOwner(source);
if (owner == NULL) {
owner = a1;
owner = source;
}
if (owner->tile != -1) {
Rect updatedRect;
_obj_connect(a3, owner->tile, owner->elevation, &updatedRect);
_obj_connect(item, owner->tile, owner->elevation, &updatedRect);
tileWindowRefreshRect(&updatedRect, gElevation);
}
}
return -1;
}
a3->owner = a2;
item->owner = target;
return 0;
}
@ -645,53 +645,53 @@ int itemDropAll(Object* critter, int tile)
}
// 0x4779F0
static bool _item_identical(Object* a1, Object* a2)
static bool _item_identical(Object* item1, Object* item2)
{
if (a1->pid != a2->pid) {
if (item1->pid != item2->pid) {
return false;
}
if (a1->sid != a2->sid) {
if (item1->sid != item2->sid) {
return false;
}
if ((a1->flags & (OBJECT_EQUIPPED | OBJECT_QUEUED)) != 0) {
if ((item1->flags & (OBJECT_EQUIPPED | OBJECT_QUEUED)) != 0) {
return false;
}
if ((a2->flags & (OBJECT_EQUIPPED | OBJECT_QUEUED)) != 0) {
if ((item2->flags & (OBJECT_EQUIPPED | OBJECT_QUEUED)) != 0) {
return false;
}
Proto* proto;
protoGetProto(a1->pid, &proto);
protoGetProto(item1->pid, &proto);
if (proto->item.type == ITEM_TYPE_CONTAINER) {
return false;
}
Inventory* inventory1 = &(a1->data.inventory);
Inventory* inventory2 = &(a2->data.inventory);
Inventory* inventory1 = &(item1->data.inventory);
Inventory* inventory2 = &(item2->data.inventory);
if (inventory1->length != 0 || inventory2->length != 0) {
return false;
}
int v1;
if (proto->item.type == ITEM_TYPE_AMMO || a1->pid == PROTO_ID_MONEY) {
v1 = a2->data.item.ammo.quantity;
a2->data.item.ammo.quantity = a1->data.item.ammo.quantity;
if (proto->item.type == ITEM_TYPE_AMMO || item1->pid == PROTO_ID_MONEY) {
v1 = item2->data.item.ammo.quantity;
item2->data.item.ammo.quantity = item1->data.item.ammo.quantity;
}
// NOTE: Probably inlined memcmp, but I'm not sure why it only checks 32
// bytes.
int i;
for (i = 0; i < 8; i++) {
if (a1->field_2C_array[i] != a2->field_2C_array[i]) {
if (item1->field_2C_array[i] != item2->field_2C_array[i]) {
break;
}
}
if (proto->item.type == ITEM_TYPE_AMMO || a1->pid == PROTO_ID_MONEY) {
a2->data.item.ammo.quantity = v1;
if (proto->item.type == ITEM_TYPE_AMMO || item1->pid == PROTO_ID_MONEY) {
item2->data.item.ammo.quantity = v1;
}
return i == 8;

View File

@ -1083,29 +1083,29 @@ static int _protinstTestDroppedExplosive(Object* a1)
_compute_explosion_on_extras(&attack, 0, 0, 1);
int team = gDude->data.critter.combat.team;
Object* v2 = NULL;
Object* watcher = NULL;
for (int index = 0; index < attack.extrasLength; index++) {
Object* v5 = attack.extras[index];
if (v5 != gDude
&& v5->data.critter.combat.team != team
&& statRoll(v5, STAT_PERCEPTION, 0, NULL) >= 2) {
_critter_set_who_hit_me(v5, gDude);
if (v2 == NULL) {
v2 = v5;
if (watcher == NULL) {
watcher = v5;
}
}
}
if (v2 != NULL && !isInCombat()) {
STRUCT_664980 attack;
attack.attacker = v2;
attack.defender = gDude;
attack.actionPointsBonus = 0;
attack.accuracyBonus = 0;
attack.minDamage = 0;
attack.maxDamage = 99999;
attack.field_1C = 0;
scriptsRequestCombat(&attack);
if (watcher != NULL && !isInCombat()) {
CombatStartData combat;
combat.attacker = watcher;
combat.defender = gDude;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.minDamage = 0;
combat.maxDamage = 99999;
combat.overrideAttackResults = 0;
scriptsRequestCombat(&combat);
}
}
return 0;

View File

@ -182,6 +182,7 @@ enum {
PROTO_ID_MIRRORED_SHADES = 433,
PROTO_ID_RAIDERS_MAP = 444,
PROTO_ID_CAR_TRUNK = 455,
PROTO_ID_JESSE_CONTAINER = 467,
PROTO_ID_PIP_BOY_LINGUAL_ENHANCER = 499,
PROTO_ID_PIP_BOY_MEDICAL_ENHANCER = 516,
PROTO_ID_SURVEY_MAP = 523,

View File

@ -37,7 +37,7 @@ typedef struct EventTypeDescription {
static int flareEventProcess(Object* obj, void* data);
static int explosionEventProcess(Object* obj, void* data);
static int _queue_explode_exit(Object* obj, void* data);
static int _queue_do_explosion_(Object* obj, bool a2);
static int _queue_do_explosion_(Object* obj, bool animate);
static int explosionFailureEventProcess(Object* obj, void* data);
// Last queue list node found during [queueFindFirstEvent] and
@ -454,7 +454,7 @@ static int _queue_explode_exit(Object* obj, void* data)
}
// 0x4A2834
static int _queue_do_explosion_(Object* explosive, bool a2)
static int _queue_do_explosion_(Object* explosive, bool animate)
{
int tile;
int elevation;
@ -483,7 +483,7 @@ static int _queue_do_explosion_(Object* explosive, bool a2)
}
}
if (actionExplode(tile, elevation, minDamage, maxDamage, gDude, a2) == -2) {
if (actionExplode(tile, elevation, minDamage, maxDamage, gDude, animate) == -2) {
queueAddEvent(50, explosive, NULL, EVENT_TYPE_EXPLOSION);
} else {
_obj_destroy(explosive);

View File

@ -213,10 +213,10 @@ static char* _blank_str = byte_50D6C0;
static unsigned int gScriptsRequests;
// 0x664958
static STRUCT_664980 stru_664958;
static CombatStartData gScriptsRequestedCSD;
// 0x664980
static STRUCT_664980 stru_664980;
static CombatStartData gScriptsCSD;
// 0x6649A8
static int gScriptsRequestedElevatorType;
@ -884,7 +884,7 @@ static int scriptsClearPendingRequests()
// 0x4A3F90
int _scripts_clear_combat_requests(Script* script)
{
if ((gScriptsRequests & SCRIPT_REQUEST_COMBAT) != 0 && stru_664958.attacker == script->owner) {
if ((gScriptsRequests & SCRIPT_REQUEST_COMBAT) != 0 && gScriptsRequestedCSD.attacker == script->owner) {
gScriptsRequests &= ~(SCRIPT_REQUEST_0x0400 | SCRIPT_REQUEST_COMBAT);
}
return 0;
@ -901,14 +901,14 @@ int scriptsHandleRequests()
if (!_action_explode_running()) {
// entering combat
gScriptsRequests &= ~(SCRIPT_REQUEST_0x0400 | SCRIPT_REQUEST_COMBAT);
memcpy(&stru_664980, &stru_664958, sizeof(stru_664980));
memcpy(&gScriptsCSD, &gScriptsRequestedCSD, sizeof(gScriptsCSD));
if ((gScriptsRequests & SCRIPT_REQUEST_0x40) != 0) {
gScriptsRequests &= ~SCRIPT_REQUEST_0x40;
_combat(NULL);
} else {
_combat(&stru_664980);
memset(&stru_664980, 0, sizeof(stru_664980));
_combat(&gScriptsCSD);
memset(&gScriptsCSD, 0, sizeof(gScriptsCSD));
}
}
}
@ -1097,14 +1097,14 @@ int _scripts_check_state_in_combat()
}
// 0x4A457C
int scriptsRequestCombat(STRUCT_664980* a1)
int scriptsRequestCombat(CombatStartData* combat)
{
if ((gScriptsRequests & SCRIPT_REQUEST_0x0400) != 0) {
return -1;
}
if (a1) {
memcpy(&stru_664958, a1, sizeof(stru_664958));
if (combat) {
memcpy(&gScriptsRequestedCSD, combat, sizeof(gScriptsRequestedCSD));
} else {
gScriptsRequests |= SCRIPT_REQUEST_0x40;
}
@ -1117,10 +1117,10 @@ int scriptsRequestCombat(STRUCT_664980* a1)
// Likely related to random encounter, ala scriptsRequestRandomEncounter RELEASE
//
// 0x4A45D4
void _scripts_request_combat_locked(STRUCT_664980* a1)
void _scripts_request_combat_locked(CombatStartData* combat)
{
if (a1 != NULL) {
memcpy(&stru_664958, a1, sizeof(stru_664958));
if (combat != NULL) {
memcpy(&gScriptsRequestedCSD, combat, sizeof(gScriptsRequestedCSD));
} else {
gScriptsRequests |= SCRIPT_REQUEST_0x40;
}

View File

@ -175,8 +175,8 @@ int scriptEventProcess(Object* obj, void* data);
int _scripts_clear_combat_requests(Script* script);
int scriptsHandleRequests();
int _scripts_check_state_in_combat();
int scriptsRequestCombat(STRUCT_664980* a1);
void _scripts_request_combat_locked(STRUCT_664980* ptr);
int scriptsRequestCombat(CombatStartData* combat);
void _scripts_request_combat_locked(CombatStartData* combat);
void scripts_request_townmap();
void scriptsRequestWorldMap();
int scriptsRequestElevator(Object* a1, int a2);

View File

@ -43,12 +43,12 @@ typedef struct SkillDescription {
int statModifier;
int stat1;
int stat2;
int field_20;
int baseValueMult;
int experience;
int field_28;
} SkillDescription;
static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4, int a5);
static void _show_skill_use_messages(Object* obj, int skill, Object* target, int successCount, int criticalChanceModifier);
static int skillGetFreeUsageSlot(int skill);
static int skill_use_slot_clear();
@ -240,16 +240,16 @@ int skillGetValue(Object* critter, int skill)
SkillDescription* skillDescription = &(gSkillDescriptions[skill]);
int v7 = critterGetStat(critter, skillDescription->stat1);
int statValueSum = critterGetStat(critter, skillDescription->stat1);
if (skillDescription->stat2 != -1) {
v7 += critterGetStat(critter, skillDescription->stat2);
statValueSum += critterGetStat(critter, skillDescription->stat2);
}
int value = skillDescription->defaultValue + skillDescription->statModifier * v7 + baseValue * skillDescription->field_20;
int value = skillDescription->defaultValue + skillDescription->statModifier * statValueSum + baseValue * skillDescription->baseValueMult;
if (critter == gDude) {
if (skillIsTagged(skill)) {
value += baseValue * skillDescription->field_20;
value += baseValue * skillDescription->baseValueMult;
if (!perkGetRank(critter, PERK_TAG) || skill != gTaggedSkills[3]) {
value += 20;
@ -503,13 +503,13 @@ int skillGetFrmId(int skill)
}
// 0x4AAC2C
static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4, int criticalChanceModifier)
static void _show_skill_use_messages(Object* obj, int skill, Object* target, int successCount, int criticalChanceModifier)
{
if (obj != gDude) {
return;
}
if (a4 <= 0) {
if (successCount <= 0) {
return;
}
@ -524,11 +524,11 @@ static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4,
baseExperience += abs(criticalChanceModifier);
}
int xpToAdd = a4 * baseExperience;
int xpToAdd = successCount * baseExperience;
int before = pcGetStat(PC_STAT_EXPERIENCE);
if (pcAddExperience(xpToAdd) == 0 && a4 > 0) {
if (pcAddExperience(xpToAdd) == 0 && successCount > 0) {
MessageListItem messageListItem;
messageListItem.num = 505; // You earn %d XP for honing your skills
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
@ -543,14 +543,14 @@ static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4,
// skill_use
// 0x4AAD08
int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
int skillUse(Object* obj, Object* target, int skill, int criticalChanceModifier)
{
MessageListItem messageListItem;
char text[60];
bool giveExp = true;
int currentHp = critterGetStat(a2, STAT_CURRENT_HIT_POINTS);
int maximumHp = critterGetStat(a2, STAT_MAXIMUM_HIT_POINTS);
int currentHp = critterGetStat(target, STAT_CURRENT_HIT_POINTS);
int maximumHp = critterGetStat(target, STAT_MAXIMUM_HIT_POINTS);
int hpToHeal = 0;
int maximumHpToHeal = 0;
@ -567,8 +567,8 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
int criticalChance = critterGetStat(obj, STAT_CRITICAL_CHANCE) + criticalChanceModifier;
int damageHealingAttempts = 1;
int v1 = 0;
int v2 = 0;
int successCount = 0;
bool skillUseSlotAdded = 0;
switch (skill) {
case SKILL_FIRST_AID:
@ -584,7 +584,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
return -1;
}
if (critterIsDead(a2)) {
if (critterIsDead(target)) {
// 512: You can't heal the dead.
// 513: Let the dead rest in peace.
// 514: It's dead, get over it.
@ -600,7 +600,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
paletteFadeTo(gPaletteBlack);
int roll;
if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) {
if (critterGetBodyType(target) == BODY_TYPE_ROBOTIC) {
roll = ROLL_FAILURE;
} else {
roll = skillRoll(obj, skill, criticalChance, &hpToHeal);
@ -608,7 +608,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 1, maximumHpToHeal + 5);
critterAdjustHitPoints(a2, hpToHeal);
critterAdjustHitPoints(target, hpToHeal);
if (obj == gDude) {
// You heal %d hit points.
@ -625,13 +625,13 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
displayMonitorAddMessage(text);
}
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
target->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
skillUpdateLastUse(SKILL_FIRST_AID);
v1 = 1;
successCount = 1;
if (a2 == gDude) {
if (target == gDude) {
interfaceRenderHitPoints(true);
}
} else {
@ -651,15 +651,15 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (obj == gDude) {
// 501: You look healty already
// 502: %s looks healthy already
messageListItem.num = (a2 == gDude ? 501 : 502);
messageListItem.num = (target == gDude ? 501 : 502);
if (!messageListGetItem(&gSkillsMessageList, &messageListItem)) {
return -1;
}
if (a2 == gDude) {
if (target == gDude) {
strcpy(text, messageListItem.text);
} else {
snprintf(text, sizeof(text), messageListItem.text, objectGetName(a2));
snprintf(text, sizeof(text), messageListItem.text, objectGetName(target));
}
displayMonitorAddMessage(text);
@ -685,7 +685,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
return -1;
}
if (critterIsDead(a2)) {
if (critterIsDead(target)) {
// 512: You can't heal the dead.
// 513: Let the dead rest in peace.
// 514: It's dead, get over it.
@ -696,15 +696,15 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
break;
}
if (currentHp < maximumHp || critterIsCrippled(a2)) {
if (currentHp < maximumHp || critterIsCrippled(target)) {
paletteFadeTo(gPaletteBlack);
if (critterGetBodyType(a2) != BODY_TYPE_ROBOTIC && critterIsCrippled(a2)) {
if (critterGetBodyType(target) != BODY_TYPE_ROBOTIC && critterIsCrippled(target)) {
int flags[HEALABLE_DAMAGE_FLAGS_LENGTH];
memcpy(flags, gHealableDamageFlags, sizeof(gHealableDamageFlags));
for (int index = 0; index < HEALABLE_DAMAGE_FLAGS_LENGTH; index++) {
if ((a2->data.critter.combat.results & flags[index]) != 0) {
if ((target->data.critter.combat.results & flags[index]) != 0) {
damageHealingAttempts++;
int roll = skillRoll(obj, skill, criticalChance, &hpToHeal);
@ -722,21 +722,21 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
MessageListItem prefix;
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) {
a2->data.critter.combat.results &= ~flags[index];
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
target->data.critter.combat.results &= ~flags[index];
target->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
// 520: You heal your %s.
// 521: You heal the %s.
prefix.num = (a2 == gDude ? 520 : 521);
prefix.num = (target == gDude ? 520 : 521);
skillUpdateLastUse(SKILL_DOCTOR);
v1 = 1;
v2 = 1;
successCount = 1;
skillUseSlotAdded = 1;
} else {
// 525: You fail to heal your %s.
// 526: You fail to heal the %s.
prefix.num = (a2 == gDude ? 525 : 526);
prefix.num = (target == gDude ? 525 : 526);
}
if (!messageListGetItem(&gSkillsMessageList, &prefix)) {
@ -745,7 +745,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
snprintf(text, sizeof(text), prefix.text, messageListItem.text);
displayMonitorAddMessage(text);
_show_skill_use_messages(obj, skill, a2, v1, criticalChanceModifier);
_show_skill_use_messages(obj, skill, target, successCount, criticalChanceModifier);
giveExp = false;
}
@ -753,7 +753,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
}
int roll;
if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) {
if (critterGetBodyType(target) == BODY_TYPE_ROBOTIC) {
roll = ROLL_FAILURE;
} else {
int skillValue = skillGetValue(obj, skill);
@ -762,7 +762,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 4, maximumHpToHeal + 10);
critterAdjustHitPoints(a2, hpToHeal);
critterAdjustHitPoints(target, hpToHeal);
if (obj == gDude) {
// You heal %d hit points.
@ -778,18 +778,18 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
displayMonitorAddMessage(text);
}
if (!v2) {
if (!skillUseSlotAdded) {
skillUpdateLastUse(SKILL_DOCTOR);
}
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
target->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
if (a2 == gDude) {
if (target == gDude) {
interfaceRenderHitPoints(true);
}
v1 = 1;
_show_skill_use_messages(obj, skill, a2, v1, criticalChanceModifier);
successCount = 1;
_show_skill_use_messages(obj, skill, target, successCount, criticalChanceModifier);
scriptsExecMapUpdateProc();
paletteFadeTo(_cmap);
@ -811,15 +811,15 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (obj == gDude) {
// 501: You look healty already
// 502: %s looks healthy already
messageListItem.num = (a2 == gDude ? 501 : 502);
messageListItem.num = (target == gDude ? 501 : 502);
if (!messageListGetItem(&gSkillsMessageList, &messageListItem)) {
return -1;
}
if (a2 == gDude) {
if (target == gDude) {
strcpy(text, messageListItem.text);
} else {
snprintf(text, sizeof(text), messageListItem.text, objectGetName(a2));
snprintf(text, sizeof(text), messageListItem.text, objectGetName(target));
}
displayMonitorAddMessage(text);
@ -837,7 +837,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
case SKILL_LOCKPICK:
break;
case SKILL_STEAL:
scriptsRequestStealing(obj, a2);
scriptsRequestStealing(obj, target);
break;
case SKILL_TRAPS:
messageListItem.num = 551; // You fail to find any traps.
@ -854,7 +854,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
return -1;
case SKILL_REPAIR:
if (critterGetBodyType(a2) != BODY_TYPE_ROBOTIC) {
if (critterGetBodyType(target) != BODY_TYPE_ROBOTIC) {
// You cannot repair that.
messageListItem.num = 553;
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
@ -874,7 +874,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
return -1;
}
if (critterIsDead(a2)) {
if (critterIsDead(target)) {
// You got it?
messageListItem.num = 1101;
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
@ -883,14 +883,14 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
break;
}
if (currentHp < maximumHp || critterIsCrippled(a2)) {
if (currentHp < maximumHp || critterIsCrippled(target)) {
int flags[REPAIRABLE_DAMAGE_FLAGS_LENGTH];
memcpy(flags, gRepairableDamageFlags, sizeof(gRepairableDamageFlags));
paletteFadeTo(gPaletteBlack);
for (int index = 0; index < REPAIRABLE_DAMAGE_FLAGS_LENGTH; index++) {
if ((a2->data.critter.combat.results & flags[index]) != 0) {
if ((target->data.critter.combat.results & flags[index]) != 0) {
damageHealingAttempts++;
int roll = skillRoll(obj, skill, criticalChance, &hpToHeal);
@ -908,20 +908,20 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
MessageListItem prefix;
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) {
a2->data.critter.combat.results &= ~flags[index];
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
target->data.critter.combat.results &= ~flags[index];
target->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
// 520: You heal your %s.
// 521: You heal the %s.
prefix.num = (a2 == gDude ? 520 : 521);
prefix.num = (target == gDude ? 520 : 521);
skillUpdateLastUse(SKILL_REPAIR);
v1 = 1;
v2 = 1;
successCount = 1;
skillUseSlotAdded = 1;
} else {
// 525: You fail to heal your %s.
// 526: You fail to heal the %s.
prefix.num = (a2 == gDude ? 525 : 526);
prefix.num = (target == gDude ? 525 : 526);
}
if (!messageListGetItem(&gSkillsMessageList, &prefix)) {
@ -931,7 +931,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
snprintf(text, sizeof(text), prefix.text, messageListItem.text);
displayMonitorAddMessage(text);
_show_skill_use_messages(obj, skill, a2, v1, criticalChanceModifier);
_show_skill_use_messages(obj, skill, target, successCount, criticalChanceModifier);
giveExp = false;
}
}
@ -941,7 +941,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 4, maximumHpToHeal + 10);
critterAdjustHitPoints(a2, hpToHeal);
critterAdjustHitPoints(target, hpToHeal);
if (obj == gDude) {
// You heal %d hit points.
@ -957,18 +957,18 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
displayMonitorAddMessage(text);
}
if (!v2) {
if (!skillUseSlotAdded) {
skillUpdateLastUse(SKILL_REPAIR);
}
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
target->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
if (a2 == gDude) {
if (target == gDude) {
interfaceRenderHitPoints(true);
}
v1 = 1;
_show_skill_use_messages(obj, skill, a2, v1, criticalChanceModifier);
successCount = 1;
_show_skill_use_messages(obj, skill, target, successCount, criticalChanceModifier);
scriptsExecMapUpdateProc();
paletteFadeTo(_cmap);
@ -990,12 +990,12 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
if (obj == gDude) {
// 501: You look healty already
// 502: %s looks healthy already
messageListItem.num = (a2 == gDude ? 501 : 502);
messageListItem.num = (target == gDude ? 501 : 502);
if (!messageListGetItem(&gSkillsMessageList, &messageListItem)) {
return -1;
}
snprintf(text, sizeof(text), messageListItem.text, objectGetName(a2));
snprintf(text, sizeof(text), messageListItem.text, objectGetName(target));
displayMonitorAddMessage(text);
giveExp = false;
@ -1017,7 +1017,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
}
if (giveExp) {
_show_skill_use_messages(obj, skill, a2, v1, criticalChanceModifier);
_show_skill_use_messages(obj, skill, target, successCount, criticalChanceModifier);
}
if (skill == SKILL_FIRST_AID || skill == SKILL_DOCTOR) {
@ -1028,40 +1028,38 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
}
// 0x4ABBE4
int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
int skillsPerformStealing(Object* thief, Object* target, Object* item, bool isPlanting)
{
int howMuch;
int stealModifier = _gStealCount;
stealModifier--;
stealModifier = -stealModifier;
int stealModifier = -_gStealCount + 1;
if (a1 != gDude || !perkHasRank(a1, PERK_PICKPOCKET)) {
if (thief != gDude || !perkHasRank(thief, PERK_PICKPOCKET)) {
// -4% per item size
stealModifier -= 4 * itemGetSize(item);
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
if (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER) {
// check facing: -25% if face to face
if (_is_hit_from_front(a1, a2)) {
if (_is_hit_from_front(thief, target)) {
stealModifier -= 25;
}
}
}
if ((a2->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0) {
if ((target->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0) {
stealModifier += 20;
}
int stealChance = stealModifier + skillGetValue(a1, SKILL_STEAL);
int stealChance = stealModifier + skillGetValue(thief, SKILL_STEAL);
if (stealChance > 95) {
stealChance = 95;
}
int stealRoll;
if (a1 == gDude && objectIsPartyMember(a2)) {
if (thief == gDude && objectIsPartyMember(target)) {
stealRoll = ROLL_CRITICAL_SUCCESS;
} else {
int criticalChance = critterGetStat(a1, STAT_CRITICAL_CHANCE);
int criticalChance = critterGetStat(thief, STAT_CRITICAL_CHANCE);
stealRoll = randomRoll(stealChance, criticalChance, &howMuch);
}
@ -1072,8 +1070,8 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
catchRoll = ROLL_SUCCESS;
} else {
int catchChance;
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER) {
catchChance = skillGetValue(a2, SKILL_STEAL) - stealModifier;
if (PID_TYPE(target->pid) == OBJ_TYPE_CRITTER) {
catchChance = skillGetValue(target, SKILL_STEAL) - stealModifier;
} else {
catchChance = 30 - stealModifier;
}

View File

@ -34,7 +34,7 @@ char* skillGetName(int skill);
char* skillGetDescription(int skill);
char* skillGetAttributes(int skill);
int skillGetFrmId(int skill);
int skillUse(Object* obj, Object* a2, int skill, int a4);
int skillUse(Object* obj, Object* target, int skill, int criticalChanceModifier);
int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting);
int skillGetGameDifficultyModifier(int skill);
int skillUpdateLastUse(int skill);

View File

@ -3719,7 +3719,7 @@ int wmSetupRandomEncounter()
prevCritter->data.critter.combat.whoHitMe = critter;
critter->data.critter.combat.whoHitMe = prevCritter;
STRUCT_664980 combat;
CombatStartData combat;
combat.attacker = prevCritter;
combat.defender = critter;
combat.actionPointsBonus = 0;
@ -3727,7 +3727,7 @@ int wmSetupRandomEncounter()
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = 500;
combat.field_1C = 0;
combat.overrideAttackResults = 0;
_caiSetupTeamCombat(critter, prevCritter);
_scripts_request_combat_locked(&combat);
@ -3736,7 +3736,7 @@ int wmSetupRandomEncounter()
if (!isInCombat()) {
prevCritter->data.critter.combat.whoHitMe = gDude;
STRUCT_664980 combat;
CombatStartData combat;
combat.attacker = prevCritter;
combat.defender = gDude;
combat.actionPointsBonus = 0;
@ -3744,7 +3744,7 @@ int wmSetupRandomEncounter()
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = 500;
combat.field_1C = 0;
combat.overrideAttackResults = 0;
_caiSetupTeamCombat(gDude, prevCritter);
_scripts_request_combat_locked(&combat);