1: #!/usr/bin/perl
  2: $debug=0;
  3: $EDdir= "/home/xethair/RolePlaying/Earthdawn";
  4: require "/home/xethair/RolePlaying/SGML/Transform/Earthdawn/shared.pl";

  6: sub Context_None {
  7:     local($gi,$start) = @_;

  9:     if ($gi eq 'CHAR') {
 10:         if ($start) {
 11:             ContextOpen('Character');
 12:         } else {
 13:             print "\n</TABLE>\n</body><\html>\n";
 14:             ContextClose();
 15:         }

 17:     } else {
 18:         Context_Any($gi,$start);
 19:     }
 20: }

 22: sub Context_Character {
 23:     local($gi,$start) = @_;

 25:     if ($gi eq 'GENINFO') {
 26:         if ($start) {
 27:             $suppress=1;
 28:             AddHandler('assoc_store');
 29:             ContextOpen('GeneralInfo');
 30:             $artsncnt = 0;
 31:         } else {
 32:             $charname = $datarray{'NAME'};
 33:             $jname = $charname;
 34:             $jname =~ s/^\s*(\S+)(\s.*)?$/$1/;
 35:             NormalizeFileName($jname);
 36:             $jlink = "../Journals/" . $jname . ".html";
 37:             $jfile = $EDdir."/html/Journals/".$jname.".html";
 38:             $rinsert = "<TD width=10%></TD>";
 39:             $linsert = "<TD width=10%></TD>";
 40:             
 41:             if (-f $jfile) {
 42:                 $rinsert = "<TD width=10%><A HREF=\"$jlink\"><EM>Journal Available</EM></A></TD>"
 43:             }
 44:             print "
 45: <html>
 46: <head>
 47: <title>$datarray{'NAME'}</title>
 48: </head>
 49: <body background=\"../graphics/firering.gif\">
 50: <TABLE WIDTH=100% BORDER=1><TR>
 51: <TR><TD  align=center colspan=3>
 52:     <TABLE width=100% border=0>
 53:     <TR>
 54:       $linsert
 55:       <TD align=center><H1>$datarray{'NAME'}</H1></TD>
 56:       $rinsert
 57:     </TABLE>
 58: </TD>
 59: <TR>
 60:   <TD VALIGN=TOP><TABLE WIDTH=100% CELLSPACING=1 BORDER=1>
 61:     <TR><TD align=center colspan=4>
 62:            General Info
 63:     <TR><TD align=right>
 64:            Player   </TD>
 65:         <TD align=left colspan=3>
 66:              $datarray{'PLAYER'}</TD>
 67:     <TR><TD align=right>
 68:            Race     </TD>
 69:         <TD align=left>
 70:              $datarray{'RACE'}</TD>
 71:         <TD align=right>
 72:            Sex      </TD>
 73:         <TD align=left>
 74:              $datarray{'SEX'}</TD>
 75:     <TR><TD align=right>
 76:            Weight   </TD>
 77:         <TD align=left>
 78:              $datarray{'WEIGHT'}</TD>
 79:         <TD align=right>
 80:            Height   </TD>
 81:         <TD align=left>
 82:              $datarray{'HEIGHT'}</TD>
 83:     <TR><TD align=right>
 84:            Eyes     </TD>
 85:         <TD align=left>
 86:              $datarray{'EYES'}</TD>
 87:         <TD align=right>
 88:            Age      </TD>
 89:         <TD align=left>
 90:              $datarray{'AGE'}</TD>
 91:     <TR><TD align=right>
 92:            Hair </TD>
 93:         <TD align=left>
 94:              $datarray{'HAIR'}</TD>
 95:         <TD align=right>
 96:            Skin     </TD>
 97:         <TD align=left>
 98:              $datarray{'SKIN'}</TD>
 99:         
100:     <TR><TD align=left colspan=3>  Discipline</TD><TD align=center>Circle</TD>
101: ";
102:             foreach $discip (keys %disciplines) {
103:                 print "
104:     <TR><TD align=center colspan=3> $discip </TD>
105:         <TD align=center> $disciplines{$discip} </TD>
106: ";
107:             }
108:             print "\n </TABLE></TD>\n";        
109:             $suppress = 0;
110:             undef %datarray;
111:             undef %disciplines;
112:             DelHandler();
113:             ContextClose();
114:         }

116:     } elsif ($gi eq 'SPECINFO') {
117:         if ($start) {
118:             ContextOpen('SpecificInfo');
119:         } else {
120:             ContextClose();
121:         }

123:     } elsif ($gi eq 'THREADS') {
124:         if ($start) {
125:             print "<TR><TD COLSPAN=3><TABLE WIDTH=100% BORDER=1>\n";
126:             print "<TR><TD>Rank</TD><TD>Target</TD><TD>Effects</TD></TR>\n";
127:             ContextOpen('Threads');
128:             AddHandler('assoc_store');
129:         } else {
130:             print "</TABLE></TD></TR>\n";
131:             undef %datarray;
132:             DelHandler();
133:             ContextClose();
134:         }
135:   
136:     } elsif ($gi eq 'LEGEND') {
137:         if ($start) {
138:             ContextOpen('LegendPoints');
139:         } else {
140:             ContextClose();
141:         }

143:     } elsif ($gi eq 'EXTRA') {
144:         if ($start) {
145:             $datalabel = $gi;
146:             print "<TR><TD colspan=3><H3 align=center>Additional (Mechanics) Information</H3>\n";
147:         } else {
148:             undef $datalabel;
149:             print "</TD></TR>\n";
150:         }
151:     } elsif ($gi eq 'EQUIPMNT') {
152:         if ($start) {
153:             @eqentries = ();
154:             $suppress=1;
155:             AddHandler('assoc_store');
156:             ContextOpen('Equipment');
157:         } else {
158:             $numcols = 2;
159:             $numents = $#eqentries+1;
160:             $numrows = ($numents+$numcols-($numents % $numcols)) / $numcols;
161:             print "<TR><TD colspan=3><TABLE WIDTH=100% BORDER=0 cellspacing=0>\n";
162:             print "  <TR><TD colspan=2 ALIGN=CENTER>Equipment</TD>\n  </TR><TR>"; 
163:             for ($r=0; $r < $numents; $r++) {
164:                 print "    <TD valign=top><TABLE WIDTH=100% BORDER=1>\n"
165:                     if ($r % $numrows == 0);
166:                 print "      <TR>$eqentries[$r]\n"; 
167:                 print "    </TABLE></TD>\n" if (($r+1) % $numrows == 0);
168:             }
169:             print "    </TABLE></TD>\n" unless ($r % $numrows == 0);
170:             print "  </TABLE></TD>\n</TR>\n";
171:             undef $suppress;
172:             undef %datarray;
173:             DelHandler();
174:             ContextClose();
175:         }

177:     } elsif ($gi eq 'DETAIL') {
178:         if ($start) {
179:             ContextOpen('Detailing');
180:         } else {
181:             ContextClose();
182:         }

184:     } else {
185:         Context_Any($gi,$start);
186:     }
187: }

