📄 g_items.pas
字号:
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:pedict_t;item:pgitem_t);
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:pedict_t;item: pgitem_t);
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:pedict_t;item: pgitem_t);
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:pedict_t;other:pedict_t):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 result := false
else
begin
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);
Result := true;
end;
end
else
begin
if (other.client.pers.inventory[ITEM_INDEX(ent.item)]<>0) then result:= false
else
begin
other.client.pers.inventory[ITEM_INDEX(ent.item)] := 1;
Result := true;
end;
end;
end
else
begin
inc(other.client.pers.inventory[ITEM_INDEX(ent.item)]);
result := true;
end;
end;
//===================================
function Add_Ammo (ent:pedict_t;item: pgitem_t; count:integer):qboolean;
var
index : integer;
max : integer;
begin
if (ent.client=nil) then result:= false
else
begin
Case item.tag of
AMMO_BULLETS : max := ent.client.pers.max_bullets;
AMMO_SHELLS : max := ent.client.pers.max_shells;
AMMO_ROCKETS : max := ent.client.pers.max_rockets;
AMMO_GRENADES: max := ent.client.pers.max_grenades;
AMMO_CELLS : max := ent.client.pers.max_cells;
AMMO_SLUGS : max := ent.client.pers.max_slugs;
else
begin // has to be a better way to do this, i don't like using exit
result := false;
exit;
end;
index := ITEM_INDEX(item);
if (ent.client.pers.inventory[index] = max)
then result:= false
else
begin
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;
result := True;
end;
end;
function Pickup_Ammo (ent:pedict_t;other:pedict_t): 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 (Add_Ammo(other, ent.item, count)) then
begin
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
else result:= false;
end;
procedure Drop_Ammo(ent:pedict_t;item: pgitem_t);
var
dropped : pedict_t;
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];
ent.client.pers.inventory[index] :=ent.client.pers.inventory[index] - dropped.count;
ValidateSelectedItem (ent);
end;
//===================================
procedure MegaHealth_think (self : pedict_t);
begin
if (self.owner.health > self.owner.max_health) and not( CTFHasRegeneration(self.owner) ) then
begin
self.nextthink := level.time + 1;
self.owner.health :=self.owner.health - 1;
end
else
begin
if (self.spawnflags and DROPPED_ITEM=0) and (deathmatch.value<>0)
then SetRespawn (self, 20)
else G_FreeEdict (self);
end;
end;
function Pickup_Health (ent:pedict_t;other:pedict_t):qboolean;
begin
if ( ((ent.style and HEALTH_IGNORE_MAX)=0) and
( other.health >= other.max_health) ) or
( other.health >= 250 and ent.count > 25 ) then
begin
result:= false;
end
else
begin
other.health := other.health + ent.count;
if ((other.health > 250) and (ent.count > 25) then other health := 250;
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) and not( CTFHasRegeneration(self.owner) 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;
end;
//===================================
function ArmorIndex (ent:pedict_t):integer;
begin
if (ent.client = nil) then Result := 0
else
begin
if (ent.client.pers.inventory[jacket_armor_index] > 0) then result:= jacket_armor_index
else if (ent.client.pers.inventory[combat_armor_index] > 0) then result:= combat_armor_index
else if (ent.client.pers.inventory[body_armor_index] > 0) then result:= body_armor_index
else result := 0;
end;
end;
function Pickup_Armor (ent:pedict_t;other: pedict_t):qboolean;
var
old_armor_index : integer;
oldinfo : pgitem_armor_t;
newinfo : pgitem_armor_t;
newcount : integer;
salvage : single;
salvagecount : integer;
begin
// get info on new armor
newinfo := ent.item.info; ///////////////////////////// is this right?
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:pedict_t):integer;
begin
if (ent.client=nil)
then result:= POWER_ARMOR_NONE
else if (ent.flags and FL_POWER_ARMOR=0)
then result:= POWER_ARMOR_NONE
else if (ent.client.pers.inventory[power_shield_index] > 0)
then result:= POWER_ARMOR_SHIELD
else if (ent.client.pers.inventory[power_screen_index] > 0)
then result:= POWER_ARMOR_SCREEN
else reslut := POWER_ARMOR_NONE;
end;
procedure Use_PowerArmor(ent:pedict_t;item: pgitem_t);
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);
end
else
begin
ent.flags :=ent.flags or FL_POWER_ARMOR;
gi.sound(ent, CHAN_AUTO, gi.soundindex('misc/power1.wav'), 1, ATTN_NORM, 0);
end;
end;
end;
function Pickup_PowerArmor (ent:pedict_t;other:pedict_t):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:pedict_t;item: pgitem_t);
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:pedict_t;other:pedict_t;plane: pcplane_t;surf: pcsurface_t);
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?
if (CTFMatchSetup()) then exit; ///////////// ctf only
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -