Page 1 of 1

Example building construction script

Posted: Sat Jun 08, 2013 11:05 pm
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..

Posted: Tue Jul 02, 2013 6:58 pm
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!!!

Posted: Tue Jul 02, 2013 9:59 pm
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.

Posted: Wed Jul 03, 2013 5:14 am
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.

Posted: Wed Jul 03, 2013 4:43 pm
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!!

Posted: Thu Jul 04, 2013 1:01 am
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.

Posted: Thu Jul 11, 2013 3:33 am
by flametard
Is there any way to use this script to lay a single surface tile? :) that might be useful.

Posted: Thu Jul 11, 2013 7:20 pm
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)

Posted: Fri Jul 19, 2013 9:18 pm
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.

Posted: Wed Aug 28, 2013 8:22 pm
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!!

Posted: Mon Sep 09, 2013 8:44 pm
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 :)

Posted: Wed Sep 11, 2013 2:39 pm
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) :)