Example building construction script

Forum Archive - from http://theuniversal.net
Locked
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Example building construction script

Post by Mit »

All the worlds i've been using to develop the tech recently have used a purely scripted process to provide players with the ability to construct buildings.

Here's an example of the process.

First, we usually have a build skill of some kind and we react to the user selecting it via the "UseSkill" event. That event could trigger the construction directly, or it might add some OSD, such as in this example from Aramathea..

Code: Select all

$kBuildingNumSchool = 20

Event( "UseSkill", "Build Education" )
{
	osdcreate(OSDLIST,"BuildEduOSD", "Build Education Skill" ) 
	osdadditem(OSDMINHEIGHT, "", "180" ) 
	osdaddat(OSDFADEDTEXT, 0, 10, 600, 0, "", "Select a building to begin construction" )
	$lineY = 35
	osdaddat(OSDIMAGE, 20, $lineY, 90, 90, "Build|$kBuildingNumSchool", "http://webspace.com/img.jpg") 
	osdaddat(OSDBIGTEXT, 120, $lineY, 0, 0, "", "School" )
	$liney = $lineY + 20
	osdaddat(OSDTEXT, 120, $liney, 0, 0, "", "(5 wood & 40 bricks)" )
	$liney = $liney + 20
	osdaddat(OSDFADEDTEXT, 120, $liney, 180, 45, "", "Allows players to learn new skills." )
	osdaddat(OSDEXITBUTTON, 195, 150, 200, 20, "exit", "Close" )
	osdactivate() 
}
On selecting the OSD button, an "OSDSelect" event is triggered.. we check to see if the user has the appropriate items then we activate the building construction display for the user like this:

Code: Select all

$buildingNum = $kBuildingNumSchool
$buildingName = "%PLAYER%'s school"
*buildingconstruct %PLAYER% $buildingNum $buildingName


When the player has positioned their building and pressed 'construct' another event is triggered, and at this point we remove the required items from the user's inventory and confirm placement of the building using 'sysAddBuilding' or 'sysAddBuildingWorld'. (The latter uses more fine-grained 'world coordinates' rather than map tile numbers).

There are a couple of ways to handle the event of the player confirming construction... if you want to react to a specific building type being placed, you use the "PlaceBuilding" event. Here's an example that limits the number of schools in a town to 2 :

Code: Select all

Event( "PlaceBuilding", "$kBuildingNumSchool" )  // Construct School
{
   $valid = sysIsBuildingPositionValid( $nBuildingCode )
   if ( $valid = 1 )
   {
	$townNum = sysGetNearestTown( $gPlayerWorldX, $gPlayerWorldY )
	$numSchoolsInTown = sysTownGetNumBuildingsOfType( $townNum, $kBuildingNumSchool )

	if ( $numSchoolsInTown < 2 )
	{
	     $didAdd = sysAddBuildingWorld( $kBuildingNumSchool, $gPlayerID, $gPlayerWorldX,$gPlayerWorldY, $buildingName,$constrAmount )
	}
	else
	{
		*msg %PLAYER% There are already 2 schools in this town
  }
}
The other method is to use the 'PlaceAnyBuilding' event. (Note: If there is a specific 'PlaceBuilding' event defined for the a particular building type, PlaceAnyBuilding won't be triggered).

Here's the example from Aramathea that requires 5 wood to construct most types of building

Code: Select all

Event( "PlaceAnyBuilding", "" )		// Catch all
{
	$nBuildingCode = $gParam[1]

	$hasWood = sysPlayerInventory( "Wood" )
	if ( $hasWood >= 5 )
	{
		$valid = sysIsBuildingPositionValid( $nBuildingCode )
		if ( $valid = 1 )
		{
		     $buildingName = sysGetTextEntry()
			$constrAmount = -1
			$didAdd = sysAddBuildingWorld( $nBuildingCode,$gPlayerID,$gPlayerWorldX,$gPlayerWorldY,$buildingName,$constrAmount )
			if ( $didAdd != 0 )
			{
				*grantitem %PLAYER% -5 Wood
			}
		}
	}
	else
	{
		*msg %PLAYER% You need 5 wood to build
	}
}
Hope that helps.. lemme know if you have any questions..
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

I wanna make a script that lets each player own only one building of a certain building number. And the sooner the better! thankss!!!
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

Did you try setting the max per player # in the bdat?

Only asking because I don't know if the script would override that.
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

yeah, well i havent tested it yet, but i think the whole building vaild stuff it checks for only has to do with being in town limits/ on the proper surface. ill test to see if it recognizes the bdat rules, but i think i gotta script it in manually. ill report back tomorrow. its pretty much the only thing left to do on xebec, but im mulling over te script till i get the answer to make sure there isnt something else i overlooked that needs adressing.
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

it recognizes the 'how many of this building a player can own"!!!! what was weird was that i had one building which 'ignored town restrictions' but the script 'ignored' that it can 'ignore the town restrictions' lol. but i fixed that by just removing the 'valid=blah blah" stuff. so im actually done and will just be bug checking now! fingers crossed, we might be moving on soon!!
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

you can do:
I wanna make a script that lets each player own only one building of a certain building number
in script by using a check on the value from sysPlayerGetNumBuildingsOfType

You've also got sysTownGetNumBuildingsOfType which aramathea uses to restrict banks & schools to one per town.
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

Is there any way to use this script to lay a single surface tile? :) that might be useful.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

Yup, aramathea does that when it adds a new town..

Code: Select all

    // Place a market square and roads around the town
	$roadX1 = $gBuildingX + 1
	$roadY1 = $gBuildingY
	$roadX2 = $roadX1 + 3
	$roadY2 = $roadY1
	*settileline 2,$roadX1,$roadY1,$roadX2,$roadY2
	// Add tile under plinth
	*settile 4,$gBuildingX,$gBuildingY
*settile [surface_num],MapX,MapY
*settileline [surface_num],MapX1,MapY1,MapX2,MapY2

(Along those lines you've also got *addtree and *addbackgroundmodel)
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

Image



wtf ....are those vars in the osd for positioning?

and all this time i've been messing with the headache typing in (or copy/pasting) those dozens numbers manually when I could have used vars to basically make a grid. damn.
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

still can't get the set tile thing to work.

Code: Select all

Event( "UseSkill", "Lay Surfaces" )
{
*msg %player% testing
*settile 2,$gPlayerWorldX,$gPlayerWorldY 
}
thats what I got so far, no tile.

PLEASE HELP ME THIS IS THE LAST HANG UP!!
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

Sorry, I've probably never made this clear (just another of those things in my head which I forget to remember aren't obvious to people outside my head :] )... theres 2 forms for the positional coordinates.. 'map coordinates' - equivalent to the world tiles, usually 256x256 or similar. Whenever I say things like MapX, MapY I refer to them.
Then there's also 'world coordinates', which refer to the fractional positional number used to refer to a specific point on the world - WorldX, WorldY

$gPlayerWorldX and $gPlayerWorldY give you the world coords - e.g 56.543m from the origin - but *settile uses the map coords. $gPlayerX and $gPlayerY should be used instead - that gives you the map coords for the player.

oh and its never the last hang-up, promise. If it ever was, game dev woud be so much less fun :)
User avatar
flametard
Posts: 1245
Joined: Sun Apr 01, 2007 2:05 am
Location: Join NR! faction name: 'NR new recruits' password: 'Truth'
Contact:

Post by flametard »

alright! one last thing:
how would I go about making the script determine if a player is within the town limits of a town he owns? i've tried many things with no luck. if i can help it, i'd like to keep players laying ground tiles only in towns they own. :D thanks!!

(oh, btw, one planet im planning for the future will be a planet building tutorial planet, so all this knowledge will be passed on for posterity within the gameplay of the game, someday. thanks) :)
Locked