drbrain avatar drbrain committed 59647a3 Merge

Merge.

Comments (0)

Files changed (5)

hscore_commands.c

 		int maxRotation = cfg->GetInt(conf, shipname, "MaximumRotation", 0);
 		int bulletSpeed = cfg->GetInt(conf, shipname, "BulletSpeed", 0);
 		int bombSpeed = cfg->GetInt(conf, shipname, "BombSpeed", 0);
+		
+		LinkedList *shipProperties = database->getShipPropertyList(p->arena, ship);
+		Link *link;
 	
 		chat->SendMessage(p, "+------------------+");
 		chat->SendMessage(p, "| %-16s |", shipname);
 		chat->SendMessage(p, "| Init Rotation: %-5d | Bullet Speed:  %-5d |                      |                      |", initRotation, bulletSpeed);
 		chat->SendMessage(p, "| Max Rotation:  %-5d | Bomb Speed:    %-5d |                      |                      |", maxRotation, bombSpeed);
 		chat->SendMessage(p, "+----------------------+----------------------+----------------------+----------------------+");
+		chat->SendMessage(p, "| Property Name        | Property Value       |");
+		chat->SendMessage(p, "+----------------------+----------------------+");
+		for (link = LLGetHead(shipProperties); link; link = link->next)
+		{
+			Property *prop = link->data;
+			if (prop->absolute)
+			{
+				chat->SendMessage(p, "| %-20s | =%-20i |", prop->name, prop->value);
+			}
+			else
+			{
+				chat->SendMessage(p, "| %-20s | %+-20i |", prop->name, prop->value);
+			}
+		}
+		chat->SendMessage(p, "+----------------------+----------------------+");
 	}
 }
 
-EXPORT const char info_hscore_commands[] = "v1.0 Dr Brain <drbrain@gmail.com>";
+EXPORT const char info_hscore_commands[] = "v1.1 Dr Brain <drbrain@gmail.com>";
 
 EXPORT int MM_hscore_commands(int action, Imodman *_mm, Arena *arena)
 {

hscore_database.c

 local void loadArenaStoresQueryCallback(int status, db_res *result, void *passedData);
 local void loadCategoryItemsQueryCallback(int status, db_res *result, void *passedData);
 local void loadArenaCategoriesQueryCallback(int status, db_res *result, void *passedData);
+local void loadShipPropertyListsQueryCallback(int status, db_res *result, void *passedData);
 local void InitPerPlayerData(Player *p);
 local void InitPerArenaData(Arena *arena);
 local void UnloadPlayerGlobals(Player *p);
 local void UnloadPlayerShips(Player *p);
 local void UnloadCategoryList(Arena *arena);
 local void UnloadStoreList(Arena *arena);
+local void UnloadShipPropertyLists(Arena *arena);
 local void UnloadItemListEnumCallback(const void *ptr);
 local void UnloadItemList();
 local void UnloadItemTypeList();
 local void LoadCategoryList(Arena *arena);
 local void LoadStoreItems(Arena *arena);
 local void LoadStoreList(Arena *arena);
+local void LoadShipPropertyLists(Arena *arena);
 local void LoadEvents();
 local void LoadProperties();
 local void LoadItemList();
 "  PRIMARY KEY  (`id`)" \
 ")"
 
+#define CREATE_SHIP_PROPERTIES_TABLE \
+"CREATE TABLE IF NOT EXISTS `hs_ship_properties` (" \
+"  `ship` tinyint(4) NOT NULL default '0'," \
+"  `name` varchar(32) NOT NULL default ''," \
+"  `value` int(11) NOT NULL default '0'," \
+"  `absolute` tinyint(4) NOT NULL default '0'," \
+"  `arena` varchar(32) NOT NULL default ''," \
+"  `id` int(10) unsigned NOT NULL auto_increment," \
+"  PRIMARY KEY  (`id`)" \
+")"
+
 #define CREATE_TRANSACTIONS_TABLE \
 "CREATE TABLE IF NOT EXISTS `hs_transactions` (" \
 "  `id` int(10) NOT NULL auto_increment," \
 	mysql->Query(NULL, NULL, 0, CREATE_PLAYERS_TABLE);
 	mysql->Query(NULL, NULL, 0, CREATE_STORE_ITEMS_TABLE);
 	mysql->Query(NULL, NULL, 0, CREATE_STORES_TABLE);
+	mysql->Query(NULL, NULL, 0, CREATE_SHIP_PROPERTIES_TABLE);
 	mysql->Query(NULL, NULL, 0, CREATE_TRANSACTIONS_TABLE);
 	mysql->Query(NULL, NULL, 0, CREATE_PLAYER_POINTS_TABLE);
 	mysql->Query(NULL, NULL, 0, CREATE_ITEM_TYPE_ASSOC_TABLE);
 
 	lm->LogA(L_DRIVEL, "hscore_database", arena, "%i categories were loaded from MySQL.", results);
 	LoadCategoryItems(arena); //now that all the stores are in, load the items into them.
-
+}
+
+local void loadShipPropertyListsQueryCallback(int status, db_res *result, void *passedData)
+{
+	int results;
+	db_row *row;
+
+	Arena *arena = passedData;
+	PerArenaData *arenaData = getPerArenaData(arena);
+
+	if (status != 0 || result == NULL)
+	{
+		lm->LogA(L_ERROR, "hscore_database", arena, "Unexpected database error during ship property load.");
+		return;
+	}
+
+	results = mysql->GetRowCount(result);
+
+	if (results == 0)
+	{
+		//no big deal
+		return;
+	}
+
+	lock();
+	while ((row = mysql->GetRow(result)))
+	{
+		int ship = atoi(mysql->GetField(row, 0)); //ship
+		if (ship < 0 || 7 < ship)
+		{
+			lm->LogA(L_ERROR, "hscore_database", arena, "ship property looking for ship %i.", ship);
+			continue;
+		}
+		
+		Property *property = amalloc(sizeof(*property));
+		
+		astrncpy(property->name, mysql->GetField(row, 1), 17);
+		property->value = atoi(mysql->GetField(row, 2));		//value
+		property->absolute = atoi(mysql->GetField(row, 3));		//absolute
+		
+		LLAdd(&arenaData->shipPropertyLists[ship], property);
+	}
+	unlock();
+
+	lm->LogA(L_DRIVEL, "hscore_database", arena, "%i ship properties were loaded from MySQL.", results);
 }
 
 //+------------------+
 
 	LLInit(&arenaData->categoryList);
 	LLInit(&arenaData->storeList);
+	
+	int i;
+	for (i = 0; i < 8; i++)
+	{
+		LLInit(&arenaData->shipPropertyLists[i]);
+	}
 }
 
 //+--------------------+
 	unlock();
 }
 
+local void UnloadShipPropertyLists(Arena *arena)
+{
+	PerArenaData *arenaData = getPerArenaData(arena);
+
+	int i;
+	int count = 0;
+	
+	lock();
+	for (i = 0; i < 8; i++)
+	{
+		LLEnum(&arenaData->shipPropertyLists[i], afree); //can simply free all the Store structs
+		count += LLCount(&arenaData->shipPropertyLists[i]);
+		LLEmpty(&arenaData->shipPropertyLists[i]);
+	}
+	unlock();
+	
+	lm->LogA(L_DRIVEL, "hscore_database", arena, "Freed %i ship properties.", count);
+}
+
 local void UnloadItemListEnumCallback(const void *ptr) //called with lock held
 {
 	Item *item = (Item*)ptr;
 	{
 		UnloadStoreList(arena);
 		UnloadCategoryList(arena);
+		UnloadShipPropertyLists(arena);
 	}
 	aman->Unlock();
 }
 	mysql->Query(loadArenaStoresQueryCallback, arena, 1, "SELECT id, name, description, region FROM hs_stores WHERE arena = ? ORDER BY hs_stores.order ASC", getArenaIdentifier(arena));
 }
 
+local void LoadShipPropertyLists(Arena *arena)
+{
+	mysql->Query(loadShipPropertyListsQueryCallback, arena, 1, "SELECT ship, name, value, absolute, arena FROM hs_ship_properties WHERE arena = ?", getArenaIdentifier(arena));
+}
+
 local void LoadEvents()
 {
 	mysql->Query(loadEventsQueryCallback, NULL, 1, "SELECT item_id, event, action, data, message FROM hs_item_events");
 "Targets: none\n"
 "Args: none\n"
 "This command will reload all current and new items from the database.\n"
-"It will also reload all arenas stores and categories.\n"
+"It will also reload all arenas stores, categories and ship properties.\n"
 "NOTE: This command will *NOT* remove items no longer in the database.\n";
 
 local void reloadItemsCommand(const char *command, const char *params, Player *p, const Target *target)
 	{
 		LoadStoreList(a);
 		LoadCategoryList(a);
-		chat->SendMessage(p, "...Ran stores/categories queries for arena '%s'", a->name);
+		LoadShipPropertyLists(a);
+		chat->SendMessage(p, "...Ran stores/categories/ship properties queries for arena '%s'", a->name);
 	}
 	aman->Unlock();
 
 		//in no special order...
 		LoadStoreList(arena);
 		LoadCategoryList(arena);
+		LoadShipPropertyLists(arena);
 	}
 	else if (action == AA_DESTROY)
 	{
 		//in no special order...
 		UnloadStoreList(arena);
 		UnloadCategoryList(arena);
+		UnloadShipPropertyLists(arena);
 
 		//no need to deallocate the lists, as they weren't allocated
 	}
 	return &arenaData->categoryList;
 }
 
+local LinkedList * getShipPropertyList(Arena *arena, int ship)
+{
+	if (ship < 0 || 7 < ship)
+	{
+		lm->LogA(L_ERROR, "hscore_database", arena, "request for ship property list for ship %i.", ship);
+		return NULL;
+	}
+	
+	PerArenaData *arenaData = getPerArenaData(arena);
+	return &arenaData->shipPropertyLists[ship];
+}
+
 local void lock()
 {
 	pthread_mutex_lock(&itemMutex);
 {
 	INTERFACE_HEAD_INIT(I_HSCORE_DATABASE, "hscore_database")
 	areShipsLoaded, isLoaded, getItemList, getStoreList,
-	getCategoryList, lock, unlock, updateItem,
+	getCategoryList, getShipPropertyList,
+	lock, unlock, updateItem,
 	updateItemNoLock, updateInventoryNoLock,
 	addShip, removeShip, getPerPlayerData,
 };

hscore_database.h

 #ifndef HSCORE_DATABASE_H
 #define HSCORE_DATABASE_H
 
-#define I_HSCORE_DATABASE "hscore_database-4"
+#define I_HSCORE_DATABASE "hscore_database-5"
 
 typedef struct PerPlayerData
 {
 {
 	LinkedList storeList;
 	LinkedList categoryList;
+	LinkedList shipPropertyLists[8];
 } PerArenaData;
 
 #define CB_ITEM_COUNT_CHANGED "itemcount-1"
 	LinkedList * (*getItemList)();
 	LinkedList * (*getStoreList)(Arena *arena);
 	LinkedList * (*getCategoryList)(Arena *arena);
+	LinkedList * (*getShipPropertyList)(Arena *arena, int ship);
 
 	void (*lock)();
 	void (*unlock)();
 	}
 
 	//not in the cache, look it up
+	LinkedList *shipProperties = database->getShipPropertyList(p->arena, ship);
+	for (link = LLGetHead(shipProperties); link; link = link->next)
+	{
+		Property *prop = link->data;
+		
+		if (strcmp(prop->name, propString) == 0)
+		{
+			count += prop->value;
+			absolute = absolute || prop->absolute;
+			break;
+		}
+	}
+	
 	inventoryList = &playerData->hull[ship]->inventoryEntryList;
-
 	for (link = LLGetHead(inventoryList); link; link = link->next)
 	{
 		Link *propLink;
 	HashEnum(table, zeroCacheEntry, NULL);
 
 	//then iterate every property and update the cache with it
+	LinkedList *shipProperties = database->getShipPropertyList(p->arena, ship);
+	for (link = LLGetHead(shipProperties); link; link = link->next)
+	{
+		Property *prop = link->data;
+		PropertyCacheEntry *propertySum;
+
+		int propDifference = prop->value;
+
+		//get it out of the cache
+		propertySum = (PropertyCacheEntry*)HashGetOne(table, prop->name);
+		if (propertySum != NULL)
+		{
+			propertySum->value += propDifference;
+			propertySum->absolute = propertySum->absolute || prop->absolute;
+		}
+		else
+		{
+			//no cache entry; create one
+			propertySum = amalloc(sizeof(*propertySum));
+			propertySum->value = propDifference;
+			propertySum->absolute = prop->absolute;
+			HashAdd(playerData->hull[ship]->propertySums, prop->name, propertySum);
+		}
+	}
+	
 	inventoryList = &playerData->hull[ship]->inventoryEntryList;
-
 	for (link = LLGetHead(inventoryList); link; link = link->next)
 	{
 		InventoryEntry *entry = link->data;
 				clientset->PlayerUnoverride(p, shipOverrideKeys[i].MaxBombs);
 			}
 
+			
+			//Alternate item set system
+			int useMassSystem = cfg->GetInt(conf, "HSCore_Spawner", "UseMassSystem", 0);
+			if (useMassSystem)
+			{
+				int mass = items->getPropertySumNoLock(p, i, "mass", 0);
+				int output = items->getPropertySumNoLock(p, i, "output", 0);
+				int maxoutput = items->getPropertySumNoLock(p, i, "maxoutput", 0);
+				
+				int thrust = max(0, (output / (0.04 * mass)) - (0.004 * mass));
+				int maxthrust = max(0, (maxoutput / (0.04 * mass)) - (0.004 * mass));
+				
+				int speed = max(0, (output / (0.0005 * mass)) - mass);
+				int maxspeed = max(0, (maxoutput / (0.0005 * mass)) - mass);
+				
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialThrust, thrust);
+				clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumThrust, maxthrust);
+				
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialSpeed, speed);
+				clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumSpeed, maxspeed);
+				
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRotation, speed * 7.5);
+				
+				int power = items->getPropertySumNoLock(p, i, "power", 0);
+				int capacity = items->getPropertySumNoLock(p, i, "capacity", 0);
+				int powerdrain = items->getPropertySumNoLock(p, i, "powerdrain", 0);
+				
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialEnergy, max(0, capacity));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRecharge, max(0, power - powerdrain));
+				
+				int afterburner = items->getPropertySumNoLock(p, i, "afterburner", 0);
+				clientset->PlayerOverride(p, shipOverrideKeys[i].AfterburnerEnergy, max(0, afterburner));
+			}
+			else
+			{
+				int thrust = items->getPropertySumNoLock(p, i, "thrust", 0);
+				int initThrust = cfg->GetInt(conf, shipname, "InitialThrust", 0);
+				int upThrust = cfg->GetInt(conf, shipname, "UpgradeThrust", 0);
+				int newThrust = max(0, initThrust + (upThrust * thrust));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialThrust, newThrust);
 
+				int speed = items->getPropertySumNoLock(p, i, "speed", 0);
+				int initSpeed = cfg->GetInt(conf, shipname, "InitialSpeed", 0);
+				int upSpeed = cfg->GetInt(conf, shipname, "UpgradeSpeed", 0);
+				int newSpeed = max(0, initSpeed + (upSpeed * speed));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialSpeed, newSpeed);
 
+				int energy = items->getPropertySumNoLock(p, i, "energy", 0);
+				int initEnergy = cfg->GetInt(conf, shipname, "InitialEnergy", 0);
+				int upEnergy = cfg->GetInt(conf, shipname, "UpgradeEnergy", 0);
+				int newEnergy = max(0, initEnergy + (upEnergy * energy));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialEnergy, newEnergy);
 
-			int thrust = items->getPropertySumNoLock(p, i, "thrust", 0);
-			int initThrust = cfg->GetInt(conf, shipname, "InitialThrust", 0);
-			int upThrust = cfg->GetInt(conf, shipname, "UpgradeThrust", 0);
-			int newThrust = max(0, initThrust + (upThrust * thrust));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].InitialThrust, newThrust);
+				int recharge = items->getPropertySumNoLock(p, i, "recharge", 0);
+				int initRecharge = cfg->GetInt(conf, shipname, "InitialRecharge", 0);
+				int upRecharge = cfg->GetInt(conf, shipname, "UpgradeRecharge", 0);
+				int newRecharge = max(0, initRecharge + (upRecharge * recharge));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRecharge, newRecharge);
 
-			int speed = items->getPropertySumNoLock(p, i, "speed", 0);
-			int initSpeed = cfg->GetInt(conf, shipname, "InitialSpeed", 0);
-			int upSpeed = cfg->GetInt(conf, shipname, "UpgradeSpeed", 0);
-			int newSpeed = max(0, initSpeed + (upSpeed * speed));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].InitialSpeed, newSpeed);
+				int rotation = items->getPropertySumNoLock(p, i, "rotation", 0);
+				int initRotation = cfg->GetInt(conf, shipname, "InitialRotation", 0);
+				int upRotation = cfg->GetInt(conf, shipname, "UpgradeRotation", 0);
+				int newRotation = max(0, initRotation + (upRotation * rotation));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRotation, newRotation);
 
-			int energy = items->getPropertySumNoLock(p, i, "energy", 0);
-			int initEnergy = cfg->GetInt(conf, shipname, "InitialEnergy", 0);
-			int upEnergy = cfg->GetInt(conf, shipname, "UpgradeEnergy", 0);
-			int newEnergy = max(0, initEnergy + (upEnergy * energy));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].InitialEnergy, newEnergy);
+				int maxthrust = items->getPropertySumNoLock(p, i, "maxthrust", 0);
+				int initMaxThrust = cfg->GetInt(conf, shipname, "MaximumThrust", 0);
+				int newMaxThrust = max(0, initMaxThrust + (upThrust * maxthrust));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumThrust, newMaxThrust);
 
-			int recharge = items->getPropertySumNoLock(p, i, "recharge", 0);
-			int initRecharge = cfg->GetInt(conf, shipname, "InitialRecharge", 0);
-			int upRecharge = cfg->GetInt(conf, shipname, "UpgradeRecharge", 0);
-			int newRecharge = max(0, initRecharge + (upRecharge * recharge));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRecharge, newRecharge);
+				int maxspeed = items->getPropertySumNoLock(p, i, "maxspeed", 0);
+				int initMaxSpeed = cfg->GetInt(conf, shipname, "MaximumSpeed", 0);
+				int newMaxSpeed = max(0, initMaxSpeed + (upSpeed * maxspeed));
+				clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumSpeed, newMaxSpeed);
 
-			int rotation = items->getPropertySumNoLock(p, i, "rotation", 0);
-			int initRotation = cfg->GetInt(conf, shipname, "InitialRotation", 0);
-			int upRotation = cfg->GetInt(conf, shipname, "UpgradeRotation", 0);
-			int newRotation = max(0, initRotation + (upRotation * rotation));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].InitialRotation, newRotation);
-
-			int maxthrust = items->getPropertySumNoLock(p, i, "maxthrust", 0);
-			int initMaxThrust = cfg->GetInt(conf, shipname, "MaximumThrust", 0);
-			int newMaxThrust = max(0, initMaxThrust + (upThrust * maxthrust));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumThrust, newMaxThrust);
-
-			int maxspeed = items->getPropertySumNoLock(p, i, "maxspeed", 0);
-			int initMaxSpeed = cfg->GetInt(conf, shipname, "MaximumSpeed", 0);
-			int newMaxSpeed = max(0, initMaxSpeed + (upSpeed * maxspeed));
-			clientset->PlayerOverride(p, shipOverrideKeys[i].MaximumSpeed, newMaxSpeed);
-
-			int afterburner = items->getPropertySumNoLock(p, i, "afterburner", 0);
-			int initAfterburner =  cfg->GetInt(conf, shipname, "AfterburnerEnergy", 0);
-			int newAfterburner = initAfterburner + (upRecharge * afterburner);
-			clientset->PlayerOverride(p, shipOverrideKeys[i].AfterburnerEnergy, newAfterburner);
-
-
-
+				int afterburner = items->getPropertySumNoLock(p, i, "afterburner", 0);
+				int initAfterburner =  cfg->GetInt(conf, shipname, "AfterburnerEnergy", 0);
+				int newAfterburner = initAfterburner + (upRecharge * afterburner);
+				clientset->PlayerOverride(p, shipOverrideKeys[i].AfterburnerEnergy, newAfterburner);
+			}
 
 			int initBurstMax = cfg->GetInt(conf, shipname, "BurstMax", 0);
 			int burstMax = max(0, items->getPropertySumNoLock(p, i, "burstmax", initBurstMax));
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.