MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 1 | // MorgenGrauen MUDlib |
| 2 | // |
| 3 | // awmaster.c -- Armours- and Weapons-Master |
| 4 | // |
| 5 | #pragma strict_types |
| 6 | #pragma no_clone |
| 7 | #pragma no_shadow |
| 8 | #pragma no_inherit |
| 9 | #pragma verbose_errors |
| 10 | #pragma combine_strings |
| 11 | #pragma pedantic |
| 12 | #pragma range_check |
| 13 | #pragma warn_deprecated |
| 14 | |
| 15 | #include <combat.h> |
| 16 | #include <language.h> |
| 17 | #include <properties.h> |
| 18 | #include <wizlevels.h> |
| 19 | |
| 20 | #define SAVEFILE "/secure/ARCH/awmaster" |
| 21 | #define ADUMPFILE "/log/ARCH/RUESTUNGEN" |
| 22 | #define DDUMPFILE "/log/ARCH/DAMAGERS" |
| 23 | #define WDUMPFILE "/log/ARCH/WAFFEN" |
| 24 | |
| 25 | #define AWF_PUTON 1 |
| 26 | #define AWF_PUTOFF 2 |
| 27 | #define AWF_BOOST 4 |
| 28 | #define AWF_ZAUBER 8 |
| 29 | #define AWF_RESIST 16 |
| 30 | |
| 31 | #define AWM_TYPE 0 |
| 32 | #define AWM_CLASS 1 |
| 33 | #define AWM_EFF_CLASS 2 |
| 34 | #define AWM_FLAGS 3 |
| 35 | #define AWM_WEIGHT 4 |
| 36 | #define AWM_VALUE 5 |
| 37 | #define AWM_HANDS 6 |
| 38 | #define AWM_D_TYPE 7 |
| 39 | #define AWM_X_CLASS 8 |
| 40 | #define AWM_TIME 9 |
| 41 | |
| 42 | mapping armours,weapons,damagers; |
| 43 | private int save_me_soon; |
| 44 | |
| 45 | private int allowed() |
| 46 | { |
| 47 | if (previous_object() && geteuid(previous_object())==ROOTID) |
| 48 | return 1; |
| 49 | if (!process_call() && previous_object() && this_interactive() && ARCH_SECURITY) |
| 50 | return 1; |
| 51 | return 0; |
| 52 | } |
| 53 | |
| 54 | void create() |
| 55 | { |
| 56 | seteuid(getuid(this_object())); |
| 57 | |
| 58 | if (!restore_object(SAVEFILE)) |
| 59 | { |
| 60 | armours = ([]); |
| 61 | weapons = ([]); |
| 62 | damagers = ([]); |
| 63 | } |
| 64 | if (widthof(damagers) == 1) { |
| 65 | mapping tmp = damagers; |
| 66 | damagers = m_allocate(sizeof(tmp),2); |
| 67 | foreach(string r, int flag: tmp) { |
| 68 | damagers[r,0]=flag; |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | void save_me(int now) |
| 74 | { |
| 75 | if (now) |
| 76 | save_object(SAVEFILE); |
| 77 | else |
| 78 | save_me_soon=1; |
| 79 | } |
| 80 | |
| 81 | void reset() { |
| 82 | if (save_me_soon) |
| 83 | { |
| 84 | save_me_soon=0; |
| 85 | save_me(1); |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | public varargs int remove(int silent) { |
| 90 | save_me(1); |
| 91 | destruct(this_object()); |
| 92 | return 1; |
| 93 | } |
| 94 | |
| 95 | int xflags(object ob){ |
| 96 | int re; |
| 97 | mapping m; |
| 98 | if (!ob || !objectp(ob)) |
| 99 | return 0; |
| 100 | re=0; |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 101 | if ((({object})ob->QueryProp(P_WEAR_FUNC))==ob || |
| 102 | (({object})ob->QueryProp(P_WIELD_FUNC))==ob ) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 103 | re += AWF_PUTON; |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 104 | if ((({object})ob->QueryProp(P_REMOVE_FUNC))==ob || |
| 105 | (({object})ob->QueryProp(P_UNWIELD_FUNC))==ob ) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 106 | re += AWF_PUTOFF; |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 107 | if ((({object})ob->QueryProp(P_DEFEND_FUNC))==ob || |
| 108 | (({object})ob->QueryProp(P_HIT_FUNC))==ob ) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 109 | re += AWF_BOOST; |
| 110 | // ists nen Mapping und nicht leer? |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 111 | if (mappingp(m=({mapping})ob->QueryProp(P_RESISTANCE_STRENGTHS)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 112 | && sizeof(m)) |
| 113 | re += AWF_RESIST; |
| 114 | return re; |
| 115 | } |
| 116 | |
| 117 | void RegisterArmour() |
| 118 | { object ob; |
| 119 | string id; |
Arathorn | b305145 | 2021-05-13 21:13:03 +0200 | [diff] [blame] | 120 | int h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 121 | |
| 122 | if (!objectp(ob=previous_object()) || |
| 123 | member(inherit_list(ob),"/std/armour.c")==-1) |
| 124 | return; |
| 125 | id = explode(object_name(ob),"#")[0]; |
| 126 | if (member(armours,id)) |
| 127 | { |
| 128 | armours[id][AWM_TIME]=time(); |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 129 | if ((h=({int})ob->QueryProp(P_AC)) > armours[id][AWM_CLASS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 130 | { |
| 131 | armours[id][AWM_CLASS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 132 | } |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 133 | if ((h=({int})ob->QueryProp(P_EFFECTIVE_AC)) > armours[id][AWM_EFF_CLASS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 134 | { |
| 135 | armours[id][AWM_EFF_CLASS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 136 | } |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 137 | if ((h=({int})ob->QueryProp(P_NR_HANDS)) < armours[id][AWM_HANDS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 138 | { |
| 139 | armours[id][AWM_HANDS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 140 | } |
| 141 | if ((h=xflags(ob)) != armours[id][AWM_FLAGS]) |
| 142 | { |
| 143 | armours[id][AWM_FLAGS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 144 | } |
| 145 | } |
| 146 | else |
| 147 | { |
| 148 | armours += ([ id : |
| 149 | ([ |
bugfix | d94d093 | 2020-04-08 11:27:13 +0200 | [diff] [blame] | 150 | AWM_TYPE : ({string})ob->QueryProp(P_ARMOUR_TYPE) , |
| 151 | AWM_CLASS : ({int})ob->QueryProp(P_AC) , |
| 152 | AWM_EFF_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_AC) , |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 153 | AWM_FLAGS : xflags(ob), |
bugfix | d94d093 | 2020-04-08 11:27:13 +0200 | [diff] [blame] | 154 | AWM_WEIGHT : ({int})ob->QueryProp(P_WEIGHT) , |
| 155 | AWM_VALUE : ({int})ob->QueryProp(P_VALUE) , |
| 156 | AWM_HANDS : ({int})ob->QueryProp(P_NR_HANDS) , // Fuer Schilde |
| 157 | AWM_D_TYPE : ({string*})ob->QueryProp(P_DAM_TYPE) , |
| 158 | AWM_X_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_WC) || |
| 159 | ({int})ob->QueryProp(P_WC), |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 160 | AWM_TIME : time() |
| 161 | ]) ]); |
| 162 | } |
| 163 | save_me(0); |
| 164 | } |
| 165 | |
| 166 | void RegisterWeapon() |
| 167 | { object ob; |
| 168 | string id; |
Arathorn | b305145 | 2021-05-13 21:13:03 +0200 | [diff] [blame] | 169 | int h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 170 | |
| 171 | if (!objectp(ob=previous_object()) || |
| 172 | member(inherit_list(ob),"/std/weapon.c")==-1) |
| 173 | return; |
| 174 | id = explode(object_name(ob),"#")[0]; |
| 175 | if (member(weapons,id)) |
| 176 | { |
| 177 | weapons[id][AWM_TIME] = time(); |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 178 | if ((h=({int})ob->QueryProp(P_WC)) > weapons[id][AWM_CLASS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 179 | { |
| 180 | weapons[id][AWM_CLASS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 181 | } |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 182 | if ((h=({int})ob->QueryProp(P_EFFECTIVE_WC)) > weapons[id][AWM_EFF_CLASS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 183 | { |
| 184 | weapons[id][AWM_EFF_CLASS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 185 | } |
Vanion | 5065232 | 2020-03-10 21:13:25 +0100 | [diff] [blame] | 186 | if ((h=({int})ob->QueryProp(P_NR_HANDS)) < weapons[id][AWM_HANDS]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 187 | { |
| 188 | weapons[id][AWM_HANDS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 189 | } |
| 190 | if ((h=xflags(ob)) != weapons[id][AWM_FLAGS]) |
| 191 | { |
| 192 | weapons[id][AWM_FLAGS]=h; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 193 | } |
| 194 | } |
| 195 | else |
| 196 | { |
| 197 | weapons += ([ id : |
| 198 | ([ |
bugfix | d94d093 | 2020-04-08 11:27:13 +0200 | [diff] [blame] | 199 | AWM_TYPE : ({string})ob->QueryProp(P_WEAPON_TYPE) , |
| 200 | AWM_CLASS : ({int})ob->QueryProp(P_WC) , |
| 201 | AWM_EFF_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_WC) , |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 202 | AWM_FLAGS : xflags(ob), |
bugfix | d94d093 | 2020-04-08 11:27:13 +0200 | [diff] [blame] | 203 | AWM_WEIGHT : ({int})ob->QueryProp(P_WEIGHT) , |
| 204 | AWM_VALUE : ({int})ob->QueryProp(P_VALUE) , |
| 205 | AWM_HANDS : ({int})ob->QueryProp(P_NR_HANDS) , |
| 206 | AWM_D_TYPE : ({string*})ob->QueryProp(P_DAM_TYPE) , |
| 207 | AWM_X_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_AC) || |
| 208 | ({int})ob->QueryProp(P_AC), |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 209 | AWM_TIME : time() |
| 210 | ]) ]); |
| 211 | } |
| 212 | save_me(0); |
| 213 | } |
| 214 | |
| 215 | void RegisterDamager(object dam_ob,int old_dam, int new_dam) |
| 216 | { object ob; |
| 217 | int flag; |
| 218 | string fn; |
| 219 | |
| 220 | if (!objectp(ob=previous_object()) || |
| 221 | (member(inherit_list(ob),"/std/weapon.c")==-1 && |
| 222 | member(inherit_list(ob),"/std/armour.c")==-1 )) |
| 223 | return; |
| 224 | if (old_dam>new_dam) // Repair |
| 225 | flag=2; |
| 226 | else if (new_dam>old_dam) // Damage |
| 227 | flag=1; |
| 228 | else |
| 229 | return; |
| 230 | if (!objectp(dam_ob)) |
| 231 | return; |
| 232 | if (!(fn=old_explode(object_name(dam_ob),"#")[0]) || !stringp(fn)) |
| 233 | return; |
| 234 | damagers[fn,0]=damagers[fn,0]|flag; |
| 235 | damagers[fn,1]=time(); |
| 236 | save_me(0); |
| 237 | } |
| 238 | |
| 239 | string dtdump(mixed arg) |
| 240 | { string re; |
| 241 | int i,w; |
| 242 | |
| 243 | if (stringp(arg)) |
| 244 | return capitalize(arg); |
| 245 | if (!pointerp(arg) || !stringp(arg[0])) |
| 246 | return "<NONE>"; |
| 247 | if ((i=sizeof(arg))==1) |
| 248 | return capitalize(arg[0]); |
| 249 | w = (31-i)/i; |
| 250 | if (w--<1) |
| 251 | return "<MANY>"; |
| 252 | for (re="",--i;i>=0;i--) |
| 253 | { |
| 254 | if (!stringp(arg[i])) |
| 255 | re += "-"; |
| 256 | else |
| 257 | re += capitalize(arg[i][0..w]); |
| 258 | if (i) |
| 259 | re += "|"; |
| 260 | } |
| 261 | return re; |
| 262 | } |
| 263 | |
| 264 | int Dump(mixed what, int sortidx) |
| 265 | { string file,*ind; |
| 266 | mapping dump; |
| 267 | |
| 268 | if (!allowed()) |
| 269 | return -1; |
| 270 | |
| 271 | if (!what) |
| 272 | { |
| 273 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 274 | return 0; |
| 275 | } |
| 276 | if (stringp(what) && sizeof(what)>0) |
| 277 | { |
| 278 | what==what[0..0]; |
| 279 | if (what=="a") |
| 280 | what=1; |
| 281 | else if (what=="w") |
| 282 | what=2; |
| 283 | else if (what=="d") |
| 284 | what=3; |
| 285 | else |
| 286 | { |
| 287 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 288 | return 0; |
| 289 | } |
| 290 | } |
| 291 | if (!intp(what) || what<1 || what>3) |
| 292 | { |
| 293 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 294 | return 0; |
| 295 | } |
| 296 | if (what==3) // Die 'damagers' haben ein anderes Ausgabeformat |
| 297 | { |
| 298 | printf("AWM: Dumping 'damagers' to '%s'\n",DDUMPFILE); |
| 299 | if (sizeof(damagers) < 1) { |
| 300 | write("AWM: Dump aborted, mapping empty.\n"); |
| 301 | return 1; |
| 302 | } |
| 303 | if (file_size(DDUMPFILE)>1) |
| 304 | rm(DDUMPFILE); |
| 305 | |
| 306 | // nach letzter Aktualisierung sortieren. |
| 307 | mixed sorted = sort_array(m_indices(damagers), |
| 308 | function int (string a, string b) { |
| 309 | return damagers[a,1] < damagers[b,1]; |
| 310 | } ); |
| 311 | |
| 312 | string ausgabe = sprintf( |
| 313 | "--- Damagers-Dump --- %s --- %s ---\n\n"+ |
| 314 | "%:15s D R [Filename]\n", |
| 315 | dtime(time()),capitalize(getuid(this_interactive())), |
| 316 | "Datum/Zeit"); |
| 317 | foreach(string rue : sorted) { |
| 318 | ausgabe += sprintf("%:15s %1s %1s %s\n", |
| 319 | strftime("%y%m%d-%H:%M:%S",damagers[rue,1]), |
| 320 | (damagers[rue,0]&1?"+":"-"), |
| 321 | (damagers[rue,0]&2?"+":"-"), |
| 322 | rue); |
| 323 | } |
| 324 | |
| 325 | write_file(DDUMPFILE, ausgabe); |
| 326 | return 1; |
| 327 | } |
| 328 | if (what==2) |
| 329 | what=0; |
| 330 | file=(what?ADUMPFILE:WDUMPFILE); |
| 331 | |
| 332 | printf("AWM: Dumping '%s' to '%s'\n", |
| 333 | (what?"armours":"weapons"),file); |
| 334 | |
| 335 | dump=(what?armours:weapons); |
| 336 | |
| 337 | if (sortidx) { |
| 338 | ind = sort_array(m_indices(dump), |
| 339 | function int (string a, string b) |
| 340 | {return dump[a][sortidx] < dump[b][sortidx];} ); |
| 341 | } |
| 342 | else |
| 343 | ind = sort_array(m_indices(dump),#'>); |
| 344 | |
| 345 | if (sizeof(ind) < 1) |
| 346 | { |
| 347 | write("AWM: Dump aborted, mapping empty.\n"); |
| 348 | return 1; |
| 349 | } |
| 350 | |
| 351 | if (file_size(file)>1) |
| 352 | rm(file); |
| 353 | |
| 354 | string ausgabe = sprintf( |
| 355 | "--- %s-Dump --- %s --- %s ---\n\n"+ |
| 356 | "[Filename], Datum/Zeit\n"+ |
| 357 | " ____Typ___ CLS ECL XCL NFBR WGHT. VALUE H %30.30'_'|s\n", |
| 358 | (what?"Ruestungs":"Waffen"),dtime(time()), |
| 359 | capitalize(getuid(this_interactive())),"DamType(s)"); |
| 360 | |
| 361 | foreach(string index : ind) |
| 362 | { |
| 363 | ausgabe += sprintf( |
| 364 | "[%s] %s\n %10s %3d %3d %3d %1s%1s%1s%1s %5d %5d %1d %-30.30s\n", |
| 365 | index, strftime("%y%m%d-%H:%M:%S",dump[index][AWM_TIME]), |
| 366 | dump[index][AWM_TYPE], |
| 367 | dump[index][AWM_CLASS], |
| 368 | dump[index][AWM_EFF_CLASS], |
| 369 | dump[index][AWM_X_CLASS], |
| 370 | (dump[index][AWM_FLAGS]&AWF_PUTON?"+":"-"), |
| 371 | (dump[index][AWM_FLAGS]&AWF_PUTOFF?"+":"-"), |
| 372 | (dump[index][AWM_FLAGS]&AWF_BOOST?"+":"-"), |
| 373 | (dump[index][AWM_FLAGS]&AWF_RESIST?"+":"-"), |
| 374 | dump[index][AWM_WEIGHT], |
| 375 | dump[index][AWM_VALUE], |
| 376 | dump[index][AWM_HANDS], |
| 377 | dtdump(dump[index][AWM_D_TYPE]) ); |
| 378 | } |
| 379 | write_file(file,ausgabe); |
| 380 | write("AWM: Done.\n"); |
| 381 | return 1; |
| 382 | } |
| 383 | |
| 384 | int Unregister(string what) |
| 385 | { |
| 386 | if (!allowed()) |
| 387 | return -1; |
| 388 | if (!what) |
| 389 | { |
| 390 | write("Du solltest schon einen Filenamen angeben!\n"); |
| 391 | return 0; |
| 392 | } |
| 393 | if (member(armours,what)) |
| 394 | { |
| 395 | m_delete(armours,what); |
| 396 | write("Unregistered "+what+" from 'armours'.\n"); |
| 397 | return 1; |
| 398 | } |
| 399 | if (member(weapons,what)) |
| 400 | { |
| 401 | m_delete(weapons,what); |
| 402 | write("Unregistered "+what+" from 'weapons'.\n"); |
| 403 | return 1; |
| 404 | } |
| 405 | if (member(damagers,what)) |
| 406 | { |
| 407 | m_delete(damagers,what); |
| 408 | write("Unregistered "+what+" from 'damagers'.\n"); |
| 409 | return 1; |
| 410 | } |
| 411 | save_me(0); |
| 412 | return 0; |
| 413 | } |
| 414 | |
| 415 | int ResetDamagers() |
| 416 | { |
| 417 | if (!allowed()) |
| 418 | return -1; |
| 419 | damagers = m_allocate(0,2); |
| 420 | save_me(1); |
| 421 | return 1; |
| 422 | } |
| 423 | |