diff --git a/Source/towners.cpp b/Source/towners.cpp index df3c07565..7a2c3abc7 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -26,15 +26,15 @@ Displacement CowOffsets[8] = { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { - /** Specifies the active sound effect ID for interacting with cows. */ _sfx_id CowPlaying = SFX_NONE; -struct TownerInit { +struct TownerData { _talker_id type; Point position; Direction dir; - void (*init)(TownerStruct &towner, const TownerInit &initData); - void (*talk)(Player &player, TownerStruct &towner); + void (*init)(Towner &towner, const TownerData &townerData); + void (*talk)(Player &player, Towner &towner); }; -void NewTownerAnim(TownerStruct &towner, byte *pAnim, uint8_t numFrames, int delay) +void NewTownerAnim(Towner &towner, byte *pAnim, uint8_t numFrames, int delay) { towner._tAnimData = pAnim; towner._tAnimLen = numFrames; @@ -43,21 +43,21 @@ void NewTownerAnim(TownerStruct &towner, byte *pAnim, uint8_t numFrames, int del towner._tAnimDelay = delay; } -void InitTownerInfo(int i, const TownerInit &initData) +void InitTownerInfo(int i, const TownerData &townerData) { auto &towner = Towners[i]; - towner._ttype = initData.type; - towner.position = initData.position; - towner.talk = initData.talk; + towner._ttype = townerData.type; + towner.position = townerData.position; + towner.talk = townerData.talk; towner.seed = AdvanceRndSeed(); // TODO: Narrowing conversion, tSeed might need to be uint16_t dMonster[towner.position.x][towner.position.y] = i + 1; - initData.init(towner, initData); + townerData.init(towner, townerData); } -void LoadTownerAnimations(TownerStruct &towner, const char *path, int frames, Direction dir, int delay) +void LoadTownerAnimations(Towner &towner, const char *path, int frames, Direction dir, int delay) { towner.data = LoadFileInMem(path); for (auto &animation : towner._tNAnim) { @@ -69,7 +69,7 @@ void LoadTownerAnimations(TownerStruct &towner, const char *path, int frames, Di /** * @brief Load Griswold into the game */ -void InitSmith(TownerStruct &towner, const TownerInit &initData) +void InitSmith(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -85,11 +85,11 @@ void InitSmith(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\Smith\\SmithN.CEL", 16, initData.dir, 3); + LoadTownerAnimations(towner, "Towners\\Smith\\SmithN.CEL", 16, townerData.dir, 3); towner.name = _("Griswold the Blacksmith"); } -void InitBarOwner(TownerStruct &towner, const TownerInit &initData) +void InitBarOwner(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -107,20 +107,20 @@ void InitBarOwner(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\TwnF\\TwnFN.CEL", 16, initData.dir, 3); + LoadTownerAnimations(towner, "Towners\\TwnF\\TwnFN.CEL", 16, townerData.dir, 3); towner.name = _("Ogden the Tavern owner"); } -void InitTownDead(TownerStruct &towner, const TownerInit &initData) +void InitTownDead(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, "Towners\\Butch\\Deadguy.CEL", 8, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\Butch\\Deadguy.CEL", 8, townerData.dir, 6); towner.name = _("Wounded Townsman"); } -void InitWitch(TownerStruct &towner, const TownerInit &initData) +void InitWitch(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -138,29 +138,29 @@ void InitWitch(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\TownWmn1\\Witch.CEL", 19, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\TownWmn1\\Witch.CEL", 19, townerData.dir, 6); towner.name = _("Adria the Witch"); } -void InitBarmaid(TownerStruct &towner, const TownerInit &initData) +void InitBarmaid(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, "Towners\\TownWmn1\\WmnN.CEL", 18, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\TownWmn1\\WmnN.CEL", 18, townerData.dir, 6); towner.name = _("Gillian the Barmaid"); } -void InitBoy(TownerStruct &towner, const TownerInit &initData) +void InitBoy(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, "Towners\\TownBoy\\PegKid1.CEL", 20, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\TownBoy\\PegKid1.CEL", 20, townerData.dir, 6); towner.name = _("Wirt the Peg-legged boy"); } -void InitHealer(TownerStruct &towner, const TownerInit &initData) +void InitHealer(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -178,11 +178,11 @@ void InitHealer(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\Healer\\Healer.CEL", 20, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\Healer\\Healer.CEL", 20, townerData.dir, 6); towner.name = _("Pepin the Healer"); } -void InitTeller(TownerStruct &towner, const TownerInit &initData) +void InitTeller(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -195,11 +195,11 @@ void InitTeller(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\Strytell\\Strytell.CEL", 25, initData.dir, 3); + LoadTownerAnimations(towner, "Towners\\Strytell\\Strytell.CEL", 25, townerData.dir, 3); towner.name = _("Cain the Elder"); } -void InitDrunk(TownerStruct &towner, const TownerInit &initData) +void InitDrunk(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; static const uint8_t AnimOrder[] = { @@ -211,11 +211,11 @@ void InitDrunk(TownerStruct &towner, const TownerInit &initData) }; towner.animOrder = AnimOrder; towner.animOrderSize = sizeof(AnimOrder); - LoadTownerAnimations(towner, "Towners\\Drunk\\TwnDrunk.CEL", 18, initData.dir, 3); + LoadTownerAnimations(towner, "Towners\\Drunk\\TwnDrunk.CEL", 18, townerData.dir, 3); towner.name = _("Farnham the Drunk"); } -void InitCows(TownerStruct &towner, const TownerInit &initData) +void InitCows(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 128; towner.animOrder = nullptr; @@ -223,12 +223,12 @@ void InitCows(TownerStruct &towner, const TownerInit &initData) for (int i = 0; i < 8; i++) { towner._tNAnim[i] = CelGetFrame(CowCels.get(), i); } - NewTownerAnim(towner, towner._tNAnim[initData.dir], 12, 3); + NewTownerAnim(towner, towner._tNAnim[townerData.dir], 12, 3); towner._tAnimFrame = GenerateRnd(11) + 1; towner.name = _("Cow"); - const Point position = initData.position; - const Point offset = position + CowOffsets[initData.dir]; + const Point position = townerData.position; + const Point offset = position + CowOffsets[townerData.dir]; int index = -dMonster[position.x][position.y]; if (dMonster[position.x][offset.y] == 0) dMonster[position.x][offset.y] = index; @@ -238,16 +238,16 @@ void InitCows(TownerStruct &towner, const TownerInit &initData) dMonster[offset.x][offset.y] = index; } -void InitFarmer(TownerStruct &towner, const TownerInit &initData) +void InitFarmer(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, "Towners\\Farmer\\Farmrn2.CEL", 15, initData.dir, 3); + LoadTownerAnimations(towner, "Towners\\Farmer\\Farmrn2.CEL", 15, townerData.dir, 3); towner.name = _("Lester the farmer"); } -void InitCowFarmer(TownerStruct &towner, const TownerInit &initData) +void InitCowFarmer(Towner &towner, const TownerData &townerData) { const char *celPath = "Towners\\Farmer\\cfrmrn2.CEL"; if (Quests[Q_JERSEY]._qactive == QUEST_DONE) { @@ -256,20 +256,20 @@ void InitCowFarmer(TownerStruct &towner, const TownerInit &initData) towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, celPath, 15, initData.dir, 3); + LoadTownerAnimations(towner, celPath, 15, townerData.dir, 3); towner.name = _("Complete Nut"); } -void InitGirl(TownerStruct &towner, const TownerInit &initData) +void InitGirl(Towner &towner, const TownerData &townerData) { towner._tAnimWidth = 96; towner.animOrder = nullptr; towner.animOrderSize = 0; - LoadTownerAnimations(towner, "Towners\\Girl\\Girlw1.CEL", 20, initData.dir, 6); + LoadTownerAnimations(towner, "Towners\\Girl\\Girlw1.CEL", 20, townerData.dir, 6); towner.name = "Celia"; } -void TownDead(TownerStruct &towner) +void TownDead(Towner &towner) { if (qtextflag) { if (Quests[Q_BUTCHER]._qvar1 == 1) @@ -290,7 +290,7 @@ void TownerTalk(_speech_id message) InitQTextMsg(message); } -void TalkToBarOwner(Player &player, TownerStruct &barOwner) +void TalkToBarOwner(Player &player, Towner &barOwner) { if (!player._pLvlVisited[0]) { InitQTextMsg(TEXT_INTRO); @@ -349,7 +349,7 @@ void TalkToBarOwner(Player &player, TownerStruct &barOwner) StartStore(STORE_TAVERN); } -void TalkToDeadguy(Player &player, TownerStruct & /*deadguy*/) +void TalkToDeadguy(Player &player, Towner & /*deadguy*/) { auto &quest = Quests[Q_BUTCHER]; if (quest._qactive == QUEST_DONE) @@ -368,7 +368,7 @@ void TalkToDeadguy(Player &player, TownerStruct & /*deadguy*/) NetSendCmdQuest(true, quest); } -void TalkToBlackSmith(Player &player, TownerStruct &blackSmith) +void TalkToBlackSmith(Player &player, Towner &blackSmith) { if (Quests[Q_ROCK]._qactive != QUEST_NOTAVAIL) { if (player._pLvlVisited[4] && Quests[Q_ROCK]._qactive != QUEST_DONE) { @@ -415,7 +415,7 @@ void TalkToBlackSmith(Player &player, TownerStruct &blackSmith) StartStore(STORE_SMITH); } -void TalkToWitch(Player &player, TownerStruct & /*witch*/) +void TalkToWitch(Player &player, Towner & /*witch*/) { if (Quests[Q_MUSHROOM]._qactive != QUEST_NOTAVAIL) { if (Quests[Q_MUSHROOM]._qactive == QUEST_INIT && player.TryRemoveInvItemById(IDI_FUNGALTM)) { @@ -461,7 +461,7 @@ void TalkToWitch(Player &player, TownerStruct & /*witch*/) StartStore(STORE_WITCH); } -void TalkToBarmaid(Player &player, TownerStruct & /*barmaid*/) +void TalkToBarmaid(Player &player, Towner & /*barmaid*/) { if (!player._pLvlVisited[21] && player.HasItem(IDI_MAPOFDOOM)) { Quests[Q_GRAVE]._qactive = QUEST_ACTIVE; @@ -475,13 +475,13 @@ void TalkToBarmaid(Player &player, TownerStruct & /*barmaid*/) StartStore(STORE_BARMAID); } -void TalkToDrunk(Player & /*player*/, TownerStruct & /*drunk*/) +void TalkToDrunk(Player & /*player*/, Towner & /*drunk*/) { TownerTalk(TEXT_FARNHAM1); StartStore(STORE_DRUNK); } -void TalkToHealer(Player &player, TownerStruct &healer) +void TalkToHealer(Player &player, Towner &healer) { if (Quests[Q_PWATER]._qactive != QUEST_NOTAVAIL) { if ((player._pLvlVisited[1] || player._pLvlVisited[5]) && Quests[Q_PWATER]._qactive == QUEST_INIT) { @@ -512,13 +512,13 @@ void TalkToHealer(Player &player, TownerStruct &healer) StartStore(STORE_HEALER); } -void TalkToBoy(Player & /*player*/, TownerStruct & /*boy*/) +void TalkToBoy(Player & /*player*/, Towner & /*boy*/) { TownerTalk(TEXT_WIRT1); StartStore(STORE_BOY); } -void TalkToStoryteller(Player &player, TownerStruct & /*storyteller*/) +void TalkToStoryteller(Player &player, Towner & /*storyteller*/) { auto &betrayerQuest = Quests[Q_BETRAYER]; if (!gbIsMultiplayer) { @@ -553,7 +553,7 @@ void TalkToStoryteller(Player &player, TownerStruct & /*storyteller*/) StartStore(STORE_STORY); } -void TalkToCow(Player &player, TownerStruct &cow) +void TalkToCow(Player &player, Towner &cow) { if (CowPlaying != SFX_NONE && effect_is_playing(CowPlaying)) return; @@ -583,7 +583,7 @@ void TalkToCow(Player &player, TownerStruct &cow) PlaySfxLoc(CowPlaying, cow.position); } -void TalkToFarmer(Player &player, TownerStruct &farmer) +void TalkToFarmer(Player &player, Towner &farmer) { auto &quest = Quests[Q_FARMER]; switch (quest._qactive) { @@ -640,7 +640,7 @@ void TalkToFarmer(Player &player, TownerStruct &farmer) } } -void TalkToCowFarmer(Player &player, TownerStruct &cowFarmer) +void TalkToCowFarmer(Player &player, Towner &cowFarmer) { if (player.TryRemoveInvItemById(IDI_GREYSUIT)) { InitQTextMsg(TEXT_JERSEY7); @@ -727,7 +727,7 @@ void TalkToCowFarmer(Player &player, TownerStruct &cowFarmer) } } -void TalkToGirl(Player &player, TownerStruct &girl) +void TalkToGirl(Player &player, Towner &girl) { auto &quest = Quests[Q_GIRL]; @@ -763,7 +763,7 @@ void TalkToGirl(Player &player, TownerStruct &girl) } } -const TownerInit TownerInitList[] = { +const TownerData TownersData[] = { // clang-format off // type position dir init talk { TOWN_SMITH, { 62, 63 }, DIR_SW, InitSmith, TalkToBlackSmith }, @@ -786,7 +786,7 @@ const TownerInit TownerInitList[] = { } // namespace -TownerStruct Towners[NUM_TOWNERS]; +Towner Towners[NUM_TOWNERS]; /** Contains the data related to quest gossip for each towner ID. */ _speech_id QuestDialogTable[NUM_TOWNER_TYPES][MAXQUESTS] = { @@ -831,11 +831,11 @@ void InitTowners() CowCels = LoadFileInMem("Towners\\Animals\\Cow.CEL"); int i = 0; - for (const auto &townerInit : TownerInitList) { - if (!IsTownerPresent(townerInit.type)) + for (const auto &townerData : TownersData) { + if (!IsTownerPresent(townerData.type)) continue; - InitTownerInfo(i, townerInit); + InitTownerInfo(i, townerData); i++; } } @@ -899,19 +899,19 @@ bool DebugTalkToTowner(std::string targetName) SetupTownStores(); std::transform(targetName.begin(), targetName.end(), targetName.begin(), [](unsigned char c) { return std::tolower(c); }); auto &myPlayer = Players[MyPlayerId]; - for (auto &towner : TownerInitList) { - if (!IsTownerPresent(towner.type)) + for (auto &townerData : TownersData) { + if (!IsTownerPresent(townerData.type)) continue; // cows have an init function that differs from the rest and isn't compatible with this code, skip them :( - if (towner.type == TOWN_COW) + if (townerData.type == TOWN_COW) continue; - TownerStruct fakeTowner; - towner.init(fakeTowner, towner); + Towner fakeTowner; + townerData.init(fakeTowner, townerData); fakeTowner.position = myPlayer.position.tile; std::string npcName(fakeTowner.name); std::transform(npcName.begin(), npcName.end(), npcName.begin(), [](unsigned char c) { return std::tolower(c); }); if (npcName.find(targetName) != std::string::npos) { - towner.talk(myPlayer, fakeTowner); + townerData.talk(myPlayer, fakeTowner); return true; } } diff --git a/Source/towners.h b/Source/towners.h index b490f534e..9d56c67b5 100644 --- a/Source/towners.h +++ b/Source/towners.h @@ -35,7 +35,7 @@ enum _talker_id : uint8_t { NUM_TOWNER_TYPES, }; -struct TownerStruct { +struct Towner { byte *_tNAnim[8]; std::unique_ptr data; byte *_tAnimData; @@ -57,11 +57,11 @@ struct TownerStruct { /** Specifies the animation frame sequence. */ const uint8_t *animOrder; // unowned std::size_t animOrderSize; - void (*talk)(Player &player, TownerStruct &towner); + void (*talk)(Player &player, Towner &towner); _talker_id _ttype; }; -extern TownerStruct Towners[NUM_TOWNERS]; +extern Towner Towners[NUM_TOWNERS]; void InitTowners(); void FreeTownerGFX();