// We are creating a char from the current char and the corpse. // Move the items from the corpse back onto us. bool CChar::RaiseCorpse( CItemCorpse * pCorpse ) { ADDTOCALLSTACK("CChar::RaiseCorpse"); if ( !pCorpse ) return false; if ( pCorpse->GetCount() > 0 ) { CItemContainer *pPack = GetPackSafe(); CItem *pItemNext = NULL; for ( CItem *pItem = pCorpse->GetContentHead(); pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); if ( pItem->IsType(IT_HAIR) || pItem->IsType(IT_BEARD) ) // hair on corpse was copied! continue; if ( pItem->GetContainedLayer() ) ItemEquip(pItem); else if ( pPack ) pPack->ContentAdd(pItem); } pCorpse->ContentsDump( GetTopPoint()); // drop left items on ground } UpdateAnimate((pCorpse->m_itCorpse.m_facing_dir & 0x80) ? ANIM_DIE_FORWARD : ANIM_DIE_BACK, true, true); pCorpse->Delete(); return true; }
bool CChar::NPC_OnTrainPay(CChar *pCharSrc, CItemMemory *pMemory, CItem * pGold) { ADDTOCALLSTACK("CChar::NPC_OnTrainPay"); SKILL_TYPE skill = static_cast<SKILL_TYPE>(pMemory->m_itEqMemory.m_Skill); if ( !IsSkillBase(skill) || !g_Cfg.m_SkillIndexDefs.IsValidIndex(skill) ) { Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_TRAINER_FORGOT)); return false; } int iTrainCost = (int)GetKeyNum("OVERRIDE.TRAINSKILLCOST", true); if ( !iTrainCost ) iTrainCost = g_Cfg.m_iTrainSkillCost; iTrainCost *= NPC_OnTrainCheck(pCharSrc, skill); if ( (iTrainCost <= 0) || !pGold ) return false; Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_TRAINER_SUCCESS ) ); // Can't ask for more gold than the maximum amount of the gold stack i am giving to the npc word iTrainCostFinal = (word)minimum(UINT16_MAX, iTrainCost); // Consume as much money as we can train for. if ( pGold->GetAmount() < iTrainCost ) { iTrainCostFinal = pGold->GetAmount(); } else if ( pGold->GetAmount() == iTrainCostFinal) { Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_TRAINER_THATSALL_1 ) ); pMemory->m_itEqMemory.m_Action = NPC_MEM_ACT_NONE; } else { Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_TRAINER_THATSALL_2 ) ); pMemory->m_itEqMemory.m_Action = NPC_MEM_ACT_NONE; // Give change back. pGold->UnStackSplit( iTrainCostFinal, pCharSrc ); } GetPackSafe()->ContentAdd( pGold ); // take my cash. // Give credit for training. NPC_TrainSkill( pCharSrc, skill, iTrainCost ); return true; }
int CChar::Do_Use_Item(CItem *pItem, bool fLink) { ADDTOCALLSTACK("CChar::Do_Use_Item"); if (!pItem) return false; if (m_pNPC && (IsTrigUsed(TRIGGER_DCLICK) || IsTrigUsed(TRIGGER_ITEMDCLICK))) // for players, DClick was called before this function { if (pItem->OnTrigger(ITRIG_DCLICK, this) == TRIGRET_RET_TRUE) return false; } CItemSpawn *pSpawn = static_cast<CItemSpawn *>(pItem->m_uidSpawnItem.ItemFind()); if (pSpawn) pSpawn->DelObj(pItem->GetUID()); // remove this item from it's spawn when DClicks it int fAction = true; switch(pItem->GetType()) { case IT_ITEM_STONE: { // Give them this item if (pItem->m_itItemStone.m_wAmount == USHRT_MAX) { SysMessageDefault(DEFMSG_MSG_IT_IS_DEAD); return true; } if (pItem->m_itItemStone.m_wRegenTime) { if (pItem->IsTimerSet()) { SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_MSG_STONEREG_TIME), pItem->GetTimerDiff() / TICK_PER_SEC); return true; } pItem->SetTimeout(pItem->m_itItemStone.m_wRegenTime * TICK_PER_SEC); } ItemBounce(CItem::CreateTemplate(pItem->m_itItemStone.m_ItemID, GetPackSafe(), this)); if (pItem->m_itItemStone.m_wAmount != 0) { pItem->m_itItemStone.m_wAmount--; if (pItem->m_itItemStone.m_wAmount == 0) pItem->m_itItemStone.m_wAmount = USHRT_MAX; } return true; } case IT_SEED: return Use_Seed(pItem, NULL); case IT_BEDROLL: return Use_BedRoll(pItem); case IT_KINDLING: return Use_Kindling(pItem); case IT_SPINWHEEL: { if (fLink) return false; // Just make them spin pItem->SetAnim(static_cast<ITEMID_TYPE>(pItem->GetID() + 1), 2 * TICK_PER_SEC); SysMessageDefault(DEFMSG_ITEMUSE_SPINWHEEL); return true; } case IT_TRAIN_DUMMY: { if (fLink) return false; Use_Train_Dummy(pItem, true); return true; } case IT_TRAIN_PICKPOCKET: { if (fLink) return false; Use_Train_PickPocketDip(pItem, true); return true; } case IT_ARCHERY_BUTTE: { if (fLink) return false; Use_Train_ArcheryButte(pItem, true); return true; } case IT_LOOM: { if (fLink) return false; SysMessageDefault(DEFMSG_ITEMUSE_LOOM); return true; } case IT_BEE_HIVE: { if (fLink) return false; // Get honey from it ITEMID_TYPE id = ITEMID_NOTHING; if (!pItem->m_itBeeHive.m_honeycount) SysMessageDefault(DEFMSG_ITEMUSE_BEEHIVE); else { switch(Calc_GetRandVal(3)) { case 1: id = ITEMID_JAR_HONEY; break; case 2: id = ITEMID_BEE_WAX; break; } } if (id) { ItemBounce(CItem::CreateScript(id, this)); pItem->m_itBeeHive.m_honeycount--; } else { SysMessageDefault(DEFMSG_ITEMUSE_BEEHIVE_STING); OnTakeDamage(Calc_GetRandVal(5), this, DAMAGE_POISON | DAMAGE_GENERAL); } pItem->SetTimeout(15 * 60 * TICK_PER_SEC); return true; } case IT_MUSICAL: { if (!Skill_Wait(SKILL_MUSICIANSHIP)) { m_Act_Targ = pItem->GetUID(); Skill_Start(SKILL_MUSICIANSHIP); } break; } case IT_CROPS: case IT_FOLIAGE: { // Pick cotton/hay/etc fAction = pItem->Plant_Use(this); break; } case IT_FIGURINE: { // Create the creature here if (Use_Figurine(pItem) != NULL) pItem->Delete(); return true; } case IT_TRAP: case IT_TRAP_ACTIVE: { // Activate the trap (plus any linked traps) int iDmg = pItem->Use_Trap(); if (CanTouch(pItem->GetTopLevelObj()->GetTopPoint())) OnTakeDamage(iDmg, NULL, DAMAGE_HIT_BLUNT | DAMAGE_GENERAL); break; } case IT_SWITCH: { // Switches can be linked to gates and doors and such. // Flip the switch graphic. pItem->SetSwitchState(); break; } case IT_PORT_LOCKED: if (!fLink && !IsPriv(PRIV_GM)) { SysMessageDefault(DEFMSG_ITEMUSE_PORT_LOCKED); return true; } case IT_PORTCULIS: // Open a metal gate vertically pItem->Use_Portculis(); break; case IT_DOOR_LOCKED: if (!ContentFindKeyFor(pItem)) { SysMessageDefault(DEFMSG_MSG_KEY_DOORLOCKED); if (!pItem->IsTopLevel()) return false; if (pItem->IsAttr(ATTR_MAGIC)) // show it's magic face { ITEMID_TYPE id = (GetDispID() & DOOR_NORTHSOUTH) ? ITEMID_DOOR_MAGIC_SI_NS : ITEMID_DOOR_MAGIC_SI_EW; CItem *pFace = CItem::CreateBase(id); ASSERT(pFace); pFace->MoveToDecay(pItem->GetTopPoint(), 4 * TICK_PER_SEC); } if (!IsPriv(PRIV_GM)) return true; } case IT_DOOR_OPEN: case IT_DOOR: { bool fOpen = pItem->Use_DoorNew(fLink); if (fLink || !fOpen) // don't link if we are just closing the door return true; } break; case IT_SHIP_PLANK: { // Close the plank if I'm inside the ship if (m_pArea->IsFlag(REGION_FLAG_SHIP) && m_pArea->GetResourceID() == pItem->m_uidLink) { if (pItem->m_itShipPlank.m_itSideType == IT_SHIP_SIDE_LOCKED && !ContentFindKeyFor(pItem)) { SysMessageDefault(DEFMSG_ITEMUSE_SHIPSIDE); return true; } return pItem->Ship_Plank(false); } else if (pItem->IsTopLevel()) { // Teleport to plank if I'm outside the ship CPointMap pntTarg = pItem->GetTopPoint(); pntTarg.m_z++; Spell_Teleport(pntTarg, true, false, false); } return true; } case IT_SHIP_SIDE_LOCKED: if (!ContentFindKeyFor(pItem)) { SysMessageDefault(DEFMSG_ITEMUSE_SHIPSIDE); return true; } case IT_SHIP_SIDE: // Open the plank pItem->Ship_Plank(true); return true; case IT_GRAIN: case IT_GRASS: case IT_GARBAGE: case IT_FRUIT: case IT_FOOD: case IT_FOOD_RAW: case IT_MEAT_RAW: { if (fLink) return false; Use_Eat(pItem); return true; } case IT_POTION: case IT_DRINK: case IT_PITCHER: case IT_WATER_WASH: case IT_BOOZE: { if (fLink) return false; Use_Drink(pItem); return true; } case IT_LIGHT_OUT: // can the light be lit? case IT_LIGHT_LIT: // can the light be doused? fAction = pItem->Use_Light(); break; case IT_CLOTHING: case IT_ARMOR: case IT_ARMOR_LEATHER: case IT_SHIELD: case IT_WEAPON_MACE_CROOK: case IT_WEAPON_MACE_PICK: case IT_WEAPON_MACE_SMITH: case IT_WEAPON_MACE_SHARP: case IT_WEAPON_SWORD: case IT_WEAPON_FENCE: case IT_WEAPON_BOW: case IT_WEAPON_AXE: case IT_WEAPON_XBOW: case IT_WEAPON_MACE_STAFF: case IT_JEWELRY: case IT_WEAPON_THROWING: { if (fLink) return false; return ItemEquip(pItem); } case IT_WEB: { if (fLink) return false; Use_Item_Web(pItem); return true; } case IT_SPY_GLASS: { if (fLink) return false; // Spyglass will tell you the moon phases static LPCTSTR const sm_sPhases[8] = { g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M1), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M2), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M3), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M4), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M5), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M6), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M7), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M8) }; SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_TR), sm_sPhases[g_World.GetMoonPhase(false)]); SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_FE), sm_sPhases[g_World.GetMoonPhase(true)]); if (m_pArea && m_pArea->IsFlag(REGION_FLAG_SHIP)) ObjMessage(pItem->Use_SpyGlass(this), this); return true; } case IT_SEXTANT: { if (fLink) return false; if ((GetTopPoint().m_map <= 1) && (GetTopPoint().m_x > UO_SIZE_X_REAL)) // dungeons and T2A lands ObjMessage(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEXTANT_T2A), this); else { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEXTANT), m_pArea->GetName(), pItem->Use_Sextant(GetTopPoint())); ObjMessage(pszMsg, this); } return true; } default: fAction = false; } return fAction | MASK_RETURN_FOLLOW_LINKS; }