1 // 2 // 3 4 #include "debris.h" 5 #include "object.h" 6 #include "shipclass.h" 7 #include "debris/debris.h" 8 #include "globalincs/linklist.h" 9 #include "ship/ship.h" 10 11 namespace scripting { 12 namespace api { 13 14 15 //**********HANDLE: Debris 16 ADE_OBJ_DERIV(l_Debris, object_h, "debris", "Debris handle", l_Object); 17 18 ADE_VIRTVAR(IsHull, l_Debris, "boolean", "Whether or not debris is a piece of hull", "boolean", "Whether debris is a hull fragment, or false if handle is invalid") 19 { 20 object_h *oh; 21 bool b=false; 22 if(!ade_get_args(L, "o|b", l_Debris.GetPtr(&oh), &b)) 23 return ade_set_error(L, "b", false); 24 25 if(!oh->IsValid()) 26 return ade_set_error(L, "b", false); 27 28 debris *db = &Debris[oh->objp->instance]; 29 30 if(ADE_SETTING_VAR) { 31 db->is_hull = b ? 1 : 0; 32 } 33 34 return ade_set_args(L, "b", db->is_hull ? true : false); 35 36 } 37 38 ADE_VIRTVAR(OriginClass, l_Debris, "shipclass", "The shipclass of the ship this debris originates from", "shipclass", "The shipclass of the ship that created this debris") 39 { 40 object_h *oh; 41 int shipIdx = -1; 42 if(!ade_get_args(L, "o|o", l_Debris.GetPtr(&oh), &shipIdx)) 43 return ade_set_error(L, "o", l_Shipclass.Set(-1)); 44 45 if(!oh->IsValid()) 46 return ade_set_error(L, "o", l_Shipclass.Set(-1)); 47 48 debris *db = &Debris[oh->objp->instance]; 49 50 if(ADE_SETTING_VAR) { 51 if (shipIdx >= 0 && shipIdx < ship_info_size()) 52 db->ship_info_index = shipIdx; 53 } 54 55 return ade_set_args(L, "o", l_Shipclass.Set(db->ship_info_index)); 56 } 57 58 ADE_VIRTVAR(DoNotExpire, l_Debris, "boolean", "Whether the debris should expire. Normally, debris does not expire if it is from ships destroyed before mission or from ships that are more than 50 meters in radius.", "boolean", "True if flag is set, false if flag is not set and nil on error") 59 { 60 object_h *objh = nullptr; 61 bool set = false; 62 63 if (!ade_get_args(L, "o|b", l_Debris.GetPtr(&objh), &set)) 64 return ADE_RETURN_NIL; 65 66 if (!objh->IsValid()) 67 return ADE_RETURN_NIL; 68 69 debris *db = &Debris[objh->objp->instance]; 70 71 if (ADE_SETTING_VAR) 72 { 73 db->flags.set(Debris_Flags::DoNotExpire, set); 74 75 // we need to be careful to manage the hull list here 76 // per comments in debris.cpp: "pieces that ... have the DoNotExpire flag should not be on it" 77 if (db->is_hull) 78 { 79 if (set) 80 debris_remove_from_hull_list(db); 81 else 82 debris_add_to_hull_list(db); 83 } 84 } 85 86 if (db->flags[Debris_Flags::DoNotExpire]) 87 return ADE_RETURN_TRUE; 88 else 89 return ADE_RETURN_FALSE; 90 } 91 92 ADE_VIRTVAR(LifeLeft, l_Debris, "number", "The time this debris piece will last. When this is 0 (and DoNotExpire is false) the debris will explode.", "number", "The amount of time, in seconds, the debris will last") 93 { 94 object_h *objh = nullptr; 95 float lifeleft = 0.0f; 96 97 if (!ade_get_args(L, "o|f", l_Debris.GetPtr(&objh), &lifeleft)) 98 return ADE_RETURN_NIL; 99 100 if (!objh->IsValid()) 101 return ADE_RETURN_NIL; 102 103 debris *db = &Debris[objh->objp->instance]; 104 105 if (ADE_SETTING_VAR) 106 db->lifeleft = lifeleft; 107 108 return ade_set_args(L, "f", lifeleft); 109 } 110 111 ADE_FUNC(getDebrisRadius, l_Debris, NULL, "The radius of this debris piece", "number", "The radius of this debris piece or -1 if invalid") 112 { 113 object_h *oh; 114 if(!ade_get_args(L, "o", l_Debris.GetPtr(&oh))) 115 return ade_set_error(L, "f", -1.0f); 116 117 if(!oh->IsValid()) 118 return ade_set_error(L, "f", -1.0f); 119 120 debris *db = &Debris[oh->objp->instance]; 121 122 polymodel *pm = model_get(db->model_num); 123 124 if (pm == NULL) 125 return ade_set_error(L, "f", -1.0f); 126 127 if (db->submodel_num < 0 || pm->n_models <= db->submodel_num) 128 return ade_set_error(L, "f", -1.0f); 129 130 return ade_set_error(L, "f", pm->submodel[db->submodel_num].rad); 131 } 132 133 ADE_FUNC(isValid, l_Debris, NULL, "Return if this debris handle is valid", "boolean", "true if valid false otherwise") 134 { 135 object_h *oh; 136 if(!ade_get_args(L, "o", l_Debris.GetPtr(&oh))) 137 return ADE_RETURN_FALSE; 138 139 return ade_set_args(L, "b", oh != NULL && oh->IsValid()); 140 } 141 142 ADE_FUNC(isGeneric, l_Debris, nullptr, "Return if this debris is the generic debris model, not a model subobject", "boolean", "true if Debris_model") 143 { 144 object_h *oh; 145 if (!ade_get_args(L, "o", l_Debris.GetPtr(&oh))) 146 return ADE_RETURN_FALSE; 147 148 if (!oh->IsValid()) 149 return ADE_RETURN_FALSE; 150 151 debris *db = &Debris[oh->objp->instance]; 152 153 return ade_set_args(L, "b", debris_is_generic(db)); 154 } 155 156 ADE_FUNC(isVaporized, l_Debris, nullptr, "Return if this debris is the vaporized debris model, not a model subobject", "boolean", "true if Debris_vaporize_model") 157 { 158 object_h *oh; 159 if (!ade_get_args(L, "o", l_Debris.GetPtr(&oh))) 160 return ADE_RETURN_FALSE; 161 162 if (!oh->IsValid()) 163 return ADE_RETURN_FALSE; 164 165 debris *db = &Debris[oh->objp->instance]; 166 167 return ade_set_args(L, "b", debris_is_vaporized(db)); 168 } 169 170 ADE_FUNC(vanish, l_Debris, nullptr, "Vanishes this piece of debris from the mission.", "boolean", "True if the deletion was successful, false otherwise.") 171 { 172 173 object_h* oh = nullptr; 174 if (!ade_get_args(L, "o", l_Debris.GetPtr(&oh))) 175 return ade_set_error(L, "b", false); 176 177 if (!oh->IsValid()) 178 return ade_set_error(L, "b", false); 179 180 //This skips all the fancy deathroll stuff, and just cleans it from the mission 181 oh->objp->flags.set(Object::Object_Flags::Should_be_dead); 182 183 return ade_set_args(L, "b", true); 184 } 185 186 } 187 } 188