• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Вопросы по скриптингу

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
  • Первое сообщение
  • #1
Прежде чем задавать вопросы, ознакомьтесь с документацией..
1) Читать онлайн
2) Архив с офлайн-версией(chm) во вложении
 

Вложения

  • Vam_tutor.rar
    171,6 KB · Просмотры: 574
Последнее редактирование модератором:

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Re: Исходники Готики

Ммм, а что ты имеешь в виду? дай пример.
Давай, пока по шапке не получили за офтоп, переедем в какую-то другую, более подходящую, тему? Я подыму файлы и скину пример после переноса сообщений.

Просьба администрации: перенесите наш офтоп в подходящую тему по своему разумению.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Для начала пару соображений по готиксорсеру и его применимости для G2ext. На мой взгляд профана, чтобы сделать возможным компилить в нем скрипты под G2ext, труда приложить много не придется - на сколько я понял, проблема в новых внутренних функциях: достаточно сделать так, чтобы нужная информация о них не зашивалась жестко в движок, а бралась из файла, который сейчас используется только для подсказок. И пусть те, кому надо, сами уже необходимые функции туда и заносят.

Сатурас, даю пример. Объект NPC, используемый двигом Готики выглядит так (http://forum.worldofplayers.de/forum/showthread.php?t=635427):
class oCNpc
{
//zCVob {
//zCObject {
var int _vtbl;
var int _zCObject_refCtr;
var int _zCObject_hashIndex;
var int _zCObject_hashNext;
var string _zCObject_objectName;
//}
var int _zCVob_globalVobTreeNode;
var int _zCVob_lastTimeDrawn;
var int _zCVob_lastTimeCollected;
var int _zCVob_vobLeafList_array;
var int _zCVob_vobLeafList_numAlloc;
var int _zCVob_vobLeafList_numInArray;
var int _zCVob_trafoObjToWorld[16];
var int _zCVob_bbox3D_mins[3];
var int _zCVob_bbox3D_maxs[3];
var int _zCVob_touchVobList_array;
var int _zCVob_touchVobList_numAlloc;
var int _zCVob_touchVobList_numInArray;
var int _zCVob_type;
var int _zCVob_groundShadowSizePacked;
var int _zCVob_homeWorld;
var int _zCVob_groundPoly;
var int _zCVob_callback_ai;
var int _zCVob_trafo;
var int _zCVob_visual;
var int _zCVob_visualAlpha;
var int _zCVob_rigidBody;
var int _zCVob_lightColorStat;
var int _zCVob_lightColorDyn;
var int _zCVob_lightDirectionStat[3];
var int _zCVob_vobPresetName;
var int _zCVob_eventManager;
var int _zCVob_nextOnTimer;
var int _zCVob_bitfield[5];
var int _zCVob_m_poCollisionObjectClass;
var int _zCVob_m_poCollisionObject;
//}
var int idx; // 0x0100 int
var string name; // 0x0104 zSTRING[5]
var string name_1;
var string name_2;
var string name_3;
var string name_4;
var string slot; // 0x0168 zSTRING
var int npcType; // 0x017C int
var int variousFlags; // 0x0180 int
var int attribute[8]; // 0x0184 int[NPC_ATR_MAX]
var int protection[8]; // 0x01A4 int[oEDamageIndex_MAX]
var int damage[8]; // 0x01C4 int[oEDamageIndex_MAX]
var int damagetype; // 0x01E4 int
var int guild; // 0x01E8 int
var int level; // 0x01EC int
var func mission[5]; // 0x01F0 int[NPC_MIS_MAX]
var int fighttactic; // 0x0204 int
var int fmode; // 0x0208 int
var int voice; // 0x020C int
var int voicePitch; // 0x0210 int
var int mass; // 0x0214 int
var func daily_routine; // 0x0218 int
var func startAIState; // 0x021C int
var string spawnPoint; // 0x0220 zSTRING
var int spawnDelay; // 0x0234 int
var int senses; // 0x0238 int
var int senses_range; // 0x023C int
var int aiscriptvars[50]; // 0x0240 int[50]
var string wpname; // 0x0308 zSTRING
var int experience_points; // 0x031C zUINT32
var int experience_points_next_level; // 0x0320 zUINT32
var int learn_points; // 0x0324 zUINT32
var int parserEnd; // 0x0328 int
var int bloodEnabled; // 0x032C int
var int bloodDistance; // 0x0330 int
var int bloodAmount; // 0x0334 int
var int bloodFlow; // 0x0338 int
var string bloodEmitter; // 0x033C zSTRING
var string bloodTexture; // 0x0350 zSTRING
var int didHit; // 0x0364 zBOOL
var int didParade; // 0x0368 zBOOL
var int didShoot; // 0x036C zBOOL
var int hasLockedEnemy; // 0x0370 zBOOL
var int isDefending; // 0x0374 zBOOL
var int wasAiming; // 0x0378 zBOOL
var int enemy; // 0x037C oCNpc*
var int speedTurn; // 0x0380 zREAL
var int foundFleePoint; // 0x0384 zBOOL
var int reachedFleePoint; // 0x0388 zBOOL
var int vecFlee[3]; // 0x038C zVEC3
var int posFlee[3]; // 0x0398 zVEC3
var int waypointFlee; // 0x03A4 zCWaypoint*
//oTRobustTrace {
var int rbt_bitfield; // 0x03A8 oCNpc_oTRobustTrace_bitfield_Xxx
var int rbt_targetPos[3]; // 0x03AC zVEC3
var int rbt_targetVob; // 0x03B8 zCVob*
var int rbt_obstVob; // 0x03BC zCVob*
var int rbt_targetDist; // 0x03C0 zREAL
var int rbt_lastTargetDist; // 0x03C4 zREAL
var int rbt_maxTargetDist; // 0x03C8 zREAL
var int rbt_dirTurn; // 0x03CC zREAL
var int rbt_timer; // 0x03D0 zREAL
var int rbt_dirFirst[3]; // 0x03D4 zVEC3
var int rbt_dirLastAngle; // 0x03E0 zREAL
//zCArray<oTDirectionInfo*> {
var int rbt_lastDirections_array; // 0x03E4 oTDirectionInfo**
var int rbt_lastDirections_numAlloc; // 0x03E8 int
var int rbt_lastDirections_numInArray; // 0x03EC int
//}
var int rbt_frameCtr; // 0x03F0 int
var int rbt_targetPosArray[15]; // 0x03F4 zVEC3[5]
var int rbt_targetPosCounter; // 0x0430 int
var int rbt_targetPosIndex; // 0x0434 int
var int rbt_checkVisibilityTime; // 0x0438 zREAL
var int rbt_positionUpdateTime; // 0x043C zREAL
var int rbt_failurePossibility; // 0x0440 zREAL
//}
//zCList<oCNpcTimedOverlay> {
var int timedOverlays_data; // 0x0444 oCNpcTimedOverlay*
var int timedOverlays_next; // 0x0448 zCList<oCNpcTimedOverlay>*
//}
//zCArray<oCNpcTalent*> {
var int talents_array; // 0x044C oCNpcTalent**
var int talents_numAlloc; // 0x0450 int
var int talents_numInArray; // 0x0454 int
//}
var int spellMana; // 0x0458 int
var int visualFX; // 0x045C oCVisualFX*
//oCMagFrontier {
var int magFrontier_warningFX; // 0x0460 oCVisualFX*
var int magFrontier_shootFX; // 0x0464 oCVisualFX*
var int magFrontier_npc; // 0x0468 oCNpc*
var int magFrontier_bitfield; // 0x046C oCMagFrontier_bitfield_Xxx
//}
//oCNpc_States {
var int state_vtbl; // 0x0470
var string state_name; // 0x0474 zSTRING
var int state_npc; // 0x0488 oCNpc*
//TNpcAIState {
var int state_curState_index; // 0x048C int
var int state_curState_loop; // 0x0490 int
var int state_curState_end; // 0x0494 int
var int state_curState_timeBehaviour; // 0x0498 int
var int state_curState_restTime; // 0x049C zREAL
var int state_curState_phase; // 0x04A0 int
var int state_curState_valid; // 0x04A4 zBOOL
var string state_curState_name; // 0x04A8 zSTRING
var int state_curState_stateTime; // 0x04BC zREAL
var int state_curState_prgIndex; // 0x04C0 int
var int state_curState_isRtnState; // 0x04C4 zBOOL
//}
//TNpcAIState {
var int state_nextState_index; // 0x04C8 int
var int state_nextState_loop; // 0x04CC int
var int state_nextState_end; // 0x04D0 int
var int state_nextState_timeBehaviour; // 0x04D4 int
var int state_nextState_restTime; // 0x04D8 zREAL
var int state_nextState_phase; // 0x04DC int
var int state_nextState_valid; // 0x04E0 zBOOL
var string state_nextState_name; // 0x04E4 zSTRING
var int state_nextState_stateTime; // 0x04F8 zREAL
var int state_nextState_prgIndex; // 0x04FC int
var int state_nextState_isRtnState; // 0x0500 zBOOL
//}
var int state_lastAIState; // 0x0504 int
var int state_hasRoutine; // 0x0508 zBOOL
var int state_rtnChanged; // 0x050C zBOOL
var int state_rtnBefore; // 0x0510 oCRtnEntry*
var int state_rtnNow; // 0x0514 oCRtnEntry*
var int state_rtnRoute; // 0x0518 zCRoute*
var int state_rtnOverlay; // 0x051C zBOOL
var int state_rtnOverlayCount; // 0x0520 int
var int state_walkmode_routine; // 0x0524 int
var int state_weaponmode_routine; // 0x0528 zBOOL
var int state_startNewRoutine; // 0x052C zBOOL
var int state_aiStateDriven; // 0x0530 int
var int state_aiStatePosition[3]; // 0x0534 zVEC3
var int state_parOther; // 0x0540 oCNpc*
var int state_parVictim; // 0x0544 oCNpc*
var int state_parItem; // 0x0548 oCItem*
var int state_rntChangeCount; // 0x054C int
//}
//oCNpcInventory {
//oCItemContainer {
var int inventory2_vtbl; // 0x0550
var int inventory2_oCItemContainer_contents; // 0x0554 zCListSort<oCItem>*
var int inventory2_oCItemContainer_npc; // 0x0558 oCNpc*
var int inventory2_oCItemContainer_selectedItem; // 0x055C int
var int inventory2_oCItemContainer_offset; // 0x0560 int
var int inventory2_oCItemContainer_drawItemMax; // 0x0564 int
var int inventory2_oCItemContainer_itemListMode; // 0x0568 oTItemListMode
var int inventory2_oCItemContainer_frame; // 0x056C zBOOL
var int inventory2_oCItemContainer_right; // 0x0570 zBOOL
var int inventory2_oCItemContainer_ownList; // 0x0574 zBOOL
var int inventory2_oCItemContainer_prepared; // 0x0578 zBOOL
var int inventory2_oCItemContainer_passive; // 0x057C zBOOL
var int inventory2_oCItemContainer_viewCat; // 0x0580 zCView*
var int inventory2_oCItemContainer_viewItem; // 0x0584 zCView*
var int inventory2_oCItemContainer_viewItemActive; // 0x0588 zCView*
var int inventory2_oCItemContainer_viewItemHightlighted; // 0x058C zCView*
var int inventory2_oCItemContainer_viewItemActiveHighlighted; // 0x0590 zCView*
var int inventory2_oCItemContainer_viewItemFocus; // 0x0594 zCView*
var int inventory2_oCItemContainer_viewItemActiveFocus; // 0x0598 zCView*
var int inventory2_oCItemContainer_viewItemHightlightedFocus; // 0x059C zCView*
var int inventory2_oCItemContainer_viewItemActiveHighlightedFocus; // 0x05A0 zCView*
var int inventory2_oCItemContainer_viewItemInfo; // 0x05A4 zCView*
var int inventory2_oCItemContainer_viewItemInfoItem; // 0x05A8 zCView*
var int inventory2_oCItemContainer_textView; // 0x05AC zCView*
var int inventory2_oCItemContainer_viewArrowAtTop; // 0x05B0 zCView*
var int inventory2_oCItemContainer_viewArrowAtBottom; // 0x05B4 zCView*
var int inventory2_oCItemContainer_rndWorld; // 0x05B8 zCWorld*
var int inventory2_oCItemContainer_posx; // 0x05BC int
var int inventory2_oCItemContainer_posy; // 0x05C0 int
var string inventory2_oCItemContainer_textCategoryStatic; // 0x05C4 zSTRING
var int inventory2_oCItemContainer_m_bManipulateItemsDisabled; // 0x05D8 zBOOL
var int inventory2_oCItemContainer_m_bCanTransferMoreThanOneItem; // 0x05DC zBOOL
var int inventory2_oCItemContainer_image_chroma; // 0x05E0 zCOLOR
var int inventory2_oCItemContainer_blit_chroma; // 0x05E4 zCOLOR
//}
var int inventory2_owner; // 0x05E8 oCNpc*
var int inventory2_packAbility; // 0x05EC zBOOL
//zCListSort<oCItem>[INV_MAX] {
var int inventory2_inventory0_Compare; // 0x05F0 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory0_data; // 0x05F4 oCItem*
var int inventory2_inventory0_next; // 0x05F8 zCListSort<oCItem>*
var int inventory2_inventory1_Compare; // 0x05FC int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory1_data; // 0x0600 oCItem*
var int inventory2_inventory1_next; // 0x0604 zCListSort<oCItem>*
var int inventory2_inventory2_Compare; // 0x0608 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory2_data; // 0x060C oCItem*
var int inventory2_inventory2_next; // 0x0610 zCListSort<oCItem>*
var int inventory2_inventory3_Compare; // 0x0614 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory3_data; // 0x0618 oCItem*
var int inventory2_inventory3_next; // 0x061C zCListSort<oCItem>*
var int inventory2_inventory4_Compare; // 0x0620 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory4_data; // 0x0624 oCItem*
var int inventory2_inventory4_next; // 0x0628 zCListSort<oCItem>*
var int inventory2_inventory5_Compare; // 0x062C int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory5_data; // 0x0630 oCItem*
var int inventory2_inventory5_next; // 0x0634 zCListSort<oCItem>*
var int inventory2_inventory6_Compare; // 0x0638 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory6_data; // 0x063C oCItem*
var int inventory2_inventory6_next; // 0x0640 zCListSort<oCItem>*
var int inventory2_inventory7_Compare; // 0x0644 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory7_data; // 0x0648 oCItem*
var int inventory2_inventory7_next; // 0x064C zCListSort<oCItem>*
var int inventory2_inventory8_Compare; // 0x0650 int(_cdecl*)(oCItem*,oCItem*)
var int inventory2_inventory8_data; // 0x0654 oCItem*
var int inventory2_inventory8_next; // 0x0658 zCListSort<oCItem>*
//}
var string inventory2_packString; // 0x065C zSTRING[INV_MAX]
var string inventory2_packString_1;
var string inventory2_packString_2;
var string inventory2_packString_3;
var string inventory2_packString_4;
var string inventory2_packString_5;
var string inventory2_packString_6;
var string inventory2_packString_7;
var string inventory2_packString_8;
var int inventory2__offset[9]; // 0x0710 int[INV_MAX]
var int inventory2__itemnr[9]; // 0x0734 int[INV_MAX]
var int inventory2_maxSlots[9]; // 0x0758 int[INV_MAX]
var int inventory2_invnr; // 0x077C int
//}
var int trader; // 0x0780 oCItemContainer*
var int tradeNpc; // 0x0784 oCNpc*
var int rangeToPlayer; // 0x0788 zREAL
//zCArray<zTSoundHandle> {
var int listOfVoiceHandles_array; // 0x078C zTSoundHandle*
var int listOfVoiceHandles_numAlloc; // 0x0790 int
var int listOfVoiceHandles_numInArray; // 0x0794 int
//}
var int voiceIndex; // 0x0798 int
var int bitfield[5]; // 0x079C oCNpc_bitfieldX_Xxx
var int instanz; // 0x07B0 int
var string mds_name; // 0x07B4 zSTRING
var string body_visualName; // 0x07C8 zSTRING
var string head_visualName; // 0x07DC zSTRING
var int model_scale[3]; // 0x07F0 VEC3
var int model_fatness; // 0x07FC zREAL
var int namenr; // 0x0800 int
var int hpHeal; // 0x0804 zREAL
var int manaHeal; // 0x0808 zREAL
var int swimtime; // 0x080C zREAL
var int divetime; // 0x0810 zREAL
var int divectr; // 0x0814 zREAL
var int fireVob; // 0x0818 zCVob*
var int fireDamage; // 0x081C int
var int fireDamageTimer; // 0x0820 zREAL
var int attitude; // 0x0824 int
var int tmp_attitude; // 0x0828 int
var int attTimer; // 0x082C zREAL
var int knowsPlayer; // 0x0830 int
var int percList[66]; // 0x0834 TNpcPerc[NPC_PERC_MAX] { int percID; int percFunc }
var int percActive; // 0x093C int
var int percActiveTime; // 0x0940 zREAL
var int percActiveDelta; // 0x0944 zREAL
var int overrideFallDownHeight; // 0x0948 zBOOL
var int fallDownHeight; // 0x094C zREAL
var int fallDownDamage; // 0x0950 int
var int mag_book; // 0x0954 oCMag_Book*
//zCList<oCSpell> {
var int activeSpells_data; // 0x0958 oCSpell*
var int activeSpells_next; // 0x095C int
//}
//zCArray<zSTRING> {
var int activeOverlays_array; // 0x0960 zSTRING*
var int activeOverlays_numAlloc; // 0x0964 int
var int activeOverlays_numInArray; // 0x0968 int
//}
var int askbox; // 0x096C oCAskBox*
var int askYes; // 0x0970 int
var int askNo; // 0x0974 int
var int canTalk; // 0x0978 zREAL
var int talkOther; // 0x097C oCNpc*
var int info; // 0x0980 oCInfo*
var int news; // 0x0984 oCNews*
var int curMission; // 0x0988 oCMission*
//oCNewsMemory {
var int knownNews_vtbl; // 0x098C
//zCList<oCNews> {
var int knownNews_iknow_data; // 0x0990 oCNews*
var int knownNews_iknow_next; // 0x0994 zCList<oCNews>*
//}
//}
var int carry_vob; // 0x0998 zCVob*
var int interactMob; // 0x099C oCMobInter*
var int interactItem; // 0x09A0 oCItem*
var int interactItemCurrentState; // 0x09A4 int
var int interactItemTargetState; // 0x09A8 int
var int script_aiprio; // 0x09AC int
var int old_script_state; // 0x09B0 int
var int human_ai; // 0x09B4 oCAIHuman*
var int anictrl; // 0x09B8 oCAniCtrl_Human*
var int route; // 0x09BC zCRoute*
var int damageMul; // 0x09C0 zREAL
var int csg; // 0x09C4 oCNpcMessage*
var int lastLookMsg; // 0x09C8 oCNpcMessage*
var int lastPointMsg; // 0x09CC oCNpcMessage*
//zCArray<zCVob*> {
var int vobList_array; // 0x09D0 zCVob**
var int vobList_numAlloc; // 0x09D4 int
var int vobList_numInArray; // 0x09D8 int
//}
var int vobcheck_time; // 0x09DC zREAL
var int pickvobdelay; // 0x09E0 zREAL
var int focus_vob; // 0x09E4 zCVob*
//zCArray<TNpcSlot*> {
var int invSlot_array; // 0x09E8 TNpcSlot**
var int invSlot_numAlloc; // 0x09EC int
var int invSlot_numInArray; // 0x09F0 int
//}
//zCArray<TNpcSlot*> {
var int tmpSlotList_array; // 0x09F4 TNpcSlot**
var int tmpSlotList_numAlloc; // 0x09F8 int
var int tmpSlotList_numInArray; // 0x09FC int
//}
var int fadeAwayTime; // 0x0A00 zREAL
var int respawnTime; // 0x0A04 zREAL
var int selfDist; // 0x0A08 zREAL
var int fightRangeBase; // 0x0A0C int
var int fightRangeFist; // 0x0A10 int
var int fight_waitTime; // 0x0A14 zREAL
var int fight_waitForAniEnd; // 0x0A18 zTModelAniID
var int fight_lastStrafeFrame; // 0x0A1C zREAL
var int soundType; // 0x0A20 int
var int soundVob; // 0x0A24 zCVob*
var int soundPosition[3]; // 0x0A28 zVEC3
var int playerGroup; // 0x0A34 zCPlayerGroup*
}; // 0x0A38
По структуре видно, какие классы он включает. Причем сорсер без проблем (конечно, если не забыть вставить определение класса в скрипты) позволяет следующую операцию:
var oCNpc Npc; Npc = Hlp_GetNpc( self );
Далее простым присваиванием по правилам можно влиять на характеристики объекта, ранее недоступные, но на сколько я понял, не все так просто - некоторые величины в закрытой от записи области памяти и надо ждать, пока сам двиг их обновит.
Я не знаю что за что точно отвечает, но могу привести примеры использования из Мрачных Тайн.
_zCVob_type при значении 130 означает простого непися, а при 129 - на него не будет наводится фокус, отсутствует имя и проверка на столкновение с оружием. Изменяя скриптами со 129 на 130 например делаются оживающие статуи.
Еще один из классов:
class zCVob
{
//zCObject {
var int _vtbl;
var int _zCObject_refCtr;
var int _zCObject_hashIndex;
var int _zCObject_hashNext;
var string _zCObject_objectName;
//}
var int globalVobTreeNode; // 0x0024 zCTree<zCVob>*
var int lastTimeDrawn; // 0x0028 zTFrameCtr
var int lastTimeCollected; // 0x002C zDWORD
//zCArray<zCBspLeaf*> {
var int vobLeafList_array; // 0x0030 zCBspLeaf**
var int vobLeafList_numAlloc; // 0x0034 int
var int vobLeafList_numInArray; // 0x0038 int
//}
var int trafoObjToWorld[16]; // 0x003C zMATRIX4
//zTBBox3D {
var int bbox3D_mins[3]; // 0x007C zPOINT3
var int bbox3D_maxs[3]; // 0x0088 zPOINT3
//}
//zCArray<zCVob*> {
var int touchVobList_array; // 0x0094 zCVob**
var int touchVobList_numAlloc; // 0x0098 int
var int touchVobList_numInArray; // 0x009C int
//}
var int type; // 0x00A0 zTVobType
var int groundShadowSizePacked; // 0x00A4 zDWORD
var int homeWorld; // 0x00A8 zCWorld*
var int groundPoly; // 0x00AC zCPolygon*
var int callback_ai; // 0x00B0 zCAIBase*
var int trafo; // 0x00B4 zMATRIX4*
var int visual; // 0x00B8 zCVisual*
var float visualAlpha; // 0x00BC zREAL
var int rigidBody; // 0x00C0 zCRigidBody*
var int lightColorStat; // 0x00C4 zCOLOR
var int lightColorDyn; // 0x00C8 zCOLOR
var int lightDirectionStat[3]; // 0x00CC zVEC3
var int vobPresetName; // 0x00D8 zSTRING*
var int eventManager; // 0x00DC zCEventManager*
var int nextOnTimer; // 0x00E0 zREAL
var int bitfield[5]; // 0x00E4 zCVob_bitfieldX_Xxx
var int m_poCollisionObjectClass; // 0x00F8 zCCollisionObjectDef*
var int m_poCollisionObject; // 0x00FC zCCollisionObject*
}; // 0x0100
С его помощью, например, делаются медленно появляющиеся и исчезающие, не отбрасывающие тени приведения в первой Готике:
/////////////////////
//------------TurnToGhost------------------------
// (Duch w Gothic 1)
// Pomysі i wykonanie funkcji Zysk & Orcwarrior.
// id = Instancja npc'ta
// visibility = widocznoњж ducha 0 = calkiem niewidoczny 19 = przeswitywanie prawie niezauwazalne
//
//Znane problemy:
//-Uїywaj№c funkcji w startupie powoduje їe cieс pod duchem nadal wystкpuje, aby cieс znikі
// funkcje najlepiej dodaж w timetriggerze, tak aby uruchamiaіa co kilka chwil.
// Pazdziernik 10, 2009 The Modders
//
//Funkcja bez problemуw dziala na kazdym C_NPC, przeznaczona do dowolnego uїytku w modyfikacjach
//miіo by jednak byіo wspomnieж gdzieњ o jej autorach
//-----------------------------------------------
func void TurnToGhost(var int id, var int visibility)
{
var zCVob vob; vob = Hlp_GetNpc(id);

vob.bitfield[0] = vob.bitfield[0] & ~zCVob_bitfield0_castDynShadow;
vob.bitfield[0] = vob.bitfield[0] & ~zCVob_bitfield0_collDetectionDynamic;
vob.bitfield[0] = vob.bitfield[0] | (1<<2);
//Bugfix

if(visibility == 24)
{
vob.visualAlpha = 1;
}
if(visibility == 23)
{
vob.visualAlpha = 1;
}
if(visibility == 22)
{
vob.visualAlpha = 1;
}
if(visibility == 21)
{
vob.visualAlpha = 1;
}
if(visibility == 20)
{
vob.visualAlpha = 1;
}
if(visibility == 19)
{
vob.visualAlpha = 0.95;
}
else if(visibility == 18)
{
vob.visualAlpha = 0.9;
}
else if(visibility == 17)
{
vob.visualAlpha = 0.85;
}
else if(visibility == 16)
{
vob.visualAlpha = 0.8;
}
else if(visibility == 15)
{
vob.visualAlpha = 0.75;
}
else if(visibility == 14)
{
vob.visualAlpha = 0.7;
}
else if(visibility == 13)
{
vob.visualAlpha = 0.65;
}
else if(visibility == 12)
{
vob.visualAlpha = 0.6;
}
else if(visibility == 11)
{
vob.visualAlpha = 0.55;
}
else if(visibility == 10)
{
vob.visualAlpha = 0.5;
}
else if(visibility == 9)
{
vob.visualAlpha = 0.45;
}
else if(visibility == 8)
{
vob.visualAlpha = 0.4;
}
else if(visibility == 7)
{
vob.visualAlpha = 0.35;
}
else if(visibility == 6)
{
vob.visualAlpha = 0.3;
}
else if(visibility == 5)
{
vob.visualAlpha = 0.25;
}
else if(visibility == 4)
{
vob.visualAlpha = 0.2;
}
else if(visibility == 3)
{
vob.visualAlpha = 0.15;
}
else if(visibility == 2)
{
vob.visualAlpha = 0.1;
}
else if(visibility == 2)
{
vob.visualAlpha = 0.05;
}
else if(visibility == 1)
{
vob.visualAlpha = 0;
}
else if(visibility == 0)
{
vob.visualAlpha = 0;
};
};
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Ммм, я вот чета неприпомню чтобы в г1 было то что ты описал, хотя можно по пробовать...
Идея выглядит нормально, но вот вопрос, КАК добавить новые классы, или производные от встроенных класов допустим oCViewStatusBar или к zCView::Create(zString,int,int,float,int)
и прочее?

Bump: Да и устраивать быдлокод в скрипте, на 90000000 строк мне както тоже нехочется, все эти вещи можно намного проще сделать на г2екст

Зы Сугубо мое мнение.

Bump: Да и вот еще, единственный минус Г2екста, состоит в том, что нельзя компилировать новые функции сорсером, хотя лично как по мне то разницы чем компилить нету, ну разви что игра, иногда "непонимает" некоторых операций например /= ,*= и тд...
Да и в г2ексте очень просто патчить память новыми функциями, или же "очищать" области памяти от ненужных вещей)
 

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Ммм, я вот чета неприпомню чтобы в г1 было то что ты описал, хотя можно по пробовать...
Идея выглядит нормально, но вот вопрос, КАК добавить новые классы, или производные от встроенных класов допустим oCViewStatusBar или к zCView::Create(zString,int,int,float,int)
и прочее?
Просто в скрипты вставляется файл с определением этих классов - копируется текстовик Нико и всего делов: так в Г1 это и появляется. Аналогично можно добавить oCViewStatusBar и zCView, если знать их точную структуру.

Bump: Да и устраивать быдлокод в скрипте, на 90000000 строк мне както тоже нехочется, все эти вещи можно намного проще сделать на г2екст
Ну у меня скрипты МТ занимают 8.8 метра, а добавленные классы 35.5 кил

Да и в г2ексте очень просто патчить память новыми функциями, или же "очищать" области памяти от ненужных вещей)
Я не спорю, но работать с сорсером удобнее, а переделывать его под г2екст, который все время модернизируется VAM врядли будет, а вот реализовать вариант использования при компиляции скриптов инфу о внутренних функциях из другого файла по-моему вполне реальный. Но, опять таки, если вопрос о Готике1, то вариант с классами самый реальный.
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Врятли ты сможешь добавить, новые инициализации классов...
Приведи мне пример создания нпс(без использования С_NPC) только на oCNpc, и глянем что выйдет.

Bump: Да, кстати ваш сорсер, далеко не "Идеал" в плане компиляции, ибо часто он может Такие ужасные вещи в код добавлять, что страшно становится)
 

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Врятли ты сможешь добавить, новые инициализации классов...
Приведи мне пример создания нпс(без использования С_NPC) только на oCNpc, и глянем что выйдет.
А зачем?! NPC создается с С_NPC, а как используется, я уже писал.
На всякий случай, напишу прямым текстом - я привел работающие примеры из работающих модов.

Да, кстати ваш сорсер, далеко не "Идеал" в плане компиляции, ибо часто он может Такие ужасные вещи в код добавлять, что страшно становится)
Ничто не идеально, но он ведь лучше аналогов;)
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Как зачем? ЧТобы проверить возможность замещения С_NPC, более широким oCNpc*flowers*
 

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Сатурас, либо я туплю, либо ты издеваешься. Зачем замещать С_NPC, более широким oCNpc?! Делаешь
var oCNpc Npc; Npc = Hlp_GetNpc( нужный_перс );
и дальше управляешь ранее недоступными свойствами, работая с переменной Npc класса oCNpc, соответствующему инстанции непися, задаваемого в скриптах как С_NPC. Я сам был в шоке, что сорсер это терпит. Но какие еще нужны доказательства, если имеет место быть факт работы всего этого?!

Я больше скажу, сорсер даже такое терпит
var zCVob vob; vob = Hlp_GetNpc(id);
хотя Hlp_GetNpc возвращает значение типа С_NPC. А то что работает без мороки можешь глянуть на скринах http://themodders.org/index.php?/topic/7478-duch/
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Да я это понял, я просто веду к тому чтобы создавать например новые индикаторы хп мп, при этом НЕ ИЗМЕНЯЯ родные, а чисто один индикатор - одна инстанция.
Про нпс я тебе сказал по той причине что нету структуры тех класов которые мне нужны, вот и я сказал чтобы по пробовтаь сделать нпс без использования C_NPC.

Bump: Через г2екст я делаю так
PHP:
oCViewStatusBar* MpBar = new oCViewStatusBar(0, 0, 8192, 8192);
screen->InsertItem(MpBar, FALSE);
MpBar->Init(0, 0, 1.0);
MpBar->SetMaxRange(0, 30.0);
screen->RemoveItem(MpBar);
screen->InsertItem(MpBar, FALSE);
А дальше просту меняю нужные параметры индикатора через новую скриптовую функцию.
а вот как этос делать твоим методом - хз...:-\
 

ВоинИнтернета

Участник форума
Регистрация
29 Апр 2010
Сообщения
752
Благодарности
3
Баллы
200
Я хотел бы поинтересоваться у скриптеров. Хотел бы вот немного научиться скриптовать. Для этого нужно прочесть что-нибудь из C+? Или можно сразу приступать зубрить ВоГовские туторы?
 

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
Не знаю, что подразумевалось под C+. C++ или C#.

Нужно немного уметь программировать. Причем, осмысленно.

А зубрить туторы - нет менее продуктивной задачи. Их надо не зубрить, а ими пользоваться. Как справочниками.
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Я хотел бы поинтересоваться у скриптеров. Хотел бы вот немного научиться скриптовать. Для этого нужно прочесть что-нибудь из C+? Или можно сразу приступать зубрить ВоГовские туторы?
Одним словом тебе необходимо учить основы програмирования. Не важно даже на каком языке, важно уметь осмысленно писать код.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
267
Баллы
230
Хм... очень странно ведёт себя переменная в функции...

Есть функция:
Код:
func string MemTest(var int i)
{
	var string text;
	
	if (i == 1)
	{
		text = ConcatStrings(text,"Строчка1");
	}
	else if (i == 2)
	{
		text = ConcatStrings(text,"Строчка2");
	};
	
	return text;
};

Вызываю 2 строчки с использованием функции, что выше:

Код:
	...
	...
	Print(MemTest(1));
	Print(MemTest(2));
	...
	...

По идее первая функция должна вывести на экран "Строчка1", она так и сделала.
Вторая должна вывести "Строчка2", а она почему-то склеила значение предыдущих данных из переменной с текущими и возвратила в итоге: "Строчка1Строчка2".

Ведь переменная text находится в области видимости только функции, в которой она объявлена. По идее при выходе из функции, все значения внутри этой функции должны выгружаться из памяти. Глобальной переменной text не существует в скриптах. Проблема решается путём очистки переменной text в начале функции MemTest().

Вопрос в том, почему при выходе из функции, все значения внутри этой функции не выгружаться из памяти, ну или хотя бы очищались? Просто при новом использовании функции приходится делать ручную очистку или не делать, если предыдущие данные заменяются новыми значениями.

А собсно почему переменная должна выгружатся? Функция ведь возвращает эту переменную, если переменная будет выгруженна при выходе из функции, то функция возвратит NULL
Не, тут возможно должно быть так:

