hujiabin 64ea33df3b 1
2023-07-16 19:16:28 +08:00

846 lines
29 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace models;
require_once('mt/Hero.php');
require_once('mt/HeroLevelAttr.php');
require_once('mt/HeroQuality.php');
require_once('mt/HeroLevel.php');
require_once('mt/AttrHelper.php');
require_once('mt/Item.php');
require_once('models/HeroSkin.php');
require_once('models/Chip.php');
require_once('models/User.php');
require_once('models/ChipPlugin.php');
require_once('services/NftService.php');
require_once('services/FormulaService.php');
require_once('services/ContractConfig.php');
use mt;
use phpcommon;
use phpcommon\SqlHelper;
use services\NftService;
use services\FormulaService;
use services\ContractConfig;
use models\ChipPlugin;
use models\User;
class Hero extends BaseModel {
const GETED_STATE = 0;
const FREE_STATE = 1;
const NO_LOCK = 0;
const LEVEL_LOCK = 1;
const QUALITY_LOCK = 2;
const SEND_LOCK = 3;
const COST_LOCK = 4;
//添加英雄方式
const TYPE_FREE = 0; //免费英雄(D)
const TYPE_1 = 1; //收费英雄(D~B)
const TYPE_2 = 2; //收费英雄(C~A)
const TYPE_3 = 3; //收费英雄(B~S)
const TYPE_4 = 4; //收费英雄(D~S)
public static function find($heroUniId)
{
return self::internalFind(myself()->_getAccountId(), myself()->_getAddress(), $heroUniId);
}
public static function findEx($heroUniId){
$row = SqlHelper::ormSelectOne(
myself()->_getMysql(myself()->_getAccountId()),
't_hero',
array(
'idx' => $heroUniId,
)
);
if ($row) {
if ($row['account_id'] != myself()->_getAccountId()) {
$row = null;
}
}
return $row;
}
public static function findByAccountId($accountId, $heroUniId)
{
return self::internalFind($accountId, User::findUserAddress($accountId), $heroUniId);
}
public static function findByTokenId($tokenId)
{
$row = SqlHelper::ormSelectOne(
myself()->_getMysql($tokenId),
't_hero',
array(
'token_id' => $tokenId,
)
);
if ($row) {
$row['hero_uniid'] = $row['idx'];
if (!NftService::isHeroOwner(myself()->_getAddress(), $row['token_id'])) {
$row = null;
}
}
return $row;
}
public static function findByTokenId2($tokenId)
{
$row = SqlHelper::ormSelectOne(
myself()->_getMysql($tokenId),
't_hero',
array(
'token_id' => $tokenId,
)
);
return $row;
}
private static function internalFind($accountId, $address, $heroUniId)
{
$row = SqlHelper::ormSelectOne(
myself()->_getMysql($accountId),
't_hero',
array(
'idx' => $heroUniId,
)
);
if ($row) {
$row['hero_uniid'] = $row['idx'];
if ($row['account_id'] != $accountId) {
$openId = $address;
if (!NftService::isHeroOwner($openId, $row['token_id'])) {
$row = null;
}
}
}
return $row;
}
public static function getValidHero($heroId)
{
$heroList = array();
Hero::getHeroList(function ($row) use($heroId, &$heroList) {
if ($row['hero_id'] == $heroId && $row['state'] == self::GETED_STATE) {
array_push($heroList, Hero::toDto($row));
}
});
return !empty($heroList) ? $heroList[0] : null;
}
public static function getRawPveCegUpLimit()
{
$cegUpLimit = 0;
self::getHeroList(function ($row) use(&$cegUpLimit) {
$heroDto = self::toDto($row);
$cegUpLimit += $heroDto['raw_pve_ceg_uplimit'];
});
return $cegUpLimit;
}
public static function getHeroList($cb)
{
SqlHelper::ormSelect(
myself()->_getSelfMysql(),
't_hero',
array(
'account_id' => myself()->_getAccountId()
),
function ($row) use($cb) {
$row['tags'] = '';
$cb($row);
}
);
foreach (NftService::getHeros(myself()->_getAddress()) as $nftDb) {
if (! $nftDb['deleted']){
$row = SqlHelper::ormSelectOne(
myself()->_getSelfMysql(),
't_hero',
array(
'token_id' => $nftDb['token_id'],
)
);
//将NFT表的数据同步到中心化英雄表 (以后可能删除)
// if (!$row) {
// $itemMeta = mt\Item::get($nftDb['item_id']);
// if ($itemMeta) {
// self::addNftHero($itemMeta, $nftDb['token_id']);
// $row = SqlHelper::ormSelectOne(
// myself()->_getSelfMysql(),
// 't_hero',
// array(
// 'token_id' => $nftDb['token_id'],
// )
// );
// }
// }
if ($row) {
if (!$row['activate']) {
self::activateHero($row);
$row = SqlHelper::ormSelectOne(
myself()->_getSelfMysql(),
't_hero',
array(
'token_id' => $nftDb['token_id'],
)
);
}
$row['tags'] = $nftDb['tags'];
$cb($row);
}
}
}
}
private static function activateHero($row){
$itemMeta = mt\Item::get($row['hero_id']);
if (!$itemMeta) {
return;
}
// $randAttr = array();
$fieldsKv = array(
// 'hero_lv' => 1,
// 'quality' => 1,
// 'hero_tili' => 0,
// 'state' => self::GETED_STATE,
// 'skill_lv1' => 1,
// 'skill_lv2' => 1,
// 'rand_attr' => json_encode($randAttr),
'lock_type' => self::NO_LOCK,
'unlock_time' => 0,
'unlock_trade_time' => 0,
'activate' => 1,
'modifytime' => myself()->_getNowTime()
);
self::updateByTokenId($row['token_id'],$fieldsKv);
}
public static function toDto($row)
{
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
if (!$attr){
$heroMeta = mt\Hero::get($row['hero_id']);
$baseAttr = mt\Hero::getHeroAttr($heroMeta);
foreach ($baseAttr as $value){
if (in_array($value['attr_id'],array(kHAT_Hp,kHAT_Atk,kHAT_Def))){
array_push($attr,array(
'attr_id' => $value['attr_id'],
'val' => $value['val'] ,
'quality' => rand(2,3),
)
);
}else{
array_push($attr,array(
'attr_id' => $value['attr_id'],
'val' => $value['val'] ,
'quality' => 0,
)
);
}
}
self::update($row['idx'],array(
'rand_attr'=>json_encode($attr)
));
}
// $lockType = 0;
// $unlockTime = 0;
// if ($row['lock_type'] != 0 && $row['unlock_time'] - myself()->_getNowTime() > 0) {
// $lockType = $row['lock_type'];
// $unlockTime = $row['unlock_time'];
// }
{
$lockType = $row['lock_type'];
$unlockTime = $row['unlock_time'];
}
$levelMeta = mt\HeroLevel::getByLevel($row['hero_lv']);
$todayGetGold = $row['today_get_gold'];
$lastGetGoldTime = $row['last_get_gold_time'];
if (myself()->_getDaySeconds($lastGetGoldTime) <
myself()->_getNowDaySeconds()) {
$todayGetGold = 0;
}
$userDb = myself()->_getOrmUserInfo();
$isSelect = 0;
if ($row['idx'] == $userDb['hero_id']){
$isSelect = 1;
}
$skinDb = HeroSkin::findBx($row['hero_id']);
$dto = array(
'idx' => $row['idx'],
'token_id' => $row['token_id'],
'hero_uniid' => $row['idx'],
'hero_id' => $row['hero_id'],
'hero_lv' => $row['hero_lv'],
'hero_tili' => $row['hero_tili'],
'state' => $row['state'],
'skin_id' => $skinDb?$skinDb['skin_id']:0,
'quality' => $row['quality'],
'skill_lv1' => $row['skill_lv1'],
'skill_lv2' => $row['skill_lv2'],
'rand_attr' => $attr,
'try_count' => $row['try_count'],
'lock_type' => $lockType,
'unlock_time' => $unlockTime,
'unlock_lefttime' => max(0,
$unlockTime - myself()->_getNowTime()),
'current_get_gold' => $todayGetGold / 100,
'last_get_gold_time' => $lastGetGoldTime,
'gold_uplimit' => $levelMeta['gold_limit'],
'unlock_trade_time' => $row['unlock_trade_time'],
'advanced_count' => $row['advanced_count'],
'offer_reward_state' => 0,
'tags' => isset($row['tags'])?$row['tags']:'',
'is_select' => $isSelect,
);
$nft_address = '';
$contract = ContractConfig::find(ContractConfig::ERC721);
if ($row['token_id']){
$nft_address = $contract ? $contract['hero'] : "";
}
$dto['nft_address'] = $nft_address;
return $dto;
}
public static function addFreeHero($heroMeta)
{
return self::internalAddHero(
myself()->_getSelfMysql(),
$heroMeta,
myself()->_getAccountId(),
null,
self::TYPE_FREE);
}
public static function addHero1($heroMeta)
{
return self::internalAddHero(
myself()->_getSelfMysql(),
$heroMeta,
myself()->_getAccountId(),
null,
self::TYPE_1);
}
public static function addHero2($heroMeta)
{
return self::internalAddHero(
myself()->_getSelfMysql(),
$heroMeta,
myself()->_getAccountId(),
null,
self::TYPE_2);
}
public static function addHero3($heroMeta)
{
return self::internalAddHero(
myself()->_getSelfMysql(),
$heroMeta,
myself()->_getAccountId(),
null,
self::TYPE_3);
}
public static function addHero($heroMeta)
{
return self::internalAddHero(
myself()->_getSelfMysql(),
$heroMeta,
myself()->_getAccountId(),
null,
self::TYPE_4);
}
public static function addNftHero($heroMeta, $tokenId)
{
return self::internalAddHero(
myself()->_getMysql($tokenId),
$heroMeta,
null,
$tokenId,
self::GETED_STATE);
}
public static function internalAddHero($conn, $heroMeta, $accountId, $tokenId,$type)
{
$skinItemMeta = \mt\Item::getMetaListByType(\mt\Item::HERO_SKIN_TYPE);
if ($skinItemMeta){
foreach ($skinItemMeta as $value){
if ($value['playerid'] == $heroMeta['id'] && $value['isdefaultskin'] ==1){
HeroSkin::addSkin($value);
}
}
}
$state = $type > 0 ? self::GETED_STATE : self::FREE_STATE;
$realHeroMeta = mt\Hero::get($heroMeta['id']);
$randAttr = self::getRandAttr($heroMeta['id'],$type) ;
$fieldsKv = array(
'hero_id' => $heroMeta['id'],
'hero_lv' => 1,
'quality' => 1,
// 'hero_tili' => FormulaService::Hero_NFT_Maximum_Physical_Strength(1,FormulaService::Hero_Advanced_Lucky_Value(1)),
'state' => $state,
'skill_lv1' => 1,
'skill_lv2' => 1,
'rand_attr' => json_encode($randAttr),
'lock_type' => self::NO_LOCK,
'unlock_time' => 0,
'unlock_trade_time' => 0,
'activate' => 1,
'base_attr' => json_encode($randAttr),
'createtime' => myself()->_getNowTime(),
'modifytime' => myself()->_getNowTime()
);
if ($accountId) {
$fieldsKv['account_id'] = $accountId;
}
if ($tokenId) {
$fieldsKv['token_id'] = $tokenId;
}
SqlHelper::insert(
$conn,
't_hero',
$fieldsKv
);
return true;
}
private static function _getAttrQuality($type){
$quality = 0;
switch ($type){
case self::TYPE_FREE :{
$quality = 1;
}break;
case self::TYPE_1 :{
$paramMeta = mt\Parameter::getVal('small_box_quality',0);
}break;
case self::TYPE_2 :{
$paramMeta = mt\Parameter::getVal('big_box_quality',0);
}break;
case self::TYPE_3 :{
$paramMeta = mt\Parameter::getVal('super_box_quality',0);
}break;
case self::TYPE_4 :{
$paramMeta = mt\Parameter::getVal('buy_hero_quality',0);
}break;
default:{
$quality = 1;
}
}
if (isset($paramMeta)){
$weightArr = explode("|",$paramMeta);
$totalWeight = 0;
foreach ($weightArr as $value){
$weights = explode(":",$value);
$totalWeight += $weights[1];
}
$currWeight = 0;
$rnd = rand() % $totalWeight;
foreach ($weightArr as $value){
$weights = explode(":",$value);
$currWeight += $weights[1];
if ($currWeight > $rnd) {
$quality = $weights[0];
break;
}
}
}
return $quality;
}
private static function getRandAttr($heroId,$type){
$heroMeta = mt\Hero::get($heroId);
$baseAttr = mt\Hero::getHeroAttr($heroMeta);
$paramMeta = mt\Parameter::getVal('quality',0);
$attr = array();
if ($paramMeta){
$rate = explode('|',$paramMeta);
foreach ($baseAttr as $value){
if (in_array($value['attr_id'],array(kHAT_Hp,kHAT_Atk,kHAT_Def))){
$quality = self::_getAttrQuality($type);
$minRate = $rate[$quality-1] * 100;
$maxRate = $rate[$quality] * 100 - 1;
if ($quality == 5){
$maxRate = $rate[$quality] * 100;
}
$finalRate = rand($minRate,$maxRate) / 100;
if ( $value['attr_id'] == kHAT_Hp){
$attr_val = round($value['val'] * $finalRate,0);
}else{
$attr_val = round($value['val'] * $finalRate,2);
}
array_push($attr,array(
'attr_id' => $value['attr_id'],
'val' => $attr_val,
'quality' => $quality,
// 'rate' => $finalRate,
)
);
} else {
array_push($attr,array(
'attr_id' => $value['attr_id'],
'val' => $value['val'] ,
'quality' => 0,
)
);
}
}
}
return $attr;
}
public static function update($heroUniId, $fieldsKv)
{
if (self::find($heroUniId)) {
SqlHelper::update
(myself()->_getSelfMysql(),
't_hero',
array(
'idx' => $heroUniId,
),
$fieldsKv
);
}
}
public static function updateByTokenId($tokenId, $fieldsKv)
{
if (self::findByTokenId($tokenId)) {
SqlHelper::update
(myself()->_getSelfMysql(),
't_hero',
array(
'token_id' => $tokenId,
),
$fieldsKv
);
}
}
public static function randHero(&$heroUniId, &$heroId)
{
$heroUniId = 0;
$heroId = 0;
$heroList = array();
Hero::getHeroList(function ($row) use($heroId, &$heroList) {
// if ($row['state'] == self::GETED_STATE) {
array_push($heroList, Hero::toDto($row));
// }
});
$key = null;
if (count($heroList)>0){
$key = array_rand($heroList, 1);
}
if (!is_null($key)) {
$heroUniId = $heroList[$key]['idx'];
$heroId = $heroList[$key]['hero_id'];
}
}
public static function addTili($heroUniId, $tili)
{
self::update($heroUniId,
array(
'hero_tili' => function () use($tili) {
return "hero_tili + ${tili}";
},
));
}
public static function gainGoldPvp($heroDto, $addGold)
{
$newGold = min($heroDto['gold_uplimit'],
$heroDto['current_get_gold'] + $addGold);
$finalyAddGold = max(0, $newGold - $heroDto['current_get_gold']);
// if ($finalyAddGold > 0) {
// self::update($heroDto['hero_uniid'],
// array(
// 'today_get_gold' => $newGold * 100,
// 'last_get_gold_time' => myself()->_getNowTime()
// ));
// }
return $finalyAddGold;
}
public static function gainGoldPve($heroDto, $addGold)
{
$newGold = min($heroDto['pve_ceg_uplimit'],
$heroDto['current_pve_get_ceg'] + $addGold);
$finalyAddGold = max(0, $newGold - $heroDto['current_pve_get_ceg']);
if ($finalyAddGold > 0) {
self::update($heroDto['hero_uniid'],
array(
'today_pve_get_ceg' => $newGold * 100,
'last_pve_get_ceg_time' => myself()->_getNowTime()
));
}
return $finalyAddGold;
}
public static function gainGoldMission($heroDto, $addGold)
{
$newGold = min($heroDto['mission_ceg_uplimit'],
$heroDto['current_mission_get_ceg'] + $addGold);
$finalyAddGold = max(0, $newGold - $heroDto['current_mission_get_ceg']);
if ($finalyAddGold > 0) {
self::update($heroDto['hero_uniid'],
array(
'today_mission_get_ceg' => $newGold * 100,
'last_mission_get_ceg_time' => myself()->_getNowTime()
));
}
return $finalyAddGold;
}
public static function calcMissionGainGold($heroDto, $count)
{
if ($count <= 0) {
return 0;
}
$newGold = min($heroDto['mission_ceg_uplimit'],
$heroDto['current_mission_get_ceg'] +
$heroDto['mission_ceg_uplimit'] / $count);
$finalyAddGold = max(0, $newGold - $heroDto['current_mission_get_ceg']);
return $finalyAddGold;
}
public static function heroIsLocking($heroDto)
{
if ($heroDto['lock_type']) {
return true;
}
$locking = false;
$heroUniId = !empty($heroDto['hero_uniid']) ? $heroDto['hero_uniid'] : $heroDto['idx'];
{
$idx = 0;
for ($i = 0; $i < kMaxHeroUpQualityNum; ++$i) {
$upHeroUniId = myself()->_getV(TN_HERO_QUALITY_UP, $i);
if ($upHeroUniId == $heroUniId) {
$idx = $i;
$locking = true;
break;
}
}
}
if (!$locking) {
$idx = 0;
for ($i = 0; $i < kMaxHeroUpLevelNum; ++$i) {
$upHeroUniId = myself()->_getV(TN_HERO_LEVEL_UP, $i);
if ($upHeroUniId == $heroUniId) {
$idx = $i;
$locking = true;
break;
}
}
}
return $locking;
}
public static function getFreeHero(){
$hero = array();
Hero::getHeroList(function ($row) use (&$hero) {
if (!$row['token_id']) {
$hero = $row;
}
});
return $hero;
}
public static function toDtoInfo($row){
$heroMeta = mt\Hero::get($row['hero_id']);
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
if ($attr){
foreach ($attr as &$value){
$value['val'] = floor($value['val']);
}
}else{
$attr = mt\Hero::getHeroAttr($heroMeta);
}
$todayGetGold = $row['today_get_gold'];
$lastGetGoldTime = $row['last_get_gold_time'];
if (myself()->_getDaySeconds($lastGetGoldTime) <
myself()->_getNowDaySeconds()) {
$todayGetGold = 0;
}
$todayPveGetCeg = $row['today_pve_get_ceg'];
$lastPveGetCegTime = $row['last_pve_get_ceg_time'];
if (myself()->_getDaySeconds($lastPveGetCegTime) <
myself()->_getNowDaySeconds()) {
$todayPveGetCeg = 0;
}
$info = array(
'idx' => $row['idx'],
'token_id' => $row['token_id'],
'hero_uniid' => $row['idx'],
'hero_name' => $heroMeta['name'],
'hero_id' => $row['hero_id'],
'hero_lv' => $row['hero_lv'],
'hero_tili' => $row['hero_tili'],
'quality' => $row['quality'],
'rand_attr' => $attr,
'current_pvp_get_ceg' => $todayGetGold / 100,
'current_pve_get_ceg' => $todayPveGetCeg / 100,
'advanced_count' => $row['advanced_count'],
);
return $info;
}
public static function getHeroByItemId($itemId){
$hero = array();
self::getHeroList(function ($row) use (&$hero,$itemId) {
if ($row['hero_id'] == $itemId) {
array_push($hero,$row);
}
});
return $hero;
}
public static function nextLvAttr($heroDb){ // 165 249 327
$randAttr = emptyReplace(json_decode($heroDb['rand_attr'], true), array());
$heroLevelMeta = \mt\HeroLevel::getByLevel($heroDb['hero_lv']+1);
// $levelAttrMeta= \mt\HeroLevelAttr::find($heroDb['hero_id']);
// $attr= \mt\HeroLevelAttr::addRandAttr($levelAttrMeta,$type);
foreach ($randAttr as &$val){
if (in_array($val['attr_id'],array(
kHAT_Def,
kHAT_Hp,
kHAT_Atk
))){
$temp = $val['val'] * ($heroLevelMeta['promote']+1);
$val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
}
// if ($val['attr_id'] == kHAT_Def){
// //升级后防御力:上一级防御力*((提升幅度+1^防御力系数)
// $temp = $val['val'] * (pow(($heroLevelMeta['promote']+1),$levelAttrMeta['def_rate']));
//// $temp = $val['val'] * ($heroLevelMeta['promote']+1);
// $val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
//
// }else if( $val['attr_id'] == kHAT_Hp){
// //升级后生命值:上一级生命值*((提升幅度+1^生命值系数)
// $temp = $val['val'] * (pow(($heroLevelMeta['promote']+1),$levelAttrMeta['hp_rate']));
// $val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
// }else if( $val['attr_id'] == kHAT_Atk){
// //升级后攻击力:上一级攻击力*((提升幅度+1^攻击力系数)
// $temp = $val['val'] * (pow(($heroLevelMeta['promote']+1),$levelAttrMeta['atk_rate']));
// $val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
// }
}
return $randAttr;
}
public static function LvUpAddAttr($heroDb){
$heroMeta = mt\Hero::get($heroDb['hero_id']);
$baseAttr = mt\Hero::getHeroAttr($heroMeta);
$attrLv1 = emptyReplace(json_decode($heroDb['base_attr'], true), array());
$randAttr = emptyReplace(json_decode($heroDb['rand_attr'], true), array());
$paramQualityMeta = mt\Parameter::getVal('quality',0);
$heroLevelMeta = \mt\HeroLevel::getByLevel($heroDb['hero_lv']+1);
foreach ($randAttr as &$val){
if (in_array($val['attr_id'],array(
kHAT_Def,
kHAT_Hp,
kHAT_Atk
))){
switch ($val['quality']){
case 1 :{
$paramMeta = mt\Parameter::getVal('d_probability',0);
}break;
case 2 :{
$paramMeta = mt\Parameter::getVal('c_probability',0);
}break;
case 3 :{
$paramMeta = mt\Parameter::getVal('b_probability',0);
}break;
case 4 :{
$paramMeta = mt\Parameter::getVal('a_probability',0);
}break;
default:{
$paramMeta = null;
$temp = $val['val'] * ($heroLevelMeta['promote']+1);
$val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
}
}
$quality = $val['quality'];
if ($paramMeta){
$weightArr = explode("|",$paramMeta);
$totalWeight = 0;
foreach ($weightArr as $value){
$weights = explode(":",$value);
$totalWeight += $weights[1];
}
$currWeight = 0;
$rnd = rand() % $totalWeight;
foreach ($weightArr as $value){
$weights = explode(":",$value);
$currWeight += $weights[1];
if ($currWeight > $rnd) {
$quality = $weights[0];
break;
}
}
if ($val['quality'] != $quality){
$rate = explode('|',$paramQualityMeta);
$minRate = $rate[$quality-1] * 100;
$maxRate = $rate[$quality] * 100 - 1;
if ($quality == 5){
$maxRate = $rate[$quality] * 100;
}
$finalRate = rand($minRate,$maxRate) / 100;
$tempVal = round(self::_getAttrVal($baseAttr,$val['attr_id']) * $finalRate,2);
$val['quality'] = $quality;
$v = ($tempVal / self::_getAttrVal($attrLv1,$val['attr_id'])) * $val['val'] * (1 + $heroLevelMeta['promote']);
$val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $v), 0, -1));
self::_setAttrVal($attrLv1,$val['attr_id'],array(
'val'=>$tempVal,
'quality'=>$quality,
));
}else{
$temp = $val['val'] * ($heroLevelMeta['promote']+1);
$val['val'] = sprintf("%.2f",substr(sprintf("%.3f", $temp), 0, -1));
}
}
}
}
return array(
'base_attr' => $attrLv1,
'rand_attr' => $randAttr,
);
}
private static function _getAttrVal($baseAttr,$attrId){
$hashAttr = array();
foreach ($baseAttr as $value){
$hashAttr[$value['attr_id']] =$value;
}
return $hashAttr[$attrId]['val'];
}
private static function _setAttrVal(&$baseAttr,$attrId,$attrVal){
foreach ($baseAttr as &$value){
if ($value['attr_id'] == $attrId){
$value['val'] = $attrVal['val'];
$value['quality'] = $attrVal['quality'];
}
}
}
}