forked from Bad-Scientists/AF-Script-Packet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vobThrowing.d
179 lines (139 loc) · 4.97 KB
/
vobThrowing.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
* Vob throwing functions
*/
/*
* Vob_ThrowAngle
*/
func void Vob_ThrowAngle (var int vobPtr, var int posPtr, var int dirPtr, var int angle, var int velocity) {
if (!vobPtr) { return; };
var int dir[3];
if (dirPtr) {
MEM_CopyBytes (dirPtr, _@ (dir), 12);
} else {
//If direction was not provided - default values
dir[0] = FLOATNULL;
dir[1] = FLOATNULL;
dir[2] = FLOATNULL;
};
//X axis rotation, in order to turn vector up we have to use negative value for angle
var int trafoRot[16]; NewTrafo (_@(trafoRot));
VectorDirToTrf (_@ (dir), _@ (trafoRot));
zMAT4_PostRotateX (_@ (trafoRot), negf (mkf (angle)));
TrfDirToVector (_@ (trafoRot), _@ (dir));
NormalizeVector (_@ (dir));
MulVector (_@ (dir), mkf (velocity));
//Set physics enabled
zCVob_SetPhysicsEnabled (vobPtr, 1);
zCVob_SetSleeping (vobPtr, 0);
//Apply 'velocity'
var int rigidBodyPtr; rigidBodyPtr = zCVob_GetRigidBody (vobPtr);
zCRigidBody_SetVelocity (rigidBodyPtr, _@ (dir));
};
/*
* Vob_ThrowFromPosToPos
* - function throws item from fromPosPtr to targetPosPtr. It calculates angle and velocity required to manage this (#peknyObluk :) )
*/
func void Vob_ThrowFromPosToPos (var int vobPtr, var int fromPosPtr, var int targetPosPtr, var int angle) {
var int trafo[16]; NewTrafo (_@(trafo));
//dir - vector smeru
var int dir[3]; SubVectors (_@ (dir), targetPosPtr, fromPosPtr);
NormalizeVector (_@ (dir));
VectorDirToTrf (_@ (dir), _@ (trafo));
//X axis rotation, in order to turn vektor up we have to use negative value for angle
zMAT4_PostRotateX (_@ (trafo), negf (mkf (angle)));
//Velocity calculation
/*
Thank you helpo1 :)
SQRT(
(1/2 * ABS(tiažové zrýchlenie))
* (dolet^2 / COS(elevačný uhol)^2)
* (1 / (výškový rozdiel + TG(elevačný uhol) * dolet))
)
*/
//9,823
var int g; g = mkf (450); //900 seems to be Gothics gravity acceleration
var int d; d = GetVectorDist (fromPosPtr, targetPosPtr);
var int b; b = divf (sqrf (d), sqrf (cos (TRF_Deg2Rad (angle))));
var int h; h = GetVectorDistY (fromPosPtr, targetPosPtr);
var int c; c = divf (mkf(1), addf (h, mulf (tan (TRF_Deg2Rad (angle)), d)));
var int velocity; velocity = mulf (mulf (g, b),c);
//
if lf (velocity, floatnull) {
velocity = floatone;
} else {
velocity = sqrtf (velocity);
};
//
TrfDirToVector (_@ (trafo), _@ (dir));
NormalizeVector (_@ (dir));
MulVector (_@ (dir), velocity);
//Set physics enabled
zCVob_SetPhysicsEnabled (vobPtr, 1);
zCVob_SetSleeping (vobPtr, 0);
//Apply 'velocity'
var int rigidBodyPtr; rigidBodyPtr = zCVob_GetRigidBody (vobPtr);
zCRigidBody_SetVelocity (rigidBodyPtr, _@ (dir));
};
func void Npc_DropInventory (var int slfInstance, var string invSlot, var int dontDropFlags, var int dontDropMainFlag) {
var oCNpc slf; slf = Hlp_GetNpc (slfInstance);
if (!Hlp_IsValidNpc (slf)) { return; };
var int noOfCategories;
if (GOTHIC_BASE_VERSION == 1) {
noOfCategories = INV_CAT_MAX;
} else {
noOfCategories = 1;
};
var int armorItemID; armorItemID = -1;
if (Npc_HasEquippedArmor(slf)) {
var C_ITEM armorItem; armorItem = Npc_GetEquippedArmor(slf);
armorItemID = Hlp_GetInstanceID(armorItem);
};
var int npcInventoryPtr; npcInventoryPtr = _@ (slf.inventory2_vtbl);
//Create inventory slot (force creation if it does not exist already)
NPC_CreateInvSlot (slf, invSlot);
var int posFrom[3];
var int nodePosPtr;
nodePosPtr = NPC_GetNodePositionWorld (slf, invSlot);
if (nodePosPtr) {
CopyVector (nodePosPtr, _@ (posFrom));
};
MEM_Free (nodePosPtr);
repeat (invCat, noOfCategories); var int invCat;
var int itmSlot; itmSlot = 0;
var int amount; amount = NPC_GetInvItemBySlot (slf, invCat, itmSlot);
var int itemInstanceID;
while (amount > 0);
itemInstanceID = Hlp_GetInstanceID (item);
//Do we want to remove this item?
//(do not remove equipped armor)
if ((item.Flags & dontDropFlags) || (item.MainFlag & dontDropMainFlag) || ((armorItemID == itemInstanceID) && (item.Flags & ITEM_ACTIVE_LEGO)))
{
itmSlot += 1;
amount = NPC_GetInvItemBySlot (slf, invCat, itmSlot);
continue;
};
var int vobPtr; vobPtr = _@ (item);
//oCNPC_UnequipItemPtr (slf, vobPtr);
//-->
//Remove from inventory
vobPtr = oCNpcInventory_RemoveByPtr (npcInventoryPtr, vobPtr, amount);
//Put into slot
oCNpc_PutInSlot_Fixed (slf, invSlot, vobPtr, 0);
//Drop from slot (this will insert it into the world)
vobPtr = oCNpc_DropFromSlot (slf, invSlot);
//Add item dropped flag
const int ITEM_DROPPED = 1 << 10; // (intern) Dropped
oCItem_AddFlags (vobPtr, ITEM_DROPPED);
//Throw item using Vob_ThrowAngle
var int dir[3];
dir[0] = mkf (Hlp_Random (1000) * (Hlp_Random (2) * -1));
dir[1] = mkf (1000); //up
dir[2] = mkf (Hlp_Random (1000) * (Hlp_Random (2) * -1));
var int angle; angle = Hlp_Random (360);
var int velocity; velocity = 200 + Hlp_Random (100);
Vob_ThrowAngle (vobPtr, _@ (posFrom), _@ (dir), angle, velocity);
//<--
amount = NPC_GetInvItemBySlot (slf, invCat, itmSlot);
end;
end;
};