189: sub Context_GeneralInfo {
190:     local($gi,$start) = @_;

192:     if ($gi=~/^(NAME|PLAYER|SEX|AGE|HEIGHT|WEIGHT|SKIN|HAIR|EYES)$/) {
193:         if ($start) {
194:             $datalabel = $gi;
195:         } else {
196:             undef $datalabel;
197:         }
198:     } elsif ($gi eq 'DISCIPS') {
199:         if ($start) {
200:             undef(%disciplines);
201:         } else {
202:             undef $datalabel;
203:         }
204:     } elsif ($gi eq 'DISCIP') {
205:         if ($start) {
206:             $datalabel = $gi;
207:         } else {
208:             $disciplines{$datarray{$datalabel}}=$attribute_value{$level,'CIRCLE'};
209:             undef $datalabel;
210:         }
211:     } elsif ($gi eq 'PHYSCHAR') {
212:     } elsif ($gi eq 'RACE') {
213:         if ($start) {
214:             $datalabel = $gi;
215:         } else {
216:             local($race,$racefile,$raceinfo);
217:             $race = $datarray{'RACE'};
218:             NormalizeFileName($race);
219:             $racefile = $EDdir."/Races/".$race.".sgm";
220:             if (-f $racefile) {
221:                 open(RACEINFO,"nsgmls $racefile | $meta/../parse.pl $meta/../extract.pl name.dex.str.tou.per.wil.cha.max.cost.step /0@,@/1@,@/2@,@/3@,@/4@,@/5@,@/6@,@/7@,@/8@,@/9 |");
222:                 $raceinfo .= <RACEINFO>;
223:                 close RACEINFO;
224:                 #warn "Learned '$raceinfo' ";
225:                 ($datarray{'RACE'},$raceadj{'Dexterity'},$raceadj{'Strength'},
226:                  $raceadj{'Toughness'},$raceadj{'Perception'},
227:                  $raceadj{'Willpower'},$raceadj{'Charisma'},$kinfo{'MAX'},
228:                  $kinfo{'COST'},$kinfo{'STEP'}) = split(/@,@/,$raceinfo);
229:             }
230:         }
231:     } else {
232:         Context_Any($gi,$start);
233:     }
234: }

236: sub Context_SpecificInfo {
237:     local($gi,$start) = @_;

239:     if ($gi eq 'ATTRIBS') {
240:         if ($start) {
241:             $suppress=1;
242:             AddHandler('assoc_store');
243:             $datalabel = $gi;
244:             ContextOpen('Attributes','ATTRIBS');
245:         } else {
246:             undef $datalabel;
247:             print "
248:   <TD VALIGN=TOP><TABLE WIDTH=100% CELLSPACING=1 BORDER=1>
249:     <TR><TD align=center colspan=4>
250:               Attributes</TD>
251:     <TR><TD align=left> Physical</TD><TD>Value</TD><TD>Step</TD><TD>Dice</TD>
252: ";
253:             foreach $attr ('Dexterity','Strength','Toughness') {
254:                 print "    <TR><TD align=right>   $attr";
255:                 print "<SUP>$attr{'INC',$attr}</SUP>"
256:                     if (defined $attr{'INC',$attr}); 
257:                 $step = AttributeStepConvert($attr{'VAL',$attr});
258:                 print "</TD>  <TD> $attr{'VAL',$attr} </TD>\n";
259:                 print "        <TD>$step</TD><TD>" . StepDice($step) . "</TD>";
260:             }
261:             
262:             print "
263:     <TR><TD align=left> Mental</TD>
264: ";
265:             foreach $attr ('Perception','Willpower','Charisma') {
266:                 print "    <TR><TD align=right>   $attr";
267:                 print "<SUP>$attr{'INC',$attr}</SUP>"
268:                     if (defined $attr{'INC',$attr}); 
269:                 $step = $attribstep{$attr};
270:                 print "</TD>  <TD> $attr{'VAL',$attr} </TD>\n";
271:                 print "        <TD>$step</TD><TD>" . StepDice($step) . "</TD>";
272:             }
273:             print "\n  </TABLE></TD>\n ";
274:             undef $suppress;
275:             undef %datarray;
276:             undef %attr; undef $attr;
277:             DelHandler();
278:             ContextClose();
279:         }
280:     } elsif ($gi eq 'STATS') {
281:         if ($start) {
282:             $suppress=1;
283:             AddHandler('assoc_store');
284:             ContextOpen('Statistics','STATS');
285:         } else {
286:             undef $datalabel;
287:             print "

289:   <TD VALIGN=TOP><TABLE WIDTH=100% CELLSPACING=1 BORDER=1>
290:     <TR><TD ALIGN=CENTER colspan=4>
291:            Combat Statistics</TD>
292:     <TR><TD align=right>Physical Defense</TD>
293:         <TD colspan=2 align=center> $datarray{'PHYSICAL'} </TD>
294:     <TR><TD align=right>Spell Defense</TD>
295:         <TD colspan=2 align=center> $datarray{'SPELL'} </TD>
296:     <TR><TD align=right>Social Defense</TD>
297:         <TD colspan=2 align=center> $datarray{'SOCIAL'} </TD>
298:     <TR><TD align=right>Armor Physical/Mystic </TD>
299:         <TD align=center> $datarray{'NORMAL'} </TD>
300:         <TD align=center> $datarray{'MYSTIC'} </TD>
301:     <TR>
302:     <TR><TD alin=left>Movement</TD>
303:     <TR><TD align=right>Normal Combat/Full</TD>
304:         <TD align=center> $datarray{'FOOT'.'COMBAT'} </TD>
305:         <TD align=center> $datarray{'FOOT'.'FULL'} </TD>
306:     <TR><TD align=right>Flying Combat/Full</TD>
307:         <TD align=center> $datarray{'FLIGHT'.'COMBAT'} </TD>
308:         <TD align=center> $datarray{'FLIGHT'.'FULL'} </TD>
309:     <TR>
310:     <TR><TD align=right>Max Carry/Lift</TD>
311:         <TD align=center> $datarray{'CARRY'} </TD>
312:         <TD align=center> $datarray{'LIFT'} </TD>
313:   </TABLE></TD>
314: </TR>

316: <TR><TD colspan=3><TABLE  width=100% border=1><TR>
317:   <TD><STRONG>Karma</STRONG></TD>
318:   <TD>Current:   $datarray{'CURRENT'} </TD>
319:   <TD>Maximum:   $kinfo{'MAX'}</TD>
320:   <TD>Cost:      $kinfo{'COST'}</TD>
321:   <TD>Step:      $kinfo{'STEP'}</TD>
322:   <TD>Dice:      " . StepDice($kinfo{'STEP'}) . "</TD>
323: </TR></TABLE></TD></TR>
324: ";
325:             undef $suppress;
326:             undef %datarray;
327:             #undef %kinfo;
328:             DelHandler();
329:             ContextClose();
330:         }
331:     } elsif ($gi eq 'TALENTS') {
332:         if ($start) {
333:             $suppress=1;
334:             AddHandler('assoc_store');
335:             $datalabel = $gi;
336:             print " 
337: <TR><TD colspan=3><TABLE  width=100% border=1>
338:   <TR><TD align=center colspan=9>
339:           Talents</TD>
340:   <TR><TD align=center>Talent</TD>
341:       <TD align=center>Rank</TD>
342:       <TD align=center>Base</TD>
343:       <TD align=center>Step</TD>
344:       <TD align=center>Dice</TD>
345:       <TD align=center>Disc</TD>
346:       <TD align=center>Karma</TD>
347:       <TD align=center>Strain</TD>
348:       <TD align=center>Action</TD>
349: ";
350:             ContextOpen('Talents','TALENTS');
351:         } else {
352:             undef $datalabel; 
353:             print "\n  </TABLE></TD>\n</TR>\n";
354:             undef $suppress;
355:             undef %datarray;
356:             DelHandler();
357:             ContextClose();
358:         }
359:     } elsif ($gi eq 'SKILLS') {
360:         if ($start) {
361:             $datalabel = $gi;
362:             @knowledges = ();
363:             @knowlranks = ();
364:             $suppress=1;
365:             AddHandler('assoc_store');
366:             ContextOpen('Skills','SKILLS');
367:             print " 
368: <TR><TD colspan=2 rowspan=2 VALIGN=TOP><TABLE width=100% border=1>
369:   <TR><TD align=center colspan=8>
370:           Skills</TD>
371:   <TR><TD align=center>Skill</TD>
372:       <TD align=center>Rank</TD>
373:       <TD align=center>Base</TD>
374:       <TD align=center>Step</TD>
375:       <TD align=center>Dice</TD>
376:       <TD align=center>Karma</TD>
377:       <TD align=center>Strain</TD>
378:       <TD align=center>Action</TD>
379: ";
380:         } else {
381:             undef $datalabel; 
382:             print "\n  </TABLE>"; # close cell under Languages
383:             $suppress=0;
384:             undef %datarray;
385:             DelHandler();
386:             ContextClose();
387:         }
388:     } elsif ($gi eq 'LANGUAGE') {
389:         if ($start) {
390:             @readlang=();
391:             @speaklang=();
392:             $suppress=1;
393:             AddHandler('assoc_store');
394:             ContextOpen('Languages','LANGUAGE');
395:         } else {
396:             $numrows = $#speaklang;
397:             $numrows = $#readlang if ($#readlang > $#speaklang);
398:             $numrows++;
399:             print"
400:     <TD colspan=1 VALIGN=TOP><TABLE width=100% border=1>
401:   <TR><TD colspan=2 ALIGN=RIGHT>Languages</TD>
402:   <TR><TD colspan=1 ALIGN=CENTER>Spoken</TD>
403:       <TD colspan=1 ALIGN=CENTER>Read</TD>";
404:             for ($i=0 ; $i < $numrows ; $i++) {
405:                 print "  <TR><TD ALIGN=RIGHT>$speaklang[$i]</TD>" . 
406:                     "<TD ALIGN=LEFT>$readlang[$i]</TD>\n";
407:             }
408:             print "\n     </TABLE></TD>\n  </TD>\n</TR>\n";
409:             
410:             #print Knowledge Skills saved from skills section
411:             $numrows = $#knowledges + 1;
412:             print "<TR><TD VALIGN=TOP><TABLE width=100% border=1>";
413:             print "<TR><TD COLSPAN=2 ALIGN=RIGHT>Knowledges</TD>";
414:             for ($i=0; $i < $numrows; $i++) {
415:                 print "<TR><TD ALIGN=CENTER>$knowledges[$i]</TD>" . 
416:                     "<TD ALIGN=CENTER>$knowlranks[$i]</TD>\n";
417:             }
418:             print "</TABLE></TD>\n";
419:             
420:             undef @readlang;
421:             undef @speaklang;
422:             undef $suppress;
423:             undef %datarray;
424:             DelHandler();
425:             ContextClose();
426:         }

428:     } else {
429:         Context_Any($gi,$start);
430:     }
431: }

433: sub Context_Attributes {
434:     local($gi,$start) = @_;

436:     if ($gi eq 'ATTHIST') {
437:         if ($start) {
438:             $datalabel = $gi;
439:         } else {
440:             $attribstep{$attr} = AttributeStepConvert($attr{'VAL',$attr});
441:             undef $datalabel;
442:         }
443:     } elsif ($gi eq 'ORIG') {
444:         if ($start) {
445:             $datalabel = $gi;
446:         } else {
447:             $attr{'VAL',$attr} = $datarray{$datalabel} + $raceadj{$attr};
448:             undef $datalabel;
449:         }
450:     } elsif ($gi eq 'INC') {
451:         if ($start) {
452:             $datalabel = $gi;
453:         } else {
454:             if (defined $attr{'INC',$attr}) {
455:                 $attr{'INC',$attr} .= ',' . $datarray{$datalabel};
456:             } else {
457:                 $attr{'INC',$attr} = $datarray{$datalabel};
458:             }
459:             $attr{'VAL',$attr} += 1;
460:             undef $datalabel;
461:         }
462:     } elsif ($gi =~ /^(DEX|STR|TOU|PER|WIL|CHA)$/) {
463:         if ($start) {
464:             $attr = $AttributeNames{$gi};
465:             $datalabel = $gi;
466:         } else {
467:             undef $datalabel; undef $attr;
468:         }

470:     } else {
471:         Context_Any($gi,$start);
472:     }
473: }

