Loot and Resources

What is battle loot?

In the City Building Kit battles, like popular free-to-play strategy games, players gain resources when attacking other player bases.

542

Gaining resources (loot) during battle by attacking a structure.

This resource gained is called loot, because it's removed -- stolen -- from the enemy player's base. When the enemy player downloads their base from the server, they'll also download the battle results file which updates them on the result of the battle that occurred while they were gone and deduct the resources lost from their total resources.

That's why it's important to build defense structures to prevent players from stealing more of their loot resources.

How do players get loot?

Players get loot during battle. By default, attacking any building awards loot. If you would like to restrict gaining loot to only certain special buildings in your game, read below for how to change this function.

597

Attack building to gain loot

652

Resources increase

834

Battle results with the total resources

Do players actually lose their resources when attacked?

Yes, the Script/Save/SaveLoadWWW.cs has a function called DownloadMyMapAttack() which is triggered when downloading the users map using the Server Load function.

DownloadMyMapAttack() checks the server for a battle results file to see if there was an attack while the player was gone - and if there was a battle, it sends the results file to Scripts/Save/SaveLoadMap.cs LoadAttackFromServer() which processes the battle results and remove the resources the player lost during battle when the game loads.

Here is an excerpt of that function:

// Excerpt from SaveLoadWWW.cs
// Checks the server for a battle results file
// and if it exists, sends it to SaveLoadMap.cs LoadAttackFromServer()
// to process the battle results and show the user the attack menu

IEnumerator DownloadMyMapAttack()   
{		
	WWWForm form = new WWWForm();		
	form.AddField("savefile","file");
	
  // Connect to the online server scripts which sync all player and battle data
  // If you don't have these server scripts yet, please contact
  // us to get download access to CityBuildingKit.com/download
  // and get your copy of the server scripts
  //
	WWW w2 = new WWW(serverAddress + matchAddress + "?get_user_map=1&mapid=" + myMapIDCode + attackExt+"&license="+license);
	
	yield return w2;
	
	if(w2.error != null)
	{
    // If a problem connecting online
    
		((Messenger)statusMsg).DisplayMessage("Attack file download failed.");
		print("Server load error" + w2.error);
	}
	
	else
	{
		//then if the retrieval was successful, validate its content to ensure the map file integrity is intact
		if(w2.text != null && w2.text != "")
		{
			if(w2.text.Contains("###StartofFile###") && w2.text.Contains("###EndofFile###"))
			{
        // There was a battle file found, and it has the correct formatting
        // So process what is inside and show the attack results menu
        // 
				print ( "Your map ID "+ myMapIDCode + attackExt +" contents are: \n\n" + w2.text);	
				
				WriteMyMapAttackFromServer(w2.text);					
				((SaveLoadMap)saveLoadMap).LoadAttackFromServer();
				StartCoroutine("EraseAttackFromServer");
				((Messenger)statusMsg).DisplayMessage("Attack results downloaded.");
        
			}
			else
			{			
        // In case an error occurs during download, we will print out
        // the materials in the Unity console for you to troubleshoot
        
				print ( "Your map file is invalid. Contents are: \n\n" + w2.text);
				//although file is broken, prints the content of the retrieved file
				((Messenger)statusMsg).DisplayMessage("Attack results corrupted. Download failed.");
			}
		}
		else
		{
			print ( "Attack file is empty");
			((Messenger)statusMsg).DisplayMessage("Your town was not attacked.");

		}
	}
}

The following function LoadAttackFromServer() in Scripts/Save/SaveLoadMap.cs is called by Scripts/Save/SaveLoadWWW.cs when DownloadMyMapAttack() downloads a battle attack file.

As mentioned above, LoadAttackFromServer() processes the battle results and remove the resources the player lost during battle when the game loads.

// The following functions parse the battle results from the server
// and remove the resources from the player's base
// Then afterwards opens the Damage Panel to show the total damage

public void LoadAttackFromServer()
{
	//	StreamReader 
	sReader = new StreamReader(filePath + fileNameAttack + fileExt);
  
  // Now we call the AttackDamage function does all of the processing
	AttackDamage (sReader);
}

// The following AttackDamage function will read the battle data
// and remove the resources
private void AttackDamage(StreamReader sReader)
{

	currentLine = "";

	currentLine = sReader.ReadLine();//skip header

	currentLine = sReader.ReadLine();//read gold/mana

	string[] losses = currentLine.Split(","[0]);

  // Parse the battle results for the total
	int goldLost = int.Parse(losses[0]);
	int manaLost = int.Parse(losses[1]);
	int buildingsLost = int.Parse(losses[2]);
	int unitsLost = int.Parse(losses[3]);

  // Nothing was lost during the battle, so we don't need to deduct resources
	if (goldLost == 0 && manaLost == 0) 
	{
		return;//the file exists, but has been loaded and reset
	}

  // Else, resources were lost so we will set the Attack damage panel data
  // And update the UI.
	goldLostLb.text = goldLost.ToString ();
	manaLostLb.text = manaLost.ToString ();
	buildingsLostLb.text = buildingsLost.ToString ();
	unitsLostLb.text = unitsLost.ToString ();

	((Stats)stats).gold -= goldLost;
	((Stats)stats).mana -= manaLost;
	((Stats)stats).UpdateUI();
	//menuMain.OnCloseSettings();
	StartCoroutine("ActivateDamagePanel");
}

If there was resources lost, the user will see a "Attack Damage" panel when the game loads from the server. Should the game take longer to load and the player already has another menu open, this attack results panel will show once the player has closed the menu or finished the task they are doing.

// SaveLoadMap.cs	
// Show the attack results panel
// keeps trying to launch the damage panel, waiting fot the user to finish other tasks, if any
// otherwise the panel is superimposed on other panels	
private IEnumerator ActivateDamagePanel()
{									
	yield return new WaitForSeconds (2);
	if(!((Relay)relay).pauseInput)
	{
		//((Relay)relay).pauseInput = true;
		if(GhostHelper.activeSelf){ ((GhostHelper)ghostHelper).ResetHelper();}

		menuMain.OnDamage();

	}
	else
		StartCoroutine("ActivateDamagePanel");
}
795

Battle results after login

Afterwards, the function EraseAttackFromServer() in Scripts/Save/SaveLoadWWW.cs will connect to the server scripts and issue a request to erase the attack results file from the server since they were downloaded and the resources removed from the player's total.

How can I change what loot is awarded?

By default, the City Building Kit Complete Strategy Kit attacking player will receive loot based on what building they are attacking and what currency the original player paid for that building. This allows for loot to be gained from attacking every building. The PrepareLoot() function in Scripts/Helios/Helios.cs demonstrates how this is assigned.

Note: if you don't customize the PrepareLoot() function then by default, attacking any of your buildings will award the second currency (Mana) because of the following line in that function:

else 
		allLootMana += value;

If you would like your gameplay to model popular free-to-play strategy games and only reward loot based on attacking resource mines or resource storage buildings - then you'll want to edit the following function to only add total battle value for your resource buildings and ignore all others.

// Excerpt from Helios.cs
// Which is the main battle control script.
// The following PrepareLoot function calculates the total value of the base
// which is later used to distribute the earnings per building

private void PrepareLoot(string buidingType)
{
	int i = 0;
							
      //0 Gold 1 Mana 2 Crystals
      // This is the list of buildings in the game
      // To the right of each of the items in this list
      // we specify what currency was used to buy them
      // This is the currency that players will gain
      
		foreach(BuildingCategoryLevels b in ShopData.Instance.BuildingsCategoryData.category){
			if(b.name.Contains(buidingType)){
				i = b.id;
				break;
			}
		}
		foreach(MilitaryCategoryLevels b in ShopData.Instance.MilitaryCategoryData.category){
			if(b.name.Contains(buidingType)){
				i = b.id;
				break;
			}
		}

	string currency = ((TransData)transData).buildingCurrency [i];

	int value = ((TransData)transData).buildingValues [i];

  // If you do not want to add currency for all buildings
  // you will need to add an if/else below to prevent all 
  // building value and currency from being added to the total
  
	BuildingValues.Add(value);
	BuildingCurrency.Add(currency);

	if(currency=="Gold") 
		allLootGold += value;
	else if(currency=="Crystals") 
		allLootGold += value;
	else 
		allLootMana += value;
}

And also, in the Scripts/Helios/Helios.cs Update() function you will want to edit the gain value (what the player gains in resources) to

// If you do not want to add currency for all buildings
  // you will need to add an if/else below to
	// gain = ... and gainPerBuilding[k] = ...
	// to prevent all buildings from awarding the
  // their original purchase currency assigned in PrepareLoot()

int[] gainPerBuilding = new int[Buildings.Count];//same count as Buildings
					
			for (int i = 0; i <= instantiationGroupIndex; i++) 
			{
				if (!pauseAttack [i] && currentDamage[i]>0) 
				{
					int k = GetBuildingListIndex(targetBuildingIndex [i]);
					//print(k.ToString());
					gain = (currentDamage [i]*BuildingValues[k])/100;				
					gainPerBuilding[k] += gain;
					BuildingsHealth [k] -= 1 * currentDamage [i];
					DamageBars[k].GetComponent<UISlider>().value = BuildingsHealth [k]*0.01f;//since full building health was 100

				}
			}