Quantcast
Channel: Modding — Beamdog Forums
Viewing all articles
Browse latest Browse all 11774

Restricting Specialist's extra Spell Slots to Specialist's School Spells

$
0
0
This mod aims to implement proper spell slot restrictions for Specialist mages, forcing them to choose a spell from their school for their bonus spell slots.

Weidu should be able to install it so long as the section dealing with the Mage Spellbook hasn't already been altered. It uses REPLACE_TEXTUALLY for all its changes, if there is a better way I am open to suggestions.

The marker effects for this are applied to specialists at level 1 through the CLAB, so games already in progress will require force-casting a spell on existing specialists through the console. This marker effect will remain if the mod is uninstalled, but does nothing by itself and will not affect gameplay otherwise. This marker is a dummy sequencer, so the Sequencer Active portrait Icon will always be in effect, and it will show up as a blank line in the active Contingencies list.
It needs to be installed after any mods that add or alter Mage spells or creatures with specialist kits, so they can receive proper recognition.

ConsoleCast:
C:Eval("ActionOverride(Myself,ReallyForceSpellRES(\"MSCHOOL\",Msyelf))")
Only the 8 specialist mage kits will receive the marker, it will have no affect on others, including Wildmages and Mod-added kits. This effect will stack if used multiple times on the same creature.

Two install modes, each with option for 1 or 2 spell slot devotion:
- First option restricts slots even if none of a given school/level exist in game.
- Second does not restrict slots for a given school/level if none exist. This will give free spell selection for Schools(levels): Illusion(9), Transmutation(5, 8), Divination(7-9), and Enchantment(6-9) without modded added/altered spells.

Two optional components:
- First causes the extra spells slots from Edwin's Amulet to be treated the same way, requiring Conjuration Spells be put in them. The effect added to the Amulet can be added to anything, using "MSCHOOL#" as the resource, where # is the Spell School(as assigned to spells), forcing an extra slot of every spell level to go to that spell school.
- Second causes items that double spell slots(Evermemory) to also double forced specialist school slots.

Specialist School spells and slots are identified by colored background, specific to each school border:




Manual Editing UI.Menu:
Comment out "INCLUDE ~%MOD_FOLDER%\UIMENU.tpa~" in the "SPECIALIST_BOOK.tp2" file, its the last line.
Replace these three functions:

function magePageInfo()
	if bookMode == 0 then -- Regular
		if characters[id].hasSorcererBook then
			return t("SPELLS_CAN_CAST_LABEL") .. ": " .. characters[id].mageDetails[currentSpellLevel].slotsRemaining .. "/" .. characters[id].mageDetails[currentSpellLevel].maxMemorized
		else
						local num = 0
			for k, v in pairs(specialistSlot) do
				if v.resref ~= "NULL" then
					num = num + 1
				end
			end
			num = num + #bottomSpells
			return t("MEMORIZED_LABEL") .. ": " .. num .. "/" .. characters[id].mageDetails[currentSpellLevel].maxMemorized
		end
	elseif bookMode == 1 then -- Sequencer/Contingency
		return t("SPELLS_LABEL") .. " :" .. #bottomSpells .. "/" .. #bottomSpellsPlaceHolder

	end
	return ""
end

function refreshMageBook()
	if currentSpellLevel == nil then
		currentSpellLevel = 1
	end
	if bookMode == 0 then
		if characters[id].hasMageBook then
			bookSpells = characters[id].mageSpells[currentSpellLevel]
			newBottomSpells = filterMemorizedMageSpells()

			if showMageMemorizationFlash == true then
				createMageMemorizationSparkle(0,0,36,36,"memorizedListMage", findFirstDifferenceInSpellList(bottomSpells, newBottomSpells))
				showMageMemorizationFlash = false
			end
			bottomSpells = newBottomSpells
			getSpecialistSlot()
			local x,y,w,z = Infinity_GetArea('memorizedListMage')	h = x - 72	newX = #specialistSlot * 36 - h
			adjustItemGroup({'memorizedListMage', 'spellframeMageList', },newX,0,0,0)
			bottomSpellsPlaceHolder = makeBlankTable(characters[id].mageDetails[currentSpellLevel].maxMemorized)
			for index = 1, #currentSchool[currentSpellLevel], 1 do
				table.remove (bottomSpellsPlaceHolder, 1)
			end
		else
			bookSpells = characters[id].mageSpells[currentSpellLevel]
			bottomSpells = {}
			bottomSpellsPlaceHolder = {}
		end
	elseif bookMode == 1 then
		bookSpells = filterContingencyMageSpells()
		bottomSpells = sequencerSpells
		bottomSpellsPlaceHolder = makeBlankTable(contingencyMaxSpells)
		contingencyDescription = mageBookStrings[contingencyResRef].tip
	end
end

function setMageBookLevel(num)
	currentBookSpell = 0
	currentSpellLevel = num
		specialistBookFilter()
	mageScreen:SetSpellLevel(num-1)
	refreshMageBook()
end

and all of menu 'MAGE':

menu
{
	name 'MAGE'
	align center center
	greyscale lua "mageBookEnabled == false"
	modal lua "bookMode == 1"
	onopen "
		showMageMemorizationFlash = false
		mgpage = nil
		setMageBookLevel(1)
		if showContingency then
			Infinity_SetArea('bookListMage', nil, 374, nil, 200)
			Infinity_SetArea('bookDescription', nil, 374, nil, 200)
		else
			Infinity_SetArea('bookListMage', nil, 174, nil, 400)
			Infinity_SetArea('bookDescription', nil, 174, nil, 400)
		end
		if bookMode == 1 then
			contingencyDescription = mageBookStrings[contingencyResRef].tip
		end
		currentContingencyCondition = 0
		currentContingencyTarget = 0
		currentAnimationID = 1
		updateCounterMemorizationSparkles = 1
		"
	onclose "
	"
	button
	{
		enabled 	"CurrentlyInGame()"
		on escape
		action
		"
			--Return to world screen on escape
			e:SelectEngine(worldScreen)
		"
	}
	template
	{
		label
		{
			enabled "showMemorizationSparkle(instanceId)"
			ignoreEvents
			area 0 0 45 42
			bam "FLASHBR"
			usealpha lua "true"
			frame lua "memorizationFlashes[instanceId][2]"
			align center center
		}
		name "TEMPLATE_mageMemorizationSparkle"
	}
	label
	{
		area 0 0 864 710
		mosaic "GUIMGB2"
	}
	label
	{
		area		82 10 700 44
		text lua	"mageBookTitle()"
		text style	"title"
	}
	label
	{
		area 		210 59 446 30
		text lua	"mageBookAction()"
		text style	"label"
	}
	button
	{
		area		168 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	0
		enabled		"maxMagePage > 0"
		action		"setMageBookLevel(1)"
	}
	button
	{
		area		227 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	1
		enabled		"maxMagePage > 1"
		action		"setMageBookLevel(2)"
	}
	button
	{
		area		286 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	2
		enabled		"maxMagePage > 2"
		action		"setMageBookLevel(3)"
	}
	button
	{
		area		345 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	3
		enabled		"maxMagePage > 3"
		action		"setMageBookLevel(4)"
	}
	button
	{
		area		404 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	4
		enabled		"maxMagePage > 4"
		action		"setMageBookLevel(5)"
	}
	button
	{
		area		464 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	5
		enabled		"maxMagePage > 5"
		action		"setMageBookLevel(6)"
	}
	button
	{
		area		523 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	6
		enabled		"maxMagePage > 6"
		action		"setMageBookLevel(7)"
	}
	button
	{
		area		583 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	7
		enabled		"maxMagePage > 7"
		action		"setMageBookLevel(8)"
	}
	button
	{
		area		644 110 54 54
		bam		GUIPRTC
		highlightgroup	mgpage
		sequence	8
		enabled		"maxMagePage > 8"
		action		"setMageBookLevel(9)"
	}
	list
	{
		column
		{
			width 15
			label
			{
				area	0 0 -1 -1
				bam	lua "bookSpells[rowNumber].icon"
				enabled "specialistIcon(0)"
				align	center center
			}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('1')"	progressbar 100	progressbar full 0 63 0 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('2')"	progressbar 100	progressbar full 31 0 63 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('3')"	progressbar 100	progressbar full 0 0 0 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('4')"	progressbar 100	progressbar full 63 63 0 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('5')"	progressbar 100	progressbar full 63 0 63 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('6')"	progressbar 100	progressbar full 63 0 0 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('7')"	progressbar 100	progressbar full 0 63 63 0	align	center center	}
			label	{	area	2 2 36 36	icon lua "bookSpells[rowNumber].icon"	greyscale lua "bookSpells[rowNumber].castable == 0"
				enabled "specialistIcon('8')"	progressbar 100	progressbar full 0 0 127 0	align	center center	}
		}
		column
		{
			width 85
			label
			{
				area		0 0 -1 -1
				text lua "Infinity_FetchString( bookSpells[rowNumber].name)"
				text style "normal_parchment"
				text align left center
			}
		}
		area 94 174 316 400
		name 		"bookListMage"
		rowheight	40
		table		"bookSpells"
		var		currentBookSpell
		scrollbar	'GUISCRC'
		action
		"
			contingencyDescription = 0
			if cellNumber == 1 then
				if bookMode == 0 then
					if #bottomSpells < #bottomSpellsPlaceHolder or SpecialistMemorize() then
						createMageMemorizationSparkle(1, 0, 40, 40, 'bookListMage', -1)
						Infinity_PlaySound('GAM_24')
						showMageMemorizationFlash = true

					mageScreen:MemorizeSpell( bookSpells[currentBookSpell].level, bookSpells[currentBookSpell].index )
				end
				elseif bookMode == 1 and #bottomSpells < #bottomSpellsPlaceHolder then
					mageScreen:SequenceSpell( bookSpells[currentBookSpell].resref )
				end
			end
			if lastCurrentBookSpell == currentBookSpell and cellNumber == 2 then
				currentBookSpell = 0
				contingencyDescription = mageBookStrings[contingencyResRef].tip
			end
			lastCurrentBookSpell = currentBookSpell
		"
		actionalt
		"
			if cellNumber == 1 and bookMode == 0 and characters[id].hasSorcererBook == false then
				popup2Button(24485, 'REMOVE_BUTTON', function() mageScreen:EraseKnownSpell(bookSpells[currentBookSpell].resref) end)
			end
		"
	}
	label
	{
		area 100 178 314 192
		rectangle 1
		rectangle opacity 200
		enabled "showContingency"
	}
	label
	{
		area 104 182 310 48
		enabled "showContingency"
		text "CONDITION_NORMAL"
		text style "normal"
	}
	list
	{
		column
		{
			width 100
			label
			{
				area		10 0 -1 -1
				text lua "Infinity_FetchString( contingencyConditions[rowNumber].strref)"
				text style "normal"
				text align left center
			}
		}
		area 104 224 310 141
		enabled 	"showContingency"
		rowheight	40
		table		"contingencyConditions"
		var		currentContingencyCondition
		scrollbar	'GUISCRC'
		action
		"
			contingencyDescription = contingencyConditions[currentContingencyCondition].desc
		"
	}
	label
	{
		area 452 176 322 193
		rectangle 1
		rectangle opacity 200
		enabled "showContingency"
	}
	label
	{
		area 464 176 310 48
		enabled "showContingency"
		text "TARGET_NORMAL"
		text style "normal"
	}
	list
	{
		column
		{
			width 100
			label
			{
				area		10 0 -1 -1
				text lua "Infinity_FetchString( contingencyTargets[rowNumber].strref)"
				text style "normal"
				text align left center
			}
		}
		area 458 228 316 141
		enabled 	"showContingency"
		rowheight	40
		table		"contingencyTargets"
		var		currentContingencyTarget
		scrollbar	'GUISCRC'
		action
		"
			contingencyDescription = contingencyTargets[currentContingencyTarget].desc
		"
	}
	text
	{
		name		"bookDescription"
		area		452 174 316 400
		text lua 	"mageBookDescription()"
		text style	"normal_parchment"
		scrollbar	'GUISCRC'
	}

	list
	{
		column
		{
			width 100
			label
			{
				area	0 0 -1 -1
				bam	"SPELFRMS"
				sequence 0
				align	center center
			}
		}
		area 72 658 714 36

			name "spellframeMageList"
			enabled "#bottomSpellsPlaceHolder ~= 0 or bookMode == 1"
		rowwidth	36
		table		"bottomSpellsPlaceHolder"
	}
	list
	{
		column
		{
			width 100
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '1')"	progressbar 100	progressbar full 0 63 0 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '2')"	progressbar 100	progressbar full 31 0 63 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '3')"	progressbar 100	progressbar full 0 0 0 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '4')"	progressbar 100	progressbar full 63 63 0 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '5')"	progressbar 100	progressbar full 63 0 63 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '6')"	progressbar 100	progressbar full 63 0 0 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '7')"	progressbar 100	progressbar full 0 63 63 0	align	center center	}
			label	{	area	0 0 -1 -1	enabled "isSpecialist(rowNumber, '8')"	progressbar 100	progressbar full 0 0 127 0	align	center center	}
		}
		name "specframeListMage"
		area 72 658 714 36
		rowwidth	36
		table		"specialistSlot"
		enabled "not isSpecialist(0, 0) and characters[id].mageDetails[currentSpellLevel].maxMemorized > 0"
	}
	list
	{
		column
		{
			width 100
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '1')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '2')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '3')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '4')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '5')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '6')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '7')"	align	center center	}
			button	{	area	0 0 -1 -1	bam lua "specialistSlot[rowNumber].icon"	greyscale lua "specialistSlot[rowNumber].castable == 0"	enabled "isSpecialist(rowNumber, '8')"	align	center center	}
		}
		name "specialistListMage"
		area 72 658 714 36
		enabled "not isSpecialist(0, 0) and characters[id].mageDetails[currentSpellLevel].maxMemorized > 0"
		rowwidth	36
		table		"specialistSlot"
		var		currentBottomSpell
		clickable lua	"specialistSlot[rowNumber].resref ~= 'NULL'"
		action	"actionSpecMemorize(currentBottomSpell)"
	}
	list
	{
		column
		{
			width 100
			label
			{
				area	0 0 -1 -1
				bam	lua "bottomSpells[rowNumber].icon"
				align	center center
				greyscale lua "bottomSpells[rowNumber].castable == 0"
			}
		}
		area 72 658 718 36
		name 		"memorizedListMage"
		enabled 	"#bottomSpells ~= 0"
		rowwidth	36
		table		"bottomSpells"
		var		currentBottomSpell
		action
		"
			if bookMode == 0 then
				showMageMemorizationFlash = false
				mageScreen:UnmemorizeSpell( bottomSpells[currentBottomSpell].level, bottomSpells[currentBottomSpell].memorizedIndex )
				Infinity_PlaySound('GAM_44')
			elseif bookMode == 1 then
				mageScreen:UnSequenceSpell( bottomSpells[currentBottomSpell].resref )
				table.remove(sequencerSpells, currentBottomSpell)
				bottomSpells = sequencerSpells
				currentBottomSpell = 0
			end
		"
	}
	label
	{
		area 282 594 300 40
		text lua "magePageInfo()"
		text style "label"
		rectangle 0
	}
	button
	{
		area 582 594 230 44
		enabled "bookMode == 0 and (#characters[id].contingencySpells > 0 or #characters[id].sequencerSpells > 0)"
		bam GUIBUTMT
		text "CONTINGENCY_BUTTON"
		text style "button"
		action "Infinity_PushMenu('MAGE_CONTINGENCY')"

	}
	button
	{
		area 52 594 230 44
		bam GUIBUTMT
		enabled "bookMode == 1 or characters[id].hasMageBook"
		clickable lua "SpecialistMemorize() and currentBookSpell ~= 0"
		text "MEMORIZE_BUTTON"
		text style "button"
		action
		"
			if bookMode == 0 then
				createMageMemorizationSparkle(1, 0, 40, 40, 'bookListMage', -1)
				showMageMemorizationFlash = true
				mageScreen:MemorizeSpell( characters[id].mageSpells[currentSpellLevel][currentBookSpell].level, characters[id].mageSpells[currentSpellLevel][currentBookSpell].index )
			elseif bookMode == 1 then
				mageScreen:SequenceSpell( bookSpells[currentBookSpell].resref )
			end
		"
	}
	button
	{
		area 582 594 230 44
		enabled "bookMode == 1"
		bam GUIBUTMT
		text lua "contingencyDoneButtonText()"
		text style "button"
		action
		"
			if contingencyComplete() then
				mageScreen:DoneSequencingSpells()
			else
				mageScreen:CancelSequencingSpells()
			end
			e:SelectEngine(worldScreen)
		"
	}
}

Replaced initial version with colored version.
Added option to exclude empty spell levels.
Fixed an issue updating CLAB's.

Viewing all articles
Browse latest Browse all 11774

Trending Articles