⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_items.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
				gi.sound(other, CHAN_ITEM, gi.soundindex('items/s_health.wav'), 1, ATTN_NORM, 0)
			else if (ent^.count = 10)then
				gi.sound(other, CHAN_ITEM, gi.soundindex('items/n_health.wav'), 1, ATTN_NORM, 0)
			else if (ent^.count = 25)then
				gi.sound(other, CHAN_ITEM, gi.soundindex('items/l_health.wav'), 1, ATTN_NORM, 0)
			else // (ent^.count = 100)
				gi.sound(other, CHAN_ITEM, gi.soundindex('items/m_health.wav'), 1, ATTN_NORM, 0);
		end
		else if (ent^.item^.pickup_sound<>nil) then
		begin
		 gi.sound(other, CHAN_ITEM, gi.soundindex(ent^.item^.pickup_sound), 1, ATTN_NORM, 0);
		end;
	end;

	if (ent^.spawnflags and ITEM_TARGETS_USED<>0) then
	begin
		G_UseTargets (ent, other);
		ent^.spawnflags :=ent^.spawnflags or ITEM_TARGETS_USED;
	end;

	if not(taken)  then
		exit;

	if ((coop^.value=0) and  (ent^.item^.flags and IT_STAY_COOP=0)) or (ent^.spawnflags and (DROPPED_ITEM or DROPPED_PLAYER_ITEM)=0) then
	begin
		if (ent^.flags and FL_RESPAWN<>0)  then
			ent^.flags :=ent^.flags and not (FL_RESPAWN)
		else
			G_FreeEdict (ent);
	end;
end;

//===================================

procedure drop_temp_touch (ent:edict_p;other:edict_p;plane: cplane_p;surf:csurface_p);
begin
	if (other = ent^.owner) then
		exit;

	Touch_Item (ent, other, plane, surf);
end;

procedure drop_make_touchable (ent:edict_p);
begin
	ent^.touch := @Touch_Item;
	if (deathmatch^.value<>0)  then
	begin
		ent^.nextthink := level.time + 29;
		ent^.think := G_FreeEdict;
	end;
end;

function Drop_Item (ent:edict_p;item:gitem_p):edict_p;
var
 dropped: edict_p;
 forwardd, right:vec3_t;
 offset:vec3_t;
 trace:	trace_t;
begin


	dropped := G_Spawn;

	dropped^.classname := item^.classname;
	dropped^.item := item;
	dropped^.spawnflags := DROPPED_ITEM;
	dropped^.s.effects := item^.world_model_flags;
	dropped^.s.renderfx := RF_GLOW;
	VectorSet (dropped^.mins, -15, -15, -15);
	VectorSet (dropped^.maxs, 15, 15, 15);
	gi.setmodel (dropped, dropped^.item^.world_model);
	dropped^.solid := SOLID_TRIGGER;
	dropped^.movetype := MOVETYPE_TOSS;  
	dropped^.touch := @drop_temp_touch;
	dropped^.owner := ent;

	if (ent^.client<>nil) then
	begin


		AngleVectors (ent^.client^.v_angle, @forwardd, @right, nil);
		VectorSet(offset, 24, 0, -16);
		G_ProjectSource (ent^.s.origin, offset, forwardd, right, dropped^.s.origin);
		trace := gi.trace (ent^.s.origin, dropped^.mins, dropped^.maxs,
			dropped^.s.origin, ent, CONTENTS_SOLID);
		VectorCopy (trace.endpos, dropped^.s.origin);
	end
	else
	begin
		AngleVectors (ent^.s.angles, @forwardd, @right, nil);
		VectorCopy (ent^.s.origin, dropped^.s.origin);
	end;

	VectorScale (forwardd, 100, dropped^.velocity);
	dropped^.velocity[2] := 300;

	dropped^.think := @drop_make_touchable;
	dropped^.nextthink := level.time + 1;

	gi.linkentity (dropped);

	result:= dropped;
end;

procedure Use_Item (ent:edict_p;other:edict_p;activator:edict_p);
begin
	ent^.svflags :=ent^.svflags and not(SVF_NOCLIENT);
	ent^.use := nil;

	if (ent^.spawnflags and ITEM_NO_TOUCH<>0) then
	begin
		ent^.solid := SOLID_BBOX;
		ent^.touch := nil;
	end
	else
	begin
		ent^.solid := SOLID_TRIGGER;
		ent^.touch := @Touch_Item;
	end;

	gi.linkentity (ent);
end;

//===================================

