Simon Volpert zdoomrl / master asmflow / AutoAssembly.acs
master

Tree @master (Download .tar.gz)

AutoAssembly.acs @masterraw · history · blame

#library "AssemblyFlow"
#include "zcommon.acs"
#include "Assemblies.acs"

str Modpacks[8] = {"AgilityMod", "BulkMod", "TechnicalMod", "PowerMod", "FirestormMod", "SniperMod", "NanoMod", "ArtiMod"};

// Return the number of required mods for an assembly
function int modreq(int AssemblyIndex, int ModType) {
	return GetChar(AssemblyDB[AssemblyIndex][ModType], 0) - 48;
}

// Watch for potential assemblies to auto-replace
script "AssemblyWatch" Enter {
	str UsedMod, HeldItem, ResultItem, BaseItem; // Set to empty string immediately before use
	int AMods, BMods, TMods, PMods, FMods, SMods, NMods, ModLimit, AsmSize;
	if (GetCvar("Debug")) {
		Log(s:"fluid assembly watch ready");
	}
	while (TRUE) {
		Delay(1);
		// Wait for a modpack activation
		UsedMod = "";
		for (int m = 0; m < 8; m++) {
			if (CheckInventory(StrParam(s:"RLUse", s:Modpacks[m]))) {
				UsedMod = StrParam(s:"RLUse", s:Modpacks[m]);
				if (GetCvar("Debug")) {
					Log(s:"used ", s:Modpacks[m]);
				}
				break;
			}
		}
		if (UsedMod == "") {
			continue;
		}
		// Wait for the modpack to deactibate
		while (CheckInventory(UsedMod)) {
			Delay(1);
		}
		HeldItem = "";
		BaseItem = "";
		// Detect the item being modified
		for (int i = 0; i < ASSEMBLIES; i++) {
			if (CheckInventory(StrParam(s:AssemblyDB[i][ASSEMBLY_BASE], s:"Selected"))) {
				HeldItem = AssemblyDB[i][ASSEMBLY_BASE];
				BaseItem = HeldItem;
				break;
			}
			else if (CheckInventory(StrParam(s:AssemblyDB[i][ASSEMBLY_RESULT], s:"Selected"))) {
				HeldItem = AssemblyDB[i][ASSEMBLY_RESULT];
				BaseItem = AssemblyDB[i][ASSEMBLY_BASE];
				break;
			}
		}
		if (HeldItem == "") {
			continue;
		}
		// Count applied modpacks
		if (GetCvar("Debug")) {
			Log(s:"checking modification of ", s:HeldItem);
		}
		AMods = CheckInventory(StrParam(s:HeldItem, s:"AgilityMod"));
		BMods = CheckInventory(StrParam(s:HeldItem, s:"BulkMod"));
		TMods = CheckInventory(StrParam(s:HeldItem, s:"TechnicalMod"));
		PMods = CheckInventory(StrParam(s:HeldItem, s:"PowerMod"));
		FMods = CheckInventory(StrParam(s:HeldItem, s:"FirestormMod"));
		SMods = CheckInventory(StrParam(s:HeldItem, s:"SniperMod"));
		NMods = CheckInventory(StrParam(s:HeldItem, s:"NanoMod"));
		ModLimit = AMods + BMods + TMods + PMods + SMods + NMods;
		// Decompose assembly if applicable
		AsmSize = 0;
		if (HeldItem != BaseItem) {
			AMods += modreq(i, MOD_A);
			BMods += modreq(i, MOD_B);
			TMods += modreq(i, MOD_T);
			PMods += modreq(i, MOD_P);
			FMods += modreq(i, MOD_F);
			SMods += modreq(i, MOD_S);
			NMods += modreq(i, MOD_N);
			AsmSize = modreq(i, ASSEMBLY_SIZE);
			ModLimit += AsmSize;
		}
		if (GetCvar("Debug")) {
			Log(i:ModLimit, s:" mods: ", i:AMods, s:"A ", i:BMods, s:"B ", i:TMods, s:"T ", i:PMods, s:"P ", i:FMods, s:"F ", i:SMods, s:"S ", i:NMods, s:"N ");
		}
		// Check assembly eligibility
		ResultItem = "";
		for (int a = 0; a < ASSEMBLIES; a++) {
			if (BaseItem != AssemblyDB[a][ASSEMBLY_BASE]) {
				continue;
			}
			if (AMods < modreq(a, MOD_A) || BMods < modreq(a, MOD_B) || TMods < modreq(a, MOD_T) || PMods < modreq(a, MOD_P) ||
				FMods < modreq(a, MOD_F) || SMods < modreq(a, MOD_S) || NMods < modreq(a, MOD_N)) {
				continue;
			}
			// Ignore assemblies of the same or lower tier
			if (AsmSize >= modreq(a, ASSEMBLY_SIZE)) {
				continue;
			}
			ResultItem = AssemblyDB[a][ASSEMBLY_RESULT];
			if (GetCvar("Debug")) {
				Log(s:"enough mods to complete ", s:ResultItem);
			}
			break;
		}
		if (ResultItem == "") {
			continue;
		}
		// Clear inventory of existing item and subtract assembly cost from total mod counts
		TakeInventory(HeldItem, 1);
		TakeInventory(StrParam(s:HeldItem, s:"AgilityMod"), 4);
		AMods -= modreq(a, MOD_A);
		TakeInventory(StrParam(s:HeldItem, s:"BulkMod"), 4);
		BMods -= modreq(a, MOD_B);
		TakeInventory(StrParam(s:HeldItem, s:"TechnicalMod"), 4);
		TMods -= modreq(a, MOD_T);
		TakeInventory(StrParam(s:HeldItem, s:"PowerMod"), 4);
		PMods -= modreq(a, MOD_P);
		TakeInventory(StrParam(s:HeldItem, s:"FirestormMod"), 4);
		FMods -= modreq(a, MOD_F);
		TakeInventory(StrParam(s:HeldItem, s:"SniperMod"), 4);
		SMods -= modreq(a, MOD_S);
		TakeInventory(StrParam(s:HeldItem, s:"NanoMod"), 4);
		NMods -= modreq(a, MOD_N);
		TakeInventory(StrParam(s:HeldItem, s:"ModLimit"), 4);
		// Give new assembled item, preserving any extra mods
		GiveInventory(ResultItem, 1);
		GiveInventory("RLDeselectionFunction", 1);
		GiveInventory("RLMisfireSpamPreventionCooldown", 1);
		GiveInventory("RLRarityTokenRemover", 1);
		// Clear assembly confirmation tokens
		for (int c = 0; c < ASSEMBLIES; c++) {
			TakeInventory(StrParam(s:AssemblyDB[c][ASSEMBLY_RESULT], s:"Confirm"), 1);
		}
		// Apply leftover mods to resulting assembly
		GiveInventory(StrParam(s:ResultItem, s:"AgilityMod"), AMods);
		GiveInventory(StrParam(s:ResultItem, s:"BulkMod"), BMods);
		GiveInventory(StrParam(s:ResultItem, s:"TechnicalMod"), TMods);
		GiveInventory(StrParam(s:ResultItem, s:"PowerMod"), PMods);
		GiveInventory(StrParam(s:ResultItem, s:"FirestormMod"), FMods);
		GiveInventory(StrParam(s:ResultItem, s:"SniperMod"), SMods);
		GiveInventory(StrParam(s:ResultItem, s:"NanoMod"), NMods);
		GiveInventory(StrParam(s:ResultItem, s:"ModLimit"), AMods + BMods + TMods + PMods + FMods + SMods + NMods);
		SetWeapon(ResultItem);
		// Report the result
		str strangemessage = "";
		if (UsedMod == "RLUseArtiMod") {
			strangemessage = "\n\nThe strange sentient mod pack seems satisfied with the\nbizarre addons it somehow put on your weapon.";
		}
		Print(s:"\cv", s:AssemblyDB[a][ASSEMBLY_NAME], s:"\c- assembled.", s:strangemessage);
		// Play a relevant sound effect
		if (modreq(a, ASSEMBLY_SIZE) == 4) {
			if (CheckInventory("RLScavengerPerk")) {
				PlaySound(0, "technician/laugh", CHAN_VOICE);
			}
			PlaySound(0, "weapons/masterassembly", CHAN_ITEM);
			PlaySound(0, "weapons/masterassemblyfanfare", CHAN_AUTO);
		}
		else {
			PlaySound(0, "weapons/assembly", CHAN_ITEM);
		}
	}
}