📄 g_items.pas
字号:
procedure Use_Silencer (ent:edict_p;item: gitem_p);
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;
begin
result:= true;
if (coop^.value<>0)then
begin
if (strcmp(ent^.classname, 'key_power_cube') = 0) then
begin
if (other^.client^.pers.power_cubes<>0) 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
result:= false;
other^.client^.pers.inventory[ITEM_INDEX(ent^.item)] := 1;
end;
// begin
result:= true;
end;
inc(other^.client^.pers.inventory[ITEM_INDEX(ent^.item)]);
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
result:= false;
exit;
end;
if (item^.tag = ord(AMMO_BULLETS)) then
max := ent^.client^.pers.max_bullets
else if (item^.tag = ord(AMMO_SHELLS)) then
max := ent^.client^.pers.max_shells
else if (item^.tag = ord(AMMO_ROCKETS)) then
max := ent^.client^.pers.max_rockets
else if (item^.tag = ord(AMMO_GRENADES)) then
max := ent^.client^.pers.max_grenades
else if (item^.tag = ord(AMMO_CELLS)) then
max := ent^.client^.pers.max_cells
else if (item^.tag = ord(AMMO_SLUGS)) then
max := ent^.client^.pers.max_slugs
else
begin
result:= false;
exit;
end;
index := ITEM_INDEX(item);
if (ent^.client^.pers.inventory[index] = max) then
begin
result:= false;
exit;
end;
ent^.client^.pers.inventory[index] :=ent^.client^.pers.inventory[index]+ count;
if (ent^.client^.pers.inventory[index] > max) then
ent^.client^.pers.inventory[index] := max;
end;
function Pickup_Ammo (ent:edict_p;other:edict_p): qboolean;
var
oldcount:integer;
count:integer;
weapon:qboolean;
begin
weapon := (ent^.item^.flags and IT_WEAPON<>0);
if ( weapon) and (round(dmflags^.value) and DF_INFINITE_AMMO <>0 ) then
count := 1000
else if (ent^.count<>0) then
count := ent^.count
else
count := ent^.item^.quantity;
oldcount := other^.client^.pers.inventory[ITEM_INDEX(ent^.item)];
if not(Add_Ammo (other, ent^.item, count)) then
begin
result:= false;
exit;
end;
if (weapon )and (oldcount<>0) then
begin
if (other^.client^.pers.weapon <> ent^.item) and
( deathmatch^.value=0) or (other^.client^.pers.weapon = FindItem('blaster') ) then
other^.client^.newweapon := ent^.item;
end;
if (ent^.spawnflags and (DROPPED_ITEM or DROPPED_PLAYER_ITEM)=0) and (deathmatch^.value<>0) then
SetRespawn (ent, 30);
result:= true;
end;
procedure Drop_Ammo(ent:edict_p;item: gitem_p);
var
dropped:edict_p;
index:integer;
begin
index := ITEM_INDEX(item);
dropped := Drop_Item (ent, item);
if (ent^.client^.pers.inventory[index] >= item^.quantity) then
dropped^.count := item^.quantity
else
dropped^.count := ent^.client^.pers.inventory[index];
if (ent^.client^.pers.weapon<>nil) and
(ent^.client^.pers.weapon^.tag = ord(AMMO_GRENADES)) and
(item^.tag = ord(AMMO_GRENADES)) and
(ent^.client^.pers.inventory[index] - dropped^.count <= 0) then
begin
gi.cprintf (ent, PRINT_HIGH, 'Can t drop current weapon'#10);
G_FreeEdict(dropped);
exit;
end;
ent^.client^.pers.inventory[index] :=ent^.client^.pers.inventory[index] - dropped^.count;
ValidateSelectedItem (ent);
end;
//===================================
procedure MegaHealth_think (self:edict_p);
begin
if (self^.owner^.health > self^.owner^.max_health) then
begin
self^.nextthink := level.time + 1;
self^.owner^.health :=self^.owner^.health - 1;
exit;
end;
if (self^.spawnflags and DROPPED_ITEM=0) and (deathmatch^.value<>0) then
SetRespawn (self, 20)
else
G_FreeEdict (self);
end;
function Pickup_Health (ent:edict_p;other:edict_p):qboolean;
begin
if (ent^.style and HEALTH_IGNORE_MAX=0) then
if (other^.health >= other^.max_health) then
begin
result:= false;
exit;
end;
other^.health:=other^.health + ent^.count;
if (ent^.style and HEALTH_IGNORE_MAX=0) then
begin
if (other^.health > other^.max_health)then
other^.health := other^.max_health;
end;
if (ent^.style and HEALTH_TIMED<>0) then
begin
ent^.think := @MegaHealth_think;
ent^.nextthink := level.time + 5;
ent^.owner := other;
ent^.flags :=ent^.flags or FL_RESPAWN;
ent^.svflags :=ent^.svflags or SVF_NOCLIENT;
ent^.solid := SOLID_NOT;
end
else
begin
if (ent^.spawnflags and DROPPED_ITEM=0) and (deathmatch^.value<>0) then
SetRespawn (ent, 30);
end;
result:=true;
end;
//===================================
function ArmorIndex (ent:edict_p):integer;
begin
result:= 0;
if (ent^.client=nil) then
exit;
if (ent^.client^.pers.inventory[jacket_armor_index] > 0) then
begin
result:= jacket_armor_index;
exit;
end;
if (ent^.client^.pers.inventory[combat_armor_index] > 0) then
begin
result:= combat_armor_index;
exit;
end;
if (ent^.client^.pers.inventory[body_armor_index] > 0) then
begin
result:= body_armor_index;
exit;
end;
end;
function Pickup_Armor (ent:edict_p;other: edict_p):qboolean;
var
old_armor_index:integer;
oldinfo:gitem_armor_p;
newinfo:gitem_armor_p;
newcount:integer;
salvage:single;
salvagecount:integer;
begin
result:=true;
// get info on new armor
newinfo := gitem_armor_p(ent^.item^.info);
old_armor_index := ArmorIndex (other);
// handle armor shards specially
if (ent^.item^.tag = ARMOR_SHARD) then
begin
if (old_armor_index=0) then
other^.client^.pers.inventory[jacket_armor_index] := 2
else
other^.client^.pers.inventory[old_armor_index] :=other^.client^.pers.inventory[old_armor_index] + 2;
end
// if player has no armor, just use it
else if (old_armor_index=0) then
begin
other^.client^.pers.inventory[ITEM_INDEX(ent^.item)] := newinfo^.base_count;
end
// use the better armor
else
begin
// get info on old armor
if (old_armor_index = jacket_armor_index) then
oldinfo := @jacketarmor_info
else if (old_armor_index = combat_armor_index) then
oldinfo := @combatarmor_info
else // (old_armor_index = body_armor_index)
oldinfo := @bodyarmor_info;
if (newinfo^.normal_protection > oldinfo^.normal_protection) then
begin
// calc new armor values
salvage := oldinfo^.normal_protection / newinfo^.normal_protection;
salvagecount := round(salvage) * other^.client^.pers.inventory[old_armor_index];
newcount := newinfo^.base_count + salvagecount;
if (newcount > newinfo^.max_count) then
newcount := newinfo^.max_count;
// zero count of old armor so it goes away
other^.client^.pers.inventory[old_armor_index] := 0;
// change armor to new item with computed value
other^.client^.pers.inventory[ITEM_INDEX(ent^.item)] := newcount;
end
else
begin
// calc new armor values
salvage := newinfo^.normal_protection / oldinfo^.normal_protection;
salvagecount := round(salvage )* newinfo^.base_count;
newcount := other^.client^.pers.inventory[old_armor_index] + salvagecount;
if (newcount > oldinfo^.max_count) then
newcount := oldinfo^.max_count;
// if we're already maxed out then we don't need the new armor
if (other^.client^.pers.inventory[old_armor_index] >= newcount) then
// begin
result:= false;
// exit;
// end;
// update current armor value
other^.client^.pers.inventory[old_armor_index] := newcount;
end;
end;
if (ent^.spawnflags and DROPPED_ITEM=0) and (deathmatch^.value<>0) then
SetRespawn (ent, 20);
result:=true;
end;
//===================================
function PowerArmorType(ent:edict_p):integer;
begin
result:= POWER_ARMOR_NONE;
if (ent^.client=nil) then
result:= POWER_ARMOR_NONE;
if (ent^.flags and FL_POWER_ARMOR=0) then
result:= POWER_ARMOR_NONE;
if (ent^.client^.pers.inventory[power_shield_index] > 0) then
result:= POWER_ARMOR_SHIELD;
if (ent^.client^.pers.inventory[power_screen_index] > 0) then
result:= POWER_ARMOR_SCREEN;
end;
procedure Use_PowerArmor(ent:edict_p;item: gitem_p);
var
index:integer;
begin
if (ent^.flags and FL_POWER_ARMOR<>0) then
begin
ent^.flags :=ent^.flags and not(FL_POWER_ARMOR);
gi.sound(ent, CHAN_AUTO, gi.soundindex('misc/power2.wav'), 1, ATTN_NORM, 0);
end
else
begin
index := ITEM_INDEX(FindItem('cells'));
if (ent^.client^.pers.inventory[index]=0) then
begin
gi.cprintf (ent, PRINT_HIGH, 'No cells for power armor.'#10);
exit;
end;
ent^.flags :=ent^.flags or FL_POWER_ARMOR;
gi.sound(ent, CHAN_AUTO, gi.soundindex('misc/power1.wav'), 1, ATTN_NORM, 0);
end;
end;
function Pickup_PowerArmor (ent:edict_p;other:edict_p):qboolean;
var
quantity:integer;
begin
quantity := other^.client^.pers.inventory[ITEM_INDEX(ent^.item)];
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);
// auto-use for DM only if we didn't already have one
if (quantity<>0) then
ent^.item^.use (other, ent^.item);
end;
result:= true;
end;
procedure Drop_PowerArmor(ent:edict_p;item: gitem_p);
begin
if (ent^.flags and FL_POWER_ARMOR<>0) and (ent^.client^.pers.inventory[ITEM_INDEX(item)] = 1) then
Use_PowerArmor (ent, item);
Drop_General (ent, item);
end;
//===================================
{
========
Touch_Item
========
}
procedure Touch_Item (ent:edict_p;other:edict_p;plane: cplane_p;surf: csurface_p);
var
taken:qboolean;
begin
if (other^.client=nil) then
exit;
if (other^.health < 1) then
exit; // dead people can't pickup
if (@ent^.item^.pickup<>nil) then
exit; // not a grabbable item?
taken := ent^.item^.pickup(ent, other);
if (taken) then
begin
// flash the screen
other^.client^.bonus_alpha := 0.25;
// show icon and name on status bar
other^.client^.ps.stats[STAT_PICKUP_ICON] := gi.imageindex(ent^.item^.icon);
other^.client^.ps.stats[STAT_PICKUP_STRING] := CS_ITEMS+ITEM_INDEX(ent^.item);
other^.client^.pickup_msg_time := level.time + 3.0;
// change selected item
if (@ent^.item^.use<>nil) then
other^.client^.pers.selected_item := ITEM_INDEX(ent^.item);
other^.client^.ps.stats[STAT_SELECTED_ITEM] := ITEM_INDEX(ent^.item);
if (@ent^.item^.pickup = @Pickup_Health) then
begin
if (ent^.count = 2) then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -