Advertisement
dr_ishmael

GuildWikiSkills.php

Jul 31st, 2011
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.95 KB | None | 0 0
  1. <?php
  2. if ( !defined( 'MEDIAWIKI' ) ) {
  3.   die( 'This file is a MediaWiki extension, it is not a valid entry point' );
  4. }
  5.  
  6. $wgExtensionCredits['parserhook'][] = array(
  7.   'path' => __FILE__,
  8.   'name' => 'GuildWikiSkills',
  9.   'version' => '0.0a',
  10.   'author' => '[[User:Dr ishmael|Tony Tauer]]',
  11.   'description' => 'Performs dynamic formatting of skill descriptions.',
  12. );
  13.  
  14. $dir = dirname( __FILE__ ) . '/';
  15.  
  16. $wgExtensionFunctions[] = 'wfSkillFunctions';
  17.  
  18. $wgHooks['LanguageGetMagic'][] = 'wfSkillFunctionsLanguageGetMagic';
  19.  
  20. /*
  21.  $wgSkillFunctionsLinks : A hash of article names to link to and the keywords
  22.                           to trigger the links
  23.  
  24.  The order here (target article => keyword regex) is counterintuitive, but it's
  25.  better to have the target article as the hash key since keys have to be unique
  26.  and we only want 1 entry per target (so we don't end up with repeated links)
  27.  
  28.  The hash values are regex fragments that will be inserted into the following:
  29.  
  30.     /(?<= |-)('.$needle.')(?!\]|\|)/i
  31.  
  32.  That means that $needle must be preceded by either a space or a hyphen, and
  33.  cannot be followed by a pipe or a closing bracket, and that the search is
  34.  case-insensitive.  Once a $needle is found and linked, it will then be
  35.  wrapped between an opening bracket and a pipe, preventing it from matching
  36.  any other patterns.
  37.  
  38.  The overall order of entries is very sensitive, since a lot of entries are
  39.  substrings of other entries.  Attack, Damage, and Skill are the most obvious,
  40.  but you should always be aware of this when adding or modifying entries.
  41. */
  42. $wgSkillFunctionsLinks = array(
  43.     # conditions
  44.    'Bleeding' => 'bleed',
  45.     'Blind' => 'blind',
  46.     'Burning' => 'burn|on fire',
  47.     'Cracked Armor' => 'cracked armor',
  48.     'Crippled' => 'cripple',
  49.     'Dazed' => 'daze',
  50.     'Deep Wound' => 'deep wound',
  51.     'Disease' => 'disease',
  52.     'Poison' => 'poison',
  53.     'Weakness' => 'weak',
  54.     'Condition' => 'condition',
  55.     # skill types (not all appear in descriptions, but listing all for completeness)
  56.    'Chant' => 'chant', # no conflict with 'enchant' since $needle must be preceded by a space
  57.    'Echo (skill type)' => '(?<=This )echo',
  58.     'Elite skill' => 'elite(| skill)',
  59.     'Flash Enchantment' => 'flash enchantment',
  60.     'Enchantment' => 'enchant',
  61.     'Form' => 'form',
  62.     'Hex' => 'hex(?!er)', # avoid Hexer's Vigor (references itself)
  63.    'Preparation' => 'preparation',
  64.     'Shout' => 'shout',
  65.     'Signet' => 'signet',
  66.     'Weapon Spell' => 'weapon spell',
  67.     'Spell' => 'spell',
  68.     'Stance' => '(?<!Berserker |Defensive |Disciplined |Tiger |Wary )stance',
  69.     'Trap' => 'trap',
  70.     'Ritual' => '(binding |nature |)ritual',
  71.     'Ward Spell' => 'ward',
  72.     'Well Spell' => 'well',
  73.     # attack skill types
  74.    'Dual attack' => 'dual attack',
  75.     'Lead attack' => 'lead attack',
  76.     'Off-hand attack' => 'off-hand attack',
  77.     'Dagger Attack' => 'dagger attack',
  78.     'Axe Attack' => 'axe attack',
  79.     'Hammer Attack' => 'hammer attack',
  80.     'Sword Attack' => 'sword attack',
  81.     'Bow Attack' => 'bow attack',
  82.     'Spear Attack' => 'spear attack',
  83.     'Scythe Attack' => 'scythe attack',
  84.     'Attack (skill type)' => 'attack skill',
  85.     'Skill' => 'skill',
  86.     # non-skill attacks
  87.    'Physical attack' => 'physical attack',
  88.     'Ranged attack' => 'ranged attack',
  89.     'Attack' => '(?<!Penetrating |Sundering )attack',
  90.     # attributes - only a few are mentioned in current descriptions; listing
  91.    # them all for completeness
  92.    'Primary attribute' => 'primary attribute',
  93.     'Attribute' => 'attribute',
  94.     'Critical Strikes' => 'critical strikes',
  95.     'Dagger Mastery' => 'dagger mastery',
  96.     'Deadly Arts' => 'deadly arts',
  97.     'Shadow Arts' => 'shadow arts',
  98.     'Earth Prayers' => 'earth prayers',
  99.     'Mysticism' => 'mysticism',
  100.     'Scythe Mastery' => 'scythe mastery',
  101.     'Wind Prayers' => 'wind prayers',
  102.     'Air Magic' => 'air magic',
  103.     'Earth Magic' => 'earth magic|earth(?= or water)',
  104.     'Energy Storage' => 'energy storage',
  105.     'Fire Magic' => 'fire magic',
  106.     'Water Magic' => 'water magic|water(?= hex)',
  107.     'Domination Magic' => 'domination magic',
  108.     'Fast Casting' => 'fast casting',
  109.     'Illusion Magic' => 'illusion magic|illusion(?= hex| attribute)',
  110.     'Inspiration Magic' => 'inspiration magic',
  111.     'Divine Favor' => 'divine favor',
  112.     'Healing Prayers' => 'healing prayer|healing(?= or protection)',
  113.     'Protection Prayers' => 'protection prayers',
  114.     'Smiting Prayers' => 'smiting prayers',
  115.     'Blood Magic' => 'blood magic',
  116.     'Curses' => 'curses',
  117.     'Death Magic' => 'death magic',
  118.     'Soul Reaping' => 'soul reaping',
  119.     'Command' => 'command',
  120.     'Leadership' => 'leadership',
  121.     'Motivation' => 'motivation',
  122.     'Spear Mastery' => 'spear mastery',
  123.     'Beast Mastery' => 'beast mastery',
  124.     'Expertise' => 'expertise',
  125.     'Marksmanship' => 'marksmanship',
  126.     'Wilderness Survival' => 'wilderness survival',
  127.     'Channeling Magic' => 'channeling magic',
  128.     'Communing' => 'communing',
  129.     'Restoration Magic' => 'restoration magic',
  130.     'Spawning Power' => 'spawning power',
  131.     'Axe Mastery' => 'axe mastery',
  132.     'Hammer Mastery' => 'hammer mastery',
  133.     'Strength' => 'strength',
  134.     'Swordsmanship' => 'swordsmanship',
  135.     'Tactics' => 'tactics',
  136.     # weapons - all '[weapon] attack' and '[weapon] mastery' entries must precede these
  137.    'Axe' => '(?<!Furious |Whirling )axe',
  138.     'Bow' => 'bow',
  139.     'Daggers' => 'daggers',
  140.     'Hammer' => '(?<!Devastating )hammer(?! Bash)',
  141.     'Scythe' => 'scythe',
  142.     'Shield' => 'shield',
  143.     'Spear' => 'spear',
  144.     'Sword' => 'sword',
  145.     'Arrow' => '(?<!Poison |Shock )arrow',
  146.     # professions - not all 10 are mentioned in current descriptions; listing
  147.    # them all for completeness
  148.    'Assassin' => 'assassin',
  149.     'Dervish' => 'dervish',
  150.     'Elementalist' => 'elementalist',
  151.     'Mesmer' => 'mesmer',
  152.     'Monk' => 'monk',
  153.     'Necromancer' => 'necromancer',
  154.     'Paragon' => 'paragon',
  155.     'Ranger' => 'ranger',
  156.     'Ritualist' => 'ritualist',
  157.     'Warrior' => 'warrior',
  158.     # skill cost terms
  159.    'Adrenaline' => 'adrenal',
  160.     'Activation time' => 'activat', # activate/activating
  161.    'Energy#Energy regeneration/degeneration' => 'energy (r|d)egeneration',
  162.     'Energy' => 'energy',
  163.     'Exhaustion' => 'exhaust', # exhaustion/exhausted
  164.    'Health#Health regeneration/degeneration' => 'health (r|d)egeneration',
  165.     'Health' => 'health',
  166.     'Heal' => 'heal(?!th)',
  167.     'Recharge' => 'recharg', # recharge/recharging
  168.    'Sacrifice' => 'sacrifice',
  169.     'Upkeep' => 'maintain',
  170.     # skill effect terms
  171.    'Touch' => 'touch',
  172.     'Disable' => 'disable',
  173.     'Interrupt' => '(?<!easily )interrupt|disrupting|uninterruptible',
  174.     'Easily interrupted' => 'easily interrupted',
  175.     'Life stealing' => 'life steal|steal(?=.*health)', # 'steal' is also used in a couple Energy stealing skills
  176.    'Block' => '(un|)block',
  177.     'Miss' => 'miss',
  178.     'Fail' => 'fail(?! to hit)',
  179.     'Knockdown' => 'knock(ed|s|)( |-|)down', # knocked/knocks/knock, joined by ' ' or '-' or nothing
  180.    'Resurrect (action)' => 'resurrect|(returned|back) to life',
  181.     'Range' => 'range|adjacent|near|in the area|earshot',
  182.     'Armor penetration' => 'armor penetration',
  183.     'Armor (rating)' => 'armor',
  184.     'Critical hit' => 'critical( attack| hit)',
  185.     'Cast' => 'cast',
  186.     'Corpse exploitation' => 'exploit',
  187.     'Create' => 'animate|create|summon',
  188.     'Shadow step' => 'shadow step',
  189.     'Teleport' => 'teleport',
  190.     'Death penalty' => 'death penalty',
  191.     'Morale boost' => 'morale boost',
  192.     'Melee' => 'melee',
  193.     'Action' => 'action',
  194.     'Double strike' => 'double strike',
  195.     'Projectile' => 'projectile',
  196.     'Bundle' => '(bundle |)item',
  197.     # damage
  198.    'Physical damage' => 'physical damage',
  199.     'Blunt damage' => 'blunt damage',
  200.     'Piercing damage' => 'piercing damage',
  201.     'Slashing damage' => 'slashing damage',
  202.     'Elemental damage' => 'elemental damage|elemental(?= and| or)',
  203.     'Cold damage' => 'cold damage|cold(?= weapon)',
  204.     'Earth damage' => 'earth damage|earth(?= weapon)',
  205.     'Fire damage' => 'fire damage|fire(?= weapon)',
  206.     'Lightning damage' => 'lightning damage|lightning(?= weapon)',
  207.     'Holy damage' => 'holy damage',
  208.     'Shadow damage' => 'shadow damage',
  209.     'Damage reduction' => 'damage reduction',
  210.     'Damage' => 'damage',
  211.     # targets
  212.    'Corpse' => 'corpse',
  213.     'Fleshy creature' => 'fleshy',
  214.     'Summoned creature' => 'summoned creature',
  215.     'Spirit' => '(?<!Watchful |Spiteful )spirit',
  216.     'Bone Fiend' => 'bone fiend',
  217.     'Bone Horror' => 'bone horror',
  218.     'Bone Minion' => 'bone minion',
  219.     'Flesh Golem' => 'flesh golem',
  220.     'Shambling Horror' => 'shambling horror',
  221.     'Jagged Horror' => 'jagged horror',
  222.     'Vampiric Horror' => 'vampiric horror',
  223.     'Minion' => 'undead (|allied)(allies|ally|minion|servant)|animated undead|minion|servant',
  224.     'Ally' => 'all(y|ies)',
  225.     'Party' => 'party',
  226.     'Animal companion' => 'animal(| companion)|pet',
  227.     'Foe' => 'foe',
  228.     # misc for PvE skills
  229.    'Sunspear rank' => 'sunspear rank',
  230.     'Raven Blessing skills quick reference' => 'raven attacks',
  231.     'Ursan Blessing skills quick reference' => 'bear attacks',
  232.     'Volfen Blessing skills quick reference' => 'wolf attacks',
  233.     'Experience' => 'experience',
  234.     'Ice Imp' => 'ice imp',
  235.     'Mursaat Elementalist' => 'mursaat',
  236.     'Naga Shaman' => 'naga shaman',
  237.     'Ruby Djinn' => 'ruby djinn',
  238.     'Boss' => 'boss',
  239.     'Destroyer' => 'destroyer',
  240.     'Drunk' => 'drunk',
  241.     'Hidden object' => 'hidden object',
  242.     'Compass' => 'compass',
  243.     'Charr' => 'charr',
  244.     'Iron Palm' => 'iron palm',
  245.     'Fox Fangs' => 'fox fangs',
  246.     'Nine Tail Strike' => 'nine tail strike',
  247. );
  248.  
  249. function wfSkillFunctions ( ) {
  250.   global $wgParser, $wgExtSkillFunctions;
  251.  
  252.   $wgExtSkillFunctions = new ExtSkillFunctions ( );
  253.  
  254.   $wgParser->setFunctionHook('descparse',      array(&$wgExtSkillFunctions,'parseDescription'      ));
  255. }
  256.  
  257. function wfSkillFunctionsLanguageGetMagic( &$magicWords, $langCode = "en" ) {
  258.   switch ( $langCode ) {
  259.     default:
  260.     $magicWords['descparse']          = array ( 0, 'descparse' );
  261.   }
  262.   return true;
  263. }
  264.  
  265. class ExtSkillFunctions {
  266.  
  267.   /**
  268.    * {{#descparse:raw_description|str1_min|str1_max|str2_min|str2_max|str3_min|str3_max}}
  269.    * Note: If any of the parameters are an empty string, they are ignored.
  270.    */
  271.   function parseDescription ( &$parser, $raw = '', $min1 = -1, $max1 = -1,
  272.                                $min2 = -1, $max2 = -1, $min3 = -1, $max3 = -1
  273.                             ) {
  274.                            
  275.     global $wgSkillFunctionsLinks;
  276.    
  277.     # Read additional link keywords from MediaWiki: pages
  278.    # These should all be of the 'target' => 'needle' format
  279.    $source = wfMsgForContent('Skill-description-links');
  280.     if( $source && !wfEmptyMsg('Skill-description-links', $source) ) {
  281.       $lines = explode("\n", $source);
  282.       $lines = ExtSkillFunctions::stripLines($lines);
  283.      
  284.       foreach($lines as $line) {
  285.         if(preg_match('/^\'.*?\' => \'.*?\'$/', $line)) {
  286.           $wgSkillFunctionsLinks[] = $line;
  287.         }
  288.       }
  289.     }
  290.  
  291.     if ( $raw === '' ) {
  292.       # if input is empty, return empty
  293.      return '';
  294.     }
  295.    
  296.     $rval = $raw;
  297.    
  298.     # Set up $parms as an array of arrays
  299.    # $parms[1][0] = $min1, $parms[3][1] = $max3, etc.
  300.    $parms = array('', array($min1, $max1), array($min2, $max2), array($min3, $max3));
  301.    
  302.     # Evaluate parms and perform %str#% substitution
  303.    foreach (array(1, 2, 3) as $i) {
  304.       $min = ($parms[$i][0] === '') ? -1 : $parms[$i][0];
  305.       $max = ($parms[$i][1] === '') ? -1 : $parms[$i][1];
  306.      
  307.       # If only the max is set, this is an error
  308.      if ($min === -1 && $max !== -1) {
  309.         return '<strong class="error">' . "Error: str${i}_max given without str${i}_min" . '</strong>';
  310.       }
  311.       # If only the min is set, then substitute %str#% with min (no formatting)
  312.      elseif ($min !== -1 && $max === -1) {
  313.         $rval = str_replace("%str$i%",$min,$rval);
  314.       }
  315.       # If both min and max are set and are different, calculate range and substitute (with formatting)
  316.      elseif ($min !== -1 && $max !== -1 && $min !== $max) {
  317.         $v12 = round($min + ($max - $min)*12/15);
  318.         $rval = str_replace("%str$i%","'''${min}...${v12}...${max}'''",$rval);
  319.       }
  320.       # If both min and max are set and are the same, substitue (with formatting)
  321.      elseif ($min !== -1 && $max !== -1 && $min === $max) {
  322.         $rval = str_replace("%str$i%","'''$min'''",$rval);
  323.       }
  324.       # Else if neither min nor max is set, and $raw contains %str#%, return error
  325.      elseif ( strpos($rval,"%str$i%") ) {
  326.         return '<strong class="error">' . "Error: description contains %str$i% but str${i}_min/max are not set" . '</strong>';
  327.       }
  328.     }
  329.    
  330.     # Collapse doubled %%
  331.    $rval = str_replace('%%','%',$rval);
  332.    
  333.     # Translate <c=@SkillDull>...</c> into ''...''
  334.    $rval = str_replace('<c=@SkillDull>',"''",$rval);
  335.     $rval = str_replace('</c>',"''",$rval);
  336.    
  337.     # Plurals
  338.    $rval = str_replace('[s]','s',$rval);                    # simple
  339.    $rval = preg_replace('/\w+\[pl:"(\w+)\"\]/','$1',$rval); # complex
  340.    
  341.     # Prepend a space so the backreferences can match at the beginning of the string
  342.    $rval = ' ' . $rval;
  343.    
  344.     # Links
  345.    foreach ($wgSkillFunctionsLinks as $target => $needle) {
  346.       $rval = preg_replace('/(?<= |-)('.$needle.')(?!\]|\|)/i','[['.$target.'|$1]]',$rval,1);
  347.     }
  348.    
  349.     # Remove the prepended space
  350.    $rval = substr($rval,1);
  351.    
  352.     # Wrap with span to set CSS class
  353.    $rval = '<span class="skill_description">' . $rval . '</span>';
  354.    
  355.     return $rval;
  356.   }
  357.  
  358.   /**
  359.    * Strip comments and whitespace, then remove blanks
  360.    * @private
  361.    * @static
  362.    */
  363.   static function stripLines( $lines ) {
  364.     return array_filter(
  365.       array_map( 'trim',
  366.           preg_replace( '/#.*$/', '',
  367.             $lines ) ) );
  368.   }
  369.  
  370. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement