Variable naming, part 2 (#320)
This commit is contained in:
parent
c6565ac96a
commit
59af02cca9
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
196
src/combat.cc
196
src/combat.cc
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
398
src/inventory.cc
398
src/inventory.cc
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
54
src/item.cc
54
src/item.cc
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
156
src/skill.cc
156
src/skill.cc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue