- Timestamp:
- 11/21/08 08:48:19 (17 years ago)
- Location:
- trunk/src
- Files:
-
- 12 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/CharacterHandler.cpp
r230 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 … … 65 65 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); 66 66 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); 67 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index, amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));67 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); 68 68 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid)); 69 69 res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid)); … … 181 181 std::string name; 182 182 uint8 race_,class_; 183 183 184 recv_data >> name; 184 185 … … 215 216 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); 216 217 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); 218 217 219 if( !classEntry || !raceEntry ) 218 220 { … … 608 610 } 609 611 610 if (! MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar))612 if (!pCurrChar->GetMap()->Add(pCurrChar)) 611 613 { 612 614 AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); … … 1000 1002 uint64 guid; 1001 1003 1002 CHECK_PACKET_SIZE(recv_data, 8 +6);1004 CHECK_PACKET_SIZE(recv_data, 8); 1003 1005 recv_data >> guid; 1004 1006 1005 1007 // not accept declined names for unsupported languages 1006 1008 std::string name; 1007 if(!objmgr.GetPlayerNameByGUID(guid, name))1008 { 1009 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1010 data << (uint32)1;1011 data << guid;1009 if(!objmgr.GetPlayerNameByGUID(guid, name)) 1010 { 1011 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1012 data << uint32(1); 1013 data << uint64(guid); 1012 1014 SendPacket(&data); 1013 1015 return; … … 1015 1017 1016 1018 std::wstring wname; 1017 if(!Utf8toWStr(name, wname))1018 { 1019 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1020 data << (uint32)1;1021 data << guid;1019 if(!Utf8toWStr(name, wname)) 1020 { 1021 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1022 data << uint32(1); 1023 data << uint64(guid); 1022 1024 SendPacket(&data); 1023 1025 return; … … 1026 1028 if(!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using 1027 1029 { 1028 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1029 data << (uint32)1;1030 data << guid;1030 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1031 data << uint32(1); 1032 data << uint64(guid); 1031 1033 SendPacket(&data); 1032 1034 return; … … 1036 1038 DeclinedName declinedname; 1037 1039 1040 CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); 1038 1041 recv_data >> name2; 1039 1042 1040 if(name2 !=name)// character have different name1041 { 1042 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1043 data << (uint32)1;1044 data << guid;1043 if(name2 != name) // character have different name 1044 { 1045 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1046 data << uint32(1); 1047 data << uint64(guid); 1045 1048 SendPacket(&data); 1046 1049 return; … … 1049 1052 for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) 1050 1053 { 1054 CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); 1051 1055 recv_data >> declinedname.name[i]; 1052 1056 if(!normalizePlayerName(declinedname.name[i])) 1053 1057 { 1054 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1055 data << (uint32)1;1056 data << guid;1058 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1059 data << uint32(1); 1060 data << uint64(guid); 1057 1061 SendPacket(&data); 1058 1062 return; … … 1060 1064 } 1061 1065 1062 if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0),declinedname))1063 { 1064 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1065 data << (uint32)1;1066 data << guid;1066 if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0), declinedname)) 1067 { 1068 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1069 data << uint32(1); 1070 data << uint64(guid); 1067 1071 SendPacket(&data); 1068 1072 return; … … 1075 1079 CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid)); 1076 1080 CharacterDatabase.PExecute("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')", 1077 GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(),declinedname.name[2].c_str(),declinedname.name[3].c_str(),declinedname.name[4].c_str());1081 GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); 1078 1082 CharacterDatabase.CommitTransaction(); 1079 1083 1080 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);1081 data << (uint32)0; // OK1082 data << guid;1084 WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); 1085 data << uint32(0); // OK 1086 data << uint64(guid); 1083 1087 SendPacket(&data); 1084 1088 } -
trunk/src/game/Pet.cpp
r253 r262 287 287 ++iter; 288 288 m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str()); 289 290 // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST 291 // so overwrite old state 292 SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction); 293 if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST; 289 294 } 290 295 … … 1323 1328 SetUInt32Value(i, 0); 1324 1329 1325 QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index, amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());1330 QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); 1326 1331 1327 1332 if(result) … … 1333 1338 uint32 spellid = fields[1].GetUInt32(); 1334 1339 uint32 effindex = fields[2].GetUInt32(); 1335 int32 damage = (int32)fields[3].GetUInt32(); 1336 int32 maxduration = (int32)fields[4].GetUInt32(); 1337 int32 remaintime = (int32)fields[5].GetUInt32(); 1338 int32 remaincharges = (int32)fields[6].GetUInt32(); 1340 uint32 stackcount= fields[3].GetUInt32(); 1341 int32 damage = (int32)fields[4].GetUInt32(); 1342 int32 maxduration = (int32)fields[5].GetUInt32(); 1343 int32 remaintime = (int32)fields[6].GetUInt32(); 1344 int32 remaincharges = (int32)fields[7].GetUInt32(); 1339 1345 1340 1346 SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); … … 1373 1379 continue; 1374 1380 1375 Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); 1376 1377 if(!damage) 1378 damage = aura->GetModifier()->m_amount; 1379 aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); 1380 AddAura(aura); 1381 for(uint32 i=0; i<stackcount; i++) 1382 { 1383 Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); 1384 1385 if(!damage) 1386 damage = aura->GetModifier()->m_amount; 1387 aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); 1388 AddAura(aura); 1389 } 1381 1390 } 1382 1391 while( result->NextRow() ); … … 1391 1400 1392 1401 AuraMap const& auras = GetAuras(); 1393 for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) 1394 { 1395 // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. 1396 SpellEntry const *spellInfo = itr->second->GetSpellProto(); 1397 uint8 i; 1398 for (i = 0; i < 3; i++) 1399 if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || 1400 spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || 1401 spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) 1402 if (auras.empty()) 1403 return; 1404 1405 spellEffectPair lastEffectPair = auras.begin()->first; 1406 uint32 stackCounter = 1; 1407 1408 for(AuraMap::const_iterator itr = auras.begin(); ; ++itr) 1409 { 1410 if(itr == auras.end() || lastEffectPair != itr->first) 1411 { 1412 AuraMap::const_iterator itr2 = itr; 1413 // save previous spellEffectPair to db 1414 itr2--; 1415 SpellEntry const *spellInfo = itr2->second->GetSpellProto(); 1416 /// do not save single target auras (unless they were cast by the player) 1417 if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))) 1418 { 1419 if(!itr2->second->IsPassive()) 1420 { 1421 // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. 1422 uint8 i; 1423 for (i = 0; i < 3; i++) 1424 if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || 1425 spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || 1426 spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) 1427 break; 1428 1429 if (i == 3) 1430 { 1431 CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " 1432 "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')", 1433 m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges)); 1434 } 1435 } 1436 } 1437 if(itr == auras.end()) 1402 1438 break; 1403 1404 if (i != 3) 1405 continue; 1406 1407 if(itr->second->IsPassive()) 1408 continue; 1409 1410 /// do not save single target auras (unless they were cast by the player) 1411 if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)) 1412 continue; 1413 1414 CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) " 1415 "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')", 1416 m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges)); 1439 } 1440 1441 if (lastEffectPair == itr->first) 1442 stackCounter++; 1443 else 1444 { 1445 lastEffectPair = itr->first; 1446 stackCounter = 1; 1447 } 1417 1448 } 1418 1449 } … … 1434 1465 return false; 1435 1466 } 1467 1468 // same spells don't have autocast option 1469 if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) active = ACT_CAST; 1436 1470 1437 1471 PetSpellMap::iterator itr = m_spells.find(spell_id); … … 1509 1543 CastSpell(this, spell_id, true); 1510 1544 else if(state == PETSPELL_NEW) 1511 m_charmInfo->AddSpellToAB(oldspell_id, spell_id );1545 m_charmInfo->AddSpellToAB(oldspell_id, spell_id, active); 1512 1546 1513 1547 if(newspell->active == ACT_ENABLED) … … 1659 1693 return; 1660 1694 1661 if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid))1662 if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER1663 && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE)1664 return;1695 //if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid)) 1696 // if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER 1697 // && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE) 1698 // return; 1665 1699 1666 1700 PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid); -
trunk/src/game/SharedDefines.h
r253 r262 249 249 #define SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY 0x00008000 // 15 remove auras on immunity 250 250 #define SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE 0x00010000 // 16 unaffected by school immunity 251 #define SPELL_ATTR_EX_UN K170x00020000 // 17251 #define SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET 0x00020000 // 17 252 252 #define SPELL_ATTR_EX_UNK18 0x00040000 // 18 253 253 #define SPELL_ATTR_EX_UNK19 0x00080000 // 19 -
trunk/src/shared/Database/DatabaseEnv.h
r149 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/DatabaseImpl.h
r173 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/DatabaseMysql.cpp
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/DatabaseMysql.h
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/Field.cpp
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/Field.h
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/QueryResult.h
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/SqlOperations.cpp
r230 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/shared/Database/SqlOperations.h
r102 r262 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20