Reconcile with reference edition
This commit is contained in:
parent
66d46bd8a5
commit
df5bceaf2a
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/combat.h
12
src/combat.h
|
@ -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);
|
||||||
|
|
128
src/combat_ai.cc
128
src/combat_ai.cc
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue