[Gothic 2] Skrypt dwóch mieczy 9554 13

O temacie

Autor Siemekk

Zaczęty 11.10.2016 roku

Wyświetleń 9554

Odpowiedzi 13

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1153
ProfesjaProgramista
  • Złote Wrota

Siemekk
Złote Wrota

[Gothic 2] Skrypt dwóch mieczy
2016-10-11, 22:08(Ostatnia zmiana: 2017-09-02, 15:06)
Nowa wersja 02.09.2017

Nowy plik o nazwie Externals.d - parsowany przed dualami.

func int GetModel(var int npc)
{
CALL__thiscall(MEM_InstToPtr(npc), 7571232);
return CALL_RetValAsInt();
};

 
func int AniIsActive(var c_npc slf, var string aniname)
{
var int ptr; ptr = GetModel(slf);
const int zCModel_AniIsActive = 5727888; //0x00576690

CALL_zStringPtrParam(Str_Upper(aniname));
CALL__thiscall(ptr, zCModel_AniIsActive);
return CALL_RetValAsInt();
};

func int MEM_KeyHold(var int key1, var int key2)
{
if((MEM_KeyState(key1) == KEY_HOLD && key1)
|| (MEM_KeyState(key2) == KEY_HOLD && key2))
{
return true;
};
return false;
};

func oCItem Hlp_GetItem(var int ID)
{
    var zCPar_Symbol symb; symb = _^ (MEM_GetSymbolByIndex (ID));
    MEM_PtrToInst (symb.offset);
};

func int oCNpc_GetSlotItem(var c_npc slf, var string slot)
{
CALL_zStringPtrParam(STR_Upper(slot));
CALL__thiscall(_@(slf), 7544720);
return CALL_RetValAsPtr();
};

func void Equip_FarWeapon (var C_NPC slf, var int ItemInst) {

    if (!Npc_HasItems (slf, ItemInst)) {
        CreateInvItems (slf, ItemInst, 1);
    };

    if (!Npc_GetInvItem(slf, ItemInst)) {
        MEM_AssertFail("Unexpected behaviour in EquipWeapon.");
        return;
    };

    if ((item.mainflag == ITEM_KAT_NF) && (Npc_HasReadiedMeleeWeapon(slf)))
    || ((item.mainflag == ITEM_KAT_FF) && (Npc_HasReadiedRangedWeapon(slf))) {
        MEM_Warn ("EquipWeapon: Caller wants to equip a weapon while weapon of the same type is readied. Ignoring request.");
        return;
    };

    if (item.flags & ITEM_ACTIVE)
    && (!EquipWeapon_TogglesEquip) {
        /* calling EquipWeapon would unequip the weapon. */
        MEM_Info ("EquipWeapon: This weapon is already equipped. Ignoring request.");
        return;
    };

const int oCNpc__EquipFarWeapon = 7578384; //  0x0073A310
CALL_PtrParam(_@(item));
CALL__thiscall(_@(slf), oCNpc__EquipFarWeapon);
};


func void oCNpc_UseItem(var c_npc slf, var int ItemInst)
{
if (!Npc_HasItems (slf, ItemInst)) {
CreateInvItems (slf, ItemInst, 1);
    };

if (!Npc_GetInvItem(slf, ItemInst)) {
return;
};

CALL_PtrParam(_@(item));
    CALL__thiscall(_@(slf), oCNpc__UseItem);
};

// Redefine MagBook : <
func int oCItem_HasFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415504);//0x007126D0
return CALL_RetValAsInt();
};

func void oCItem_SetFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415568); //0x00712710
};

func void oCItem_ClearFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415536); //0x007126F0

};
//int __thiscall oCMag_Book::DeRegister(oCItem *)    0x00475CC0 0 5 public: int __thiscall oCMag_Book::DeRegister(oCItem

func int oCMagBook_DeRegister(var int it)
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;

if(ptr)
{
CALL_PtrParam(_@(it));
CALL__thiscall(ptr, 4676800);
return CALL_RetValAsInt();
};
};

func int oCMagBook_GetNoOfSpells()
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;

if(ptr)
{
CALL__thiscall(ptr, 4692832); //0x00479B60
return CALL_RetValAsInt();
};
};

func void oCMagBook_Register(var int it)
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;
if(ptr)
{
CALL_PtrParam(_@(it));
CALL__thiscall(ptr, 4676528); //0x00475BB0
};
};


func void Ext_PutInSlot(var c_npc slf, var c_item itm, var string SlotName)
{
CALL_IntParam(1);
    CALL_PtrParam(_@(itm));
    CALL_zStringPtrParam(SlotName);
    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__PutInSlot);
};

func int Ext_RemoveFromSlot(var c_npc slf, var string SlotName)
{
CALL_IntParam(1);
    CALL_PtrParam(1);
    CALL_zStringPtrParam(SlotName);
    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__RemoveFromSlot);
return CALL_RetValAsInt();
};

Kod duali:
const int Hero_TalentDuals = 1;
const string Dual_SlotEquip  = "ZS_LONGSWORD";
const string Dual_SlotDraw = "ZS_LEFTHAND";
const string Duals_Mds = "Humans_1hSt1.mds";
var int Dual_SwimFix;
var int Duals_Equipped;

func void Dual_Equip()
{
if(!Hero_TalentDuals)
{
return;
};

var c_item it; it = _^(MEM_ReadInt(ESP+324+4));
var c_item old;

//Get action key!
var int k1; k1 = MEM_GetKey("keyParade");
var int k2; k2 = MEM_GetSecondaryKey("keyParade");

if(MEM_KeyState(k1) == KEY_PRESSED && k1)
||(MEM_KeyState(k2) == KEY_PRESSED && k2)
{
if(it.flags & (ITEM_SWD | ITEM_AXE))
&&(oCNpc_GetSlotItem(hero, "ZS_SWORD"))
{
if(!oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
if(!(it.flags & ITEM_ACTIVE))
{
Ext_PutInSlot(hero, it, Dual_SlotEquip);
oCItem_SetFlag(it, ITEM_ACTIVE);
Mdl_ApplyOverlayMds(hero, Duals_Mds);
Duals_Equipped = true;
};
}
else
{
if(it.flags & ITEM_ACTIVE)
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip) == _@(it))
{
old = _^(oCNpc_GetSlotItem(hero, Dual_SlotEquip));
oCItem_ClearFlag(old, ITEM_ACTIVE);
Ext_RemoveFromSlot(hero, Dual_SlotEquip);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
}
else
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
old = _^(oCNpc_GetSlotItem(hero, Dual_SlotEquip));
Ext_RemoveFromSlot(hero, Dual_SlotEquip);
oCItem_ClearFlag(old, ITEM_ACTIVE);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
//Put new
Ext_PutInSlot(hero, it, Dual_SlotEquip);
oCItem_SetFlag(it, ITEM_ACTIVE);
Mdl_ApplyOverlayMds(hero, Duals_Mds);
Duals_Equipped = true;
};
};
};
};
};

func void Dual_Unequip()
{
if(ECX != _@(hero))
{
return;
};

var c_item it; it = _^(MEM_ReadInt(ESP+4));
if(it.flags & (ITEM_SWD | ITEM_AXE))
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
it = _^(Ext_RemoveFromSlot(hero, Dual_SlotEquip));
oCItem_ClearFlag(it, ITEM_ACTIVE);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
};
};

func void Dual_Drop()
{
if(ECX != _@(hero))
{
return;
};

var oCNpc her; her = _^(ECX);
if(her.fmode)
{
return;
};

if(oCNpc_GetSlotItem(hero, "ZS_LEFTHAND"))
{
var c_item it; it = _^(oCNpc_GetSlotItem(hero, Dual_SlotDraw));
oCNpc_UnequipItem(hero, _@(it));

CALL_zStringPtrParam(Dual_SlotDraw);
CALL__thiscall(_@(hero), 7644560);
};
};

func void Dual_Draw()
{
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_RIGHTHAND")
&& !oCNpc_GetSlotItem(hero, Dual_SlotDraw))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotEquip));
Ext_PutInSlot(hero, it, Dual_SlotDraw);
Dual_SwimFix = _@(it);
};
};

func void Dual_UnDraw()
{
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_SWORD")
&& !oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotDraw));
Ext_PutInSlot(hero, it, Dual_SlotEquip);
Dual_SwimFix = 0;
};
};

func void DisableKeys(var int key)
{
if(MEM_ReadInt(ESP+4)==key)
{
MEM_WriteInt(ESP+4,-1);
};
};

func void Duals_RemoveKeys()
{
var int k1; k1 = MEM_GetKey("keyParade");
var int k2; k2 = MEM_GetSecondaryKey("keyParade");

DisableKeys(k1);
DisableKeys(k2);
};

//keyShowMap
func void SwimFix()
{
if(Dual_SwimFix)
{
var c_item d; d = _^(Dual_SwimFix);

if(C_BodyStateContains(hero, BS_SWIM)
|| C_BodyStateContains(hero, BS_DIVE))
{
if(oCNpc_GetSlotItem(hero, Dual_SlotDraw))
{
Ext_RemoveFromSlot(hero, Dual_SlotDraw);
};
Ext_PutInSlot(hero, d, Dual_SlotEquip);
Dual_SwimFix = 0;
};
};
};

func void Duals_Init()
{
const int done = 0;
if(!done)
{
HookEngineF(7546560, 6, Dual_Unequip);
HookEngineF(7397440, 6, Duals_RemoveKeys);
HookEngineF(7369071, 6, Dual_Equip);

HookEngineF(7654416,    6, Dual_Draw);
HookEngineF(7656160,    5, Dual_Draw);
HookEngineF(7656832,    6, Dual_Draw);
HookEngineF(7658272,  7, Dual_UnDraw);
HookEngineF(7660720, 7, Dual_UnDraw);
done = 1;
};
FF_ApplyOnce(SwimFix);
};
Klawisz odpowiedzialny za blok (przy włączonym ekwipunku) odpowiada za nałożenie lewego miecza.
Aby nie było błędów należy dodać parę fix'ów w pliku: player_hotkey_screen_map. (Nie daje gotowca!)

To wszystko, jednak duale nie działają z moim QucikSlotem.

P.S jeżeli używasz tego w modyfikacji warto wspomnieć o autorze.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Pan.L

Pan.L

Użytkownicy
posty72
Propsy3
Profesjabrak
  • Użytkownicy
Dobra robota leci props :) Czekam na więcej skryptów. Osobiście uważam że powinno powstawać więcej poradników tego typu aby pewne osiągnięcia w dziedzinach animacji,skryptów stawały się standardem który podniesie jak mniemam jakość wszystkich modów. Sam po cichu liczę że powstanie podobny poradnik do kołczanów które próbuje od jakiegoś czasu rozkminić :D
 

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Mały edit Pan.L to nie jest poradnik tylko gotowiec :D

Toworish

Toworish

Użytkownicy
http://chomikuj.pl/ToWoRiSh
posty1664
Propsy254
ProfesjaNierób
  • Użytkownicy
  • http://chomikuj.pl/ToWoRiSh
Co do wypadania miecza, o ile dobrze pamiętam podobny miałem problem, http://themodders.org/index.php?topic=25315.0

Patrz @Siemekk tutaj w moim starym poradniku jest  kawałek skryptu od Splash'a który to usuwa miecz ze slotu w odpowiednim momencie
 
Niebawem...Pierdolnę se poradniki do Goticzka. Albo i nie, bo sie mnie nie chce.

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1153
ProfesjaProgramista
  • Złote Wrota
Miecz wypada normalnie :P Dzięki tej funkcji:
func void _Dual_Drop()
{
if(!ECX) { return; };
var c_npc slf; slf = MEM_PtrToInst(ECX);
if(!Npc_IsPlayer(slf)){return;};

if(!hero.aivar[AIV_Dual])||(!Dual_Instance){return;};
if(Npc_IsInFightMode(hero, FMode_None)) { return; };

var c_item dual; dual = MEM_PtrToInst(Dual_Instance);
var zCVob npc; npc = MEM_PtrToInst(ECX);
    MEM_InsertItem(dual,npc.trafoObjToWorld[3], npc.trafoObjToWorld[7], npc.trafoObjToWorld[11]);
        Npc_RemoveInvItem(slf, Hlp_GetInstanceID(dual));

if(oCNPC_GetSlotItem(hero,"ZS_LONGSWORD"))
{
oCNpc_RemoveFromSlot(hero, DUAL_SlotEquip, hero.aivar[AIV_Dual], DUAL_Slot);
}
else if(oCNPC_GetSlotItem(hero,"ZS_LEFTHAND"))
{
oCNpc_RemoveFromSlot(hero, "ZS_LEFTHAND", hero.aivar[AIV_Dual], DUAL_Slot);
};
dual.flags = dual.flags & ~ ITEM_ACTIVE;
hero.aivar[AIV_Dual] = 0;
Mdl_RemoveOverlayMDS(hero,"humans_1hst1");
Dual_Instance = 0;
hero.aivar[AIV_Dual_Equipped] = FALSE;
};
Brakuje tylko dodawania DMG do puli, mogę to zrobić, ale nie chce mi się teraz, oraz nie mam też tyle czasu...
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Frizbick
  • Gość
A dałoby się tak zrobić, żeby postać w jednej ręce trzymała kuszę a w drugiej miecz? :D Taki szalony pomysł mi przyszedł do głowy. Coś jak zabójca z Heroes 5 (http://www.tawerna.biz/h/5/jednostki/loch/s1_zabojca.jpg).
 

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Pewnie się da ale trzeba też mieć animacje.

Kempix

Kempix

Użytkownicy
posty171
Propsy12
ProfesjaSkrypter
  • Użytkownicy
Hm wywala mi błąd przy: if(!C_BodyStateContains(hero,BS_STAND)){return;};
 

55TIGER39

55TIGER39

Użytkownicy
posty60
Propsy19
Profesjabrak
  • Użytkownicy
Jeśli o dark sagę chodzi to MDSy i animacje skompilowane już, człowiek sprytny wyciągnie sobie nawet i gomanem XD (Aczkolwiek wszystko pojedyńczo)
No ale są od tego udostępnione narządzia żeby nie robić sobie pod górkę.

Ja pamietam że u siebie robiłem prostym skryptem item oflagowany pod MDS jako broń i też działało.

Mniej więcej tym sposobem, tak

Cytuj
instance TARCZA_5(C_Item)
{
   name = "Stara tarcza Paladyna";
   mainflag = ITEM_KAT_FF;
   flags = ITEM_CROSSBOW;
   material = MAT_METAL;
   value = 1250;
   on_equip = equip_tarcza;
   on_unequip = unequip_tarcza;
   protection[PROT_EDGE] = 10;
   protection[PROT_BLUNT] = 10;
   protection[PROT_POINT] = 5;
   protection[PROT_FIRE] = 5;
   protection[PROT_MAGIC] = 4;
   munition = ItMi_StoneOfKnowlegde_MIS;
   cond_atr[2] = ATR_STRENGTH;
   cond_value[2] = 55;
   visual = "TARCZA_5.3DS";
   description = name;
   text[0] = "Bardzo stara,pamięta pierwsze wojny z Orkami.Obecnie nie używana przez zakon";
   text[1] = NAME_Prot_Edge;
   count[1] = protection[PROT_EDGE];
   text[2] = NAME_Prot_Point;
   count[2] = protection[PROT_POINT];
   text[3] = NAME_Prot_Fire;
   count[3] = protection[PROT_FIRE];
   text[4] = NAME_Str_needed;
   count[4] = cond_value[2];
   text[5] = NAME_Value;
   count[5] = value;
};

FUNC VOID Equip_tarcza()
{
self.protection [1] += item.protection [2];
self.protection [2] += item.protection [2];
self.protection [6] += item.protection [6];
self.protection [3] += item.protection [3];
self.protection [5] += item.protection [5];
Mdl_ApplyOverlayMds (self,"HUM_SHIELD2.msb");
};

FUNC VOID UnEquip_tarcza()
{
self.protection [1] -= item.protection [2];
self.protection [2] -= item.protection [2];
self.protection [6] -= item.protection [6];
self.protection [3] -= item.protection [3];
self.protection [5] -= item.protection [5];
Mdl_RemoveOverlayMds (self,"HUM_SHIELD2.msb");
};
 

Vic7im

Vic7im

Użytkownicy
posty84
Propsy92
Profesjabrak
  • Użytkownicy
Hello there @Siemekk, good morning!

I'm trying to make the dual wield script work but I recieve one error when parsing it, there's no call for  HookEngineF(oCNpc__EV_DrawWeapon2), Ikarus only goes as far as weapon 1.
Cytuj
const int oCNpc__EV_DrawWeapon                      = 7654416; //0x74CC10 Hook: Shields
const int oCNpc__EV_DrawWeapon1                     = 7656160; //0x74D2E0 Hook: Shields

What's the engine address for drawweapon2? :P
 

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1153
ProfesjaProgramista
  • Złote Wrota
const int oCNpc_EVDrawWeapon2 = 7656832; //0x0074D580


Post połączony: 2017-09-02, 12:29
This script is big shit - i must rewrite because in old script i used 4 aivars for duals for only hero!.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Vic7im

Vic7im

Użytkownicy
posty84
Propsy92
Profesjabrak
  • Użytkownicy
const int oCNpc_EVDrawWeapon2 = 7656832; //0x0074D580


Post połączony: 2017-09-02, 12:29
This script is big shit - i must rewrite because in old script i used 4 aivars for duals for only hero!.

Thank you! I've tried and animations don't rig, the left-sword stays behind the hero when using DS animations (I have permission to use those :P)

About the new script, you mean the one in unbalance 1.4?  I had a look at it but the game creates a looping stacktrace error that freezes the game, so I thought it was a work in progress script :P
Edit: The looping error comes from the MEM_ReadInt part
Cytuj
MEM_ReadInt(ESP+324+4));

If you need me to test something, let me know!
 

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1153
ProfesjaProgramista
  • Złote Wrota
New file: Externals - parsed before Duals:
func int GetModel(var int npc)
{
CALL__thiscall(MEM_InstToPtr(npc), 7571232);
return CALL_RetValAsInt();
};

 
func int AniIsActive(var c_npc slf, var string aniname)
{
var int ptr; ptr = GetModel(slf);
const int zCModel_AniIsActive = 5727888; //0x00576690

CALL_zStringPtrParam(Str_Upper(aniname));
CALL__thiscall(ptr, zCModel_AniIsActive);
return CALL_RetValAsInt();
};

func int MEM_KeyHold(var int key1, var int key2)
{
if((MEM_KeyState(key1) == KEY_HOLD && key1)
|| (MEM_KeyState(key2) == KEY_HOLD && key2))
{
return true;
};
return false;
};

func oCItem Hlp_GetItem(var int ID)
{
    var zCPar_Symbol symb; symb = _^ (MEM_GetSymbolByIndex (ID));
    MEM_PtrToInst (symb.offset);
};

func int oCNpc_GetSlotItem(var c_npc slf, var string slot)
{
CALL_zStringPtrParam(STR_Upper(slot));
CALL__thiscall(_@(slf), 7544720);
return CALL_RetValAsPtr();
};

func void Equip_FarWeapon (var C_NPC slf, var int ItemInst) {

    if (!Npc_HasItems (slf, ItemInst)) {
        CreateInvItems (slf, ItemInst, 1);
    };

    if (!Npc_GetInvItem(slf, ItemInst)) {
        MEM_AssertFail("Unexpected behaviour in EquipWeapon.");
        return;
    };

    if ((item.mainflag == ITEM_KAT_NF) && (Npc_HasReadiedMeleeWeapon(slf)))
    || ((item.mainflag == ITEM_KAT_FF) && (Npc_HasReadiedRangedWeapon(slf))) {
        MEM_Warn ("EquipWeapon: Caller wants to equip a weapon while weapon of the same type is readied. Ignoring request.");
        return;
    };

    if (item.flags & ITEM_ACTIVE)
    && (!EquipWeapon_TogglesEquip) {
        /* calling EquipWeapon would unequip the weapon. */
        MEM_Info ("EquipWeapon: This weapon is already equipped. Ignoring request.");
        return;
    };

const int oCNpc__EquipFarWeapon = 7578384; //  0x0073A310
CALL_PtrParam(_@(item));
CALL__thiscall(_@(slf), oCNpc__EquipFarWeapon);
};


func void oCNpc_UseItem(var c_npc slf, var int ItemInst)
{
if (!Npc_HasItems (slf, ItemInst)) {
CreateInvItems (slf, ItemInst, 1);
    };

if (!Npc_GetInvItem(slf, ItemInst)) {
return;
};

CALL_PtrParam(_@(item));
    CALL__thiscall(_@(slf), oCNpc__UseItem);
};

// Redefine MagBook : <
func int oCItem_HasFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415504);//0x007126D0
return CALL_RetValAsInt();
};

func void oCItem_SetFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415568); //0x00712710
};

func void oCItem_ClearFlag(var c_item ItemInst, var int flag)
{
CALL_PtrParam(flag);
CALL__thiscall(_@(ItemInst), 7415536); //0x007126F0

};
//int __thiscall oCMag_Book::DeRegister(oCItem *)    0x00475CC0 0 5 public: int __thiscall oCMag_Book::DeRegister(oCItem

func int oCMagBook_DeRegister(var int it)
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;

if(ptr)
{
CALL_PtrParam(_@(it));
CALL__thiscall(ptr, 4676800);
return CALL_RetValAsInt();
};
};

func int oCMagBook_GetNoOfSpells()
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;

if(ptr)
{
CALL__thiscall(ptr, 4692832); //0x00479B60
return CALL_RetValAsInt();
};
};

func void oCMagBook_Register(var int it)
{
var oCNpc her; her = Hlp_GetNpc(hero);
var int ptr; ptr = her.mag_book;
if(ptr)
{
CALL_PtrParam(_@(it));
CALL__thiscall(ptr, 4676528); //0x00475BB0
};
};


func void Ext_PutInSlot(var c_npc slf, var c_item itm, var string SlotName)
{
CALL_IntParam(1);
    CALL_PtrParam(_@(itm));
    CALL_zStringPtrParam(SlotName);
    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__PutInSlot);
};

func int Ext_RemoveFromSlot(var c_npc slf, var string SlotName)
{
CALL_IntParam(1);
    CALL_PtrParam(1);
    CALL_zStringPtrParam(SlotName);
    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__RemoveFromSlot);
return CALL_RetValAsInt();
};

Duals system:
const int Hero_TalentDuals = 1;
const string Dual_SlotEquip  = "ZS_LONGSWORD";
const string Dual_SlotDraw = "ZS_LEFTHAND";
const string Duals_Mds = "Humans_1hSt1.mds";
var int Dual_SwimFix;
var int Duals_Equipped;
//oCNpc_GetSlotItem
//oCItem_SetFlag
//oCItem_ClearFlag
//Ext_PutInSlot(c_npc, c_item, string)
//Ext_RemoveFromSlot(c_npc, string);

func void Dual_Equip()
{
if(!Hero_TalentDuals)
{
return;
};

var c_item it; it = _^(MEM_ReadInt(ESP+324+4));
var c_item old;

//Get action key!
var int k1; k1 = MEM_GetKey("keyParade");
var int k2; k2 = MEM_GetSecondaryKey("keyParade");

if(MEM_KeyState(k1) == KEY_PRESSED && k1)
||(MEM_KeyState(k2) == KEY_PRESSED && k2)
{
if(it.flags & (ITEM_SWD | ITEM_AXE))
&&(oCNpc_GetSlotItem(hero, "ZS_SWORD"))
{
if(!oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
if(!(it.flags & ITEM_ACTIVE))
{
Ext_PutInSlot(hero, it, Dual_SlotEquip);
oCItem_SetFlag(it, ITEM_ACTIVE);
Mdl_ApplyOverlayMds(hero, Duals_Mds);
Duals_Equipped = true;
};
}
else
{
if(it.flags & ITEM_ACTIVE)
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip) == _@(it))
{
old = _^(oCNpc_GetSlotItem(hero, Dual_SlotEquip));
oCItem_ClearFlag(old, ITEM_ACTIVE);
Ext_RemoveFromSlot(hero, Dual_SlotEquip);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
}
else
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
old = _^(oCNpc_GetSlotItem(hero, Dual_SlotEquip));
Ext_RemoveFromSlot(hero, Dual_SlotEquip);
oCItem_ClearFlag(old, ITEM_ACTIVE);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
//Put new
Ext_PutInSlot(hero, it, Dual_SlotEquip);
oCItem_SetFlag(it, ITEM_ACTIVE);
Mdl_ApplyOverlayMds(hero, Duals_Mds);
Duals_Equipped = true;
};
};
};
};
};

func void Dual_Unequip()
{
if(ECX != _@(hero))
{
return;
};

var c_item it; it = _^(MEM_ReadInt(ESP+4));
if(it.flags & (ITEM_SWD | ITEM_AXE))
{
if(oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
it = _^(Ext_RemoveFromSlot(hero, Dual_SlotEquip));
oCItem_ClearFlag(it, ITEM_ACTIVE);
Mdl_RemoveOverlayMds(hero, Duals_Mds);
Duals_Equipped = false;
};
};
};

func void Dual_Drop()
{
if(ECX != _@(hero))
{
return;
};

var oCNpc her; her = _^(ECX);
if(her.fmode)
{
return;
};

if(oCNpc_GetSlotItem(hero, "ZS_LEFTHAND"))
{
var c_item it; it = _^(oCNpc_GetSlotItem(hero, Dual_SlotDraw));
oCNpc_UnequipItem(hero, _@(it));

CALL_zStringPtrParam(Dual_SlotDraw);
CALL__thiscall(_@(hero), 7644560);
};
};

func void Dual_Draw()
{
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_RIGHTHAND")
&& !oCNpc_GetSlotItem(hero, Dual_SlotDraw))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotEquip));
Ext_PutInSlot(hero, it, Dual_SlotDraw);
Dual_SwimFix = _@(it);
};
};

func void Dual_UnDraw()
{
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_SWORD")
&& !oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotDraw));
Ext_PutInSlot(hero, it, Dual_SlotEquip);
Dual_SwimFix = 0;
};
};

func void DisableKeys(var int key)
{
if(MEM_ReadInt(ESP+4)==key)
{
MEM_WriteInt(ESP+4,-1);
};
};

func void Duals_RemoveKeys()
{
var int k1; k1 = MEM_GetKey("keyParade");
var int k2; k2 = MEM_GetSecondaryKey("keyParade");

DisableKeys(k1);
DisableKeys(k2);
};

//keyShowMap
func void SwimFix()
{
if(Dual_SwimFix)
{
var c_item d; d = _^(Dual_SwimFix);

if(C_BodyStateContains(hero, BS_SWIM)
|| C_BodyStateContains(hero, BS_DIVE))
{
if(oCNpc_GetSlotItem(hero, Dual_SlotDraw))
{
Ext_RemoveFromSlot(hero, Dual_SlotDraw);
};
Ext_PutInSlot(hero, d, Dual_SlotEquip);
Dual_SwimFix = 0;
};
};
};

func void Duals_Init()
{
const int done = 0;
if(!done)
{
HookEngineF(7546560, 6, Dual_Unequip);
HookEngineF(7397440, 6, Duals_RemoveKeys);
HookEngineF(7369071, 6, Dual_Equip);

HookEngineF(7654416,    6, Dual_Draw);
HookEngineF(7656160,    5, Dual_Draw);
HookEngineF(7656832,    6, Dual_Draw);
HookEngineF(7658272,  7, Dual_UnDraw);
HookEngineF(7660720, 7, Dual_UnDraw);
done = 1;
};
FF_ApplyOnce(SwimFix);
};

Key Parade == Equip left dual.
To fix map you must add fix in function: player_hotkey_screen_map.
That's all, but code don't work with my QuickSlots!
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Vic7im

Vic7im

Użytkownicy
posty84
Propsy92
Profesjabrak
  • Użytkownicy
Shit sorry I don't know what I've done I clicked the flag and I really wanted to +1 you XD

By the way, I've complemented your code a little bit, adding the offhand weapon damage to the mix (unfortunately, only as a damage boost on the main weapon).

I have yet to test the code thoroughly, will do later.

func void Dual_Draw()
{
var C_ITEM MainHand; //added
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_RIGHTHAND")
&& !oCNpc_GetSlotItem(hero, Dual_SlotDraw))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotEquip));
Ext_PutInSlot(hero, it, Dual_SlotDraw);
MainHand = Npc_GetEquippedMeleeWeapon(hero); //added
MainHand.DamageTotal += it.DamageTotal; //added
Dual_SwimFix = _@(it);
};
};

func void Dual_UnDraw()
{
var C_ITEM MainHand; //added
if(ECX != _@(hero))
{
return;
};

if (oCNpc_GetSlotItem(hero, "ZS_SWORD")
&& !oCNpc_GetSlotItem(hero, Dual_SlotEquip))
{
var c_item it; it = _^(Ext_RemoveFromSlot(hero, Dual_SlotDraw));
Ext_PutInSlot(hero, it, Dual_SlotEquip);
MainHand = Npc_GetEquippedMeleeWeapon(hero); //added
MainHand.DamageTotal -= it.DamageTotal; //added
Dual_SwimFix = 0;
};
};


It just edits the Dual_Draw() and Dual_UnDraw() functions.
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry