// take control of the NPC static void TakeControlOfNPC(TGameObj* npc) { // remove skill tags int tagSkill[4]; #if (_MSC_VER < 1600) std::fill(std_begin(tagSkill), std_end(tagSkill), -1); #else std::fill(std::begin(tagSkill), std::end(tagSkill), -1); #endif SkillSetTags(tagSkill, 4); // reset traits ptr_pc_traits[0] = ptr_pc_traits[1] = -1; // reset perks for (int i = 0; i < PERK_count; i++) { (*ptr_perkLevelDataList)[i] = 0; } // change character name CritterPcSetName(CritterName(npc)); // change level int level = IsPartyMember(npc) ? PartyMemberGetCurrentLevel(npc) : 0; *ptr_Level_ = level; *ptr_last_level = level; // reset other stats *ptr_Experience_ = 0; *ptr_free_perk = 0; ptr_curr_pc_stat[0] = 0; *ptr_sneak_working = 0; // deduce active hand by weapon anim code char critterAnim = (npc->artFID & 0xF000) >> 12; // current weapon as seen in hands if (AnimCodeByWeapon(GetInvenWeaponLeft(npc)) == critterAnim) { // definitely left hand.. *ptr_itemCurrentItem = 0; } else { *ptr_itemCurrentItem = 1; } *ptr_inven_pid = npc->pid; // switch main dude_obj pointers - this should be done last! *ptr_obj_dude = npc; *ptr_inven_dude = npc; IsControllingNPC = 1; DelayedExperience = 0; SetInventoryCheck(true); InterfaceRedraw(); }
// return values: 0 - use vanilla handler, 1 - skip vanilla handler, return 0 (normal status), -1 - skip vanilla, return -1 (game ended) static int _stdcall CombatWrapperInner(TGameObj* obj) { if ((obj != *obj_dude_ptr) && (Chars.size() == 0 || IsInPidList(obj)) && (Mode == 1 || IsPartyMember(obj))) { IsControllingNPC = 1; SetInventoryCheck(true); char dudeWeaponSlot = (char)*activeUIHand_ptr; // save "real" dude state real_dude = *obj_dude_ptr; *obj_dude_ptr = obj; *inven_dude_ptr = obj; memcpy(real_traits, dude_traits, sizeof(DWORD)*2); // deduce active hand by weapon anim code char critterAnim = (obj->artFID & 0xF000) >> 12; // current weapon as seen in hands if (AnimCodeByWeapon(GetInvenWeaponLeft(obj)) == critterAnim) { // definitely left hand.. *activeUIHand_ptr = 0; } else { *activeUIHand_ptr = 1; } int turnResult; __asm { call intface_redraw_; mov eax, obj; call combat_turn_; mov turnResult, eax; } // restore state if (IsControllingNPC) { // if game was loaded during turn, PartyControlReset() was called and already restored state *activeUIHand_ptr = dudeWeaponSlot; memcpy(dude_traits, real_traits, sizeof(DWORD)*2); *obj_dude_ptr = real_dude; *inven_dude_ptr = real_dude; __asm { call intface_redraw_; } SetInventoryCheck(false); IsControllingNPC = 0; } // -1 means that combat ended during turn return (turnResult == -1) ? -1 : 1; }