A way to make this into a function?

Forum Archive - from http://theuniversal.net
Locked
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

A way to make this into a function?

Post by zaroba »

If those that are more experienced with functions could lend a hand, could this script be turned into a function?

This is the production script for zoric buildings.
Var explanation:
$gBuildingVar20 = item # being made (bvar 24, 28, 32, and 36 for slots 2, 3, 4, and 5)
$gBuildingVar21 = the total qty set to produce if $gBuildingVar2 = 2. Or a var that counts production cycles between producing if $gBuildingVar2 = 0.
$gBuildingVar22 = qty produced since production was started
$gBuildingVar23 = status of the production slot. full, no supplies, broken, finished making what it was set to make
$gBuildingVar127 - power, besides being needed to create things, it's also needed by default just to run production
$gBuildingVar124 - lubrication, without it, the building has a high chance of breaking down and be unusable until repaired


$prod1 = bvar for qty of item # being made
$prod1qty= the qty being made in the recipe
$prod1d#= bvar for the qty of the first demanded item
$prod1d#qty=qty needed of the first demanded item

the 1 in the temp vars is due to this example being for production slot 1.
other slots would have a 2, 3, 4, or 5 (so yes, the below script is replicated for each of the 5 production lines buildings can have)

additional notes for each part of the script are in the script below

Code: Select all

Event( "BuildingProductionRun", "30" )
	{
	if ($gBuildingVar23=0)				//------no pre-existing issues, assign temp vars for production script
		{
		if ($gBuildingVar20=29)	
			{
			$prod1=85
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=250
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=115
			$prod1d3qty=25
			$prod1d4=112
			$prod1d4qty=25
			$prod1d5=118
			$prod1d5qty=50
			}
		if ($gBuildingVar20=30)	
			{
			$prod1=82
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=100
			$prod1d2=121
			$prod1d2qty=25
			$prod1d3=115
			$prod1d3qty=50
			$prod1d4=112
			$prod1d4qty=25
			}
		if ($gBuildingVar20=31)	
			{
			$prod1=79
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=500
			$prod1d2=121
			$prod1d2qty=100
			$prod1d3=115
			$prod1d3qty=10
			$prod1d4=112
			$prod1d4qty=50
			$prod1d5=118
			$prod1d5qty=25
			}
		if ($gBuildingVar20=32)	
			{
			$prod1=56
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=100
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=115
			$prod1d3qty=50
			$prod1d4=109
			$prod1d4qty=1000
			}
		if ($gBuildingVar20=33)	
			{
			$prod1=73
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=100
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=115
			$prod1d3qty=50
			$prod1d4=106
			$prod1d4qty=1000
			}
		if ($gBuildingVar20=47)	
			{
			$prod1=76
			$prod1qty=10
			$prod1d1=127
			$prod1d1qty=25
			$prod1d2=121
			$prod1d2qty=5
			$prod1d3=115
			$prod1d3qty=5
			$prod1d4=112
			$prod1d4qty=5
			$prod1d5=118
			$prod1d5qty=5
			}

		if ($gBuildingVar20=141)	
			{
			$prod1=70
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=250
			$prod1d2=121
			$prod1d2qty=100
			$prod1d3=118
			$prod1d3qty=100
			$prod1d4=112
			$prod1d4qty=10
			$prod1d5=115
			$prod1d5qty=10
			}
		if ($gBuildingVar20=142)	
			{
			$prod1=67
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=250
			$prod1d2=121
			$prod1d2qty=100
			$prod1d3=118
			$prod1d3qty=100
			$prod1d4=112
			$prod1d4qty=10
			$prod1d5=115
			$prod1d5qty=10
			}
		if ($gBuildingVar20=209)	
			{
			$prod1=61
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=25
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=103
			$prod1d3qty=250
			}
		if ($gBuildingVar20=210)	
			{
			$prod1=58
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=100
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=118
			$prod1d3qty=50
			$prod1d4=112
			$prod1d4qty=10
			$prod1d5=115
			$prod1d5qty=100
			}
		if ($gBuildingVar20=215)	
			{
			$prod1=64
			$prod1qty=1
			$prod1d1=127
			$prod1d1qty=25
			$prod1d2=121
			$prod1d2qty=50
			$prod1d3=103
			$prod1d3qty=250
			}
		if ($prod1qty=5)						//----random qty variation, to make it impossible to exactly predict item costs
			{
			$rand=sysRand(5)
			if ($rand=1)
				{
				$prod1qty=$prod1qty+1
				}
			if ($rand=4)
				{
				$prod1qty=$prod1qty-1
				}
			}
		if ($prod1qty=10)						//----random qty variation, to make it impossible to exactly predict item costs
			{
			$rand=sysRand(10)
			if ($rand=2)
				{
				$prod1qty=$prod1qty-2
				}
			if ($rand=4)
				{
				$prod1qty=$prod1qty+1
				}
			if ($rand=6)
				{
				$prod1qty=$prod1qty-1
				}
			if ($rand=8)
				{
				$prod1qty=$prod1qty+2
				}
			}
		if ($prod1qty=25)						//----random qty variation, to make it impossible to exactly predict item costs
			{
			$rand=sysRand(15)
			if ($rand=2)
				{
				$prod1qty=$prod1qty-5
				}
			if ($rand=4)
				{
				$prod1qty=$prod1qty+3
				}
			if ($rand=6)
				{
				$prod1qty=$prod1qty-1
				}
			if ($rand=9)
				{
				$prod1qty=$prod1qty+1
				}
			if ($rand=11)
				{
				$prod1qty=$prod1qty-3
				}
			if ($rand=13)
				{
				$prod1qty=$prod1qty+5
				}
			}
		if ($prod1qty=50)						//----random qty variation, to make it impossible to exactly predict item costs
			{
			$rand=sysRand(25)
			if ($rand=2)
				{
				$prod1qty=$prod1qty-10
				}
			if ($rand=4)
				{
				$prod1qty=$prod1qty+8
				}
			if ($rand=6)
				{
				$prod1qty=$prod1qty-6
				}
			if ($rand=8)
				{
				$prod1qty=$prod1qty+4
				}
			if ($rand=11)
				{
				$prod1qty=$prod1qty-2
				}
			if ($rand=14)
				{
				$prod1qty=$prod1qty+2
				}
			if ($rand=17)
				{
				$prod1qty=$prod1qty-4
				}
			if ($rand=20)
				{
				$prod1qty=$prod1qty+6
				}
			if ($rand=22)
				{
				$prod1qty=$prod1qty-8
				}
			if ($rand=24)
				{
				$prod1qty=$prod1qty+10
				}
			}
		if ($prod1qty>99)						//----random qty variation, to make it impossible to exactly predict item costs
			{
			$rand=sysRand(40)
			$bon10=$prod1qty/10
			$bon20=$prod1qty/20
			$bon30=$prod1qty/30
			$bon40=$prod1qty/40
			$bon50=$prod1qty/50
			$bon60=$prod1qty/60
			$bon70=$prod1qty/70
			$bon80=$prod1qty/80
			$bon90=$prod1qty/90
			if ($rand=2)
				{
				$prod1qty=$prod1qty-$bon10
				}
			if ($rand=4)
				{
				$prod1qty=$prod1qty+$bon20
				}
			if ($rand=6)
				{
				$prod1qty=$prod1qty-$bon30
				}
			if ($rand=8)
				{
				$prod1qty=$prod1qty+$bon40
				}
			if ($rand=10)
				{
				$prod1qty=$prod1qty-$bon50
				}
			if ($rand=12)
				{
				$prod1qty=$prod1qty+$bon60
				}
			if ($rand=14)
				{
				$prod1qty=$prod1qty-$bon70
				}
			if ($rand=16)
				{
				$prod1qty=$prod1qty+$bon80
				}
			if ($rand=18)
				{
				$prod1qty=$prod1qty-$bon90
				}
			if ($rand=22)
				{
				$prod1qty=$prod1qty+$bon90
				}
			if ($rand=24)
				{
				$prod1qty=$prod1qty-$bon80
				}
			if ($rand=26)
				{
				$prod1qty=$prod1qty+$bon70
				}
			if ($rand=28)
				{
				$prod1qty=$prod1qty-$bon60
				}
			if ($rand=30)
				{
				$prod1qty=$prod1qty+$bon50
				}
			if ($rand=32)
				{
				$prod1qty=$prod1qty-$bon40
				}
			if ($rand=34)
				{
				$prod1qty=$prod1qty+$bon30
				}
			if ($rand=36)
				{
				$prod1qty=$prod1qty-$bon20
				}
			if ($rand=38)
				{
				$prod1qty=$prod1qty+$bon10
				}
			}
		$storelim=$gBuildingVar17-$prod1qty		//----make sure there is space to store everythign that is produced
		if ($gBuildingVar2=1)
			{
			if ($gBuildingVar[$prod1]>=$storelim)
				{
				$gBuildingVar23=1		//----no space, stop line from running
				}
			}
		if ($gBuildingVar2=2)		//----if automation is upgraded to level 2 (fully programmable)
			{
			if ($gBuildingVar22>=$gBuildingVar21)
				{
				$gBuildingVar23=5		//----line produced all it was told to produce, stop line from running
				}
			if ($gBuildingVar22<=$gBuildingVar21)
				{
				if ($gBuildingVar[$prod1]>=$storelim)
					{
					$gBuildingVar23=7		//----not finished producing, but not enough space to produce
                        // pause line and resume if space becomes available
					}
				}
			}
		if ($gBuildingVar23=0)		//----this is where the script makes sure the demanded items exist
			{
			if ($gBuildingVar[$prod1d1]<$prod1d1qty)
				{
				$gBuildingVar23=2		//----stop line if the demanded item isn't in stock
				}
			if ($gBuildingVar[$prod1d2]<$prod1d2qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar[$prod1d3]<$prod1d3qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar[$prod1d4]<$prod1d4qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar[$prod1d5]<$prod1d5qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar[$prod1d6]<$prod1d6qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar[$prod1d7]<$prod1d7qty)
				{
				$gBuildingVar23=2
				}
			if ($gBuildingVar23=2)
				{
				if ($gBuildingVar2=0)	//----if automation is at level 0, line stops completely and settingsreset
					{
					$gBuildingVar23=4
					$gBuildingVar20=0
					}
				}
			}
		if ($gBuildingVar23=0)		//----if this var is *still* 0, then no problems exist and the building can actually produce
			{
			$gBuildingTimeVar1=$gServerVar9		//----activity counter, if building is inactive for too long, it shuts down
			$gBuildingVar[$prod1]=$gBuildingVar[$prod1]+$prod1qty		//----add produced items, remove demanded items
			if ($prod1i2>0)
				{
				$gBuildingVar[$prod1i2]=$gBuildingVar[$prod1i2]-$prod1i2qty	//----a few recipies make a 2nd item
				}
			if ($prod1d1qty>0)
				{
				$gBuildingVar[$prod1d1]=$gBuildingVar[$prod1d1]-$prod1d1qty
				}
			if ($prod1d2qty>0)
				{
				$gBuildingVar[$prod1d2]=$gBuildingVar[$prod1d2]-$prod1d2qty
				}
			if ($prod1d3qty>0)
				{
				$gBuildingVar[$prod1d3]=$gBuildingVar[$prod1d3]-$prod1d3qty
				}
			if ($prod1d4qty>0)
				{
				$gBuildingVar[$prod1d4]=$gBuildingVar[$prod1d4]-$prod1d4qty
				}
			if ($prod1d5qty>0)
				{
				$gBuildingVar[$prod1d5]=$gBuildingVar[$prod1d5]-$prod1d5qty
				}
			if ($prod1d6qty>0)
				{
				$gBuildingVar[$prod1d6]=$gBuildingVar[$prod1d6]-$prod1d6qty
				}
			if ($prod1d7qty>0)
				{
				$gBuildingVar[$prod1d7]=$gBuildingVar[$prod1d7]-$prod1d7qty
				}
			if ($gBuildingVar2=0)		//----more checks after production to see if the line is good to produce next cycle
				{
				if ($gBuildingVar[$prod1]>=$storelim)
					{
					$gBuildingVar23=4
					$gBuildingVar20=0
					}
				}
			if ($gBuildingVar2=1)
				{
				if ($gBuildingVar[$prod1]>=$storelim)
					{
					$gBuildingVar23=1
					}
				}
			if ($gBuildingVar2=2)
				{
				$gBuildingVar22=$gBuildingVar22+$prod1qty
				if ($gBuildingVar22>=$gBuildingVar21)
					{
					$gBuildingVar23=5
					}
				if ($gBuildingVar22<=$gBuildingVar21)
					{
					if ($gBuildingVar[$prod1]>=$storelim)
						{
						$gBuildingVar23=7
						}
					}
				}
			}
		}
Image
Last edited by zaroba on Wed Feb 05, 2014 10:54 am, edited 1 time in total.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

This sorta thing really needs the script language to support tables :/

If im interpreting your script right, its rather difficult to functionise the thing because there doesn't seem to be a fixed pattern with your use of building vars. (e.g. If the var20 item is 209 why does it get the prod1d3 from 103 rather than 115 or 118 as is the case in most of the others?)

If you were able to rearrange things you could simplify a lot of that code by having a structure like :

Bvar 20 - Item Num
Bvar 21 - Demanded Item1
Bvar 22 - Demanaded quantity 1
Bvar 23 - Demanded Item2
Bvar 24 - Demanaded quantity 2
...

Then you'd have a function in which you just passed in the base slot (20) and it could get the other values by knowing that the demanded item would always be in 'Base Slot + 1', the 2nd demanded quantity would be in 'Base Slot + 4' etc. This same function could then be reused for all the different production slots just by passing in a different base number. ( "so yes, the below script is replicated for each of the 5 production lines buildings can have" = Eeek!! :] ).

That aside, you could simplify your random qty variations code with a bit of maths, e.g :

Code: Select all

    $rand = sysRand( 20 )
    $qtyBonus = $prod1qty * $rand
    $qtyBonus /= 100
  
    $BonusOrReduction = sysRand( 2 )
    if ( $BonusOrReduction == 1 )
    {
        $prod1qty += $qtyBonus
    }
    else
    {
          $prod1qty -= $qtyBonus
    }
which effectively replaces about 100 lines of script (hence the server will be more responsive), is a bit less error-prone and does much the same job in terms of varying the quantity produced by +/- 20%.

To make that bit even more useful and reusable you might make it into a function like :

Code: Select all

Function     CalculateVariableQuantity(  $Quantity,  $variationPercentage )
{
    $rand = sysRand( $variationPercentage )
    $qtyBonus = $Quantity * $rand
    $qtyBonus /= 100
  
     $BonusOrReduction = sysRand( 2 )
    if ( $BonusOrReduction == 1 )
    {
        $Quantity += $qtyBonus
    }
    else
    {
          $Quantity -= $qtyBonus
    }
    return( $Quantity )
}
which you'd call like :

Code: Select all

$prod1qty = CalculateVariableQuantity( $prod1qty, 20 )
As a general principle, making functions that have a clear, specific and generic purpose (in this case taking a quantity and varying it by a percentage) and also operate *only* on the parameters passed in to them (rather than referring directly to particular building or Player Var slots) will go a long way to making your script code more flexible, reliable and maintainable.
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

There is kinda a fixed pattern.
Every building has its vars used for the same thing, but with different values based on the building.
1-50 are pretty standard.

51-128 is used for items, qtys, and prices.
128=item #, 127=qty, 126=buy/sale price, repeating counting down.
87-128 are used for demanded items
51-86 are used for sold / made items.

Item 209 is a farm pen upgrade, prod1d3 is 103 since $bBuildingVar[$prod1d3] is the qty of wood the building has in stock.


I'd love to be able to put the production details as buildingvars but there aren't enough. Would need possibly 4x buildingvars for that. Even better would be if the number of servervars could be upped to a few k (is it silly for me to ask for 4k servervars at this point in the game? )
-Could store all the recipes in servervars then and make a gui to allow changing them.
-Could store building construction material and skill requirements and make a gui to change them.
-Could store the initial buildingvar setup in servervars as well (currently its a script runs first building access and whenever updated to set default var values)


The end result would be being able to zip up the script and send it to somebody else for them to put on their world and have it work properly with a very different economy with (ideally) no changes needed to any of the script itself. They could make a bdat with building names and types (which is all zoric's bdat contains) and do everything else in game via the script gui. No needing to make a custom construction script and no needing to edit the main scripts to make it work with different items/buildings
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

mm,ok..
i don't have an issue upping the server var count (building var is a little trickier to maintain backward compatability and many more could start making the server's data files a bit hefty).

However, I don't think thats the best place to do this sorta thing - the server vars are intended for storing state values for your server that change as your game runs, rather than storing the (mostly) fixed configuration values that define your production setup. Aramathea keeps all its production data in the buildings.dat.. the other better option is (as you say) to keep it all in one place in the script.

So im putting in tables now.. should be included in server 0.66.0
That'll allow you to add lists of values to your script, e.g. :

Code: Select all

//                            item     qty     demand      amount
   $mProductionTable[] = {    1,     100,       5,         1, 
                             20,      40,      10,         2,
                             29,     143,       3,         1   }
and you access the data in the same way as with other array vars, e.g. $mProductionTable[6] gives you the 'qty' value (40) for the second item in the list.

A table is just a flat list of numbers - there's no inherent structure to it - but if you arrange things in a fixed manner like suggested above, you'd then be able to have functions that take an item number and return the demanded item just by looking in the appropriate slot in the table.

Like normal variables, arrays can be passed into functions, so you might have a separate table definining the production setup for each building, then pass it into a *single* function that performs all the production operations u need to do on all the different building types.
Last edited by Mit on Sun Feb 09, 2014 1:55 am, edited 4 times in total.
User avatar
morbydvisns
Posts: 1889
Joined: Sun Jan 30, 2005 12:51 am

Post by morbydvisns »

velly intellesting.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

This is functional in 0.66.0. (If its confusing or scary, try reading from the bottom up. If its still confusing or scary, try codeclub :] )

