Animal Farm Script Problem

Forum Archive - from http://theuniversal.net
Locked
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Animal Farm Script Problem

Post by Haxina »

I'm currently working on a animal farm script on Narnia, and the problem is that when i try to add an animal, it usually adds another animal instead.
eg:
There's Cow, Chicken, Pig and Sheep.
If i try to add Cow, it *might* add a sheep instead. (What animal it adds differ whenever i reopen the building OSD)

The same problem goes for removing the animal aswell.

I've tried tracking this down for a few hours and just can't seem to find the problem.
Here's the script:

Code: Select all

//**************Info**************//
//gBuildingVar20 = Amount of Cows
//gBuildingVar21 = Amount of Chickens
//gBuildingVar22 = Amount of Pigs
//gBuildingVar23 = Amount of Sheeps
//
//gBuildingTimeVar1 = Cow's birth date
//gBuildingTimeVar2 = Chicken's birth date
//gBuildingTimeVar3 = Pigs birth date
//gBuildingTimeVar4 = Sheeps birth date
//--------------------------
//AddToInventorySilent() exists in the ServerScript.mit file.
//No need to think about it.
//--------------------------


Function AnimalFarm_Display()
{
	AnimalFarm_AddRemoveAnimals("Cow", 5);
	AnimalFarm_AddRemoveAnimals("Chicken", 20);
	AnimalFarm_AddRemoveAnimals("Pig", 35);
	AnimalFarm_AddRemoveAnimals("Sheep", 50);
}

Function AnimalFarm_AddRemoveAnimals($animal, $posY)
{
	//Get the amount of animals there is for $animal
	if ($animal == "Cow")
	{
		$amountOfAnimal = $gBuildingVar20;
	}
	else if ($animal == "Chicken")
	{
		$amountOfAnimal = $gBuildingVar21;
	}
	else if ($animal == "Pig")
	{
		$amountOfAnimal = $gBuildingVar22;
	}
	else if ($animal == "Sheep")
	{
		$amountOfAnimal = $gBuildingVar23;
	}
	
	//Add button for animal
	if (sysPlayerInventory($animal) > 0) //If player has $animal, add a Add button.
	{
		$addingAnimal = $animal;
		OSDAddAt(BUTTON, 220, $posY, 50, 15, "AddAnimal", "Add");
	}
	else //If player doesn't have $animal, add a faded Add button
	{
		OSDAddAt(FADEDBUTTON, 220, $posY, 50, 15, "", "Add");
	}
	
	//Remove button for animal
	if ($amountOfAnimal > 0) //If the farm does have $animal, add a Remove button
	{
		$removingAnimal = $animal;
		OSDAddAt(BUTTON, 270, $posY, 90, 15, "RemoveAnimal", "Remove");
	}
	else //If the farm doesn't have a $animal, add a faded Remove button
	{
		OSDAddAt(FADEDBUTTON, 270, $posY, 90, 15, "", "Remove");
	}
}

Event ("OSDSelect", "AnimalFarm:AddAnimal")
{
	if ($addingAnimal == "Cow") //Adding Cows to farm
	{
		if ($gBuildingVar20 <= 0) //If this is the first cow that gets added, set a birth day for it.
		{
			$gBuildingTimeVar1 = $gGameDay;
		}
		
		$gBuildingVar20 = $gBuildingVar20 + 1; //Add cow to building.
		AddToInventorySilent("Cow", -1, 1); //Remove cow from player inventory
	}
	else if ($addingAnimal == "Chicken") //Adding Chickens to farm
	{
		if ($gBuildingVar21 <= 0) //If this is the first chicken that gets added, set a birth day for it.
		{
			$gBuildingTimeVar2 = $gGameDay;
		}
		
		$gBuildingVar21 = $gBuildingVar21 + 1; //Add chicken to building.
		AddToInventorySilent("Chicken", -1, 1); //Remove chicken from player inventory
	}
	else if ($addingAnimal == "Pig") //Adding Pigs to farm
	{
		if ($gBuildingVar22 <= 0) //If this is the first pig that gets added, set a birth day for it.
		{
			$gBuildingTimeVar3 = $gGameDay;
		}
		
		$gBuildingVar22 = $gBuildingVar22 + 1; //Add pig to building.
		AddToInventorySilent("Pig", -1, 1); //Remove pig from player inventory
	}
	else if ($addingAnimal == "Sheep") //Adding Sheeps to farm
	{
		if ($gBuildingVar23 <= 0) //If this is the first sheep that gets added, set a birth day for it.
		{
			$gBuildingTimeVar4 = $gGameDay;
		}
		
		$gBuildingVar23 = $gBuildingVar23 + 1; //Add sheep to building.
		AddToInventorySilent("Sheep", -1, 1); //Remove sheep from player inventory
	}
	else //If value isn't anything of above, notify it.
	{
		*say Error trying to add animal ($addingAnimal) from Animal Farm (ID:$gBuildingAccessNum)
	}
	
	AnimalFarm_Display();
}

Event ("OSDSelect", "AnimalFarm:RemoveAnimal")
{
	if ($removingAnimal == "Cow") //If value is Cow, remove 1 from gBuildingVar20, and add 1 to inventory. (Same goes for the else...if's below)
	{
		$gBuildingVar20 = $gBuildingVar20 - 1;
		AddToInventorySilent("Cow", 1, 1);
	}
	else if ($removingAnimal == "Chicken")
	{
		$gBuildingVar21 = $gBuildingVar21 - 1;
		AddToInventorySilent("Chicken", 1, 1);
	}
	else if ($removingAnimal == "Pig")
	{
		$gBuildingVar22 = $gBuildingVar22 - 1;
		AddToInventorySilent("Pig", 1, 1);
	}
	else if ($removingAnimal == "Sheep")
	{
		$gBuildingVar23 = $gBuildingVar23 - 1;
		AddToInventorySilent("Sheep", 1, 1);
	}
	else //If value isn't anything of above, notify it.
	{
		*say Error trying to remove animal ($removingAnimal) from Animal Farm (ID:$gBuildingAccessNum)
	}
	
	AnimalFarm_Display();
}
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Post by Haxina »

Seems like i found my mistake here.
i define the var $addingAnimal something new everytime the function AnimalFarm_AddRemoveAnimals() gets called, so since Sheep is the last animal that's the one that's defined in $addingAnimal (and $removingAnimal)

Code: Select all

AnimalFarm_AddRemoveAnimals("Cow", 5); 
AnimalFarm_AddRemoveAnimals("Chicken", 20); 
AnimalFarm_AddRemoveAnimals("Pig", 35); 
AnimalFarm_AddRemoveAnimals("Sheep", 50); <--
Edit: Problem has been solved.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

You may find it neater if you use parameters on your OSDSelect event. Formatting them is slightly odd (pipe separated values in the OSDAddat name) and you can only use numbers as parameters atm not text, but it can make things much easier to deal with.

As an example, you'd set your osd up like:

Code: Select all

OSDAddAt( BUTTON, 100, 100, 100, 20, "AddAnimal|$CowItemNum", "Add a cow" );
OSDAddAt( BUTTON, 100, 100, 100, 20, "AddAnimal|$SheepItemNum", "Add a sheep" );
The piped parameters are removed so the OSDSelect event that gets triggered is still AnimalFarm:AddAnimal. Then at the start of the OSDSelect event add :

Code: Select all

$animalItemTypeAdded = $gParam[1]
$animalName = sysGetItemName( $animalItemTypeAdded )
You could also consider removing all the IFs and else IFs by using a table and reduce that whole script to just a few lines. (Therefore less to debug if it goes wrong :] and it also makes it much easier to add new items or make a new version of the building that does different stuff. )

Code: Select all

$m_AnimalFarmData[ ] = { // Item Name      BuildingVar slot
                            "Cow",              20,   
                            "Chickens",         21,
                            "Pigs",             22,
                             "Sheep",           23
                             "",                    0             }   // End of list marker


Function AnimalFarm_Display() 
{ 
   AnimalFarm_AddRemoveAnimals( 0,  5); 
   AnimalFarm_AddRemoveAnimals( 1, 20); 
   AnimalFarm_AddRemoveAnimals( 2, 35); 
   AnimalFarm_AddRemoveAnimals( 3, 50); 
} 

Function AnimalFarm_AddRemoveAnimals( $tableIndex, $posY) 
{ 
   $tableIndex *= 2;

   $animal = $m_AnimalFarmData[ $tableIndex ]
   $bvarSlot = $m_AnimalFarmData[ $tableIndex + 1 ]

   $amountOfAnimal = $gBuildingVar[$bvarSlot]

  ....    
For dessert, modify the osd creation so it just loops through the table (until it reaches the end of list marker) filling out the names and item numbers dynamically, and you'll have a purely data-driven little script that could be reused / adjusted just by changing the values in the table.
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Post by Haxina »

Thanks a ton for letting me know about those parameters, and giving me those examples!
That was exactly what i wanted to do from the start, but i just didn't know about those parameters (Apart from the table, didn't think about that one) :)

I've scripted it over again and it's working perfectly. Thanks :)
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

almost perfectly.
something in the animal farm script causes narnia to illegal op.

you've probably already noticed via the ftp that i renamed the anmimal farm script so the world would start
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Post by Haxina »

Yes i've noticed it. And i can't find the problem.. But i can say that narnia crashes when i try to refresh the script.

I'll post the full code tomorrow so you guys can look at it ;)
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Post by Haxina »

Alright. Here's a link for the full code: Pastebin
I thought it were a bit too much for posting here ;)

The Event "AnimalFarm:More", functions AnimalFarm_MoreFunctions() and AnimalFarm_GetFromAnimal() (but commented out as i thoght that could solve the problem) is new.

Before i added the new stuff there were no problems with refreshing the scripts. (There wasn't actually any problems either when i added the "More" Event)
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

Oddly that doesnt cause a crash on my current server code (and I'm not aware of any changes i've made that would affect it). I'll dig some more, but meantime there seems to be a few malformed lines at the top of the script that might be causing problems :

Code: Select all

chickensProductionRange = 4; //The higher this is the less change there's to hatching an egg.

msg
{
chickensProductionRange is missing a $ to declare the variable.
Dunno what the 'msg' is about? (Though i can't imagine that should do anything).

Nice tidy looking script otherwise :).
@Zar, I assume the world is running 0.67.9 server?
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

67.7

67.9 isn't available for download yet :P
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

ah, so it isnt.. could be i've fixed something since then.. I'll post up 0.68.1 servers soon.
(if its not cooked tonight, i'll send you a custom build).
User avatar
zaroba
World Owner
World Owner
Posts: 7257
Joined: Fri Oct 10, 2003 11:06 pm
Location: Hereford, PA
Contact:

Post by zaroba »

k, when i get home from work I'll look for them.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

just a guess for now (until i get home myself and can do a proper test), but wouldn't surprise me if the problem is in the building production run event (which would explain why i dont get a crash here).

Don't see anything obvious wrong there (other than the unset global for chickensProductionRange, but that should be harmless enough) but if you get chance could you confirm if the server crashes without the 'BuildingProductionRun' event present?
Haxina
VIP
VIP
Posts: 63
Joined: Thu Oct 17, 2013 4:25 pm

Post by Haxina »

So, i removed the "msg" line, and added a $ to the var, and it did not crash when i tried to refresh server script. However! I added them back in and there was still no problem, it didn't crash.

I'll try and track down the crash. i can imagine that it was trying to access chickensProductionRange (without the $), failed and crashed server. However since it didn't exists as a var (no $), wouldn't it just return "0"? (Line.711). tbh i'm a bit confused.

Edit: I tried removing the $ from the var, waitet a bit for BuildingProductionRun to execute, then refreshed script and still no crash.
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

yeh, if it didnt exist it'd be treated as a new local variable defaulting to 0.
Its possible that a system function or command might not like working with 0 (for instance, I had to check that doing sysRand( 0 ) was ok - as it might have resulted in a divide by zero error - but thats already covered in the script engine).

mmm.. all very curious..
User avatar
Mit
Staff
Staff
Posts: 3551
Joined: Sun Sep 21, 2003 10:14 pm
Location: Unknown

Post by Mit »

p.s. im fairly sure none of the changes in server code since 0.67.7 will make any difference to this, but just in case, a server v0.68.0 is on the members downloads page now.
Locked