Print(MemTest(1));
//очистка переменных внутри MemTest
Print(MemTest(2));
//очистка переменных внутри MemTest

Т.е. как бы после return text, функция MemTest выгружается. После взвращённого значения, а не ДО.

Jr13San, а зачем проводить конкатенацию переменной text c собой? Не проще ли сделать так:
Здесь дело даже не в "конкат функции" а в выгрузке всех переменных внутри функции!
 

Вариматас

Забанен
Регистрация
11 Апр 2011
Сообщения
175
Благодарности
1
Баллы
165
А собсно почему переменная должна выгружатся? Функция ведь возвращает эту переменную, если переменная будет выгруженна при выходе из функции, то функция возвратит NULL
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.168
Баллы
915
Jr13San, а зачем проводить конкатенацию переменной text c собой? Не проще ли сделать так:
Код:
func string MemTest(var int i)
{
    var string text;
 
    text = ConcatStrings("Строчка",IntToString(i));
 
    return text;
};
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
А собсно почему переменная должна выгружатся? Функция ведь возвращает эту переменную, если переменная будет выгруженна при выходе из функции, то функция возвратит NULL
выгружаться должна по определению. это закон программирования, так как переменная объявлена локально внутри функции.
 

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
Строка в функции может попасть на ту же самую область памяти, что и при предыдущем вызове. И в ней может оказаться старая информация. Вообще-то, всегда надо полагать, что в новой переменной содержится случайная информация, и из элементарных гигиенических соображений, новые переменные надо инициализировать. Некоторые компилляторы, конечно, сами делают инициализацию новых переменных, но надеяться на это, не зная наверняка, не следует. Лучше перестраховаться, чем недостраховаться.

Это была ошибка номер раз. А номер два - использование конкатенации там, где достаточно обычного присвоения.
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.168
Баллы
915
Пожалуйста удалите мой пост, т.к. он практически повторял ответ kraw.
 

George_M

Участник форума
Регистрация
17 Дек 2010
Сообщения
692
Благодарности
18
Баллы
255
Тут вопрос родился по поводу областей памяти и т.д. Наткнулся я на немецком воге, как сделать динамическое изменение цен в первой Готике используя скриптовый пакет Ikarus. Компилится просто так в сорсере он не хочет, но весь то пакет тут и не нужен, а достаточно только нескольких функций. Уже неделю втыкаю, пытаясь понять как это вообще работать умудряется. Собственно функции, меняющие множитель при торговле:
Код:
func void Trade_ChangeSellMultiplier(var int mul)
{
    var int ptr;
    ptr = MEMINT_oCInformationManager_Address;
    ptr = MEM_ReadInt(ptr+24);//oCInformationManager.dlgTrade
    ptr = MEM_ReadInt(ptr+260);    //dlgTrade.oCViewDialogItemContainer
    MEM_WriteInt(ptr+268,mul);//oCViewDialogItemContainer.Multiplier = mul
};

func void Trade_ChangeBuyMultiplier(var int mul)
{
    var int ptr;
    ptr = MEMINT_oCInformationManager_Address;
    ptr = MEM_ReadInt(ptr+24);//oCInformationManager.dlgTrade
    ptr = MEM_ReadInt(ptr+252);    //dlgTrade.oCViewDialogStealContainer
    MEM_WriteInt(ptr+268,mul);//oCViewDialogStealContainer.Multiplier = mul    
};
А вот цепочка для MEM_ReadInt:
Код:
class MEMINT_HelperClass {};
var MEMINT_HelperClass MEMINT_PopDump;

func int MEMINT_StackPushInt (var int val) 
{
    return val + 0;
};

func int MEMINT_StackPopInt() {};

func MEMINT_HelperClass MEMINT_StackPopInstSub () {};

func void MEMINT_StackPopInst () 
{
    MEMINT_PopDump = MEMINT_StackPopInstSub();
};

func int MEMINT_StackPushInst (var int val) 
{
    MEMINT_StackPushInt (val);
    MEMINT_StackPopInst();
};

func void MEMINT_StackPushVar (var int adr)
 {
    MEMINT_StackPushInst (adr);
    MEMINT_StackPushInst (zPAR_TOK_PUSHVAR);
};

func int MEM_ReadInt (var int address) 
{
    if (address <= 0) {
        MEM_Error (ConcatStrings ("MEM_ReadInt: Invalid address: ", IntToString (address)));
        return 0;
    };

    MEMINT_StackPushVar (address);
    MEMINT_StackPushInt (MEMINT_StackPopInt()); //als int nicht als var auf dem Stack
};
Не поможете разобраться? Фиг с компиляцией в сорсере - спейсером соберу, но уже хочется понять, как же это все работает.
 
Сверху Снизу