{
========
droptofloor
========
}
procedure droptofloor (ent:edict_p);
var
 	tr:trace_t;
	dest,temp:vec3_t;
	v:vec3_t;//pSingle;
begin


       //	v := tv(-15,-15,-15);
        v := tv2(-15,-15,-15);
	VectorCopy (v, ent^.mins);
	v := tv2(15,15,15);
	VectorCopy (v, ent^.maxs);

	if (ent^.model<>nil) then
		gi.setmodel (ent, ent^.model)
	else
		gi.setmodel (ent, ent^.item^.world_model);
	ent^.solid := SOLID_TRIGGER;
	ent^.movetype := MOVETYPE_TOSS;  
	ent^.touch := @Touch_Item;

	v := tv2(0,0,-128);
	VectorAdd (ent^.s.origin, v, dest);

	tr := gi.trace (ent^.s.origin, ent^.mins, ent^.maxs, dest, ent, MASK_SOLID);
	if (tr.startsolid)   then
	begin
		gi_dprintf ('droptofloor: %s startsolid at %s'#10,[ent^.classname, vtos(ent^.s.origin)]);
		G_FreeEdict (ent);
		exit;
	end;

	VectorCopy (tr.endpos, ent^.s.origin);

	if (ent^.team<>nil)  then
	begin
		ent^.flags :=ent^.flags and not(FL_TEAMSLAVE);
		ent^.chain := ent^.teamchain;
		ent^.teamchain := nil;

		ent^.svflags :=ent^.svflags or SVF_NOCLIENT;
		ent^.solid := SOLID_NOT;
		if (ent = ent^.teammaster) then
		begin
			ent^.nextthink := level.time + FRAMETIME;
			ent^.think := @DoRespawn;
		end;
	end;

	if (ent^.spawnflags and ITEM_NO_TOUCH<>0)  then
	begin
		ent^.solid := SOLID_BBOX;
		ent^.touch := nil;
		ent^.s.effects :=ent^.s.effects and not(EF_ROTATE);
		ent^.s.renderfx :=ent^.s.renderfx and not(RF_GLOW);
	end;

	if (ent^.spawnflags and ITEM_TRIGGER_SPAWN<>0)  then
	begin
		ent^.svflags :=ent^.svflags or SVF_NOCLIENT;
		ent^.solid := SOLID_NOT;
		ent^.use := @Use_Item;
	end;

   gi.linkentity (ent);
end;


{
========
PrecacheItem

Precaches all data needed for a given item.
This will be called for each item spawned in a level,
and for each item in each client's inventory.
========
}
procedure PrecacheItem (it:gitem_p);
var
  s,start:pchar;
  data:array[0..MAX_QPATH-1] of char;
  len:integer;
  ammo:	gitem_p;


begin


	if (it=nil)  then
		exit;

	if (it^.pickup_sound<>nil) then
		gi.soundindex (it^.pickup_sound);
	if (it^.world_model<>nil)  then
		gi.modelindex (it^.world_model);
	if (it^.view_model<>nil)  then
		gi.modelindex (it^.view_model);
	if (it^.icon<>nil)       then
		gi.imageindex (it^.icon);

	// parse everything for its ammo
	if (it^.ammo<>nil) and (it^.ammo[0]<>'') then
	begin
		ammo := FindItem (it^.ammo);
		if (ammo <> it) then
			PrecacheItem (ammo);
	end;

	// parse the space seperated precache string for other items
	s := it^.precaches;
	if (s=nil) or (s[0]<>'')  then
		exit;

	while ( s=nil) do
	begin
		start := s;
		while ( s=nil) and (s <>' ') do
			inc(s);

		len := s-start;
		if (len >= MAX_QPATH) or( len < 5)  then
			gi_error ('PrecacheItem: %s has bad precache string', [it^.classname]);
		memcpy (@data, start, len);
		data[len] := #0;
		if ( s<>nil)  then
			inc(s);

		// determine type based on extension
		if (strcmp(data+len-3, 'md2')=0) then
			gi.modelindex (data)
		else if (strcmp(data+len-3, 'sp2')=0) then
			gi.modelindex (data)
		else if (strcmp(data+len-3, 'wav')=0) then
			gi.soundindex (data);
		if (strcmp(data+len-3, 'pcx')=0) then
			gi.imageindex (data);
	end;
end;

{
======
SpawnItem

Sets the clipping size and plants the object on the floor.

Items can't be immediately dropped to floor, because they might
be on an entity that hasn't spawned yet.
======
}
procedure SpawnItem (ent:edict_p;item: gitem_p);
begin
	PrecacheItem (item);

	if (ent^.spawnflags<>0)  then
	begin
		if (strcmp(ent^.classname, 'key_power_cube') <> 0)  then
		begin
			ent^.spawnflags := 0;
			gi_dprintf('%s at %s has invalid spawnflags set'#10, [ent^.classname, vtos(ent^.s.origin)]);
		end;
	end;

	// some items will be prevented in deathmatch
	if (deathmatch^.value<>0)   then
	begin
		if ( round(dmflags^.value) and DF_NO_ARMOR <>0)  then
		begin
	       	if (@item^.pickup = @Pickup_Armor) or (@item^.pickup = @Pickup_PowerArmor)  then
			begin
				G_FreeEdict (ent);
				exit;
			end;
		end;
		if ( round(dmflags^.value) and DF_NO_ITEMS <>0)   then
		begin
			if (@item^.pickup = @Pickup_Powerup)  then
			begin
				G_FreeEdict (ent);
				exit;
			end;
		end;
		if ( round(dmflags^.value) and DF_NO_HEALTH <>0)  then
		begin
			if (@item^.pickup = @Pickup_Health) or (@item^.pickup = @Pickup_Adrenaline )or (@item^.pickup = @Pickup_AncientHead)  then
			begin
				G_FreeEdict (ent);
				exit;
			end;
		end;
		if ( round(dmflags^.value) and DF_INFINITE_AMMO <>0)    then
		begin
		   if ( item^.flags = IT_AMMO) or (strcmp(ent^.classname, 'weapon_bfg') = 0 )  then
			begin
				G_FreeEdict (ent);
				exit;
			end;
		end;
	end;

	if (coop^.value<>0) and (strcmp(ent^.classname, 'key_power_cube') = 0) then
	begin
		ent^.spawnflags :=ent^.spawnflags or  (1 shl (8 + level.power_cubes));
		inc(level.power_cubes);
	end;

	// don't let them drop items that stay in a coop game
	if (coop^.value<>0) and (item^.flags and IT_STAY_COOP<>0) then
	begin
		item^.drop := nil;
	end;

	ent^.item := item;
	ent^.nextthink := level.time + 2 * FRAMETIME;    // items start after other solids
	ent^.think := @droptofloor;
	ent^.s.effects := item^.world_model_flags;
	ent^.s.renderfx := RF_GLOW;
	if (ent^.model<>nil)   then
		gi.modelindex (ent^.model);
end;
(*
//===================================
 type  gitem_p =record
    classname: PChar;  // spawning name
    pickup: BoolFunc_2edict_s;
    use: Proc_edit_s__gitem_s;
    drop: Proc_edit_s__gitem_s;
    weaponthink: Proc_edit_s;
    pickup_sound: PChar;
    world_model: PChar;
    world_model_flags: integer;
    view_model: PChar;

    // client side info
    icon: PChar;
    pickup_name: PChar;	// for printing on pickup
    count_width: integer; // number of digits to display by icon

    quantity: integer;	// for ammo how much, for weapons how much is used per shot
    ammo: PChar; 	// for weapons
    flags: integer;	// IT_* flags

    weapmodel: integer;	// weapon model index (for weapons)

    info: Pointer;
    tag: integer;

    precaches: PChar; // string of all models, sounds, and images this item will use *)


const	itemlist:array[0..42]of gitem_s =  (

       (
       //	nil
       ),	// leave index 0 alone

	//
	// ARMOR
	//

{QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16)
}
	(
	        classname        : 'item_armor_body';
	        pickup           : Pickup_Armor;
        	use              : nil;
          	drop             : nil;
	        weaponthink      : nil;
	        pickup_sound     : 'misc/ar1_pkup.wav';
	        world_model      : 'models/items/armor/body/tris.md2';
                world_model_flags: EF_ROTATE;
          	view_model       : nil;
{ icon }        icon             : 'i_bodyarmor';
{ pickup}	pickup_name      :'Body Armor';
{ width }	count_width      : 3;
		quantity         : 0;
		ammo             : nil;
		flags            : IT_ARMOR;
		weapmodel        : 0;
		info             : @bodyarmor_info;
	        tag              : ARMOR_BODY;
{ precache }    precaches        : '';
	),

{QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16)
}
       (

                classname        : 'item_armor_combat';
	        pickup           : Pickup_Armor;
        	use              : nil;
          	drop             : nil;
	        weaponthink      : nil;
	        pickup_sound     : 'misc/ar1_pkup.wav';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -