changes to Roody's Phone class

This is a discussion / support forum for the Hugo programming language by Kent Tessman. Hugo is a powerful programming language for making text games / interactive fiction with multimedia support.

Hugo download links: https://www.generalcoffee.com/hugo
Roody Yogurt's Hugo Blog: https://notdeadhugo.blogspot.com
The Hugor interpreter by RealNC: http://ifwiki.org/index.php/Hugor

Moderators: Ice Cream Jonsey, joltcountry

misterman83

changes to Roody's Phone class

Post by misterman83 »

Hello everyone. I've made some changes to some of Roody's code found at http://notdeadhugo.blogspot.com/2014/09 ... stuff.html. The only chanes I've made is to change calls to the doDialNumber(x) and doAnswerNumber(x) routines. I've changed these to the x.react_dial and x.react_answer properties. I don't know how polished it is, but I thought I'd post it here for the more experienced hugo programmers to look at.

Code: Select all

!\
Phone.h -- an upgrade of some code by Roody Yogurt
which was based on code by Cardinal Teulbachs
\!

attribute someone_on_line alias switchedon
property current_number alias misc
property react_dial alias react_before
property react_answer alias react_after
 
class phone "telephone_class"
{
	type phone
	is open, platform
	nouns "telephone", "phone"
	article "a"
	parse_rank 3
	long_desc
	{
		"It's just an ordinary telephone.";
		if Contains(player, receiver)
		{
			print AFTER_PERIOD;
			"The receiver is off the hook."
		}
		else : ""
	}
	before
	{
		object DoGet,DoListen, DoHangup, DoAnswer
		{
			Perform(verbroutine, receiver)
		}
		xobject DoPutIn
		{
			if object = receiver
			Perform(&DoPutIn, receiver, hook)
			else : return false
		}
		xobject DoGet
		{
			if object = receiver
				Perform(&DoGet, receiver, hook)
			else : return false
		}
	}
 
	react_before
	{
		if verbroutine = &DoGo
		{
			if object.type = direction and
			(location.(object.dir_to)).type = room,door
			{
				"You hang up the phone before leaving the room."
				move receiver to hook
				receiver is hidden
				receiver is not someone_on_line
			}
		}
		elseif verbroutine = &DoListen and not object
		{
			if receiver is someone_on_line and not Contains(player,receiver)
			{
				"The phone is ringing."
				return true
			}
		}
		return false
	}
	react_after
	{
		if (verbroutine = &DoGo, &DoExit, &DoEnter) and location ~= old_location
		{
			receiver.found_in = location
			receiver.attached_to = self
			hook.part_of = self
			move receiver to hook
		}
		else
			return false
	}
}
 
class phone_number
{
	type phone_number
	is known
	in_scope
	{
		return player
	}
	before
	{
		object DoDial
		{
			receiver.current_number = self
			Perform(&DoDial, receiver)
		}
		object
		{
			if verbroutine = &DoLook
				return false
			print "You can't do that with "; self.name ;"."
		}
	}
}
 
!\--------------------------------------------------------------------------
 
Next come the receiver and hook. Note that the receiver is of the attachable
class. This will prevent the player from moving off to another location
while he's holding it. He'll also get a nice little inventory description
telling him that the receiver he's holding is attached to the telephone,
which impresses the hell out of people from Estonia.
 
---------------------------------------------------------------------------\!
 
attachable receiver "telephone receiver"
{
	is hidden
	found_in 0
	current_number 0
	adjective "telephone", "phone"
	nouns "receiver", "handset"
	article "a"
	attached_to 0
	attached_desc "attached to"
	long_desc
	{
		if not Contains(player,self): "The receiver is on the hook."
		else : "The receiver is off the hook."
	}
	before
	{
		object DoAnswer
		{
			if Contains(player,self)
				"The phone is already off the hook."
			elseif receiver is not someone_on_line
			{
				move receiver to player
				receiver is not hidden
				"You pick up the phone, but there's no one on the line."
			}
			else
			{
				move receiver to player
				receiver is not hidden
				run   receiver.current_number.react_answer
			}
		}
		object DoGet
		{
			if Contains(player,self)
				"The phone is already off the hook."
			elseif receiver is not someone_on_line
			{
				move receiver to player
				receiver is not hidden
				"You pick up the phone."
			}
			else
				Perform(&DoAnswer, self)
		}
		object DoHangup
		{
			if not Contains(player,self)
				"The phone is already hung up."
			else
			{
				move receiver to hook
				receiver is hidden
				receiver is not someone_on_line
				"You hang up the phone."
			}
		}
		object DoDrop
		{
			Perform(&DoHangup, self)
		}
		object DoPutIn
		{
			if xobject.type ~= phone
			{
				"That shouldn't go there."
			}
			else
				return false
		}
	}
	after
	{
		object DoListen
		{
			if not Contains(player,self)
			{
				if receiver is someone_on_line
					"The phone is ringing."
				else
					"The phone is silent."
			}
			elseif receiver is someone_on_line
				"The other party is speaking to you."
			else
				"You hear a dial tone."
		}
	}
}
 
component hook "phone hook"
{
	is open, platform
	part_of 0
	nouns "hook", "cradle"
	article "the"
	long_desc
	{
		if Contains(self,receiver): "There's a receiver on the hook."
		else : "The hook is empty."
	}
	before
	{
		xobject DoPutIn
		{
			if object = receiver
				Perform(&DoDrop, receiver)
			else : "You can't put that on the hook."
		}
		xobject DoGet
		{
			if object = receiver
				Perform(&DoGet, receiver)
			else : "That's not on the hook."
		}
		object DoMove ! DoPush
		{
			if not Contains(self, receiver)
			{
				if receiver is someone_on_line
				{
					receiver is not someone_on_line
					"You press the cradle, breaking the connection."
				}
				else : "You press the cradle."
			}
			else : "The receiver is in the way."
		}
	}
}
 
routine DoAnswer
{
	"Sure. Ok, buddy. Whatever."
}
 
routine DoDial
{
	if not object
		"Dial it where?"
	elseif (object.type ~= phone,phone_number) and object ~= receiver or
	(xobject and xobject.type ~= phone)
		"You can't dial that."
	elseif receiver.found_in ~= location
		"There is no phone here."
	else
	{
			if not Contains(player, receiver)
				"You'd better pick up the phone first."
			elseif receiver is someone_on_line
				"That would be rude."
			else
			{
  run  receiver.current_number.react_dial
			}
		return true
	}
	return false
}
 
routine DoHangup
{
	if receiver.found_in = location : Perform(&DoHangup, receiver)
	elseif not object : "There's nothing here to hang up."
	else : "You can't hang that up."
}
 
#ifset _ROODYLIB_H
object 1st_room_phone_detector
{
	in main_instructions
	execute
	{
		local a
		a = FindObjectOfType(phone,location)
		if a
		{
			receiver.found_in = location
			receiver.attached_to = a
			hook.part_of = a
			move receiver to hook
		}
		remove self
	}
}
#else
 
event
{
	if counter < 1
	&#123;
		local a
		a = FindObjectOfType&#40;phone,location&#41;
		if a
		&#123;
			receiver.found_in = location
			receiver.attached_to = a
			hook.part_of = a
			move receiver to hook
		&#125;
	&#125;
&#125;
 
#if undefined FindObjectOfType
routine FindObjectOfType&#40;t, loc&#41;
&#123;
	local i, obj, suspect
 
	if loc = 0&#58;  loc = location
 
	for i in loc
	&#123;
		if i.type = t
		&#123;
			if suspect
				return nothing
			suspect = i
		&#125;
		elseif children&#40;i&#41; and &#40;i is not container or i is open or i is not openable&#41;
		&#123;
			obj = FindObjectOfType&#40;t, i&#41;
			if obj
			&#123;
				if suspect
					! More than 1
					return nothing
				else
					suspect = obj
			&#125;
		&#125;
	&#125;
	! Only do the whole-tree check when loc is a room-level object&#58;
	if parent&#40;loc&#41; = nothing and not suspect
	&#123;
		for &#40;i=1; i<=objects; i++&#41;
		&#123;
			if i.type = t and i ~= suspect
			&#123;
				if FindObject&#40;i, location&#41;
				&#123;
					if suspect
						! More than one
						return nothing
					else
						suspect = obj
				&#125;
			&#125;
		&#125;
	&#125;
	return suspect
&#125;
#endif
Well, there you go. I felt that properties would be a better way of doing things, rather than requiring authors to define a large routine (like in footnotes.h and newsimpletalk.h, for example).

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

That's a good idea! I probably was inspired by phototalk/simpletalk when I added those routines, but yes, it'd be much nicer if the messages were attached to the phone number objects themselves.

Of course, that method could be applied to newsimpletalk, too. I see the appeal of dialogue being declared inside the relevant character object... although I guess I also can imagine authors wanting all dialogue in one place (well, two places).

Anyhow, cool that anyone would take such a close look at my code! Thanks for sharing!

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

I've updated the code over at http://notdeadhugo.blogspot.com/2014/09 ... stuff.html to reflect the change.

Post Reply