Quality of life: Spellcasting #536

Merged
NQNStudios merged 21 commits from recast-hint into master 2025-01-23 14:30:08 +00:00
13 changed files with 369 additions and 195 deletions

View File

@@ -3,80 +3,212 @@
<dialog defbtn='cast'>
<pict name='pic' type='dlog' num='12' top='9' left='9'/>
<text size='large' top='6' left='54' width='139' height='18'>Select a Spell:</text>
<button name='caster1' type='regular' def-key='1' top='81' left='10'><key/></button>
<button name='caster2' type='regular' def-key='2' top='105' left='10'><key/></button>
<button name='caster3' type='regular' def-key='3' top='129' left='10'><key/></button>
<button name='caster4' type='regular' def-key='4' top='153' left='10'><key/></button>
<button name='caster5' type='regular' def-key='5' top='177' left='10'><key/></button>
<button name='caster6' type='regular' def-key='6' top='201' left='10'><key/></button>
<button name='target1' type='small' def-key='shift 1' top='82' left='235'><key/></button>
<button name='target2' type='small' def-key='shift 2' top='106' left='235'><key/></button>
<button name='target3' type='small' def-key='shift 3' top='130' left='235'><key/></button>
<button name='target4' type='small' def-key='shift 4' top='154' left='235'><key/></button>
<button name='target5' type='small' def-key='shift 5' top='178' left='235'><key/></button>
<button name='target6' type='small' def-key='shift 6' top='202' left='235'><key/></button>
<button name='cancel' type='regular' def-key='esc' top='394' left='479'>Cancel</button>
<button name='cast' type='regular' top='394' left='549'>Cast</button>
<text name='pc1' top='84' left='88' width='122' height='16'/>
<text name='pc2' top='108' left='88' width='122' height='16'/>
<text name='pc3' top='132' left='88' width='122' height='16'/>
<text name='pc4' top='156' left='88' width='122' height='16'/>
<text name='pc5' top='180' left='88' width='122' height='16'/>
<text name='pc6' top='204' left='88' width='122' height='16'/>
<text name='hp1' top='85' left='265' width='32' height='16'/>
<text name='hp2' top='109' left='265' width='32' height='16'/>
<text name='hp3' top='133' left='265' width='32' height='16'/>
<text name='hp4' top='156' left='265' width='32' height='16'/>
<text name='hp5' top='181' left='265' width='32' height='16'/>
<text name='hp6' top='205' left='265' width='32' height='16'/>
<text name='sp1' top='85' left='304' width='32' height='16'/>
<text name='sp2' top='109' left='304' width='32' height='16'/>
<text name='sp3' top='133' left='304' width='32' height='16'/>
<text name='sp4' top='156' left='304' width='32' height='16'/>
<text name='sp5' top='181' left='304' width='32' height='16'/>
<text name='sp6' top='205' left='304' width='32' height='16'/>
<text name='feedback' framed='true' top='400' left='30' width='186' height='16'>Pick spell to cast.</text>
<led name='spell1' state='off' top='247' left='14'/>
<led name='spell2' state='off' top='261' left='14'/>
<led name='spell3' state='off' top='275' left='14'/>
<led name='spell4' state='off' top='289' left='14'/>
<led name='spell5' state='off' top='303' left='14'/>
<led name='spell6' state='off' top='317' left='14'/>
<led name='spell7' state='off' top='331' left='14'/>
<led name='spell8' state='off' top='345' left='14'/>
<led name='spell9' state='off' top='359' left='14'/>
<led name='spell10' state='off' top='373' left='14'/>
<led name='spell11' state='off' top='247' left='177'/>
<led name='spell12' state='off' top='261' left='177'/>
<led name='spell13' state='off' top='275' left='177'/>
<led name='spell14' state='off' top='289' left='177'/>
<led name='spell15' state='off' top='303' left='177'/>
<led name='spell16' state='off' top='317' left='177'/>
<led name='spell17' state='off' top='331' left='177'/>
<led name='spell18' state='off' top='345' left='177'/>
<led name='spell19' state='off' top='359' left='177'/>
<led name='spell20' state='off' top='373' left='177'/>
<led name='spell21' state='off' top='247' left='339'/>
<led name='spell22' state='off' top='261' left='339'/>
<led name='spell23' state='off' top='275' left='339'/>
<led name='spell24' state='off' top='289' left='339'/>
<led name='spell25' state='off' top='303' left='339'/>
<led name='spell26' state='off' top='317' left='339'/>
<led name='spell27' state='off' top='331' left='339'/>
<led name='spell28' state='off' top='345' left='339'/>
<led name='spell29' state='off' top='359' left='339'/>
<led name='spell30' state='off' top='373' left='339'/>
<led name='spell31' state='off' top='247' left='488'/>
<led name='spell32' state='off' top='261' left='488'/>
<led name='spell33' state='off' top='275' left='488'/>
<led name='spell34' state='off' top='289' left='488'/>
<led name='spell35' state='off' top='303' left='488'/>
<led name='spell36' state='off' top='317' left='488'/>
<led name='spell37' state='off' top='331' left='488'/>
<led name='spell38' state='off' top='345' left='488'/>
<!-- To the left of PC names, buttons to select caster -->
<text name='caster-head' size='large' top='60' left='22' width='75' height='16'>Caster:</text>
<button name='caster1' type='regular' def-key='1' relative='neg pos-in' rel-anchor='prev' top='19' left='12'><key/></button>
<button name='caster2' type='regular' def-key='2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='caster3' type='regular' def-key='3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='caster4' type='regular' def-key='4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='caster5' type='regular' def-key='5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='caster6' type='regular' def-key='6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<!-- PC names -->
<text name='pc-head' size='large' relative='pos-in pos-in' anchor='caster-head' top='0' left='66' width='75' height='16'></text><!-- Just for positioning-->
<text name='pc1' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<text name='pc2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<text name='pc3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<text name='pc4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<text name='pc5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<text name='pc6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='122' height='16'/>
<!-- To the right of PC name, buttons to select target -->
<text name='target-head' size='large' relative='pos-in pos-in' anchor='pc-head' top='0' left='112' width='223' height='16'>Target:</text>
<button name='target1' type='small' def-key='shift 1' relative='pos-in pos-in' rel-anchor='prev' top='19' left='6'><key/></button>
<button name='target2' type='small' def-key='shift 2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='target3' type='small' def-key='shift 3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='target4' type='small' def-key='shift 4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='target5' type='small' def-key='shift 5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<button name='target6' type='small' def-key='shift 6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'><key/></button>
<!-- To the right of target buttons, green arrows to highlight choice -->
<text name='arrow1' relative='neg pos-in' anchor='hp1' top='0' left='20' width='32' height='16' colour='light-green'>-&gt;</text>
<text name='arrow2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-green'>-&gt;</text>
<text name='arrow3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-green'>-&gt;</text>
<text name='arrow4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-green'>-&gt;</text>
<text name='arrow5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-green'>-&gt;</text>
<text name='arrow6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-green'>-&gt;</text>
<!-- To the right of target buttons, PC HP -->
<text name='hp-head' size='large' relative='pos-in pos-in' anchor='target-head' top='0' left='55' width='223' height='16'>HP:</text>
<text name='hp1' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<text name='hp2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<text name='hp3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<text name='hp4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<text name='hp5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<text name='hp6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='red'/>
<!-- To the right of PC HP, PC SP -->
<text name='sp-head' size='large' relative='pos-in pos-in' anchor='hp-head' top='0' left='24' width='223' height='16'>SP:</text>
<text name='sp1' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<text name='sp2' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<text name='sp3' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<text name='sp4' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<text name='sp5' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<text name='sp6' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0' width='32' height='16' colour='light-blue'/>
<!-- To the right of PC SP, Status icons -->
<!-- Whee... time for the status effects! 15 statuses x 6 PCs! -->
<text name='status-head' size='large' relative='pos-in pos-in' anchor='sp-head' top='0' left='24' width='223' height='16'>Status:</text>
<pict name='pc1-stat1' type='status' num='0' relative='pos-in pos-in' anchor='status-head' top='24' left='0'/>
<pict name='pc2-stat1' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat1' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat1' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat1' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat1' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat2' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat1' top='0' left='13'/>
<pict name='pc2-stat2' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat2' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat2' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat2' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat2' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat3' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat2' top='0' left='13'/>
<pict name='pc2-stat3' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat3' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat3' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat3' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat3' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat4' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat3' top='0' left='13'/>
<pict name='pc2-stat4' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat4' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat4' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat4' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat4' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat5' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat4' top='0' left='13'/>
<pict name='pc2-stat5' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat5' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat5' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat5' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat5' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat6' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat5' top='0' left='13'/>
<pict name='pc2-stat6' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat6' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat6' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat6' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat6' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat7' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat6' top='0' left='13'/>
<pict name='pc2-stat7' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat7' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat7' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat7' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat7' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat8' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat7' top='0' left='13'/>
<pict name='pc2-stat8' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat8' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat8' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat8' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat8' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat9' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat8' top='0' left='13'/>
<pict name='pc2-stat9' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat9' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat9' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat9' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat9' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat10' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat9' top='0' left='13'/>
<pict name='pc2-stat10' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat10' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat10' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat10' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat10' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat11' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat10' top='0' left='13'/>
<pict name='pc2-stat11' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat11' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat11' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat11' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat11' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat12' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat11' top='0' left='13'/>
<pict name='pc2-stat12' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat12' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat12' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat12' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat12' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat13' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat12' top='0' left='13'/>
<pict name='pc2-stat13' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat13' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat13' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat13' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat13' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat14' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat13' top='0' left='13'/>
<pict name='pc2-stat14' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat14' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat14' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat14' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat14' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc1-stat15' type='status' num='0' relative='pos-in pos-in' anchor='pc1-stat14' top='0' left='13'/>
<pict name='pc2-stat15' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc3-stat15' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc4-stat15' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc5-stat15' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<pict name='pc6-stat15' type='status' num='0' relative='pos-in pos-in' rel-anchor='prev' top='24' left='0'/>
<!-- Spell columns -->
<text name='col1' top='227' left='10' width='100' height='16'/>
<led name='spell1' state='off' relative='pos-in pos-in' rel-anchor='prev' top='20' left='6'/>
<led name='spell2' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell3' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell4' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell5' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell6' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell7' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell8' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell9' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell10' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<text name='col2' relative='pos-in pos-in' anchor='col1' top='0' left='152' width='100' height='16'/>
<led name='spell11' state='off' relative='pos-in pos-in' rel-anchor='prev' top='20' left='4'/>
<led name='spell12' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell13' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell14' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell15' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell16' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell17' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell18' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell19' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell20' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<text name='col3' relative='pos-in pos-in' anchor='col2' top='0' left='164' width='100' height='16'/>
<led name='spell21' state='off' relative='pos-in pos-in' rel-anchor='prev' top='20' left='4'/>
<led name='spell22' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell23' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell24' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell25' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell26' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell27' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell28' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell29' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell30' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<text name='col4' relative='pos-in pos-in' anchor='col3' top='0' left='160' width='100' height='16'/>
<led name='spell31' state='off' relative='pos-in pos-in' rel-anchor='prev' top='20' left='4'/>
<led name='spell32' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell33' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell34' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell35' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell36' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell37' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<led name='spell38' state='off' relative='pos-in pos-in' rel-anchor='prev' top='14' left='0'/>
<button name='other' type='large' def-key='space' top='394' left='371'>Other Spells</button>
<text size='large' top='60' left='9' width='75' height='16'>Caster:</text>
<text size='large' top='60' left='209' width='223' height='16'>Target: HP: SP: Status:</text>
<!-- Help messages -->
<text top='0' left='202' width='290' height='57'>
Keyboard:
<key ref='caster1'/><key ref='caster2'/><key ref='caster3'/>
@@ -89,63 +221,10 @@
key by spell to cast spell.<br/>
Alt-click spell name for description.
</text>
<text name='feedback' framed='true' top='400' left='30' width='186' height='16'>Pick spell to cast.</text>
<button name='help' type='help' def-key='help' top='6' left='596'/>
<text name='col1' top='227' left='10' width='100' height='16'/>
<text name='col2' top='227' left='162' width='100' height='16'/>
<text name='col3' top='227' left='326' width='100' height='16'/>
<text name='col4' top='227' left='486' width='100' height='16'/>
<!-- Whee... time for the status effects! Fifteen per PC! -->
<pict name='pc1-stat1' type='status' num='0' top='84' left='334'/> <pict name='pc1-stat2' type='status' num='0' top='84' left='347'/>
<pict name='pc1-stat3' type='status' num='0' top='84' left='360'/> <pict name='pc1-stat4' type='status' num='0' top='84' left='373'/>
<pict name='pc1-stat5' type='status' num='0' top='84' left='386'/> <pict name='pc1-stat6' type='status' num='0' top='84' left='399'/>
<pict name='pc1-stat7' type='status' num='0' top='84' left='412'/> <pict name='pc1-stat8' type='status' num='0' top='84' left='425'/>
<pict name='pc1-stat9' type='status' num='0' top='84' left='438'/> <pict name='pc1-stat10' type='status' num='0' top='84' left='451'/>
<pict name='pc1-stat11' type='status' num='0' top='84' left='464'/><pict name='pc1-stat12' type='status' num='0' top='84' left='477'/>
<pict name='pc1-stat13' type='status' num='0' top='84' left='490'/><pict name='pc1-stat14' type='status' num='0' top='84' left='503'/>
<pict name='pc1-stat15' type='status' num='0' top='84' left='516'/>
<pict name='pc2-stat1' type='status' num='0' top='109' left='334'/> <pict name='pc2-stat2' type='status' num='0' top='109' left='347'/>
<pict name='pc2-stat3' type='status' num='0' top='109' left='360'/> <pict name='pc2-stat4' type='status' num='0' top='109' left='373'/>
<pict name='pc2-stat5' type='status' num='0' top='109' left='386'/> <pict name='pc2-stat6' type='status' num='0' top='109' left='399'/>
<pict name='pc2-stat7' type='status' num='0' top='109' left='412'/> <pict name='pc2-stat8' type='status' num='0' top='109' left='425'/>
<pict name='pc2-stat9' type='status' num='0' top='109' left='438'/> <pict name='pc2-stat10' type='status' num='0' top='109' left='451'/>
<pict name='pc2-stat11' type='status' num='0' top='109' left='464'/><pict name='pc2-stat12' type='status' num='0' top='109' left='477'/>
<pict name='pc2-stat13' type='status' num='0' top='109' left='490'/><pict name='pc2-stat14' type='status' num='0' top='109' left='503'/>
<pict name='pc2-stat15' type='status' num='0' top='109' left='516'/>
<pict name='pc3-stat1' type='status' num='0' top='134' left='334'/> <pict name='pc3-stat2' type='status' num='0' top='134' left='347'/>
<pict name='pc3-stat3' type='status' num='0' top='134' left='360'/> <pict name='pc3-stat4' type='status' num='0' top='134' left='373'/>
<pict name='pc3-stat5' type='status' num='0' top='134' left='386'/> <pict name='pc3-stat6' type='status' num='0' top='134' left='399'/>
<pict name='pc3-stat7' type='status' num='0' top='134' left='412'/> <pict name='pc3-stat8' type='status' num='0' top='134' left='425'/>
<pict name='pc3-stat9' type='status' num='0' top='134' left='438'/> <pict name='pc3-stat10' type='status' num='0' top='134' left='451'/>
<pict name='pc3-stat11' type='status' num='0' top='134' left='464'/><pict name='pc3-stat12' type='status' num='0' top='134' left='477'/>
<pict name='pc3-stat13' type='status' num='0' top='134' left='490'/><pict name='pc3-stat14' type='status' num='0' top='134' left='503'/>
<pict name='pc3-stat15' type='status' num='0' top='134' left='516'/>
<pict name='pc4-stat1' type='status' num='0' top='159' left='334'/> <pict name='pc4-stat2' type='status' num='0' top='159' left='347'/>
<pict name='pc4-stat3' type='status' num='0' top='159' left='360'/> <pict name='pc4-stat4' type='status' num='0' top='159' left='373'/>
<pict name='pc4-stat5' type='status' num='0' top='159' left='386'/> <pict name='pc4-stat6' type='status' num='0' top='159' left='399'/>
<pict name='pc4-stat7' type='status' num='0' top='159' left='412'/> <pict name='pc4-stat8' type='status' num='0' top='159' left='425'/>
<pict name='pc4-stat9' type='status' num='0' top='159' left='438'/> <pict name='pc4-stat10' type='status' num='0' top='159' left='451'/>
<pict name='pc4-stat11' type='status' num='0' top='159' left='464'/><pict name='pc4-stat12' type='status' num='0' top='159' left='477'/>
<pict name='pc4-stat13' type='status' num='0' top='159' left='490'/><pict name='pc4-stat14' type='status' num='0' top='159' left='503'/>
<pict name='pc4-stat15' type='status' num='0' top='159' left='516'/>
<pict name='pc5-stat1' type='status' num='0' top='184' left='334'/> <pict name='pc5-stat2' type='status' num='0' top='184' left='347'/>
<pict name='pc5-stat3' type='status' num='0' top='184' left='360'/> <pict name='pc5-stat4' type='status' num='0' top='184' left='373'/>
<pict name='pc5-stat5' type='status' num='0' top='184' left='386'/> <pict name='pc5-stat6' type='status' num='0' top='184' left='399'/>
<pict name='pc5-stat7' type='status' num='0' top='184' left='412'/> <pict name='pc5-stat8' type='status' num='0' top='184' left='425'/>
<pict name='pc5-stat9' type='status' num='0' top='184' left='438'/> <pict name='pc5-stat10' type='status' num='0' top='184' left='451'/>
<pict name='pc5-stat11' type='status' num='0' top='184' left='464'/><pict name='pc5-stat12' type='status' num='0' top='184' left='477'/>
<pict name='pc5-stat13' type='status' num='0' top='184' left='490'/><pict name='pc5-stat14' type='status' num='0' top='184' left='503'/>
<pict name='pc5-stat15' type='status' num='0' top='184' left='516'/>
<pict name='pc6-stat1' type='status' num='0' top='209' left='334'/> <pict name='pc6-stat2' type='status' num='0' top='209' left='347'/>
<pict name='pc6-stat3' type='status' num='0' top='209' left='360'/> <pict name='pc6-stat4' type='status' num='0' top='209' left='373'/>
<pict name='pc6-stat5' type='status' num='0' top='209' left='386'/> <pict name='pc6-stat6' type='status' num='0' top='209' left='399'/>
<pict name='pc6-stat7' type='status' num='0' top='209' left='412'/> <pict name='pc6-stat8' type='status' num='0' top='209' left='425'/>
<pict name='pc6-stat9' type='status' num='0' top='209' left='438'/> <pict name='pc6-stat10' type='status' num='0' top='209' left='451'/>
<pict name='pc6-stat11' type='status' num='0' top='209' left='464'/><pict name='pc6-stat12' type='status' num='0' top='209' left='477'/>
<pict name='pc6-stat13' type='status' num='0' top='209' left='490'/><pict name='pc6-stat14' type='status' num='0' top='209' left='503'/>
<pict name='pc6-stat15' type='status' num='0' top='209' left='516'/>
<!-- Main buttons -->
<button name='cancel' type='regular' def-key='esc' top='394' left='479'>Cancel</button>
<button name='cast' type='regular' top='394' left='549'>Cast</button>
</dialog>

View File

@@ -11,6 +11,7 @@
#include <functional>
#include <sstream>
#include <string>
#include <map>
#include "dialog.hpp"
#include "gfx/tiling.hpp" // for bg
#include "fileio/resmgr/res_dialog.hpp"
@@ -45,6 +46,8 @@ cDialog* cDialog::topWindow = nullptr;
void (*cDialog::redraw_everything)() = nullptr;
std::mt19937 cDialog::ui_rand;
extern std::map<std::string,sf::Color> colour_map;
extern bool check_for_interrupt(std::string);
std::string cDialog::generateRandomString(){
@@ -86,39 +89,9 @@ sf::Color cControl::parseColor(string what){
}
}
clr.r = r, clr.g = g, clr.b = b;
}else if(what == "black")
clr.r = 0x00, clr.g = 0x00, clr.b = 0x00;
else if(what == "red")
clr.r = 0xFF, clr.g = 0x00, clr.b = 0x00;
else if(what == "lime")
clr.r = 0x00, clr.g = 0xFF, clr.b = 0x00;
else if(what == "blue")
clr.r = 0x00, clr.g = 0x00, clr.b = 0xFF;
else if(what == "yellow")
clr.r = 0xFF, clr.g = 0xFF, clr.b = 0x00;
else if(what == "aqua")
clr.r = 0x00, clr.g = 0xFF, clr.b = 0xFF;
else if(what == "fuchsia")
clr.r = 0xFF, clr.g = 0x00, clr.b = 0xFF;
else if(what == "white")
clr.r = 0xFF, clr.g = 0xFF, clr.b = 0xFF;
else if(what == "gray" || what == "grey")
clr.r = 0x80, clr.g = 0x80, clr.b = 0x80;
else if(what == "maroon")
clr.r = 0x80, clr.g = 0x00, clr.b = 0x00;
else if(what == "green")
clr.r = 0x00, clr.g = 0x80, clr.b = 0x00;
else if(what == "navy")
clr.r = 0x00, clr.g = 0x00, clr.b = 0x80;
else if(what == "olive")
clr.r = 0x80, clr.g = 0x80, clr.b = 0x00;
else if(what == "teal")
clr.r = 0x00, clr.g = 0x80, clr.b = 0x80;
else if(what == "purple")
clr.r = 0x80, clr.g = 0x00, clr.b = 0x80;
else if(what == "silver")
clr.r = 0xC0, clr.g = 0xC0, clr.b = 0xC0;
else throw -1;
}else if(colour_map.find(what) != colour_map.end()){
return colour_map[what];
}else throw -1;
return clr;
}

