Roarl

Members
  • Content Count

    32
  • Joined

  • Last visited

  • Days Won

    4

Roarl last won the day on October 18

Roarl had the most liked content!

Community Reputation

29 Excellent

1 Follower

About Roarl

  • Rank
    Advanced Member

Personal Information

  • Specialty
    Level Design
    DBC Editing
    Lore/Quests

Contacts

  • Discord
    Pixel Weaver#5446
  • Skype
    antoine.cajot

Recent Profile Visitors

3,251 profile views
  1. Roarl

    GossipSelect triggered twice

    Hi, thanks for your answer. I get your point and indeed, adding a second GossipItem in the menu before sending it works. But do you know why it is that way ? And do you have any idea why it works for Rochet2's script and not for mine ? For instance, in the code below at case case EQUIPMENT_SLOT_END + 9: the menu is working as it should. static bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) { ClearGossipMenuFor(player); WorldSession* session = player->GetSession(); switch (sender) { case EQUIPMENT_SLOT_END: // Show items you can use ShowTransmogItems(player, creature, action); break; case EQUIPMENT_SLOT_END + 1: // Main menu OnGossipHello(player, creature); break; case EQUIPMENT_SLOT_END + 2: // Remove Transmogrifications { bool removed = false; for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) { if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) { if (!newItem->transmog) continue; newItem->transmog = 0; newItem->SetState(ITEM_CHANGED, player); sTransmogrification->UpdateItem(player, newItem); removed = true; } } if (removed) session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_UNTRANSMOG_OK)); else session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS); OnGossipHello(player, creature); } break; case EQUIPMENT_SLOT_END + 3: // Remove Transmogrification from single item { if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, action)) { if (newItem->transmog) { newItem->transmog = 0; newItem->SetState(ITEM_CHANGED, player); sTransmogrification->UpdateItem(player, newItem); session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_UNTRANSMOG_OK)); } else session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS); } OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, action); } break; #ifdef PRESETS case EQUIPMENT_SLOT_END + 4: // Presets menu { if (!sTransmogrification->EnableSets) { OnGossipHello(player, creature); return true; } if (sTransmogrification->EnableSetInfo) AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Book_11:30:30:-18:0|tHow sets work", EQUIPMENT_SLOT_END + 10, 0); if (!player->presetMap.empty()) { for (PresetMapType::const_iterator it = player->presetMap.begin(); it != player->presetMap.end(); ++it) AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|t" + it->second.name, EQUIPMENT_SLOT_END + 6, it->first); if (player->presetMap.size() < sTransmogrification->MaxSets) AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", EQUIPMENT_SLOT_END + 8, 0); } else AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", EQUIPMENT_SLOT_END + 8, 0); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 1, 0); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); } break; case EQUIPMENT_SLOT_END + 5: // Use preset { if (!sTransmogrification->EnableSets) { OnGossipHello(player, creature); return true; } // action = presetID PresetMapType::const_iterator it = player->presetMap.find(action); if (it != player->presetMap.end()) { for (PresetslotMapType::const_iterator it2 = it->second.slotMap.begin(); it2 != it->second.slotMap.end(); ++it2) if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, it2->first)) sTransmogrification->PresetTransmog(player, item, it2->second, it2->first); } OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 6, action); } break; case EQUIPMENT_SLOT_END + 6: // view preset { if (!sTransmogrification->EnableSets) { OnGossipHello(player, creature); return true; } // action = presetID PresetMapType::const_iterator it = player->presetMap.find(action); if (it == player->presetMap.end()) { OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 4, 0); return true; } for (PresetslotMapType::const_iterator it2 = it->second.slotMap.begin(); it2 != it->second.slotMap.end(); ++it2) AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sTransmogrification->GetItemIcon(it2->second, 30, 30, -18, 0) + sTransmogrification->GetItemLink(it2->second, session), sender, action); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|tUse set", EQUIPMENT_SLOT_END + 5, action, "Using this set for transmogrify will bind transmogrified items to you and make them non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + it->second.name, 0, false); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-LeaveItem-Opaque:30:30:-18:0|tDelete set", EQUIPMENT_SLOT_END + 7, action, "Are you sure you want to delete " + it->second.name + "?", 0, false); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); } break; case EQUIPMENT_SLOT_END + 7: // Delete preset { if (!sTransmogrification->EnableSets) { OnGossipHello(player, creature); return true; } // action = presetID auto it = player->presetMap.find(action); if (it != player->presetMap.end()) { CharacterDatabase.PExecute("DELETE FROM `custom_transmogrification_sets` WHERE `Owner` = %u AND `PresetID` = %u", player->GetGUID().GetCounter(), uint32(action)); player->presetMap.erase(it); } OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 4, 0); } break; case EQUIPMENT_SLOT_END + 8: // Save preset { if (!sTransmogrification->EnableSets) { OnGossipHello(player, creature); return true; } if (player->presetMap.size() >= sTransmogrification->MaxSets) { OnGossipHello(player, creature); return true; } uint32 cost = 0; bool canSave = false; for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) { if (!sTransmogrification->GetSlotName(slot, session)) continue; if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) { uint32 entry = newItem->transmog; if (!entry) continue; const ItemTemplate* temp = sObjectMgr->GetItemTemplate(entry); if (!temp) continue; if (!sTransmogrification->SuitableForTransmogrification(player, temp)) // no need to check? continue; cost += sTransmogrification->GetSpecialPrice(temp); canSave = true; AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sTransmogrification->GetItemIcon(entry, 30, 30, -18, 0) + sTransmogrification->GetItemLink(entry, session), EQUIPMENT_SLOT_END + 8, 0); } } if (canSave) AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", 0, 0, "Insert set name", cost*sTransmogrification->SetCostModifier + sTransmogrification->SetCopperCost, true); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", sender, action); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); } break; case EQUIPMENT_SLOT_END + 10: // Set info { AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0); SendGossipMenuFor(player, sTransmogrification->SetNpcText, creature->GetGUID()); } break; #endif case EQUIPMENT_SLOT_END + 9: // Transmog info { AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 1, 0); SendGossipMenuFor(player, sTransmogrification->TransmogNpcText, creature->GetGUID()); } break; default: // Transmogrify { if (!sender && !action) { OnGossipHello(player, creature); return true; } // sender = slot, action = display TransmogTrinityStrings res = sTransmogrification->Transmogrify(player, ObjectGuid(HighGuid::Item, 0, action), sender); if (res == LANG_ERR_TRANSMOG_OK) session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_TRANSMOG_OK)); else session->SendNotification(res); // OnGossipSelect(player, EQUIPMENT_SLOT_END, sender); new Timed(player, creature, EQUIPMENT_SLOT_END, sender); } break; } return true; }
  2. Roarl

    Сustom Battleground

    What version of the game are you using ? What emulator are you using ? ( I am going to guess 3.3.5 and TrinityCore from now on ) In any case, you should start by getting used to TrinityCore code and understanding how they implemented battlegrounds in the first place. When you are done coding the battleground itself, you can either replace one of the existing battlegrounds with it, or create a custom NPC to queue for it, or add it in BattlemasterList.dbc I guess. There might be additionnal .dbc work involved, I am not sure.
  3. Roarl

    WMO Blender Addon | Complete guide

    Not sure I am gonna use this anytime soon but this is amazing... No idea why I didn't stumble on it earlier ! Good work both, and very nice and exhaustive tutorial !
  4. Version 1.0.0

    8 downloads

    I always disliked how the AuctionHouseBot handled selling and buying items randomly in the recent TrinityCore releases. It used the in-game npc seller price to determine both the sell and buy prices on the AH for the bot resulting in prices being to damn low (generally) or really too high (less often) and sold strange random items sometimes never sold by players. With this version of the AuctionHouseBot, the sell and buy prices are worked out from an external table in the world database called auction_prices which simply contains item ids and their price in copper. ONLY items belonging to this table can be sold or bought by the bot and their price in the table is used to determine both the sell price and the buy price. The contents of the auction_prices table has been generated using sampled AH data from several private servers and will be updated from time to time. General rules : The chance of an item being bought when the price is higher than the table price is a decaying exponential. The exponential decays later if no other instance of an item is sold. E.G. If you have a monopoly on [Copper Ore] then the bot knows that the price of [Copper Ore] is a bit higher than usual. The bot will NEVER buy an item if another instance of that item is sold for less. This is simply more realistic. An item sold by a player that can be bought from a npc using base money will never be bought by the bot even if it appears in auction_prices, to avoid exploit. They still can be sold by the bot, though. Of course, a code is never perfect. Should you have any suggestion for the bot behavior, problems to report or improvements to make in the code, feel free to leave a comment. Installation : Move the 6 .cpp files to your \src\server\game\AuctionHouseBot TrinityCore source directory and replace the existing ones Don't forget to commit them if you use git Recompile your core Apply the auction_prices.sql statement to your world database Apply the update.sql statement to your world database, if there is one. [Repeat step 5 only for each future update] Changelog : # Changelog ## [1.0.0] - 2018-09-27 ### Created
  5. Roarl

    GossipSelect triggered twice

    Hello, I am currently working on a small housing system and am almost done with the bare bones but something is still refusing to work properly. I want to add a very small description of how the housing system works in a gossip menu, but as soon as SendGossipMenuFor it triggers the OnGossipHello instantly. I compared this part to the Transmogrifier script of Rochet2, which works fine, and it really looks the same so I do not get what I am doing wrong. More concretly, when I click "Why acquire a property ?" in the first menu, the relevant action (case 1 in OnGossipSelect in the code below) is executed (as expected) but then instantly the action made available in the next menu is also executed instantly (default case, with action = 3) : in the end the second menu never appears, instead OnGossipHello is executed again. Does anyone have any idea how to avoid this ? Thanks in advance for your time ! class npc_house_seller : public CreatureScript { public: npc_house_seller() : CreatureScript("npc_house_seller") { } class npc_house_sellerAI : public ScriptedAI { public: npc_house_sellerAI(Creature* creature) : ScriptedAI(creature) {} bool GossipHello(Player* player) override { return OnGossipHello(player, me); } static bool OnGossipHello(Player* player, Creature* creature) { WorldSession* session = player->GetSession(); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Book_11:30:30:-18:0|tWhy acquire a property ?", 1, 0); std::stringstream warningMessage; warningMessage.str(std::string()); warningMessage << "Are you sure you want to proceed ? It will cost you " << HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price / 10000 << " gold and strip you of any previous estate property."; AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Enchant_Disenchant:30:30:-18:0|tPurchase this estate", 2, 0, warningMessage.str().c_str(), 0, false); SendGossipMenuFor(player, 800001, creature->GetGUID()); return true; } bool GossipSelect(Player* player, uint32 /*menu_id*/, uint32 gossipListId) override { uint32 sender = player->PlayerTalkClass->GetGossipOptionSender(gossipListId); uint32 action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); return OnGossipSelect(player, me, sender, action); } static bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) { ClearGossipMenuFor(player); WorldSession* session = player->GetSession(); switch (sender) { case 1: { AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", 3, 0); SendGossipMenuFor(player, 800002, creature->GetGUID()); } break; case 2: if (player->HasEnoughMoney(HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price)) { House* house = HousingSystem::instance()->HouseFromPlayer(player->GetGUID().GetCounter()); if (house != nullptr) { house->_owner = 0; // Respawn NPC Map* map = sMapMgr->FindBaseNonInstanceMap(house->_map_id); Position pos(house->_coord_x, house->_coord_y, house->_coord_z, house->_orientation); Creature* cbuffer = new Creature(); if (!cbuffer->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, PHASEMASK_ANYWHERE, 50006, pos)) delete cbuffer; cbuffer->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), PHASEMASK_ANYWHERE); ObjectGuid::LowType db_guid = cbuffer->GetSpawnId(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells() // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior cbuffer->CleanupsBeforeDelete(); delete cbuffer; cbuffer = new Creature(); if (!cbuffer->LoadFromDB(db_guid, map, true, true)) delete cbuffer; sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); house->_seller = db_guid; HousingSystem::instance()->AdaptSellerMapOnHouseChange(db_guid, house); house->SaveToDB(); } house = HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId()); house->_owner = player->GetGUID().GetCounter(); house->_seller = 0; house->SaveToDB(); HousingSystem::instance()->AdaptPlayerMapOnHouseChange(house->_owner, house); // Remove Creature ObjectGuid::LowType guid = creature->GetGUID().GetCounter(); creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); player->ModifyMoney(0-HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price, false); std::stringstream yay; yay.str(std::string()); yay << "Congratulations ! You are now the proud owner of this estate ! "; WorldPacket data(SMSG_MOTD); Tokenizer motdTokens(yay.str(), '@'); data << uint32(motdTokens.size()); for (Tokenizer::const_reference token : motdTokens) data << token; player->GetSession()->SendPacket(&data); player->AddItem(60073,1); player->PlayerTalkClass->SendCloseGossip(); } else { std::stringstream nope; nope.str(std::string()); nope << "You cannot afford that property ! You need at least " << HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price/10000 << " gold."; session->SendNotification(nope.str().c_str()); player->PlayerTalkClass->SendCloseGossip(); } break; default: { std::stringstream nope; nope.str(std::string()); nope << "Triggered " << sender << " !"; session->SendNotification(nope.str().c_str()); } return OnGossipHello(player, creature); } return true; } }; CreatureAI* GetAI(Creature *creature) const override { return new npc_house_sellerAI(creature); } };
  6. Roarl

    Coffee Induced Dreams

    Amazing work, keep it up !
  7. Roarl

    Alastor Void Case Pack

    No comments no rating for this? Always loved your work, Alastor, these models are awesome. I've stopped modding as well but I think this is a really nice release. They look even better ingame. Cheers
  8. Roarl

    WoD npc models for WoTLK + textures

    Oh, nothing serious. I think I spotted some typos in the F.A.Q. and in the description. Just corrected them.... Also added a quote of Amaroth in the F.A.Q so that the information given is relevant. I can PM you when I release the new models if you wanna.
  9. Roarl

    [HELP!] N.P.C. Importing Issues:-S

    Hi dude, You need to provide a password in the Session Manager window of HeidiSQL (seen @ 0:44). You should be able to find it in the config files of your server (which I guess are located in the configs directory of Arcemu in your case). Once you get there look for something like LoginDatabaseInfo = "127.0.0.1;3306;root;ROOT;auth" WorldDatabaseInfo = "127.0.0.1;3306;root;ROOT;world" CharacterDatabaseInfo = "127.0.0.1;3306;root;ROOT;characters"In this example, root is the user and ROOT is the password. These lines are from TrinityCore but it should not be so different from Arcemu. Cheers
  10. Roarl

    3.3.5 [T.C.] Moving Platforms

    Thank you! Yes I surely will update both the tool and the tutorial at some point (E.G. it would be great if the tool could load the last ID from the dbc and append the animation directly to it )
  11. That will do! Thanks dude!
  12. Roarl

    3.3.5 [T.C.] Moving Platforms

    Basic platform animationsSo, you are building a platform game and you want to spice things up a trifle? Or maybe you just want an elevator for your custom map? You just hit the right tutorial then! A. RequirementsDBCUtil ( or any DBC<->CSV tool) (I think MyDBCEditor sucks here because it uses hexa for some columns which tends to complicate things a lot)Ladik's MPQ EditorA TrinityCore serverA kebab skewerB. Table of ContentsCreating the GameObjectGetting TransportAnimation.dbcEditing TransportAnimation.dbc.csvBPAG releaseC. Tutorial1.Creating the GameObjectOpen your favorite SQL Editor and head to the gameobject_template table. Once you get there create an entry for your custom gameobject, set the type as 11 (GAMEOBJECT_TYPE_TRANSPORT)and use whatever displayID you want to use. SET THE FLAGS TO 40 (without that, your character will not move with the platform) Note down its Guid. N.B.I Modifying the size will NOT have any effect as animated gameobjects always have their standard size in-game ( that is to say 1 ). 2.Getting TransportAnimation.dbcIf you built TrinityCore in the "C:\Build" directory for instance, you should find the dbc files in "C:\Build\bin\Release\dbc". Copy TransportAnimation.dbc and paste it where you are going to use DBCUtil. 3.Editing TransportAnimation.dbc.csvAfter you have converted TransportAnimation.dbc to csv (simple drag and drop on DBCUtil will do), let us open it with your favorite text / csv editor. The columns of the TransportAnimation are 1 ID Integer 2 TransportID Integer 3 TimeIndex Integer 4 PosX Float 5 PosY Float 6 PosZ Float 7 iRefID_SequenceID Integer (from http://pxr.dk/wowdev/wiki/). Foremost, once the server notified your client that it is encountering a transport gameobject(GAMEOBJECT_TYPE_TRANSPORT), your client plays the transport animation which he reads from TransportAnimation.dbc. He will find the animation in the dbc using the Guid of the gameobject (TransportID). The animation is then sequenced through time using the TimeIndex which is expressed in milliseconds. The 4th, 5th and 6th columns express the relative displacement of the gameobject along the Y, X and Z axis respectively (careful here, the wiki states that it rather is X, Y, Z but it's actually not the case). Eventually, the last column is the animation played by the gameobject. It is NOT compulsory but when the model you are using as moving platform has animations, why not take advantage of it? Here an example : 179710, 301034, 0, 0, 0, 0, 148, 179711, 301034, 0, 0, 0, 0, 148, 179712, 301034, 3000, -29.1, -1.6, 0, 148, 179713, 301034, 3000, -29.1, -1.6, 0, 149, 179714, 301034, 3030, -29.1, -1.6, 0, 146, 179715, 301034, 6030, 0, 0, 0, 146,Once you have done all this, convert the csv file back to dbc and put it in the dbc folder of TrinityCore AS WELL AS in your custom patch using the MPQ Editor. 4.BPAG releaseAs you create animations, you will soon find out writing these rows is a tedious work. I have therefore written a tiny console tool which will write them for you (christened BPAG, an acronym for Basic Platform Animation Generator (the name is pretty cool but this piece of software is total bullshit )). You can download it here. You will need to feed the BPAG with several details, let me explain them to you. First ID : the ID (first column) of the last row of the TransportAnimation.dbc file PLUS one. gobGUID : the Guid of the gameobject you are using Start position : Coordinates of the starting point of your platform, X, Y, Z in order (E.G. 123 451 154) End Position : Coordinates of the return point of your platform, X, Y, Z in order (E.G. 123 451 154) Travel Time (ms) : The time that the platform will take to travel from the the starting point to the return point (in milliseconds). Pause Time (ms) : If you want your platform to stop at the starting position and at the return position (useful for elevators) (in milliseconds) Is it a two-speed platform ? (y/n) : Answer by y/Y (yes) or n/N (no). Two-speed platforms will speed up after some time interval. Speed ratio (if it is a two-speed platform) : If you want the platform to go 5 times faster after the previously mentioned time interval, input 5. Speed change time (ms) (if it is a two-speed platform) : Is the previously mentioned time interval in milliseconds Once you have provided the BPAG with all this, you will find the generated animation in output.txt (same directory as the .exe). You only have to paste that at the end of TransportAnimation.dbc.csv then convert it back to dbc.
  13. Hi there! How do you access the (player) user of a gameobject? For instance, let us consider this simple gameobject script : class go_chairofjudgmentgood : public GameObjectScript { public: go_chairofjudgmentgood() : GameObjectScript("go_chairofjudgmentgood") { } struct go_chairofjudgmentgoodAI : public GameObjectAI { uint32 goTimer; go_chairofjudgmentgoodAI(GameObject* go) : GameObjectAI(go) {} void Reset() { goTimer = 7000; } void UpdateAI(uint32 diff) override { GameObjectAI::UpdateAI(diff); if (goTimer <= diff) { //HERE } else goTimer -= diff; } }; GameObjectAI * GetAI(GameObject * go) const { return new go_chairofjudgmentgoodAI(go); } };Let us assume the object type of the chairofjudgmentgood is indeed a chair. How could I get the Player (class) of the player sitting on the chair at line 23 (//HERE)? Thanks in advance for your help
  14. Roarl

    What Are You Working On?

    And that is so goddamn true... I tried WoD on retail... Well as Amaroth said it's fine but you are not deserving anything you have. Didn't die once before level 43. So... fun? yeah definitely plus the added content and brand new graphics make it really fancy. Challenging? They definitely lack that part since Cataclysm.
  15. Haha I guess I made that mistake as well, and more than once. x) It's funny how it's always the small mistakes we fail to see!