Generic Boomerang Thing (#261)

(an instance of generic thing made by Dred)

     This thing will return to its home after a certain delay, settable, from when it 
was removed from its home. Much like a boomerang. See `help #261' for details.

Go to location of this object, wooden box.


HELP MANUAL:
     This object is set up to return home after a certain time delay started when it leaves 
its home.
     
     Settable properties:
     
     home - where this object lives and where it will return after the delay.
            Use `@home  is ' to set this.
     delay - how long, in seconds, the object is allowed away from home.
             The delay must be a positive number, or it won't return at all.
             (Perhaps a strategic programming advantage.)
     ohome_arrive_msg - message displayed to home when the object comes in.
     go_home_msg - message displayed to the player who had the object when it left.
     ogo_home_msg - if the object is in a room when it leaves, this is displayed.
     
     ----




VERB SOURCE CODE:

birth:
if (caller == this)
    if (this.delay <= 0)
        return 0;
    elseif (!$recycler:valid(this.home))
        return 0;
    elseif (!$code_utils:task_valid(this.return_task))
        this.birth_time = time();
        fork birth (0)
            this.return_task = birth;
            this:countdown();
        endfork
        return 1;
    elseif ($code_utils:task_valid(this.return_task))
        "extend delay";
        this.birth_time = time();
    else
        "Something weird.";
        return 0;
    endif
else
    return E_PERM;
endif
.


return_home:
if (caller != this)
    return E_PERM;
endif
if ($recycler:valid(this.home))
    source = this.location;
    if (is_player(source))
        source:tell(this:go_home_msg());
    else
        source:announce_all(this:ogo_home_msg());
    endif
    "This assumes the :moveto won't crap out. Might should fork it..";
    this:moveto(this.home);
    if (this.location == this.home)
        this.home:announce_all(this:ohome_arrive_msg());
    endif
else
    "Ack, bad home";
    return 0;
endif
.


countdown:
if (caller != this)
    return E_PERM;
endif
while ((this.location != this.home) && (time() < (this.birth_time + this.delay)))
    suspend(this.interim_delay);
    this:interim_effect();
endwhile
if (this.location != this.home)
    this:return_home();
endif
this.return_task = 0;
this.birth_time = 0;
.


moveto:
pass(@args);
if (this.location != this.home)
    this:birth();
endif
.


ohome_arrive_msg go_home_msg ogo_home_msg:
return $string_utils:pronoun_sub(this.(verb));
.


interim_effect:
"Default is to just do nothing. But fun kids can overwrite this verb and have interim 
effects every .interim_delay. I made that property !c, so if they want a longer delay, 
just let me know and I'll set it.";
return;
.


@home:
"Usage: @home  is ";
"";
"Sets the home of this boomerang child to whatever place might be.";
if ($perm_utils:controls(player, this))
    if (iobjstr)
        what = player:my_match_object(iobjstr);
        if (!$command_utils:object_match_failed(what, iobjstr))
            player:tell("Setting home of ", $string_utils:nn(this), " to ", $string_utils:nn(what));
            this.home = what;
        endif
    else
        player:tell("Current home of ", $string_utils:nn(this), ": ", $string_utils:nn(this.home));
    endif
else
    player:tell(E_PERM);
endif
.



PROPERTY DATA:
      home
      birth_time
      return_task
      delay
      ohome_arrive_msg
      go_home_msg
      ogo_home_msg
      help_msg
      interim_delay

CHILDREN:
Tome of Enigmatic Theory silverware Generic Edible Object Red Hat woad yellow ocher red ocher Ankh Generic Consumable I ticket microphone Carrier Pigeon Playbill quarter irony a prayer-wheel the sun a hanger ball block pyramid table glistening earthmound a brush lipstick