📄 g_items.pas
字号:
g_utils,
Cpas, g_main, game_add, q_shared_add, g_local_add;
//===================================
{
========
GetItemByIndex
========
}
function GetItemByIndex(index: Integer):GItem_p;
begin
Result := nil;
if (index = 0) or (index >= game.num_items) then exit;
result := @itemlist[index];
end;
{
========
FindItemByClassname
========
}
function FindItemByClassname(classname: pchar):GItem_p;
var i:Integer;
It: GItem_p;
begin
for i := 0 to game.num_items - 1 do begin
it := @itemlist[i];
if it^.classname = '' then continue;
//if (CompareText(it^.classname, classname)) = 0 then begin
if Q_stricmp(it^.classname, classname) = 0 then
begin
Result := it;
exit;
end;
end;
result := nil;
end;
{
========
FindItem
========
}
function FindItem(pickup_name: pchar):GItem_p;
var
i:Integer;
It: GItem_p;
begin
for i := 0 to game.num_items - 1 do begin
it := @itemlist[i];
if it^.pickup_name = '' then continue;
if (Q_stricmp(it^.pickup_name, pickup_name)) = 0 then
begin
Result := it;
exit;
end;
end;
Result := Nil;
end;
//===================================
procedure DoRespawn(Ent:edict_p); cdecl;
var
Master: edict_p;
Count, Choice: Integer;
begin
if (ent^.team <> nil) then
begin // pick a random team member
master := ent^.teammaster;
count := 0;
ent := master;
while ent <> nil do
begin
ent := ent^.chain; Inc(count);
end;
choice := rand() mod count;
count := 0; ent := master;
while count < choice do
begin
ent := ent^.chain; Inc(count);
end;
end;
ent^.svflags :=ent^.svflags and not(SVF_NOCLIENT);
ent^.solid := SOLID_TRIGGER;
gi.linkentity (ent);
// send an effect
ent^.s.event := EV_ITEM_RESPAWN;
end;
procedure SetRespawn(Ent:edict_p; Delay: Single);
begin
ent^.flags := ent^.flags or FL_RESPAWN;
ent^.svflags := ent^.svflags or SVF_NOCLIENT;
ent^.solid := SOLID_NOT;
ent^.nextthink := level.time + delay;
ent^.think := DoRespawn;
gi.linkentity (ent);
end;
//===================================
function Pickup_Powerup (Ent, Other:edict_p): QBoolean; cdecl;
var Quantity: Integer;
begin
// Check quantity: 3.20
Result := false;
Quantity := other^.client^.pers.inventory[ITEM_INDEX(ent^.item)];
if ((skill^.value = 1) and (quantity >= 2)) or ((skill^.value >= 2) and (quantity >= 1)) then Exit;
if (coop^.value <> 0) and ((ent^.item^.flags and IT_STAY_COOP) > 0)
and (quantity > 0) then exit;
Inc(other^.client^.pers.inventory[ITEM_INDEX(ent^.item)]);
if (deathmatch^.value <> 0) then begin
if (ent^.spawnflags and DROPPED_ITEM) = 0 then
SetRespawn (ent, ent^.item^.quantity);
if ((round(dmflags^.value) and DF_INSTANT_ITEMS) > 0) or (@ent^.item^.use = @Use_Quad) and ((ent^.spawnflags and DROPPED_PLAYER_ITEM) > 0) then
begin
if (@ent^.item^.use = @Use_Quad) and ((ent^.spawnflags and DROPPED_PLAYER_ITEM) > 0) then
quad_drop_timeout_hack := round((ent^.nextthink - level.time) / FRAMETIME);
// use it immediately
ent^.item^.use (other, ent^.item);
end;
end;
Result := true;
end;
procedure Drop_General(Ent:edict_p;Item: GItem_p); cdecl;
begin
Drop_Item(ent, item);
Dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
end;
//===================================
function Pickup_Adrenaline (Ent, Other:edict_p): QBoolean; cdecl;
begin
if (deathmatch^.value=0) then Inc(other^.max_health);
if (other^.health < other^.max_health) then other^.health := other^.max_health;
if (ent^.spawnflags and DROPPED_ITEM= 0) and (deathmatch^.value<>0) then
SetRespawn (ent, ent^.item^.quantity);
Result := True;
end;
function Pickup_AncientHead (Ent, Other:edict_p): QBoolean; cdecl;
begin
Inc(other^.max_health, 2);
if (ent^.spawnflags and DROPPED_ITEM = 0) and (deathmatch^.value<>0) then
SetRespawn (ent, ent^.item^.quantity);
Result := True;
end;
function Pickup_Bandolier (Ent, Other:edict_p): QBoolean; cdecl;
var item: GItem_p;
Index:Integer;
begin
if (other^.client^.pers.max_bullets < 250) then other^.client^.pers.max_bullets := 250;
if (other^.client^.pers.max_shells < 150) then other^.client^.pers.max_shells := 150;
if (other^.client^.pers.max_cells < 250) then other^.client^.pers.max_cells := 250;
if (other^.client^.pers.max_slugs < 75) then other^.client^.pers.max_slugs := 75;
item := FindItem('Bullets');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_bullets) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_bullets;
end;
item := FindItem('Shells');
if item <> nil then begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_shells) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_shells;
end;
if (ent^.spawnflags and DROPPED_ITEM=0) and (deathmatch^.value<>0) then
SetRespawn (ent, ent^.item^.quantity);
Result := True;
end;
function Pickup_Pack (Ent, Other:edict_p): QBoolean; cdecl;
var item: GItem_p;
Index:Integer;
begin
if (other^.client^.pers.max_bullets < 300) then other^.client^.pers.max_bullets := 300;
if (other^.client^.pers.max_shells < 200) then other^.client^.pers.max_shells := 200;
if (other^.client^.pers.max_rockets < 100) then other^.client^.pers.max_rockets := 100;
if (other^.client^.pers.max_grenades < 100) then other^.client^.pers.max_grenades := 100;
if (other^.client^.pers.max_cells < 300) then other^.client^.pers.max_cells := 300;
if (other^.client^.pers.max_slugs < 100) then other^.client^.pers.max_slugs := 100;
item := FindItem('Bullets');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_bullets) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_bullets;
end;
item := FindItem('Shells');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_shells) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_shells;
end;
item := FindItem('Cells');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_cells) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_cells;
end;
if item <> nil then
begin
item := FindItem('Grenades');
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_grenades) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_grenades;
end;
item := FindItem('Rockets');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_rockets) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_rockets;
end;
item := FindItem('Slugs');
if item <> nil then
begin
index := ITEM_INDEX(item);
Inc(other^.client^.pers.inventory[index], item^.quantity);
if (other^.client^.pers.inventory[index] > other^.client^.pers.max_slugs) then
other^.client^.pers.inventory[index] := other^.client^.pers.max_slugs;
end;
if (ent^.spawnflags and DROPPED_ITEM = 0) and (deathmatch^.value<>0) then
SetRespawn (ent, ent^.item^.quantity);
Result := True;
end;
//===================================
procedure Use_Quad (ent:edict_p; item:gitem_p);
var
timeout:integer;
begin
dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
if (quad_drop_timeout_hack<>0) then
begin
timeout := quad_drop_timeout_hack;
quad_drop_timeout_hack := 0;
end
else
begin
timeout := 300;
end;
if (ent^.client^.quad_framenum > level.framenum) then
ent^.client^.quad_framenum :=ent^.client^.quad_framenum + timeout
else
ent^.client^.quad_framenum := level.framenum + timeout;
gi.sound(ent, CHAN_ITEM, gi.soundindex('items/damage.wav'), 1, ATTN_NORM, 0);
end;
//===================================
procedure Use_Breather (ent:edict_p; item:gitem_p); cdecl;
begin
dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
if (ent^.client^.breather_framenum > level.framenum) then
ent^.client^.breather_framenum:=ent^.client^.breather_framenum + 300
else
ent^.client^.breather_framenum := level.framenum + 300;
// gi.sound(ent, CHAN_ITEM, gi.soundindex('items/damage.wav'), 1, ATTN_NORM, 0);
end;
//===================================
procedure Use_Envirosuit(ent:edict_p;item:gitem_p); cdecl;
begin
dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
if (ent^.client^.enviro_framenum > level.framenum) then
ent^.client^.enviro_framenum := ent^.client^.enviro_framenum + 300
else
ent^.client^.enviro_framenum := level.framenum + 300;
// gi.sound(ent, CHAN_ITEM, gi.soundindex('items/damage.wav'), 1, ATTN_NORM, 0);
end;
//===================================
procedure Use_Invulnerability(ent:edict_p;item: gitem_p); cdecl;
begin
dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
if (ent^.client^.invincible_framenum > level.framenum) then
ent^.client^.invincible_framenum :=ent^.client^.invincible_framenum + 300
else
ent^.client^.invincible_framenum := level.framenum + 300;
gi.sound(ent, CHAN_ITEM, gi.soundindex('items/protect.wav'), 1, ATTN_NORM, 0);
end;
//===================================
procedure Use_Silencer (ent:edict_p;item: gitem_p); cdecl;
begin
dec(ent^.client^.pers.inventory[ITEM_INDEX(item)]);
ValidateSelectedItem (ent);
ent^.client^.silencer_shots := ent^.client^.silencer_shots + 30;
// gi.sound(ent, CHAN_ITEM, gi.soundindex('items/damage.wav'), 1, ATTN_NORM, 0);
end;
//===================================
function Pickup_Key (ent:edict_p;other:edict_p):qboolean; cdecl;
begin
if (coop^.value <> 0)then
begin
if (strcmp(ent^.classname, 'key_power_cube') = 0) then
begin
if (other^.client^.pers.power_cubes and ((ent^.spawnflags and $0000ff00) shr 8)) <> 0 then
begin
Result := False;
Exit;
end;
inc(other^.client^.pers.inventory[ITEM_INDEX(ent^.item)]);
other^.client^.pers.power_cubes := other^.client^.pers.power_cubes or ((ent^.spawnflags and $0000ff00) shr 8);
end
else
begin
if (other^.client^.pers.inventory[ITEM_INDEX(ent^.item)] <> 0) then
begin
Result := False;
Exit;
end;
other^.client^.pers.inventory[ITEM_INDEX(ent^.item)] := 1;
end;
Result := True;
Exit;
end;
inc(other^.client^.pers.inventory[ITEM_INDEX(ent^.item)]);
Result := True;
end;
//===================================
function Add_Ammo (ent:edict_p;item: gitem_p; count:integer):qboolean;
var
index:integer;
max:integer;
begin
result:= true;
if (ent^.client=nil) then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -