private function getQuestionOut(SR_Player $player)
 {
     $back = array();
     foreach (self::$NEED as $itemname => $need) {
         $back[] = sprintf('%d %s', $need, $itemname);
     }
     return GWF_Array::implodeHuman($back);
 }
Example #2
0
 /**
  * Get simple stat string in arg 0.
  * @return string
  */
 public function getQuestDescriptionStats()
 {
     $va = array();
     $data = $this->getQuestData();
     $out = array();
     foreach ($this->getQuestDataItems($this->getPlayer()) as $itemname => $amt) {
         $out[] = sprintf("%d/%d %s", $data[$itemname], $amt, $itemname);
     }
     return GWF_Array::implodeHuman($out);
 }
Example #3
0
 private function listFonts()
 {
     $files = scandir(GWF_EXTRA_PATH . 'font/');
     foreach ($files as $i => $file) {
         if ($file[0] === '.') {
             unset($files[$i]);
         } else {
             $files[$i] = substr($file, 0, -4);
         }
     }
     return GWF_Array::implodeHuman($files);
 }
Example #4
0
 public function onEnter(SR_Player $player)
 {
     $p = $player->getParty();
     $names = array();
     foreach ($p->getMembers() as $member) {
         if (!$member->hasConst('SEATTLE_BM')) {
             $names[] = $member->getName();
         }
     }
     if (count($names) === 0) {
         return parent::onEnter($player);
     }
     $this->partyMessage($player, 'oops', array(GWF_Array::implodeHuman($names)));
     return false;
 }
Example #5
0
 public function onEnter(SR_Player $player)
 {
     $p = $player->getParty();
     $names = array();
     foreach ($p->getMembers() as $member) {
         if (!$member->hasConst('SEATTLE_BM')) {
             $names[] = $member->getName();
         }
     }
     if (count($names) === 0) {
         return parent::onEnter($player);
     }
     $this->partyMessage($player, 'nonono', array(GWF_Array::implodeHuman($names)));
     return false;
     // 		$p->notice(sprintf('One of the guards come to you. Seems like %s lack(s) the permission to enter. You decide to turn around and leave.', GWF_Array::implodeHuman($names)));
 }
Example #6
0
 public function getHelpText(SR_Player $player)
 {
     $c = Shadowrun4::SR_SHORTCUT;
     $cmds = $this->getCommands($player);
     foreach ($cmds as $i => $cmd) {
         $cmds[$i] = "{$c}{$cmd}";
     }
     return $player->lang('hlp_store', array(GWF_Array::implodeHuman($cmds))) . parent::getHelpText($player);
     // 		if ($player->getBase('thief') > 0)
     // 		{
     // 			return "In shops you can use {$c}view, {$c}buy, {$c}sell and {$c}steal.";
     // 		}
     // 		else
     // 		{
     // 			return "In shops you can use {$c}view, {$c}buy and {$c}sell.";
     // 		}
 }
Example #7
0
 private static function displaySet(SR_Player $player, $set)
 {
     if (false === ($data = SR_SetItems::getSetByName($set)) && false === ($data = SR_SetItems::getSetForItem($set))) {
         return self::rply($player, '1189');
     }
     $modifiers = SR_SetItems::getModifiersForSet($set);
     $modstr = '';
     $format = ', %s:%s';
     $i = $i2 = '';
     if (SR_SetItems::hasSet($player, $set)) {
         $i = "6";
         $i2 = "";
     }
     foreach ($data[0] as $key => $value) {
         $modstr .= sprintf($format, $key, $value);
     }
     $modstr = $i . trim($modstr, ',; ') . $i2;
     $itemstr = '';
     $format = ', %s%s%s';
     foreach ($data[1] as $items2) {
         $items2 = GWF_Array::arrify($items2);
         $pre = count($items2) > 1 ? '(' : '';
         $aft = count($items2) > 1 ? ')' : '';
         $itemstr .= $pre;
         foreach ($items2 as $itemname) {
             if ($player->hasEquipped($itemname)) {
                 $i = "3";
                 $i2 = "";
                 $itename = shadowlang::displayItemNameS($itemname);
             } elseif (false === ($item = $player->getItemByName($itemname, false))) {
                 $i = "15";
                 $i2 = "";
                 $itename = shadowlang::displayItemNameS($itemname);
             } else {
                 $i = $i2 = '';
                 $itemname = $item->displayName($player);
             }
             $itemstr .= sprintf($format, $i, $itemname, $i2);
         }
         $itemstr .= $aft;
     }
     $itemstr = str_replace('(, ', ', (', $itemstr);
     $itemstr = trim($itemstr, ',; ');
     return self::rply($player, '5296', array($set, $itemstr, $modstr));
 }
Example #8
0
 public function checkQuest(SR_NPC $npc, SR_Player $player)
 {
     if ($this->isDone($player)) {
         return false;
     }
     $data = $this->getQuestData();
     if (!isset($data['LEG'])) {
         $data = array('LEG' => 0, 'ARMOR' => 0, 'HELMET' => 0);
     }
     $data['LEG'] = $this->giveQuesties($player, $npc, 'ChainLegs', $data['LEG'], self::NEED_LEG);
     $data['ARMOR'] = $this->giveQuesties($player, $npc, 'ChainBody', $data['ARMOR'], self::NEED_ARMOR);
     $data['HELMET'] = $this->giveQuesties($player, $npc, 'ChainHelmet', $data['HELMET'], self::NEED_HELMET);
     $this->saveQuestData($data);
     $need_leg = self::NEED_LEG - $data['LEG'];
     $need_armor = self::NEED_ARMOR - $data['ARMOR'];
     $need_helmet = self::NEED_HELMET - $data['HELMET'];
     $need = array();
     if ($need_leg > 0) {
         $need[$need_leg . ' ChainLegs'] = $need_leg;
     }
     if ($need_armor > 0) {
         $need[$need_armor . ' ChainBodies'] = $need_armor;
     }
     if ($need_helmet > 0) {
         $need[$need_helmet . ' ChainHelmets'] = $need_helmet;
     }
     if (count($need) === 0) {
         $npc->reply($this->lang('thx1'));
         // 			$npc->reply('Thank you very very much.');
         // 			$npc->reply('Please take this as reward!');
         $player->message($this->lang('thx2', array(Shadowfunc::displayNuyen(self::REWARD_NUYEN), self::REWARD_XP)));
         // 			$player->message(sprintf('The dwarf hands you %s. You also gain %s XP.', Shadowfunc::displayNuyen(self::REWARD_NUYEN), self::REWARD_XP));
         $player->giveXP(self::REWARD_XP);
         $player->giveNuyen(self::REWARD_NUYEN);
         $this->onSolve($player);
     } else {
         $npc->reply($this->lang('more', array(GWF_Array::implodeHuman(array_keys($need)))));
         // 			$npc->reply(sprintf('I still need %s.', GWF_Array::implodeHuman(array_keys($need))));
     }
     return true;
 }
Example #9
0
 /**
  * Translate an item.
  * @param string $iso
  * @param string $key
  * @param null|array $args
  * @return string|array
  */
 private function translate($iso, $key, $args = NULL)
 {
     if (false === isset($this->trans[$iso][$key])) {
         return htmlspecialchars($key) . (is_array($args) ? ': ' . GWF_Array::implode(',', $args) : '');
     }
     return $this->replaceArgs($this->trans[$iso][$key], $args);
 }
Example #10
0
 private function onCSVExport()
 {
     GWF_Website::plaintext();
     $flags = WC_Warflag::getByWarbox($this->warbox, 'wf_order ASC');
     echo self::CSV_COLUMNS . PHP_EOL;
     foreach ($flags as $flag) {
         $flag instanceof WC_Warflag;
         $input = array($flag->getVar('wf_order'), $flag->getVar('wf_cat'), $flag->getVar('wf_score'), $flag->getVar('wf_title'), $flag->getVar('wf_url'), $flag->getVar('wf_authors'), $flag->getVar('wf_status'), $flag->getVar('wf_login'), '', $flag->isWarchall() ? 'SSH' : 'WEB');
         echo GWF_Array::toCSV($input) . PHP_EOL;
     }
     die(0);
 }
Example #11
0
 /**
  * Display classnames of missing quests in a city.
  * @param SR_Player $player
  * @param array $quests
  * @param array $args
  * @return true
  */
 private static function displayMissing(SR_Player $player, array $quests, array $args)
 {
     if (count($args) === 1) {
         $args[] = $player->getParty()->getCity();
     }
     if (count($args) !== 2) {
         return self::reply($player, Shadowhelp::getHelp($player, 'quests'));
     }
     if (false === ($city = Shadowrun4::getCityByAbbrev($args[1]))) {
         return self::reply($player, Shadowhelp::getHelp($player, 'quests'));
     }
     $cityname = $city->getName();
     $names = array();
     $all = SR_Quest::getQuests();
     foreach ($all as $classname => $quest) {
         $quest instanceof SR_Quest;
         if ($quest->getCityName() !== $cityname) {
             continue;
         }
         $q2 = SR_Quest::getQuest($player, $quest->getVar('sr4qu_name'));
         if ($q2->isUnknown($player)) {
             $names[] = Common::substrFrom($classname, '_', $classname);
         }
     }
     return self::rply($player, '5265', array($cityname, GWF_Array::implodeHuman($names)));
 }
Example #12
0
 private function onSendB($email, $message)
 {
     $admin = GWF_Group::ADMIN;
     if (false === ($adminids = GDO::table('GWF_UserGroup')->selectColumn('ug_userid', "group_name='{$admin}'", '', array('group')))) {
         return GWF_HTML::err('ERR_DATABASE', array(__FILE__, __LINE__));
     }
     $send_to = array();
     foreach ($adminids as $userid) {
         if (false === ($user = GWF_User::getByID($userid))) {
             continue;
         }
         if (false === $user->hasValidMail()) {
             continue;
         }
         if (false === $this->onSendC($email, $message, $user)) {
             continue;
         }
         $send_to[] = $user->displayUsername();
     }
     return $send_to === '' ? GWF_HTML::err('ERR_MAIL_SENT') : $this->module->message('msg_mailed', array(GWF_Array::implodeHuman($send_to)));
 }
Example #13
0
 public function swapMembers(SR_Player $a, SR_Player $b)
 {
     $this->members = GWF_Array::swapAssoc($this->members, $a->getID(), $b->getID());
     $this->recomputeEnums();
     return $this->updateMembers();
 }
Example #14
0
 private function checkNPCEquipmentB(SR_NPC $npc, $key = NULL, $items)
 {
     if ($items === '') {
         return;
     }
     foreach (GWF_Array::arrify($items) as $iname) {
         if (false === ($item = SR_Item::createByName($iname, true, false))) {
             die(sprintf('The NPC %s has an invalid item: %s.', get_class($npc), $iname));
         }
         if ($key !== NULL && $item->getItemType() !== $key) {
             die(sprintf('The NPC %s has %s item in wrong slot %s: %s.', get_class($npc), $item->getItemType(), $key, $iname));
         }
     }
 }
Example #15
0
 private function getMissingIncredientsMessage(SR_Player $player, array $need)
 {
     $back = array();
     foreach ($need as $item) {
         $item instanceof SR_Item;
         $back[] = $item->getAmount() . 'x' . $item->displayFullName($player);
     }
     return GWF_Array::implodeHuman($back);
 }
Example #16
0
 /**
  * Swap the position of 2 items.
  * @author digitalseraphim
  * @param string $item1
  * @param string $item2
  * @return int
  */
 public function swapInvItems($item1, $item2)
 {
     $items1 = array_reverse($this->getInvItems($item1));
     $items2 = array_reverse($this->getInvItems($item2));
     if (count($items1) == 0) {
         return -1;
     }
     if (count($items2) == 0) {
         return -2;
     }
     if ($items1[0]->getName() == $items2[0]->getName()) {
         return -3;
     }
     $this->sr4_inventory = GWF_Array::swapAssoc($this->sr4_inventory, $items1[0]->getID(), $items2[0]->getID());
     $temp = $items1[0]->getMicrotime();
     # Look ma, without temp!
     if ($temp == $items2[0]->getMicrotime()) {
         $temp += 0.001;
         // 1ms
     }
     $items1[0]->saveMicrotime($items2[0]->getMicrotime());
     $items2[0]->saveMicrotime($temp);
     // 		$beforeFirst = array();
     // 		$firstKey = -1;
     // 		$firstVal = null;
     // 		$beforeSecond = array();
     // 		$secondKey = -1;
     // 		$toMove = array();
     // 		$newinv = array();
     // 		$currentAdd =& $beforeFirst;
     // 		foreach($this->sr4_inventory as $key=>$value){
     // 			$vName = $value->getName();
     // 			if($vName == $items1[0]->getName() || $vName == $items2[0]->getName()){
     // 				if($firstKey == -1){
     // 					$firstKey = $key;
     // 					$firstVal = $value;
     // 					$currentAdd =& $beforeSecond;
     // 				}elseif($secondKey == -1 && $vName != $firstVal->getName()){
     // 					$secondKey = $key;
     // 					foreach($beforeFirst as $k => $v){
     // 						$newinv[$k] = $v;
     // 					}
     // 					$newinv[$key] = $value;
     // 					foreach($beforeSecond as $k => $v){
     // 						$newinv[$k] = $v;
     // 					}
     // 					$newinv[$firstKey] = $firstVal;
     // 					foreach($beforeSecond as $k => $v){
     // 						$newinv[$k] = $v;
     // 					}
     // 					foreach($toMove as $k => $v){
     // 						$newinv[$k] = $v;
     // 					}
     // 					$currentAdd =& $newinv;
     // 					$toMove =& $newinv;
     // 				}else{
     // 					$toMove[$key] = $value;
     // 				}
     // 			}else{
     // 				$currentAdd[$key] = $value;
     // 			}
     // 		}
     // 		$this->sr4_inventory = $newinv;
     // 		$this->updateInventory();
 }
Example #17
0
<?php

$lang = array('en' => array('help' => 'Usage: %CMD%. Show the botflagged users in this channel.', 'bots' => '%s bots: %s. And me!', 'nobots' => 'There are no bots here beside me.'), 'de' => array('help' => 'Nutze: %CMD%. Zeige alle User mit einem Botflag in diesem Kanal.', 'bots' => '%s Bots: %s. Und ich!', 'nobots' => 'Es gibt hier keine Bots ausser mir.'));
$plugin = Dog::getPlugin();
$channel = Dog::getChannel();
$names = array();
foreach ($channel->getUsers() as $user) {
    $user instanceof Dog_User;
    if ($user->isBot()) {
        $names[] = $user->getName();
    }
}
$count = count($names);
if ($count === 0) {
    $plugin->rply('nobots');
} else {
    $plugin->rply('bots', array($count, GWF_Array::implodeHuman($names)));
}
Example #18
0
 /**
  * strip values from arraykeys which begin with 'pass'
  * @todo faster way without foreach...
  * print_r and preg_match ?
  * array_map stripos('pass') return '';
  */
 private static function stripPassword(array $a)
 {
     $back = '';
     foreach ($a as $k => $v) {
         if (stripos($k, 'pass') !== false || $k === 'answer') {
             $v = 'xxxxx';
         } elseif (is_array($v) === true) {
             $v = GWF_Array::implode(',', $v);
         }
         $back .= self::$POST_DELIMITER . $k . '=>' . $v;
     }
     return self::shortString($back);
 }
Example #19
0
 public function on_split(SR_Player $player, array $args)
 {
     # Bailout
     $bot = Shadowrap::instance($player);
     if (count($args) !== 1) {
         $bot->reply(Shadowhelp::getHelp($player, 'split'));
         return false;
     }
     # Get Item
     if (false === ($rune = $player->getItem($args[0]))) {
         $bot->rply('1029');
         // 			$bot->reply('You don`t have that item.');
         return false;
     }
     $pid = $player->getID();
     $itemname = $rune->getItemName();
     $ditemname = $rune->displayFullName($player);
     $confirmed = isset(self::$SPLIT_CONFIRM[$pid]) && self::$SPLIT_CONFIRM[$pid] === $rune->getID();
     unset(self::$SPLIT_CONFIRM[$pid]);
     if (!$rune instanceof SR_Rune) {
         $bot->rply('1166');
         // 			$bot->reply('You can only split runes.');
         return false;
     }
     $mods = array_merge($rune->getItemModifiersA($player), $rune->getItemModifiersB());
     if (count($mods) < 2) {
         $bot->rply('1167');
         // 			$bot->reply('This rune has only one modifier.');
         return false;
     }
     # Check price
     $price = $this->calcSplitPrice($player, $rune->getItemPriceStatted());
     $dp = Shadowfunc::displayNuyen($price);
     if (!$player->hasNuyen($price)) {
         $bot->rply('1063', array($dp, $player->displayNuyen()));
         // 			$player->message(sprintf('It would cost %s to split the %s, but you only have %s.', $dp, $itemname, $player->getNuyen()));
         return false;
     }
     # Confirm?
     if (!$confirmed) {
         self::$SPLIT_CONFIRM[$pid] = $rune->getID();
         $bot->rply('5216', array($dp, $ditemname));
         // 			$player->message(sprintf('It would cost %s to split the %s. Retype your command to confirm.', $dp, $itemname));
         return true;
     }
     $runes = array();
     $names = array();
     $mods = array_merge($rune->getItemModifiersA($player), $rune->getItemModifiersB());
     foreach ($mods as $k => $v) {
         $v /= 2;
         $v += Shadowfunc::diceFloat(0.0, $v / 2, 1);
         $v = round($v, 1);
         if ($v >= 0.1) {
             $name = "Rune_of_{$k}:{$v}";
             $rune2 = SR_Item::createByName($name);
             $runes[] = $rune2;
             $names[] = $rune2->displayFullName($player);
         }
     }
     if (false === $rune->deleteItem($player)) {
         $bot->reply(sprintf('Cannot delete rune in %s line %s.', __FILE__, __LINE__));
         return false;
     }
     if (count($runes) === 0) {
         $bot->rply('1168');
         // 			$bot->reply(sprintf('The rune burned into dust while splitting it. You don\'t need to pay.'));
         return true;
     }
     if (false === $player->giveItems($runes)) {
         $bot->reply(sprintf('Cannot give items in %s line %s.', __FILE__, __LINE__));
         return false;
     }
     if (false === $player->pay($price)) {
         $bot->reply(sprintf('Cannot pay price in %s line %s.', __FILE__, __LINE__));
         return false;
     }
     return $bot->rply('5217', array($dp, $ditemname, GWF_Array::implodeHuman($names)));
     // 		return $bot->reply(sprintf('You pay %s and split your %s into %s.', $dp, $itemname, GWF_Array::implodeHuman($names)));
 }
Example #20
0
 /**
  * Check a file for translation errors 
  * @todo remove 2 loops, compare keys with array sort
  */
 private function onCheckFile($path2)
 {
     $this->num_files++;
     $path1 = $this->getOtherPath($path2);
     # English file exists?
     if (!file_exists($path1) || !is_file($path1) || !is_readable($path1)) {
         $this->MissingFile['en'][] = $path1;
         $this->errors['en']++;
         $lang1 = false;
     } else {
         # TODO: try{} to catch syntax errors?!
         include $path1;
         if (!isset($lang) || empty($lang)) {
             $this->EmptyFile['en'][] = $path1;
             $this->errors['en']++;
             $lang = false;
         }
         $lang1 = $lang;
         unset($lang);
     }
     # same paths?
     if ($path1 === $path2) {
         $lang2 = false;
     } elseif (!file_exists($path2) || !is_file($path2) || !is_readable($path2)) {
         # if $lang1 is false or empty, the error lies within the english file, not the translation one
         if (false !== $lang1 && !empty($lang1)) {
             $this->MissingFile['tr'][] = $path2;
             $this->missing['tr']++;
         }
         $lang2 = false;
     } else {
         include $path2;
         if (!isset($lang)) {
             $this->EmptyFile['tr'][] = $path2;
             $this->errors['tr']++;
             $lang = false;
         }
         $lang2 = $lang;
         unset($lang);
     }
     # separation between errors/warns related to english files and errors in tranaltion files
     $errs = array('en' => array(), 'tr' => array());
     $warn = array('en' => array(), 'tr' => array());
     # Check if there really is a lang to check
     if (is_array($lang1)) {
         # English lang file
         foreach ($lang1 as $key => $value) {
             # Value is empty?
             if ($value === '') {
                 $errs['en'][] = $this->module->lang('err_empty_key', array($key));
                 continue;
             }
             # other ISO lang file
             if ($lang2 === false) {
                 continue;
             }
             # Key exists?
             if (false === isset($lang2[$key])) {
                 $errs['tr'][] = $this->module->lang('err_missing_key', array($key));
             } elseif ($lang2[$key] === $lang1[$key]) {
                 $out = is_array($lang2[$key]) ? 'A(' . GWF_Array::implodeHuman($lang2[$key]) . ')' : $lang2[$key];
                 $warn['tr'][] = $this->module->lang('err_key_not_translated', array($key, htmlspecialchars($out)));
             }
         }
         if (isset($lang1[''])) {
             $errs['en'][] = $this->module->lang('err_not_finished', array($path1));
         }
     }
     # Check if there really is a lang to check
     if (is_array($lang2)) {
         if (isset($lang2[''])) {
             $errs['tr'][] = $this->module->lang('err_not_finished', array($path2));
         }
         # TODO: remove, do it faster
         # other-ISO lang file
         foreach ($lang2 as $key => $value) {
             if ($value === '') {
                 $errs['tr'][] = $this->module->lang('err_empty_key', array($key));
             }
         }
     }
     if ($lang2 !== false) {
         $this->errors['tr'] += count($errs['tr']);
         $this->warnings['tr'] += count($warn['tr']);
         $path = GWF_Debug::shortpath(realpath($path2));
         # FIXME: duplication errors if two different modulelang locations
         if (count($errs['tr']) > 0) {
             $this->errErrorMessages[$path] = $errs['tr'];
         }
         if (count($warn['tr']) > 0 && $this->show_warns === true) {
             $this->errWarnMessages[$path] = $warn['tr'];
         }
     }
     if ($lang1 !== false) {
         $this->errors['en'] += count($errs['en']);
         $this->warnings['en'] += count($warn['en']);
         $path = GWF_Debug::shortpath(realpath($path1));
         # FIXME: duplication errors if two different modulelang locations
         if (count($errs['en']) > 0) {
             $this->errErrorMessages[$path] = $errs['en'];
         }
         if (count($warn['en']) > 0 && $this->show_warns === true) {
             $this->errWarnMessages[$path] = $warn['en'];
         }
     }
 }
