MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // ---------------------------------------------------------------------- |
| 2 | // Die Basis- und Hilfsfunktionen der Teller. |
| 3 | // Stack und Memory |
| 4 | // ---------------------------------------------------------------------- |
| 5 | #include "teller.h" |
| 6 | |
| 7 | #include <moving.h> |
| 8 | #include <terminal.h> |
| 9 | |
| 10 | static mixed *stack; |
| 11 | static mapping memory; |
| 12 | static object *oldinv; |
| 13 | static bool mit_namen; |
| 14 | static bool fehler_passiert; |
| 15 | static bool mit_say; |
| 16 | static bool secureinv; |
| 17 | static bool dologaccess; |
| 18 | static bool pretty; |
| 19 | static bool do_profile; |
| 20 | |
| 21 | static mixed top(); |
| 22 | static mixed pop(); |
| 23 | static void push( mixed ob ); |
| 24 | |
| 25 | static void dump_obj( mixed ob, int indent ); |
| 26 | |
| 27 | void create() |
| 28 | { |
| 29 | stack = ({}); |
| 30 | memory = ([]); |
| 31 | mit_namen = TRUE; |
| 32 | fehler_passiert = FALSE; |
| 33 | mit_say = TRUE; |
| 34 | secureinv = FALSE; |
| 35 | dologaccess = FALSE; |
| 36 | pretty = TRUE; |
| 37 | } |
| 38 | |
| 39 | // ---------------------------------------------------------------------- |
| 40 | // Hilfsfunktionen |
| 41 | // ---------------------------------------------------------------------- |
| 42 | |
| 43 | static int error( string msg ) |
| 44 | { |
| 45 | write( "Fehler in "+msg+".\n" ); |
| 46 | fehler_passiert = TRUE; |
| 47 | return FALSE; |
| 48 | } |
| 49 | |
| 50 | static int memo( string msg ) |
| 51 | { |
| 52 | write( "MEMO: "+msg+".\n" ); |
| 53 | return FALSE; |
| 54 | } |
| 55 | |
| 56 | static int calcinv( string str ) |
| 57 | { |
| 58 | object* obs; |
| 59 | object ob; |
| 60 | int val; |
| 61 | |
| 62 | if( sscanf( str, "%d", val ) == 1 ) |
| 63 | { |
| 64 | obs = all_inventory(top()); |
| 65 | if( val<0 || val>=sizeof(obs) ) |
| 66 | return error( "'.': Kein Objekt mit dieser Nummer" ); |
| 67 | pop(); |
| 68 | push(obs[val]); |
| 69 | return TRUE; |
| 70 | } |
| 71 | |
| 72 | if( !(ob=present(str,top())) ) |
| 73 | return error( "'.': Kein Objekt namens \""+str+"\" gefunden" ); |
| 74 | pop(); |
| 75 | push(ob); |
| 76 | return TRUE; |
| 77 | } |
| 78 | |
| 79 | static mixed push_str( string str ) |
| 80 | { |
| 81 | return |
| 82 | push( implode(old_explode( implode(old_explode( implode(old_explode( |
| 83 | " "+str+" ", |
| 84 | "\\n"),"\n"), "\\e"),ESC), "\\b"),"\b") |
| 85 | [1..<2] ); |
| 86 | } |
| 87 | |
| 88 | static void do_move( object ob, mixed dest ) |
| 89 | { |
| 90 | int weight; |
| 91 | |
| 92 | weight = ob->QueryWeight(); |
| 93 | if( environment(ob) ) |
| 94 | environment(ob)->AddWeight(-weight); |
| 95 | ob->move(dest,M_NOCHECK); |
| 96 | dest->AddWeight(weight); |
| 97 | } |
| 98 | |
| 99 | void heart_beat() |
| 100 | { |
| 101 | object *newinv; |
| 102 | object owner; |
| 103 | int i,j; |
| 104 | |
| 105 | if( owner=find_player(getuid()) ) |
| 106 | { |
| 107 | newinv = sort_array( all_inventory(owner), lambda( ({'a,'b}), |
| 108 | ({ #'<, |
| 109 | ({ #'object_name, 'a }), |
| 110 | ({ #'object_name, 'b }) |
| 111 | }) |
| 112 | ) ); |
| 113 | if( pointerp(oldinv) ) |
| 114 | { |
| 115 | for( i=0,j=0; i<sizeof(newinv) && j<sizeof(oldinv) ; ) |
| 116 | { |
| 117 | if( newinv[i] == oldinv[j] ) |
| 118 | { i++; j++; } |
| 119 | else if( object_name(newinv[i]) > object_name(oldinv[j]) ) |
| 120 | { |
| 121 | tell_object(owner, |
| 122 | "MEMO: \""+object_name(newinv[i])+"\" entered inventory.\n" ); |
| 123 | i++; |
| 124 | } |
| 125 | else |
| 126 | j++; |
| 127 | } |
| 128 | for( ; i<sizeof(newinv) ; i++ ) |
| 129 | tell_object( owner, |
| 130 | "MEMO: \""+object_name(newinv[i])+"\" entered inventory.\n" ); |
| 131 | } |
| 132 | } |
| 133 | oldinv = newinv; |
| 134 | } |
| 135 | |
| 136 | // ---------------------------------------------------------------------- |
| 137 | // Dumpfunktionen |
| 138 | // ---------------------------------------------------------------------- |
| 139 | |
| 140 | static void dump_array( mixed* ob, int indent ) |
| 141 | { |
| 142 | int i; |
| 143 | for( i=0; i<sizeof(ob); i++ ) |
| 144 | { |
| 145 | printf( "%*s", indent, "" ); |
| 146 | dump_obj( ob[i], indent ); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | static void dump_mapping( mapping ob, int indent ) |
| 151 | { |
| 152 | mixed *index; |
| 153 | mixed key; |
| 154 | int i,j,values; |
| 155 | |
| 156 | index = m_indices( ob ); |
| 157 | values = get_type_info(ob)[1]; |
| 158 | for( i=0; i<sizeof(index); i++ ) |
| 159 | { |
| 160 | key = index[i]; |
| 161 | printf( "%*s", indent, "" ); |
| 162 | dump_obj( key, indent ); |
| 163 | for( j=0; j<values; j++ ) |
| 164 | { |
| 165 | printf( "%*s: ", indent+1, "" ); |
| 166 | dump_obj( ob[key,j], indent+3 ); |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | static void dump_obj( mixed ob, int indent ) |
| 172 | { |
| 173 | if( !pretty ) |
| 174 | { |
| 175 | printf( "%O\n", ob ); |
| 176 | return; |
| 177 | } |
| 178 | if( intp(ob) ) |
| 179 | write( ob + "\n" ); |
| 180 | else if( floatp(ob) ) |
| 181 | printf( "%1.5f\n", ob ); |
| 182 | else if( stringp(ob) ) |
| 183 | { |
| 184 | if ( ob==";" ) |
| 185 | write( ";\n" ); |
| 186 | else |
| 187 | { |
| 188 | write( "\"" + implode(old_explode( implode(old_explode( implode(old_explode( |
| 189 | " "+ob+" ", |
| 190 | "\n"),"\\n"), ESC), "\\e"), "\b"),"\\b") |
| 191 | [1..<2] + "\"\n" |
| 192 | ); |
| 193 | } |
| 194 | } |
| 195 | else if( objectp(ob) ) |
| 196 | { |
| 197 | if( mit_namen ) |
| 198 | write( object_name(ob)+" ("+ob->name(WER,0)+")\n" ); |
| 199 | else |
| 200 | write( object_name(ob)+"\n" ); |
| 201 | } |
| 202 | else if( mappingp(ob) ) |
| 203 | { |
| 204 | write( "([\n" ); |
| 205 | dump_mapping( ob, indent + 2 ); |
| 206 | printf( "%*s\n", indent + 2, "])" ); |
| 207 | } |
| 208 | else if( pointerp(ob) ) |
| 209 | { |
| 210 | write( "({\n" ); |
| 211 | dump_array( ob, indent+2 ); |
| 212 | printf( "%*s\n", indent+2 , "})" ); |
| 213 | } |
| 214 | else |
| 215 | printf( "%O\n", ob ); |
| 216 | } |
| 217 | |
| 218 | // ---------------------------------------------------------------------- |
| 219 | // Speicherfunktionen |
| 220 | // ---------------------------------------------------------------------- |
| 221 | |
| 222 | static void do_recall( mixed arg ) |
| 223 | { |
| 224 | if( member(memory,arg) ) |
| 225 | push( memory[arg,0] ); |
| 226 | } |
| 227 | |
| 228 | static void do_store( mixed arg ) |
| 229 | { |
| 230 | if ( sizeof(stack) ) |
| 231 | { |
| 232 | if( !top() ) |
| 233 | memory = m_delete(memory,arg); |
| 234 | else |
| 235 | memory += ([ arg: top(); 0 ]); |
| 236 | } |
| 237 | else |
| 238 | memo( "Es wurde kein Wert in \""+arg+"\" gespeichert" ); |
| 239 | } |
| 240 | |
| 241 | // ---------------------------------------------------------------------- |
| 242 | // Stack-Funktionen |
| 243 | // ---------------------------------------------------------------------- |
| 244 | |
| 245 | static void push( mixed ob ) |
| 246 | { |
| 247 | stack = ({ ob }) + stack; |
| 248 | } |
| 249 | |
| 250 | static mixed pop() |
| 251 | { |
| 252 | mixed answer; |
| 253 | |
| 254 | if( !sizeof( stack ) ) |
| 255 | return FALSE; |
| 256 | answer = stack[0]; |
| 257 | stack = stack[1..]; |
| 258 | return answer; |
| 259 | } |
| 260 | |
| 261 | static mixed top() |
| 262 | { |
| 263 | if( sizeof(stack) ) |
| 264 | return stack[0]; |
| 265 | } |
| 266 | |
| 267 | static varargs int becomes_obj( mixed argv) |
| 268 | { |
| 269 | object ob; |
| 270 | |
| 271 | if( !pointerp(argv) ) // default ist der stack ! |
| 272 | argv = stack; |
| 273 | if( !sizeof(argv) ) |
| 274 | return FALSE; |
| 275 | if( stringp(argv[0]) && !catch(call_other(argv[0],"?")) ) |
| 276 | { |
| 277 | argv[0] = find_object(argv[0]); |
| 278 | return TRUE; |
| 279 | } |
| 280 | else |
| 281 | return objectp(argv[0]); |
| 282 | } |
| 283 | |
| 284 | static isSubStr( pl, str, len ) |
| 285 | { |
| 286 | return getuid(pl)[0..len] == str; |
| 287 | } |
| 288 | |
| 289 | static becomes_pl(argv) |
| 290 | { |
| 291 | object pl; |
| 292 | object* pllist; |
| 293 | string str; |
| 294 | int len; |
| 295 | |
| 296 | if( !argv ) argv = stack; |
| 297 | if( !sizeof(argv) || ( becomes_obj() && !interactive(argv[0]) ) ) |
| 298 | return FALSE; |
| 299 | if( stringp(argv[0]) ) |
| 300 | { |
| 301 | str = lower_case( argv[0] ); |
| 302 | pl = 0; |
| 303 | if( str[<1..<1] == "*" ) |
| 304 | { |
| 305 | str = str[0..<2]; |
| 306 | len = sizeof(str) - 1; |
| 307 | pllist = filter( users(), #'isSubStr, str, len ); |
| 308 | if( sizeof(pllist) == 1 ) |
| 309 | { |
| 310 | pl=pllist[0]; |
| 311 | argv[0] = pl; |
| 312 | } |
| 313 | } |
| 314 | if( !pl && pl=find_player(argv[0]) ) |
| 315 | argv[0] = pl; |
| 316 | return pl; |
| 317 | } |
| 318 | return argv[0]; |
| 319 | } |
| 320 | |
| 321 | static DumpObj( ob ) |
| 322 | { |
| 323 | string ans; |
| 324 | int i,j; |
| 325 | |
| 326 | if( intp(ob) ) |
| 327 | return ""+ob; |
| 328 | else if( stringp(ob) ) |
| 329 | return "\""+implode(explode(ob,"\n"),"\\n")+"\""; |
| 330 | else if( objectp(ob) ) |
| 331 | return "\""+object_name(ob)+"\""; |
| 332 | else if( mappingp(ob) ) |
| 333 | { |
| 334 | ans="(["; |
| 335 | for( i=0; i<sizeof(ob)-1; i++ ) |
| 336 | ans += DumpMapp(ob,i)+","; |
| 337 | // rely on right value of i |
| 338 | return ans+DumpMapp(ob,i)+"])"; |
| 339 | } |
| 340 | else |
| 341 | { |
| 342 | ans="({"; |
| 343 | for( i=0; i<sizeof(ob)-1; i++ ) |
| 344 | ans += DumpObj(ob[i])+","; |
| 345 | // rely on right value of i |
| 346 | return ans+DumpObj(ob[i])+"})"; |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | static DumpMapp(ob,i) |
| 351 | { |
| 352 | int j,vz; |
| 353 | string ans; |
| 354 | |
| 355 | vz = get_type_info(ob)[1]; |
| 356 | ans = DumpObj(m_indices(ob)[i])+":"; |
| 357 | for( j=0; j<vz-1; j++ ) |
| 358 | ans += DumpObj(ob[m_indices(ob)[i],j])+";"; |
| 359 | // rely on value of j |
| 360 | return ans + DumpObj(ob[m_indices(ob)[i],j]); |
| 361 | } |