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; |
| 101 | if (((object)ob->QueryProp(P_WEAR_FUNC))==ob || |
| 102 | ((object)ob->QueryProp(P_WIELD_FUNC))==ob ) |
| 103 | re += AWF_PUTON; |
| 104 | if (((object)ob->QueryProp(P_REMOVE_FUNC))==ob || |
| 105 | ((object)ob->QueryProp(P_UNWIELD_FUNC))==ob ) |
| 106 | re += AWF_PUTOFF; |
| 107 | if (((object)ob->QueryProp(P_DEFEND_FUNC))==ob || |
| 108 | ((object)ob->QueryProp(P_HIT_FUNC))==ob ) |
| 109 | re += AWF_BOOST; |
| 110 | // ists nen Mapping und nicht leer? |
| 111 | if (mappingp(m=(mapping)ob->QueryProp(P_RESISTANCE_STRENGTHS)) |
| 112 | && sizeof(m)) |
| 113 | re += AWF_RESIST; |
| 114 | return re; |
| 115 | } |
| 116 | |
| 117 | void RegisterArmour() |
| 118 | { object ob; |
| 119 | string id; |
| 120 | int flag,h; |
| 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(); |
| 129 | flag=0; |
| 130 | if ((h=(int)ob->QueryProp(P_AC)) > armours[id][AWM_CLASS]) |
| 131 | { |
| 132 | armours[id][AWM_CLASS]=h; |
| 133 | flag=1; |
| 134 | } |
| 135 | if ((h=(int)ob->QueryProp(P_EFFECTIVE_AC)) > armours[id][AWM_EFF_CLASS]) |
| 136 | { |
| 137 | armours[id][AWM_EFF_CLASS]=h; |
| 138 | flag=1; |
| 139 | } |
| 140 | if ((h=(int)ob->QueryProp(P_NR_HANDS)) < armours[id][AWM_HANDS]) |
| 141 | { |
| 142 | armours[id][AWM_HANDS]=h; |
| 143 | flag=1; |
| 144 | } |
| 145 | if ((h=xflags(ob)) != armours[id][AWM_FLAGS]) |
| 146 | { |
| 147 | armours[id][AWM_FLAGS]=h; |
| 148 | flag=1; |
| 149 | } |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | armours += ([ id : |
| 154 | ([ |
| 155 | AWM_TYPE : ob->QueryProp(P_ARMOUR_TYPE) , |
| 156 | AWM_CLASS : ob->QueryProp(P_AC) , |
| 157 | AWM_EFF_CLASS : ob->QueryProp(P_EFFECTIVE_AC) , |
| 158 | AWM_FLAGS : xflags(ob), |
| 159 | AWM_WEIGHT : ob->QueryProp(P_WEIGHT) , |
| 160 | AWM_VALUE : ob->QueryProp(P_VALUE) , |
| 161 | AWM_HANDS : ob->QueryProp(P_NR_HANDS) , // Fuer Schilde |
| 162 | AWM_D_TYPE : ob->QueryProp(P_DAM_TYPE) , |
| 163 | AWM_X_CLASS : ob->QueryProp(P_EFFECTIVE_WC) || |
| 164 | ob->QueryProp(P_WC), |
| 165 | AWM_TIME : time() |
| 166 | ]) ]); |
| 167 | } |
| 168 | save_me(0); |
| 169 | } |
| 170 | |
| 171 | void RegisterWeapon() |
| 172 | { object ob; |
| 173 | string id; |
| 174 | int flag,h; |
| 175 | |
| 176 | if (!objectp(ob=previous_object()) || |
| 177 | member(inherit_list(ob),"/std/weapon.c")==-1) |
| 178 | return; |
| 179 | id = explode(object_name(ob),"#")[0]; |
| 180 | if (member(weapons,id)) |
| 181 | { |
| 182 | weapons[id][AWM_TIME] = time(); |
| 183 | flag=0; |
| 184 | if ((h=(int)ob->QueryProp(P_WC)) > weapons[id][AWM_CLASS]) |
| 185 | { |
| 186 | weapons[id][AWM_CLASS]=h; |
| 187 | flag=1; |
| 188 | } |
| 189 | if ((h=(int)ob->QueryProp(P_EFFECTIVE_WC)) > weapons[id][AWM_EFF_CLASS]) |
| 190 | { |
| 191 | weapons[id][AWM_EFF_CLASS]=h; |
| 192 | flag=1; |
| 193 | } |
| 194 | if ((h=(int)ob->QueryProp(P_NR_HANDS)) < weapons[id][AWM_HANDS]) |
| 195 | { |
| 196 | weapons[id][AWM_HANDS]=h; |
| 197 | flag=1; |
| 198 | } |
| 199 | if ((h=xflags(ob)) != weapons[id][AWM_FLAGS]) |
| 200 | { |
| 201 | weapons[id][AWM_FLAGS]=h; |
| 202 | flag=1; |
| 203 | } |
| 204 | } |
| 205 | else |
| 206 | { |
| 207 | weapons += ([ id : |
| 208 | ([ |
| 209 | AWM_TYPE : ob->QueryProp(P_WEAPON_TYPE) , |
| 210 | AWM_CLASS : ob->QueryProp(P_WC) , |
| 211 | AWM_EFF_CLASS : ob->QueryProp(P_EFFECTIVE_WC) , |
| 212 | AWM_FLAGS : xflags(ob), |
| 213 | AWM_WEIGHT : ob->QueryProp(P_WEIGHT) , |
| 214 | AWM_VALUE : ob->QueryProp(P_VALUE) , |
| 215 | AWM_HANDS : ob->QueryProp(P_NR_HANDS) , |
| 216 | AWM_D_TYPE : ob->QueryProp(P_DAM_TYPE) , |
| 217 | AWM_X_CLASS : ob->QueryProp(P_EFFECTIVE_AC) || |
| 218 | ob->QueryProp(P_AC), |
| 219 | AWM_TIME : time() |
| 220 | ]) ]); |
| 221 | } |
| 222 | save_me(0); |
| 223 | } |
| 224 | |
| 225 | void RegisterDamager(object dam_ob,int old_dam, int new_dam) |
| 226 | { object ob; |
| 227 | int flag; |
| 228 | string fn; |
| 229 | |
| 230 | if (!objectp(ob=previous_object()) || |
| 231 | (member(inherit_list(ob),"/std/weapon.c")==-1 && |
| 232 | member(inherit_list(ob),"/std/armour.c")==-1 )) |
| 233 | return; |
| 234 | if (old_dam>new_dam) // Repair |
| 235 | flag=2; |
| 236 | else if (new_dam>old_dam) // Damage |
| 237 | flag=1; |
| 238 | else |
| 239 | return; |
| 240 | if (!objectp(dam_ob)) |
| 241 | return; |
| 242 | if (!(fn=old_explode(object_name(dam_ob),"#")[0]) || !stringp(fn)) |
| 243 | return; |
| 244 | damagers[fn,0]=damagers[fn,0]|flag; |
| 245 | damagers[fn,1]=time(); |
| 246 | save_me(0); |
| 247 | } |
| 248 | |
| 249 | string dtdump(mixed arg) |
| 250 | { string re; |
| 251 | int i,w; |
| 252 | |
| 253 | if (stringp(arg)) |
| 254 | return capitalize(arg); |
| 255 | if (!pointerp(arg) || !stringp(arg[0])) |
| 256 | return "<NONE>"; |
| 257 | if ((i=sizeof(arg))==1) |
| 258 | return capitalize(arg[0]); |
| 259 | w = (31-i)/i; |
| 260 | if (w--<1) |
| 261 | return "<MANY>"; |
| 262 | for (re="",--i;i>=0;i--) |
| 263 | { |
| 264 | if (!stringp(arg[i])) |
| 265 | re += "-"; |
| 266 | else |
| 267 | re += capitalize(arg[i][0..w]); |
| 268 | if (i) |
| 269 | re += "|"; |
| 270 | } |
| 271 | return re; |
| 272 | } |
| 273 | |
| 274 | int Dump(mixed what, int sortidx) |
| 275 | { string file,*ind; |
| 276 | mapping dump; |
| 277 | |
| 278 | if (!allowed()) |
| 279 | return -1; |
| 280 | |
| 281 | if (!what) |
| 282 | { |
| 283 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 284 | return 0; |
| 285 | } |
| 286 | if (stringp(what) && sizeof(what)>0) |
| 287 | { |
| 288 | what==what[0..0]; |
| 289 | if (what=="a") |
| 290 | what=1; |
| 291 | else if (what=="w") |
| 292 | what=2; |
| 293 | else if (what=="d") |
| 294 | what=3; |
| 295 | else |
| 296 | { |
| 297 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 298 | return 0; |
| 299 | } |
| 300 | } |
| 301 | if (!intp(what) || what<1 || what>3) |
| 302 | { |
| 303 | write("Nimm doch mal einen richtigen Parameter!\n"); |
| 304 | return 0; |
| 305 | } |
| 306 | if (what==3) // Die 'damagers' haben ein anderes Ausgabeformat |
| 307 | { |
| 308 | printf("AWM: Dumping 'damagers' to '%s'\n",DDUMPFILE); |
| 309 | if (sizeof(damagers) < 1) { |
| 310 | write("AWM: Dump aborted, mapping empty.\n"); |
| 311 | return 1; |
| 312 | } |
| 313 | if (file_size(DDUMPFILE)>1) |
| 314 | rm(DDUMPFILE); |
| 315 | |
| 316 | // nach letzter Aktualisierung sortieren. |
| 317 | mixed sorted = sort_array(m_indices(damagers), |
| 318 | function int (string a, string b) { |
| 319 | return damagers[a,1] < damagers[b,1]; |
| 320 | } ); |
| 321 | |
| 322 | string ausgabe = sprintf( |
| 323 | "--- Damagers-Dump --- %s --- %s ---\n\n"+ |
| 324 | "%:15s D R [Filename]\n", |
| 325 | dtime(time()),capitalize(getuid(this_interactive())), |
| 326 | "Datum/Zeit"); |
| 327 | foreach(string rue : sorted) { |
| 328 | ausgabe += sprintf("%:15s %1s %1s %s\n", |
| 329 | strftime("%y%m%d-%H:%M:%S",damagers[rue,1]), |
| 330 | (damagers[rue,0]&1?"+":"-"), |
| 331 | (damagers[rue,0]&2?"+":"-"), |
| 332 | rue); |
| 333 | } |
| 334 | |
| 335 | write_file(DDUMPFILE, ausgabe); |
| 336 | return 1; |
| 337 | } |
| 338 | if (what==2) |
| 339 | what=0; |
| 340 | file=(what?ADUMPFILE:WDUMPFILE); |
| 341 | |
| 342 | printf("AWM: Dumping '%s' to '%s'\n", |
| 343 | (what?"armours":"weapons"),file); |
| 344 | |
| 345 | dump=(what?armours:weapons); |
| 346 | |
| 347 | if (sortidx) { |
| 348 | ind = sort_array(m_indices(dump), |
| 349 | function int (string a, string b) |
| 350 | {return dump[a][sortidx] < dump[b][sortidx];} ); |
| 351 | } |
| 352 | else |
| 353 | ind = sort_array(m_indices(dump),#'>); |
| 354 | |
| 355 | if (sizeof(ind) < 1) |
| 356 | { |
| 357 | write("AWM: Dump aborted, mapping empty.\n"); |
| 358 | return 1; |
| 359 | } |
| 360 | |
| 361 | if (file_size(file)>1) |
| 362 | rm(file); |
| 363 | |
| 364 | string ausgabe = sprintf( |
| 365 | "--- %s-Dump --- %s --- %s ---\n\n"+ |
| 366 | "[Filename], Datum/Zeit\n"+ |
| 367 | " ____Typ___ CLS ECL XCL NFBR WGHT. VALUE H %30.30'_'|s\n", |
| 368 | (what?"Ruestungs":"Waffen"),dtime(time()), |
| 369 | capitalize(getuid(this_interactive())),"DamType(s)"); |
| 370 | |
| 371 | foreach(string index : ind) |
| 372 | { |
| 373 | ausgabe += sprintf( |
| 374 | "[%s] %s\n %10s %3d %3d %3d %1s%1s%1s%1s %5d %5d %1d %-30.30s\n", |
| 375 | index, strftime("%y%m%d-%H:%M:%S",dump[index][AWM_TIME]), |
| 376 | dump[index][AWM_TYPE], |
| 377 | dump[index][AWM_CLASS], |
| 378 | dump[index][AWM_EFF_CLASS], |
| 379 | dump[index][AWM_X_CLASS], |
| 380 | (dump[index][AWM_FLAGS]&AWF_PUTON?"+":"-"), |
| 381 | (dump[index][AWM_FLAGS]&AWF_PUTOFF?"+":"-"), |
| 382 | (dump[index][AWM_FLAGS]&AWF_BOOST?"+":"-"), |
| 383 | (dump[index][AWM_FLAGS]&AWF_RESIST?"+":"-"), |
| 384 | dump[index][AWM_WEIGHT], |
| 385 | dump[index][AWM_VALUE], |
| 386 | dump[index][AWM_HANDS], |
| 387 | dtdump(dump[index][AWM_D_TYPE]) ); |
| 388 | } |
| 389 | write_file(file,ausgabe); |
| 390 | write("AWM: Done.\n"); |
| 391 | return 1; |
| 392 | } |
| 393 | |
| 394 | int Unregister(string what) |
| 395 | { |
| 396 | if (!allowed()) |
| 397 | return -1; |
| 398 | if (!what) |
| 399 | { |
| 400 | write("Du solltest schon einen Filenamen angeben!\n"); |
| 401 | return 0; |
| 402 | } |
| 403 | if (member(armours,what)) |
| 404 | { |
| 405 | m_delete(armours,what); |
| 406 | write("Unregistered "+what+" from 'armours'.\n"); |
| 407 | return 1; |
| 408 | } |
| 409 | if (member(weapons,what)) |
| 410 | { |
| 411 | m_delete(weapons,what); |
| 412 | write("Unregistered "+what+" from 'weapons'.\n"); |
| 413 | return 1; |
| 414 | } |
| 415 | if (member(damagers,what)) |
| 416 | { |
| 417 | m_delete(damagers,what); |
| 418 | write("Unregistered "+what+" from 'damagers'.\n"); |
| 419 | return 1; |
| 420 | } |
| 421 | save_me(0); |
| 422 | return 0; |
| 423 | } |
| 424 | |
| 425 | int ResetDamagers() |
| 426 | { |
| 427 | if (!allowed()) |
| 428 | return -1; |
| 429 | damagers = m_allocate(0,2); |
| 430 | save_me(1); |
| 431 | return 1; |
| 432 | } |
| 433 | |