Example #21
0
 private function missingBits($file, $otherfile)
 {
     include $file;
     $lang_en = $lang;
     include $otherfile;
     $lang2 = $lang;
     foreach ($lang_en as $key => $value) {
         if (is_array($value)) {
             $valueE2 = GWF_Array::implode('[,]', $value);
         } else {
             $valueE2 = $value;
         }
         if (isset($lang2[$key])) {
             $valueO = $lang2[$key];
             if (is_array($valueO)) {
                 $valueO = GWF_Array::implode('[,]', $valueO);
             }
         } else {
             $valueO = $valueE2;
         }
         if ($valueO === $valueE2) {
             $this->addMissingBit($file, $key, $value);
         }
     }
 }
Example #22
0
 private function genConfig()
 {
     $vars = array('site_id', 'site_name', 'site_classname', 'wb_id', 'wb_name', 'wb_levels', 'wb_port', 'wb_host', 'wb_user', 'wb_pass', 'wb_weburl', 'wb_ip', 'wb_whitelist', 'wb_blacklist', 'wb_launched_at');
     $output = GWF_Array::toCSV($vars) . "\n";
     foreach ($this->getWarboxes(true) as $warbox) {
         $warbox instanceof WC_Warbox;
         $data = array();
         foreach ($vars as $var) {
             $data[] = $warbox->getVar($var);
         }
         $output .= GWF_Array::toCSV($data) . "\n";
     }
     // 		$format = '%5s, %15s, %5s, %2s, %64s, %24s, %s'."\n";
     // 		$output = vsprintf('#'.$format, explode(',', 'CLS,IP,prt,RS,warhost,displayname,webhost'));
     // 		foreach ($this->getWarboxes(true) as $warbox)
     // 		{
     // 			$warbox instanceof WC_Warbox;
     // 			$output .= sprintf(' '.$format,
     // 				$warbox->getVar('site_classname'), $warbox->getWarIP(),
     // 				$warbox->getWarPort(), $warbox->getWarReduceScore(),
     // 				$warbox->getWarHost(), $warbox->getSitename(), $warbox->getURL())."\n";
     // 		}
     $_GET['ajax'] = 1;
     GWF_Website::plaintext();
     return $output;
 }
Example #23
0
 public static function getItemCI($name)
 {
     return GWF_Array::getCaseI(self::$items, $name);
 }
Example #24
0
 public function getHelpTextNPCs(SR_Player $player)
 {
     $npcs = $this->getNPCS($player);
     # None
     if (count($npcs) === 0) {
         return false;
     }
     # Single
     if (count($npcs) === 1) {
         $cmd = '#' . key($npcs);
         $classname = array_pop($npcs);
         $npc = Shadowrun4::getNPC($classname);
         $npc->setChatPartner($player);
         return ' ' . $player->lang('hlp_talking1', array($cmd, $npc->getName()));
     }
     # Multiple
     $cmds = array();
     foreach ($npcs as $cmd => $classname) {
         $cmds[] = '#' . $cmd;
     }
     return ' ' . $player->lang('hlp_talking2', array(GWF_Array::implodeHuman($cmds)));
 }