Reconcile with reference edition

This commit is contained in:
Alexander Batalov 2022-08-02 13:31:26 +03:00
parent 66d46bd8a5
commit df5bceaf2a
5 changed files with 119 additions and 123 deletions

View File

@ -46,8 +46,15 @@
#define CALLED_SHOT_WINDOW_WIDTH (504) #define CALLED_SHOT_WINDOW_WIDTH (504)
#define CALLED_SHOT_WINDOW_HEIGHT (309) #define CALLED_SHOT_WINDOW_HEIGHT (309)
typedef struct CombatAiInfo {
Object* friendlyDead;
Object* lastTarget;
Object* lastItem;
int lastMove;
} CombatAiInfo;
static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6); static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6);
static int _combatCopyAIInfo(int a1, int a2); static int aiInfoCopy(int srcIndex, int destIndex);
static void _combat_begin(Object* a1); static void _combat_begin(Object* a1);
static void _combat_begin_extra(Object* a1); static void _combat_begin_extra(Object* a1);
static void _combat_over(); static void _combat_over();
@ -96,7 +103,7 @@ int _combatNumTurns = 0;
unsigned int gCombatState = COMBAT_STATE_0x02; unsigned int gCombatState = COMBAT_STATE_0x02;
// 0x510948 // 0x510948
static CombatAIInfo* _aiInfoList = NULL; static CombatAiInfo* _aiInfoList = NULL;
// 0x51094C // 0x51094C
static STRUCT_664980* _gcsd = NULL; static STRUCT_664980* _gcsd = NULL;
@ -1989,7 +1996,6 @@ int _find_cid(int a1, int cid, Object** critterList, int critterListLength)
int combatLoad(File* stream) int combatLoad(File* stream)
{ {
int v14; int v14;
CombatAIInfo* ptr;
int a2; int a2;
Object* obj; Object* obj;
int v24; int v24;
@ -2071,42 +2077,42 @@ int combatLoad(File* stream)
internal_free(_aiInfoList); internal_free(_aiInfoList);
} }
_aiInfoList = (CombatAIInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total); _aiInfoList = (CombatAiInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
if (_aiInfoList == NULL) { if (_aiInfoList == NULL) {
return -1; return -1;
} }
for (v14 = 0; v14 < _list_total; v14++) { for (v14 = 0; v14 < _list_total; v14++) {
ptr = &(_aiInfoList[v14]); CombatAiInfo* aiInfo = &(_aiInfoList[v14]);
if (fileReadInt32(stream, &a2) == -1) return -1; if (fileReadInt32(stream, &a2) == -1) return -1;
if (a2 == -1) { if (a2 == -1) {
ptr->friendlyDead = NULL; aiInfo->friendlyDead = NULL;
} else { } else {
ptr->friendlyDead = objectFindById(a2); aiInfo->friendlyDead = objectFindById(a2);
if (ptr->friendlyDead == NULL) return -1; if (aiInfo->friendlyDead == NULL) return -1;
} }
if (fileReadInt32(stream, &a2) == -1) return -1; if (fileReadInt32(stream, &a2) == -1) return -1;
if (a2 == -1) { if (a2 == -1) {
ptr->lastTarget = NULL; aiInfo->lastTarget = NULL;
} else { } else {
ptr->lastTarget = objectFindById(a2); aiInfo->lastTarget = objectFindById(a2);
if (ptr->lastTarget == NULL) return -1; if (aiInfo->lastTarget == NULL) return -1;
} }
if (fileReadInt32(stream, &a2) == -1) return -1; if (fileReadInt32(stream, &a2) == -1) return -1;
if (a2 == -1) { if (a2 == -1) {
ptr->lastItem = NULL; aiInfo->lastItem = NULL;
} else { } else {
ptr->lastItem = objectFindById(a2); aiInfo->lastItem = objectFindById(a2);
if (ptr->lastItem == NULL) return -1; if (aiInfo->lastItem == NULL) return -1;
} }
if (fileReadInt32(stream, &(ptr->lastMove)) == -1) return -1; if (fileReadInt32(stream, &(aiInfo->lastMove)) == -1) return -1;
} }
_combat_begin_extra(gDude); _combat_begin_extra(gDude);
@ -2138,12 +2144,12 @@ int combatSave(File* stream)
} }
for (int index = 0; index < _list_total; index++) { for (int index = 0; index < _list_total; index++) {
CombatAIInfo* ptr = &(_aiInfoList[index]); CombatAiInfo* aiInfo = &(_aiInfoList[index]);
if (fileWriteInt32(stream, ptr->friendlyDead != NULL ? ptr->friendlyDead->id : -1) == -1) return -1; if (fileWriteInt32(stream, aiInfo->friendlyDead != NULL ? aiInfo->friendlyDead->id : -1) == -1) return -1;
if (fileWriteInt32(stream, ptr->lastTarget != NULL ? ptr->lastTarget->id : -1) == -1) return -1; if (fileWriteInt32(stream, aiInfo->lastTarget != NULL ? aiInfo->lastTarget->id : -1) == -1) return -1;
if (fileWriteInt32(stream, ptr->lastItem != NULL ? ptr->lastItem->id : -1) == -1) return -1; if (fileWriteInt32(stream, aiInfo->lastItem != NULL ? aiInfo->lastItem->id : -1) == -1) return -1;
if (fileWriteInt32(stream, ptr->lastMove) == -1) return -1; if (fileWriteInt32(stream, aiInfo->lastMove) == -1) return -1;
} }
return 0; return 0;
@ -2283,24 +2289,21 @@ void _combat_data_init(Object* obj)
} }
// 0x421850 // 0x421850
static int _combatCopyAIInfo(int a1, int a2) static int aiInfoCopy(int srcIndex, int destIndex)
{ {
CombatAIInfo* v3; CombatAiInfo* src = &_aiInfoList[srcIndex];
CombatAIInfo* v4; CombatAiInfo* dest = &_aiInfoList[destIndex];
v3 = &_aiInfoList[a1]; dest->friendlyDead = src->friendlyDead;
v4 = &_aiInfoList[a2]; dest->lastTarget = src->lastTarget;
dest->lastItem = src->lastItem;
v4->friendlyDead = v3->friendlyDead; dest->lastMove = src->lastMove;
v4->lastTarget = v3->lastTarget;
v4->lastItem = v3->lastItem;
v4->lastMove = v3->lastMove;
return 0; return 0;
} }
// 0x421880 // 0x421880
Object* _combatAIInfoGetFriendlyDead(Object* obj) Object* aiInfoGetFriendlyDead(Object* obj)
{ {
if (!isInCombat()) { if (!isInCombat()) {
return NULL; return NULL;
@ -2318,7 +2321,7 @@ Object* _combatAIInfoGetFriendlyDead(Object* obj)
} }
// 0x4218AC // 0x4218AC
int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2) int aiInfoSetFriendlyDead(Object* a1, Object* a2)
{ {
if (!isInCombat()) { if (!isInCombat()) {
return 0; return 0;
@ -2342,7 +2345,7 @@ int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2)
} }
// 0x4218EC // 0x4218EC
Object* _combatAIInfoGetLastTarget(Object* obj) Object* aiInfoGetLastTarget(Object* obj)
{ {
if (!isInCombat()) { if (!isInCombat()) {
return NULL; return NULL;
@ -2360,7 +2363,7 @@ Object* _combatAIInfoGetLastTarget(Object* obj)
} }
// 0x421918 // 0x421918
int _combatAIInfoSetLastTarget(Object* a1, Object* a2) int aiInfoSetLastTarget(Object* a1, Object* a2)
{ {
if (!isInCombat()) { if (!isInCombat()) {
return 0; return 0;
@ -2388,7 +2391,7 @@ int _combatAIInfoSetLastTarget(Object* a1, Object* a2)
} }
// 0x42196C // 0x42196C
Object* _combatAIInfoGetLastItem(Object* obj) Object* aiInfoGetLastItem(Object* obj)
{ {
int v1; int v1;
@ -2409,7 +2412,7 @@ Object* _combatAIInfoGetLastItem(Object* obj)
} }
// 0x421998 // 0x421998
int _combatAIInfoSetLastItem(Object* obj, Object* a2) int aiInfoSetLastItem(Object* obj, Object* a2)
{ {
int v2; int v2;
@ -2446,17 +2449,17 @@ static void _combat_begin(Object* a1)
_list_total = objectListCreate(-1, _combat_elev, OBJ_TYPE_CRITTER, &_combat_list); _list_total = objectListCreate(-1, _combat_elev, OBJ_TYPE_CRITTER, &_combat_list);
_list_noncom = _list_total; _list_noncom = _list_total;
_list_com = 0; _list_com = 0;
_aiInfoList = (CombatAIInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total); _aiInfoList = (CombatAiInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
if (_aiInfoList == NULL) { if (_aiInfoList == NULL) {
return; return;
} }
for (int index = 0; index < _list_total; index++) { for (int index = 0; index < _list_total; index++) {
CombatAIInfo* ptr = &(_aiInfoList[index]); CombatAiInfo* aiInfo = &(_aiInfoList[index]);
ptr->friendlyDead = NULL; aiInfo->friendlyDead = NULL;
ptr->lastTarget = NULL; aiInfo->lastTarget = NULL;
ptr->lastItem = NULL; aiInfo->lastItem = NULL;
ptr->lastMove = 0; aiInfo->lastMove = 0;
} }
Object* v1 = NULL; Object* v1 = NULL;
@ -3393,7 +3396,7 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
_combat_call_display = 1; _combat_call_display = 1;
_combat_cleanup_enabled = 1; _combat_cleanup_enabled = 1;
_combatAIInfoSetLastTarget(a1, a2); aiInfoSetLastTarget(a1, a2);
debugPrint("running attack...\n"); debugPrint("running attack...\n");
return 0; return 0;
@ -5791,7 +5794,7 @@ void _combat_delete_critter(Object* obj)
while (i < (_list_total - 1)) { while (i < (_list_total - 1)) {
_combat_list[i] = _combat_list[i + 1]; _combat_list[i] = _combat_list[i + 1];
_combatCopyAIInfo(i + 1, i); aiInfoCopy(i + 1, i);
i++; i++;
} }

View File

@ -21,12 +21,12 @@ bool _combat_safety_invalidate_weapon(Object* a1, Object* a2, int hitMode, Objec
bool _combatTestIncidentalHit(Object* a1, Object* a2, Object* a3, Object* a4); bool _combatTestIncidentalHit(Object* a1, Object* a2, Object* a3, Object* a4);
Object* _combat_whose_turn(); Object* _combat_whose_turn();
void _combat_data_init(Object* obj); void _combat_data_init(Object* obj);
Object* _combatAIInfoGetFriendlyDead(Object* obj); Object* aiInfoGetFriendlyDead(Object* obj);
int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2); int aiInfoSetFriendlyDead(Object* a1, Object* a2);
Object* _combatAIInfoGetLastTarget(Object* obj); Object* aiInfoGetLastTarget(Object* obj);
int _combatAIInfoSetLastTarget(Object* a1, Object* a2); int aiInfoSetLastTarget(Object* a1, Object* a2);
Object* _combatAIInfoGetLastItem(Object* obj); Object* aiInfoGetLastItem(Object* obj);
int _combatAIInfoSetLastItem(Object* obj, Object* a2); int aiInfoSetLastItem(Object* obj, Object* a2);
void _combat_update_critter_outline_for_los(Object* critter, bool a2); void _combat_update_critter_outline_for_los(Object* critter, bool a2);
void _combat_over_from_load(); void _combat_over_from_load();
void _combat_give_exps(int exp_points); void _combat_give_exps(int exp_points);

View File

@ -72,19 +72,19 @@ typedef struct AiPacket {
char* general_type; char* general_type;
} AiPacket; } AiPacket;
typedef struct STRUCT_832 { typedef struct AiRetargetData {
Object* field_0; Object* source;
Object* field_4; Object* target;
Object* field_8[100]; Object* critterList[100];
int field_198[100]; int ratingList[100];
int field_328; int critterCount;
int field_32C; int sourceTeam;
int field_330; int sourceRating;
int field_334; bool notSameTile;
int* field_338; int* tiles;
int field_33C; int currentTileIndex;
int field_340; int sourceIntelligence;
} STRUCT_832; } AiRetargetData;
static void _parse_hurt_str(char* str, int* out_value); static void _parse_hurt_str(char* str, int* out_value);
static int _cai_match_str_to_list(const char* str, const char** list, int count, int* out_value); static int _cai_match_str_to_list(const char* str, const char** list, int count, int* out_value);
@ -114,8 +114,8 @@ static Object* _ai_search_environ(Object* critter, int itemType);
static Object* _ai_retrieve_object(Object* a1, Object* a2); static Object* _ai_retrieve_object(Object* a1, Object* a2);
static int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3); static int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3);
static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a4); static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a4);
static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3); static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
static int _cai_retargetTileFromFriendlyFireSubFunc(STRUCT_832* a1, int a2); static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile);
static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance); static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance);
static int _ai_switch_weapons(Object* a1, int* hitMode, Object** weapon, Object* a4); static int _ai_switch_weapons(Object* a1, int* hitMode, Object** weapon, Object* a4);
static int _ai_called_shot(Object* a1, Object* a2, int a3); static int _ai_called_shot(Object* a1, Object* a2, int a3);
@ -939,7 +939,7 @@ static int _ai_check_drugs(Object* critter)
int v25 = 0; int v25 = 0;
int v28 = 0; int v28 = 0;
int v29 = 0; int v29 = 0;
Object* v3 = _combatAIInfoGetLastItem(critter); Object* v3 = aiInfoGetLastItem(critter);
if (v3 == NULL) { if (v3 == NULL) {
AiPacket* ai = aiGetPacket(critter); AiPacket* ai = aiGetPacket(critter);
if (ai == NULL) { if (ai == NULL) {
@ -1467,7 +1467,7 @@ static Object* _ai_danger_source(Object* a1)
attackWho = aiGetPacket(a1)->attack_who; attackWho = aiGetPacket(a1)->attack_who;
switch (attackWho) { switch (attackWho) {
case ATTACK_WHO_WHOMEVER_ATTACKING_ME: { case ATTACK_WHO_WHOMEVER_ATTACKING_ME: {
Object* candidate = _combatAIInfoGetLastTarget(gDude); Object* candidate = aiInfoGetLastTarget(gDude);
if (candidate == NULL || a1->data.critter.combat.team == candidate->data.critter.combat.team) { if (candidate == NULL || a1->data.critter.combat.team == candidate->data.critter.combat.team) {
break; break;
} }
@ -2086,7 +2086,7 @@ static Object* _ai_retrieve_object(Object* a1, Object* a2)
a2 = NULL; a2 = NULL;
} }
_combatAIInfoSetLastItem(v3, a2); aiInfoSetLastItem(v3, a2);
return v3; return v3;
} }
@ -2262,21 +2262,21 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
} }
// 0x42A1D4 // 0x42A1D4
static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3) static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr)
{ {
if (a1 == NULL) { if (source == NULL) {
return -1; return -1;
} }
if (a2 == NULL) { if (target == NULL) {
return -1; return -1;
} }
if (a3 == NULL) { if (tilePtr == NULL) {
return -1; return -1;
} }
if (*a3 == -1) { if (*tilePtr == -1) {
return -1; return -1;
} }
@ -2286,16 +2286,16 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
int tiles[32]; int tiles[32];
STRUCT_832 v1; AiRetargetData aiRetargetData;
v1.field_0 = a1; aiRetargetData.source = source;
v1.field_4 = a2; aiRetargetData.target = target;
v1.field_32C = a1->data.critter.combat.team; aiRetargetData.sourceTeam = source->data.critter.combat.team;
v1.field_330 = _combatai_rating(a1); aiRetargetData.sourceRating = _combatai_rating(source);
v1.field_328 = 0; aiRetargetData.critterCount = 0;
v1.field_338 = tiles; aiRetargetData.tiles = tiles;
v1.field_334 = *a3 != a1->tile; aiRetargetData.notSameTile = *tilePtr != source->tile;
v1.field_33C = 0; aiRetargetData.currentTileIndex = 0;
v1.field_340 = critterGetStat(a1, STAT_INTELLIGENCE); aiRetargetData.sourceIntelligence = critterGetStat(source, STAT_INTELLIGENCE);
for (int index = 0; index < 32; index++) { for (int index = 0; index < 32; index++) {
tiles[index] = -1; tiles[index] = -1;
@ -2304,23 +2304,23 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
for (int index = 0; index < _curr_crit_num; index++) { for (int index = 0; index < _curr_crit_num; index++) {
Object* obj = _curr_crit_list[index]; Object* obj = _curr_crit_list[index];
if ((obj->data.critter.combat.results & DAM_DEAD) == 0 if ((obj->data.critter.combat.results & DAM_DEAD) == 0
&& obj->data.critter.combat.team == v1.field_32C && obj->data.critter.combat.team == aiRetargetData.sourceTeam
&& _combatAIInfoGetLastTarget(obj) == v1.field_4 && aiInfoGetLastTarget(obj) == aiRetargetData.target
&& obj != v1.field_0) { && obj != aiRetargetData.source) {
int v10 = _combatai_rating(obj); int rating = _combatai_rating(obj);
if (v10 >= v1.field_330) { if (rating >= aiRetargetData.sourceRating) {
v1.field_8[v1.field_328] = obj; aiRetargetData.critterList[aiRetargetData.critterCount] = obj;
v1.field_198[v1.field_328] = v10; aiRetargetData.ratingList[aiRetargetData.critterCount] = rating;
v1.field_328 += 1; aiRetargetData.critterCount += 1;
} }
} }
} }
_combat_obj = a1; _combat_obj = source;
qsort(v1.field_8, v1.field_328, sizeof(*v1.field_8), _compare_nearer); qsort(aiRetargetData.critterList, aiRetargetData.critterCount, sizeof(*aiRetargetData.critterList), _compare_nearer);
if (_cai_retargetTileFromFriendlyFireSubFunc(&v1, *a3) == 0) { if (_cai_retargetTileFromFriendlyFireSubFunc(&aiRetargetData, *tilePtr) == 0) {
int minDistance = 99999; int minDistance = 99999;
int minDistanceIndex = -1; int minDistanceIndex = -1;
@ -2330,8 +2330,8 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
break; break;
} }
if (_obj_blocking_at(NULL, tile, a1->elevation) == 0) { if (_obj_blocking_at(NULL, tile, source->elevation) == 0) {
int distance = tileDistanceBetween(*a3, tile); int distance = tileDistanceBetween(*tilePtr, tile);
if (distance < minDistance) { if (distance < minDistance) {
minDistance = distance; minDistance = distance;
minDistanceIndex = index; minDistanceIndex = index;
@ -2340,7 +2340,7 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
} }
if (minDistanceIndex != -1) { if (minDistanceIndex != -1) {
*a3 = tiles[minDistanceIndex]; *tilePtr = tiles[minDistanceIndex];
} }
} }
@ -2348,24 +2348,24 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
} }
// 0x42A410 // 0x42A410
static int _cai_retargetTileFromFriendlyFireSubFunc(STRUCT_832* a1, int tile) static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile)
{ {
if (a1->field_340 <= 0) { if (aiRetargetData->sourceIntelligence <= 0) {
return 0; return 0;
} }
int distance = 1; int distance = 1;
for (int index = 0; index < a1->field_328; index++) { for (int index = 0; index < aiRetargetData->critterCount; index++) {
Object* obj = a1->field_8[index]; Object* obj = aiRetargetData->critterList[index];
if (_cai_attackWouldIntersect(obj, a1->field_4, a1->field_0, tile, &distance)) { if (_cai_attackWouldIntersect(obj, aiRetargetData->target, aiRetargetData->source, tile, &distance)) {
debugPrint("In the way!"); debugPrint("In the way!");
a1->field_338[a1->field_33C] = tileGetTileInDirection(tile, (obj->rotation + 1) % ROTATION_COUNT, distance); aiRetargetData->tiles[aiRetargetData->currentTileIndex] = tileGetTileInDirection(tile, (obj->rotation + 1) % ROTATION_COUNT, distance);
a1->field_338[a1->field_33C + 1] = tileGetTileInDirection(tile, (obj->rotation + 5) % ROTATION_COUNT, distance); aiRetargetData->tiles[aiRetargetData->currentTileIndex + 1] = tileGetTileInDirection(tile, (obj->rotation + 5) % ROTATION_COUNT, distance);
a1->field_340 -= 2; aiRetargetData->sourceIntelligence -= 2;
a1->field_33C += 2; aiRetargetData->currentTileIndex += 2;
break; break;
} }
} }
@ -2884,10 +2884,10 @@ void _combat_ai(Object* a1, Object* a2)
&& (a1->data.critter.combat.results & DAM_DEAD) == 0 && (a1->data.critter.combat.results & DAM_DEAD) == 0
&& a1->data.critter.combat.ap != 0 && a1->data.critter.combat.ap != 0
&& objectGetDistanceBetween(a1, a2) > ai->max_dist) { && objectGetDistanceBetween(a1, a2) > ai->max_dist) {
Object* v13 = _combatAIInfoGetFriendlyDead(a1); Object* v13 = aiInfoGetFriendlyDead(a1);
if (v13 != NULL) { if (v13 != NULL) {
_ai_move_away(a1, v13, 10); _ai_move_away(a1, v13, 10);
_combatAIInfoSetFriendlyDead(a1, NULL); aiInfoSetFriendlyDead(a1, NULL);
} else { } else {
int perception = critterGetStat(a1, STAT_PERCEPTION); int perception = critterGetStat(a1, STAT_PERCEPTION);
if (!_ai_find_friend(a1, perception * 2, 5)) { if (!_ai_find_friend(a1, perception * 2, 5)) {
@ -2900,10 +2900,10 @@ void _combat_ai(Object* a1, Object* a2)
Object* whoHitMe = combatData->whoHitMe; Object* whoHitMe = combatData->whoHitMe;
if (whoHitMe != NULL) { if (whoHitMe != NULL) {
if ((whoHitMe->data.critter.combat.results & DAM_DEAD) == 0 && combatData->damageLastTurn > 0) { if ((whoHitMe->data.critter.combat.results & DAM_DEAD) == 0 && combatData->damageLastTurn > 0) {
Object* v16 = _combatAIInfoGetFriendlyDead(a1); Object* v16 = aiInfoGetFriendlyDead(a1);
if (v16 != NULL) { if (v16 != NULL) {
_ai_move_away(a1, v16, 10); _ai_move_away(a1, v16, 10);
_combatAIInfoSetFriendlyDead(a1, NULL); aiInfoSetFriendlyDead(a1, NULL);
} else { } else {
const char* name = critterGetName(a1); const char* name = critterGetName(a1);
debugPrint("%s: FLEEING: Somebody is shooting at me that I can't see!"); debugPrint("%s: FLEEING: Somebody is shooting at me that I can't see!");
@ -2913,11 +2913,11 @@ void _combat_ai(Object* a1, Object* a2)
} }
} }
Object* v18 = _combatAIInfoGetFriendlyDead(a1); Object* v18 = aiInfoGetFriendlyDead(a1);
if (v18 != NULL) { if (v18 != NULL) {
_ai_move_away(a1, v18, 10); _ai_move_away(a1, v18, 10);
if (objectGetDistanceBetween(a1, v18) >= 10) { if (objectGetDistanceBetween(a1, v18) >= 10) {
_combatAIInfoSetFriendlyDead(a1, NULL); aiInfoSetFriendlyDead(a1, NULL);
} }
} }
@ -3036,7 +3036,7 @@ int critterSetTeam(Object* obj, int team)
} }
} }
_combatAIInfoSetLastTarget(obj, NULL); aiInfoSetLastTarget(obj, NULL);
if (isInCombat()) { if (isInCombat()) {
bool outlineWasEnabled = obj->outline != 0 && (obj->outline & OUTLINE_DISABLED) == 0; bool outlineWasEnabled = obj->outline != 0 && (obj->outline & OUTLINE_DISABLED) == 0;
@ -3408,7 +3408,7 @@ void _combatai_notify_onlookers(Object* a1)
if ((a1->data.critter.combat.results & DAM_DEAD) != 0) { if ((a1->data.critter.combat.results & DAM_DEAD) != 0) {
if (!objectCanHearObject(obj, obj->data.critter.combat.whoHitMe)) { if (!objectCanHearObject(obj, obj->data.critter.combat.whoHitMe)) {
debugPrint("\nSomebody Died and I don't know why! Run!!!"); debugPrint("\nSomebody Died and I don't know why! Run!!!");
_combatAIInfoSetFriendlyDead(obj, a1); aiInfoSetFriendlyDead(obj, a1);
} }
} }
} }

View File

@ -84,13 +84,6 @@ typedef enum HitLocation {
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1, HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
} HitLocation; } HitLocation;
typedef struct CombatAIInfo {
Object* friendlyDead;
Object* lastTarget;
Object* lastItem;
int lastMove;
} CombatAIInfo;
typedef struct STRUCT_664980 { typedef struct STRUCT_664980 {
Object* attacker; Object* attacker;
Object* defender; Object* defender;

View File

@ -4724,7 +4724,7 @@ static void opTerminateCombat(Program* program)
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) { if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
self->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING; self->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING;
self->data.critter.combat.whoHitMe = NULL; self->data.critter.combat.whoHitMe = NULL;
_combatAIInfoSetLastTarget(self, NULL); aiInfoSetLastTarget(self, NULL);
} }
} }
} }
@ -4755,7 +4755,7 @@ static void opCritterStopAttacking(Program* program)
if (obj != NULL) { if (obj != NULL) {
obj->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING; obj->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING;
obj->data.critter.combat.whoHitMe = NULL; obj->data.critter.combat.whoHitMe = NULL;
_combatAIInfoSetLastTarget(obj, NULL); aiInfoSetLastTarget(obj, NULL);
} else { } else {
scriptPredefinedError(program, "critter_stop_attacking", SCRIPT_ERROR_OBJECT_IS_NULL); scriptPredefinedError(program, "critter_stop_attacking", SCRIPT_ERROR_OBJECT_IS_NULL);
} }