475: sub Context_Statistics {
476:     local($gi,$start) = @_;

478:     if ($gi=~/^(DEFENSE|ARMOR|MOVEMENT|STRENGTH|KARMA)$/) {
479:     } elsif ($gi =~ /^(PHYSICAL|SOCIAL|SPELL|NORMAL|MYSTIC|LIFT|CARRY|CURRENT|USED)$/) {
480:         if ($start) {
481:             $datalabel = $gi;
482:         } else {
483:             undef $datalabel;
484:         }
485:     } elsif   ($gi eq 'FOOT') {
486:         $datalabel = $gi;
487:         $movetype = 'FOOT';
488:     } elsif   ($gi eq 'FLIGHT') {
489:         $movetype = 'FLIGHT';
490:         $datalabel = $gi;
491:     } elsif     ($gi eq 'COMBAT') {
492:         $datalabel = $movetype . $gi;
493:     } elsif     ($gi eq 'FULL') {
494:         $datalabel = $movetype . $gi;

496:     } else {
497:         Context_Any($gi,$start);
498:     }
499: }

501: sub Context_Talents {
502:     local($gi,$start) = @_;

504:     if ($gi eq 'TALENT') {
505:         if ($start) {
506:             $datalabel = $gi;
507:         } else {
508:             local($talent,$rank,$base,@temp,$stepel,$talfile,$talinfo,$action,$karma,$strain,$stepdesc,$step,@steparr,$dice,$disc,$name,$circle,$line);
509:             $talent = $datarray{'TALENT'};
510:             $rank = $attribute_value{$level,'RANK'};
511:             $base = ''; $step = 0;
512:             $talfile = $talent;
513:             $talfile = $EDdir."/Talents/".NormalizeFileName($talfile).".sgm";
514:             if (-f $talfile) {
515:                 open(TALINFO,"nsgmls $talfile | $meta/../parse.pl $meta/../extract.pl name.action.karma.strain.step /0@,@/1@,@/2@,@/3@,@/4 |");
516:                 $talinfo = <TALINFO>;
517:                 close TALINFO;
518:                 ($talent,$action,$karma,$strain,$stepdesc) = split(/@,@/,$talinfo);
519:                 @steparr = split(/\s*\+\s*/,$stepdesc);
520:                 foreach $stepel (@steparr) {
521:                     if ($stepel =~ /rank/i) {
522:                         $step += $rank;
523:                     } elsif ( $stepel =~ /dexterity|strength|toughness|perception|willpower|charisma/i) {
524:                         $step += $attribstep{$stepel};
525:                         @temp = split (//,$stepel);
526:                         $temp[0] =~ tr/a-z/A-Z/;
527:                         $temp[1] =~ tr/A-Z/a-z/;
528:                         $temp[2] =~ tr/A-Z/a-z/;
529:                         $base = $temp[0].$temp[1].$temp[2];
530:                     } else {
531:                         # can only be a number?
532:                         $step += $stepel;
533:                         $base .= "+$stepel";
534:                     }
535:                 }
536:                 if ($action eq '') {
537:                     $step = '';
538:                     $dice = '';
539:                 }
540:             } else {
541:                 $karma = $strain = $action = $base = '<EM>(unkn)</EM>';
542:                 
543:             }
544:             $dice = StepDice($step) if ($step > 0);
545:             $disc = '<EM>(Ign)</EM>';  # Need discipline parsing for these two
546:             if ($attribute_value{$level,'VERSATILITY'} eq 'VERSATILITY') {
547:                 $note = 'V';
548:             } else {
549:                 $circle = '?';
550:             }
551:             print "
552:   <TR><TD align=left>   <SUP>$note</SUP>$talent</TD>
553:       <TD align=center> $rank </TD>
554:       <TD align=center> $base </TD>
555:       <TD align=center> $step </TD>
556:       <TD align=center> $dice </TD>
557:       <TD align=center> $disc </TD>
558:       <TD align=center> $karma </TD>
559:       <TD align=center> $strain </TD>
560:       <TD align=center> $action </TD>
561: ";
562:             $first = 1;
563:             foreach $line (@knacks) {
564:                 print "  <TR><TD></TD><TD align=left colspan=8>" if $first;
565:                 print ", " unless $first;
566:                 $first = 0;
567:                 print $line;
568:             }
569:             print "</TD>\n" unless $first;
570:             undef @knacks;
571:             undef $datalabel;  #knack alreadly killed it
572:         }
573:         
574:     } elsif ($gi eq 'KNACK') {
575:         if ($start) {
576:             $datalabel = $gi;
577:         } else {
578:             local($knack,$rank,$knfile,$kninfo);
579:             $knack = $datarray{'KNACK'};
580:             $knfile = $knack;
581:             $knfile =~ s/\s//;
582:             $knfile = $EDdir . "/Knacks/" . $knfile . ".sgm";
583:             if (-f $knfile) {
584:                 open(KNINFO,"nsgmls  $knfile | $meta/../parse.pl $meta/../extract.pl name.rank /0@,@/1 |");
585:                 $kninfo = <KNINFO>;
586:                 close KNINFO;
587:                 ($name,$rank) = split(/@,@/,$kninfo);
588:             } else {
589:                 $name = $knack;
590:                 $rank = '?';
591:             }
592:             push (@knacks,"<EM>$name</EM><SUP>$rank</SUP>");
593:             undef $datalabel;
594:         }

596:     } else {
597:         Context_Any($gi,$start);
598:     }
599: }

601: sub Context_Skills {
602:     local($gi,$start) = @_;

604:     if ($gi eq 'SKILL') {
605:         if ($start) {
606:             $datalabel = $gi;
607:         } else {
608:             local($talent,$rank,$base,@temp,$stepel,$talfile,$talinfo,
609:                   $action,$karma,$strain,$stepdesc,$step,@steparr,$dice,
610:                   $disc,$circle,$line);
611:             $talent = $datarray{'SKILL'};
612:             $rank = $attribute_value{$level,'RANK'};
613:             if ($attribute_value{$level,'KNOWLEDGE'} eq 'KNOWLEDGE') {
614:                 push(@knowledges,$talent);
615:                 push(@knowlranks,$rank);
616:             } else {
617:                 $base = ''; $step = 0;
618:                 $talfile = $talent;
619:                 $talfile = $EDdir."/Skills/".NormalizeFileName($talfile).".sgm";
620:                 if (! -f $talfile) {
621:                     $talfile =~ s|/Talents/|/Skills/|;
622:                 }
623:                 if (-f $talfile) {
624:                     open(TALINFO,"nsgmls $talfile | $meta/../parse.pl $meta/../extract.pl name.action.karma.strain.step /0@,@/1@,@/2@,@/3@,@/4 |");
625:                     $talinfo = <TALINFO>;
626:                     close TALINFO;
627:                     ($talent,$action,$karma,$strain,$stepdesc) = split(/@,@/,$talinfo);
628:                     @steparr = split(/\s*\+\s*/,$stepdesc);
629:                     foreach $stepel (@steparr) {
630:                         if ($stepel =~ /rank/i) {
631:                             $step += $rank;
632:                         } elsif ( $stepel =~ /dexterity|strength|toughness|perception|willpower|charisma/i) {
633:                             $step += $attribstep{$stepel};
634:                             @temp = split (//,$stepel);
635:                             $temp[0] =~ tr/a-z/A-Z/;
636:                             $temp[1] =~ tr/A-Z/a-z/;
637:                             $temp[2] =~ tr/A-Z/a-z/;
638:                             $base = $temp[0].$temp[1].$temp[2];
639:                         } else {
640:                             # can only be a number?
641:                             $step += $stepel;
642:                             $base .= "+$stepel";
643:                         }
644:                     }
645:                     if ($action eq '') {
646:                         $step = '';
647:                         $dice = '';
648:                     }
649:                 } else {
650:                     $karma = $strain = $action = $base = '<EM>(unkn)</EM>';
651:                     
652:                 }
653:                 $dice = StepDice($step) if ($step > 0);
654:                 print "
655:   <TR><TD align=left>   $talent</TD>
656:       <TD align=center> $rank </TD>
657:       <TD align=center> $base </TD>
658:       <TD align=center> $step </TD>
659:       <TD align=center> $dice </TD>
660:       <TD align=center> $karma </TD>
661:       <TD align=center> $strain </TD>
662:       <TD align=center> $action </TD>
663: ";
664:             }
665:             undef $datalabel;
666:         }
667:         
668:     } else {
669:         Context_Any($gi,$start);
670:     }
671: }
672:     
673: sub Context_Languages {
674:     local($gi,$start) = @_;

676:     if ($gi eq 'READ') {
677:         if ($start) {
678:             $datalabel = $gi;
679:         } else {
680:             push(@readlang,$datarray{'READ'});
681:             undef $datalabel;
682:         }
683:     } elsif ($gi eq 'SPEAK') {
684:         if ($start) {
685:             $datalabel = $gi;
686:         } else {
687:             push(@speaklang,$datarray{'SPEAK'});
688:             undef $datalabel;
689:         }

691:     } else {
692:         Context_Any($gi,$start);
693:     }
694: }

696: sub Context_LegendPoints {
697:     local($gi,$start) = @_;
698:     
699:     if ($gi eq 'LPHIST') {
700:         if ($start) {
701:             $lptotal = 0;
702:             $krtotal = 0;
703:             $suppress=1;
704:             AddHandler('assoc_store');
705:             $datalabel = $gi;
706:         } else {
707:             undef $datalabel;
708:             $numcols = 3;
709:             $numents = $#lpentries+1;
710:             $numrows = ($numents+$numcols-($numents % $numcols)) / $numcols;
711:             print "<TR><TD COLSPAN=3><TABLE WIDTH=100% BORDER=0>\n";
712:             print "<TR><TD>Current: " . ($lptotal - $lpspent) . "</TD>\n" . 
713:                 "<TD>Total: $lptotal</TD>\n";
714:             if ($krtotal > 0) {
715:                 print "<TD>Karma Used: $krtotal</TD>\n";
716:             }
717:             print "<TD>Legendary Status: ";
718:             if ($lptotal < 10000) {
719:                 print "Zero";
720:             } elsif ($lptotal < 40000) {
721:                 print "One";
722:             } elsif ($lptotal < 160000) {
723:                 print "<EM>Two</EM>";
724:             } elsif ($lptotal < 640000) {
725:                 print "<STRONG>Three</STRONG>";
726:             } elsif ($lptotal < 2560000) {
727:                 print "<STRONG><EM>Four</EM></STRONG>";
728:             } else {
729:                 print "<STRONG><EM>FIVE</EM></STRONG>";
730:             }
731:             print "</TD>\n";
732:             print "</TABLE></TD></TR>\n";
733:             #print "<TR><TD COLSPAN=3><TABLE WIDTH=100% BORDER=1><TR>";
734:             #for ($r=0; $r < $#lpentries+1; $r++) {
735:             #    print "<TD valign=top><TABLE WIDTH=100% BORDER=1>\n"
736:             #        if ($r % $numrows == 0);
737:             #    print "<TR>$lpentries[$r]\n"; 
738:             #    print "</TABLE></TD>\n" if (($r+1) % $numrows == 0);
739:             #}
740:             #print "</TABLE></TD>\n" unless ($r % $numrows == 0);
741:             #print "</TR></TABLE></TD></TR>\n";
742:             undef $suppress;
743:             undef %datarray;
744:             DelHandler();
745:         }
746:     } elsif ($gi eq 'LPENTRY') {
747:         if ($start) {
748:             $entry = '';
749:         } else {
750:             push(@lpentries,$entry);
751:         }
752:     } elsif ($gi eq 'LP') {
753:         if ($start) {
754:             $datalabel = $gi;
755:         } else {
756:             if ($datarray{'LP'} > 0) {
757:                 $lptotal += $datarray{'LP'};
758:             } else {
759:                 $lpspent += -$datarray{'LP'};
760:             }
761:             $entry .= "<TD ALIGN=RIGHT VALIGN=TOP>$datarray{'LP'}</TD>";
762:             undef $datalabel;
763:         }
764:     } elsif ($gi eq 'NOTE') {
765:         if ($start) {
766:             $datalabel = $gi;
767:         } else {
768:             $karma = $attribute_value{$level,'KARMA'};
769:             $krtotal += $karma;
770:             $lpspent += $kinfo{'COST'} * $karma;
771:             $entry .= "<TD>";
772:             $entry .= "<SUP>$karma</SUP>" if ($karma > 0);
773:             $entry .= "$datarray{$gi}</TD>";
774:             undef $datalabel;
775:         }
776:         
777:     } else {
778:         Context_Any($gi,$start);
779:     }
780: }

782: sub Context_Detailing {
783:     local($gi,$start) = @_;

785:     if ($gi eq 'BACKGRND') {
786:         if ($start) {
787:             $datalabel = $gi;
788:             print "<TR><TD colspan=3><H3 align=center>Background</H3>\n";
789:         } else {
790:             undef $datalabel;
791:             print "</TD></TR>\n";
792:         }
793:     } elsif ($gi eq 'PROFILE') {
794:         if ($start) {
795:             $datalabel = $gi;
796:             print "<TR><TD colspan=3><TABLE width=100% border=0><TR><TD width=10%></TD><TD align=center><H3>Profile</H3></TD><TD width=10%>";
797:             print "<A HREF=\"$jlink\"><EM>Journal Available</EM></A>" if (-f $jfile);
798:             print "</TD></TABLE>\n";
799:         } else {
800:             undef $datalabel;
801:             print "</TD></TR>\n";
802:         }

804:     } else {
805:         Context_Any($gi,$start);
806:     }
807: }

809: sub Context_Threads {
810:     local($gi,$start) = @_;
811:     if ($gi eq 'THREAD') {
812:         if ($start) {
813:             $datarray{'EFFECT'} = $datarray{'TARGET'} = $datarray{'ITEM'} = '';
814:         } else {
815:             $datarray{'RANK'} = $attribute_value{$level,'RANK'};
816:             $datarray{'BASECOST'} = $attribute_value{$level,'BASE'};
817:             print "  <TR><TD ALIGN=CENTER VALIGN=TOP>$datarray{'RANK'}</TD>";
818:             if ($datarray{'ITEM'} ne '') {
819:                 print "    <TD ALIGN=LEFT VALIGN=TOP>$datarray{'ITEM'}</TD>\n";
820:                 print "    <TD ALIGN=LEFT VALIGN=TOP>$datarray{'EFFECT'}</TD>\n";
821:             } else {
822:                 print "    <TD ALIGN=LEFT COLSPAN=2 VALIGN=TOP>$datarray{'TARGET'}</TD>\n";
823:             }
824:             print "  </TR>\n";
825:         }
826:     } elsif ($gi =~ /^(ITEM|EFFECT|TARGET)$/) {
827:         if ($start) {
828:             $datalabel = $gi;
829:         } else {
830:             undef $datalabel;
831:         }
832:         
833:     } else {
834:         Context_Any($gi,$start);
835:     }
836: }

838: sub Context_Equipment {
839:     local($gi,$start) = @_;
840:     if ($gi eq 'EQENTRY') {
841:         if ($start) {
842:             $datarray{'NOTE'} = $datarray{'LOC'} = $datarray{'WEIGHT'} = 
843:                 $datarray{'ITEM'} = '';
844:         } else {
845:             $entry = "<TD ALIGN=RIGHT VALIGN=TOP>$datarray{'ITEM'}</TD>\n".
846:                 "<TD ALIGN=CENTER VALIGN=TOP>$datarray{'WEIGHT'}</TD>\n".
847:                 "<TD ALIGN=CENTER VALIGN=TOP>$datarray{'LOC'}</TD>\n".
848:                 "<TD ALIGN=LEFT VALIGN=TOP>$datarray{'NOTE'}</TD>\n";
849:             push(@eqentries,$entry);
850:         }
851:     } elsif ($gi =~ /^(ITEM|LOC|WEIGHT|NOTE)$/) {
852:         if ($start) {
853:             $datalabel = $gi;
854:         } else {
855:             undef $datalabel;
856:         }
857:         
858:     } else {
859:         Context_Any($gi,$start);
860:     }
861: }

863: 1;