Version 1/121012 of Mutable Kinds by Dannii Willis begins here. "Change the default values of the properties of Mutable Kinds at run-time" [ TODO: better error messages for running out of mutable properties inheritance? ] Use maximum mutable kinds of at least 5 translates as (- Constant MAX_MUT_KINDS = {N}; -). Use maximum mutable properties of at least 5 translates as (- Constant MAX_MUT_PROPS = {N}; -). Include (- ! Stores the default value of each kind, each row is Kind, Default Object Constant MAX_MUT_KINDS_LEN = MAX_MUT_KINDS * 2; Array kind_defaults --> MAX_MUT_KINDS_LEN; ! Each row on the mutable property table is: Kind, Prop, Value, Default Value !Constant MAX_MUT_KINDS_PROPS = MAX_MUT_KINDS * MAX_MUT_PROPS; Constant MAX_MUT_PROPS_LEN = MAX_MUT_PROPS * 4; Array mutable_properties --> MAX_MUT_PROPS_LEN; -). Section - Functions for accessing mutable kinds Include (- ! Find the kind of an object [ KindOfObj obj; return KindHierarchy-->( ( obj.KD_Count ) * 2 ); ]; ! Check if an kind is mutable [ IsMutKind kind i; while ( i < MAX_MUT_KINDS_LEN ) { if ( kind_defaults-->i == kind ) return 1; if ( kind_defaults-->i == 0 ) return 0; i = i + 2; } ]; ! Make a kind mutable [ MakeMutKind kind i obj; while ( i < MAX_MUT_KINDS_LEN ) { ! This kind is already mutable. Hurray! if ( kind_defaults-->i == kind ) return; ! Find and set the default object for this kind if ( kind_defaults-->i == 0 ) { kind_defaults-->i = kind; objectloop( obj ofclass kind ) { kind_defaults-->(i + 1) = obj; return; } } i = i + 2; } print "Error: too many mutable kinds!^^"; ]; ! Find the default object for a mutable kind [ DefaultObjOfKind kind i; while ( i < MAX_MUT_KINDS_LEN ) { if ( kind_defaults-->i == kind ) return kind_defaults-->(i + 1); if ( kind_defaults-->i == 0 ) break; i = i + 2; } print "Error: mutable kind not found!^^"; ]; ! Test if a kind is a subkind of another kind [ TestSubkind subclass superclass i; ! These classes are outside the kind heirarchy and must be dealt with first if ( subclass == Class or Object or Routine or String or VPH_Class ) rfalse; while (1) { if ( KindHierarchy-->i == subclass ) return KindHierarchy-->( KindHierarchy-->(i + 1) * 2 ) == superclass; i = i + 2; } ]; -). Section - Phrases for accessing mutable kinds To decide which K is kind of/-- (kind - name of kind of value of kind K): (- KindOfObj( {-default-value-for:kind} ) -). To repeat with (loopvar - nonexisting K variable) running through the/-- kinds of (kind - name of kind of value of kind K) begin -- end: (- objectloop( {loopvar} && metaclass({loopvar}) == Class && TestSubkind({loopvar}, KindOfObj({-default-value-for:kind})) ) -). Section - Implementing mutable kinds Include (- [ GProperty K V pr obj i kind val defaultval; if (K == OBJECT_TY) obj = V; else obj = KOV_representatives-->K; if (obj == 0) { RunTimeProblem(RTP_PROPOFNOTHING, obj, pr); rfalse; } ! Property of a Kind if ( metaclass(obj) == Class ) { while ( i < MAX_MUT_PROPS_LEN ) { ! mutable property not set if ( mutable_properties-->i == 0 ) return DefaultObjOfKind(obj).pr; ! Retreive a mutable property if ( mutable_properties-->i == obj && mutable_properties-->(i + 1) == pr ) return mutable_properties-->(i + 2); i = i + 4; } rfalse; } if (obj provides pr) { if (K == OBJECT_TY) { if (pr == door_to) return obj.pr(); if (WhetherProvides(V, false, pr, true)) { ! Get the object's own property val = obj.pr; kind = KindOfObj( obj ); ! Non-mutable kind, return the object's own property if ( IsMutKind( kind ) == 0 ) return val; ! Search the mutable properties table while ( i < MAX_MUT_PROPS_LEN ) { ! mutable property not set if ( mutable_properties-->i == 0 ) return val; ! Retreive a mutable property if ( mutable_properties-->i == kind && mutable_properties-->(i + 1) == pr ) { ! Check if this object has a non-default property value and return it, otherwise return the kind's default value defaultval = mutable_properties-->(i + 3); if ( val == defaultval ) return mutable_properties-->(i + 2); else return val; } i = i + 4; } } rfalse; } if (obj ofclass K0_kind) WhetherProvides(V, false, pr, true); ! to force a run-time problem if ((V < 1) || (V > obj.value_range)) { RunTimeProblem(RTP_BADVALUEPROPERTY); return 0; } return (obj.pr)-->(V+COL_HSIZE); } else { if (obj ofclass K0_kind) WhetherProvides(V, false, pr, true); ! to force a run-time problem } rfalse; ]; -) instead of "Value Property" in "RTP.i6t". Include (- [ WriteGProperty K V pr val obj i; if (K == OBJECT_TY) obj = V; else obj = KOV_representatives-->K; if (obj == 0) { RunTimeProblem(RTP_PROPOFNOTHING, obj, pr); rfalse; } if (K == OBJECT_TY) { if ( metaclass(obj) == Class ) { ! Make this a mutable kind MakeMutKind( obj ); ! Add this property to the list of mutable properties while ( i < MAX_MUT_PROPS_LEN ) { ! New mutable property if ( mutable_properties-->i == 0 ) { mutable_properties-->i = obj; mutable_properties-->(i + 1) = pr; mutable_properties-->(i + 2) = val; mutable_properties-->(i + 3) = DefaultObjOfKind(obj).pr; return; } ! Updating a mutable property if ( mutable_properties-->i == obj && mutable_properties-->(i + 1) == pr ) { mutable_properties-->(i + 2) = val; return; } i = i + 4; } print "Error: no more mutable properties!^^"; } else if (WhetherProvides(V, false, pr, true)) obj.pr = val; } else { if ((V < 1) || (V > obj.value_range)) return RunTimeProblem(RTP_BADVALUEPROPERTY); if (obj provides pr) { (obj.pr)-->(V+COL_HSIZE) = val; } } ]; -) instead of "Write Value Property" in "RTP.i6t". Include (- [ GetEitherOrProperty obj pr i res kind defaultval; if (obj == nothing) rfalse; if (pr<0) pr = ~pr; ! Property of a Kind if ( metaclass(obj) == Class ) { while ( i < MAX_MUT_PROPS_LEN ) { ! mutable property not set if ( mutable_properties-->i == 0 ) { kind = DefaultObjOfKind(obj); if (pri == obj && mutable_properties-->(i + 1) == pr ) return mutable_properties-->(i + 2); i = i + 4; } rfalse; } if (WhetherProvides(obj, true, pr, false)) { ! Get the object's own property if (pri == 0 ) return res; ! Retreive a mutable property if ( mutable_properties-->i == kind && mutable_properties-->(i + 1) == pr ) { ! Check if this object has a non-default property value and return it, otherwise return the kind's default value defaultval = mutable_properties-->(i + 3); if ( res == defaultval ) return mutable_properties-->(i + 2); else return res; } i = i + 4; } } ]; -) instead of "Get Either-Or Property" in "RTP.i6t". Include (- [ SetEitherOrProperty obj pr negate adj val i defaultobj defaultval; if (pr<0) { pr = ~pr; negate = ~negate; val = 1; } if ( metaclass(obj) == Class ) { ! Make this a mutable kind MakeMutKind( obj ); ! Add this property to the list of mutable properties while ( i < MAX_MUT_PROPS_LEN ) { ! New mutable property if ( mutable_properties-->i == 0 ) { mutable_properties-->i = obj; mutable_properties-->(i + 1) = pr; mutable_properties-->(i + 2) = val; defaultobj = DefaultObjOfKind(obj); if (pr(i + 3) = defaultval; return; } ! Updating a mutable property if ( mutable_properties-->i == obj && mutable_properties-->(i + 1) == pr ) { mutable_properties-->(i + 2) = val; return; } i = i + 4; } print "Error: no more mutable properties!^^"; } if (adj) { (adj)(obj); } else if (WhetherProvides(obj, true, pr, true)) { if (negate) { if (pr. This extension is released under the Creative Commons Attribution licence. Contact the author at Example: * Time Machine - Stop time for everything else but yourself The player carries a machine which somehow stops time for everyone other than themselves. Play with the machine and notice how the time the watch tells is always changing. This is because the watch's now property has been customised, whereas the other clocks get their time from the clock kind itself. *: "Time Machine" Shop is a room. "There are hundreds of clocks on every wall." A clock is a kind of thing. There is a clock. A clock has a time called now. The now of a clock is usually 10:00 am. Instead of examining a clock: say "It says [the now of the noun]." Every turn: increment the now of the watch; if the machine is switched off: let C be the kind of clock; increment the now of C; Here is a clock called a grandfather clock. Here is a clock called a stylish clock. Here is a clock called a sundial. The player wears a clock called a watch. The now of the watch is 11:00 am. The player carries a device called the machine. Test me with "x sundial/g/x watch/g/switch on machine/x sundial/g/x watch/g/switch off machine/x sundial/g/x watch/g".