View File

@@ -266,6 +266,14 @@ void handle_spellcast(eSkill which_type, bool& did_something, bool& need_redraw,
short store_sp[6];
extern short spec_target_fail;
extern eSpecCtxType spec_target_type;
// Dual-caster recast hint toggle:
// Change the recast hint to mage if last spell wasn't mage
if(spell_forced && is_combat() && univ.current_pc().last_cast_type != which_type){
spell_forced = false;
univ.current_pc().last_cast_type = which_type;
need_redraw = true;
return;
}
if(!someone_awake()) {
ASB("Everyone's asleep/paralyzed.");
need_reprint = true;
@@ -1850,6 +1858,7 @@ void handle_menu_spell(eSpell spell_picked) {
spell_forced = true;
pc_casting = univ.cur_pc;
univ.current_pc().last_cast[spell_type] = spell_picked;
univ.current_pc().last_cast_type = spell_type;
if(spell_type == eSkill::MAGE_SPELLS)
store_mage = spell_picked;
else store_priest = spell_picked;
@@ -2448,6 +2457,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
// cast multi-target spell, set # targets to 0 so that space clicked doesn't matter
num_targets_left = 0;
handle_target_space(center, did_something, need_redraw, need_reprint);
advance_time(did_something, need_redraw, need_reprint);
} else if(overall_mode == MODE_SPELL_TARGET)
// Rotate a force wall
spell_cast_hit_return();

View File

@@ -611,8 +611,42 @@ void draw_text_bar() {
}
if((is_combat()) && (univ.cur_pc < 6) && !monsters_going) {
std::ostringstream sout;
sout << univ.current_pc().name << " (ap: " << univ.current_pc().ap << ')';
put_text_bar(sout.str());
cPlayer& current_pc = univ.current_pc();
sout << current_pc.name << " (ap: " << current_pc.ap << ')';
// Spellcasters print a hint for recasting.
// There's not enough space to print 2 hints for dual-casters,
// so just handle the last type cast.
eSkill type = current_pc.last_cast_type;
std::string hint_prefix = "";
std::ostringstream hint_out;
switch(type){
case eSkill::MAGE_SPELLS:
hint_prefix = "M";
break;
case eSkill::PRIEST_SPELLS:
hint_prefix = "P";
break;
// The only other expected value is eSkill::INVALID
default:
break;
}
if(!hint_prefix.empty()){
hint_out << hint_prefix << ": ";
if(current_pc.last_cast[type] != eSpell::NONE){
const cSpell& spell = (*current_pc.last_cast[type]);
if(pc_can_cast_spell(current_pc,type) && spell.cost <= current_pc.get_magic()) {
hint_out << "Recast " << spell.name();
}else{
hint_out << "Cannot recast";
}
}else{
hint_out << "No spell to recast";
}
}
put_text_bar(sout.str(), hint_out.str());
}
if((is_combat()) && (monsters_going))
// Print bar for 1st monster with >0 ap - that is monster that is going
@@ -623,7 +657,7 @@ void draw_text_bar() {
}
}
void put_text_bar(std::string str) {
void put_text_bar(std::string str, std::string right_str) {
text_bar_gworld.setActive(false);
auto& bar_gw = *ResMgr::graphics.get("textbar");
rect_draw_some_item(bar_gw, rectangle(bar_gw), text_bar_gworld, rectangle(bar_gw));
@@ -635,9 +669,13 @@ void put_text_bar(std::string str) {
rectangle to_rect = rectangle(text_bar_gworld);
to_rect.top += 7;
to_rect.left += 5;
to_rect.right -= 5;
win_draw_string(text_bar_gworld, to_rect, str, eTextMode::LEFT_TOP, style);
if(!monsters_going) {
// the recast hint will replace status icons:
if(!right_str.empty()){
// Style has to be wrap to get right-alignment
win_draw_string(text_bar_gworld, to_rect, right_str, eTextMode::WRAP, style, true);
}else if(!monsters_going) {
sf::Texture& status_gworld = *ResMgr::graphics.get("staticons");
to_rect.top -= 2;
to_rect.left = to_rect.right - 15;

View File

@@ -31,7 +31,7 @@ void redraw_screen(int refresh);
void put_background();
void draw_text_bar();
void refresh_text_bar();
void put_text_bar(std::string str);
void put_text_bar(std::string str, std::string right_str = "");
void draw_terrain(short mode = 0);
void place_trim(short q,short r,location where,ter_num_t ter_type);
void draw_trim(short q,short r,short which_trim,short which_mode);

View File

@@ -147,7 +147,7 @@ eStatMode stat_screen_mode;
short anim_step = -1;
// Spell casting globals
eSpell store_mage = eSpell::LIGHT, store_priest = eSpell::BLESS_MINOR;
eSpell store_mage = eSpell::NONE, store_priest = eSpell::NONE;
short store_mage_lev = 0, store_priest_lev = 0;
short store_spell_target = 6,pc_casting;
short num_targets_left = 0;

View File

@@ -52,6 +52,11 @@ short combat_percent[20] = {
70,70,67,62,57,52,47,42,40,40};
short who_cast,which_pc_displayed;
// Light can be cast in or out of combat
const eSpell DEFAULT_SELECTED_MAGE = eSpell::LIGHT;
// Bless can only be cast in combat, so separate defaults are needed
const eSpell DEFAULT_SELECTED_PRIEST = eSpell::HEAL_MINOR;
const eSpell DEFAULT_SELECTED_PRIEST_COMBAT = eSpell::BLESS_MINOR;
eSpell town_spell;
extern bool spell_freebie;
extern eSpecCtxType spec_target_type;
@@ -94,6 +99,9 @@ short spell_index[38] = {38,39,40,41,42,43,44,45,90,90,46,47,48,49,50,51,52,53,9
// Says which buttons hit which spells on second spell page, 90 means no button
bool can_choose_caster;
const sf::Color SELECTED_COLOUR = Colours::LIGHT_GREEN;
const sf::Color DISABLED_COLOUR = Colours::GREY;
// Dialog vars
short store_graphic_pc_num ;
short store_graphic_mode ;
@@ -490,6 +498,13 @@ bool repeat_cast_ok(eSkill type) {
what_spell = univ.party[who_would_cast].last_cast[type];
else what_spell = type == eSkill::MAGE_SPELLS ? store_mage : store_priest;
if(what_spell == eSpell::NONE){
std::ostringstream sout;
sout << "Repeat cast: No " << (type == eSkill::MAGE_SPELLS ? "mage" : "priest") << " spell stored.";
add_string_to_buf(sout.str());
return false;
}
if(!pc_can_cast_spell(univ.party[who_would_cast],what_spell)) {
add_string_to_buf("Repeat cast: Can't cast.");
return false;
@@ -1640,8 +1655,8 @@ static void draw_spell_info(cDialog& me, const eSkill store_situation, const sho
}
break;
case SELECT_ANY:
// TODO: Split off party members should probably be excluded too?
if(univ.party[i].main_status != eMainStatus::ABSENT) {
// Absent party members and split-off party members are excluded
if(univ.party[i].main_status != eMainStatus::ABSENT && univ.party[i].main_status < eMainStatus::SPLIT) {
me[id].show();
}
else {
@@ -1691,6 +1706,7 @@ static void draw_spell_pc_info(cDialog& me) {
if(univ.party[i].main_status != eMainStatus::ABSENT) {
me["pc" + n].setText(univ.party[i].name);
me["arrow" + n].hide();
if(univ.party[i].main_status == eMainStatus::ALIVE) {
me["hp" + n].setTextToNum(univ.party[i].cur_health);
me["sp" + n].setTextToNum(univ.party[i].cur_sp);
@@ -1706,7 +1722,7 @@ static void put_pc_caster_buttons(cDialog& me) {
std::string n = boost::lexical_cast<std::string>(i + 1);
if(me["caster" + n].isVisible()) {
if(i == pc_casting)
me["pc" + n].setColour(Colours::RED);
me["pc" + n].setColour(SELECTED_COLOUR);
else me["pc" + n].setColour(me.getDefTextClr());
}
}
@@ -1716,13 +1732,11 @@ static void put_pc_target_buttons(cDialog& me, short& store_last_target_darkened
if(store_spell_target < 6) {
std::string n = boost::lexical_cast<std::string>(store_spell_target + 1);
me["hp" + n].setColour(Colours::RED);
me["sp" + n].setColour(Colours::RED);
me["arrow" + n].show();
}
if((store_last_target_darkened < 6) && (store_last_target_darkened != store_spell_target)) {
std::string n = boost::lexical_cast<std::string>(store_last_target_darkened + 1);
me["hp" + n].setColour(me.getDefTextClr());
me["sp" + n].setColour(me.getDefTextClr());
me["arrow" + n].hide();
}
store_last_target_darkened = store_spell_target;
}
@@ -1740,12 +1754,16 @@ static void put_spell_led_buttons(cDialog& me, const eSkill store_situation,cons
eSpell spell = cSpell::fromNum(store_situation, spell_for_this_button);
if(store_spell == spell_for_this_button) {
led.setState(led_green);
// Text color:
led.setColour(SELECTED_COLOUR);
}
else if(pc_can_cast_spell(univ.party[pc_casting],spell)) {
led.setState(led_red);
led.setColour(me.getDefTextClr());
}
else {
led.setState(led_off);
led.setColour(DISABLED_COLOUR);
}
}
}
@@ -1862,9 +1880,7 @@ static bool pick_spell_select_led(cDialog& me, std::string id, eKeyMod mods, con
me["feedback"].setText(bad_spell);
}
else {
if(store_situation == eSkill::MAGE_SPELLS)
store_spell = (on_which_spell_page == 0) ? item_hit : spell_index[item_hit];
else store_spell = (on_which_spell_page == 0) ? item_hit : spell_index[item_hit];
draw_spell_info(me, store_situation, store_spell);
put_spell_led_buttons(me, store_situation, store_spell);
@@ -1914,6 +1930,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
if(store_situation == eSkill::MAGE_SPELLS && (*picked_spell).need_select == SELECT_NO) {
store_last_cast_mage = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(false);
me.setResult<short>(store_spell);
return true;
@@ -1921,6 +1938,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
if(store_situation == eSkill::PRIEST_SPELLS && (*picked_spell).need_select == SELECT_NO) {
store_last_cast_priest = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(false);
me.setResult<short>(store_spell);
return true;
@@ -1938,6 +1956,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
store_last_cast_mage = pc_casting;
else store_last_cast_priest = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(true);
return true;
}
@@ -1947,7 +1966,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
//short situation; // 0 - out 1 - town 2 - combat
eSpell pick_spell(short pc_num,eSkill type) { // 70 - no spell OW spell num
using namespace std::placeholders;
eSpell store_spell = type == eSkill::MAGE_SPELLS ? store_mage : store_priest;
eSpell default_spell = type == eSkill::MAGE_SPELLS ? store_mage : store_priest;
short former_target = store_spell_target;
short dark = 6;
@@ -1995,29 +2014,38 @@ eSpell pick_spell(short pc_num,eSkill type) { // 70 - no spell OW spell num
// If in combat, make the spell being cast this PCs most recent spell
if(is_combat()) {
if(type == eSkill::MAGE_SPELLS)
store_spell = univ.party[pc_casting].last_cast[eSkill::MAGE_SPELLS];
else store_spell = univ.party[pc_casting].last_cast[eSkill::PRIEST_SPELLS];
default_spell = univ.party[pc_casting].last_cast[eSkill::MAGE_SPELLS];
else{
default_spell = univ.party[pc_casting].last_cast[eSkill::PRIEST_SPELLS];
if(default_spell == eSpell::NONE){
default_spell = DEFAULT_SELECTED_PRIEST_COMBAT;
}
}
}
if(default_spell == eSpell::NONE){
default_spell = type == eSkill::MAGE_SPELLS ? DEFAULT_SELECTED_MAGE : DEFAULT_SELECTED_PRIEST;
}
// Keep the stored spell, if it's still castable
if(!pc_can_cast_spell(univ.party[pc_casting],store_spell)) {
if(!pc_can_cast_spell(univ.party[pc_casting],default_spell)) {
if(type == eSkill::MAGE_SPELLS) {
store_spell = eSpell::LIGHT;
default_spell = DEFAULT_SELECTED_MAGE;
}
else {
store_spell = eSpell::HEAL_MINOR;
default_spell = DEFAULT_SELECTED_PRIEST;
}
}
// If a target is needed, keep the same target if that PC still targetable
if(store_spell_target < 6) {
if((*store_spell).need_select != SELECT_NO) {
if((*default_spell).need_select != SELECT_NO) {
if(univ.party[store_spell_target].main_status != eMainStatus::ALIVE)
store_spell_target = 6;
} else store_spell_target = 6;
}
short former_spell = int(store_spell) % 100;
short former_spell = int(default_spell) % 100;
// Set the spell page, based on starting spell
if(former_spell >= 38) on_which_spell_page = 1;
else on_which_spell_page = 0;
@@ -2042,9 +2070,7 @@ eSpell pick_spell(short pc_num,eSkill type) { // 70 - no spell OW spell num
cLed& led = dynamic_cast<cLed&>(castSpell[id]);
led.attachKey(key);
castSpell.addLabelFor(id, {static_cast<char>(i > 25 ? toupper(key.c) : key.c)}, LABEL_LEFT, 8, true);
if(spell_index[i] == 90){
continue;
}
// All LEDs should get the click handler and set state, because page 2 will hide them if necessary
led.setState((pc_can_cast_spell(univ.party[pc_casting],cSpell::fromNum(type,on_which_spell_page == 0 ? i : spell_index[i])))
? led_red : led_green);
led.attachClickHandler(std::bind(pick_spell_select_led, _1, _2, _3, type, std::ref(dark), std::ref(former_spell)));

View File

@@ -17,6 +17,36 @@
using boost::math::constants::pi;
using pt_idx_t = decltype(((sf::Shape*)nullptr)->getPointCount());
std::map<std::string,sf::Color> colour_map = {
{"white", Colours::WHITE},
{"black", Colours::BLACK},
{"grey", Colours::GREY},
{"gray", Colours::GREY},
{"red", Colours::RED},
{"green", Colours::GREEN},
{"blue", Colours::BLUE},
{"teal", Colours::TEAL},
{"pink", Colours::PINK},
{"yellow", Colours::YELLOW},
{"orange", Colours::ORANGE},
{"light-blue", Colours::LIGHT_BLUE},
{"shadow", Colours::SHADOW},
{"title-blue", Colours::TITLE_BLUE},
{"navy", Colours::NAVY},
{"dark_blue", Colours::DARK_BLUE},
{"dark-green", Colours::DARK_GREEN},
{"light-green", Colours::LIGHT_GREEN},
{"dark-red", Colours::DARK_RED},
// Extra Colors
{"lime", Colours::LIME},
{"aqua", Colours::AQUA},
{"fuchsia", Colours::FUCHSIA},
{"maroon", Colours::MAROON},
{"olive", Colours::OLIVE},
{"purple", Colours::PURPLE},
{"silver", Colours::SILVER}
};
// TODO: Put these classes in a header?
class EllipseShape : public sf::Shape {
float divSz;

View File

@@ -11,6 +11,7 @@
#include <vector>
#include <memory>
#include <map>
#include <SFML/Graphics/Shape.hpp>
#include "location.hpp"
@@ -48,6 +49,7 @@ void undo_clip(sf::RenderTarget& where);
namespace Colours {
const sf::Color WHITE = sf::Color::White;
const sf::Color BLACK = sf::Color::Black;
const sf::Color GREY { 0x80, 0x80, 0x80};
const sf::Color RED { 0xdd, 0x00, 0x00};
const sf::Color GREEN { 0x00, 0x88, 0x00};
const sf::Color BLUE { 0x00, 0x00, 0xdd};
@@ -55,6 +57,7 @@ namespace Colours {
const sf::Color PINK { 0xff, 0x00, 0x99};
const sf::Color YELLOW { 0xff, 0xff, 0x31};
const sf::Color ORANGE { 0xff, 0x80, 0x00};
const sf::Color LIGHT_BLUE { 0xad, 0xd8, 0xe6 }; // Spell points on dark background
// Text colours for shopping / talking
// TODO: The Windows version appears to use completely different colours?
const sf::Color SHADOW { 0x00, 0x00, 0x68}; // formerly c[3] QD colour = {0,0,26623} (shop/character name shadow, shop subtitle)
@@ -64,6 +67,14 @@ namespace Colours {
const sf::Color DARK_GREEN { 0x00, 0x60, 0x00}; // formerly c[5] QD colour = {0,40959,0} (talking buttons)
const sf::Color LIGHT_GREEN { 0x00, 0xa0, 0x00}; // formerly c[6] QD colour = {0,24575,0} (talking buttons pressed)
const sf::Color DARK_RED { 0xa0, 0x00, 0x14}; // formerly c[7] (clickable text, new in OBoE)
// Extra colors
const sf::Color LIME { 0x00, 0xFF, 0x00};
const sf::Color AQUA { 0x00, 0xFF, 0xFF};
const sf::Color FUCHSIA { 0xFF, 0x00, 0xFF};
const sf::Color MAROON { 0x80, 0x00, 0x00};
const sf::Color OLIVE { 0x80, 0x80, 0x00};
const sf::Color PURPLE { 0x80, 0x00, 0x80};
const sf::Color SILVER { 0xC0, 0xC0, 0xC0};
}
const sf::Color PRESET_WORD_ON = Colours::DARK_GREEN;

View File

@@ -149,7 +149,7 @@ static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,st
short total_width = str_to_draw.getLocalBounds().width;
eTextMode mode = options.mode;
if(mode == eTextMode::WRAP && total_width < dest_rect.width())
if(mode == eTextMode::WRAP && total_width < dest_rect.width() && !options.right_align)
mode = eTextMode::LEFT_TOP;
if(mode == eTextMode::LEFT_TOP && str.find('|') != std::string::npos)
mode = eTextMode::WRAP;

View File

@@ -92,6 +92,10 @@ eSpell cSpell::fromNum(int num) {
return check;
}
// NOTE:
// asPeaceful() marks a spell as castable by pacifist PCs. It doesn't mean "only in peace mode"
// (which would make a lot of these contradictory/broken)
// Mage Spells
cSpell M_LIGHT = cSpell(eSpell::LIGHT).asType(eSkill::MAGE_SPELLS).asLevel(1)
.withCost(1).when(WHEN_COMBAT).when(WHEN_TOWN).when(WHEN_OUTDOORS).asPeaceful().finish();
@@ -211,7 +215,7 @@ cSpell M_FLIGHT = cSpell(eSpell::FLIGHT).asType(eSkill::MAGE_SPELLS).asLevel(6)
cSpell M_SHOCKWAVE = cSpell(eSpell::SHOCKWAVE).asType(eSkill::MAGE_SPELLS).asLevel(7)
.withCost(12).withRefer(REFER_IMMED).when(WHEN_COMBAT).finish();
cSpell M_BLESS_MAJOR = cSpell(eSpell::BLESS_MAJOR).asType(eSkill::MAGE_SPELLS).asLevel(7)
.withCost(8).withRefer(REFER_IMMED).when(WHEN_COMBAT).when(WHEN_TOWN).asPeaceful().finish();
.withCost(8).withRefer(REFER_IMMED).when(WHEN_COMBAT).asPeaceful().finish();
cSpell M_PARALYSIS_MASS = cSpell(eSpell::PARALYSIS_MASS).asType(eSkill::MAGE_SPELLS).asLevel(7)
.withRange(8).withCost(20).withRefer(REFER_IMMED).when(WHEN_COMBAT).finish();
cSpell M_PROTECTION = cSpell(eSpell::PROTECTION).asType(eSkill::MAGE_SPELLS).asLevel(7)

View File

@@ -105,7 +105,10 @@ public:
eRace race;
long unique_id;
// transient stuff
std::map<eSkill,eSpell> last_cast;
std::map<eSkill,eSpell> last_cast = {{ eSkill::MAGE_SPELLS, eSpell::NONE}, { eSkill::PRIEST_SPELLS, eSpell::NONE }};
// There is already a global last_spellcast_type, but that variable is for the whole party.
// This one is per-PC
eSkill last_cast_type = eSkill::INVALID;
location combat_pos;
short parry = 0;
iLiving* last_attacked = nullptr; // Note: Currently this is assigned but never read

View File

@@ -258,7 +258,7 @@ TEST_CASE("Construction sanity test for player character") {
CHECK(pc.traits.empty());
CHECK(pc.race == eRace::HUMAN);
// Skip unique_id since it's non-deterministic
CHECK(pc.last_cast.empty());
CHECK(pc.last_cast.size() == 2);
CHECK(pc.combat_pos == loc(-1,-1));
CHECK(pc.parry == 0);
CHECK(pc.last_attacked == nullptr);