Code: Select all

//-----------------------------------------------------------------
// Table Example

$mProductionValues[] = 
{  
// Item num     Max     Demand1    Demand2
	  30,       40,       13,        15,       // Slot Num 1		
	  33,       10,       7,         8,	     // Slot Num 2		

	  0,         0,       0,         0			// EOL
}

//--- Here we define some values and the indices of the structure which'll 
//--- make it easier to reference in the code and easier to change later
$mNumItemsPerSlot = 4

$kStructItemNum = 0
$kStructMax = 1
$kStructDemand1 = 2
$kStructDemand2 = 3
//--------------------------------------------------------

//----- Find Slot
// Checks the production values for the 'item num' and returns the slot
// num if found (0 if not)
//------------------------------
Function	FindSlot( $itemNum )
{
	// We could recurse here (or use a loop if mit ever bothered to support it)
	// but to keep it simple we'll just assume theres only two slots to check
	if ( $mProductionValues[1] == $itemNum )
	{
		return( 1 )
	}
	else if ( $mProductionValues[5] == $itemNum )
	{
		return( 2 )
	}
	return( 0 )
}

// --- GetSlotIndex
// This function converts a 'Slot Num' into the index we need to reference in the
// production array
//  i.e. SlotNum 1 starts at array index 1, Slot Num 2 starts at array index 5 (etc)
//  (This changes if we add more fields to the table by changing $mNumItemsPerSlot)
//------------------------------
Function	GetSlotIndex( $slotNum )
{
    $slotIndex = $slotNum - 1
    $slotIndex *= $mNumItemsPerSlot
    $slotIndex += 1
	return( $slotIndex )
}

// --- GetDemand1
// Example function showing how to retrieve a data field from the table based on
// an index value we pass in
//------------------------------
Function	GetDemand1( $itemNum )
{
	$slotNum = FindSlot( $itemNum )
	if ( $slotNum > 0 )
	{
		$slotIndex = GetSlotIndex( $slotNum )

		$demandSlotIndex = $slotIndex + $kStructDemand1
		return( $mProductionValues[$demandSlotIndex] )
	}
	return( 0 )
}


//--- An example custom event
// To demo, use *event OWNER GetDemand|30   
//      - which will lookup the item in the table and then print 
//           'The Demand1 item for 30 is 13'
// or *event OWNER GetDemand|33
//      - which will print 'The Demand1 item for 33 is 7'
//------------------------------
Event( "Custom", "GetDemand" )
{
	$itemNum = $gParam[1]
	$demand1 = GetDemand1( $itemNum )

	// Show the result
	*say The Demand1 item for $itemNum is $demand1
}
Last edited by Mit on Sun Feb 09, 2014 1:52 am, edited 2 times in total.
User avatar
morbydvisns
Posts: 1889
Joined: Sun Jan 30, 2005 12:51 am

Post by morbydvisns »

https://www.codeclub.org.uk/
A nationwide network of volunteer-led after school coding clubs for children aged 9-11

:lol:
Locked