diff --git a/common/main/robot.h b/common/main/robot.h index 450d297e6..bf98307b3 100644 --- a/common/main/robot.h +++ b/common/main/robot.h @@ -30,9 +30,11 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifdef __cplusplus #include "pack.h" +#include "ai.h" #include "aistruct.h" #include "polyobj.h" #include "weapon_id.h" +#include "object.h" #define MAX_GUNS 8 //should be multiple of 4 for ubyte array @@ -154,6 +156,14 @@ struct robot_info : prohibit_void_ptr constexpr auto weapon_none = weapon_id_type::unspecified; namespace dsx { +static inline objptridx_t robot_create(ubyte id, vsegptridx_t segnum, const vms_vector &pos, const vms_matrix *orient, fix size, ai_behavior behavior, const segidx_t hide_segment = segment_none) +{ + auto objp = obj_create(OBJ_ROBOT, id, segnum, pos, orient, size, CT_AI, MT_PHYSICS, RT_POLYOBJ); + if (objp) + init_ai_object(objp, behavior, hide_segment); + return objp; +} + #if defined(DXX_BUILD_DESCENT_I) // maximum number of robot types constexpr unsigned MAX_ROBOT_TYPES = 30; diff --git a/d2x-rebirth/main/escort.cpp b/d2x-rebirth/main/escort.cpp index 367d56656..c3fdc1e84 100644 --- a/d2x-rebirth/main/escort.cpp +++ b/d2x-rebirth/main/escort.cpp @@ -1223,7 +1223,6 @@ void recreate_thief(const uint8_t thief_id) const auto &&new_obj = create_morph_robot(segp, center_point, thief_id); if (new_obj == object_none) return; - init_ai_object(new_obj, ai_behavior::AIB_SNIPE, segment_none); Re_init_thief_time = GameTime64 + F1_0*10; // In 10 seconds, re-initialize thief. } diff --git a/similar/editor/eobject.cpp b/similar/editor/eobject.cpp index 8c4c091fc..ffdab15e3 100644 --- a/similar/editor/eobject.cpp +++ b/similar/editor/eobject.cpp @@ -146,9 +146,19 @@ int place_object(const vsegptridx_t segp, const vms_vector &object_pos, short ob } case OBJ_ROBOT: { - objnum = obj_create(OBJ_ROBOT, object_id, segp, object_pos, - &seg_matrix, Polygon_models[Robot_info[object_id].model_num].rad, - CT_AI, MT_PHYSICS, RT_POLYOBJ); + segnum_t hide_segment; + if (Markedsegp) + hide_segment = Markedsegp; + else + hide_segment = segment_none; + + objnum = robot_create(object_id, segp, object_pos, + &seg_matrix, Polygon_models[Robot_info[object_id].model_num].rad, + Robot_info[object_id].attack_type ? + // robots which lunge forward to attack cannot have behavior type still. + ai_behavior::AIB_NORMAL : + ai_behavior::AIB_STILL, + hide_segment); if ( objnum == object_none) return 0; @@ -168,16 +178,6 @@ int place_object(const vsegptridx_t segp, const vms_vector &object_pos, short ob obj->mtype.phys_info.flags |= (PF_LEVELLING); obj->shields = Robot_info[get_robot_id(obj)].strength; - - { - segnum_t hide_segment; - if (Markedsegp) - hide_segment = Markedsegp; - else - hide_segment = segment_none; - // robots which lunge forward to attack cannot have behavior type still. - init_ai_object(obj, Robot_info[get_robot_id(obj)].attack_type ? ai_behavior::AIB_NORMAL : ai_behavior::AIB_STILL, hide_segment); - } break; } case OBJ_POWERUP: diff --git a/similar/main/ai.cpp b/similar/main/ai.cpp index 419f08eaa..9cdc13ebb 100644 --- a/similar/main/ai.cpp +++ b/similar/main/ai.cpp @@ -1895,7 +1895,14 @@ static objptridx_t create_gated_robot(const vsegptridx_t segp, int object_id, co return object_none; } - auto objp = obj_create(OBJ_ROBOT, object_id, segp, object_pos, &vmd_identity_matrix, objsize, CT_AI, MT_PHYSICS, RT_POLYOBJ); +#if defined(DXX_BUILD_DESCENT_I) + const ai_behavior default_behavior = (object_id == 10) // This is a toaster guy! + ? ai_behavior::AIB_RUN_FROM + : ai_behavior::AIB_NORMAL; +#elif defined(DXX_BUILD_DESCENT_II) + const ai_behavior default_behavior = robptr->behavior; +#endif + auto objp = robot_create(object_id, segp, object_pos, &vmd_identity_matrix, objsize, default_behavior); if ( objp == object_none ) { Last_gate_time = GameTime64 - 3*Gate_interval/4; @@ -1917,15 +1924,9 @@ static objptridx_t create_gated_robot(const vsegptridx_t segp, int object_id, co objp->shields = robptr->strength; objp->matcen_creator = BOSS_GATE_MATCEN_NUM; // flag this robot as having been created by the boss. -#if defined(DXX_BUILD_DESCENT_I) - const ai_behavior default_behavior = (object_id == 10) // This is a toaster guy! - ? ai_behavior::AIB_RUN_FROM - : ai_behavior::AIB_NORMAL; -#elif defined(DXX_BUILD_DESCENT_II) +#if defined(DXX_BUILD_DESCENT_II) objp->lifeleft = F1_0*30; // Gated in robots only live 30 seconds. - const ai_behavior default_behavior = robptr->behavior; #endif - init_ai_object(objp, default_behavior, segment_none ); // Note, -1 = segment this robot goes to to hide, should probably be something useful object_create_explosion(segp, object_pos, i2f(10), VCLIP_MORPHING_ROBOT ); digi_link_sound_to_pos( Vclip[VCLIP_MORPHING_ROBOT].sound_num, segp, 0, object_pos, 0 , F1_0); diff --git a/similar/main/fireball.cpp b/similar/main/fireball.cpp index d17f77639..5f2f289bf 100644 --- a/similar/main/fireball.cpp +++ b/similar/main/fireball.cpp @@ -931,7 +931,7 @@ objptridx_t drop_powerup(int type, int id, int num, const vms_vector &init_vel, #elif defined(DXX_BUILD_DESCENT_II) const auto robot_id = id; #endif - const auto &&obj = obj_create(OBJ_ROBOT, id, segnum, new_pos, &vmd_identity_matrix, Polygon_models[Robot_info[robot_id].model_num].rad, CT_AI, MT_PHYSICS, RT_POLYOBJ); + const auto &&obj = robot_create(id, segnum, new_pos, &vmd_identity_matrix, Polygon_models[Robot_info[robot_id].model_num].rad, ai_behavior::AIB_NORMAL); objnum = obj; if (objnum == object_none) @@ -948,7 +948,6 @@ objptridx_t drop_powerup(int type, int id, int num, const vms_vector &init_vel, { Net_create_objnums[Net_create_loc++] = objnum; } - init_ai_object(obj, ai_behavior::AIB_NORMAL, segment_none); //Set polygon-object-specific data obj->rtype.pobj_info.model_num = Robot_info[get_robot_id(obj)].model_num; diff --git a/similar/main/fuelcen.cpp b/similar/main/fuelcen.cpp index a66607458..a39559c07 100644 --- a/similar/main/fuelcen.cpp +++ b/similar/main/fuelcen.cpp @@ -300,9 +300,18 @@ objptridx_t create_morph_robot( const vsegptridx_t segp, const vms_vector &obje get_local_player().num_robots_level++; get_local_player().num_robots_total++; - auto obj = obj_create(OBJ_ROBOT, object_id, segp, object_pos, + ai_behavior default_behavior; +#if defined(DXX_BUILD_DESCENT_I) + default_behavior = ai_behavior::AIB_NORMAL; + if (object_id == 10) // This is a toaster guy! + default_behavior = ai_behavior::AIB_RUN_FROM; +#elif defined(DXX_BUILD_DESCENT_II) + default_behavior = Robot_info[object_id].behavior; +#endif + + auto obj = robot_create(object_id, segp, object_pos, &vmd_identity_matrix, Polygon_models[Robot_info[object_id].model_num].rad, - CT_AI, MT_PHYSICS, RT_POLYOBJ); + default_behavior); if (obj == object_none) { @@ -323,16 +332,6 @@ objptridx_t create_morph_robot( const vsegptridx_t segp, const vms_vector &obje obj->mtype.phys_info.flags |= (PF_LEVELLING); obj->shields = Robot_info[get_robot_id(obj)].strength; - ai_behavior default_behavior; -#if defined(DXX_BUILD_DESCENT_I) - default_behavior = ai_behavior::AIB_NORMAL; - if (object_id == 10) // This is a toaster guy! - default_behavior = ai_behavior::AIB_RUN_FROM; -#elif defined(DXX_BUILD_DESCENT_II) - default_behavior = Robot_info[get_robot_id(obj)].behavior; -#endif - - init_ai_object(obj, default_behavior, segment_none ); // Note, -1 = segment this robot goes to to hide, should probably be something useful create_n_segment_path(obj, 6, segment_none); // Create a 6 segment path from creation point.